r-state-tree 0.5.0 → 0.6.1
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/README.md +291 -69
- package/dist/index.d.ts +4 -3
- package/dist/model/ChildModelsAdministration.d.ts +1 -1
- package/dist/observables/array.d.ts +6 -3
- package/dist/observables/collection.d.ts +10 -14
- package/dist/observables/index.d.ts +2 -2
- package/dist/observables/internal/Administration.d.ts +2 -3
- package/dist/observables/internal/NodeMap.d.ts +1 -0
- package/dist/observables/internal/lookup.d.ts +3 -2
- package/dist/observables/internal/utils.d.ts +1 -1
- package/dist/observables/object.d.ts +5 -4
- package/dist/observables/preact.d.ts +6 -22
- package/dist/r-state-tree.cjs +776 -384
- package/dist/r-state-tree.js +790 -395
- package/dist/toObservableTree.d.ts +1 -0
- package/dist/types.d.ts +5 -11
- package/dist/utils.d.ts +1 -1
- package/package.json +1 -1
- package/dist/computedProxy.d.ts +0 -2
package/dist/r-state-tree.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { batch,
|
|
2
|
-
import { Signal as Signal2, batch as batch2, effect as effect2,
|
|
1
|
+
import { batch, signal as signal$1, Signal, computed as computed$1, untracked, effect } from "@preact/signals-core";
|
|
2
|
+
import { Signal as Signal2, batch as batch2, effect as effect2, untracked as untracked2 } from "@preact/signals-core";
|
|
3
3
|
var lib = {};
|
|
4
4
|
var hasRequiredLib;
|
|
5
5
|
function requireLib() {
|
|
@@ -16,8 +16,6 @@ var CommonCfgTypes = /* @__PURE__ */ ((CommonCfgTypes2) => {
|
|
|
16
16
|
})(CommonCfgTypes || {});
|
|
17
17
|
var ModelCfgTypes = /* @__PURE__ */ ((ModelCfgTypes2) => {
|
|
18
18
|
ModelCfgTypes2["state"] = "state";
|
|
19
|
-
ModelCfgTypes2["stateShallow"] = "stateShallow";
|
|
20
|
-
ModelCfgTypes2["stateSignal"] = "stateSignal";
|
|
21
19
|
ModelCfgTypes2["id"] = "id";
|
|
22
20
|
ModelCfgTypes2["modelRef"] = "modelRef";
|
|
23
21
|
return ModelCfgTypes2;
|
|
@@ -27,9 +25,6 @@ var StoreCfgTypes = /* @__PURE__ */ ((StoreCfgTypes2) => {
|
|
|
27
25
|
return StoreCfgTypes2;
|
|
28
26
|
})(StoreCfgTypes || {});
|
|
29
27
|
var ObservableCfgTypes = /* @__PURE__ */ ((ObservableCfgTypes2) => {
|
|
30
|
-
ObservableCfgTypes2["observable"] = "observable";
|
|
31
|
-
ObservableCfgTypes2["observableShallow"] = "observableShallow";
|
|
32
|
-
ObservableCfgTypes2["observableSignal"] = "observableSignal";
|
|
33
28
|
ObservableCfgTypes2["computed"] = "computed";
|
|
34
29
|
return ObservableCfgTypes2;
|
|
35
30
|
})(ObservableCfgTypes || {});
|
|
@@ -46,14 +41,6 @@ const stateType = {
|
|
|
46
41
|
type: "state"
|
|
47
42
|
/* state */
|
|
48
43
|
};
|
|
49
|
-
const stateShallowType = {
|
|
50
|
-
type: "stateShallow"
|
|
51
|
-
/* stateShallow */
|
|
52
|
-
};
|
|
53
|
-
const stateSignalType = {
|
|
54
|
-
type: "stateSignal"
|
|
55
|
-
/* stateSignal */
|
|
56
|
-
};
|
|
57
44
|
const modelRefType = Object.assign(
|
|
58
45
|
function(childType2) {
|
|
59
46
|
return { type: "modelRef", childType: childType2 };
|
|
@@ -78,32 +65,29 @@ function isPropertyKey(val) {
|
|
|
78
65
|
return typeof val === "string" || typeof val === "number" || typeof val === "symbol";
|
|
79
66
|
}
|
|
80
67
|
function getPropertyType(key, obj) {
|
|
81
|
-
const
|
|
68
|
+
const ctor = obj.constructor;
|
|
69
|
+
const hasMetadata = ctor != null && ctor[Symbol.metadata] !== void 0;
|
|
82
70
|
const descriptor = getPropertyDescriptor$1(obj, key);
|
|
83
71
|
if (descriptor?.value && typeof descriptor.value === "function") {
|
|
84
72
|
return "action";
|
|
85
73
|
}
|
|
86
|
-
const
|
|
74
|
+
const isAccessor = descriptor && (typeof descriptor.get === "function" || typeof descriptor.set === "function");
|
|
87
75
|
if (!hasMetadata) {
|
|
88
|
-
if (
|
|
76
|
+
if (descriptor?.get) {
|
|
89
77
|
return "computed";
|
|
90
78
|
}
|
|
79
|
+
if (isAccessor) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
91
82
|
return "observable";
|
|
92
83
|
}
|
|
93
84
|
const metadata = obj.constructor[Symbol.metadata];
|
|
94
|
-
|
|
95
|
-
|
|
85
|
+
const config = metadata?.[key];
|
|
86
|
+
if (config) {
|
|
96
87
|
switch (config.type) {
|
|
97
88
|
case ObservableCfgTypes.computed:
|
|
98
89
|
return "computed";
|
|
99
|
-
case ObservableCfgTypes.observableShallow:
|
|
100
|
-
case ModelCfgTypes.stateShallow:
|
|
101
|
-
return "observableShallow";
|
|
102
|
-
case ObservableCfgTypes.observableSignal:
|
|
103
|
-
case ModelCfgTypes.stateSignal:
|
|
104
|
-
return "observableSignal";
|
|
105
90
|
case ModelCfgTypes.state:
|
|
106
|
-
case ObservableCfgTypes.observable:
|
|
107
91
|
case ModelCfgTypes.id:
|
|
108
92
|
case ModelCfgTypes.modelRef:
|
|
109
93
|
case CommonCfgTypes.child:
|
|
@@ -111,7 +95,7 @@ function getPropertyType(key, obj) {
|
|
|
111
95
|
return "observable";
|
|
112
96
|
}
|
|
113
97
|
}
|
|
114
|
-
return null;
|
|
98
|
+
return isAccessor ? null : "observable";
|
|
115
99
|
}
|
|
116
100
|
function getPropertyDescriptor$1(obj, key) {
|
|
117
101
|
let node = obj;
|
|
@@ -140,7 +124,7 @@ class Administration {
|
|
|
140
124
|
atom;
|
|
141
125
|
valuesMap;
|
|
142
126
|
isObserved = false;
|
|
143
|
-
|
|
127
|
+
forceObservedAtom;
|
|
144
128
|
constructor(source2) {
|
|
145
129
|
this.atom = createObservedAtom();
|
|
146
130
|
this.source = source2;
|
|
@@ -150,13 +134,9 @@ class Administration {
|
|
|
150
134
|
);
|
|
151
135
|
}
|
|
152
136
|
flushChange() {
|
|
153
|
-
if (this.
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
this.forceObservedAtoms[i].reportChanged();
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
this.forceObservedAtoms = void 0;
|
|
137
|
+
if (this.forceObservedAtom) {
|
|
138
|
+
this.forceObservedAtom.reportChanged();
|
|
139
|
+
this.forceObservedAtom = void 0;
|
|
160
140
|
}
|
|
161
141
|
}
|
|
162
142
|
getNode() {
|
|
@@ -165,9 +145,7 @@ class Administration {
|
|
|
165
145
|
reportChanged() {
|
|
166
146
|
this.atom.reportChanged();
|
|
167
147
|
}
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
reportObserved(deep = false) {
|
|
148
|
+
reportObserved() {
|
|
171
149
|
const entry = circularRefSet == null;
|
|
172
150
|
if (entry) {
|
|
173
151
|
circularRefSet = /* @__PURE__ */ new WeakSet();
|
|
@@ -175,15 +153,10 @@ class Administration {
|
|
|
175
153
|
return;
|
|
176
154
|
}
|
|
177
155
|
circularRefSet.add(this);
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
this.forceObservedAtoms = [];
|
|
181
|
-
}
|
|
182
|
-
this.forceObservedAtoms.push(atom);
|
|
183
|
-
atom.reportObserved();
|
|
184
|
-
if (deep) {
|
|
185
|
-
this.reportObserveDeep();
|
|
156
|
+
if (!this.forceObservedAtom) {
|
|
157
|
+
this.forceObservedAtom = createAtom();
|
|
186
158
|
}
|
|
159
|
+
this.forceObservedAtom.reportObserved();
|
|
187
160
|
if (entry) {
|
|
188
161
|
circularRefSet = null;
|
|
189
162
|
}
|
|
@@ -246,6 +219,9 @@ class NodeMap {
|
|
|
246
219
|
reportChanged(key, value) {
|
|
247
220
|
return this.get(key)?.reportChanged(value);
|
|
248
221
|
}
|
|
222
|
+
keys() {
|
|
223
|
+
return this.map?.keys() ?? [];
|
|
224
|
+
}
|
|
249
225
|
}
|
|
250
226
|
class AtomMap extends NodeMap {
|
|
251
227
|
createNode() {
|
|
@@ -263,31 +239,34 @@ class ObjectAdministration extends Administration {
|
|
|
263
239
|
valuesMap;
|
|
264
240
|
computedMap;
|
|
265
241
|
types;
|
|
242
|
+
isWriting = false;
|
|
266
243
|
static proxyTraps = {
|
|
267
244
|
has(target, name) {
|
|
268
245
|
const adm = getAdministration(target);
|
|
269
|
-
if (!(name in Object.prototype)
|
|
246
|
+
if (isPropertyKey(name) && (!(name in Object.prototype) || Object.prototype.hasOwnProperty.call(adm.source, name)))
|
|
270
247
|
return adm.has(name);
|
|
271
248
|
return Reflect.has(adm.source, name);
|
|
272
249
|
},
|
|
273
250
|
get(target, name) {
|
|
274
251
|
const adm = getAdministration(target);
|
|
275
|
-
if (!(name in Object.prototype)
|
|
276
|
-
return adm.read(name);
|
|
252
|
+
if (isPropertyKey(name) && (!(name in Object.prototype) || Object.prototype.hasOwnProperty.call(adm.source, name)) && (typeof adm.source !== "function" || name !== "prototype")) {
|
|
253
|
+
return adm.read(name, arguments[2]);
|
|
277
254
|
}
|
|
278
|
-
return Reflect.get(adm.source, name,
|
|
255
|
+
return Reflect.get(adm.source, name, arguments[2]);
|
|
279
256
|
},
|
|
280
257
|
set(target, name, value) {
|
|
281
258
|
if (!isPropertyKey(name)) return false;
|
|
282
259
|
const adm = getAdministration(target);
|
|
283
|
-
|
|
284
|
-
|
|
260
|
+
const receiver = arguments[3];
|
|
261
|
+
if (receiver === adm.proxy) {
|
|
262
|
+
return adm.write(name, value);
|
|
263
|
+
}
|
|
264
|
+
return Reflect.set(adm.source, name, value, receiver);
|
|
285
265
|
},
|
|
286
266
|
deleteProperty(target, name) {
|
|
287
267
|
if (!isPropertyKey(name)) return false;
|
|
288
268
|
const adm = getAdministration(target);
|
|
289
|
-
adm.remove(name);
|
|
290
|
-
return true;
|
|
269
|
+
return adm.remove(name);
|
|
291
270
|
},
|
|
292
271
|
ownKeys(target) {
|
|
293
272
|
const adm = getAdministration(target);
|
|
@@ -296,22 +275,46 @@ class ObjectAdministration extends Administration {
|
|
|
296
275
|
adm.atom.reportObserved();
|
|
297
276
|
});
|
|
298
277
|
return Reflect.ownKeys(adm.source);
|
|
278
|
+
},
|
|
279
|
+
defineProperty(target, name, descriptor) {
|
|
280
|
+
const adm = getAdministration(target);
|
|
281
|
+
if (adm.isWriting) {
|
|
282
|
+
return Reflect.defineProperty(adm.source, name, descriptor);
|
|
283
|
+
}
|
|
284
|
+
const result = Reflect.defineProperty(adm.source, name, descriptor);
|
|
285
|
+
if (result) {
|
|
286
|
+
batch(() => {
|
|
287
|
+
adm.types.delete(name);
|
|
288
|
+
adm.flushChange();
|
|
289
|
+
adm.keysAtom.reportChanged();
|
|
290
|
+
adm.hasMap.reportChanged(name);
|
|
291
|
+
if ("value" in descriptor) {
|
|
292
|
+
if (isObservable(descriptor.value)) {
|
|
293
|
+
adm.explicitObservables.add(name);
|
|
294
|
+
} else {
|
|
295
|
+
adm.explicitObservables.delete(name);
|
|
296
|
+
}
|
|
297
|
+
adm.valuesMap.reportChanged(name, descriptor.value);
|
|
298
|
+
} else {
|
|
299
|
+
adm.valuesMap.reportChanged(name, void 0);
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
return result;
|
|
299
304
|
}
|
|
300
305
|
};
|
|
301
306
|
constructor(source2 = {}) {
|
|
302
307
|
super(source2);
|
|
303
308
|
this.keysAtom = createAtom();
|
|
304
309
|
this.hasMap = new AtomMap(this.atom);
|
|
305
|
-
this.valuesMap = new SignalMap();
|
|
310
|
+
this.valuesMap = new SignalMap(this.atom);
|
|
306
311
|
this.types = /* @__PURE__ */ new Map();
|
|
307
312
|
}
|
|
308
313
|
get(key) {
|
|
309
314
|
return Reflect.get(this.source, key, this.proxy);
|
|
310
315
|
}
|
|
311
316
|
set(key, value) {
|
|
312
|
-
batch(() =>
|
|
313
|
-
Reflect.set(this.source, key, value, this.proxy);
|
|
314
|
-
});
|
|
317
|
+
return batch(() => Reflect.set(this.source, key, value, this.proxy));
|
|
315
318
|
}
|
|
316
319
|
getComputed(key) {
|
|
317
320
|
if (!this.computedMap) this.computedMap = /* @__PURE__ */ new Map();
|
|
@@ -338,17 +341,6 @@ class ObjectAdministration extends Administration {
|
|
|
338
341
|
}
|
|
339
342
|
return type;
|
|
340
343
|
}
|
|
341
|
-
reportObserveDeep() {
|
|
342
|
-
Object.getOwnPropertyNames(this.source).forEach((name) => {
|
|
343
|
-
const type = this.getType(name);
|
|
344
|
-
if (type === "observable") {
|
|
345
|
-
const value = this.source[name];
|
|
346
|
-
if (value && typeof value === "object") {
|
|
347
|
-
getAdministration(getObservable(value))?.reportObserved();
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
});
|
|
351
|
-
}
|
|
352
344
|
reportChanged() {
|
|
353
345
|
this.types.clear();
|
|
354
346
|
super.reportChanged();
|
|
@@ -363,14 +355,13 @@ class ObjectAdministration extends Administration {
|
|
|
363
355
|
}
|
|
364
356
|
return resolveNode(this.valuesMap.getOrCreate(key, this.source[key]));
|
|
365
357
|
}
|
|
366
|
-
read(key) {
|
|
358
|
+
read(key, receiver = this.proxy) {
|
|
367
359
|
const type = this.getType(key);
|
|
368
360
|
if (type === null) {
|
|
369
|
-
return
|
|
361
|
+
return Reflect.get(this.source, key, receiver);
|
|
370
362
|
}
|
|
371
363
|
switch (type) {
|
|
372
364
|
case "observable":
|
|
373
|
-
case "observableShallow":
|
|
374
365
|
case "action": {
|
|
375
366
|
if (key in this.source) {
|
|
376
367
|
this.valuesMap.reportObserved(key, this.source[key]);
|
|
@@ -380,48 +371,66 @@ class ObjectAdministration extends Administration {
|
|
|
380
371
|
this.hasMap.reportObserved(key);
|
|
381
372
|
}
|
|
382
373
|
if (type === "observable") {
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
374
|
+
const value = Reflect.get(this.source, key, receiver);
|
|
375
|
+
const shouldWrap = this.explicitObservables.has(key) || isObservable(value);
|
|
376
|
+
if (shouldWrap && value && typeof value === "object" && !Object.isFrozen(value)) {
|
|
377
|
+
const desc = getPropertyDescriptor$1(this.source, key);
|
|
378
|
+
if (desc && !desc.configurable && !desc.writable) {
|
|
379
|
+
return value;
|
|
380
|
+
}
|
|
381
|
+
const existingAdm = getAdministration(value);
|
|
382
|
+
if (existingAdm) {
|
|
383
|
+
return existingAdm.proxy;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
return value;
|
|
387
387
|
}
|
|
388
|
-
return getAction(
|
|
388
|
+
return getAction(
|
|
389
|
+
Reflect.get(this.source, key, receiver)
|
|
390
|
+
);
|
|
389
391
|
}
|
|
390
|
-
case "
|
|
391
|
-
if (
|
|
392
|
-
this.
|
|
392
|
+
case "computed": {
|
|
393
|
+
if (receiver === this.proxy) {
|
|
394
|
+
return this.callComputed(key);
|
|
393
395
|
}
|
|
394
396
|
this.atom.reportObserved();
|
|
395
|
-
|
|
396
|
-
this.hasMap.reportObserved(key);
|
|
397
|
-
}
|
|
398
|
-
return this.get(key);
|
|
399
|
-
}
|
|
400
|
-
case "computed": {
|
|
401
|
-
return this.callComputed(key);
|
|
397
|
+
return Reflect.get(this.source, key, receiver);
|
|
402
398
|
}
|
|
403
399
|
default:
|
|
404
400
|
throw new Error(`unknown type passed to configure`);
|
|
405
401
|
}
|
|
406
402
|
}
|
|
403
|
+
explicitObservables = /* @__PURE__ */ new Set();
|
|
407
404
|
write(key, newValue) {
|
|
408
405
|
const type = this.getType(key);
|
|
409
406
|
if (type === null) {
|
|
410
|
-
this.set(key, newValue);
|
|
411
|
-
return;
|
|
407
|
+
return this.set(key, newValue);
|
|
412
408
|
}
|
|
413
409
|
if (type === "computed") {
|
|
414
|
-
batch(() => this.set(key, newValue));
|
|
415
|
-
return;
|
|
410
|
+
return batch(() => this.set(key, newValue));
|
|
416
411
|
}
|
|
417
412
|
const had = key in this.source;
|
|
418
413
|
const oldValue = this.get(key);
|
|
419
414
|
const targetValue = getSource(newValue);
|
|
415
|
+
const oldExplicit = this.explicitObservables.has(key);
|
|
416
|
+
const newExplicit = isObservable(newValue);
|
|
417
|
+
if (newExplicit) {
|
|
418
|
+
this.explicitObservables.add(key);
|
|
419
|
+
} else {
|
|
420
|
+
this.explicitObservables.delete(key);
|
|
421
|
+
}
|
|
420
422
|
if (type === "action" && typeof newValue !== "function" || type === "observable" && typeof newValue === "function") {
|
|
421
423
|
this.types.delete(key);
|
|
422
424
|
}
|
|
423
|
-
|
|
424
|
-
|
|
425
|
+
const changed = !had || !isObservable(oldValue) && oldExplicit !== newExplicit || (isObservable(oldValue) ? oldValue !== newValue : oldValue !== targetValue);
|
|
426
|
+
if (changed) {
|
|
427
|
+
this.isWriting = true;
|
|
428
|
+
try {
|
|
429
|
+
const result = this.set(key, targetValue);
|
|
430
|
+
if (!result) return false;
|
|
431
|
+
} finally {
|
|
432
|
+
this.isWriting = false;
|
|
433
|
+
}
|
|
425
434
|
batch(() => {
|
|
426
435
|
this.flushChange();
|
|
427
436
|
if (!had) {
|
|
@@ -430,7 +439,9 @@ class ObjectAdministration extends Administration {
|
|
|
430
439
|
}
|
|
431
440
|
this.valuesMap.reportChanged(key, newValue);
|
|
432
441
|
});
|
|
442
|
+
return true;
|
|
433
443
|
}
|
|
444
|
+
return true;
|
|
434
445
|
}
|
|
435
446
|
has(key) {
|
|
436
447
|
this.atom.reportObserved();
|
|
@@ -440,39 +451,27 @@ class ObjectAdministration extends Administration {
|
|
|
440
451
|
return key in this.source;
|
|
441
452
|
}
|
|
442
453
|
remove(key) {
|
|
443
|
-
if (!(key in this.source)) return;
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
454
|
+
if (!(key in this.source)) return true;
|
|
455
|
+
const result = Reflect.deleteProperty(this.source, key);
|
|
456
|
+
if (result) {
|
|
457
|
+
batch(() => {
|
|
458
|
+
this.flushChange();
|
|
459
|
+
this.valuesMap.reportChanged(key, void 0);
|
|
460
|
+
this.keysAtom.reportChanged();
|
|
461
|
+
this.hasMap.reportChanged(key);
|
|
462
|
+
this.valuesMap.delete(key);
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
return result;
|
|
452
466
|
}
|
|
453
467
|
}
|
|
454
468
|
class PreactObjectAdministration extends ObjectAdministration {
|
|
455
|
-
static proxyTraps = Object.assign(
|
|
456
|
-
{},
|
|
457
|
-
ObjectAdministration.proxyTraps,
|
|
458
|
-
{
|
|
459
|
-
get(target, prop, proxy) {
|
|
460
|
-
if (!(prop in target) && (typeof prop === "string" || typeof prop === "number") && String(prop)[0] === "$") {
|
|
461
|
-
return getSignal(proxy, prop.substring(1));
|
|
462
|
-
}
|
|
463
|
-
return ObjectAdministration.proxyTraps.get?.apply(
|
|
464
|
-
null,
|
|
465
|
-
arguments
|
|
466
|
-
);
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
);
|
|
470
469
|
}
|
|
471
470
|
function createObservedAtom() {
|
|
472
471
|
let value = 0;
|
|
473
472
|
const callbacks = /* @__PURE__ */ new Set();
|
|
474
473
|
let observing = false;
|
|
475
|
-
const
|
|
474
|
+
const signal2 = new Signal(value, {
|
|
476
475
|
watched() {
|
|
477
476
|
callbacks.forEach((callback) => callback(true));
|
|
478
477
|
observing = true;
|
|
@@ -483,12 +482,12 @@ function createObservedAtom() {
|
|
|
483
482
|
}
|
|
484
483
|
});
|
|
485
484
|
return {
|
|
486
|
-
node:
|
|
485
|
+
node: signal2,
|
|
487
486
|
reportObserved() {
|
|
488
|
-
return
|
|
487
|
+
return signal2.value;
|
|
489
488
|
},
|
|
490
489
|
reportChanged() {
|
|
491
|
-
return
|
|
490
|
+
return signal2.value = ++value;
|
|
492
491
|
},
|
|
493
492
|
get observing() {
|
|
494
493
|
return observing;
|
|
@@ -502,7 +501,7 @@ function createObservedAtom() {
|
|
|
502
501
|
};
|
|
503
502
|
}
|
|
504
503
|
function createSignal(initialValue) {
|
|
505
|
-
const s = signal(initialValue);
|
|
504
|
+
const s = signal$1(initialValue);
|
|
506
505
|
return {
|
|
507
506
|
node: s,
|
|
508
507
|
reportChanged(value) {
|
|
@@ -521,7 +520,7 @@ function createSignal(initialValue) {
|
|
|
521
520
|
}
|
|
522
521
|
function createAtom() {
|
|
523
522
|
let value = 0;
|
|
524
|
-
const s = signal(value);
|
|
523
|
+
const s = signal$1(value);
|
|
525
524
|
return {
|
|
526
525
|
node: s,
|
|
527
526
|
reportChanged() {
|
|
@@ -604,31 +603,12 @@ function createComputed(fn, context = null) {
|
|
|
604
603
|
}
|
|
605
604
|
};
|
|
606
605
|
}
|
|
607
|
-
function
|
|
608
|
-
|
|
609
|
-
context.metadata[context.name] = { type: "observable" };
|
|
610
|
-
return value;
|
|
611
|
-
}
|
|
612
|
-
return getObservable(value);
|
|
613
|
-
}
|
|
614
|
-
function shallowDecorator(value, context) {
|
|
615
|
-
if (context && typeof context === "object" && "kind" in context) {
|
|
616
|
-
context.metadata[context.name] = { type: "observableShallow" };
|
|
617
|
-
return value;
|
|
618
|
-
}
|
|
619
|
-
throw new Error("observable.shallow can only be used as a decorator");
|
|
606
|
+
function observable(obj) {
|
|
607
|
+
return getObservable(obj);
|
|
620
608
|
}
|
|
621
|
-
function
|
|
622
|
-
|
|
623
|
-
context.metadata[context.name] = { type: "observableSignal" };
|
|
624
|
-
return value;
|
|
625
|
-
}
|
|
626
|
-
throw new Error("observable.signal can only be used as a decorator");
|
|
609
|
+
function signal(value) {
|
|
610
|
+
return signal$1(value);
|
|
627
611
|
}
|
|
628
|
-
const observable = Object.assign(observableImpl, {
|
|
629
|
-
shallow: shallowDecorator,
|
|
630
|
-
signal: signalDecorator
|
|
631
|
-
});
|
|
632
612
|
function computed(value, context) {
|
|
633
613
|
if (context && typeof context === "object" && "kind" in context) {
|
|
634
614
|
context.metadata[context.name] = { type: "computed" };
|
|
@@ -639,29 +619,24 @@ function computed(value, context) {
|
|
|
639
619
|
function source(obj) {
|
|
640
620
|
return getSource(obj);
|
|
641
621
|
}
|
|
642
|
-
class Observable {
|
|
643
|
-
constructor() {
|
|
644
|
-
return getObservableClassInstance(this);
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
622
|
function reportChanged(obj) {
|
|
648
623
|
const adm = getAdministration(obj);
|
|
649
624
|
adm.reportChanged();
|
|
650
625
|
return obj;
|
|
651
626
|
}
|
|
652
|
-
function reportObserved(obj
|
|
627
|
+
function reportObserved(obj) {
|
|
653
628
|
const adm = getAdministration(obj);
|
|
654
|
-
adm.reportObserved(
|
|
629
|
+
adm.reportObserved();
|
|
655
630
|
return obj;
|
|
656
631
|
}
|
|
657
632
|
const signalMap = /* @__PURE__ */ new WeakMap();
|
|
658
633
|
function getSignal(obj, key) {
|
|
659
634
|
const node = getInternalNode(obj, key);
|
|
660
635
|
if (node instanceof Signal) {
|
|
661
|
-
let
|
|
662
|
-
if (!
|
|
663
|
-
|
|
664
|
-
Object.defineProperties(
|
|
636
|
+
let signal2 = signalMap.get(node);
|
|
637
|
+
if (!signal2) {
|
|
638
|
+
signal2 = new Signal();
|
|
639
|
+
Object.defineProperties(signal2, {
|
|
665
640
|
value: {
|
|
666
641
|
get() {
|
|
667
642
|
return obj[key];
|
|
@@ -676,9 +651,9 @@ function getSignal(obj, key) {
|
|
|
676
651
|
}
|
|
677
652
|
}
|
|
678
653
|
});
|
|
679
|
-
signalMap.set(node,
|
|
654
|
+
signalMap.set(node, signal2);
|
|
680
655
|
}
|
|
681
|
-
return
|
|
656
|
+
return signal2;
|
|
682
657
|
}
|
|
683
658
|
return node;
|
|
684
659
|
}
|
|
@@ -687,17 +662,26 @@ class CollectionAdministration extends Administration {
|
|
|
687
662
|
hasMap;
|
|
688
663
|
valuesMap;
|
|
689
664
|
keysAtom;
|
|
665
|
+
isWeak;
|
|
666
|
+
strongTracking = null;
|
|
667
|
+
weakTracking = null;
|
|
690
668
|
static proxyTraps = {
|
|
691
669
|
get(target, name) {
|
|
692
670
|
const adm = getAdministration(target);
|
|
693
|
-
if (name === "size" && "size" in adm.source) {
|
|
671
|
+
if (name === "size" && !adm.isWeak && "size" in adm.source) {
|
|
694
672
|
return adm.size;
|
|
695
673
|
}
|
|
696
674
|
const val = adm.source[name];
|
|
697
675
|
const collectionMethods = adm.constructor.methods;
|
|
698
|
-
if (collectionMethods.hasOwnProperty(name)
|
|
676
|
+
if (collectionMethods.hasOwnProperty(name)) {
|
|
677
|
+
if (adm.isWeak && !isValidWeakMethod(name)) {
|
|
678
|
+
return val;
|
|
679
|
+
}
|
|
699
680
|
return collectionMethods[name];
|
|
700
681
|
}
|
|
682
|
+
if (typeof val === "function") {
|
|
683
|
+
return val;
|
|
684
|
+
}
|
|
701
685
|
return val;
|
|
702
686
|
}
|
|
703
687
|
};
|
|
@@ -712,17 +696,71 @@ class CollectionAdministration extends Administration {
|
|
|
712
696
|
entries: createMethod$1("entries"),
|
|
713
697
|
keys: createMethod$1("keys"),
|
|
714
698
|
values: createMethod$1("values"),
|
|
715
|
-
[Symbol.iterator]: createMethod$1(Symbol.iterator)
|
|
699
|
+
[Symbol.iterator]: createMethod$1(Symbol.iterator),
|
|
700
|
+
// New ES methods
|
|
701
|
+
union: createGenericMethod("union"),
|
|
702
|
+
intersection: createGenericMethod("intersection"),
|
|
703
|
+
difference: createGenericMethod("difference"),
|
|
704
|
+
symmetricDifference: createGenericMethod("symmetricDifference"),
|
|
705
|
+
isSubsetOf: createGenericMethod("isSubsetOf"),
|
|
706
|
+
isSupersetOf: createGenericMethod("isSupersetOf"),
|
|
707
|
+
isDisjointFrom: createGenericMethod("isDisjointFrom")
|
|
716
708
|
};
|
|
717
709
|
constructor(source2) {
|
|
718
710
|
super(source2);
|
|
719
711
|
this.hasMap = new AtomMap(this.atom);
|
|
720
|
-
this.valuesMap = new SignalMap();
|
|
712
|
+
this.valuesMap = new SignalMap(this.atom);
|
|
721
713
|
this.keysAtom = createAtom();
|
|
722
714
|
this.isMap = typeof source2.set === "function" && typeof source2.get === "function";
|
|
715
|
+
this.isWeak = source2 instanceof WeakMap || source2 instanceof WeakSet;
|
|
716
|
+
if (this.isWeak) {
|
|
717
|
+
this.weakTracking = /* @__PURE__ */ new WeakSet();
|
|
718
|
+
} else {
|
|
719
|
+
this.strongTracking = /* @__PURE__ */ new Set();
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
trackExplicitObservable(key) {
|
|
723
|
+
if (this.isWeak) {
|
|
724
|
+
if (isNonPrimitive(key)) {
|
|
725
|
+
this.weakTracking.add(key);
|
|
726
|
+
}
|
|
727
|
+
} else {
|
|
728
|
+
this.strongTracking.add(key);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
untrackExplicitObservable(key) {
|
|
732
|
+
if (this.isWeak) {
|
|
733
|
+
if (isNonPrimitive(key)) {
|
|
734
|
+
this.weakTracking.delete(key);
|
|
735
|
+
}
|
|
736
|
+
} else {
|
|
737
|
+
this.strongTracking.delete(key);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
hasExplicitObservable(key) {
|
|
741
|
+
if (this.isWeak) {
|
|
742
|
+
return isNonPrimitive(key) && this.weakTracking.has(key);
|
|
743
|
+
}
|
|
744
|
+
return this.strongTracking.has(key);
|
|
745
|
+
}
|
|
746
|
+
getProxyVariant(key) {
|
|
747
|
+
if (!isNonPrimitive(key)) return void 0;
|
|
748
|
+
const adm = getAdministration(key);
|
|
749
|
+
if (adm && adm.proxy && adm.proxy !== key) {
|
|
750
|
+
return adm.proxy;
|
|
751
|
+
}
|
|
752
|
+
return void 0;
|
|
753
|
+
}
|
|
754
|
+
getExistingKey(key) {
|
|
755
|
+
const target = getSource(key);
|
|
756
|
+
if (this.source.has(target)) return target;
|
|
757
|
+
if (this.source.has(key)) return key;
|
|
758
|
+
const proxy = this.getProxyVariant(key);
|
|
759
|
+
if (proxy !== void 0 && this.source.has(proxy)) return proxy;
|
|
760
|
+
return void 0;
|
|
723
761
|
}
|
|
724
762
|
hasEntry(key) {
|
|
725
|
-
return this.
|
|
763
|
+
return this.getExistingKey(key) !== void 0;
|
|
726
764
|
}
|
|
727
765
|
onCollectionChange(key) {
|
|
728
766
|
batch(() => {
|
|
@@ -731,13 +769,6 @@ class CollectionAdministration extends Administration {
|
|
|
731
769
|
this.flushChange();
|
|
732
770
|
});
|
|
733
771
|
}
|
|
734
|
-
reportObserveDeep() {
|
|
735
|
-
this.source.forEach?.((value) => {
|
|
736
|
-
if (value && typeof value === "object") {
|
|
737
|
-
getAdministration(getObservable(value))?.reportObserved();
|
|
738
|
-
}
|
|
739
|
-
});
|
|
740
|
-
}
|
|
741
772
|
getNode(key) {
|
|
742
773
|
if (key == null) {
|
|
743
774
|
return resolveNode(this.atom);
|
|
@@ -758,13 +789,12 @@ class CollectionAdministration extends Administration {
|
|
|
758
789
|
this.keysAtom.reportObserved();
|
|
759
790
|
this.atom.reportObserved();
|
|
760
791
|
this.source.forEach((value, key) => {
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
);
|
|
792
|
+
if (this.isMap) {
|
|
793
|
+
callbackFn.call(thisArg, this.get(key), key, this.proxy);
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
const wrapped = this.wrapSetValue(key);
|
|
797
|
+
callbackFn.call(thisArg, wrapped, wrapped, this.proxy);
|
|
768
798
|
});
|
|
769
799
|
}
|
|
770
800
|
get size() {
|
|
@@ -773,43 +803,65 @@ class CollectionAdministration extends Administration {
|
|
|
773
803
|
return this.source.size;
|
|
774
804
|
}
|
|
775
805
|
add(value) {
|
|
806
|
+
const target = getSource(value);
|
|
807
|
+
if (isObservable(value)) {
|
|
808
|
+
this.trackExplicitObservable(target);
|
|
809
|
+
}
|
|
776
810
|
if (!this.hasEntry(value)) {
|
|
777
|
-
const target = getSource(value);
|
|
778
811
|
this.source.add(target);
|
|
779
812
|
this.onCollectionChange(target);
|
|
780
813
|
}
|
|
781
814
|
return this;
|
|
782
815
|
}
|
|
783
816
|
delete(value) {
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
817
|
+
const existingKey = this.getExistingKey(value);
|
|
818
|
+
if (existingKey === void 0) return false;
|
|
819
|
+
const target = getSource(value);
|
|
820
|
+
this.untrackExplicitObservable(target);
|
|
821
|
+
this.untrackExplicitObservable(value);
|
|
822
|
+
const proxy = this.getProxyVariant(value);
|
|
823
|
+
if (proxy !== void 0) this.untrackExplicitObservable(proxy);
|
|
824
|
+
this.source.delete(existingKey);
|
|
825
|
+
this.source.delete(target);
|
|
826
|
+
this.source.delete(value);
|
|
827
|
+
if (proxy !== void 0) this.source.delete(proxy);
|
|
828
|
+
this.onCollectionChange(target);
|
|
829
|
+
return true;
|
|
830
|
+
}
|
|
831
|
+
wrapSetValue(value) {
|
|
832
|
+
if (this.hasExplicitObservable(value)) {
|
|
833
|
+
if (value && typeof value === "object" && !Object.isFrozen(value)) {
|
|
834
|
+
const existingAdm = getAdministration(value);
|
|
835
|
+
if (existingAdm) return existingAdm.proxy;
|
|
836
|
+
}
|
|
790
837
|
}
|
|
791
|
-
return
|
|
838
|
+
return value;
|
|
792
839
|
}
|
|
793
840
|
has(value) {
|
|
794
841
|
this.atom.reportObserved();
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
this.hasMap.reportObserved(target);
|
|
798
|
-
}
|
|
842
|
+
const target = getSource(value);
|
|
843
|
+
this.hasMap.reportObserved(target);
|
|
799
844
|
return this.hasEntry(value);
|
|
800
845
|
}
|
|
801
846
|
entries() {
|
|
847
|
+
this.keysAtom.reportObserved();
|
|
848
|
+
this.atom.reportObserved();
|
|
802
849
|
const self = this;
|
|
803
|
-
const
|
|
850
|
+
const iterator = this.source.entries();
|
|
804
851
|
return {
|
|
805
852
|
[Symbol.iterator]: function() {
|
|
806
853
|
return this;
|
|
807
854
|
},
|
|
808
855
|
next() {
|
|
809
|
-
const { done, value } =
|
|
856
|
+
const { done, value } = iterator.next();
|
|
857
|
+
if (done) return { done: true, value: void 0 };
|
|
858
|
+
const [key, val] = value;
|
|
810
859
|
return {
|
|
811
|
-
done,
|
|
812
|
-
value:
|
|
860
|
+
done: false,
|
|
861
|
+
value: [
|
|
862
|
+
self.isMap ? key : self.wrapSetValue(key),
|
|
863
|
+
self.isMap ? self.get(key) : self.wrapSetValue(val)
|
|
864
|
+
]
|
|
813
865
|
};
|
|
814
866
|
}
|
|
815
867
|
};
|
|
@@ -817,19 +869,19 @@ class CollectionAdministration extends Administration {
|
|
|
817
869
|
keys() {
|
|
818
870
|
this.keysAtom.reportObserved();
|
|
819
871
|
this.atom.reportObserved();
|
|
820
|
-
|
|
821
|
-
const
|
|
822
|
-
(o) => getObservable(o)
|
|
823
|
-
);
|
|
872
|
+
const self = this;
|
|
873
|
+
const iterator = this.source.keys();
|
|
824
874
|
return {
|
|
825
875
|
[Symbol.iterator]: function() {
|
|
826
876
|
return this;
|
|
827
877
|
},
|
|
828
878
|
next() {
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
879
|
+
const { done, value } = iterator.next();
|
|
880
|
+
if (done) return { done: true, value: void 0 };
|
|
881
|
+
return {
|
|
882
|
+
done: false,
|
|
883
|
+
value: self.isMap ? value : self.wrapSetValue(value)
|
|
884
|
+
};
|
|
833
885
|
}
|
|
834
886
|
};
|
|
835
887
|
}
|
|
@@ -837,31 +889,54 @@ class CollectionAdministration extends Administration {
|
|
|
837
889
|
const targetKey = getSource(key);
|
|
838
890
|
const sourceMap = this.source;
|
|
839
891
|
const has = this.has(key);
|
|
840
|
-
|
|
841
|
-
|
|
892
|
+
if (!has) return void 0;
|
|
893
|
+
const existingKey = this.getExistingKey(key);
|
|
894
|
+
const value = sourceMap.get(existingKey);
|
|
895
|
+
this.valuesMap.reportObserved(targetKey, value);
|
|
896
|
+
if (key !== targetKey) {
|
|
842
897
|
this.valuesMap.reportObserved(key, value);
|
|
843
|
-
|
|
844
|
-
|
|
898
|
+
}
|
|
899
|
+
const proxyKey = this.getProxyVariant(key);
|
|
900
|
+
if (proxyKey !== void 0 && proxyKey !== key && proxyKey !== targetKey) {
|
|
901
|
+
this.valuesMap.reportObserved(proxyKey, value);
|
|
902
|
+
}
|
|
903
|
+
if (this.hasExplicitObservable(targetKey) || this.hasExplicitObservable(key) || proxyKey !== void 0 && this.hasExplicitObservable(proxyKey)) {
|
|
904
|
+
if (value && typeof value === "object" && !Object.isFrozen(value)) {
|
|
905
|
+
const existingAdm = getAdministration(value);
|
|
906
|
+
if (existingAdm) return existingAdm.proxy;
|
|
845
907
|
}
|
|
846
|
-
return getObservable(value);
|
|
847
908
|
}
|
|
848
|
-
return
|
|
909
|
+
return value;
|
|
849
910
|
}
|
|
850
911
|
set(key, value) {
|
|
851
912
|
const targetKey = getSource(key);
|
|
852
913
|
const targetValue = getSource(value);
|
|
853
914
|
const sourceMap = this.source;
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
915
|
+
if (isObservable(value)) {
|
|
916
|
+
this.trackExplicitObservable(targetKey);
|
|
917
|
+
} else {
|
|
918
|
+
this.untrackExplicitObservable(targetKey);
|
|
919
|
+
this.untrackExplicitObservable(key);
|
|
920
|
+
}
|
|
921
|
+
const existingKey = this.getExistingKey(key);
|
|
922
|
+
const hasKey = existingKey !== void 0;
|
|
923
|
+
const oldValue = hasKey ? sourceMap.get(existingKey) : void 0;
|
|
924
|
+
if (!hasKey || (isObservable(oldValue) ? oldValue !== value : oldValue !== targetValue)) {
|
|
857
925
|
batch(() => {
|
|
858
926
|
this.flushChange();
|
|
859
|
-
if (
|
|
860
|
-
sourceMap.set(
|
|
927
|
+
if (existingKey !== void 0) {
|
|
928
|
+
sourceMap.set(existingKey, targetValue);
|
|
861
929
|
} else {
|
|
862
930
|
sourceMap.set(targetKey, targetValue);
|
|
863
931
|
}
|
|
864
|
-
this.valuesMap.reportChanged(
|
|
932
|
+
this.valuesMap.reportChanged(targetKey, value);
|
|
933
|
+
if (key !== targetKey) {
|
|
934
|
+
this.valuesMap.reportChanged(key, value);
|
|
935
|
+
}
|
|
936
|
+
const proxyKey = this.getProxyVariant(key);
|
|
937
|
+
if (proxyKey !== void 0 && proxyKey !== key && proxyKey !== targetKey) {
|
|
938
|
+
this.valuesMap.reportChanged(proxyKey, value);
|
|
939
|
+
}
|
|
865
940
|
if (!hasKey) {
|
|
866
941
|
this.hasMap.reportChanged(targetKey);
|
|
867
942
|
this.keysAtom.reportChanged();
|
|
@@ -871,20 +946,22 @@ class CollectionAdministration extends Administration {
|
|
|
871
946
|
return this;
|
|
872
947
|
}
|
|
873
948
|
values() {
|
|
874
|
-
|
|
875
|
-
|
|
949
|
+
this.keysAtom.reportObserved();
|
|
950
|
+
this.atom.reportObserved();
|
|
876
951
|
if (!this.isMap) {
|
|
877
|
-
return keys;
|
|
952
|
+
return this.keys();
|
|
878
953
|
}
|
|
954
|
+
const entries = this.entries();
|
|
879
955
|
return {
|
|
880
956
|
[Symbol.iterator]: function() {
|
|
881
957
|
return this;
|
|
882
958
|
},
|
|
883
959
|
next() {
|
|
884
|
-
const { done, value } =
|
|
960
|
+
const { done, value } = entries.next();
|
|
961
|
+
if (done) return { done: true, value: void 0 };
|
|
885
962
|
return {
|
|
886
|
-
done,
|
|
887
|
-
value:
|
|
963
|
+
done: false,
|
|
964
|
+
value: value[1]
|
|
888
965
|
};
|
|
889
966
|
}
|
|
890
967
|
};
|
|
@@ -894,53 +971,197 @@ class CollectionAdministration extends Administration {
|
|
|
894
971
|
}
|
|
895
972
|
[Symbol.toStringTag] = "Set";
|
|
896
973
|
}
|
|
974
|
+
function isValidWeakMethod(name) {
|
|
975
|
+
const n = name;
|
|
976
|
+
return n === "get" || n === "set" || n === "add" || n === "has" || n === "delete";
|
|
977
|
+
}
|
|
978
|
+
function createGenericMethod(name) {
|
|
979
|
+
return function() {
|
|
980
|
+
const adm = getAdministration(this);
|
|
981
|
+
const method = adm.source[name];
|
|
982
|
+
if (typeof method !== "function") return method;
|
|
983
|
+
if (["union", "intersection", "difference", "symmetricDifference"].includes(
|
|
984
|
+
name
|
|
985
|
+
)) {
|
|
986
|
+
const other = arguments[0];
|
|
987
|
+
const result2 = /* @__PURE__ */ new Set();
|
|
988
|
+
if (name === "union") {
|
|
989
|
+
for (const item of this) result2.add(item);
|
|
990
|
+
for (const item of other) result2.add(item);
|
|
991
|
+
} else if (name === "intersection") {
|
|
992
|
+
for (const item of this) {
|
|
993
|
+
if (other.has(item)) result2.add(item);
|
|
994
|
+
}
|
|
995
|
+
} else if (name === "difference") {
|
|
996
|
+
for (const item of this) {
|
|
997
|
+
if (!other.has(item)) result2.add(item);
|
|
998
|
+
}
|
|
999
|
+
} else if (name === "symmetricDifference") {
|
|
1000
|
+
for (const item of this) {
|
|
1001
|
+
if (!other.has(item)) result2.add(item);
|
|
1002
|
+
}
|
|
1003
|
+
for (const item of other) {
|
|
1004
|
+
if (!this.has(item)) result2.add(item);
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
return result2;
|
|
1008
|
+
}
|
|
1009
|
+
adm.keysAtom.reportObserved();
|
|
1010
|
+
adm.atom.reportObserved();
|
|
1011
|
+
const args = new Array(arguments.length);
|
|
1012
|
+
for (let i = 0; i < arguments.length; i++) {
|
|
1013
|
+
const arg = arguments[i];
|
|
1014
|
+
args[i] = getSource(arg);
|
|
1015
|
+
if (isObservable(arg)) {
|
|
1016
|
+
reportObserved(arg);
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
const result = method.apply(adm.source, args);
|
|
1020
|
+
if (result === adm.source) return adm.proxy;
|
|
1021
|
+
return result;
|
|
1022
|
+
};
|
|
1023
|
+
}
|
|
897
1024
|
function createMethod$1(method) {
|
|
898
1025
|
return function() {
|
|
899
1026
|
const adm = getAdministration(this);
|
|
900
|
-
|
|
1027
|
+
const result = adm[method].apply(adm, arguments);
|
|
1028
|
+
if (method === "add" || method === "set") {
|
|
1029
|
+
return this;
|
|
1030
|
+
}
|
|
1031
|
+
return result;
|
|
901
1032
|
};
|
|
902
1033
|
}
|
|
1034
|
+
function isArrayIndexKey(key) {
|
|
1035
|
+
if (typeof key === "symbol") return false;
|
|
1036
|
+
const keyStr = String(key);
|
|
1037
|
+
const num = Number(keyStr);
|
|
1038
|
+
return Number.isInteger(num) && num >= 0 && num < 4294967295 && // 2^32 - 1
|
|
1039
|
+
String(num) === keyStr;
|
|
1040
|
+
}
|
|
1041
|
+
function reportConflict() {
|
|
1042
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1043
|
+
throw new Error(
|
|
1044
|
+
"r-state-tree: Cannot assign the same object as both observable and raw source in the same array. The value will be treated as observable."
|
|
1045
|
+
);
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
903
1048
|
class ArrayAdministration extends Administration {
|
|
904
1049
|
valuesMap;
|
|
905
1050
|
keysAtom;
|
|
1051
|
+
/**
|
|
1052
|
+
* Parent-based ownership tracking: sources assigned as observable.
|
|
1053
|
+
* Unlike index-based tracking, this doesn't require updates on reorder ops.
|
|
1054
|
+
*/
|
|
1055
|
+
observableSources = /* @__PURE__ */ new WeakSet();
|
|
1056
|
+
rawSources = /* @__PURE__ */ new WeakSet();
|
|
1057
|
+
/**
|
|
1058
|
+
* Track a value being assigned to this array.
|
|
1059
|
+
* Detects conflicts if same source is assigned as both observable and raw.
|
|
1060
|
+
*/
|
|
1061
|
+
trackValue(value) {
|
|
1062
|
+
if (value && typeof value === "object") {
|
|
1063
|
+
const source2 = getSource(value);
|
|
1064
|
+
if (isObservable(value)) {
|
|
1065
|
+
if (this.rawSources.has(source2)) {
|
|
1066
|
+
reportConflict();
|
|
1067
|
+
}
|
|
1068
|
+
this.observableSources.add(source2);
|
|
1069
|
+
} else {
|
|
1070
|
+
if (this.observableSources.has(source2)) {
|
|
1071
|
+
reportConflict();
|
|
1072
|
+
} else {
|
|
1073
|
+
this.rawSources.add(source2);
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
906
1078
|
static proxyTraps = {
|
|
907
|
-
get(target, name) {
|
|
1079
|
+
get(target, name, receiver) {
|
|
908
1080
|
const adm = getAdministration(target);
|
|
909
1081
|
if (name === "length") {
|
|
910
1082
|
return adm.getArrayLength();
|
|
911
1083
|
}
|
|
912
|
-
if (
|
|
913
|
-
return adm.get(name);
|
|
914
|
-
}
|
|
915
|
-
if (typeof name === "string" && String(parseInt(name)) === name) {
|
|
916
|
-
return adm.get(parseInt(name));
|
|
1084
|
+
if (isArrayIndexKey(name)) {
|
|
1085
|
+
return adm.get(Number(name));
|
|
917
1086
|
}
|
|
918
1087
|
const arrayMethods = adm.constructor.methods;
|
|
919
1088
|
if (arrayMethods.hasOwnProperty(name)) {
|
|
920
1089
|
return arrayMethods[name];
|
|
921
1090
|
}
|
|
922
|
-
return adm.source
|
|
1091
|
+
return Reflect.get(adm.source, name, receiver);
|
|
923
1092
|
},
|
|
924
1093
|
set(target, name, value) {
|
|
925
1094
|
const adm = getAdministration(target);
|
|
926
1095
|
if (name === "length") {
|
|
927
|
-
adm.setArrayLength(value);
|
|
928
|
-
} else if (
|
|
929
|
-
adm.set(name, value);
|
|
930
|
-
} else if (typeof name === "string" && String(parseInt(name)) === name) {
|
|
931
|
-
adm.set(parseInt(name), value);
|
|
1096
|
+
return adm.setArrayLength(value);
|
|
1097
|
+
} else if (isArrayIndexKey(name)) {
|
|
1098
|
+
return adm.set(Number(name), value);
|
|
932
1099
|
} else {
|
|
933
|
-
adm.source
|
|
1100
|
+
return Reflect.set(adm.source, name, value, arguments[3]);
|
|
934
1101
|
}
|
|
935
|
-
|
|
1102
|
+
},
|
|
1103
|
+
defineProperty(target, name, descriptor) {
|
|
1104
|
+
const adm = getAdministration(target);
|
|
1105
|
+
const result = Reflect.defineProperty(adm.source, name, descriptor);
|
|
1106
|
+
if (result) {
|
|
1107
|
+
batch(() => {
|
|
1108
|
+
adm.flushChange();
|
|
1109
|
+
if (name === "length") {
|
|
1110
|
+
adm.keysAtom.reportChanged();
|
|
1111
|
+
adm.atom.reportChanged();
|
|
1112
|
+
} else if (isArrayIndexKey(name)) {
|
|
1113
|
+
const index = Number(name);
|
|
1114
|
+
adm.keysAtom.reportChanged();
|
|
1115
|
+
adm.onArrayChanged(false, index, 1);
|
|
1116
|
+
} else {
|
|
1117
|
+
adm.atom.reportChanged();
|
|
1118
|
+
}
|
|
1119
|
+
});
|
|
1120
|
+
}
|
|
1121
|
+
return result;
|
|
1122
|
+
},
|
|
1123
|
+
deleteProperty(target, name) {
|
|
1124
|
+
const adm = getAdministration(target);
|
|
1125
|
+
const isIndex = isArrayIndexKey(name);
|
|
1126
|
+
const had = name in adm.source;
|
|
1127
|
+
const result = Reflect.deleteProperty(adm.source, name);
|
|
1128
|
+
if (result && had && isIndex) {
|
|
1129
|
+
const index = Number(name);
|
|
1130
|
+
adm.onArrayChanged(true, index, 1);
|
|
1131
|
+
}
|
|
1132
|
+
return result;
|
|
1133
|
+
},
|
|
1134
|
+
ownKeys(target) {
|
|
1135
|
+
const adm = getAdministration(target);
|
|
1136
|
+
batch(() => {
|
|
1137
|
+
adm.keysAtom.reportObserved();
|
|
1138
|
+
adm.atom.reportObserved();
|
|
1139
|
+
});
|
|
1140
|
+
return Reflect.ownKeys(adm.source);
|
|
1141
|
+
},
|
|
1142
|
+
has(target, name) {
|
|
1143
|
+
const adm = getAdministration(target);
|
|
1144
|
+
if (isArrayIndexKey(name)) {
|
|
1145
|
+
const index = Number(name);
|
|
1146
|
+
adm.atom.reportObserved();
|
|
1147
|
+
adm.valuesMap.reportObserved(index, adm.source[index]);
|
|
1148
|
+
return index in adm.source;
|
|
1149
|
+
}
|
|
1150
|
+
return Reflect.has(adm.source, name);
|
|
936
1151
|
}
|
|
937
1152
|
};
|
|
938
1153
|
static methods = {
|
|
939
1154
|
fill(value, start, end) {
|
|
940
1155
|
const adm = getAdministration(this);
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
adm.
|
|
1156
|
+
adm.trackValue(value);
|
|
1157
|
+
const targetValue = getSource(value);
|
|
1158
|
+
adm.source.fill(targetValue, start, end);
|
|
1159
|
+
const length = adm.source.length;
|
|
1160
|
+
const from = start == null ? 0 : start < 0 ? Math.max(length + start, 0) : start;
|
|
1161
|
+
const to = end == null ? length : end < 0 ? Math.max(length + end, 0) : Math.min(end, length);
|
|
1162
|
+
if (from < to) {
|
|
1163
|
+
adm.onArrayChanged(false, from, to - from);
|
|
1164
|
+
}
|
|
944
1165
|
return this;
|
|
945
1166
|
},
|
|
946
1167
|
splice(index, deleteCount, ...newItems) {
|
|
@@ -982,10 +1203,20 @@ class ArrayAdministration extends Administration {
|
|
|
982
1203
|
},
|
|
983
1204
|
sort(compareFn) {
|
|
984
1205
|
const adm = getAdministration(this);
|
|
985
|
-
adm.
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
);
|
|
1206
|
+
const pairs = adm.source.map((stored, i) => ({
|
|
1207
|
+
value: this[i],
|
|
1208
|
+
stored
|
|
1209
|
+
}));
|
|
1210
|
+
const comparator = compareFn ?? ((a, b) => {
|
|
1211
|
+
const as = String(a);
|
|
1212
|
+
const bs = String(b);
|
|
1213
|
+
return as < bs ? -1 : as > bs ? 1 : 0;
|
|
1214
|
+
});
|
|
1215
|
+
pairs.sort((a, b) => comparator(a.value, b.value));
|
|
1216
|
+
for (let i = 0; i < pairs.length; i++) {
|
|
1217
|
+
adm.source[i] = pairs[i].stored;
|
|
1218
|
+
}
|
|
1219
|
+
adm.onArrayChanged(false, 0, adm.source.length);
|
|
989
1220
|
return this;
|
|
990
1221
|
},
|
|
991
1222
|
join: createStringMethod("join"),
|
|
@@ -997,7 +1228,12 @@ class ArrayAdministration extends Administration {
|
|
|
997
1228
|
slice: createCopyMethod("slice"),
|
|
998
1229
|
concat: createCopyMethod("concat"),
|
|
999
1230
|
flat: createCopyMethod("flat"),
|
|
1000
|
-
copyWithin
|
|
1231
|
+
copyWithin(target, start, end) {
|
|
1232
|
+
const adm = getAdministration(this);
|
|
1233
|
+
adm.source.copyWithin(target, start, end);
|
|
1234
|
+
adm.onArrayChanged(false, 0, adm.source.length);
|
|
1235
|
+
return this;
|
|
1236
|
+
},
|
|
1001
1237
|
every: createMapMethod("every"),
|
|
1002
1238
|
forEach: createMapMethod("forEach"),
|
|
1003
1239
|
map: createMapMethod("map"),
|
|
@@ -1011,17 +1247,9 @@ class ArrayAdministration extends Administration {
|
|
|
1011
1247
|
};
|
|
1012
1248
|
constructor(source2 = []) {
|
|
1013
1249
|
super(source2);
|
|
1014
|
-
this.valuesMap = new SignalMap();
|
|
1250
|
+
this.valuesMap = new SignalMap(this.atom);
|
|
1015
1251
|
this.keysAtom = createAtom();
|
|
1016
1252
|
}
|
|
1017
|
-
reportObserveDeep() {
|
|
1018
|
-
for (let i = 0; i < this.source.length; i++) {
|
|
1019
|
-
const value = this.source[i];
|
|
1020
|
-
if (value && typeof value === "object") {
|
|
1021
|
-
getAdministration(getObservable(value))?.reportObserved();
|
|
1022
|
-
}
|
|
1023
|
-
}
|
|
1024
|
-
}
|
|
1025
1253
|
getNode(key) {
|
|
1026
1254
|
if (key == null) {
|
|
1027
1255
|
return this.atom;
|
|
@@ -1031,45 +1259,69 @@ class ArrayAdministration extends Administration {
|
|
|
1031
1259
|
get(index) {
|
|
1032
1260
|
this.atom.reportObserved();
|
|
1033
1261
|
this.valuesMap.reportObserved(index, this.source[index]);
|
|
1034
|
-
|
|
1035
|
-
|
|
1262
|
+
return this._getEffectiveValue(index);
|
|
1263
|
+
}
|
|
1264
|
+
_getEffectiveValue(index) {
|
|
1265
|
+
const value = this.source[index];
|
|
1266
|
+
if (value && typeof value === "object" && !Object.isFrozen(value)) {
|
|
1267
|
+
if (this.observableSources.has(value)) {
|
|
1268
|
+
const adm = getAdministration(value);
|
|
1269
|
+
if (adm.proxy !== value) {
|
|
1270
|
+
const desc = Object.getOwnPropertyDescriptor(this.source, index);
|
|
1271
|
+
if (desc && !desc.configurable && !desc.writable) {
|
|
1272
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1273
|
+
console.warn(
|
|
1274
|
+
`r-state-tree: cannot return an observable proxy for arr[${index}] because it is a non-configurable, non-writable data property; returning the raw value to uphold Proxy invariants.`
|
|
1275
|
+
);
|
|
1276
|
+
}
|
|
1277
|
+
return value;
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
return adm.proxy;
|
|
1281
|
+
}
|
|
1036
1282
|
}
|
|
1037
|
-
return
|
|
1283
|
+
return value;
|
|
1038
1284
|
}
|
|
1039
1285
|
set(index, newValue) {
|
|
1040
1286
|
const values = this.source;
|
|
1041
1287
|
const targetValue = getSource(newValue);
|
|
1042
|
-
|
|
1288
|
+
const oldLength = values.length;
|
|
1289
|
+
this.trackValue(newValue);
|
|
1290
|
+
let changed = true;
|
|
1291
|
+
if (index < oldLength) {
|
|
1043
1292
|
const oldValue = values[index];
|
|
1044
|
-
|
|
1045
|
-
if (changed) {
|
|
1046
|
-
values[index] = targetValue;
|
|
1047
|
-
this.onArrayChanged(false, index, 1);
|
|
1048
|
-
}
|
|
1049
|
-
} else if (index === values.length) {
|
|
1050
|
-
this.spliceWithArray(index, 0, [newValue]);
|
|
1051
|
-
} else {
|
|
1052
|
-
throw new Error(
|
|
1053
|
-
`Index out of bounds, ${index} is larger than ${values.length}`
|
|
1054
|
-
);
|
|
1293
|
+
changed = targetValue !== oldValue;
|
|
1055
1294
|
}
|
|
1295
|
+
if (!changed) return true;
|
|
1296
|
+
const result = Reflect.set(values, index, targetValue);
|
|
1297
|
+
if (!result) return false;
|
|
1298
|
+
const newLength = values.length;
|
|
1299
|
+
const lengthChanged = newLength !== oldLength;
|
|
1300
|
+
this.onArrayChanged(lengthChanged, index, 1);
|
|
1301
|
+
return true;
|
|
1056
1302
|
}
|
|
1057
1303
|
getArrayLength() {
|
|
1058
1304
|
this.atom.reportObserved();
|
|
1059
1305
|
this.keysAtom.reportObserved();
|
|
1060
1306
|
return this.source.length;
|
|
1061
1307
|
}
|
|
1062
|
-
setArrayLength(
|
|
1063
|
-
|
|
1064
|
-
|
|
1308
|
+
setArrayLength(input) {
|
|
1309
|
+
const num = Number(input);
|
|
1310
|
+
const coerced = num >>> 0;
|
|
1311
|
+
if (coerced !== num) {
|
|
1312
|
+
throw new RangeError("Invalid array length");
|
|
1313
|
+
}
|
|
1314
|
+
const newLength = coerced;
|
|
1065
1315
|
const currentLength = this.source.length;
|
|
1066
|
-
if (newLength === currentLength) return;
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1316
|
+
if (newLength === currentLength) return true;
|
|
1317
|
+
const result = Reflect.set(this.source, "length", newLength);
|
|
1318
|
+
if (!result) return false;
|
|
1319
|
+
if (newLength < currentLength) {
|
|
1320
|
+
this.onArrayChanged(true, newLength, currentLength - newLength);
|
|
1321
|
+
} else {
|
|
1322
|
+
this.onArrayChanged(true, currentLength, newLength - currentLength);
|
|
1323
|
+
}
|
|
1324
|
+
return true;
|
|
1073
1325
|
}
|
|
1074
1326
|
spliceWithArray(index, deleteCount, newItems) {
|
|
1075
1327
|
const length = this.source.length;
|
|
@@ -1077,6 +1329,7 @@ class ArrayAdministration extends Administration {
|
|
|
1077
1329
|
if (newItems) {
|
|
1078
1330
|
for (let i = 0; i < newItems.length; i++) {
|
|
1079
1331
|
newTargetItems[i] = getSource(newItems[i]);
|
|
1332
|
+
this.trackValue(newItems[i]);
|
|
1080
1333
|
}
|
|
1081
1334
|
}
|
|
1082
1335
|
if (index === void 0) index = 0;
|
|
@@ -1085,15 +1338,18 @@ class ArrayAdministration extends Administration {
|
|
|
1085
1338
|
if (arguments.length === 1) deleteCount = length - index;
|
|
1086
1339
|
else if (deleteCount === void 0 || deleteCount === null) deleteCount = 0;
|
|
1087
1340
|
else deleteCount = Math.max(0, Math.min(deleteCount, length - index));
|
|
1088
|
-
const
|
|
1341
|
+
const removedItems = [];
|
|
1342
|
+
for (let i = index; i < index + deleteCount; i++) {
|
|
1343
|
+
removedItems.push(this._getEffectiveValue(i));
|
|
1344
|
+
}
|
|
1345
|
+
this.spliceItemsIntoValues(index, deleteCount, newTargetItems);
|
|
1089
1346
|
if (deleteCount !== 0 || newTargetItems.length !== 0) {
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
);
|
|
1347
|
+
const shift = (newItems?.length ?? 0) - deleteCount;
|
|
1348
|
+
const reindexing = shift !== 0 && index + deleteCount < length;
|
|
1349
|
+
const count = reindexing ? Number.POSITIVE_INFINITY : Math.max(deleteCount ?? 0, newItems?.length ?? 0);
|
|
1350
|
+
this.onArrayChanged(length !== this.source.length, index, count);
|
|
1095
1351
|
}
|
|
1096
|
-
return
|
|
1352
|
+
return removedItems;
|
|
1097
1353
|
}
|
|
1098
1354
|
spliceItemsIntoValues(index, deleteCount, newItems) {
|
|
1099
1355
|
return this.source.splice.apply(
|
|
@@ -1108,9 +1364,16 @@ class ArrayAdministration extends Administration {
|
|
|
1108
1364
|
}
|
|
1109
1365
|
if (index == null) {
|
|
1110
1366
|
this.atom.reportChanged();
|
|
1111
|
-
} else {
|
|
1112
|
-
|
|
1113
|
-
|
|
1367
|
+
} else if (count !== void 0 && count > 0) {
|
|
1368
|
+
const observedKeys = this.valuesMap.keys();
|
|
1369
|
+
const end = index + count;
|
|
1370
|
+
for (const key of observedKeys) {
|
|
1371
|
+
if (typeof key === "number" && key >= index && key < end) {
|
|
1372
|
+
const node = this.valuesMap.get(key);
|
|
1373
|
+
if (node) {
|
|
1374
|
+
node.reportChanged(this._getEffectiveValue(key));
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1114
1377
|
}
|
|
1115
1378
|
}
|
|
1116
1379
|
this.flushChange();
|
|
@@ -1126,7 +1389,7 @@ function createMethod(method, func) {
|
|
|
1126
1389
|
function createStringMethod(method) {
|
|
1127
1390
|
return createMethod(method, function() {
|
|
1128
1391
|
const adm = getAdministration(this);
|
|
1129
|
-
adm.reportObserved(
|
|
1392
|
+
adm.reportObserved();
|
|
1130
1393
|
const sourceArr = getSource(this);
|
|
1131
1394
|
return sourceArr[method].apply(sourceArr, arguments);
|
|
1132
1395
|
});
|
|
@@ -1134,7 +1397,7 @@ function createStringMethod(method) {
|
|
|
1134
1397
|
function createSearchMethod(method) {
|
|
1135
1398
|
return createMethod(method, function() {
|
|
1136
1399
|
const adm = getAdministration(this);
|
|
1137
|
-
adm.reportObserved(
|
|
1400
|
+
adm.reportObserved();
|
|
1138
1401
|
const target = arguments[0];
|
|
1139
1402
|
const source2 = getSource(target);
|
|
1140
1403
|
const sourceArr = getSource(this);
|
|
@@ -1150,10 +1413,38 @@ function createSearchMethod(method) {
|
|
|
1150
1413
|
function createCopyMethod(method) {
|
|
1151
1414
|
return createMethod(method, function() {
|
|
1152
1415
|
const adm = getAdministration(this);
|
|
1153
|
-
adm.reportObserved(
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
);
|
|
1416
|
+
adm.reportObserved();
|
|
1417
|
+
const observedInput = [];
|
|
1418
|
+
observedInput.length = adm.source.length;
|
|
1419
|
+
const keys = Object.keys(adm.source);
|
|
1420
|
+
for (let i = 0; i < keys.length; i++) {
|
|
1421
|
+
const key = keys[i];
|
|
1422
|
+
const idx = Number(key);
|
|
1423
|
+
if (!Number.isNaN(idx)) {
|
|
1424
|
+
observedInput[idx] = this[idx];
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
const args = Array.from(arguments);
|
|
1428
|
+
if (method === "concat") {
|
|
1429
|
+
for (let i = 0; i < args.length; i++) {
|
|
1430
|
+
const arg = args[i];
|
|
1431
|
+
if (Array.isArray(arg) && isObservable(arg)) {
|
|
1432
|
+
const argAdm = getAdministration(arg);
|
|
1433
|
+
const argObserved = [];
|
|
1434
|
+
argObserved.length = argAdm.source.length;
|
|
1435
|
+
const argKeys = Object.keys(argAdm.source);
|
|
1436
|
+
for (let j = 0; j < argKeys.length; j++) {
|
|
1437
|
+
const argKey = argKeys[j];
|
|
1438
|
+
const argIdx = Number(argKey);
|
|
1439
|
+
if (!Number.isNaN(argIdx)) {
|
|
1440
|
+
argObserved[argIdx] = arg[argIdx];
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
args[i] = argObserved;
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
return Array.prototype[method].apply(observedInput, args);
|
|
1157
1448
|
});
|
|
1158
1449
|
}
|
|
1159
1450
|
function createMapMethod(method) {
|
|
@@ -1161,14 +1452,9 @@ function createMapMethod(method) {
|
|
|
1161
1452
|
method,
|
|
1162
1453
|
function(callback, thisArg) {
|
|
1163
1454
|
const adm = getAdministration(this);
|
|
1164
|
-
adm.reportObserved(
|
|
1165
|
-
return adm.source[method]((
|
|
1166
|
-
return callback.call(
|
|
1167
|
-
thisArg,
|
|
1168
|
-
element && typeof element === "object" ? getObservable(element) : element,
|
|
1169
|
-
index,
|
|
1170
|
-
this
|
|
1171
|
-
);
|
|
1455
|
+
adm.reportObserved();
|
|
1456
|
+
return adm.source[method]((_element, index) => {
|
|
1457
|
+
return callback.call(thisArg, this[index], index, this);
|
|
1172
1458
|
});
|
|
1173
1459
|
}
|
|
1174
1460
|
);
|
|
@@ -1178,28 +1464,17 @@ function createFilterMethod(method) {
|
|
|
1178
1464
|
method,
|
|
1179
1465
|
function(callback, thisArg) {
|
|
1180
1466
|
const adm = getAdministration(this);
|
|
1181
|
-
adm.reportObserved(
|
|
1182
|
-
return
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
thisArg,
|
|
1186
|
-
element && typeof element === "object" ? getObservable(element) : element,
|
|
1187
|
-
index,
|
|
1188
|
-
this
|
|
1189
|
-
);
|
|
1190
|
-
})
|
|
1191
|
-
);
|
|
1467
|
+
adm.reportObserved();
|
|
1468
|
+
return adm.source[method]((_element, index) => {
|
|
1469
|
+
return callback.call(thisArg, this[index], index, this);
|
|
1470
|
+
});
|
|
1192
1471
|
}
|
|
1193
1472
|
);
|
|
1194
1473
|
}
|
|
1195
1474
|
function createReduceMethod(method) {
|
|
1196
1475
|
return createMethod(method, function() {
|
|
1197
1476
|
const adm = getAdministration(this);
|
|
1198
|
-
adm.reportObserved(
|
|
1199
|
-
const callback = arguments[0];
|
|
1200
|
-
arguments[0] = (accumulator, currentValue, index) => {
|
|
1201
|
-
return callback(accumulator, getObservable(currentValue), index, this);
|
|
1202
|
-
};
|
|
1477
|
+
adm.reportObserved();
|
|
1203
1478
|
return adm.source[method].apply(adm.source, arguments);
|
|
1204
1479
|
});
|
|
1205
1480
|
}
|
|
@@ -1226,6 +1501,7 @@ function addDateSetMethod(method) {
|
|
|
1226
1501
|
const adm = getAdministration(this);
|
|
1227
1502
|
const res = adm.source[method].apply(adm.source, arguments);
|
|
1228
1503
|
adm.atom.reportChanged();
|
|
1504
|
+
adm.flushChange();
|
|
1229
1505
|
return res;
|
|
1230
1506
|
};
|
|
1231
1507
|
}
|
|
@@ -1261,9 +1537,15 @@ function getAction(fn) {
|
|
|
1261
1537
|
}
|
|
1262
1538
|
function getObservableClassInstance(value) {
|
|
1263
1539
|
const adm = new PreactObjectAdministration(value);
|
|
1540
|
+
administrationMap.set(adm.proxy, adm);
|
|
1264
1541
|
administrationMap.set(adm.source, adm);
|
|
1265
1542
|
return adm.proxy;
|
|
1266
1543
|
}
|
|
1544
|
+
class Observable {
|
|
1545
|
+
constructor() {
|
|
1546
|
+
return getObservableClassInstance(this);
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1267
1549
|
function createObservableWithCustomAdministration(value, Adm) {
|
|
1268
1550
|
const adm = new Adm(value);
|
|
1269
1551
|
administrationMap.set(adm.proxy, adm);
|
|
@@ -1271,40 +1553,6 @@ function createObservableWithCustomAdministration(value, Adm) {
|
|
|
1271
1553
|
return adm.proxy;
|
|
1272
1554
|
}
|
|
1273
1555
|
function getObservable(value) {
|
|
1274
|
-
if (!value) {
|
|
1275
|
-
return value;
|
|
1276
|
-
}
|
|
1277
|
-
const adm = getAdministration(value);
|
|
1278
|
-
if (adm) {
|
|
1279
|
-
return adm.proxy;
|
|
1280
|
-
}
|
|
1281
|
-
if ((typeof value === "object" || typeof value === "function") && !Object.isFrozen(value)) {
|
|
1282
|
-
const obj = value;
|
|
1283
|
-
let Adm = PreactObjectAdministration;
|
|
1284
|
-
if (Array.isArray(obj)) {
|
|
1285
|
-
Adm = ArrayAdministration;
|
|
1286
|
-
} else if (obj instanceof Map || obj instanceof WeakMap) {
|
|
1287
|
-
Adm = CollectionAdministration;
|
|
1288
|
-
} else if (obj instanceof Set || obj instanceof WeakSet) {
|
|
1289
|
-
Adm = CollectionAdministration;
|
|
1290
|
-
} else if (obj instanceof Date) {
|
|
1291
|
-
Adm = DateAdministration;
|
|
1292
|
-
} else if (!isPlainObject(value)) {
|
|
1293
|
-
return value;
|
|
1294
|
-
}
|
|
1295
|
-
const adm2 = new Adm(obj);
|
|
1296
|
-
administrationMap.set(adm2.proxy, adm2);
|
|
1297
|
-
administrationMap.set(adm2.source, adm2);
|
|
1298
|
-
return adm2.proxy;
|
|
1299
|
-
}
|
|
1300
|
-
return value;
|
|
1301
|
-
}
|
|
1302
|
-
const shallowObservables = /* @__PURE__ */ new WeakSet();
|
|
1303
|
-
function isShallowObservable(obj) {
|
|
1304
|
-
if (!obj || typeof obj !== "object") return false;
|
|
1305
|
-
return shallowObservables.has(obj);
|
|
1306
|
-
}
|
|
1307
|
-
function getShallowObservable(value) {
|
|
1308
1556
|
if (!value) {
|
|
1309
1557
|
return value;
|
|
1310
1558
|
}
|
|
@@ -1312,23 +1560,43 @@ function getShallowObservable(value) {
|
|
|
1312
1560
|
if (existingAdm) {
|
|
1313
1561
|
return existingAdm.proxy;
|
|
1314
1562
|
}
|
|
1315
|
-
if (
|
|
1563
|
+
if (typeof value === "function") {
|
|
1564
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1565
|
+
console.warn(
|
|
1566
|
+
`r-state-tree: functions are not observable containers. The function will be returned unchanged. Note: functions read from observable objects are still automatically batched as actions.`
|
|
1567
|
+
);
|
|
1568
|
+
}
|
|
1569
|
+
return value;
|
|
1570
|
+
}
|
|
1571
|
+
if (typeof value === "object") {
|
|
1316
1572
|
const obj = value;
|
|
1317
1573
|
let Adm = null;
|
|
1318
|
-
if (
|
|
1319
|
-
Adm = ArrayAdministration;
|
|
1320
|
-
} else if (obj instanceof Map || obj instanceof WeakMap) {
|
|
1574
|
+
if (obj instanceof Map || obj instanceof WeakMap) {
|
|
1321
1575
|
Adm = CollectionAdministration;
|
|
1322
1576
|
} else if (obj instanceof Set || obj instanceof WeakSet) {
|
|
1323
1577
|
Adm = CollectionAdministration;
|
|
1578
|
+
} else if (obj instanceof Date) {
|
|
1579
|
+
Adm = DateAdministration;
|
|
1580
|
+
} else if (!Object.isFrozen(obj)) {
|
|
1581
|
+
if (Array.isArray(obj)) {
|
|
1582
|
+
Adm = ArrayAdministration;
|
|
1583
|
+
} else if (isPlainObject(obj)) {
|
|
1584
|
+
Adm = PreactObjectAdministration;
|
|
1585
|
+
}
|
|
1324
1586
|
}
|
|
1325
1587
|
if (Adm) {
|
|
1326
1588
|
const adm = new Adm(obj);
|
|
1327
1589
|
administrationMap.set(adm.proxy, adm);
|
|
1328
1590
|
administrationMap.set(adm.source, adm);
|
|
1329
|
-
shallowObservables.add(adm.proxy);
|
|
1330
1591
|
return adm.proxy;
|
|
1331
1592
|
}
|
|
1593
|
+
if (process.env.NODE_ENV !== "production" && !Object.isFrozen(obj)) {
|
|
1594
|
+
const proto = Object.getPrototypeOf(obj);
|
|
1595
|
+
const typeName = proto?.constructor?.name && proto.constructor.name !== "Object" ? `instance of ${proto.constructor.name}` : "non-plain object";
|
|
1596
|
+
console.warn(
|
|
1597
|
+
`r-state-tree: observable() was called with a ${typeName}. This object will NOT be made observable because proxying arbitrary class instances can break #private fields and built-in brand checks. To make a class observable, use 'class MyClass extends Observable'.`
|
|
1598
|
+
);
|
|
1599
|
+
}
|
|
1332
1600
|
}
|
|
1333
1601
|
return value;
|
|
1334
1602
|
}
|
|
@@ -1357,19 +1625,77 @@ function getPropertyDescriptor(obj, key) {
|
|
|
1357
1625
|
}
|
|
1358
1626
|
return void 0;
|
|
1359
1627
|
}
|
|
1360
|
-
function clone(val) {
|
|
1361
|
-
if (
|
|
1362
|
-
return val
|
|
1363
|
-
}
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
const key = keys[i];
|
|
1368
|
-
cloned[key] = clone(val[key]);
|
|
1628
|
+
function clone(val, path = "") {
|
|
1629
|
+
if (val === null || val === void 0) {
|
|
1630
|
+
return val;
|
|
1631
|
+
}
|
|
1632
|
+
if (typeof val !== "object") {
|
|
1633
|
+
if (typeof val === "string" || typeof val === "number" || typeof val === "boolean") {
|
|
1634
|
+
return val;
|
|
1369
1635
|
}
|
|
1370
|
-
|
|
1636
|
+
const atPath = path ? ` at path "${path}"` : "";
|
|
1637
|
+
if (typeof val === "bigint") {
|
|
1638
|
+
throw new Error(
|
|
1639
|
+
`r-state-tree: snapshots do not support bigint${atPath}. Snapshots are JSON-only (primitives, arrays, plain objects, Dates as ISO strings).`
|
|
1640
|
+
);
|
|
1641
|
+
}
|
|
1642
|
+
if (typeof val === "symbol") {
|
|
1643
|
+
throw new Error(
|
|
1644
|
+
`r-state-tree: snapshots do not support symbol${atPath}. Snapshots are JSON-only (primitives, arrays, plain objects, Dates as ISO strings).`
|
|
1645
|
+
);
|
|
1646
|
+
}
|
|
1647
|
+
if (typeof val === "function") {
|
|
1648
|
+
throw new Error(
|
|
1649
|
+
`r-state-tree: snapshots do not support function${atPath}. Snapshots are JSON-only (primitives, arrays, plain objects, Dates as ISO strings).`
|
|
1650
|
+
);
|
|
1651
|
+
}
|
|
1652
|
+
throw new Error(
|
|
1653
|
+
`r-state-tree: snapshots do not support ${typeof val}${atPath}. Snapshots are JSON-only (primitives, arrays, plain objects, Dates as ISO strings).`
|
|
1654
|
+
);
|
|
1655
|
+
}
|
|
1656
|
+
if (val instanceof Signal) {
|
|
1657
|
+
return clone(
|
|
1658
|
+
val.value,
|
|
1659
|
+
path
|
|
1660
|
+
);
|
|
1661
|
+
}
|
|
1662
|
+
if (val instanceof Date) {
|
|
1663
|
+
return val.toISOString();
|
|
1664
|
+
}
|
|
1665
|
+
if (Array.isArray(val)) {
|
|
1666
|
+
return val.map(
|
|
1667
|
+
(v, i) => clone(v, path ? `${path}[${i}]` : `[${i}]`)
|
|
1668
|
+
);
|
|
1371
1669
|
}
|
|
1372
|
-
|
|
1670
|
+
if (!isPlainObject(val)) {
|
|
1671
|
+
const typeName = getTypeName(val);
|
|
1672
|
+
const atPath = path ? ` at path "${path}"` : "";
|
|
1673
|
+
throw new Error(
|
|
1674
|
+
`r-state-tree: snapshots do not support ${typeName}${atPath}. Snapshots are JSON-only (primitives, arrays, plain objects, Dates as ISO strings).`
|
|
1675
|
+
);
|
|
1676
|
+
}
|
|
1677
|
+
const keys = Object.keys(val);
|
|
1678
|
+
const cloned = {};
|
|
1679
|
+
for (let i = 0; i < keys.length; i++) {
|
|
1680
|
+
const key = keys[i];
|
|
1681
|
+
const keyPath = path ? `${path}.${key}` : key;
|
|
1682
|
+
cloned[key] = clone(val[key], keyPath);
|
|
1683
|
+
}
|
|
1684
|
+
return cloned;
|
|
1685
|
+
}
|
|
1686
|
+
function getTypeName(val) {
|
|
1687
|
+
if (val instanceof Map) return "Map";
|
|
1688
|
+
if (val instanceof Set) return "Set";
|
|
1689
|
+
if (val instanceof WeakMap) return "WeakMap";
|
|
1690
|
+
if (val instanceof WeakSet) return "WeakSet";
|
|
1691
|
+
if (val instanceof RegExp) return "RegExp";
|
|
1692
|
+
if (val instanceof Error) return "Error";
|
|
1693
|
+
if (val instanceof Promise) return "Promise";
|
|
1694
|
+
const proto = Object.getPrototypeOf(val);
|
|
1695
|
+
if (proto?.constructor?.name && proto.constructor.name !== "Object") {
|
|
1696
|
+
return `class instance (${proto.constructor.name})`;
|
|
1697
|
+
}
|
|
1698
|
+
return "non-plain object";
|
|
1373
1699
|
}
|
|
1374
1700
|
function getDiff(o1, o2, getConfig) {
|
|
1375
1701
|
const config = getConfig(o2);
|
|
@@ -1442,7 +1768,9 @@ function updateProps(props, newProps) {
|
|
|
1442
1768
|
}
|
|
1443
1769
|
});
|
|
1444
1770
|
if (newProps.models) {
|
|
1445
|
-
if (!props.models
|
|
1771
|
+
if (!props.models || !isObservable(props.models)) {
|
|
1772
|
+
props.models = getObservable(props.models || {});
|
|
1773
|
+
}
|
|
1446
1774
|
Object.assign(props.models, newProps.models);
|
|
1447
1775
|
}
|
|
1448
1776
|
});
|
|
@@ -1666,7 +1994,9 @@ class StoreAdministration extends PreactObjectAdministration {
|
|
|
1666
1994
|
}
|
|
1667
1995
|
}
|
|
1668
1996
|
getModelRef(name) {
|
|
1669
|
-
|
|
1997
|
+
const models = this.proxy.props.models;
|
|
1998
|
+
const ref = models?.[name] ?? null;
|
|
1999
|
+
return ref;
|
|
1670
2000
|
}
|
|
1671
2001
|
isRoot() {
|
|
1672
2002
|
return !this.parent;
|
|
@@ -2004,11 +2334,12 @@ class ObservableListener {
|
|
|
2004
2334
|
class ChildModelsAdministration extends ArrayAdministration {
|
|
2005
2335
|
set(index, newValue) {
|
|
2006
2336
|
return batch(() => {
|
|
2007
|
-
super.set(index, newValue);
|
|
2337
|
+
const result = super.set(index, newValue);
|
|
2008
2338
|
const sourceValue = getSource(newValue);
|
|
2009
2339
|
if (this.source[index] !== sourceValue) {
|
|
2010
2340
|
notifyArrayUpdate(this.proxy, index, this.source[index], sourceValue);
|
|
2011
2341
|
}
|
|
2342
|
+
return result;
|
|
2012
2343
|
});
|
|
2013
2344
|
}
|
|
2014
2345
|
spliceWithArray(index, deleteCount, newItems) {
|
|
@@ -2126,9 +2457,7 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2126
2457
|
adm.setId(name, value);
|
|
2127
2458
|
break;
|
|
2128
2459
|
}
|
|
2129
|
-
case ModelCfgTypes.state:
|
|
2130
|
-
case ModelCfgTypes.stateShallow:
|
|
2131
|
-
case ModelCfgTypes.stateSignal: {
|
|
2460
|
+
case ModelCfgTypes.state: {
|
|
2132
2461
|
adm.setState(name, value);
|
|
2133
2462
|
break;
|
|
2134
2463
|
}
|
|
@@ -2198,12 +2527,14 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2198
2527
|
setState(name, value) {
|
|
2199
2528
|
const oldValue = this.source[name];
|
|
2200
2529
|
if (value !== oldValue) {
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2530
|
+
batch(() => {
|
|
2531
|
+
PreactObjectAdministration.proxyTraps.set(
|
|
2532
|
+
this.source,
|
|
2533
|
+
name,
|
|
2534
|
+
value,
|
|
2535
|
+
this.proxy
|
|
2536
|
+
);
|
|
2537
|
+
});
|
|
2207
2538
|
}
|
|
2208
2539
|
}
|
|
2209
2540
|
setId(name, v) {
|
|
@@ -2257,9 +2588,9 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2257
2588
|
getModelAdm(currentValue).detach();
|
|
2258
2589
|
} else if (Array.isArray(currentValue)) {
|
|
2259
2590
|
const oldModels = currentValue;
|
|
2260
|
-
const newModelSet = new Set(newModels);
|
|
2591
|
+
const newModelSet = new Set(newModels.map((m) => getSource(m)));
|
|
2261
2592
|
oldModels.forEach(
|
|
2262
|
-
(child2) => newModelSet.has(child2) || getModelAdm(child2).detach()
|
|
2593
|
+
(child2) => newModelSet.has(getSource(child2)) || getModelAdm(child2).detach()
|
|
2263
2594
|
);
|
|
2264
2595
|
this.modelsTraceUnsub.get(name)?.();
|
|
2265
2596
|
}
|
|
@@ -2282,8 +2613,8 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2282
2613
|
})
|
|
2283
2614
|
);
|
|
2284
2615
|
newModels.forEach((child2) => {
|
|
2285
|
-
const oldModelSet = Array.isArray(currentValue) ? new Set(currentValue) : /* @__PURE__ */ new Set();
|
|
2286
|
-
if (!oldModelSet.has(child2)) {
|
|
2616
|
+
const oldModelSet = Array.isArray(currentValue) ? new Set(currentValue.map((m) => getSource(m))) : /* @__PURE__ */ new Set();
|
|
2617
|
+
if (!oldModelSet.has(getSource(child2))) {
|
|
2287
2618
|
const internalModel = getModelAdm(child2);
|
|
2288
2619
|
internalModel.attach(this, name);
|
|
2289
2620
|
}
|
|
@@ -2397,11 +2728,12 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2397
2728
|
toJSON() {
|
|
2398
2729
|
return Object.keys(this.configuration).reduce((json, key) => {
|
|
2399
2730
|
switch (this.configuration[key].type) {
|
|
2400
|
-
case ModelCfgTypes.state:
|
|
2401
|
-
|
|
2402
|
-
|
|
2731
|
+
case ModelCfgTypes.state: {
|
|
2732
|
+
json[key] = clone(this.proxy[key], key);
|
|
2733
|
+
break;
|
|
2734
|
+
}
|
|
2403
2735
|
case ModelCfgTypes.id:
|
|
2404
|
-
json[key] = clone(getSource(this.proxy[key]));
|
|
2736
|
+
json[key] = clone(getSource(this.proxy[key]), key);
|
|
2405
2737
|
break;
|
|
2406
2738
|
case ModelCfgTypes.modelRef:
|
|
2407
2739
|
const model2 = this.proxy[key];
|
|
@@ -2465,8 +2797,6 @@ class ModelAdministration extends PreactObjectAdministration {
|
|
|
2465
2797
|
const value = snapshot[key];
|
|
2466
2798
|
switch (type) {
|
|
2467
2799
|
case ModelCfgTypes.state:
|
|
2468
|
-
case ModelCfgTypes.stateShallow:
|
|
2469
|
-
case ModelCfgTypes.stateSignal:
|
|
2470
2800
|
this.proxy[key] = value;
|
|
2471
2801
|
break;
|
|
2472
2802
|
case ModelCfgTypes.modelRef:
|
|
@@ -2660,6 +2990,73 @@ function createContext(defaultValue) {
|
|
|
2660
2990
|
}
|
|
2661
2991
|
};
|
|
2662
2992
|
}
|
|
2993
|
+
function toObservableTree(value) {
|
|
2994
|
+
return toObservableTreeInternal(value, /* @__PURE__ */ new Set(), "");
|
|
2995
|
+
}
|
|
2996
|
+
function buildPath(currentPath, key) {
|
|
2997
|
+
if (typeof key === "number") {
|
|
2998
|
+
return `${currentPath}[${key}]`;
|
|
2999
|
+
}
|
|
3000
|
+
return currentPath ? `${currentPath}.${key}` : key;
|
|
3001
|
+
}
|
|
3002
|
+
function toObservableTreeInternal(value, ancestorPath, path) {
|
|
3003
|
+
if (value === null || typeof value !== "object") {
|
|
3004
|
+
return value;
|
|
3005
|
+
}
|
|
3006
|
+
if (Array.isArray(value)) {
|
|
3007
|
+
if (ancestorPath.has(value)) {
|
|
3008
|
+
throw new Error(
|
|
3009
|
+
`r-state-tree: toObservableTree does not support circular references (cycle detected at path "${path}")`
|
|
3010
|
+
);
|
|
3011
|
+
}
|
|
3012
|
+
ancestorPath.add(value);
|
|
3013
|
+
const toWrap = [];
|
|
3014
|
+
for (let i = 0; i < value.length; i++) {
|
|
3015
|
+
const element = value[i];
|
|
3016
|
+
if (Array.isArray(element) || isPlainObject(element)) {
|
|
3017
|
+
toWrap.push({ index: i, element });
|
|
3018
|
+
}
|
|
3019
|
+
}
|
|
3020
|
+
const proxy = observable(value);
|
|
3021
|
+
for (const { index, element } of toWrap) {
|
|
3022
|
+
proxy[index] = toObservableTreeInternal(
|
|
3023
|
+
element,
|
|
3024
|
+
ancestorPath,
|
|
3025
|
+
buildPath(path, index)
|
|
3026
|
+
);
|
|
3027
|
+
}
|
|
3028
|
+
ancestorPath.delete(value);
|
|
3029
|
+
return proxy;
|
|
3030
|
+
}
|
|
3031
|
+
if (isPlainObject(value)) {
|
|
3032
|
+
if (ancestorPath.has(value)) {
|
|
3033
|
+
throw new Error(
|
|
3034
|
+
`r-state-tree: toObservableTree does not support circular references (cycle detected at path "${path}")`
|
|
3035
|
+
);
|
|
3036
|
+
}
|
|
3037
|
+
ancestorPath.add(value);
|
|
3038
|
+
const toWrap = [];
|
|
3039
|
+
const keys = Object.keys(value);
|
|
3040
|
+
for (let i = 0; i < keys.length; i++) {
|
|
3041
|
+
const key = keys[i];
|
|
3042
|
+
const propValue = value[key];
|
|
3043
|
+
if (Array.isArray(propValue) || isPlainObject(propValue)) {
|
|
3044
|
+
toWrap.push({ key, propValue });
|
|
3045
|
+
}
|
|
3046
|
+
}
|
|
3047
|
+
const proxy = observable(value);
|
|
3048
|
+
for (const { key, propValue } of toWrap) {
|
|
3049
|
+
proxy[key] = toObservableTreeInternal(
|
|
3050
|
+
propValue,
|
|
3051
|
+
ancestorPath,
|
|
3052
|
+
buildPath(path, key)
|
|
3053
|
+
);
|
|
3054
|
+
}
|
|
3055
|
+
ancestorPath.delete(value);
|
|
3056
|
+
return proxy;
|
|
3057
|
+
}
|
|
3058
|
+
return value;
|
|
3059
|
+
}
|
|
2663
3060
|
function makeDecorator(type) {
|
|
2664
3061
|
return function(value, context) {
|
|
2665
3062
|
context.metadata[context.name] = type;
|
|
@@ -2682,10 +3079,7 @@ const child = makeChildDecorator(childType);
|
|
|
2682
3079
|
const modelRef = makeChildDecorator(modelRefType);
|
|
2683
3080
|
const model = makeDecorator(modelType);
|
|
2684
3081
|
const id = makeDecorator(idType);
|
|
2685
|
-
const state =
|
|
2686
|
-
shallow: makeDecorator(stateShallowType),
|
|
2687
|
-
signal: makeDecorator(stateSignalType)
|
|
2688
|
-
});
|
|
3082
|
+
const state = makeDecorator(stateType);
|
|
2689
3083
|
export {
|
|
2690
3084
|
Model,
|
|
2691
3085
|
Observable,
|
|
@@ -2710,9 +3104,10 @@ export {
|
|
|
2710
3104
|
reaction,
|
|
2711
3105
|
reportChanged,
|
|
2712
3106
|
reportObserved,
|
|
2713
|
-
|
|
3107
|
+
signal,
|
|
2714
3108
|
source,
|
|
2715
3109
|
state,
|
|
3110
|
+
toObservableTree,
|
|
2716
3111
|
toSnapshot,
|
|
2717
3112
|
unmount,
|
|
2718
3113
|
untracked2 as untracked,
|