summaryrefslogtreecommitdiffstats
path: root/devtools/client/debugger/src/actions/utils/middleware/promise.js
blob: 52054a1fcc2c89d8b515d0ffb2d1e9d3d17fe14f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */

import { executeSoon } from "../../../utils/DevToolsUtils";

import { pending, rejected, fulfilled } from "../../../utils/async-value";
export function asyncActionAsValue(action) {
  if (action.status === "start") {
    return pending();
  }
  if (action.status === "error") {
    return rejected(action.error);
  }
  return fulfilled(action.value);
}

let seqIdVal = 1;

function seqIdGen() {
  return seqIdVal++;
}

function promiseMiddleware({ dispatch, getState }) {
  return next => action => {
    if (!(PROMISE in action)) {
      return next(action);
    }

    const seqId = seqIdGen().toString();
    const { [PROMISE]: promiseInst, ...originalActionProperties } = action;

    // Create a new action that doesn't have the promise field and has
    // the `seqId` field that represents the sequence id
    action = { ...originalActionProperties, seqId };

    dispatch({ ...action, status: "start" });

    // Return the promise so action creators can still compose if they
    // want to.
    return Promise.resolve(promiseInst)
      .finally(() => new Promise(resolve => executeSoon(resolve)))
      .then(
        value => {
          dispatch({ ...action, status: "done", value: value });
          return value;
        },
        error => {
          dispatch({
            ...action,
            status: "error",
            error: error.message || error,
          });
          return Promise.reject(error);
        }
      );
  };
}

export const PROMISE = "@@dispatch/promise";
export { promiseMiddleware as promise };