/
index.ts
56 lines (45 loc) · 1.51 KB
/
index.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
import { Effect, Event, is, Store } from 'effector';
import { als, diInit } from 'ts-fp-di';
export const effectorAsyncLocalStorageFactory =
({
onCreateEvent,
onCreateEffect,
onCreateStore,
}: {
onCreateEvent: (label: string, event: Event<any>) => void;
onCreateEffect: (label: string, effect: Effect<any, any, any>) => void;
onCreateStore: (label: string, store: Store<any>) => void;
}) =>
<T extends (this: U, ...args: any) => any, U>(label: string, cb: T) => {
const resp = function (this: U, ...args: Parameters<T>): ReturnType<T> {
type AlsStore = { effector: Map<typeof cb, ReturnType<T>> };
const store = storeOrError();
if (!store.effector) {
store.effector = new Map();
}
const cachedUnit = (store as unknown as AlsStore).effector.get(cb);
if (cachedUnit != null) {
return cachedUnit;
}
const unit = cb.apply(this, args);
unit.sid = label;
(store as unknown as AlsStore).effector.set(cb, unit);
if (is.event(unit)) {
onCreateEvent(label, unit);
} else if (is.effect(unit)) {
onCreateEffect(label, unit);
} else if (is.store(unit)) {
onCreateStore(label, unit);
}
return unit;
};
return resp;
};
export const effectorAsyncLocalStorageInit = diInit;
const storeOrError = () => {
const store = als.getStore();
if (store == null) {
throw new Error('DI container not registered! Consider, that you call "diInit" before');
}
return store;
};