-
Notifications
You must be signed in to change notification settings - Fork 7
/
trrack.ts
116 lines (96 loc) · 2.59 KB
/
trrack.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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import { initializeTrrack, Registry } from '@trrack/core';
import { useMemo, useState } from 'react';
import { Task } from './types';
const initialState = {
tasks: [] as Task[],
};
type State = typeof initialState;
// ! Add example for async action (e.g. data loading)
export function useTrrackTaskManager() {
const [counter, setCounter] = useState(0);
const [state, setState] = useState(initialState);
const { registry, actions } = useMemo(() => {
const reg = Registry.create();
const addTask = reg.register('add-task', (state, task: Task) => {
state.tasks.push(task);
});
const removeTask = reg.register('remove-task', (state, task: Task) => {
state.tasks = state.tasks.filter((t: Task) => t.id !== task.id);
});
const markTaskComplete = reg.register(
'complete-task',
(state, task: Task) => {
const idx = state.tasks.findIndex((d: any) => d.id === task.id);
state.tasks[idx].completed = true;
}
);
const markTaskIncomplete = reg.register(
'incomplete-task',
(state, task: Task) => {
const idx = state.tasks.findIndex((d: any) => d.id === task.id);
state.tasks[idx].completed = false;
}
);
const incrementCounter = reg.register(
'increment-counter',
(add: number) => {
setCounter((c) => c + add);
return {
type: 'decrement-counter',
payload: add,
meta: {
hasSideEffects: true,
},
};
}
);
const decrementCounter = reg.register(
'decrement-counter',
(sub: number) => {
setCounter((c) => c - sub);
return {
type: 'increment-counter',
payload: sub,
meta: {
hasSideEffects: true,
},
};
}
);
return {
registry: reg,
actions: {
addTask,
removeTask,
markTaskComplete,
markTaskIncomplete,
incrementCounter,
decrementCounter,
},
};
}, []);
const trrack = useMemo(() => {
const t = initializeTrrack({
initialState,
registry,
});
t.currentChange(() => {
setState(t.current.state.val as State);
});
return t;
}, [registry]);
const current = useMemo(() => {
return trrack.current;
}, [trrack]);
const isAtLatest = current ? current.children.length === 0 : false;
const isAtRoot = current ? current.id === trrack.root.id : false;
return {
trrack,
isAtLatest,
isAtRoot,
state,
counter,
actions,
};
}
export type Trrack = ReturnType<typeof useTrrackTaskManager>;