-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
107 lines (96 loc) · 3.03 KB
/
index.js
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
function createState(initialState) {
var state = JSON.parse(JSON.stringify(initialState))
var initial = JSON.parse(JSON.stringify(initialState))
var listeners = {};
function createRef(key, path = [key]) {
function reset() {
if (path.length === 1 && key === 'state') {
state = initial;
callListeners();
return;
}
var update = state;
for (var i=1; i<path.length-1; i++) {
update = update[path[i]];
}
if (update[key] === initial[key]) return;
update[key] = initial[key];
callListeners();
}
function ref(key) {
return createRef(key, path.concat(key));
}
function val() {
var value = state;
for (var i=1; i<path.length; i++) {
var innerVal = value[path[i]]
if (innerVal === undefined) return undefined
value = innerVal;
}
return JSON.parse(JSON.stringify(value))
}
// function callListeners() {
// for (var i=0; i<path.length; i++) {
// var paths = path.slice(0, i+1);
// const id = paths.join('-');
// if (!listeners[id]) continue;
// console.log('calling all with id: ', id)
// for (var j=0; j<listeners[id].length; j++) {
// var ref = createRef(paths[i], paths);
// listeners[id][j](ref);
// }
// }
// }
function callListeners() {
var pathKey = path.join('-');
var keys = Object.keys(listeners);
for (var i=0; i<keys.length; i++) {
var hasPrefix = pathKey.startsWith(keys[i]);
var isPrefix = keys[i].startsWith(pathKey);
if (!hasPrefix && !isPrefix) continue;
var id = keys[i];
if (!listeners[id]) continue;
for (var j=0; j<listeners[id].length; j++) {
var refPath = id.split('-');
var refKey = refPath[refPath.length - 1];
var ref = createRef(refKey, refPath);
listeners[id][j](ref);
}
}
}
function set(value) {
if (path.length === 1 && key === 'state') {
state = value;
callListeners();
return;
}
var update = state;
for (var i=1; i<path.length-1; i++) {
update = update[path[i]];
}
if (update[key] === value) return;
update[key] = value;
callListeners();
}
function listen(listener) {
var id = path.join('-');
if (!listeners[id]) {
listeners[id] = [];
}
listeners[id].push(listener);
return function() {
var index = listeners[id].indexOf(listener);
listeners[id].splice(index, 1);
}
}
return {
ref: ref,
val: val,
set: set,
listen: listen,
reset: reset
}
}
return createRef('state');
}
module.exports = createState;