@legendapp/state 3.0.0-alpha.2 → 3.0.0-alpha.20

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.
Files changed (54) hide show
  1. package/CHANGELOG.md +831 -1
  2. package/LICENSE +21 -1
  3. package/README.md +141 -1
  4. package/babel.js +0 -2
  5. package/babel.mjs +0 -2
  6. package/helpers/trackHistory.js +2 -2
  7. package/helpers/trackHistory.mjs +2 -2
  8. package/index.d.mts +45 -32
  9. package/index.d.ts +45 -32
  10. package/index.js +234 -156
  11. package/index.mjs +234 -156
  12. package/package.json +6 -1
  13. package/persist-plugins/async-storage.d.mts +2 -2
  14. package/persist-plugins/async-storage.d.ts +2 -2
  15. package/persist-plugins/indexeddb.js +1 -1
  16. package/persist-plugins/indexeddb.mjs +1 -1
  17. package/react.d.mts +17 -14
  18. package/react.d.ts +17 -14
  19. package/react.js +55 -30
  20. package/react.mjs +56 -31
  21. package/sync-plugins/_transformObjectFields.d.mts +31 -0
  22. package/sync-plugins/_transformObjectFields.d.ts +31 -0
  23. package/sync-plugins/_transformObjectFields.js +114 -0
  24. package/sync-plugins/_transformObjectFields.mjs +110 -0
  25. package/sync-plugins/crud.d.mts +14 -23
  26. package/sync-plugins/crud.d.ts +14 -23
  27. package/sync-plugins/crud.js +194 -129
  28. package/sync-plugins/crud.mjs +195 -130
  29. package/sync-plugins/firebase.d.mts +26 -0
  30. package/sync-plugins/firebase.d.ts +26 -0
  31. package/sync-plugins/firebase.js +365 -0
  32. package/sync-plugins/firebase.mjs +360 -0
  33. package/sync-plugins/keel.d.mts +24 -8
  34. package/sync-plugins/keel.d.ts +24 -8
  35. package/sync-plugins/keel.js +32 -16
  36. package/sync-plugins/keel.mjs +32 -16
  37. package/sync-plugins/supabase.d.mts +1 -1
  38. package/sync-plugins/supabase.d.ts +1 -1
  39. package/sync-plugins/supabase.js +5 -4
  40. package/sync-plugins/supabase.mjs +6 -5
  41. package/sync-plugins/tanstack-query.d.mts +2 -2
  42. package/sync-plugins/tanstack-query.d.ts +2 -2
  43. package/sync-plugins/tanstack-query.js +3 -2
  44. package/sync-plugins/tanstack-query.mjs +3 -2
  45. package/sync-plugins/tanstack-react-query.d.mts +1 -1
  46. package/sync-plugins/tanstack-react-query.d.ts +1 -1
  47. package/sync.d.mts +38 -185
  48. package/sync.d.ts +38 -185
  49. package/sync.js +354 -296
  50. package/sync.mjs +356 -297
  51. package/types/babel.d.ts +12 -1
  52. package/.DS_Store +0 -0
  53. /package/config/{enable_GetSet.d.mts → enable$GetSet.d.mts} +0 -0
  54. /package/config/{enable_GetSet.d.ts → enable$GetSet.d.ts} +0 -0
