forked from firefox-devtools/debugger
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmemoizableAction.js
More file actions
84 lines (77 loc) · 2.33 KB
/
memoizableAction.js
File metadata and controls
84 lines (77 loc) · 2.33 KB
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/* 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/>. */
// @flow
import type { ThunkArgs } from "../actions/types";
export type MemoizedAction<
Args,
Result
> = Args => ThunkArgs => Promise<?Result>;
type MemoizableActionParams<Args, Result> = {
exitEarly?: (args: Args, thunkArgs: ThunkArgs) => boolean,
hasValue: (args: Args, thunkArgs: ThunkArgs) => boolean,
getValue: (args: Args, thunkArgs: ThunkArgs) => Result,
createKey: (args: Args, thunkArgs: ThunkArgs) => string,
action: (args: Args, thunkArgs: ThunkArgs) => Promise<Result>
};
/*
* memoizableActon is a utility for actions that should only be performed
* once per key. It is useful for loading sources, parsing symbols ...
*
* @exitEarly - if true, do not attempt to perform the action
* @hasValue - checks to see if the result is in the redux store
* @getValue - gets the result from the redux store
* @createKey - creates a key for the requests map
* @action - kicks off the async work for the action
*
*
* For Example
*
* export const setItem = memoizeableAction(
* "setItem",
* {
* hasValue: ({ a }, { getState }) => hasItem(getState(), a),
* getValue: ({ a }, { getState }) => getItem(getState(), a),
* createKey: ({ a }) => a,
* action: ({ a }, thunkArgs) => doSetItem(a, thunkArgs)
* }
* );
*
*/
export function memoizeableAction<Args, Result>(
name: string,
{
hasValue,
getValue,
createKey,
action,
exitEarly
}: MemoizableActionParams<Args, Result>
): MemoizedAction<Args, Result> {
const requests = new Map();
return args => async (thunkArgs: ThunkArgs) => {
if (exitEarly && exitEarly(args, thunkArgs)) {
return;
}
if (hasValue(args, thunkArgs)) {
return getValue(args, thunkArgs);
}
const key = createKey(args, thunkArgs);
if (!requests.has(key)) {
requests.set(
key,
(async () => {
try {
await action(args, thunkArgs);
} catch (e) {
console.warn(`Action ${name} had an exception:`, e);
} finally {
requests.delete(key);
}
})()
);
}
await requests.get(key);
return getValue(args, thunkArgs);
};
}