@legendapp/state 2.1.0-next.1 → 2.1.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/CHANGELOG.md +7 -0
- package/history.js +1 -1
- package/history.js.map +1 -1
- package/history.mjs +1 -1
- package/history.mjs.map +1 -1
- package/index.d.ts +2 -4
- package/index.js +412 -561
- package/index.js.map +1 -1
- package/index.mjs +412 -561
- package/index.mjs.map +1 -1
- package/package.json +1 -1
- package/persist.d.ts +1 -1
- package/persist.js +16 -3
- package/persist.js.map +1 -1
- package/persist.mjs +16 -5
- package/persist.mjs.map +1 -1
- package/react.d.ts +1 -0
- package/react.js +40 -16
- package/react.js.map +1 -1
- package/react.mjs +42 -19
- package/react.mjs.map +1 -1
- package/src/ObservableObject.d.ts +1 -1
- package/src/createObservable.d.ts +1 -1
- package/src/globals.d.ts +3 -7
- package/src/helpers.d.ts +3 -1
- package/src/observable.d.ts +2 -11
- package/src/observableInterfaces.d.ts +11 -25
- package/src/persist/persistObservable.d.ts +5 -1
- package/src/react/useLegendStatePauseProvider.d.ts +8 -0
package/index.js
CHANGED
|
@@ -60,17 +60,9 @@ const extraPrimitiveActivators = new Map();
|
|
|
60
60
|
const extraPrimitiveProps = new Map();
|
|
61
61
|
const globalState = {
|
|
62
62
|
isLoadingLocal: false,
|
|
63
|
+
isLoadingRemote: false,
|
|
63
64
|
isMerging: false,
|
|
64
|
-
isLoadingRemote$: undefined,
|
|
65
|
-
onChangeRemote: undefined,
|
|
66
65
|
};
|
|
67
|
-
function isObservable(obs) {
|
|
68
|
-
return !!obs && !!obs[symbolGetNode];
|
|
69
|
-
}
|
|
70
|
-
function isComputed(obs) {
|
|
71
|
-
var _a;
|
|
72
|
-
return obs && ((_a = obs[symbolGetNode]) === null || _a === void 0 ? void 0 : _a.isComputed);
|
|
73
|
-
}
|
|
74
66
|
function checkActivate(node) {
|
|
75
67
|
var _a;
|
|
76
68
|
const root = node.root;
|
|
@@ -97,13 +89,12 @@ function setNodeValue(node, newValue) {
|
|
|
97
89
|
const prevValue = parentValue[key];
|
|
98
90
|
const isFunc = isFunction(newValue);
|
|
99
91
|
// Compute newValue if newValue is a function or an observable
|
|
100
|
-
newValue =
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
92
|
+
newValue =
|
|
93
|
+
!parentNode.isAssigning && isFunc
|
|
94
|
+
? newValue(prevValue)
|
|
95
|
+
: isObject(newValue) && (newValue === null || newValue === void 0 ? void 0 : newValue[symbolGetNode])
|
|
96
|
+
? newValue.peek()
|
|
97
|
+
: newValue;
|
|
107
98
|
try {
|
|
108
99
|
parentNode.isSetting = (parentNode.isSetting || 0) + 1;
|
|
109
100
|
// Save the new value
|
|
@@ -137,13 +128,7 @@ function getNodeValue(node) {
|
|
|
137
128
|
}
|
|
138
129
|
return child;
|
|
139
130
|
}
|
|
140
|
-
|
|
141
|
-
const length = originalFunction.length;
|
|
142
|
-
return length > 1
|
|
143
|
-
? (arg1, arg2) => originalFunction(arg1, arg2)
|
|
144
|
-
: (...args) => originalFunction(...args);
|
|
145
|
-
};
|
|
146
|
-
function getChildNode(node, key, asFunction) {
|
|
131
|
+
function getChildNode(node, key) {
|
|
147
132
|
var _a;
|
|
148
133
|
// Get the child by key
|
|
149
134
|
let child = (_a = node.children) === null || _a === void 0 ? void 0 : _a.get(key);
|
|
@@ -155,12 +140,6 @@ function getChildNode(node, key, asFunction) {
|
|
|
155
140
|
key,
|
|
156
141
|
lazy: true,
|
|
157
142
|
};
|
|
158
|
-
if (asFunction) {
|
|
159
|
-
child = Object.assign(cloneFunction(asFunction), child);
|
|
160
|
-
}
|
|
161
|
-
else if (node.proxyFn2) {
|
|
162
|
-
child = Object.assign(node.proxyFn2.bind(node, key), child);
|
|
163
|
-
}
|
|
164
143
|
if (!node.children) {
|
|
165
144
|
node.children = new Map();
|
|
166
145
|
}
|
|
@@ -182,7 +161,6 @@ function ensureNodeValue(node) {
|
|
|
182
161
|
return value;
|
|
183
162
|
}
|
|
184
163
|
function findIDKey(obj, node) {
|
|
185
|
-
var _a, _b;
|
|
186
164
|
let idKey = isObject(obj)
|
|
187
165
|
? 'id' in obj
|
|
188
166
|
? 'id'
|
|
@@ -195,8 +173,7 @@ function findIDKey(obj, node) {
|
|
|
195
173
|
: undefined
|
|
196
174
|
: undefined;
|
|
197
175
|
if (!idKey && node.parent) {
|
|
198
|
-
const
|
|
199
|
-
const keyExtractor = (_b = (_a = node.functions) === null || _a === void 0 ? void 0 : _a.get(k)) !== null && _b !== void 0 ? _b : getNodeValue(node.parent)[node.key + '_keyExtractor'];
|
|
176
|
+
const keyExtractor = getNodeValue(node.parent)[node.key + '_keyExtractor'];
|
|
200
177
|
if (keyExtractor && isFunction(keyExtractor)) {
|
|
201
178
|
idKey = keyExtractor;
|
|
202
179
|
}
|
|
@@ -452,19 +429,15 @@ function endBatch(force) {
|
|
|
452
429
|
}
|
|
453
430
|
}
|
|
454
431
|
|
|
455
|
-
function createObservable(value, makePrimitive,
|
|
432
|
+
function createObservable(value, makePrimitive, createObject, createPrimitive) {
|
|
456
433
|
const valueIsPromise = isPromise(value);
|
|
457
|
-
const valueIsFunction = isFunction(value);
|
|
458
434
|
const root = {
|
|
459
435
|
_: value,
|
|
460
436
|
};
|
|
461
|
-
|
|
437
|
+
const node = {
|
|
462
438
|
root,
|
|
463
439
|
lazy: true,
|
|
464
440
|
};
|
|
465
|
-
if (valueIsFunction) {
|
|
466
|
-
node = Object.assign(cloneFunction(value), node);
|
|
467
|
-
}
|
|
468
441
|
const prim = makePrimitive || isActualPrimitive(value);
|
|
469
442
|
const obs = prim
|
|
470
443
|
? new createPrimitive(node)
|
|
@@ -475,176 +448,6 @@ function createObservable(value, makePrimitive, extractPromise, createObject, cr
|
|
|
475
448
|
return obs;
|
|
476
449
|
}
|
|
477
450
|
|
|
478
|
-
function isEvent(obs) {
|
|
479
|
-
var _a;
|
|
480
|
-
return obs && ((_a = obs[symbolGetNode]) === null || _a === void 0 ? void 0 : _a.isEvent);
|
|
481
|
-
}
|
|
482
|
-
function computeSelector(selector, e, retainObservable) {
|
|
483
|
-
let c = selector;
|
|
484
|
-
if (isFunction(c)) {
|
|
485
|
-
c = e ? c(e) : c();
|
|
486
|
-
}
|
|
487
|
-
return isObservable(c) && !retainObservable ? c.get() : c;
|
|
488
|
-
}
|
|
489
|
-
function getObservableIndex(obs) {
|
|
490
|
-
const node = getNode(obs);
|
|
491
|
-
const n = +node.key;
|
|
492
|
-
return n - n < 1 ? +n : -1;
|
|
493
|
-
}
|
|
494
|
-
function opaqueObject(value) {
|
|
495
|
-
if (value) {
|
|
496
|
-
value[symbolOpaque] = true;
|
|
497
|
-
}
|
|
498
|
-
return value;
|
|
499
|
-
}
|
|
500
|
-
function lockObservable(obs, value) {
|
|
501
|
-
var _a;
|
|
502
|
-
const root = (_a = getNode(obs)) === null || _a === void 0 ? void 0 : _a.root;
|
|
503
|
-
if (root) {
|
|
504
|
-
root.locked = value;
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
function setAtPath(obj, path, pathTypes, value, fullObj, restore) {
|
|
508
|
-
let o = obj;
|
|
509
|
-
let oFull = fullObj;
|
|
510
|
-
if (path.length > 0) {
|
|
511
|
-
for (let i = 0; i < path.length; i++) {
|
|
512
|
-
const p = path[i];
|
|
513
|
-
if (i === path.length - 1) {
|
|
514
|
-
// Don't set if the value is the same. This prevents creating a new key
|
|
515
|
-
// when setting undefined on an object without this key
|
|
516
|
-
if (o[p] !== value) {
|
|
517
|
-
o[p] = value;
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
else if (o[p] === symbolDelete) {
|
|
521
|
-
// If this was previously deleted, restore it
|
|
522
|
-
if (oFull) {
|
|
523
|
-
o[p] = oFull[p];
|
|
524
|
-
restore === null || restore === void 0 ? void 0 : restore(path.slice(0, i + 1), o[p]);
|
|
525
|
-
}
|
|
526
|
-
break;
|
|
527
|
-
}
|
|
528
|
-
else if (o[p] === undefined || o[p] === null) {
|
|
529
|
-
o[p] = pathTypes[i] === 'array' ? [] : {};
|
|
530
|
-
}
|
|
531
|
-
o = o[p];
|
|
532
|
-
if (oFull) {
|
|
533
|
-
oFull = oFull[p];
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
else {
|
|
538
|
-
obj = value;
|
|
539
|
-
}
|
|
540
|
-
return obj;
|
|
541
|
-
}
|
|
542
|
-
function setInObservableAtPath(obs, path, pathTypes, value, mode) {
|
|
543
|
-
let o = obs;
|
|
544
|
-
let v = value;
|
|
545
|
-
for (let i = 0; i < path.length; i++) {
|
|
546
|
-
const p = path[i];
|
|
547
|
-
if (!o.peek()[p] && pathTypes[i] === 'array') {
|
|
548
|
-
o[p].set([]);
|
|
549
|
-
}
|
|
550
|
-
o = o[p];
|
|
551
|
-
v = v[p];
|
|
552
|
-
}
|
|
553
|
-
if (v === symbolDelete) {
|
|
554
|
-
o.delete();
|
|
555
|
-
}
|
|
556
|
-
// Assign if possible, or set otherwise
|
|
557
|
-
else if (mode === 'assign' && o.assign && isObject(o.peek())) {
|
|
558
|
-
o.assign(v);
|
|
559
|
-
}
|
|
560
|
-
else {
|
|
561
|
-
o.set(v);
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
function mergeIntoObservable(target, ...sources) {
|
|
565
|
-
beginBatch();
|
|
566
|
-
globalState.isMerging = true;
|
|
567
|
-
for (let i = 0; i < sources.length; i++) {
|
|
568
|
-
target = _mergeIntoObservable(target, sources[i]);
|
|
569
|
-
}
|
|
570
|
-
globalState.isMerging = false;
|
|
571
|
-
endBatch();
|
|
572
|
-
return target;
|
|
573
|
-
}
|
|
574
|
-
function _mergeIntoObservable(target, source) {
|
|
575
|
-
var _a;
|
|
576
|
-
if (isObservable(source)) {
|
|
577
|
-
source = source.peek();
|
|
578
|
-
}
|
|
579
|
-
const needsSet = isObservable(target);
|
|
580
|
-
const targetValue = needsSet ? target.peek() : target;
|
|
581
|
-
const isTargetArr = isArray(targetValue);
|
|
582
|
-
const isTargetObj = !isTargetArr && isObject(targetValue);
|
|
583
|
-
if ((isTargetObj && isObject(source) && !isEmpty(targetValue)) ||
|
|
584
|
-
(isTargetArr && isArray(source) && targetValue.length > 0)) {
|
|
585
|
-
const keys = Object.keys(source);
|
|
586
|
-
for (let i = 0; i < keys.length; i++) {
|
|
587
|
-
const key = keys[i];
|
|
588
|
-
const sourceValue = source[key];
|
|
589
|
-
if (sourceValue === symbolDelete) {
|
|
590
|
-
needsSet && ((_a = target[key]) === null || _a === void 0 ? void 0 : _a.delete) ? target[key].delete() : delete target[key];
|
|
591
|
-
}
|
|
592
|
-
else {
|
|
593
|
-
const isObj = isObject(sourceValue);
|
|
594
|
-
const isArr = !isObj && isArray(sourceValue);
|
|
595
|
-
const targetChild = target[key];
|
|
596
|
-
if ((isObj || isArr) && targetChild && (needsSet || !isEmpty(targetChild))) {
|
|
597
|
-
if (!needsSet && (!targetChild || (isObj ? !isObject(targetChild) : !isArray(targetChild)))) {
|
|
598
|
-
target[key] = sourceValue;
|
|
599
|
-
}
|
|
600
|
-
else {
|
|
601
|
-
_mergeIntoObservable(targetChild, sourceValue);
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
else {
|
|
605
|
-
needsSet
|
|
606
|
-
? targetChild.set(sourceValue)
|
|
607
|
-
: (target[key] = sourceValue);
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
else if (source !== undefined) {
|
|
613
|
-
needsSet ? target.set(source) : (target = source);
|
|
614
|
-
}
|
|
615
|
-
return target;
|
|
616
|
-
}
|
|
617
|
-
function constructObjectWithPath(path, pathTypes, value) {
|
|
618
|
-
let out;
|
|
619
|
-
if (path.length > 0) {
|
|
620
|
-
let o = (out = {});
|
|
621
|
-
for (let i = 0; i < path.length; i++) {
|
|
622
|
-
const p = path[i];
|
|
623
|
-
o[p] = i === path.length - 1 ? value : pathTypes[i] === 'array' ? [] : {};
|
|
624
|
-
o = o[p];
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
else {
|
|
628
|
-
out = value;
|
|
629
|
-
}
|
|
630
|
-
return out;
|
|
631
|
-
}
|
|
632
|
-
function deconstructObjectWithPath(path, pathTypes, value) {
|
|
633
|
-
let o = value;
|
|
634
|
-
for (let i = 0; i < path.length; i++) {
|
|
635
|
-
const p = path[i];
|
|
636
|
-
o = o ? o[p] : pathTypes[i] === 'array' ? [] : {};
|
|
637
|
-
}
|
|
638
|
-
return o;
|
|
639
|
-
}
|
|
640
|
-
function isObservableValueReady(value) {
|
|
641
|
-
return !!value && ((!isObject(value) && !isArray(value)) || !isEmpty(value));
|
|
642
|
-
}
|
|
643
|
-
function setSilently(obs, newValue) {
|
|
644
|
-
const node = getNode(obs);
|
|
645
|
-
return setNodeValue(node, newValue).newValue;
|
|
646
|
-
}
|
|
647
|
-
|
|
648
451
|
function onChange(node, callback, options = {}) {
|
|
649
452
|
const { initial, immediate, noArgs } = options;
|
|
650
453
|
const { trackingType } = options;
|
|
@@ -683,23 +486,6 @@ function onChange(node, callback, options = {}) {
|
|
|
683
486
|
return () => listeners.delete(listener);
|
|
684
487
|
}
|
|
685
488
|
|
|
686
|
-
function setupTracking(nodes, update, noArgs, immediate) {
|
|
687
|
-
let listeners = [];
|
|
688
|
-
// Listen to tracked nodes
|
|
689
|
-
nodes === null || nodes === void 0 ? void 0 : nodes.forEach((tracked) => {
|
|
690
|
-
const { node, track } = tracked;
|
|
691
|
-
listeners.push(onChange(node, update, { trackingType: track, immediate, noArgs }));
|
|
692
|
-
});
|
|
693
|
-
return () => {
|
|
694
|
-
if (listeners) {
|
|
695
|
-
for (let i = 0; i < listeners.length; i++) {
|
|
696
|
-
listeners[i]();
|
|
697
|
-
}
|
|
698
|
-
listeners = undefined;
|
|
699
|
-
}
|
|
700
|
-
};
|
|
701
|
-
}
|
|
702
|
-
|
|
703
489
|
let trackCount = 0;
|
|
704
490
|
const trackingQueue = [];
|
|
705
491
|
const tracking = {
|
|
@@ -739,148 +525,56 @@ function updateTracking(node, track) {
|
|
|
739
525
|
}
|
|
740
526
|
}
|
|
741
527
|
|
|
742
|
-
|
|
528
|
+
const ArrayModifiers = new Set([
|
|
529
|
+
'copyWithin',
|
|
530
|
+
'fill',
|
|
531
|
+
'from',
|
|
532
|
+
'pop',
|
|
533
|
+
'push',
|
|
534
|
+
'reverse',
|
|
535
|
+
'shift',
|
|
536
|
+
'sort',
|
|
537
|
+
'splice',
|
|
538
|
+
'unshift',
|
|
539
|
+
]);
|
|
540
|
+
const ArrayLoopers = new Set([
|
|
541
|
+
'every',
|
|
542
|
+
'filter',
|
|
543
|
+
'find',
|
|
544
|
+
'findIndex',
|
|
545
|
+
'forEach',
|
|
546
|
+
'includes',
|
|
547
|
+
'join',
|
|
548
|
+
'map',
|
|
549
|
+
'some',
|
|
550
|
+
]);
|
|
551
|
+
const ArrayLoopersReturn = new Set(['filter', 'find']);
|
|
552
|
+
const observableProperties = new Map();
|
|
553
|
+
const observableFns = new Map([
|
|
554
|
+
['get', get],
|
|
555
|
+
['set', set],
|
|
556
|
+
['peek', peek],
|
|
557
|
+
['onChange', onChange],
|
|
558
|
+
['assign', assign],
|
|
559
|
+
['delete', deleteFn],
|
|
560
|
+
['toggle', toggle],
|
|
561
|
+
]);
|
|
562
|
+
if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
|
|
563
|
+
// eslint-disable-next-line no-var
|
|
564
|
+
var __devUpdateNodes = new Set();
|
|
565
|
+
}
|
|
566
|
+
function collectionSetter(node, target, prop, ...args) {
|
|
743
567
|
var _a;
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
}
|
|
755
|
-
else {
|
|
756
|
-
// Compute the selector inside a tracking context
|
|
757
|
-
beginTracking();
|
|
758
|
-
value = selector ? computeSelector(selector, observeEvent, observeOptions === null || observeOptions === void 0 ? void 0 : observeOptions.fromComputed) : selector;
|
|
759
|
-
tracker = tracking.current;
|
|
760
|
-
nodes = tracker.nodes;
|
|
761
|
-
endTracking();
|
|
762
|
-
if ((process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') && tracker && nodes) {
|
|
763
|
-
(_a = tracker.traceListeners) === null || _a === void 0 ? void 0 : _a.call(tracker, nodes);
|
|
764
|
-
if (tracker.traceUpdates) {
|
|
765
|
-
updateFn = tracker.traceUpdates(update);
|
|
766
|
-
}
|
|
767
|
-
// Clear tracing so it doesn't leak to other components
|
|
768
|
-
tracker.traceListeners = undefined;
|
|
769
|
-
tracker.traceUpdates = undefined;
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
|
-
if (!(observeEvent === null || observeEvent === void 0 ? void 0 : observeEvent.cancel)) {
|
|
773
|
-
// Do tracing if it was requested
|
|
774
|
-
// useSyncExternalStore doesn't subscribe until after the component mount.
|
|
775
|
-
// We want to subscribe immediately so we don't miss any updates
|
|
776
|
-
dispose = setupTracking(nodes, updateFn, false, observeOptions === null || observeOptions === void 0 ? void 0 : observeOptions.immediate);
|
|
777
|
-
resubscribe = createResubscribe ? () => setupTracking(nodes, updateFn) : undefined;
|
|
778
|
-
}
|
|
779
|
-
return { value, dispose, resubscribe };
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
function observe(selectorOrRun, reactionOrOptions, options) {
|
|
783
|
-
let reaction;
|
|
784
|
-
if (isFunction(reactionOrOptions)) {
|
|
785
|
-
reaction = reactionOrOptions;
|
|
786
|
-
}
|
|
787
|
-
else {
|
|
788
|
-
options = reactionOrOptions;
|
|
789
|
-
}
|
|
790
|
-
let dispose;
|
|
791
|
-
const e = { num: 0 };
|
|
792
|
-
// Wrap it in a function so it doesn't pass all the arguments to run()
|
|
793
|
-
const update = function () {
|
|
794
|
-
if (e.onCleanup) {
|
|
795
|
-
e.onCleanup();
|
|
796
|
-
e.onCleanup = undefined;
|
|
797
|
-
}
|
|
798
|
-
// Run in a batch so changes don't happen until we're done tracking here
|
|
799
|
-
beginBatch();
|
|
800
|
-
// Run the function/selector
|
|
801
|
-
delete e.value;
|
|
802
|
-
// Dispose listeners from previous run
|
|
803
|
-
dispose === null || dispose === void 0 ? void 0 : dispose();
|
|
804
|
-
const { dispose: _dispose, value } = trackSelector(selectorOrRun, update, e, options);
|
|
805
|
-
dispose = _dispose;
|
|
806
|
-
e.value = value;
|
|
807
|
-
if (e.onCleanupReaction) {
|
|
808
|
-
e.onCleanupReaction();
|
|
809
|
-
e.onCleanupReaction = undefined;
|
|
810
|
-
}
|
|
811
|
-
endBatch();
|
|
812
|
-
// Call the reaction if there is one and the value changed
|
|
813
|
-
if (reaction &&
|
|
814
|
-
((options === null || options === void 0 ? void 0 : options.fromComputed) || ((e.num > 0 || !isEvent(selectorOrRun)) && e.previous !== e.value))) {
|
|
815
|
-
reaction(e);
|
|
816
|
-
}
|
|
817
|
-
// Update the previous value
|
|
818
|
-
e.previous = e.value;
|
|
819
|
-
// Increment the counter
|
|
820
|
-
e.num++;
|
|
821
|
-
};
|
|
822
|
-
update();
|
|
823
|
-
// Return function calling dispose because dispose may be changed in update()
|
|
824
|
-
return () => {
|
|
825
|
-
var _a, _b;
|
|
826
|
-
(_a = e.onCleanup) === null || _a === void 0 ? void 0 : _a.call(e);
|
|
827
|
-
e.onCleanup = undefined;
|
|
828
|
-
(_b = e.onCleanupReaction) === null || _b === void 0 ? void 0 : _b.call(e);
|
|
829
|
-
e.onCleanupReaction = undefined;
|
|
830
|
-
dispose === null || dispose === void 0 ? void 0 : dispose();
|
|
831
|
-
};
|
|
832
|
-
}
|
|
833
|
-
|
|
834
|
-
const ArrayModifiers = new Set([
|
|
835
|
-
'copyWithin',
|
|
836
|
-
'fill',
|
|
837
|
-
'from',
|
|
838
|
-
'pop',
|
|
839
|
-
'push',
|
|
840
|
-
'reverse',
|
|
841
|
-
'shift',
|
|
842
|
-
'sort',
|
|
843
|
-
'splice',
|
|
844
|
-
'unshift',
|
|
845
|
-
]);
|
|
846
|
-
const ArrayLoopers = new Set([
|
|
847
|
-
'every',
|
|
848
|
-
'filter',
|
|
849
|
-
'find',
|
|
850
|
-
'findIndex',
|
|
851
|
-
'forEach',
|
|
852
|
-
'includes',
|
|
853
|
-
'join',
|
|
854
|
-
'map',
|
|
855
|
-
'some',
|
|
856
|
-
]);
|
|
857
|
-
const ArrayLoopersReturn = new Set(['filter', 'find']);
|
|
858
|
-
const observableProperties = new Map();
|
|
859
|
-
const observableFns = new Map([
|
|
860
|
-
['get', get],
|
|
861
|
-
['set', set],
|
|
862
|
-
['peek', peek],
|
|
863
|
-
['onChange', onChange],
|
|
864
|
-
['assign', assign],
|
|
865
|
-
['delete', deleteFn],
|
|
866
|
-
['toggle', toggle],
|
|
867
|
-
]);
|
|
868
|
-
if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
|
|
869
|
-
// eslint-disable-next-line no-var
|
|
870
|
-
var __devUpdateNodes = new Set();
|
|
871
|
-
}
|
|
872
|
-
function collectionSetter(node, target, prop, ...args) {
|
|
873
|
-
var _a;
|
|
874
|
-
const prevValue = (isArray(target) && target.slice()) || target;
|
|
875
|
-
const ret = target[prop].apply(target, args);
|
|
876
|
-
if (node) {
|
|
877
|
-
const hasParent = isChildNodeValue(node);
|
|
878
|
-
const key = hasParent ? node.key : '_';
|
|
879
|
-
const parentValue = hasParent ? getNodeValue(node.parent) : node.root;
|
|
880
|
-
// Set the object to the previous value first
|
|
881
|
-
parentValue[key] = prevValue;
|
|
882
|
-
// Then set with the new value so it notifies with the correct prevValue
|
|
883
|
-
setKey((_a = node.parent) !== null && _a !== void 0 ? _a : node, key, target);
|
|
568
|
+
const prevValue = (isArray(target) && target.slice()) || target;
|
|
569
|
+
const ret = target[prop].apply(target, args);
|
|
570
|
+
if (node) {
|
|
571
|
+
const hasParent = isChildNodeValue(node);
|
|
572
|
+
const key = hasParent ? node.key : '_';
|
|
573
|
+
const parentValue = hasParent ? getNodeValue(node.parent) : node.root;
|
|
574
|
+
// Set the object to the previous value first
|
|
575
|
+
parentValue[key] = prevValue;
|
|
576
|
+
// Then set with the new value so it notifies with the correct prevValue
|
|
577
|
+
setKey((_a = node.parent) !== null && _a !== void 0 ? _a : node, key, target);
|
|
884
578
|
}
|
|
885
579
|
// Return the original value
|
|
886
580
|
return ret;
|
|
@@ -1069,10 +763,10 @@ function updateNodes(parent, obj, prevValue) {
|
|
|
1069
763
|
}
|
|
1070
764
|
return retValue !== null && retValue !== void 0 ? retValue : false;
|
|
1071
765
|
}
|
|
1072
|
-
function getProxy(node, p
|
|
766
|
+
function getProxy(node, p) {
|
|
1073
767
|
// Get the child node if p prop
|
|
1074
768
|
if (p !== undefined)
|
|
1075
|
-
node = getChildNode(node, p
|
|
769
|
+
node = getChildNode(node, p);
|
|
1076
770
|
// Create a proxy if not already cached and return it
|
|
1077
771
|
return (node.proxy || (node.proxy = new Proxy(node, proxyHandler)));
|
|
1078
772
|
}
|
|
@@ -1150,15 +844,6 @@ const proxyHandler = {
|
|
|
1150
844
|
if (isObject(value) && value[symbolOpaque]) {
|
|
1151
845
|
return vProp;
|
|
1152
846
|
}
|
|
1153
|
-
const fnOrComputed = (_a = node.functions) === null || _a === void 0 ? void 0 : _a.get(p);
|
|
1154
|
-
if (fnOrComputed) {
|
|
1155
|
-
if (isObservable(fnOrComputed)) {
|
|
1156
|
-
return fnOrComputed;
|
|
1157
|
-
}
|
|
1158
|
-
else {
|
|
1159
|
-
return getProxy(node, p, fnOrComputed);
|
|
1160
|
-
}
|
|
1161
|
-
}
|
|
1162
847
|
// Handle function calls
|
|
1163
848
|
if (isFunction(vProp)) {
|
|
1164
849
|
if (isArray(value)) {
|
|
@@ -1205,9 +890,15 @@ const proxyHandler = {
|
|
|
1205
890
|
// Update that this primitive node was accessed for observers
|
|
1206
891
|
if (isArray(value) && p === 'length') {
|
|
1207
892
|
updateTracking(node, true);
|
|
893
|
+
// } else if (!isPrimitive(value)) {
|
|
894
|
+
// updateTracking(getChildNode(node, p));
|
|
1208
895
|
return vProp;
|
|
1209
896
|
}
|
|
1210
897
|
}
|
|
898
|
+
const fnOrComputed = (_a = node.functions) === null || _a === void 0 ? void 0 : _a.get(p);
|
|
899
|
+
if (fnOrComputed) {
|
|
900
|
+
return fnOrComputed;
|
|
901
|
+
}
|
|
1211
902
|
// TODOV3: Remove "state"
|
|
1212
903
|
if (vProp === undefined && (p === 'state' || p === '_state') && node.state) {
|
|
1213
904
|
return node.state;
|
|
@@ -1274,10 +965,6 @@ const proxyHandler = {
|
|
|
1274
965
|
const value = getNodeValue(node);
|
|
1275
966
|
return Reflect.has(value, prop);
|
|
1276
967
|
},
|
|
1277
|
-
apply(target, thisArg, argArray) {
|
|
1278
|
-
// If it's a function call it as a function
|
|
1279
|
-
return Reflect.apply(target, thisArg, argArray);
|
|
1280
|
-
},
|
|
1281
968
|
};
|
|
1282
969
|
function set(node, newValue) {
|
|
1283
970
|
if (node.parent) {
|
|
@@ -1318,7 +1005,7 @@ function setKey(node, key, newValue, level) {
|
|
|
1318
1005
|
}
|
|
1319
1006
|
const isRoot = !node.parent && key === '_';
|
|
1320
1007
|
// Get the child node for updating and notifying
|
|
1321
|
-
const childNode = isRoot ? node : getChildNode(node, key
|
|
1008
|
+
const childNode = isRoot ? node : getChildNode(node, key);
|
|
1322
1009
|
// Set the raw value on the parent object
|
|
1323
1010
|
const { newValue: savedValue, prevValue, parentValue } = setNodeValue(childNode, newValue);
|
|
1324
1011
|
const isFunc = isFunction(savedValue);
|
|
@@ -1457,7 +1144,7 @@ function extractPromise(node, value) {
|
|
|
1457
1144
|
if (!node.state) {
|
|
1458
1145
|
node.state = createObservable({
|
|
1459
1146
|
isLoaded: false,
|
|
1460
|
-
}, false,
|
|
1147
|
+
}, false, getProxy);
|
|
1461
1148
|
}
|
|
1462
1149
|
value
|
|
1463
1150
|
.then((value) => {
|
|
@@ -1474,7 +1161,6 @@ function extractFunctionOrComputed(node, obj, k, v) {
|
|
|
1474
1161
|
}
|
|
1475
1162
|
else if (typeof v === 'function') {
|
|
1476
1163
|
extractFunction(node, k, v);
|
|
1477
|
-
delete obj[k];
|
|
1478
1164
|
}
|
|
1479
1165
|
else if (typeof v == 'object' && v !== null && v !== undefined) {
|
|
1480
1166
|
const childNode = getNode(v);
|
|
@@ -1497,137 +1183,202 @@ function peek(node) {
|
|
|
1497
1183
|
const value = getNodeValue(node);
|
|
1498
1184
|
// If node is not yet lazily computed go do that
|
|
1499
1185
|
if (node.lazy) {
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
for (const key in value) {
|
|
1505
|
-
if (hasOwnProperty.call(value, key)) {
|
|
1506
|
-
extractFunctionOrComputed(node, value, key, value[key]);
|
|
1507
|
-
}
|
|
1186
|
+
delete node.lazy;
|
|
1187
|
+
for (const key in value) {
|
|
1188
|
+
if (hasOwnProperty.call(value, key)) {
|
|
1189
|
+
extractFunctionOrComputed(node, value, key, value[key]);
|
|
1508
1190
|
}
|
|
1509
1191
|
}
|
|
1510
|
-
delete node.lazy;
|
|
1511
1192
|
}
|
|
1512
1193
|
// Check if computed needs to activate
|
|
1513
1194
|
checkActivate(node);
|
|
1514
1195
|
return value;
|
|
1515
1196
|
}
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1197
|
+
|
|
1198
|
+
function isObservable(obs) {
|
|
1199
|
+
return obs && !!obs[symbolGetNode];
|
|
1200
|
+
}
|
|
1201
|
+
function isEvent(obs) {
|
|
1202
|
+
var _a;
|
|
1203
|
+
return obs && ((_a = obs[symbolGetNode]) === null || _a === void 0 ? void 0 : _a.isEvent);
|
|
1204
|
+
}
|
|
1205
|
+
function computeSelector(selector, e, retainObservable) {
|
|
1206
|
+
let c = selector;
|
|
1207
|
+
if (isFunction(c)) {
|
|
1208
|
+
c = e ? c(e) : c();
|
|
1209
|
+
}
|
|
1210
|
+
return isObservable(c) && !retainObservable ? c.get() : c;
|
|
1211
|
+
}
|
|
1212
|
+
function getObservableIndex(obs) {
|
|
1213
|
+
const node = getNode(obs);
|
|
1214
|
+
const n = +node.key;
|
|
1215
|
+
return n - n < 1 ? +n : -1;
|
|
1216
|
+
}
|
|
1217
|
+
function opaqueObject(value) {
|
|
1218
|
+
if (value) {
|
|
1219
|
+
value[symbolOpaque] = true;
|
|
1220
|
+
}
|
|
1221
|
+
return value;
|
|
1222
|
+
}
|
|
1223
|
+
function lockObservable(obs, value) {
|
|
1224
|
+
var _a;
|
|
1225
|
+
const root = (_a = getNode(obs)) === null || _a === void 0 ? void 0 : _a.root;
|
|
1226
|
+
if (root) {
|
|
1227
|
+
root.locked = value;
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
function setAtPath(obj, path, pathTypes, value, fullObj, restore) {
|
|
1231
|
+
let o = obj;
|
|
1232
|
+
let oFull = fullObj;
|
|
1233
|
+
if (path.length > 0) {
|
|
1234
|
+
for (let i = 0; i < path.length; i++) {
|
|
1235
|
+
const p = path[i];
|
|
1236
|
+
if (i === path.length - 1) {
|
|
1237
|
+
// Don't set if the value is the same. This prevents creating a new key
|
|
1238
|
+
// when setting undefined on an object without this key
|
|
1239
|
+
if (o[p] !== value) {
|
|
1240
|
+
o[p] = value;
|
|
1533
1241
|
}
|
|
1534
1242
|
}
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
// a data source and sends updates into the observable
|
|
1541
|
-
const subscribe = (fn) => {
|
|
1542
|
-
if (!subscribed) {
|
|
1543
|
-
subscribed = true;
|
|
1544
|
-
fn({
|
|
1545
|
-
update: ({ value }) => {
|
|
1546
|
-
globalState.onChangeRemote(() => {
|
|
1547
|
-
set(node, value);
|
|
1548
|
-
});
|
|
1549
|
-
},
|
|
1550
|
-
});
|
|
1551
|
-
}
|
|
1552
|
-
};
|
|
1553
|
-
// The proxy function simply marks the node as a proxy with this function
|
|
1554
|
-
// so that child nodes will be created with this function, and then simply
|
|
1555
|
-
// activated as a function
|
|
1556
|
-
const proxy = (fn) => {
|
|
1557
|
-
node.proxyFn2 = fn;
|
|
1558
|
-
};
|
|
1559
|
-
if (!node.state) {
|
|
1560
|
-
node.state = createObservable({
|
|
1561
|
-
isLoaded: false,
|
|
1562
|
-
}, false, extractPromise, getProxy);
|
|
1563
|
-
}
|
|
1564
|
-
const { isLoaded } = node.state;
|
|
1565
|
-
let prevTarget$;
|
|
1566
|
-
let curTarget$;
|
|
1567
|
-
let wasPromise;
|
|
1568
|
-
const activator = (isFunction(node) ? node : node.lazy);
|
|
1569
|
-
observe(() => {
|
|
1570
|
-
// Run the function at this node
|
|
1571
|
-
let value = activator({ onSet, subscribe, proxy });
|
|
1572
|
-
// If target is an observable, get() it to make sure we listen to its changes
|
|
1573
|
-
// and set up an onSet to write changes back to it
|
|
1574
|
-
if (isObservable(value)) {
|
|
1575
|
-
prevTarget$ = curTarget$;
|
|
1576
|
-
curTarget$ = value;
|
|
1577
|
-
onSet(({ value: newValue, getPrevious }) => {
|
|
1578
|
-
// Don't set the target observable if the target has changed since the last run
|
|
1579
|
-
if (!prevTarget$ || curTarget$ === prevTarget$) {
|
|
1580
|
-
// Set the node value back to what it was before before setting it.
|
|
1581
|
-
// This is a workaround for linked objects because it might not notify
|
|
1582
|
-
// if setting a property of an object
|
|
1583
|
-
// TODO: Is there a way to not do this? Or at least only do it in a
|
|
1584
|
-
// small subset of cases?
|
|
1585
|
-
setNodeValue(getNode(curTarget$), getPrevious());
|
|
1586
|
-
// Set the value on the curTarget
|
|
1587
|
-
curTarget$.set(newValue);
|
|
1243
|
+
else if (o[p] === symbolDelete) {
|
|
1244
|
+
// If this was previously deleted, restore it
|
|
1245
|
+
if (oFull) {
|
|
1246
|
+
o[p] = oFull[p];
|
|
1247
|
+
restore === null || restore === void 0 ? void 0 : restore(path.slice(0, i + 1), o[p]);
|
|
1588
1248
|
}
|
|
1589
|
-
|
|
1590
|
-
// Get the value from the observable because we still want the raw value
|
|
1591
|
-
// for the effect.
|
|
1592
|
-
value = value.get();
|
|
1593
|
-
}
|
|
1594
|
-
if (isPromise(value)) {
|
|
1595
|
-
wasPromise = true;
|
|
1596
|
-
extractPromise(node, value);
|
|
1597
|
-
value = undefined;
|
|
1598
|
-
}
|
|
1599
|
-
return value;
|
|
1600
|
-
}, ({ value }) => {
|
|
1601
|
-
if (!isSetting) {
|
|
1602
|
-
const doSet = () => {
|
|
1603
|
-
set(node, value);
|
|
1604
|
-
isLoaded.set(true);
|
|
1605
|
-
};
|
|
1606
|
-
if (wasPromise) {
|
|
1607
|
-
wasPromise = false;
|
|
1608
|
-
globalState.onChangeRemote(doSet);
|
|
1249
|
+
break;
|
|
1609
1250
|
}
|
|
1610
|
-
else {
|
|
1611
|
-
|
|
1251
|
+
else if (o[p] === undefined || o[p] === null) {
|
|
1252
|
+
o[p] = pathTypes[i] === 'array' ? [] : {};
|
|
1253
|
+
}
|
|
1254
|
+
o = o[p];
|
|
1255
|
+
if (oFull) {
|
|
1256
|
+
oFull = oFull[p];
|
|
1612
1257
|
}
|
|
1613
1258
|
}
|
|
1614
|
-
}
|
|
1259
|
+
}
|
|
1260
|
+
else {
|
|
1261
|
+
obj = value;
|
|
1262
|
+
}
|
|
1263
|
+
return obj;
|
|
1615
1264
|
}
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1265
|
+
function setInObservableAtPath(obs, path, pathTypes, value, mode) {
|
|
1266
|
+
let o = obs;
|
|
1267
|
+
let v = value;
|
|
1268
|
+
for (let i = 0; i < path.length; i++) {
|
|
1269
|
+
const p = path[i];
|
|
1270
|
+
if (!o.peek()[p] && pathTypes[i] === 'array') {
|
|
1271
|
+
o[p].set([]);
|
|
1272
|
+
}
|
|
1273
|
+
o = o[p];
|
|
1274
|
+
v = v[p];
|
|
1275
|
+
}
|
|
1276
|
+
if (v === symbolDelete) {
|
|
1277
|
+
o.delete();
|
|
1278
|
+
}
|
|
1279
|
+
// Assign if possible, or set otherwise
|
|
1280
|
+
else if (mode === 'assign' && o.assign && isObject(o.peek())) {
|
|
1281
|
+
o.assign(v);
|
|
1282
|
+
}
|
|
1283
|
+
else {
|
|
1284
|
+
o.set(v);
|
|
1624
1285
|
}
|
|
1625
1286
|
}
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1287
|
+
function mergeIntoObservable(target, ...sources) {
|
|
1288
|
+
beginBatch();
|
|
1289
|
+
globalState.isMerging = true;
|
|
1290
|
+
for (let i = 0; i < sources.length; i++) {
|
|
1291
|
+
target = _mergeIntoObservable(target, sources[i]);
|
|
1292
|
+
}
|
|
1293
|
+
globalState.isMerging = false;
|
|
1294
|
+
endBatch();
|
|
1295
|
+
return target;
|
|
1296
|
+
}
|
|
1297
|
+
function _mergeIntoObservable(target, source) {
|
|
1298
|
+
var _a;
|
|
1299
|
+
const needsSet = isObservable(target);
|
|
1300
|
+
const targetValue = needsSet ? target.peek() : target;
|
|
1301
|
+
const isTargetArr = isArray(targetValue);
|
|
1302
|
+
const isTargetObj = !isTargetArr && isObject(targetValue);
|
|
1303
|
+
if ((isTargetObj && isObject(source) && !isEmpty(targetValue)) ||
|
|
1304
|
+
(isTargetArr && isArray(source) && targetValue.length > 0)) {
|
|
1305
|
+
const keys = Object.keys(source);
|
|
1306
|
+
for (let i = 0; i < keys.length; i++) {
|
|
1307
|
+
const key = keys[i];
|
|
1308
|
+
const sourceValue = source[key];
|
|
1309
|
+
if (sourceValue === symbolDelete) {
|
|
1310
|
+
needsSet && ((_a = target[key]) === null || _a === void 0 ? void 0 : _a.delete) ? target[key].delete() : delete target[key];
|
|
1311
|
+
}
|
|
1312
|
+
else {
|
|
1313
|
+
const isObj = isObject(sourceValue);
|
|
1314
|
+
const isArr = !isObj && isArray(sourceValue);
|
|
1315
|
+
const targetChild = target[key];
|
|
1316
|
+
if ((isObj || isArr) && targetChild && (needsSet || !isEmpty(targetChild))) {
|
|
1317
|
+
if (!needsSet && (!targetChild || (isObj ? !isObject(targetChild) : !isArray(targetChild)))) {
|
|
1318
|
+
target[key] = sourceValue;
|
|
1319
|
+
}
|
|
1320
|
+
else {
|
|
1321
|
+
_mergeIntoObservable(targetChild, sourceValue);
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
else {
|
|
1325
|
+
needsSet
|
|
1326
|
+
? targetChild.set(sourceValue)
|
|
1327
|
+
: (target[key] = sourceValue);
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
else if (source !== undefined) {
|
|
1333
|
+
needsSet ? target.set(source) : (target = source);
|
|
1334
|
+
}
|
|
1335
|
+
return target;
|
|
1336
|
+
}
|
|
1337
|
+
function constructObjectWithPath(path, pathTypes, value) {
|
|
1338
|
+
let out;
|
|
1339
|
+
if (path.length > 0) {
|
|
1340
|
+
let o = (out = {});
|
|
1341
|
+
for (let i = 0; i < path.length; i++) {
|
|
1342
|
+
const p = path[i];
|
|
1343
|
+
o[p] = i === path.length - 1 ? value : pathTypes[i] === 'array' ? [] : {};
|
|
1344
|
+
o = o[p];
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
else {
|
|
1348
|
+
out = value;
|
|
1349
|
+
}
|
|
1350
|
+
return out;
|
|
1351
|
+
}
|
|
1352
|
+
function deconstructObjectWithPath(path, pathTypes, value) {
|
|
1353
|
+
let o = value;
|
|
1354
|
+
for (let i = 0; i < path.length; i++) {
|
|
1355
|
+
const p = path[i];
|
|
1356
|
+
o = o ? o[p] : pathTypes[i] === 'array' ? [] : {};
|
|
1357
|
+
}
|
|
1358
|
+
return o;
|
|
1359
|
+
}
|
|
1360
|
+
function isObservableValueReady(value) {
|
|
1361
|
+
return !!value && ((!isObject(value) && !isArray(value)) || !isEmpty(value));
|
|
1362
|
+
}
|
|
1363
|
+
function setSilently(obs, newValue) {
|
|
1364
|
+
const node = getNode(obs);
|
|
1365
|
+
return setNodeValue(node, newValue).newValue;
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
const fns = ['get', 'set', 'peek', 'onChange', 'toggle'];
|
|
1369
|
+
function ObservablePrimitiveClass(node) {
|
|
1370
|
+
this._node = node;
|
|
1371
|
+
// Bind to this
|
|
1372
|
+
for (let i = 0; i < fns.length; i++) {
|
|
1373
|
+
const key = fns[i];
|
|
1374
|
+
this[key] = this[key].bind(this);
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
// Add observable functions to prototype
|
|
1378
|
+
function proto(key, fn) {
|
|
1379
|
+
ObservablePrimitiveClass.prototype[key] = function (...args) {
|
|
1380
|
+
return fn.call(this, this._node, ...args);
|
|
1381
|
+
};
|
|
1631
1382
|
}
|
|
1632
1383
|
proto('peek', peek);
|
|
1633
1384
|
proto('get', get);
|
|
@@ -1655,76 +1406,122 @@ ObservablePrimitiveClass.prototype.delete = function () {
|
|
|
1655
1406
|
return this;
|
|
1656
1407
|
};
|
|
1657
1408
|
|
|
1658
|
-
function
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1409
|
+
function observable(value) {
|
|
1410
|
+
return createObservable(value, false, getProxy, ObservablePrimitiveClass);
|
|
1411
|
+
}
|
|
1412
|
+
function observablePrimitive(value) {
|
|
1413
|
+
return createObservable(value, true, getProxy, ObservablePrimitiveClass);
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
function setupTracking(nodes, update, noArgs, immediate) {
|
|
1417
|
+
let listeners = [];
|
|
1418
|
+
// Listen to tracked nodes
|
|
1419
|
+
nodes === null || nodes === void 0 ? void 0 : nodes.forEach((tracked) => {
|
|
1420
|
+
const { node, track } = tracked;
|
|
1421
|
+
listeners.push(onChange(node, update, { trackingType: track, immediate, noArgs }));
|
|
1422
|
+
});
|
|
1423
|
+
return () => {
|
|
1424
|
+
if (listeners) {
|
|
1425
|
+
for (let i = 0; i < listeners.length; i++) {
|
|
1426
|
+
listeners[i]();
|
|
1427
|
+
}
|
|
1428
|
+
listeners = undefined;
|
|
1671
1429
|
}
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1430
|
+
};
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
function trackSelector(selector, update, observeEvent, observeOptions, createResubscribe) {
|
|
1434
|
+
var _a;
|
|
1435
|
+
let nodes;
|
|
1436
|
+
let value;
|
|
1437
|
+
let dispose;
|
|
1438
|
+
let tracker;
|
|
1439
|
+
let resubscribe;
|
|
1440
|
+
let updateFn = update;
|
|
1441
|
+
if (isObservable(selector)) {
|
|
1442
|
+
value = selector.peek();
|
|
1443
|
+
dispose = selector.onChange(update);
|
|
1444
|
+
resubscribe = createResubscribe ? selector.onChange(update) : undefined;
|
|
1687
1445
|
}
|
|
1688
1446
|
else {
|
|
1689
|
-
//
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
effect = resolve;
|
|
1447
|
+
// Compute the selector inside a tracking context
|
|
1448
|
+
beginTracking();
|
|
1449
|
+
value = selector ? computeSelector(selector, observeEvent, observeOptions === null || observeOptions === void 0 ? void 0 : observeOptions.fromComputed) : selector;
|
|
1450
|
+
tracker = tracking.current;
|
|
1451
|
+
nodes = tracker.nodes;
|
|
1452
|
+
endTracking();
|
|
1453
|
+
if ((process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') && tracker && nodes) {
|
|
1454
|
+
(_a = tracker.traceListeners) === null || _a === void 0 ? void 0 : _a.call(tracker, nodes);
|
|
1455
|
+
if (tracker.traceUpdates) {
|
|
1456
|
+
updateFn = tracker.traceUpdates(update);
|
|
1700
1457
|
}
|
|
1701
|
-
|
|
1702
|
-
|
|
1458
|
+
// Clear tracing so it doesn't leak to other components
|
|
1459
|
+
tracker.traceListeners = undefined;
|
|
1460
|
+
tracker.traceUpdates = undefined;
|
|
1461
|
+
}
|
|
1703
1462
|
}
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1463
|
+
if (!(observeEvent === null || observeEvent === void 0 ? void 0 : observeEvent.cancel)) {
|
|
1464
|
+
// Do tracing if it was requested
|
|
1465
|
+
// useSyncExternalStore doesn't subscribe until after the component mount.
|
|
1466
|
+
// We want to subscribe immediately so we don't miss any updates
|
|
1467
|
+
dispose = setupTracking(nodes, updateFn, false, observeOptions === null || observeOptions === void 0 ? void 0 : observeOptions.immediate);
|
|
1468
|
+
resubscribe = createResubscribe ? () => setupTracking(nodes, updateFn) : undefined;
|
|
1469
|
+
}
|
|
1470
|
+
return { value, dispose, resubscribe };
|
|
1710
1471
|
}
|
|
1711
1472
|
|
|
1712
|
-
function
|
|
1713
|
-
|
|
1473
|
+
function observe(selectorOrRun, reactionOrOptions, options) {
|
|
1474
|
+
let reaction;
|
|
1475
|
+
if (isFunction(reactionOrOptions)) {
|
|
1476
|
+
reaction = reactionOrOptions;
|
|
1477
|
+
}
|
|
1478
|
+
else {
|
|
1479
|
+
options = reactionOrOptions;
|
|
1480
|
+
}
|
|
1481
|
+
let dispose;
|
|
1482
|
+
const e = { num: 0 };
|
|
1483
|
+
// Wrap it in a function so it doesn't pass all the arguments to run()
|
|
1484
|
+
const update = function () {
|
|
1485
|
+
if (e.onCleanup) {
|
|
1486
|
+
e.onCleanup();
|
|
1487
|
+
e.onCleanup = undefined;
|
|
1488
|
+
}
|
|
1489
|
+
// Run in a batch so changes don't happen until we're done tracking here
|
|
1490
|
+
beginBatch();
|
|
1491
|
+
// Run the function/selector
|
|
1492
|
+
delete e.value;
|
|
1493
|
+
// Dispose listeners from previous run
|
|
1494
|
+
dispose === null || dispose === void 0 ? void 0 : dispose();
|
|
1495
|
+
const { dispose: _dispose, value } = trackSelector(selectorOrRun, update, e, options);
|
|
1496
|
+
dispose = _dispose;
|
|
1497
|
+
e.value = value;
|
|
1498
|
+
if (e.onCleanupReaction) {
|
|
1499
|
+
e.onCleanupReaction();
|
|
1500
|
+
e.onCleanupReaction = undefined;
|
|
1501
|
+
}
|
|
1502
|
+
endBatch();
|
|
1503
|
+
// Call the reaction if there is one and the value changed
|
|
1504
|
+
if (reaction &&
|
|
1505
|
+
(e.num > 0 || !isEvent(selectorOrRun)) &&
|
|
1506
|
+
(e.previous !== e.value || (options === null || options === void 0 ? void 0 : options.fromComputed))) {
|
|
1507
|
+
reaction(e);
|
|
1508
|
+
}
|
|
1509
|
+
// Update the previous value
|
|
1510
|
+
e.previous = e.value;
|
|
1511
|
+
// Increment the counter
|
|
1512
|
+
e.num++;
|
|
1513
|
+
};
|
|
1514
|
+
update();
|
|
1515
|
+
// Return function calling dispose because dispose may be changed in update()
|
|
1516
|
+
return () => {
|
|
1517
|
+
var _a, _b;
|
|
1518
|
+
(_a = e.onCleanup) === null || _a === void 0 ? void 0 : _a.call(e);
|
|
1519
|
+
e.onCleanup = undefined;
|
|
1520
|
+
(_b = e.onCleanupReaction) === null || _b === void 0 ? void 0 : _b.call(e);
|
|
1521
|
+
e.onCleanupReaction = undefined;
|
|
1522
|
+
dispose === null || dispose === void 0 ? void 0 : dispose();
|
|
1523
|
+
};
|
|
1714
1524
|
}
|
|
1715
|
-
function observablePrimitive(value) {
|
|
1716
|
-
return createObservable(value, true, extractPromise, getProxy, ObservablePrimitiveClass);
|
|
1717
|
-
}
|
|
1718
|
-
globalState.isLoadingRemote$ = observable(false);
|
|
1719
|
-
globalState.onChangeRemote = function onChangeRemote(cb) {
|
|
1720
|
-
when(() => !globalState.isLoadingRemote$.get(), () => {
|
|
1721
|
-
// Remote changes should only update local state
|
|
1722
|
-
globalState.isLoadingRemote$.set(true);
|
|
1723
|
-
batch(cb, () => {
|
|
1724
|
-
globalState.isLoadingRemote$.set(false);
|
|
1725
|
-
});
|
|
1726
|
-
});
|
|
1727
|
-
};
|
|
1728
1525
|
|
|
1729
1526
|
function computed(compute, set$1) {
|
|
1730
1527
|
// Create an observable for this computed variable
|
|
@@ -1888,6 +1685,60 @@ function proxy(get, set) {
|
|
|
1888
1685
|
return obs;
|
|
1889
1686
|
}
|
|
1890
1687
|
|
|
1688
|
+
function _when(predicate, effect, checkReady) {
|
|
1689
|
+
// If predicate is a regular Promise skip all the observable stuff
|
|
1690
|
+
if (isPromise(predicate)) {
|
|
1691
|
+
return effect ? predicate.then(effect) : predicate;
|
|
1692
|
+
}
|
|
1693
|
+
let value;
|
|
1694
|
+
// Create a wrapping fn that calls the effect if predicate returns true
|
|
1695
|
+
function run(e) {
|
|
1696
|
+
const ret = computeSelector(predicate);
|
|
1697
|
+
if (!isPromise(ret) && (checkReady ? isObservableValueReady(ret) : ret)) {
|
|
1698
|
+
value = ret;
|
|
1699
|
+
// Set cancel so that observe does not track anymore
|
|
1700
|
+
e.cancel = true;
|
|
1701
|
+
}
|
|
1702
|
+
return value;
|
|
1703
|
+
}
|
|
1704
|
+
function doEffect() {
|
|
1705
|
+
// If value is truthy then run the effect
|
|
1706
|
+
effect === null || effect === void 0 ? void 0 : effect(value);
|
|
1707
|
+
}
|
|
1708
|
+
// Run in an observe
|
|
1709
|
+
observe(run, doEffect);
|
|
1710
|
+
// If first run resulted in a truthy value just return it.
|
|
1711
|
+
// It will have set e.cancel so no need to dispose
|
|
1712
|
+
if (isPromise(value)) {
|
|
1713
|
+
return effect ? value.then(effect) : value;
|
|
1714
|
+
}
|
|
1715
|
+
else if (value !== undefined) {
|
|
1716
|
+
return Promise.resolve(value);
|
|
1717
|
+
}
|
|
1718
|
+
else {
|
|
1719
|
+
// Wrap it in a promise
|
|
1720
|
+
const promise = new Promise((resolve) => {
|
|
1721
|
+
if (effect) {
|
|
1722
|
+
const originalEffect = effect;
|
|
1723
|
+
effect = (value) => {
|
|
1724
|
+
const effectValue = originalEffect(value);
|
|
1725
|
+
resolve(effectValue);
|
|
1726
|
+
};
|
|
1727
|
+
}
|
|
1728
|
+
else {
|
|
1729
|
+
effect = resolve;
|
|
1730
|
+
}
|
|
1731
|
+
});
|
|
1732
|
+
return promise;
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
function when(predicate, effect) {
|
|
1736
|
+
return _when(predicate, effect, false);
|
|
1737
|
+
}
|
|
1738
|
+
function whenReady(predicate, effect) {
|
|
1739
|
+
return _when(predicate, effect, true);
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1891
1742
|
const internal = {
|
|
1892
1743
|
ensureNodeValue,
|
|
1893
1744
|
findIDKey,
|