package/index.js CHANGED
@@ -33,15 +33,20 @@ function isPromise(obj) {
33
33
  function isMap(obj) {
34
34
  return obj instanceof Map;
35
35
  }
36
+ function isSet(obj) {
37
+ return obj instanceof Set;
38
+ }
36
39
  function isNumber(obj) {
37
40
  const n = obj;
38
- return n - n < 1;
41
+ return typeof n === "number" && n - n < 1;
39
42
  }
40
43
  function isEmpty(obj) {
41
44
  if (!obj)
42
45
  return false;
43
46
  if (isArray(obj))
44
47
  return obj.length === 0;
48
+ if (isMap(obj) || isSet(obj))
49
+ return obj.size === 0;
45
50
  for (const key in obj) {
46
51
  if (hasOwnProperty.call(obj, key)) {
47
52
  return false;
@@ -62,6 +67,7 @@ function isChildNodeValue(node) {
62
67
 
63
68
  // src/globals.ts
64
69
  var symbolToPrimitive = Symbol.toPrimitive;
70
+ var symbolIterator = Symbol.iterator;
65
71
  var symbolGetNode = Symbol("getNode");
66
72
  var symbolDelete = /* @__PURE__ */ Symbol("delete");
67
73
  var symbolOpaque = Symbol("opaque");
@@ -69,7 +75,6 @@ var optimized = Symbol("optimized");
69
75
  var symbolLinked = Symbol("linked");
70
76
  var globalState = {
71
77
  isLoadingLocal: false,
72
- isMerging: false,
73
78
  isLoadingRemote: false,
74
79
  activateSyncedNode: void 0,
75
80
  pendingNodes: /* @__PURE__ */ new Map(),
@@ -77,6 +82,9 @@ var globalState = {
77
82
  replacer: void 0,
78
83
  reviver: void 0
79
84
  };
85
+ function isOpaqueObject(value) {
86
+ return value && (value[symbolOpaque] || value["$$typeof"]);
87
+ }
80
88
  function getPathType(value) {
81
89
  return isArray(value) ? "array" : isMap(value) ? "map" : value instanceof Set ? "set" : "object";
82
90
  }
@@ -118,10 +126,10 @@ function reviver(key, value) {
118
126
  return value;
119
127
  }
120
128
  function safeStringify(value) {
121
- return JSON.stringify(value, replacer);
129
+ return value ? JSON.stringify(value, replacer) : value;
122
130
  }
123
131
  function safeParse(value) {
124
- return JSON.parse(value, reviver);
132
+ return value ? JSON.parse(value, reviver) : value;
125
133
  }
126
134
  function clone(value) {
127
135
  return safeParse(safeStringify(value));
@@ -137,7 +145,7 @@ function isEvent(value$) {
137
145
  return value$ && ((_a = value$[symbolGetNode]) == null ? void 0 : _a.isEvent);
138
146
  }
139
147
  function setNodeValue(node, newValue) {
140
- var _a, _b, _c;
148
+ var _a;
141
149
  const parentNode = (_a = node.parent) != null ? _a : node;
142
150
  const key = node.parent ? node.key : "_";
143
151
  const isDelete = newValue === symbolDelete;
@@ -147,7 +155,7 @@ function setNodeValue(node, newValue) {
147
155
  const prevValue = parentValue[key];
148
156
  const isFunc = isFunction(newValue);
149
157
  newValue = !parentNode.isAssigning && isFunc && !isFunction(prevValue) ? newValue(prevValue) : newValue;
150
- if (!globalState.isMerging || isNullOrUndefined(prevValue) || isFunction(prevValue) || !((_c = (_b = node.parent) == null ? void 0 : _b.functions) == null ? void 0 : _c.get(key))) {
158
+ if (newValue !== prevValue) {
151
159
  try {
152
160
  parentNode.isSetting = (parentNode.isSetting || 0) + 1;
153
161
  const useMapFn = isMap(parentValue);
@@ -285,10 +293,15 @@ function setAtPath(obj, path, pathTypes, value, mode, fullObj, restore) {
285
293
  } else if (o[p] === void 0 && value === void 0 && i === path.length - 1) {
286
294
  return obj;
287
295
  } else if (o[p] === void 0 || o[p] === null) {
288
- o[p] = initializePathType(pathTypes[i]);
296
+ const child = initializePathType(pathTypes[i]);
297
+ if (isMap(o)) {
298
+ o.set(p, child);
299
+ } else {
300
+ o[p] = child;
301
+ }
289
302
  }
290
303
  if (i < path.length - 1) {
291
- o = o[p];
304
+ o = isMap(o) ? o.get(p) : o[p];
292
305
  if (oFull) {
293
306
  oFull = oFull[p];
294
307
  }
@@ -297,13 +310,13 @@ function setAtPath(obj, path, pathTypes, value, mode, fullObj, restore) {
297
310
  }
298
311
  if (p === void 0) {
299
312
  if (mode === "merge") {
300
- obj = _mergeIntoObservable(obj, value);
313
+ obj = deepMerge(obj, value, false, 0);
301
314
  } else {
302
315
  obj = value;
303
316
  }
304
317
  } else {
305
318
  if (mode === "merge") {
306
- o[p] = _mergeIntoObservable(o[p], value);
319
+ o[p] = deepMerge(o[p], value, false, 0);
307
320
  } else if (isMap(o)) {
308
321
  o.set(p, value);
309
322
  } else {
@@ -334,48 +347,58 @@ function setInObservableAtPath(value$, path, pathTypes, value, mode) {
334
347
  }
335
348
  }
336
349
  function mergeIntoObservable(target, ...sources) {
350
+ if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") {
351
+ if (!isObservable(target)) {
352
+ console.error("[legend-state] should only use mergeIntoObservable with observables");
353
+ }
354
+ }
337
355
  beginBatch();
338
- globalState.isMerging = true;
339
356
  for (let i = 0; i < sources.length; i++) {
340
- target = _mergeIntoObservable(target, sources[i]);
357
+ _mergeIntoObservable(
358
+ target,
359
+ sources[i],
360
+ /*assign*/
361
+ i < sources.length - 1,
362
+ 0
363
+ );
341
364
  }
342
- globalState.isMerging = false;
343
365
  endBatch();
344
366
  return target;
345
367
  }
346
- function _mergeIntoObservable(target, source) {
347
- var _a;
368
+ function _mergeIntoObservable(target, source, assign2, levelsDeep) {
348
369
  if (isObservable(source)) {
349
370
  source = source.peek();
350
371
  }
351
- const needsSet = isObservable(target);
352
- const targetValue = needsSet ? target.peek() : target;
372
+ const targetValue = target.peek();
353
373
  const isTargetArr = isArray(targetValue);
354
374
  const isTargetObj = !isTargetArr && isObject(targetValue);
355
- if (isTargetObj && isObject(source) && !isEmpty(targetValue) || isTargetArr && targetValue.length > 0) {
356
- const keys = Object.keys(source);
375
+ const isSourceMap = isMap(source);
376
+ const isSourceSet = isSet(source);
377
+ if (isSourceSet && isSet(targetValue)) {
378
+ target.set(/* @__PURE__ */ new Set([...source, ...targetValue]));
379
+ } else if (isTargetObj && isObject(source) && !isEmpty(targetValue) || isTargetArr && targetValue.length > 0) {
380
+ const keys = isSourceMap || isSourceSet ? Array.from(source.keys()) : Object.keys(source);
357
381
  for (let i = 0; i < keys.length; i++) {
358
382
  const key = keys[i];
359
- const sourceValue = source[key];
383
+ const sourceValue = isSourceSet ? key : isSourceMap ? source.get(key) : source[key];
360
384
  if (sourceValue === symbolDelete) {
361
- needsSet && ((_a = target[key]) == null ? void 0 : _a.delete) ? target[key].delete() : delete target[key];
385
+ target[key].delete();
362
386
  } else {
363
387
  const isObj = isObject(sourceValue);
364
388
  const isArr = !isObj && isArray(sourceValue);
365
389
  const targetChild = target[key];
366
- if ((isObj || isArr) && targetChild && (needsSet || !isEmpty(targetChild))) {
367
- if (!needsSet && (!targetChild || (isObj ? !isObject(targetChild) : !isArray(targetChild)))) {
368
- target[key] = sourceValue;
369
- } else {
370
- _mergeIntoObservable(targetChild, sourceValue);
390
+ if ((isObj || isArr) && targetChild) {
391
+ if (levelsDeep > 0 && isEmpty(sourceValue)) {
392
+ targetChild.set(sourceValue);
371
393
  }
394
+ _mergeIntoObservable(targetChild, sourceValue, false, levelsDeep + 1);
372
395
  } else {
373
- needsSet ? targetChild.set(sourceValue) : target[key] = sourceValue;
396
+ targetChild.set(sourceValue);
374
397
  }
375
398
  }
376
399
  }
377
400
  } else if (source !== void 0) {
378
- needsSet ? target.set(source) : target = source;
401
+ target.set(source);
379
402
  }
380
403
  return target;
381
404
  }
@@ -430,6 +453,25 @@ function applyChanges(value, changes, applyPrevious) {
430
453
  }
431
454
  return value;
432
455
  }
456
+ function deepMerge(target, ...sources) {
457
+ const result = { ...target };
458
+ for (let i = 0; i < sources.length; i++) {
459
+ const obj2 = sources[i];
460
+ for (const key in obj2) {
461
+ if (hasOwnProperty.call(obj2, key)) {
462
+ if (obj2[key] instanceof Object && !isObservable(obj2[key]) && Object.keys(obj2[key]).length > 0) {
463
+ result[key] = deepMerge(
464
+ result[key] || (isArray(obj2[key]) ? [] : {}),
465
+ obj2[key]
466
+ );
467
+ } else {
468
+ result[key] = obj2[key];
469
+ }
470
+ }
471
+ }
472
+ }
473
+ return result;
474
+ }
433
475
 
434
476
  // src/batching.ts
435
477
  var timeout;
@@ -489,31 +531,35 @@ function notify(node, value, prev, level, whenOptimizedOnlyIf) {
489
531
  level,
490
532
  whenOptimizedOnlyIf
491
533
  );
492
- if (changesInBatch.size) {
493
- batchNotifyChanges(
494
- changesInBatch,
495
- /*immediate*/
496
- true
497
- );
498
- }
499
534
  const existing = _batchMap.get(node);
500
535
  if (existing) {
501
- existing.value = value;
536
+ if (existing.prev === value) {
537
+ _batchMap.delete(node);
538
+ } else {
539
+ existing.value = value;
540
+ }
502
541
  } else {
503
542
  _batchMap.set(node, {
504
543
  value,
505
544
  prev,
506
545
  level,
507
546
  whenOptimizedOnlyIf,
508
- remote: globalState.isLoadingRemote,
509
- loading: globalState.isLoadingLocal
547
+ isFromSync: globalState.isLoadingRemote,
548
+ isFromPersist: globalState.isLoadingLocal
510
549
  });
511
550
  }
551
+ if (changesInBatch.size) {
552
+ batchNotifyChanges(
553
+ changesInBatch,
554
+ /*immediate*/
555
+ true
556
+ );
557
+ }
512
558
  if (numInBatch <= 0) {
513
559
  runBatch();
514
560
  }
515
561
  }
516
- function computeChangesAtNode(changesInBatch, node, loading, remote, value, path, pathTypes, valueAtPath, prevAtPath, immediate, level, whenOptimizedOnlyIf) {
562
+ function computeChangesAtNode(changesInBatch, node, isFromPersist, isFromSync, value, path, pathTypes, valueAtPath, prevAtPath, immediate, level, whenOptimizedOnlyIf) {
517
563
  if (immediate ? node.listenersImmediate : node.listeners) {
518
564
  const change = {
519
565
  path,
@@ -526,13 +572,14 @@ function computeChangesAtNode(changesInBatch, node, loading, remote, value, path
526
572
  const { changes } = changeInBatch;
527
573
  if (!isArraySubset(changes[0].path, change.path)) {
528
574
  changes.push(change);
575
+ changeInBatch.level = Math.min(changeInBatch.level, level);
529
576
  }
530
577
  } else {
531
578
  changesInBatch.set(node, {
532
579
  level,
533
580
  value,
534
- remote,
535
- loading,
581
+ isFromSync,
582
+ isFromPersist,
536
583
  whenOptimizedOnlyIf,
537
584
  changes: [change]
538
585
  });
@@ -596,7 +643,7 @@ function computeChangesRecursive(changesInBatch, node, loading, remote, value, p
596
643
  }
597
644
  function batchNotifyChanges(changesInBatch, immediate) {
598
645
  const listenersNotified = /* @__PURE__ */ new Set();
599
- changesInBatch.forEach(({ changes, level, value, loading, remote, whenOptimizedOnlyIf }, node) => {
646
+ changesInBatch.forEach(({ changes, level, value, isFromPersist, isFromSync, whenOptimizedOnlyIf }, node) => {
600
647
  const listeners = immediate ? node.listenersImmediate : node.listeners;
601
648
  if (listeners) {
602
649
  let listenerParams;
@@ -610,8 +657,8 @@ function batchNotifyChanges(changesInBatch, immediate) {
610
657
  if (!noArgs && !listenerParams) {
611
658
  listenerParams = {
612
659
  value,
613
- loading,
614
- remote,
660
+ isFromPersist,
661
+ isFromSync,
615
662
  getPrevious: createPreviousHandler(value, changes),
616
663
  changes
617
664
  };
@@ -639,12 +686,12 @@ function runBatch() {
639
686
  const map = _batchMap;
640
687
  _batchMap = /* @__PURE__ */ new Map();
641
688
  const changesInBatch = /* @__PURE__ */ new Map();
642
- map.forEach(({ value, prev, level, loading, remote, whenOptimizedOnlyIf }, node) => {
689
+ map.forEach(({ value, prev, level, isFromPersist, isFromSync, whenOptimizedOnlyIf }, node) => {
643
690
  computeChangesRecursive(
644
691
  changesInBatch,
645
692
  node,
646
- loading,
647
- remote,
693
+ isFromPersist,
694
+ isFromSync,
648
695
  value,
649
696
  [],
650
697
  [],
@@ -703,21 +750,6 @@ function getNodeAtPath(obj, path) {
703
750
  return o;
704
751
  }
705
752
 
706
- // src/linked.ts
707
- function linked(params, options) {
708
- if (isFunction(params)) {
709
- params = { get: params };
710
- }
711
- if (options) {
712
- params = { ...params, ...options };
713
- }
714
- const ret = function() {
715
- return { [symbolLinked]: params };
716
- };
717
- ret.prototype[symbolLinked] = params;
718
- return ret;
719
- }
720
-
721
753
  // src/createObservable.ts
722
754
  function createObservable(value, makePrimitive, extractPromise2, createObject, createPrimitive) {
723
755
  if (isObservable(value)) {
@@ -747,6 +779,21 @@ function createObservable(value, makePrimitive, extractPromise2, createObject, c
747
779
  return obs;
748
780
  }
749
781
 
782
+ // src/linked.ts
783
+ function linked(params, options) {
784
+ if (isFunction(params)) {
785
+ params = { get: params };
786
+ }
787
+ if (options) {
788
+ params = { ...params, ...options };
789
+ }
790
+ const ret = function() {
791
+ return { [symbolLinked]: params };
792
+ };
793
+ ret.prototype[symbolLinked] = params;
794
+ return ret;
795
+ }
796
+
750
797
  // src/onChange.ts
751
798
  function onChange(node, callback, options = {}, fromLinks) {
752
799
  var _a;
@@ -771,8 +818,8 @@ function onChange(node, callback, options = {}, fromLinks) {
771
818
  const value = getNodeValue(node);
772
819
  callback({
773
820
  value,
774
- loading: true,
775
- remote: false,
821
+ isFromPersist: true,
822
+ isFromSync: false,
776
823
  changes: [
777
824
  {
778
825
  path: [],
@@ -829,13 +876,13 @@ function onChange(node, callback, options = {}, fromLinks) {
829
876
  }
830
877
  function createCb(linkedFromNode, path, callback) {
831
878
  let { valueAtPath: prevAtPath } = getValueAtPath2(getNodeValue(linkedFromNode), path);
832
- return function({ value: valueA, loading, remote }) {
879
+ return function({ value: valueA, isFromPersist, isFromSync }) {
833
880
  const { valueAtPath } = getValueAtPath2(valueA, path);
834
881
  if (valueAtPath !== prevAtPath) {
835
882
  callback({
836
883
  value: valueAtPath,
837
- loading,
838
- remote,
884
+ isFromPersist,
885
+ isFromSync,
839
886
  changes: [
840
887
  {
841
888
  path: [],
@@ -955,12 +1002,17 @@ function observe(selectorOrRun, reactionOrOptions, options) {
955
1002
  options = reactionOrOptions;
956
1003
  }
957
1004
  let dispose;
1005
+ let isRunning = false;
958
1006
  const e = { num: 0 };
959
1007
  const update = function() {
1008
+ if (isRunning) {
1009
+ return;
1010
+ }
960
1011
  if (e.onCleanup) {
961
1012
  e.onCleanup();
962
1013
  e.onCleanup = void 0;
963
1014
  }
1015
+ isRunning = true;
964
1016
  beginBatch();
965
1017
  delete e.value;
966
1018
  dispose == null ? void 0 : dispose();
@@ -974,6 +1026,7 @@ function observe(selectorOrRun, reactionOrOptions, options) {
974
1026
  e.onCleanupReaction = void 0;
975
1027
  }
976
1028
  endBatch();
1029
+ isRunning = false;
977
1030
  if (reaction && ((options == null ? void 0 : options.fromComputed) || (e.num > 0 || !isEvent(selectorOrRun)) && (e.previous !== e.value || typeof e.value === "object"))) {
978
1031
  reaction(e);
979
1032
  }
@@ -1110,7 +1163,7 @@ function updateNodes(parent, obj, prevValue) {
1110
1163
  }
1111
1164
  __devUpdateNodes.add(obj);
1112
1165
  }
1113
- if (isObject(obj) && obj[symbolOpaque] || isObject(prevValue) && prevValue[symbolOpaque]) {
1166
+ if (isObject(obj) && isOpaqueObject(obj) || isObject(prevValue) && isOpaqueObject(prevValue)) {
1114
1167
  const isDiff = obj !== prevValue;
1115
1168
  if (isDiff) {
1116
1169
  if (parent.listeners || parent.listenersImmediate) {
@@ -1298,10 +1351,10 @@ var proxyHandler = {
1298
1351
  if (p === symbolGetNode) {
1299
1352
  return node;
1300
1353
  }
1301
- if (p === "apply") {
1354
+ if (p === "apply" || p === "call") {
1302
1355
  const nodeValue = getNodeValue(node);
1303
1356
  if (isFunction(nodeValue)) {
1304
- return nodeValue.apply;
1357
+ return nodeValue[p];
1305
1358
  }
1306
1359
  }
1307
1360
  let value = peekInternal(
@@ -1309,6 +1362,9 @@ var proxyHandler = {
1309
1362
  /*activateRecursive*/
1310
1363
  p === "get" || p === "peek"
1311
1364
  );
1365
+ if (p === symbolIterator) {
1366
+ return !value || isPrimitive(value) ? void 0 : value[p];
1367
+ }
1312
1368
  const targetNode = node.linkedToNode || (value == null ? void 0 : value[symbolGetNode]);
1313
1369
  if (targetNode && p !== "onChange") {
1314
1370
  return proxyHandler.get(targetNode, p, receiver);
@@ -1343,7 +1399,7 @@ var proxyHandler = {
1343
1399
  return property.get(node);
1344
1400
  }
1345
1401
  let vProp = value == null ? void 0 : value[p];
1346
- if (isObject(value) && value[symbolOpaque]) {
1402
+ if (isObject(value) && isOpaqueObject(value)) {
1347
1403
  return vProp;
1348
1404
  }
1349
1405
  const fnOrComputed = (_a = node.functions) == null ? void 0 : _a.get(p);
@@ -1509,11 +1565,17 @@ function setKey(node, key, newValue, level) {
1509
1565
  } else {
1510
1566
  const { newValue: savedValue, prevValue } = setNodeValue(childNode, newValue);
1511
1567
  const isPrim = isPrimitive(savedValue) || savedValue instanceof Date;
1512
- if (!equals(savedValue, prevValue)) {
1513
- updateNodesAndNotify(node, savedValue, prevValue, childNode, isPrim, isRoot, level);
1514
- }
1515
1568
  if (!isPrim) {
1516
- childNode.needsExtract = true;
1569
+ let parent = childNode;
1570
+ do {
1571
+ parent.needsExtract = true;
1572
+ parent.recursivelyAutoActivated = false;
1573
+ } while (parent = parent.parent);
1574
+ }
1575
+ const notify2 = !equals(savedValue, prevValue);
1576
+ const forceNotify = !notify2 && childNode.isComputing && !isPrim;
1577
+ if (notify2 || forceNotify) {
1578
+ updateNodesAndNotify(node, savedValue, prevValue, childNode, isPrim, isRoot, level, forceNotify);
1517
1579
  }
1518
1580
  extractFunctionOrComputed(node, key, savedValue);
1519
1581
  }
@@ -1528,6 +1590,8 @@ function assign(node, value) {
1528
1590
  const currentValue = getNodeValue(node);
1529
1591
  if (isMap(currentValue)) {
1530
1592
  value.forEach((value2, key) => currentValue.set(key, value2));
1593
+ } else {
1594
+ set(node, value);
1531
1595
  }
1532
1596
  } else {
1533
1597
  node.isAssigning = (node.isAssigning || 0) + 1;
@@ -1624,20 +1688,20 @@ function handlerMapSet(node, p, value) {
1624
1688
  };
1625
1689
  }
1626
1690
  }
1627
- function updateNodesAndNotify(node, newValue, prevValue, childNode, isPrim, isRoot, level) {
1691
+ function updateNodesAndNotify(node, newValue, prevValue, childNode, isPrim, isRoot, level, forceNotify) {
1628
1692
  if (!childNode)
1629
1693
  childNode = node;
1630
1694
  beginBatch();
1631
1695
  if (isPrim === void 0) {
1632
1696
  isPrim = isPrimitive(newValue);
1633
1697
  }
1634
- let hasADiff = isPrim;
1698
+ let hasADiff = forceNotify || isPrim;
1635
1699
  let whenOptimizedOnlyIf = false;
1636
1700
  if (!isPrim || prevValue && !isPrimitive(prevValue)) {
1637
1701
  if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && typeof __devUpdateNodes !== "undefined") {
1638
1702
  __devUpdateNodes.clear();
1639
1703
  }
1640
- hasADiff = updateNodes(childNode, newValue, prevValue);
1704
+ hasADiff = hasADiff || updateNodes(childNode, newValue, prevValue);
1641
1705
  if (isArray(newValue)) {
1642
1706
  whenOptimizedOnlyIf = (newValue == null ? void 0 : newValue.length) !== (prevValue == null ? void 0 : prevValue.length);
1643
1707
  }
@@ -1654,6 +1718,7 @@ function updateNodesAndNotify(node, newValue, prevValue, childNode, isPrim, isRo
1654
1718
  endBatch();
1655
1719
  }
1656
1720
  function extractPromise(node, value, setter) {
1721
+ const numGets = node.numGets = (node.numGets || 0) + 1;
1657
1722
  if (!node.state) {
1658
1723
  node.state = createObservable(
1659
1724
  {
@@ -1665,11 +1730,14 @@ function extractPromise(node, value, setter) {
1665
1730
  );
1666
1731
  }
1667
1732
  value.then((value2) => {
1668
- setter ? setter({ value: value2 }) : set(node, value2);
1669
- node.state.assign({
1670
- isLoaded: true,
1671
- error: void 0
1672
- });
1733
+ if (numGets >= (node.getNumResolved || 0)) {
1734
+ node.getNumResolved = node.numGets;
1735
+ setter ? setter({ value: value2 }) : set(node, value2);
1736
+ node.state.assign({
1737
+ isLoaded: true,
1738
+ error: void 0
1739
+ });
1740
+ }
1673
1741
  }).catch((error) => {
1674
1742
  node.state.error.set(error);
1675
1743
  });
@@ -1686,6 +1754,7 @@ function extractFunctionOrComputed(node, k, v) {
1686
1754
  const childNode = getChildNode(node, k, fn);
1687
1755
  const targetNode = getNode(v);
1688
1756
  const initialValue = peek(targetNode);
1757
+ setToObservable(childNode, v);
1689
1758
  setNodeValue(childNode, initialValue);
1690
1759
  return getNodeValue(childNode);
1691
1760
  } else if (typeof v === "function") {
@@ -1718,7 +1787,9 @@ function peekInternal(node, activateRecursive) {
1718
1787
  }
1719
1788
  isFlushing = false;
1720
1789
  let value = getNodeValue(node);
1721
- value = checkLazy(node, value, !!activateRecursive);
1790
+ if (!globalState.isLoadingLocal) {
1791
+ value = checkLazy(node, value, !!activateRecursive);
1792
+ }
1722
1793
  return value;
1723
1794
  }
1724
1795
  function checkLazy(node, value, activateRecursive) {
@@ -1733,10 +1804,12 @@ function checkLazy(node, value, activateRecursive) {
1733
1804
  } else {
1734
1805
  if (node.parent) {
1735
1806
  const parentValue = getNodeValue(node.parent);
1736
- if (parentValue) {
1737
- delete parentValue[node.key];
1738
- } else {
1739
- node.root._ = void 0;
1807
+ if (isFunction(value)) {
1808
+ if (parentValue) {
1809
+ delete parentValue[node.key];
1810
+ } else {
1811
+ node.root._ = void 0;
1812
+ }
1740
1813
  }
1741
1814
  }
1742
1815
  value = activateNodeFunction(node, lazyFn);
@@ -1825,7 +1898,9 @@ function activateNodeFunction(node, lazyFn) {
1825
1898
  var _a, _b, _c, _d;
1826
1899
  if (isFirst) {
1827
1900
  isFirst = false;
1828
- setNodeValue(node, void 0);
1901
+ if (isFunction(getNodeValue(node))) {
1902
+ setNodeValue(node, void 0);
1903
+ }
1829
1904
  } else if (!isFlushing && refreshFn) {
1830
1905
  if (shouldIgnoreUnobserved(node, refreshFn)) {
1831
1906
  ignoreThisUpdate = true;
@@ -1838,7 +1913,7 @@ function activateNodeFunction(node, lazyFn) {
1838
1913
  didSetToObs = true;
1839
1914
  value = setToObservable(node, value);
1840
1915
  }
1841
- if (isFunction(value)) {
1916
+ if (isFunction(value) && value.length === 0) {
1842
1917
  value = value();
1843
1918
  }
1844
1919
  const activated = !isObservable(value) ? value == null ? void 0 : value[symbolLinked] : void 0;
@@ -1896,16 +1971,14 @@ function activateNodeFunction(node, lazyFn) {
1896
1971
  }
1897
1972
  } else {
1898
1973
  activatedValue = value;
1899
- if (node.state.isLoaded.peek()) {
1974
+ const isLoaded = node.state.isLoaded.peek();
1975
+ if (isLoaded || !isFunction(value)) {
1900
1976
  node.isComputing = true;
1901
1977
  set(node, value);
1902
1978
  node.isComputing = false;
1903
- } else {
1904
- setNodeValue(node, value);
1905
- node.state.assign({
1906
- isLoaded: true,
1907
- error: void 0
1908
- });
1979
+ }
1980
+ if (!isLoaded) {
1981
+ node.state.assign({ isLoaded: true, error: void 0 });
1909
1982
  }
1910
1983
  }
1911
1984
  }
@@ -1946,14 +2019,14 @@ function activateNodeBase(node, value) {
1946
2019
  if (allChanges.length > 0) {
1947
2020
  let changes;
1948
2021
  let value2;
1949
- let loading = false;
1950
- let remote = false;
2022
+ let isFromPersist = false;
2023
+ let isFromSync = false;
1951
2024
  let getPrevious;
1952
2025
  if (listenerParams) {
1953
2026
  changes = listenerParams.changes;
1954
2027
  value2 = listenerParams.value;
1955
- loading = listenerParams.loading;
1956
- remote = listenerParams.remote;
2028
+ isFromPersist = listenerParams.isFromPersist;
2029
+ isFromSync = listenerParams.isFromSync;
1957
2030
  getPrevious = listenerParams.getPrevious;
1958
2031
  } else {
1959
2032
  changes = allChanges;
@@ -1973,8 +2046,8 @@ function activateNodeBase(node, value) {
1973
2046
  setFn({
1974
2047
  value: value2,
1975
2048
  changes,
1976
- loading,
1977
- remote,
2049
+ isFromPersist,
2050
+ isFromSync,
1978
2051
  getPrevious
1979
2052
  });
1980
2053
  node.isComputing = false;
@@ -2019,7 +2092,9 @@ function setToObservable(node, value) {
2019
2092
  linkedNode,
2020
2093
  () => {
2021
2094
  value = peekInternal(linkedNode);
2022
- set(node, value);
2095
+ if (!isFunction(value)) {
2096
+ set(node, value);
2097
+ }
2023
2098
  },
2024
2099
  { initial: true },
2025
2100
  /* @__PURE__ */ new Set([node])
@@ -2028,7 +2103,8 @@ function setToObservable(node, value) {
2028
2103
  return value;
2029
2104
  }
2030
2105
  function recursivelyAutoActivate(obj, node) {
2031
- if (isObject(obj) || isArray(obj)) {
2106
+ if (!node.recursivelyAutoActivated && (isObject(obj) || isArray(obj)) && !isOpaqueObject(obj)) {
2107
+ node.recursivelyAutoActivated = true;
2032
2108
  const pathStack = [];
2033
2109
  const getNodeAtPath2 = () => {
2034
2110
  var _a;
@@ -2046,27 +2122,29 @@ function recursivelyAutoActivate(obj, node) {
2046
2122
  }
2047
2123
  function recursivelyAutoActivateInner(obj, pathStack, getNodeAtPath2) {
2048
2124
  var _a;
2049
- for (const key in obj) {
2050
- if (hasOwnProperty.call(obj, key)) {
2051
- const value = obj[key];
2052
- if (isObservable(value)) {
2053
- const childNode = getNodeAtPath2();
2054
- extractFunctionOrComputed(childNode, key, value);
2055
- delete childNode.lazy;
2056
- } else {
2057
- const linkedOptions = isFunction(value) && ((_a = value.prototype) == null ? void 0 : _a[symbolLinked]);
2058
- if (linkedOptions) {
2059
- const activate = linkedOptions.activate;
2060
- if (!activate || activate === "auto") {
2061
- const childNode = getNodeAtPath2();
2062
- peek(getChildNode(childNode, key, value));
2125
+ if ((isObject(obj) || isArray(obj)) && !isOpaqueObject(obj)) {
2126
+ for (const key in obj) {
2127
+ if (hasOwnProperty.call(obj, key)) {
2128
+ const value = obj[key];
2129
+ if (isObservable(value)) {
2130
+ const childNode = getNodeAtPath2();
2131
+ extractFunctionOrComputed(childNode, key, value);
2132
+ delete childNode.lazy;
2133
+ } else {
2134
+ const linkedOptions = isFunction(value) && ((_a = value.prototype) == null ? void 0 : _a[symbolLinked]);
2135
+ if (linkedOptions) {
2136
+ const activate = linkedOptions.activate;
2137
+ if (!activate || activate === "auto") {
2138
+ const childNode = getNodeAtPath2();
2139
+ peek(getChildNode(childNode, key, value));
2140
+ }
2063
2141
  }
2064
2142
  }
2065
- }
2066
- if (typeof value === "object") {
2067
- pathStack.push({ key, value });
2068
- recursivelyAutoActivateInner(value, pathStack, getNodeAtPath2);
2069
- pathStack.pop();
2143
+ if (typeof value === "object") {
2144
+ pathStack.push({ key, value });
2145
+ recursivelyAutoActivateInner(value, pathStack, getNodeAtPath2);
2146
+ pathStack.pop();
2147
+ }
2070
2148
  }
2071
2149
  }
2072
2150
  }
@@ -2122,16 +2200,6 @@ function observable(value) {
2122
2200
  function observablePrimitive(value) {
2123
2201
  return createObservable(value, true, extractPromise, getProxy, ObservablePrimitiveClass);
2124
2202
  }
2125
- function syncState(obs) {
2126
- const node = getNode(obs);
2127
- if (!node.state) {
2128
- peekInternal(node);
2129
- }
2130
- if (!node.state) {
2131
- node.state = observable({});
2132
- }
2133
- return node.state;
2134
- }
2135
2203
 
2136
2204
  // src/computed.ts
2137
2205
  function computed(get2, set2) {
@@ -2209,54 +2277,63 @@ function proxy(get2, set2) {
2209
2277
  );
2210
2278
  }
2211
2279
 
2280
+ // src/syncState.ts
2281
+ function syncState(obs) {
2282
+ const node = getNode(obs);
2283
+ if (!node.state) {
2284
+ node.state = observable({
2285
+ isPersistLoaded: false,
2286
+ isLoaded: false,
2287
+ isPersistEnabled: true,
2288
+ isSyncEnabled: true,
2289
+ isGetting: false,
2290
+ isSetting: false,
2291
+ numPendingSets: 0,
2292
+ syncCount: 0,
2293
+ clearPersist: void 0,
2294
+ sync: () => Promise.resolve(),
2295
+ getPendingChanges: () => ({})
2296
+ });
2297
+ }
2298
+ return node.state;
2299
+ }
2300
+
2212
2301
  // src/retry.ts
2213
- function calculateRetryDelay(retryOptions, attemptNum) {
2302
+ function calculateRetryDelay(retryOptions, retryNum) {
2214
2303
  const { backoff, delay = 1e3, infinite, times = 3, maxDelay = 3e4 } = retryOptions;
2215
- if (infinite || attemptNum < times) {
2216
- const delayTime = Math.min(delay * (backoff === "constant" ? 1 : 2 ** attemptNum), maxDelay);
2304
+ if (infinite || retryNum < times) {
2305
+ const delayTime = Math.min(delay * (backoff === "constant" ? 1 : 2 ** retryNum), maxDelay);
2217
2306
  return delayTime;
2218
2307
  }
2219
2308
  return null;
2220
2309
  }
2221
- function createRetryTimeout(retryOptions, attemptNum, fn) {
2222
- const delayTime = calculateRetryDelay(retryOptions, attemptNum);
2310
+ function createRetryTimeout(retryOptions, retryNum, fn) {
2311
+ const delayTime = calculateRetryDelay(retryOptions, retryNum);
2223
2312
  if (delayTime) {
2224
2313
  return setTimeout(fn, delayTime);
2225
2314
  }
2226
2315
  }
2227
- function runWithRetry(node, state, fn) {
2228
- const { waitFor } = node.activationState;
2316
+ function runWithRetry(state, fn) {
2229
2317
  const { retry } = state;
2230
- const e = { cancel: false };
2231
- let value = void 0;
2232
- if (waitFor) {
2233
- value = whenReady(waitFor, () => {
2234
- node.activationState.waitFor = void 0;
2235
- return fn(e);
2236
- });
2237
- } else {
2238
- value = fn(e);
2239
- }
2318
+ const e = Object.assign(state, { cancel: false, cancelRetry: () => e.cancel = false });
2319
+ let value = fn(e);
2240
2320
  if (isPromise(value) && retry) {
2241
2321
  let timeoutRetry;
2242
2322
  return new Promise((resolve) => {
2243
2323
  const run = () => {
2244
2324
  value.then((val) => {
2245
- node.activationState.persistedRetry = false;
2246
2325
  resolve(val);
2247
2326
  }).catch(() => {
2248
- state.attemptNum++;
2327
+ state.retryNum++;
2249
2328
  if (timeoutRetry) {
2250
2329
  clearTimeout(timeoutRetry);
2251
2330
  }
2252
2331
  if (!e.cancel) {
2253
- timeoutRetry = createRetryTimeout(retry, state.attemptNum, () => {
2332
+ timeoutRetry = createRetryTimeout(retry, state.retryNum, () => {
2254
2333
  value = fn(e);
2255
2334
  run();
2256
2335
  });
2257
2336
  }
2258
- }).finally(() => {
2259
- node.activationState.persistedRetry = false;
2260
2337
  });
2261
2338
  };
2262
2339
  run();
@@ -2269,6 +2346,7 @@ function runWithRetry(node, state, fn) {
2269
2346
  var internal = {
2270
2347
  createPreviousHandler,
2271
2348
  clone,
2349
+ deepMerge,
2272
2350
  ensureNodeValue,
2273
2351
  findIDKey,
2274
2352
  get,