-
Notifications
You must be signed in to change notification settings - Fork 0
/
kstate.ts
64 lines (58 loc) · 1.74 KB
/
kstate.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
type Tail<T> = T extends [any, ...infer Tail] ? Tail : any[];
export class ControllerState<
T extends Record<string, any>,
U extends Record<
string,
(controllerState: ControllerState<T, U, V, X>, ...args: any) => any
>,
V extends Record<
string,
(controllerState: ControllerState<T, U, V, X>, ...args: any) => any
>,
X extends Record<
string,
(controllerState: ControllerState<T, U, V, X>) => any
>
> {
state: T;
actions: U;
setters: V;
getters: X;
history: [string, string, string][];
constructor(initialState: { state: T; actions: U; setters: V; getters: X }) {
this.state = initialState.state;
this.actions = initialState.actions;
this.setters = initialState.setters;
this.getters = initialState.getters;
this.commit = this.commit.bind(this);
this.dispatch = this.dispatch.bind(this);
// TODO: We need a better model for history
this.history = [];
}
commit<S extends keyof V>(setter: S, ...args: Tail<Parameters<V[S]>>) {
this.history.push(["Commit", String(setter), JSON.stringify(args)]);
this.setters[setter](this, ...args);
}
async dispatch<S extends keyof U>(
action: S,
...args: Tail<Parameters<U[S]>>
) {
this.history.push(["Dispatch", String(action), JSON.stringify(args)]);
const response = await this.actions[action](this, ...args).catch(
(error: any) => {
this.history.push(["Rejected", String(action), "Error"]);
throw error;
}
);
this.history.push([
"Response",
String(action),
response ? JSON.stringify(response) : "Success",
]);
return response;
}
useGetter<S extends keyof X>(getter: S) {
return () => this.getters[getter](this);
}
}
export default ControllerState;