@legendapp/state 0.16.1 → 0.17.0-next.0
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/index.d.ts +1 -0
- package/index.js +262 -133
- package/index.js.map +1 -1
- package/index.mjs +260 -134
- package/index.mjs.map +1 -1
- package/package.json +1 -1
- package/react-components.js.map +1 -1
- package/react-components.mjs.map +1 -1
- package/react.js +131 -151
- package/react.js.map +1 -1
- package/react.mjs +133 -153
- package/react.mjs.map +1 -1
- package/src/ObservablePrimitive.d.ts +11 -0
- package/src/notify.d.ts +3 -0
- package/src/observable.d.ts +9 -9
- package/src/observableInterfaces.d.ts +15 -16
- package/src/observe.d.ts +1 -1
- package/src/onChange.d.ts +1 -1
- package/src/react/flow.d.ts +2 -1
- package/src/react/useComputed.d.ts +2 -6
- package/src/react/useObservable.d.ts +5 -2
- package/src/react/useObserve.d.ts +1 -1
- package/src/react/useSelector.d.ts +1 -0
- package/src/react-components/react-components.d.ts +5 -5
- package/src/react-native-components/rn-components.d.ts +2 -2
- package/src/tracking.d.ts +3 -0
- package/trace.js +1 -1
- package/trace.js.map +1 -1
- package/trace.mjs +1 -1
- package/trace.mjs.map +1 -1
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -7,6 +7,7 @@ const tracking = {
|
|
|
7
7
|
nodes: undefined,
|
|
8
8
|
listeners: undefined,
|
|
9
9
|
updates: undefined,
|
|
10
|
+
callbacksMarked: new Set(),
|
|
10
11
|
};
|
|
11
12
|
function beginTracking() {
|
|
12
13
|
// Keep a copy of the previous tracking context so it can be restored
|
|
@@ -59,6 +60,22 @@ function checkTracking(node, track) {
|
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
62
|
}
|
|
63
|
+
let timeoutSweep;
|
|
64
|
+
function scheduleSweep() {
|
|
65
|
+
if (timeoutSweep) {
|
|
66
|
+
clearTimeout(timeoutSweep);
|
|
67
|
+
}
|
|
68
|
+
timeoutSweep = setTimeout(sweep, 0);
|
|
69
|
+
}
|
|
70
|
+
function sweep() {
|
|
71
|
+
timeoutSweep = undefined;
|
|
72
|
+
if (tracking.callbacksMarked.size)
|
|
73
|
+
console.log('sweeping');
|
|
74
|
+
for (let marked of tracking.callbacksMarked) {
|
|
75
|
+
marked();
|
|
76
|
+
}
|
|
77
|
+
tracking.callbacksMarked.clear();
|
|
78
|
+
}
|
|
62
79
|
|
|
63
80
|
/** @internal */
|
|
64
81
|
function isArray(obj) {
|
|
@@ -92,6 +109,15 @@ function isBoolean(obj) {
|
|
|
92
109
|
function isEmpty(obj) {
|
|
93
110
|
return obj && Object.keys(obj).length === 0;
|
|
94
111
|
}
|
|
112
|
+
const mapPrimitives = new Map([
|
|
113
|
+
['boolean', true],
|
|
114
|
+
['string', true],
|
|
115
|
+
['number', true],
|
|
116
|
+
]);
|
|
117
|
+
/** @internal */
|
|
118
|
+
function isActualPrimitive(arg) {
|
|
119
|
+
return mapPrimitives.has(typeof arg);
|
|
120
|
+
}
|
|
95
121
|
|
|
96
122
|
const symbolDateModified = Symbol('dateModified');
|
|
97
123
|
const symbolIsObservable = Symbol('isObservable');
|
|
@@ -160,48 +186,32 @@ function getChildNode(node, key) {
|
|
|
160
186
|
return child;
|
|
161
187
|
}
|
|
162
188
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
const value = ((_b = (_a = target).get) === null || _b === void 0 ? void 0 : _b.call(_a)) || target;
|
|
192
|
-
for (const key in source) {
|
|
193
|
-
if (isObject(source[key])) {
|
|
194
|
-
if (!value[key] || !isObject(value[key])) {
|
|
195
|
-
needsSet ? target.set(key, {}) : (target[key] = {});
|
|
196
|
-
}
|
|
197
|
-
mergeIntoObservable(target[key], source[key]);
|
|
198
|
-
}
|
|
199
|
-
else {
|
|
200
|
-
needsSet ? target.set(key, source[key]) : (target[key] = source[key]);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
return mergeIntoObservable(target, ...sources);
|
|
189
|
+
/******************************************************************************
|
|
190
|
+
Copyright (c) Microsoft Corporation.
|
|
191
|
+
|
|
192
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
193
|
+
purpose with or without fee is hereby granted.
|
|
194
|
+
|
|
195
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
196
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
197
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
198
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
199
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
200
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
201
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
202
|
+
***************************************************************************** */
|
|
203
|
+
|
|
204
|
+
function __classPrivateFieldGet(receiver, state, kind, f) {
|
|
205
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
206
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
207
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function __classPrivateFieldSet(receiver, state, value, kind, f) {
|
|
211
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
212
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
213
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
214
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
205
215
|
}
|
|
206
216
|
|
|
207
217
|
let timeout;
|
|
@@ -269,14 +279,185 @@ function endBatch(force) {
|
|
|
269
279
|
}
|
|
270
280
|
}
|
|
271
281
|
|
|
272
|
-
function
|
|
282
|
+
function createPreviousHandler(value, path, prevAtPath) {
|
|
283
|
+
// Create a function that clones the current state and injects the previous data at the changed path
|
|
284
|
+
return function () {
|
|
285
|
+
let clone = value ? JSON.parse(JSON.stringify(value)) : path.length > 0 ? {} : value;
|
|
286
|
+
let o = clone;
|
|
287
|
+
if (path.length > 0) {
|
|
288
|
+
let i;
|
|
289
|
+
for (i = 0; i < path.length - 1; i++) {
|
|
290
|
+
o = o[path[i]];
|
|
291
|
+
}
|
|
292
|
+
o[path[i]] = prevAtPath;
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
clone = prevAtPath;
|
|
296
|
+
}
|
|
297
|
+
return clone;
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
function doNotify(node, value, path, valueAtPath, prevAtPath, level, whenOptimizedOnlyIf) {
|
|
301
|
+
const listeners = node.listeners;
|
|
302
|
+
if (listeners) {
|
|
303
|
+
let getPrevious;
|
|
304
|
+
for (let listenerFn of listeners) {
|
|
305
|
+
const { track, noArgs } = listenerFn;
|
|
306
|
+
const ok = track === exports.Tracking.shallow
|
|
307
|
+
? level <= 0
|
|
308
|
+
: track === exports.Tracking.optimized
|
|
309
|
+
? whenOptimizedOnlyIf && level <= 0
|
|
310
|
+
: true;
|
|
311
|
+
// Notify if listener is not shallow or if this is the first level
|
|
312
|
+
if (ok) {
|
|
313
|
+
// Create a function to get the previous data. Computing a clone of previous data can be expensive if doing
|
|
314
|
+
// it often, so leave it up to the caller.
|
|
315
|
+
if (!noArgs && !getPrevious) {
|
|
316
|
+
getPrevious = createPreviousHandler(value, path, prevAtPath);
|
|
317
|
+
}
|
|
318
|
+
batchNotify(noArgs
|
|
319
|
+
? listenerFn.listener
|
|
320
|
+
: {
|
|
321
|
+
cb: listenerFn.listener,
|
|
322
|
+
value,
|
|
323
|
+
getPrevious,
|
|
324
|
+
path,
|
|
325
|
+
valueAtPath,
|
|
326
|
+
prevAtPath,
|
|
327
|
+
node,
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
function _notifyParents(node, value, path, valueAtPath, prevAtPath, level, whenOptimizedOnlyIf) {
|
|
334
|
+
// Do the notify
|
|
335
|
+
doNotify(node, value, path, valueAtPath, prevAtPath, level, whenOptimizedOnlyIf);
|
|
336
|
+
// If not root notify up through parents
|
|
337
|
+
if (node.parent) {
|
|
338
|
+
const parent = node.parent;
|
|
339
|
+
if (parent) {
|
|
340
|
+
const parentValue = getNodeValue(parent);
|
|
341
|
+
_notifyParents(parent, parentValue, [node.key].concat(path), valueAtPath, prevAtPath, level + 1, whenOptimizedOnlyIf);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
function notify(node, value, prev, level, whenOptimizedOnlyIf) {
|
|
346
|
+
// Notify self and up through parents
|
|
347
|
+
_notifyParents(node, value, [], value, prev, level, whenOptimizedOnlyIf);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
function onChange(node, callback, track, noArgs, markAndSweep) {
|
|
273
351
|
let listeners = node.listeners;
|
|
274
352
|
if (!listeners) {
|
|
275
353
|
node.listeners = listeners = new Set();
|
|
276
354
|
}
|
|
277
|
-
|
|
355
|
+
let dispose;
|
|
356
|
+
let listener;
|
|
357
|
+
let c = callback;
|
|
358
|
+
if (markAndSweep) {
|
|
359
|
+
c = function () {
|
|
360
|
+
tracking.callbacksMarked.add(dispose);
|
|
361
|
+
callback();
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
listener = { listener: c, track: track, noArgs };
|
|
278
365
|
listeners.add(listener);
|
|
279
|
-
return () =>
|
|
366
|
+
return (dispose = () => {
|
|
367
|
+
if (markAndSweep) {
|
|
368
|
+
tracking.callbacksMarked.delete(dispose);
|
|
369
|
+
}
|
|
370
|
+
listeners.delete(listener);
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
var _ObservablePrimitive_node;
|
|
375
|
+
class ObservablePrimitive {
|
|
376
|
+
constructor(node) {
|
|
377
|
+
_ObservablePrimitive_node.set(this, void 0);
|
|
378
|
+
__classPrivateFieldSet(this, _ObservablePrimitive_node, node, "f");
|
|
379
|
+
this.set = this.set.bind(this);
|
|
380
|
+
}
|
|
381
|
+
get value() {
|
|
382
|
+
const node = __classPrivateFieldGet(this, _ObservablePrimitive_node, "f");
|
|
383
|
+
updateTracking(node);
|
|
384
|
+
return node.root._;
|
|
385
|
+
}
|
|
386
|
+
set value(value) {
|
|
387
|
+
if (__classPrivateFieldGet(this, _ObservablePrimitive_node, "f").root.locked) {
|
|
388
|
+
throw new Error(process.env.NODE_ENV === 'development'
|
|
389
|
+
? '[legend-state] Cannot modify an observable while it is locked. Please make sure that you unlock the observable before making changes.'
|
|
390
|
+
: '[legend-state] Modified locked observable');
|
|
391
|
+
}
|
|
392
|
+
const prev = __classPrivateFieldGet(this, _ObservablePrimitive_node, "f").root._;
|
|
393
|
+
__classPrivateFieldGet(this, _ObservablePrimitive_node, "f").root._ = value;
|
|
394
|
+
doNotify(__classPrivateFieldGet(this, _ObservablePrimitive_node, "f"), value, [], value, prev, 0);
|
|
395
|
+
}
|
|
396
|
+
get() {
|
|
397
|
+
return this.value;
|
|
398
|
+
}
|
|
399
|
+
set(value) {
|
|
400
|
+
if (isFunction(value)) {
|
|
401
|
+
value = value(__classPrivateFieldGet(this, _ObservablePrimitive_node, "f").root._);
|
|
402
|
+
}
|
|
403
|
+
this.value = value;
|
|
404
|
+
return this;
|
|
405
|
+
}
|
|
406
|
+
onChange(cb, track, noArgs, markAndSweep) {
|
|
407
|
+
return onChange(__classPrivateFieldGet(this, _ObservablePrimitive_node, "f"), cb, track, noArgs, markAndSweep);
|
|
408
|
+
}
|
|
409
|
+
obs() {
|
|
410
|
+
return this;
|
|
411
|
+
}
|
|
412
|
+
/** @internal */
|
|
413
|
+
getNode() {
|
|
414
|
+
return __classPrivateFieldGet(this, _ObservablePrimitive_node, "f");
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
_ObservablePrimitive_node = new WeakMap();
|
|
418
|
+
|
|
419
|
+
function isObservable(obs) {
|
|
420
|
+
return obs && (obs instanceof ObservablePrimitive || !!obs[symbolIsObservable]);
|
|
421
|
+
}
|
|
422
|
+
function getNode(obs) {
|
|
423
|
+
return obs instanceof ObservablePrimitive ? obs.getNode() : obs[symbolGetNode];
|
|
424
|
+
}
|
|
425
|
+
function lockObservable(obs, value) {
|
|
426
|
+
var _a;
|
|
427
|
+
const root = (_a = getNode(obs)) === null || _a === void 0 ? void 0 : _a.root;
|
|
428
|
+
if (root) {
|
|
429
|
+
root.locked = value;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
function mergeIntoObservable(target, ...sources) {
|
|
433
|
+
var _a, _b;
|
|
434
|
+
if (!sources.length)
|
|
435
|
+
return target;
|
|
436
|
+
const source = sources.shift();
|
|
437
|
+
const needsSet = isObservable(target);
|
|
438
|
+
if (isObject(target) && isObject(source)) {
|
|
439
|
+
if (source[symbolDateModified]) {
|
|
440
|
+
if (needsSet) {
|
|
441
|
+
target.set(symbolDateModified, source[symbolDateModified]);
|
|
442
|
+
}
|
|
443
|
+
else {
|
|
444
|
+
target[symbolDateModified] = source[symbolDateModified];
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
const value = ((_b = (_a = target).get) === null || _b === void 0 ? void 0 : _b.call(_a)) || target;
|
|
448
|
+
for (const key in source) {
|
|
449
|
+
if (isObject(source[key])) {
|
|
450
|
+
if (!value[key] || !isObject(value[key])) {
|
|
451
|
+
needsSet ? target.set(key, {}) : (target[key] = {});
|
|
452
|
+
}
|
|
453
|
+
mergeIntoObservable(target[key], source[key]);
|
|
454
|
+
}
|
|
455
|
+
else {
|
|
456
|
+
needsSet ? target.set(key, source[key]) : (target[key] = source[key]);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
return mergeIntoObservable(target, ...sources);
|
|
280
461
|
}
|
|
281
462
|
|
|
282
463
|
let lastAccessedNode;
|
|
@@ -305,21 +486,22 @@ const objectFns = new Map([
|
|
|
305
486
|
['delete', deleteFn],
|
|
306
487
|
]);
|
|
307
488
|
// Override primitives
|
|
308
|
-
const wrapFn = (fn) => function (...args) {
|
|
489
|
+
const wrapFn = (name, fn) => function (...args) {
|
|
309
490
|
if (lastAccessedNode && lastAccessedPrimitive) {
|
|
310
491
|
const node = getChildNode(lastAccessedNode, lastAccessedPrimitive);
|
|
311
492
|
if (getNodeValue(node) === this) {
|
|
312
493
|
return fn(node, ...args);
|
|
313
494
|
}
|
|
314
495
|
else if (process.env.NODE_ENV === 'development') {
|
|
315
|
-
console.error(`[legend-state] Error calling ${
|
|
496
|
+
console.error(`[legend-state] Error calling ${name} on a primitive with value [${this}]. Please ensure that if you are saving references to observable functions on primitive values that you use obs() first, like obs.primitive.obs().set.`);
|
|
497
|
+
debugger;
|
|
316
498
|
}
|
|
317
499
|
}
|
|
318
500
|
};
|
|
319
501
|
const toOverride = [Number, Boolean, String];
|
|
320
502
|
for (let [key, fn] of objectFns) {
|
|
321
503
|
for (let i = 0; i < toOverride.length; i++) {
|
|
322
|
-
toOverride[i].prototype[key] = wrapFn(fn);
|
|
504
|
+
toOverride[i].prototype[key] = wrapFn(key, fn);
|
|
323
505
|
}
|
|
324
506
|
}
|
|
325
507
|
function collectionSetter(node, target, prop, ...args) {
|
|
@@ -377,7 +559,7 @@ function updateNodes(parent, obj, prevValue) {
|
|
|
377
559
|
updateNodes(child, undefined, prev);
|
|
378
560
|
}
|
|
379
561
|
if (child.listeners) {
|
|
380
|
-
|
|
562
|
+
doNotify(child, undefined, [], undefined, prev, 0);
|
|
381
563
|
}
|
|
382
564
|
}
|
|
383
565
|
}
|
|
@@ -431,7 +613,7 @@ function updateNodes(parent, obj, prevValue) {
|
|
|
431
613
|
// But do not notify child if the parent is an array with changing length -
|
|
432
614
|
// the array's listener will cover it
|
|
433
615
|
if (child.listeners) {
|
|
434
|
-
|
|
616
|
+
doNotify(child, value, [], value, prev, 0, !isArrDiff);
|
|
435
617
|
}
|
|
436
618
|
}
|
|
437
619
|
}
|
|
@@ -491,7 +673,7 @@ const proxyHandler = {
|
|
|
491
673
|
};
|
|
492
674
|
}
|
|
493
675
|
let value = getNodeValue(node);
|
|
494
|
-
if (!node.parent && isPrimitive(value) && p === 'value') {
|
|
676
|
+
if (!node.parent && isPrimitive(value) && node.root._ === value && p === 'value') {
|
|
495
677
|
updateTracking(node);
|
|
496
678
|
return value;
|
|
497
679
|
}
|
|
@@ -686,73 +868,6 @@ function setProp(node, key, newValue, level) {
|
|
|
686
868
|
inSetFn = false;
|
|
687
869
|
return isRoot ? getProxy(node) : getProxy(node, key);
|
|
688
870
|
}
|
|
689
|
-
function createPreviousHandler(value, path, prevAtPath) {
|
|
690
|
-
// Create a function that clones the current state and injects the previous data at the changed path
|
|
691
|
-
return function () {
|
|
692
|
-
let clone = value ? JSON.parse(JSON.stringify(value)) : path.length > 0 ? {} : value;
|
|
693
|
-
let o = clone;
|
|
694
|
-
if (path.length > 0) {
|
|
695
|
-
let i;
|
|
696
|
-
for (i = 0; i < path.length - 1; i++) {
|
|
697
|
-
o = o[path[i]];
|
|
698
|
-
}
|
|
699
|
-
o[path[i]] = prevAtPath;
|
|
700
|
-
}
|
|
701
|
-
else {
|
|
702
|
-
clone = prevAtPath;
|
|
703
|
-
}
|
|
704
|
-
return clone;
|
|
705
|
-
};
|
|
706
|
-
}
|
|
707
|
-
function _notify(node, value, path, valueAtPath, prevAtPath, level, whenOptimizedOnlyIf) {
|
|
708
|
-
const listeners = node.listeners;
|
|
709
|
-
if (listeners) {
|
|
710
|
-
let getPrevious;
|
|
711
|
-
for (let listenerFn of listeners) {
|
|
712
|
-
const { track, noArgs } = listenerFn;
|
|
713
|
-
const ok = track === exports.Tracking.shallow
|
|
714
|
-
? level <= 0
|
|
715
|
-
: track === exports.Tracking.optimized
|
|
716
|
-
? whenOptimizedOnlyIf && level <= 0
|
|
717
|
-
: true;
|
|
718
|
-
// Notify if listener is not shallow or if this is the first level
|
|
719
|
-
if (ok) {
|
|
720
|
-
// Create a function to get the previous data. Computing a clone of previous data can be expensive if doing
|
|
721
|
-
// it often, so leave it up to the caller.
|
|
722
|
-
if (!getPrevious) {
|
|
723
|
-
getPrevious = createPreviousHandler(value, path, prevAtPath);
|
|
724
|
-
}
|
|
725
|
-
batchNotify(noArgs
|
|
726
|
-
? listenerFn.listener
|
|
727
|
-
: {
|
|
728
|
-
cb: listenerFn.listener,
|
|
729
|
-
value,
|
|
730
|
-
getPrevious,
|
|
731
|
-
path,
|
|
732
|
-
valueAtPath,
|
|
733
|
-
prevAtPath,
|
|
734
|
-
node,
|
|
735
|
-
});
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
function _notifyParents(node, value, path, valueAtPath, prevAtPath, level, whenOptimizedOnlyIf) {
|
|
741
|
-
// Do the notify
|
|
742
|
-
_notify(node, value, path, valueAtPath, prevAtPath, level, whenOptimizedOnlyIf);
|
|
743
|
-
// If not root notify up through parents
|
|
744
|
-
if (node.parent) {
|
|
745
|
-
const parent = node.parent;
|
|
746
|
-
if (parent) {
|
|
747
|
-
const parentValue = getNodeValue(parent);
|
|
748
|
-
_notifyParents(parent, parentValue, [node.key].concat(path), valueAtPath, prevAtPath, level + 1, whenOptimizedOnlyIf);
|
|
749
|
-
}
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
function notify(node, value, prev, level, whenOptimizedOnlyIf) {
|
|
753
|
-
// Notify self and up through parents
|
|
754
|
-
_notifyParents(node, value, [], value, prev, level, whenOptimizedOnlyIf);
|
|
755
|
-
}
|
|
756
871
|
function assign(node, value) {
|
|
757
872
|
const proxy = getProxy(node);
|
|
758
873
|
beginBatch();
|
|
@@ -788,25 +903,31 @@ function observable(value, safe) {
|
|
|
788
903
|
id: nextNodeID.current++,
|
|
789
904
|
root: obs,
|
|
790
905
|
};
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
906
|
+
if (isActualPrimitive(value)) {
|
|
907
|
+
// @ts-ignore
|
|
908
|
+
return new ObservablePrimitive(node);
|
|
909
|
+
}
|
|
910
|
+
else {
|
|
911
|
+
const proxy = getProxy(node);
|
|
912
|
+
if (promise) {
|
|
913
|
+
promise.catch((error) => {
|
|
914
|
+
proxy.set({ error });
|
|
915
|
+
});
|
|
916
|
+
promise.then((value) => {
|
|
917
|
+
proxy.set(value);
|
|
918
|
+
});
|
|
919
|
+
}
|
|
920
|
+
return proxy;
|
|
799
921
|
}
|
|
800
|
-
return proxy;
|
|
801
922
|
}
|
|
802
923
|
|
|
803
|
-
function setupTracking(nodes, update, noArgs) {
|
|
924
|
+
function setupTracking(nodes, update, noArgs, markAndSweep) {
|
|
804
925
|
let listeners = [];
|
|
805
926
|
// Listen to tracked nodes
|
|
806
927
|
if (nodes) {
|
|
807
928
|
for (let tracked of nodes.values()) {
|
|
808
929
|
const { node, track } = tracked;
|
|
809
|
-
listeners.push(onChange(node, update, track, noArgs));
|
|
930
|
+
listeners.push(onChange(node, update, track, noArgs, markAndSweep));
|
|
810
931
|
}
|
|
811
932
|
}
|
|
812
933
|
return () => {
|
|
@@ -824,7 +945,7 @@ function observe(run) {
|
|
|
824
945
|
// Wrap it in a function so it doesn't pass all the arguments to run()
|
|
825
946
|
let update = function () {
|
|
826
947
|
var _a;
|
|
827
|
-
if (cleanup) {
|
|
948
|
+
if (cleanup && isFunction(cleanup)) {
|
|
828
949
|
cleanup();
|
|
829
950
|
cleanup = undefined;
|
|
830
951
|
}
|
|
@@ -849,7 +970,7 @@ function observe(run) {
|
|
|
849
970
|
update = tracking.updates(update);
|
|
850
971
|
}
|
|
851
972
|
}
|
|
852
|
-
const ret = setupTracking(tracking.nodes, update);
|
|
973
|
+
const ret = setupTracking(tracking.nodes, update, /*noArgs*/ true);
|
|
853
974
|
endTracking(trackingPrev);
|
|
854
975
|
return ret;
|
|
855
976
|
}
|
|
@@ -861,11 +982,14 @@ function computed(compute) {
|
|
|
861
982
|
const val = compute();
|
|
862
983
|
if (obs) {
|
|
863
984
|
// Update the computed value
|
|
985
|
+
lockObservable(obs, false);
|
|
864
986
|
obs.set(val);
|
|
987
|
+
lockObservable(obs, true);
|
|
865
988
|
}
|
|
866
989
|
else {
|
|
867
990
|
// Create the observable on the first run
|
|
868
991
|
obs = observable(val);
|
|
992
|
+
lockObservable(obs, true);
|
|
869
993
|
}
|
|
870
994
|
};
|
|
871
995
|
observe(fn);
|
|
@@ -881,8 +1005,10 @@ function event() {
|
|
|
881
1005
|
// Notify increments the value so that the observable changes
|
|
882
1006
|
obs.value++;
|
|
883
1007
|
},
|
|
884
|
-
on:
|
|
885
|
-
|
|
1008
|
+
on: function (cb) {
|
|
1009
|
+
return obs.onChange(cb);
|
|
1010
|
+
},
|
|
1011
|
+
get: () => obs.get(),
|
|
886
1012
|
};
|
|
887
1013
|
}
|
|
888
1014
|
|
|
@@ -913,6 +1039,7 @@ function when(predicate, effect) {
|
|
|
913
1039
|
return promise || cleanup;
|
|
914
1040
|
}
|
|
915
1041
|
|
|
1042
|
+
exports.ObservablePrimitive = ObservablePrimitive;
|
|
916
1043
|
exports.batch = batch;
|
|
917
1044
|
exports.beginBatch = beginBatch;
|
|
918
1045
|
exports.beginTracking = beginTracking;
|
|
@@ -934,7 +1061,9 @@ exports.mergeIntoObservable = mergeIntoObservable;
|
|
|
934
1061
|
exports.observable = observable;
|
|
935
1062
|
exports.observe = observe;
|
|
936
1063
|
exports.onChange = onChange;
|
|
1064
|
+
exports.scheduleSweep = scheduleSweep;
|
|
937
1065
|
exports.setupTracking = setupTracking;
|
|
1066
|
+
exports.sweep = sweep;
|
|
938
1067
|
exports.symbolDateModified = symbolDateModified;
|
|
939
1068
|
exports.symbolIsObservable = symbolIsObservable;
|
|
940
1069
|
exports.symbolUndef = symbolUndef;
|