-
Notifications
You must be signed in to change notification settings - Fork 0
/
plugin.ts
82 lines (76 loc) · 2.2 KB
/
plugin.ts
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
import { GenericStoreApi, GetStoreApiSetter, GetStoreApiState } from '~/types';
import {
ExecuteCommandCallback,
makeCommandNotifier,
} from '~/plugins/commands/notifier';
import { GenericStateCommand } from '~/plugins/commands/command';
import { makePlugin } from '~/api';
import {
ProxifyCommands,
StoreWithProxyCommands,
} from '~/plugins/commands/types';
import { makeProxyHandlers } from '~/plugins/commands/proxy';
import { applyDevtools } from '~/plugins/commands/devtools';
function plugin<ActionsMap extends Record<string, unknown>>(): <
TGenericApi extends GenericStoreApi,
>(
ctx: TGenericApi,
) => StoreWithProxyCommands<
TGenericApi,
GetStoreApiState<TGenericApi>,
ProxifyCommands<ActionsMap>
> {
return <TGenericApi extends GenericStoreApi>(
ctx: TGenericApi,
): StoreWithProxyCommands<
TGenericApi,
GetStoreApiState<TGenericApi>,
ProxifyCommands<ActionsMap>
> => {
const { callbacks, watchCommand, dispatch } = makeCommandNotifier(ctx);
const { commands, actions } = makeProxyHandlers<ActionsMap>(dispatch);
return {
commands,
actions,
hold(command, cb) {
const resolvedCallbacks = callbacks.get(command.identity) || [];
const updatedCallbacks = resolvedCallbacks.concat(
cb as ExecuteCommandCallback<
GetStoreApiState<TGenericApi>,
GenericStateCommand,
GetStoreApiSetter<TGenericApi>
>,
);
callbacks.set(command.identity, updatedCallbacks);
return this;
},
dispatch,
watchCommand,
};
};
}
interface PluginOptions {
devtools?: { storeName: string };
}
export function withProxyCommands<T extends Record<string, unknown>>(
options?: PluginOptions,
) {
return makePlugin(
(store, context) => {
const storeWithProxy = plugin<T>()(store);
if (options?.devtools) {
const { storeName } = options.devtools;
context.hooks.onInit(() => {
const unsubscribe = applyDevtools(store, storeWithProxy, {
storeName,
});
context.hooks.onDestroy(() => unsubscribe());
});
}
return storeWithProxy;
},
{
name: 'withProxyCommands',
},
);
}