@yiin/reactive-proxy-state 1.0.12 → 1.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/computed.d.ts +6 -0
- package/dist/constants.d.ts +8 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1474 -11
- package/dist/reactive.d.ts +14 -2
- package/dist/ref.d.ts +24 -7
- package/dist/state.d.ts +6 -0
- package/dist/types.d.ts +1 -1
- package/dist/watch-effect.d.ts +2 -1
- package/dist/wrap-array.d.ts +2 -2
- package/dist/wrap-map.d.ts +2 -2
- package/dist/wrap-set.d.ts +2 -2
- package/package.json +2 -2
- package/dist/computed.js +0 -58
- package/dist/reactive.js +0 -114
- package/dist/ref.js +0 -91
- package/dist/state.js +0 -211
- package/dist/types.js +0 -1
- package/dist/utils.js +0 -220
- package/dist/watch-effect.js +0 -154
- package/dist/watch.js +0 -44
- package/dist/watchEffect.d.ts +0 -54
- package/dist/watchEffect.js +0 -154
- package/dist/wrap-array.js +0 -237
- package/dist/wrap-map.js +0 -252
- package/dist/wrap-set.js +0 -182
- package/dist/wrapArray.d.ts +0 -2
- package/dist/wrapArray.js +0 -227
- package/dist/wrapMap.d.ts +0 -2
- package/dist/wrapMap.js +0 -230
- package/dist/wrapSet.d.ts +0 -2
- package/dist/wrapSet.js +0 -167
package/dist/wrapArray.js
DELETED
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
import { deepEqual, getPathConcat, setPathConcat, wrapperCache } from './utils';
|
|
2
|
-
import { reactive } from './reactive';
|
|
3
|
-
import { wrapMap } from './wrap-map';
|
|
4
|
-
import { wrapSet } from './wrap-set';
|
|
5
|
-
import { track, trigger } from './watch-effect';
|
|
6
|
-
// avoid repeated typeof checks
|
|
7
|
-
function isObject(v) {
|
|
8
|
-
return v && typeof v === 'object';
|
|
9
|
-
}
|
|
10
|
-
export function wrapArray(arr, emit, path) {
|
|
11
|
-
// reuse existing proxy if available for performance
|
|
12
|
-
const cachedProxy = wrapperCache.get(arr);
|
|
13
|
-
if (cachedProxy)
|
|
14
|
-
return cachedProxy;
|
|
15
|
-
const proxy = new Proxy(arr, {
|
|
16
|
-
get(target, prop, receiver) {
|
|
17
|
-
track(target, prop);
|
|
18
|
-
// handle specific array mutation methods that require custom logic and event emission
|
|
19
|
-
switch (prop) {
|
|
20
|
-
case 'push':
|
|
21
|
-
track(target, 'length');
|
|
22
|
-
return function (...items) {
|
|
23
|
-
const oldLength = target.length;
|
|
24
|
-
const result = target.push(...items);
|
|
25
|
-
const newLength = target.length;
|
|
26
|
-
if (items.length > 0) {
|
|
27
|
-
const event = {
|
|
28
|
-
action: 'array-push',
|
|
29
|
-
path: path,
|
|
30
|
-
key: oldLength, // start index was the old length
|
|
31
|
-
items: items
|
|
32
|
-
};
|
|
33
|
-
emit(event);
|
|
34
|
-
trigger(target, Symbol.iterator);
|
|
35
|
-
if (oldLength !== newLength) {
|
|
36
|
-
trigger(target, 'length');
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
return result;
|
|
40
|
-
};
|
|
41
|
-
case 'pop':
|
|
42
|
-
track(target, 'length');
|
|
43
|
-
return function () {
|
|
44
|
-
if (target.length === 0)
|
|
45
|
-
return undefined;
|
|
46
|
-
const oldLength = target.length;
|
|
47
|
-
const poppedIndex = oldLength - 1;
|
|
48
|
-
const oldValue = target[poppedIndex];
|
|
49
|
-
const result = target.pop();
|
|
50
|
-
const newLength = target.length;
|
|
51
|
-
const event = {
|
|
52
|
-
action: 'array-pop',
|
|
53
|
-
path: path,
|
|
54
|
-
key: poppedIndex,
|
|
55
|
-
oldValue: oldValue
|
|
56
|
-
};
|
|
57
|
-
emit(event);
|
|
58
|
-
trigger(target, Symbol.iterator);
|
|
59
|
-
if (oldLength !== newLength) {
|
|
60
|
-
trigger(target, 'length');
|
|
61
|
-
}
|
|
62
|
-
return result;
|
|
63
|
-
};
|
|
64
|
-
case 'shift':
|
|
65
|
-
track(target, 'length');
|
|
66
|
-
return function () {
|
|
67
|
-
if (target.length === 0)
|
|
68
|
-
return undefined;
|
|
69
|
-
const oldLength = target.length;
|
|
70
|
-
const oldValue = target[0];
|
|
71
|
-
const result = target.shift();
|
|
72
|
-
const newLength = target.length;
|
|
73
|
-
const event = {
|
|
74
|
-
action: 'array-shift',
|
|
75
|
-
path: path,
|
|
76
|
-
key: 0,
|
|
77
|
-
oldValue: oldValue
|
|
78
|
-
};
|
|
79
|
-
emit(event);
|
|
80
|
-
trigger(target, Symbol.iterator);
|
|
81
|
-
if (oldLength !== newLength) {
|
|
82
|
-
trigger(target, 'length');
|
|
83
|
-
}
|
|
84
|
-
return result;
|
|
85
|
-
};
|
|
86
|
-
case 'unshift':
|
|
87
|
-
track(target, 'length');
|
|
88
|
-
return function (...items) {
|
|
89
|
-
const oldLength = target.length;
|
|
90
|
-
const result = target.unshift(...items);
|
|
91
|
-
const newLength = target.length;
|
|
92
|
-
if (items.length > 0) {
|
|
93
|
-
const event = {
|
|
94
|
-
action: 'array-unshift',
|
|
95
|
-
path: path,
|
|
96
|
-
key: 0,
|
|
97
|
-
items: items
|
|
98
|
-
};
|
|
99
|
-
emit(event);
|
|
100
|
-
trigger(target, Symbol.iterator);
|
|
101
|
-
if (oldLength !== newLength) {
|
|
102
|
-
trigger(target, 'length');
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
return result;
|
|
106
|
-
};
|
|
107
|
-
case 'splice':
|
|
108
|
-
track(target, 'length');
|
|
109
|
-
return function (start, deleteCount, ...items) {
|
|
110
|
-
const oldLength = target.length;
|
|
111
|
-
const actualStart = start < 0 ? Math.max(target.length + start, 0) : Math.min(start, target.length);
|
|
112
|
-
const deleteCountNum = deleteCount === undefined ? target.length - actualStart : Number(deleteCount);
|
|
113
|
-
const actualDeleteCount = Math.min(deleteCountNum, target.length - actualStart);
|
|
114
|
-
const deletedItems = target.slice(actualStart, actualStart + actualDeleteCount);
|
|
115
|
-
const result = target.splice(start, deleteCountNum, ...items);
|
|
116
|
-
const newLength = target.length;
|
|
117
|
-
if (actualDeleteCount > 0 || items.length > 0) {
|
|
118
|
-
const event = {
|
|
119
|
-
action: 'array-splice',
|
|
120
|
-
path: path,
|
|
121
|
-
key: actualStart,
|
|
122
|
-
deleteCount: actualDeleteCount,
|
|
123
|
-
items: items.length > 0 ? items : undefined,
|
|
124
|
-
oldValues: deletedItems.length > 0 ? deletedItems : undefined
|
|
125
|
-
};
|
|
126
|
-
emit(event);
|
|
127
|
-
trigger(target, Symbol.iterator);
|
|
128
|
-
if (oldLength !== newLength) {
|
|
129
|
-
trigger(target, 'length');
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
return result;
|
|
133
|
-
};
|
|
134
|
-
// handle methods that rely on iteration state
|
|
135
|
-
case Symbol.iterator:
|
|
136
|
-
case 'values':
|
|
137
|
-
case 'keys':
|
|
138
|
-
case 'entries':
|
|
139
|
-
case 'forEach':
|
|
140
|
-
case 'map':
|
|
141
|
-
case 'filter':
|
|
142
|
-
case 'reduce':
|
|
143
|
-
case 'reduceRight':
|
|
144
|
-
case 'find':
|
|
145
|
-
case 'findIndex':
|
|
146
|
-
case 'every':
|
|
147
|
-
case 'some':
|
|
148
|
-
case 'join':
|
|
149
|
-
track(target, Symbol.iterator);
|
|
150
|
-
// fall through to default behavior (usually binding)
|
|
151
|
-
break;
|
|
152
|
-
case 'length':
|
|
153
|
-
track(target, 'length');
|
|
154
|
-
return Reflect.get(target, prop, receiver);
|
|
155
|
-
}
|
|
156
|
-
const value = Reflect.get(target, prop, receiver);
|
|
157
|
-
// determine if the property access is numeric array index access
|
|
158
|
-
const isNumericIndex = typeof prop === 'number' || (typeof prop === 'string' && !isNaN(parseInt(prop, 10)));
|
|
159
|
-
if (isNumericIndex) {
|
|
160
|
-
track(target, String(prop));
|
|
161
|
-
if (!isObject(value))
|
|
162
|
-
return value;
|
|
163
|
-
// reuse existing proxy for nested object/array if available
|
|
164
|
-
const cachedValueProxy = wrapperCache.get(value);
|
|
165
|
-
if (cachedValueProxy)
|
|
166
|
-
return cachedValueProxy;
|
|
167
|
-
// calculate the nested path for the element, optimizing with caching
|
|
168
|
-
const propKey = String(prop);
|
|
169
|
-
const pathKey = path.length > 0 ? `${path.join('.')}.${propKey}` : propKey;
|
|
170
|
-
let newPath = getPathConcat(pathKey);
|
|
171
|
-
if (newPath === undefined) {
|
|
172
|
-
newPath = path.concat(propKey);
|
|
173
|
-
setPathConcat(pathKey, newPath);
|
|
174
|
-
}
|
|
175
|
-
// recursively wrap nested structures
|
|
176
|
-
if (Array.isArray(value))
|
|
177
|
-
return wrapArray(value, emit, newPath);
|
|
178
|
-
if (value instanceof Map)
|
|
179
|
-
return wrapMap(value, emit, newPath);
|
|
180
|
-
if (value instanceof Set)
|
|
181
|
-
return wrapSet(value, emit, newPath);
|
|
182
|
-
if (value instanceof Date)
|
|
183
|
-
return new Date(value.getTime()); // dates are not proxied, return a copy
|
|
184
|
-
return reactive(value, emit, newPath);
|
|
185
|
-
}
|
|
186
|
-
// ensure functions accessed directly are bound to the original target
|
|
187
|
-
if (typeof value === 'function') {
|
|
188
|
-
return value.bind(target);
|
|
189
|
-
}
|
|
190
|
-
return value;
|
|
191
|
-
},
|
|
192
|
-
set(target, prop, value, receiver) {
|
|
193
|
-
const oldValue = target[prop];
|
|
194
|
-
// avoid unnecessary triggers if value hasn't changed
|
|
195
|
-
if (oldValue === value)
|
|
196
|
-
return true;
|
|
197
|
-
if (isObject(oldValue) && isObject(value) && deepEqual(oldValue, value, new WeakMap()))
|
|
198
|
-
return true;
|
|
199
|
-
const descriptor = Reflect.getOwnPropertyDescriptor(target, prop);
|
|
200
|
-
const result = Reflect.set(target, prop, value, receiver);
|
|
201
|
-
const isNumericIndex = typeof prop === 'number' || (typeof prop === 'string' && !isNaN(parseInt(String(prop))));
|
|
202
|
-
// emit event and trigger effects only if the set was successful and wasn't intercepted by a setter
|
|
203
|
-
// (unless it's a direct numeric index set, which doesn't have a descriptor.set)
|
|
204
|
-
if (result && (!descriptor || !descriptor.set || isNumericIndex)) {
|
|
205
|
-
const propKey = String(prop);
|
|
206
|
-
const pathKey = path.length > 0 ? `${path.join('.')}.${propKey}` : propKey;
|
|
207
|
-
let newPath = getPathConcat(pathKey);
|
|
208
|
-
if (newPath === undefined) {
|
|
209
|
-
newPath = path.concat(propKey);
|
|
210
|
-
setPathConcat(pathKey, newPath);
|
|
211
|
-
}
|
|
212
|
-
const event = {
|
|
213
|
-
action: 'set',
|
|
214
|
-
path: newPath,
|
|
215
|
-
oldValue,
|
|
216
|
-
newValue: value
|
|
217
|
-
};
|
|
218
|
-
emit(event);
|
|
219
|
-
trigger(target, prop);
|
|
220
|
-
}
|
|
221
|
-
return result;
|
|
222
|
-
}
|
|
223
|
-
});
|
|
224
|
-
// cache the newly created proxy before returning
|
|
225
|
-
wrapperCache.set(arr, proxy);
|
|
226
|
-
return proxy;
|
|
227
|
-
}
|
package/dist/wrapMap.d.ts
DELETED
package/dist/wrapMap.js
DELETED
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
import { deepEqual, getPathConcat, setPathConcat, wrapperCache } from './utils';
|
|
2
|
-
import { reactive } from './reactive';
|
|
3
|
-
import { wrapArray } from './wrap-array';
|
|
4
|
-
import { wrapSet } from './wrap-set';
|
|
5
|
-
import { track, trigger } from './watch-effect';
|
|
6
|
-
export function wrapMap(map, emit, path) {
|
|
7
|
-
// reuse existing proxy if available for performance
|
|
8
|
-
const cachedProxy = wrapperCache.get(map);
|
|
9
|
-
if (cachedProxy)
|
|
10
|
-
return cachedProxy;
|
|
11
|
-
const proxy = new Proxy(map, {
|
|
12
|
-
get(target, prop, receiver) {
|
|
13
|
-
track(target, prop);
|
|
14
|
-
if (prop === 'set') {
|
|
15
|
-
return function (key, value) {
|
|
16
|
-
const existed = target.has(key);
|
|
17
|
-
const oldValue = target.get(key);
|
|
18
|
-
const oldSize = target.size;
|
|
19
|
-
// avoid unnecessary work if value hasn't changed
|
|
20
|
-
if (oldValue === value)
|
|
21
|
-
return receiver;
|
|
22
|
-
if (oldValue && typeof oldValue === 'object' && value && typeof value === 'object' && deepEqual(oldValue, value, new WeakMap()))
|
|
23
|
-
return receiver;
|
|
24
|
-
target.set(key, value);
|
|
25
|
-
const newSize = target.size;
|
|
26
|
-
// optimize path calculation by caching concatenated paths
|
|
27
|
-
const pathKey = path.join('.');
|
|
28
|
-
let cachedPath = getPathConcat(pathKey);
|
|
29
|
-
if (cachedPath === undefined) {
|
|
30
|
-
cachedPath = path;
|
|
31
|
-
setPathConcat(pathKey, cachedPath);
|
|
32
|
-
}
|
|
33
|
-
const event = {
|
|
34
|
-
action: 'map-set',
|
|
35
|
-
path: cachedPath,
|
|
36
|
-
key,
|
|
37
|
-
oldValue,
|
|
38
|
-
newValue: value
|
|
39
|
-
};
|
|
40
|
-
emit(event);
|
|
41
|
-
// trigger effects based on whether it was an add or update
|
|
42
|
-
if (!existed) {
|
|
43
|
-
trigger(target, Symbol.iterator);
|
|
44
|
-
if (oldSize !== newSize) {
|
|
45
|
-
trigger(target, 'size');
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
trigger(target, String(key));
|
|
50
|
-
}
|
|
51
|
-
return receiver;
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
if (prop === 'delete') {
|
|
55
|
-
return function (key) {
|
|
56
|
-
const existed = target.has(key);
|
|
57
|
-
if (!existed)
|
|
58
|
-
return false;
|
|
59
|
-
const oldValue = target.get(key);
|
|
60
|
-
const oldSize = target.size;
|
|
61
|
-
const result = target.delete(key);
|
|
62
|
-
const newSize = target.size;
|
|
63
|
-
if (result) { // only emit and trigger if delete was successful
|
|
64
|
-
const pathKey = path.join('.');
|
|
65
|
-
let cachedPath = getPathConcat(pathKey);
|
|
66
|
-
if (cachedPath === undefined) {
|
|
67
|
-
cachedPath = path;
|
|
68
|
-
setPathConcat(pathKey, cachedPath);
|
|
69
|
-
}
|
|
70
|
-
const event = {
|
|
71
|
-
action: 'map-delete',
|
|
72
|
-
path: cachedPath,
|
|
73
|
-
key,
|
|
74
|
-
oldValue
|
|
75
|
-
};
|
|
76
|
-
emit(event);
|
|
77
|
-
trigger(target, Symbol.iterator);
|
|
78
|
-
if (oldSize !== newSize) {
|
|
79
|
-
trigger(target, 'size');
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
return result;
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
if (prop === 'clear') {
|
|
86
|
-
return function () {
|
|
87
|
-
const oldSize = target.size;
|
|
88
|
-
if (oldSize === 0)
|
|
89
|
-
return;
|
|
90
|
-
target.clear();
|
|
91
|
-
const newSize = target.size;
|
|
92
|
-
const event = {
|
|
93
|
-
action: 'map-clear',
|
|
94
|
-
path: path,
|
|
95
|
-
key: null
|
|
96
|
-
};
|
|
97
|
-
emit(event);
|
|
98
|
-
trigger(target, Symbol.iterator);
|
|
99
|
-
if (oldSize !== newSize) {
|
|
100
|
-
trigger(target, 'size');
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
if (prop === 'get') {
|
|
105
|
-
// return a function that tracks the specific key only when called
|
|
106
|
-
return function (key) {
|
|
107
|
-
track(target, String(key));
|
|
108
|
-
const value = target.get(key);
|
|
109
|
-
if (!value || typeof value !== 'object')
|
|
110
|
-
return value;
|
|
111
|
-
const cachedValueProxy = wrapperCache.get(value);
|
|
112
|
-
if (cachedValueProxy)
|
|
113
|
-
return cachedValueProxy;
|
|
114
|
-
const keyString = String(key);
|
|
115
|
-
const pathKey = path.length > 0 ? `${path.join('.')}.${keyString}` : keyString;
|
|
116
|
-
let newPath = getPathConcat(pathKey);
|
|
117
|
-
if (newPath === undefined) {
|
|
118
|
-
newPath = path.concat(keyString);
|
|
119
|
-
setPathConcat(pathKey, newPath);
|
|
120
|
-
}
|
|
121
|
-
// recursively wrap nested structures
|
|
122
|
-
if (value instanceof Map)
|
|
123
|
-
return wrapMap(value, emit, newPath);
|
|
124
|
-
if (value instanceof Set)
|
|
125
|
-
return wrapSet(value, emit, newPath);
|
|
126
|
-
if (Array.isArray(value))
|
|
127
|
-
return wrapArray(value, emit, newPath);
|
|
128
|
-
if (value instanceof Date)
|
|
129
|
-
return new Date(value.getTime()); // dates are not proxied, return a copy
|
|
130
|
-
return reactive(value, emit, newPath);
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
if (prop === 'has') {
|
|
134
|
-
track(target, Symbol.iterator);
|
|
135
|
-
return function (key) {
|
|
136
|
-
// track the specific key only when 'has' is called
|
|
137
|
-
track(target, String(key));
|
|
138
|
-
return target.has(key);
|
|
139
|
-
}.bind(target);
|
|
140
|
-
}
|
|
141
|
-
// handle iteration methods
|
|
142
|
-
if (prop === Symbol.iterator || prop === 'entries' || prop === 'values' || prop === 'keys' || prop === 'forEach') {
|
|
143
|
-
track(target, Symbol.iterator);
|
|
144
|
-
const originalMethod = Reflect.get(target, prop, receiver);
|
|
145
|
-
// return custom iterators/foreach that wrap values during iteration
|
|
146
|
-
if (prop === 'forEach') {
|
|
147
|
-
return (callbackfn, thisArg) => {
|
|
148
|
-
// use the proxied .entries() to ensure values passed to callback are wrapped and tracked
|
|
149
|
-
const entriesIterator = proxy.entries();
|
|
150
|
-
for (const [key, value] of entriesIterator) {
|
|
151
|
-
callbackfn.call(thisArg, value, key, proxy);
|
|
152
|
-
}
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
// handle symbol.iterator, entries, values, keys by creating generator functions
|
|
156
|
-
return function* (...args) {
|
|
157
|
-
const iterator = originalMethod.apply(target, args);
|
|
158
|
-
for (const entry of iterator) {
|
|
159
|
-
let keyToWrap = entry;
|
|
160
|
-
let valueToWrap = entry;
|
|
161
|
-
let isEntry = false;
|
|
162
|
-
if (prop === 'entries' || prop === Symbol.iterator) {
|
|
163
|
-
keyToWrap = entry[0];
|
|
164
|
-
valueToWrap = entry[1];
|
|
165
|
-
isEntry = true;
|
|
166
|
-
}
|
|
167
|
-
// wrap key if it's an object
|
|
168
|
-
// note: reactivity on map keys can be complex/unexpected
|
|
169
|
-
let wrappedKey = keyToWrap;
|
|
170
|
-
if (isEntry && keyToWrap && typeof keyToWrap === 'object') {
|
|
171
|
-
const pathKey = path.length > 0 ? `${path.join('.')}.${String(keyToWrap)}` : String(keyToWrap);
|
|
172
|
-
let keyPath = getPathConcat(pathKey);
|
|
173
|
-
if (keyPath === undefined) {
|
|
174
|
-
keyPath = path.concat(String(keyToWrap));
|
|
175
|
-
setPathConcat(pathKey, keyPath);
|
|
176
|
-
}
|
|
177
|
-
// todo: decide if map keys should be deeply reactive
|
|
178
|
-
wrappedKey = reactive(keyToWrap, emit, keyPath);
|
|
179
|
-
}
|
|
180
|
-
// wrap value if it's an object
|
|
181
|
-
let wrappedValue = valueToWrap;
|
|
182
|
-
if (valueToWrap && typeof valueToWrap === 'object') {
|
|
183
|
-
const cachedValueProxy = wrapperCache.get(valueToWrap);
|
|
184
|
-
if (cachedValueProxy) {
|
|
185
|
-
wrappedValue = cachedValueProxy;
|
|
186
|
-
}
|
|
187
|
-
else {
|
|
188
|
-
const keyString = String(keyToWrap); // use original key for path
|
|
189
|
-
const pathKey = path.length > 0 ? `${path.join('.')}.${keyString}` : keyString;
|
|
190
|
-
let newPath = getPathConcat(pathKey);
|
|
191
|
-
if (newPath === undefined) {
|
|
192
|
-
newPath = path.concat(keyString);
|
|
193
|
-
setPathConcat(pathKey, newPath);
|
|
194
|
-
}
|
|
195
|
-
if (valueToWrap instanceof Map)
|
|
196
|
-
wrappedValue = wrapMap(valueToWrap, emit, newPath);
|
|
197
|
-
else if (valueToWrap instanceof Set)
|
|
198
|
-
wrappedValue = wrapSet(valueToWrap, emit, newPath);
|
|
199
|
-
else if (Array.isArray(valueToWrap))
|
|
200
|
-
wrappedValue = wrapArray(valueToWrap, emit, newPath);
|
|
201
|
-
else if (valueToWrap instanceof Date)
|
|
202
|
-
wrappedValue = new Date(valueToWrap.getTime());
|
|
203
|
-
else
|
|
204
|
-
wrappedValue = reactive(valueToWrap, emit, newPath);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
if (prop === 'entries' || prop === Symbol.iterator) {
|
|
208
|
-
yield [wrappedKey, wrappedValue];
|
|
209
|
-
}
|
|
210
|
-
else if (prop === 'values') {
|
|
211
|
-
yield wrappedValue;
|
|
212
|
-
}
|
|
213
|
-
else { // keys
|
|
214
|
-
yield wrappedKey;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
if (prop === 'size') {
|
|
220
|
-
track(target, 'size');
|
|
221
|
-
return target.size;
|
|
222
|
-
}
|
|
223
|
-
const value = Reflect.get(target, prop, receiver);
|
|
224
|
-
return value;
|
|
225
|
-
}
|
|
226
|
-
});
|
|
227
|
-
// cache the newly created proxy before returning
|
|
228
|
-
wrapperCache.set(map, proxy);
|
|
229
|
-
return proxy;
|
|
230
|
-
}
|
package/dist/wrapSet.d.ts
DELETED
package/dist/wrapSet.js
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import { getPathConcat, setPathConcat, wrapperCache } from './utils';
|
|
2
|
-
import { reactive } from './reactive';
|
|
3
|
-
import { wrapArray } from './wrap-array';
|
|
4
|
-
import { wrapMap } from './wrap-map';
|
|
5
|
-
import { track, trigger } from './watch-effect';
|
|
6
|
-
export function wrapSet(set, emit, path) {
|
|
7
|
-
// reuse existing proxy if available for performance
|
|
8
|
-
const cachedProxy = wrapperCache.get(set);
|
|
9
|
-
if (cachedProxy)
|
|
10
|
-
return cachedProxy;
|
|
11
|
-
const proxy = new Proxy(set, {
|
|
12
|
-
get(target, prop, receiver) {
|
|
13
|
-
track(target, prop);
|
|
14
|
-
if (prop === 'add') {
|
|
15
|
-
return function (value) {
|
|
16
|
-
const existed = target.has(value);
|
|
17
|
-
const oldSize = target.size;
|
|
18
|
-
// only add and trigger if the value doesn't already exist
|
|
19
|
-
if (!existed) {
|
|
20
|
-
target.add(value);
|
|
21
|
-
const newSize = target.size;
|
|
22
|
-
const event = {
|
|
23
|
-
action: 'set-add',
|
|
24
|
-
path: path,
|
|
25
|
-
value: value
|
|
26
|
-
};
|
|
27
|
-
emit(event);
|
|
28
|
-
trigger(target, Symbol.iterator);
|
|
29
|
-
if (oldSize !== newSize) {
|
|
30
|
-
trigger(target, 'size');
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
return receiver; // return the proxy itself for chaining
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
if (prop === 'delete') {
|
|
37
|
-
return function (value) {
|
|
38
|
-
const existed = target.has(value);
|
|
39
|
-
const oldSize = target.size;
|
|
40
|
-
if (existed) {
|
|
41
|
-
const oldValue = value;
|
|
42
|
-
const result = target.delete(value);
|
|
43
|
-
const newSize = target.size;
|
|
44
|
-
if (result) { // only emit and trigger if delete was successful
|
|
45
|
-
const event = {
|
|
46
|
-
action: 'set-delete',
|
|
47
|
-
path: path,
|
|
48
|
-
value: value,
|
|
49
|
-
oldValue: oldValue
|
|
50
|
-
};
|
|
51
|
-
emit(event);
|
|
52
|
-
trigger(target, Symbol.iterator);
|
|
53
|
-
if (oldSize !== newSize) {
|
|
54
|
-
trigger(target, 'size');
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return result;
|
|
58
|
-
}
|
|
59
|
-
return false;
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
if (prop === 'clear') {
|
|
63
|
-
return function () {
|
|
64
|
-
const oldSize = target.size;
|
|
65
|
-
if (oldSize === 0)
|
|
66
|
-
return;
|
|
67
|
-
target.clear();
|
|
68
|
-
const newSize = target.size;
|
|
69
|
-
const event = {
|
|
70
|
-
action: 'set-clear',
|
|
71
|
-
path: path,
|
|
72
|
-
value: null
|
|
73
|
-
};
|
|
74
|
-
emit(event);
|
|
75
|
-
trigger(target, Symbol.iterator);
|
|
76
|
-
if (oldSize !== newSize) {
|
|
77
|
-
trigger(target, 'size');
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
if (prop === 'has') {
|
|
82
|
-
track(target, Symbol.iterator);
|
|
83
|
-
return function (value) {
|
|
84
|
-
// track specific primitive value when 'has' is called
|
|
85
|
-
// tracking object values for existence is complex and less common, handled by iteration track
|
|
86
|
-
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'symbol') {
|
|
87
|
-
track(target, String(value));
|
|
88
|
-
}
|
|
89
|
-
return target.has(value);
|
|
90
|
-
}.bind(target);
|
|
91
|
-
}
|
|
92
|
-
// handle iteration methods
|
|
93
|
-
if (prop === 'values' || prop === Symbol.iterator || prop === 'entries' || prop === 'keys' || prop === 'forEach') {
|
|
94
|
-
track(target, Symbol.iterator);
|
|
95
|
-
const originalMethod = Reflect.get(target, prop, receiver);
|
|
96
|
-
// return custom iterators/foreach that wrap values during iteration
|
|
97
|
-
if (prop === 'forEach') {
|
|
98
|
-
return (callbackfn, thisArg) => {
|
|
99
|
-
// use the proxied values() to ensure values passed to callback are wrapped and tracked
|
|
100
|
-
const valuesIterator = proxy.values();
|
|
101
|
-
for (const value of valuesIterator) {
|
|
102
|
-
callbackfn.call(thisArg, value, value, proxy);
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
// handle symbol.iterator, values, keys, entries by creating generator functions
|
|
107
|
-
return function* (...args) {
|
|
108
|
-
let index = 0; // use index for path generation if value is not primitive
|
|
109
|
-
const iterator = originalMethod.apply(target, args);
|
|
110
|
-
for (const entry of iterator) {
|
|
111
|
-
let valueToWrap = entry;
|
|
112
|
-
let mapKey = undefined; // key for entries() which yields [value, value]
|
|
113
|
-
if (prop === 'entries') {
|
|
114
|
-
mapKey = entry[0]; // for Set.entries(), key and value are the same
|
|
115
|
-
valueToWrap = entry[1];
|
|
116
|
-
}
|
|
117
|
-
track(target, String(index));
|
|
118
|
-
let wrappedValue = valueToWrap;
|
|
119
|
-
if (valueToWrap && typeof valueToWrap === 'object') {
|
|
120
|
-
const cachedValueProxy = wrapperCache.get(valueToWrap);
|
|
121
|
-
if (cachedValueProxy) {
|
|
122
|
-
wrappedValue = cachedValueProxy;
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
// calculate path using index as key, as set values don't have inherent keys
|
|
126
|
-
const keyForPath = String(index);
|
|
127
|
-
const pathKey = path.length > 0 ? `${path.join('.')}.${keyForPath}` : keyForPath;
|
|
128
|
-
let newPath = getPathConcat(pathKey);
|
|
129
|
-
if (newPath === undefined) {
|
|
130
|
-
newPath = path.concat(keyForPath);
|
|
131
|
-
setPathConcat(pathKey, newPath);
|
|
132
|
-
}
|
|
133
|
-
// recursively wrap nested structures
|
|
134
|
-
if (valueToWrap instanceof Map)
|
|
135
|
-
wrappedValue = wrapMap(valueToWrap, emit, newPath);
|
|
136
|
-
else if (valueToWrap instanceof Set)
|
|
137
|
-
wrappedValue = wrapSet(valueToWrap, emit, newPath);
|
|
138
|
-
else if (Array.isArray(valueToWrap))
|
|
139
|
-
wrappedValue = wrapArray(valueToWrap, emit, newPath);
|
|
140
|
-
else if (valueToWrap instanceof Date)
|
|
141
|
-
wrappedValue = new Date(valueToWrap.getTime()); // dates are not proxied, return copy
|
|
142
|
-
else
|
|
143
|
-
wrappedValue = reactive(valueToWrap, emit, newPath);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
if (prop === 'entries') {
|
|
147
|
-
yield [wrappedValue, wrappedValue]; // set entries yield [value, value]
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
yield wrappedValue;
|
|
151
|
-
}
|
|
152
|
-
index++;
|
|
153
|
-
}
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
if (prop === 'size') {
|
|
157
|
-
track(target, 'size');
|
|
158
|
-
return target.size;
|
|
159
|
-
}
|
|
160
|
-
const value = Reflect.get(target, prop, receiver);
|
|
161
|
-
return value;
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
// cache the newly created proxy before returning
|
|
165
|
-
wrapperCache.set(set, proxy);
|
|
166
|
-
return proxy;
|
|
167
|
-
}
|