forked from cerebral/overmind
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.ts
More file actions
133 lines (115 loc) · 3.3 KB
/
Copy pathindex.ts
File metadata and controls
133 lines (115 loc) · 3.3 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
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import proxify, { IS_PROXY, Status } from "./proxify";
type Mutation = {
method: string,
path: string,
args: any[]
}
class ProxyStateTree<State> {
state: State
pathDependencies: object
mutations: Mutation[]
paths: Set<string>[]
status: Status
proxy: any
constructor(state) {
this.state = state;
this.pathDependencies = {};
this.mutations = [];
this.paths = [];
this.status = Status.IDLE;
this.proxy = proxify(this, state);
}
get(): State {
return this.proxy;
}
flush() {
const pathCallbacksCalled = new Set();
for (let mutation in this.mutations) {
const path = this.mutations[mutation].path;
if (this.pathDependencies[path]) {
for (let callback of this.pathDependencies[path]) {
if (!pathCallbacksCalled.has(callback)) {
pathCallbacksCalled.add(callback);
callback();
}
}
}
}
pathCallbacksCalled.clear();
}
startMutationTracking() {
if (this.status !== Status.IDLE) {
throw new Error(
`You can not start tracking mutations unless idle. The status is: ${
this.status
}`
);
}
const currentMutations = this.mutations.slice();
this.status = Status.TRACKING_MUTATIONS;
this.mutations.length = 0;
return currentMutations;
}
clearMutationTracking() {
this.status = Status.IDLE;
return this.mutations.slice();
}
startPathsTracking() {
if (this.status === Status.TRACKING_MUTATIONS) {
throw new Error(
`You can not start tracking paths when tracking mutations.`
);
}
this.status = Status.TRACKING_PATHS;
return this.paths.push(new Set()) - 1;
}
clearPathsTracking(index) {
if (index !== this.paths.length - 1) {
throw new Error(
"Nested path tracking requires you to stop the nested path tracker before the outer"
);
}
const pathSet = this.paths[index];
this.paths.pop();
if (!this.paths.length) {
this.status = Status.IDLE;
}
return pathSet;
}
addMutationListener(initialPaths, cb) {
const pathDependencies = this.pathDependencies;
let currentStringPaths = initialPaths;
for (let currentStringPath of currentStringPaths) {
pathDependencies[currentStringPath] = pathDependencies[currentStringPath]
? pathDependencies[currentStringPath].add(cb)
: new Set([cb]);
}
return {
update(newStringPaths) {
for (let currentStringPath of currentStringPaths) {
if (!newStringPaths.has(currentStringPath)) {
pathDependencies[currentStringPath].delete(cb);
}
}
for (let newStringPath of newStringPaths) {
if (!currentStringPaths.has(newStringPath)) {
pathDependencies[newStringPath] = pathDependencies[newStringPath]
? pathDependencies[newStringPath].add(cb)
: new Set([cb]);
}
}
currentStringPaths = newStringPaths;
},
dispose() {
for (let currentStringPath of currentStringPaths) {
pathDependencies[currentStringPath].delete(cb);
if (pathDependencies[currentStringPath].size === 0) {
delete pathDependencies[currentStringPath];
}
}
}
};
}
}
export { IS_PROXY };
export default ProxyStateTree;