@legendapp/state 2.0.0-next.9 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/config/enableDirectAccess.js +6 -3
  3. package/config/enableDirectAccess.js.map +1 -1
  4. package/config/enableDirectAccess.mjs +7 -4
  5. package/config/enableDirectAccess.mjs.map +1 -1
  6. package/config/enableReactDirectRender.d.ts +2 -0
  7. package/config/enableReactDirectRender.js +78 -0
  8. package/config/enableReactDirectRender.js.map +1 -0
  9. package/config/enableReactDirectRender.mjs +75 -0
  10. package/config/enableReactDirectRender.mjs.map +1 -0
  11. package/config/enableReactNativeComponents.js +15 -0
  12. package/config/enableReactNativeComponents.js.map +1 -1
  13. package/config/enableReactNativeComponents.mjs +16 -1
  14. package/config/enableReactNativeComponents.mjs.map +1 -1
  15. package/config/enableReactTracking.d.ts +15 -0
  16. package/config/enableReactTracking.js +47 -0
  17. package/config/enableReactTracking.js.map +1 -0
  18. package/config/enableReactTracking.mjs +45 -0
  19. package/config/enableReactTracking.mjs.map +1 -0
  20. package/history.js +1 -1
  21. package/history.js.map +1 -1
  22. package/history.mjs +1 -1
  23. package/history.mjs.map +1 -1
  24. package/index.d.ts +4 -3
  25. package/index.js +145 -121
  26. package/index.js.map +1 -1
  27. package/index.mjs +143 -122
  28. package/index.mjs.map +1 -1
  29. package/package.json +31 -1
  30. package/persist-plugins/async-storage.d.ts +14 -0
  31. package/persist-plugins/async-storage.js +100 -0
  32. package/persist-plugins/async-storage.js.map +1 -0
  33. package/persist-plugins/async-storage.mjs +98 -0
  34. package/persist-plugins/async-storage.mjs.map +1 -0
  35. package/persist-plugins/fetch.d.ts +10 -0
  36. package/persist-plugins/fetch.js +22 -0
  37. package/persist-plugins/fetch.js.map +1 -0
  38. package/persist-plugins/fetch.mjs +20 -0
  39. package/persist-plugins/fetch.mjs.map +1 -0
  40. package/persist-plugins/firebase.d.ts +51 -0
  41. package/persist-plugins/firebase.js +694 -0
  42. package/persist-plugins/firebase.js.map +1 -0
  43. package/persist-plugins/firebase.mjs +692 -0
  44. package/persist-plugins/firebase.mjs.map +1 -0
  45. package/persist-plugins/indexeddb.d.ts +2 -3
  46. package/persist-plugins/indexeddb.js +1 -16
  47. package/persist-plugins/indexeddb.js.map +1 -1
  48. package/persist-plugins/indexeddb.mjs +1 -16
  49. package/persist-plugins/indexeddb.mjs.map +1 -1
  50. package/persist-plugins/local-storage.d.ts +1 -2
  51. package/persist-plugins/local-storage.js +1 -5
  52. package/persist-plugins/local-storage.js.map +1 -1
  53. package/persist-plugins/local-storage.mjs +1 -5
  54. package/persist-plugins/local-storage.mjs.map +1 -1
  55. package/persist-plugins/mmkv.d.ts +4 -4
  56. package/persist-plugins/mmkv.js +6 -4
  57. package/persist-plugins/mmkv.js.map +1 -1
  58. package/persist-plugins/mmkv.mjs +6 -4
  59. package/persist-plugins/mmkv.mjs.map +1 -1
  60. package/persist-plugins/query.d.ts +18 -0
  61. package/persist-plugins/query.js +79 -0
  62. package/persist-plugins/query.js.map +1 -0
  63. package/persist-plugins/query.mjs +77 -0
  64. package/persist-plugins/query.mjs.map +1 -0
  65. package/persist.js +167 -151
  66. package/persist.js.map +1 -1
  67. package/persist.mjs +168 -152
  68. package/persist.mjs.map +1 -1
  69. package/react-hooks/useObservableNextRouter.js +6 -6
  70. package/react-hooks/useObservableNextRouter.js.map +1 -1
  71. package/react-hooks/useObservableNextRouter.mjs +6 -6
  72. package/react-hooks/useObservableNextRouter.mjs.map +1 -1
  73. package/react-hooks/usePersistedObservable.d.ts +2 -2
  74. package/react-hooks/usePersistedObservable.js +1 -6
  75. package/react-hooks/usePersistedObservable.js.map +1 -1
  76. package/react-hooks/usePersistedObservable.mjs +1 -6
  77. package/react-hooks/usePersistedObservable.mjs.map +1 -1
  78. package/react.d.ts +1 -0
  79. package/react.js +137 -54
  80. package/react.js.map +1 -1
  81. package/react.mjs +137 -56
  82. package/react.mjs.map +1 -1
  83. package/src/ObservableObject.d.ts +4 -4
  84. package/src/config/enableReactDirectRender.d.ts +2 -0
  85. package/src/config/enableReactTracking.d.ts +15 -0
  86. package/src/createObservable.d.ts +2 -0
  87. package/src/globals.d.ts +3 -3
  88. package/src/helpers.d.ts +3 -3
  89. package/src/is.d.ts +1 -0
  90. package/src/observable.d.ts +3 -3
  91. package/src/observableInterfaces.d.ts +90 -74
  92. package/src/observe.d.ts +1 -2
  93. package/src/persist/observablePersistRemoteFunctionsAdapter.d.ts +2 -0
  94. package/src/persist/persistObservable.d.ts +10 -13
  95. package/src/persist-plugins/async-storage.d.ts +14 -0
  96. package/src/persist-plugins/fetch.d.ts +10 -0
  97. package/src/persist-plugins/firebase.d.ts +51 -0
  98. package/src/persist-plugins/indexeddb.d.ts +2 -3
  99. package/src/persist-plugins/local-storage.d.ts +1 -2
  100. package/src/persist-plugins/mmkv.d.ts +4 -4
  101. package/src/persist-plugins/query.d.ts +18 -0
  102. package/src/react/For.d.ts +7 -6
  103. package/src/react/Reactive.d.ts +1 -1
  104. package/src/react/react-globals.d.ts +3 -0
  105. package/src/react/reactInterfaces.d.ts +8 -5
  106. package/src/react/useMount.d.ts +1 -2
  107. package/src/react/useObservableState.d.ts +2 -0
  108. package/src/react/useWhen.d.ts +3 -0
  109. package/src/react-hooks/usePersistedObservable.d.ts +2 -2
  110. package/src/trackSelector.d.ts +2 -2
  111. package/src/tracking.d.ts +2 -3
  112. package/src/persist/observablePersistRemoteSimple.d.ts +0 -2
package/index.js CHANGED
@@ -50,55 +50,14 @@ function isChildNodeValue(node) {
50
50
  return !!node.parent;
51
51
  }
52
52
 
53
- let trackCount = 0;
54
- const trackingQueue = [];
55
- const tracking = {
56
- current: undefined,
57
- inRender: false,
58
- };
59
- function beginTracking(inRender) {
60
- // Keep a copy of the previous tracking context so it can be restored
61
- // when this context is complete
62
- trackingQueue.push(tracking.current);
63
- trackCount++;
64
- tracking.inRender = inRender;
65
- tracking.current = {};
66
- }
67
- function endTracking(fromRender) {
68
- // Restore the previous tracking context
69
- trackCount--;
70
- if (trackCount < 0) {
71
- trackCount = 0;
72
- }
73
- if (fromRender) {
74
- tracking.inRender = false;
75
- }
76
- tracking.current = trackingQueue.pop();
77
- }
78
- function updateTracking(node, track) {
79
- if (trackCount) {
80
- const tracker = tracking.current;
81
- if (tracker) {
82
- if (!tracker.nodes) {
83
- tracker.nodes = new Map();
84
- }
85
- const existing = tracker.nodes.get(node);
86
- if (existing) {
87
- existing.track = existing.track || track;
88
- existing.num++;
89
- }
90
- else {
91
- tracker.nodes.set(node, { node, track, num: 1 });
92
- }
93
- }
94
- }
95
- }
96
-
97
53
  const symbolToPrimitive = Symbol.toPrimitive;
98
54
  const symbolGetNode = Symbol('getNode');
99
55
  const symbolDelete = /* @__PURE__ */ Symbol('delete');
100
56
  const symbolOpaque = Symbol('opaque');
101
57
  const optimized = Symbol('optimized');
58
+ // TODOV3 Remove these
59
+ const extraPrimitiveActivators = new Map();
60
+ const extraPrimitiveProps = new Map();
102
61
  const globalState = {
103
62
  isLoadingLocal: false,
104
63
  isLoadingRemote: false,
@@ -116,15 +75,6 @@ function checkActivate(node) {
116
75
  function getNode(obs) {
117
76
  return obs && obs[symbolGetNode];
118
77
  }
119
- function get(node, track) {
120
- // Track by default
121
- updateTracking(node, track);
122
- return peek(node);
123
- }
124
- function peek(node) {
125
- checkActivate(node);
126
- return getNodeValue(node);
127
- }
128
78
  function setNodeValue(node, newValue) {
129
79
  var _a;
130
80
  const parentNode = (_a = node.parent) !== null && _a !== void 0 ? _a : node;
@@ -188,6 +138,7 @@ function getChildNode(node, key) {
188
138
  root: node.root,
189
139
  parent: node,
190
140
  key,
141
+ lazy: true,
191
142
  };
192
143
  if (!node.children) {
193
144
  node.children = new Map();
@@ -478,6 +429,25 @@ function endBatch(force) {
478
429
  }
479
430
  }
480
431
 
432
+ function createObservable(value, makePrimitive, createObject, createPrimitive) {
433
+ const valueIsPromise = isPromise(value);
434
+ const root = {
435
+ _: value,
436
+ };
437
+ const node = {
438
+ root,
439
+ lazy: true,
440
+ };
441
+ const prim = makePrimitive || isActualPrimitive(value);
442
+ const obs = prim
443
+ ? new createPrimitive(node)
444
+ : createObject(node);
445
+ if (valueIsPromise) {
446
+ extractPromise(node, value);
447
+ }
448
+ return obs;
449
+ }
450
+
481
451
  function onChange(node, callback, options = {}) {
482
452
  const { initial, immediate, noArgs } = options;
483
453
  const { trackingType } = options;
@@ -516,6 +486,45 @@ function onChange(node, callback, options = {}) {
516
486
  return () => listeners.delete(listener);
517
487
  }
518
488
 
489
+ let trackCount = 0;
490
+ const trackingQueue = [];
491
+ const tracking = {
492
+ current: undefined,
493
+ };
494
+ function beginTracking() {
495
+ // Keep a copy of the previous tracking context so it can be restored
496
+ // when this context is complete
497
+ trackingQueue.push(tracking.current);
498
+ trackCount++;
499
+ tracking.current = {};
500
+ }
501
+ function endTracking() {
502
+ // Restore the previous tracking context
503
+ trackCount--;
504
+ if (trackCount < 0) {
505
+ trackCount = 0;
506
+ }
507
+ tracking.current = trackingQueue.pop();
508
+ }
509
+ function updateTracking(node, track) {
510
+ if (trackCount) {
511
+ const tracker = tracking.current;
512
+ if (tracker) {
513
+ if (!tracker.nodes) {
514
+ tracker.nodes = new Map();
515
+ }
516
+ const existing = tracker.nodes.get(node);
517
+ if (existing) {
518
+ existing.track = existing.track || track;
519
+ existing.num++;
520
+ }
521
+ else {
522
+ tracker.nodes.set(node, { node, track, num: 1 });
523
+ }
524
+ }
525
+ }
526
+ }
527
+
519
528
  const ArrayModifiers = new Set([
520
529
  'copyWithin',
521
530
  'fill',
@@ -678,7 +687,6 @@ function updateNodes(parent, obj, prevValue) {
678
687
  const prev = isMap ? prevValue === null || prevValue === void 0 ? void 0 : prevValue.get(key) : prevValue === null || prevValue === void 0 ? void 0 : prevValue[key];
679
688
  let isDiff = value !== prev;
680
689
  if (isDiff) {
681
- extractFunctionOrComputed(parent, obj, key, value);
682
690
  const id = idField && value
683
691
  ? isIdFieldFunction
684
692
  ? idField(value)
@@ -760,7 +768,7 @@ function getProxy(node, p) {
760
768
  if (p !== undefined)
761
769
  node = getChildNode(node, p);
762
770
  // Create a proxy if not already cached and return it
763
- return node.proxy || (node.proxy = new Proxy(node, proxyHandler));
771
+ return (node.proxy || (node.proxy = new Proxy(node, proxyHandler)));
764
772
  }
765
773
  const proxyHandler = {
766
774
  get(node, p, receiver) {
@@ -773,12 +781,13 @@ const proxyHandler = {
773
781
  if (p === symbolGetNode) {
774
782
  return node;
775
783
  }
784
+ const value = peek(node);
776
785
  // If this node is linked to another observable then forward to the target's handler.
777
786
  // The exception is onChange because it needs to listen to this node for changes.
787
+ // This needs to be below peek because it activates there.
778
788
  if (node.linkedToNode && p !== 'onChange') {
779
789
  return proxyHandler.get(node.linkedToNode, p, receiver);
780
790
  }
781
- const value = peek(node);
782
791
  if (value instanceof Map || value instanceof WeakMap || value instanceof Set || value instanceof WeakSet) {
783
792
  const ret = handlerMapSet(node, p, value);
784
793
  if (ret !== undefined) {
@@ -817,6 +826,20 @@ const proxyHandler = {
817
826
  if (property) {
818
827
  return property.get(node);
819
828
  }
829
+ // TODOV3 Remove this
830
+ const isValuePrimitive = isPrimitive(value);
831
+ // If accessing a key that doesn't already exist, and this node has been activated with extra keys
832
+ // then return the values that were set. This is used by enableLegendStateReact for example.
833
+ if (value === undefined || value === null || isValuePrimitive) {
834
+ if (extraPrimitiveProps.size && (node.isActivatedPrimitive || extraPrimitiveActivators.has(p))) {
835
+ node.isActivatedPrimitive = true;
836
+ const vPrim = extraPrimitiveProps.get(p);
837
+ if (vPrim !== undefined) {
838
+ return isFunction(vPrim) ? vPrim(getProxy(node)) : vPrim;
839
+ }
840
+ }
841
+ }
842
+ // /TODOV3 Remove this
820
843
  const vProp = value === null || value === void 0 ? void 0 : value[p];
821
844
  if (isObject(value) && value[symbolOpaque]) {
822
845
  return vProp;
@@ -876,6 +899,9 @@ const proxyHandler = {
876
899
  if (fnOrComputed) {
877
900
  return fnOrComputed;
878
901
  }
902
+ if (p === 'state' && node.state) {
903
+ return node.state;
904
+ }
879
905
  // Return an observable proxy to the property
880
906
  return getProxy(node, p);
881
907
  },
@@ -986,7 +1012,7 @@ function setKey(node, key, newValue, level) {
986
1012
  if (savedValue !== prevValue) {
987
1013
  updateNodesAndNotify(node, savedValue, prevValue, childNode, isPrim, isRoot, level);
988
1014
  }
989
- extractFunctionOrComputed(node, parentValue, key, newValue);
1015
+ extractFunctionOrComputed(node, parentValue, key, savedValue);
990
1016
  return isFunc ? savedValue : isRoot ? getProxy(node) : getProxy(node, key);
991
1017
  }
992
1018
  function assign(node, value) {
@@ -1114,16 +1140,20 @@ function updateNodesAndNotify(node, newValue, prevValue, childNode, isPrim, isRo
1114
1140
  endBatch();
1115
1141
  }
1116
1142
  function extractPromise(node, value) {
1117
- value.status = 'pending';
1143
+ if (!node.state) {
1144
+ node.state = createObservable({
1145
+ isLoaded: false,
1146
+ }, false, getProxy);
1147
+ }
1118
1148
  value
1119
1149
  .then((value) => {
1120
1150
  set(node, value);
1151
+ node.state.isLoaded.set(true);
1121
1152
  })
1122
1153
  .catch((error) => {
1123
- set(node, { error, status: 'rejected' });
1154
+ node.state.error.set(error);
1124
1155
  });
1125
1156
  }
1126
- const __devExtractFunctionsAndComputedsNodes = process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test' ? new Set() : undefined;
1127
1157
  function extractFunctionOrComputed(node, obj, k, v) {
1128
1158
  if (isPromise(v)) {
1129
1159
  extractPromise(getChildNode(node, k), v);
@@ -1142,21 +1172,26 @@ function extractFunctionOrComputed(node, obj, k, v) {
1142
1172
  }
1143
1173
  }
1144
1174
  }
1145
- function extractFunctionsAndComputeds(node, obj) {
1146
- if ((process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') &&
1147
- typeof __devExtractFunctionsAndComputedsNodes !== 'undefined') {
1148
- if (__devExtractFunctionsAndComputedsNodes.has(obj)) {
1149
- console.error('[legend-state] Circular reference detected in object. You may want to use opaqueObject to stop traversing child nodes.', obj);
1150
- return false;
1151
- }
1152
- __devExtractFunctionsAndComputedsNodes.add(obj);
1153
- }
1154
- for (const k in obj) {
1155
- const v = obj[k];
1156
- if (v && extractFunctionOrComputed(node, obj, k, v) && !v[symbolOpaque]) {
1157
- extractFunctionsAndComputeds(getChildNode(node, k), v);
1175
+ function get(node, options) {
1176
+ const track = options ? (isObject(options) ? options.shallow : options) : undefined;
1177
+ // Track by default
1178
+ updateTracking(node, track);
1179
+ return peek(node);
1180
+ }
1181
+ function peek(node) {
1182
+ const value = getNodeValue(node);
1183
+ // If node is not yet lazily computed go do that
1184
+ if (node.lazy) {
1185
+ delete node.lazy;
1186
+ for (const key in value) {
1187
+ if (hasOwnProperty.call(value, key)) {
1188
+ extractFunctionOrComputed(node, value, key, value[key]);
1189
+ }
1158
1190
  }
1159
1191
  }
1192
+ // Check if computed needs to activate
1193
+ checkActivate(node);
1194
+ return value;
1160
1195
  }
1161
1196
 
1162
1197
  function isObservable(obs) {
@@ -1226,11 +1261,14 @@ function setAtPath(obj, path, pathTypes, value, fullObj, restore) {
1226
1261
  }
1227
1262
  return obj;
1228
1263
  }
1229
- function setInObservableAtPath(obs, path, value, mode) {
1264
+ function setInObservableAtPath(obs, path, pathTypes, value, mode) {
1230
1265
  let o = obs;
1231
1266
  let v = value;
1232
1267
  for (let i = 0; i < path.length; i++) {
1233
1268
  const p = path[i];
1269
+ if (!o.peek()[p] && pathTypes[i] === 'array') {
1270
+ o[p].set([]);
1271
+ }
1234
1272
  o = o[p];
1235
1273
  v = v[p];
1236
1274
  }
@@ -1295,7 +1333,7 @@ function _mergeIntoObservable(target, source) {
1295
1333
  }
1296
1334
  return target;
1297
1335
  }
1298
- function constructObjectWithPath(path, value, pathTypes) {
1336
+ function constructObjectWithPath(path, pathTypes, value) {
1299
1337
  let out;
1300
1338
  if (path.length > 0) {
1301
1339
  let o = (out = {});
@@ -1310,11 +1348,11 @@ function constructObjectWithPath(path, value, pathTypes) {
1310
1348
  }
1311
1349
  return out;
1312
1350
  }
1313
- function deconstructObjectWithPath(path, value) {
1351
+ function deconstructObjectWithPath(path, pathTypes, value) {
1314
1352
  let o = value;
1315
1353
  for (let i = 0; i < path.length; i++) {
1316
1354
  const p = path[i];
1317
- o = o[p];
1355
+ o = o ? o[p] : pathTypes[i] === 'array' ? [] : {};
1318
1356
  }
1319
1357
  return o;
1320
1358
  }
@@ -1367,36 +1405,11 @@ ObservablePrimitiveClass.prototype.delete = function () {
1367
1405
  return this;
1368
1406
  };
1369
1407
 
1370
- function createObservable(value, makePrimitive) {
1371
- const valueIsPromise = isPromise(value);
1372
- const root = {
1373
- _: value,
1374
- };
1375
- const node = {
1376
- root,
1377
- };
1378
- const prim = makePrimitive || isActualPrimitive(value);
1379
- const obs = prim
1380
- ? new ObservablePrimitiveClass(node)
1381
- : getProxy(node);
1382
- if (valueIsPromise) {
1383
- extractPromise(node, value);
1384
- }
1385
- else if (!prim) {
1386
- if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
1387
- __devExtractFunctionsAndComputedsNodes.clear();
1388
- }
1389
- if (value) {
1390
- extractFunctionsAndComputeds(node, value);
1391
- }
1392
- }
1393
- return obs;
1394
- }
1395
1408
  function observable(value) {
1396
- return createObservable(value);
1409
+ return createObservable(value, false, getProxy, ObservablePrimitiveClass);
1397
1410
  }
1398
1411
  function observablePrimitive(value) {
1399
- return createObservable(value, /*makePrimitive*/ true);
1412
+ return createObservable(value, true, getProxy, ObservablePrimitiveClass);
1400
1413
  }
1401
1414
 
1402
1415
  function setupTracking(nodes, update, noArgs, immediate) {
@@ -1416,7 +1429,7 @@ function setupTracking(nodes, update, noArgs, immediate) {
1416
1429
  };
1417
1430
  }
1418
1431
 
1419
- function trackSelector(selector, update, observeEvent, observeOptions, createResubscribe, inRender) {
1432
+ function trackSelector(selector, update, observeEvent, observeOptions, createResubscribe) {
1420
1433
  var _a;
1421
1434
  let nodes;
1422
1435
  let value;
@@ -1424,23 +1437,21 @@ function trackSelector(selector, update, observeEvent, observeOptions, createRes
1424
1437
  let tracker;
1425
1438
  let resubscribe;
1426
1439
  let updateFn = update;
1427
- let noArgs = true;
1428
1440
  if (isObservable(selector)) {
1429
1441
  value = selector.peek();
1430
- dispose = selector.onChange(update, { noArgs: true });
1431
- resubscribe = createResubscribe ? selector.onChange(update, { noArgs: true }) : undefined;
1442
+ dispose = selector.onChange(update);
1443
+ resubscribe = createResubscribe ? selector.onChange(update) : undefined;
1432
1444
  }
1433
1445
  else {
1434
1446
  // Compute the selector inside a tracking context
1435
- beginTracking(inRender);
1436
- value = selector ? computeSelector(selector, observeEvent, observeOptions === null || observeOptions === void 0 ? void 0 : observeOptions.retainObservable) : selector;
1447
+ beginTracking();
1448
+ value = selector ? computeSelector(selector, observeEvent, observeOptions === null || observeOptions === void 0 ? void 0 : observeOptions.fromComputed) : selector;
1437
1449
  tracker = tracking.current;
1438
1450
  nodes = tracker.nodes;
1439
- endTracking(inRender);
1451
+ endTracking();
1440
1452
  if ((process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') && tracker && nodes) {
1441
1453
  (_a = tracker.traceListeners) === null || _a === void 0 ? void 0 : _a.call(tracker, nodes);
1442
1454
  if (tracker.traceUpdates) {
1443
- noArgs = false;
1444
1455
  updateFn = tracker.traceUpdates(update);
1445
1456
  }
1446
1457
  // Clear tracing so it doesn't leak to other components
@@ -1452,8 +1463,8 @@ function trackSelector(selector, update, observeEvent, observeOptions, createRes
1452
1463
  // Do tracing if it was requested
1453
1464
  // useSyncExternalStore doesn't subscribe until after the component mount.
1454
1465
  // We want to subscribe immediately so we don't miss any updates
1455
- dispose = setupTracking(nodes, updateFn, noArgs, observeOptions === null || observeOptions === void 0 ? void 0 : observeOptions.immediate);
1456
- resubscribe = createResubscribe ? () => setupTracking(nodes, updateFn, noArgs) : undefined;
1466
+ dispose = setupTracking(nodes, updateFn, false, observeOptions === null || observeOptions === void 0 ? void 0 : observeOptions.immediate);
1467
+ resubscribe = createResubscribe ? () => setupTracking(nodes, updateFn) : undefined;
1457
1468
  }
1458
1469
  return { value, dispose, resubscribe };
1459
1470
  }
@@ -1487,15 +1498,17 @@ function observe(selectorOrRun, reactionOrOptions, options) {
1487
1498
  e.onCleanupReaction();
1488
1499
  e.onCleanupReaction = undefined;
1489
1500
  }
1501
+ endBatch();
1490
1502
  // Call the reaction if there is one and the value changed
1491
- if (reaction && (e.num > 0 || !isEvent(selectorOrRun)) && e.previous !== e.value) {
1503
+ if (reaction &&
1504
+ (e.num > 0 || !isEvent(selectorOrRun)) &&
1505
+ (e.previous !== e.value || (options === null || options === void 0 ? void 0 : options.fromComputed))) {
1492
1506
  reaction(e);
1493
1507
  }
1494
1508
  // Update the previous value
1495
1509
  e.previous = e.value;
1496
1510
  // Increment the counter
1497
1511
  e.num++;
1498
- endBatch();
1499
1512
  };
1500
1513
  update();
1501
1514
  // Return function calling dispose because dispose may be changed in update()
@@ -1582,7 +1595,7 @@ function computed(compute, set$1) {
1582
1595
  else {
1583
1596
  setInner(value);
1584
1597
  }
1585
- }, { immediate: true, retainObservable: true });
1598
+ }, { immediate: true, fromComputed: true });
1586
1599
  };
1587
1600
  if (set$1) {
1588
1601
  node.root.set = (value) => {
@@ -1672,20 +1685,27 @@ function proxy(get, set) {
1672
1685
  }
1673
1686
 
1674
1687
  function _when(predicate, effect, checkReady) {
1688
+ // If predicate is a regular Promise skip all the observable stuff
1689
+ if (isPromise(predicate)) {
1690
+ return effect ? predicate.then(effect) : predicate;
1691
+ }
1675
1692
  let value;
1676
1693
  // Create a wrapping fn that calls the effect if predicate returns true
1677
1694
  function run(e) {
1678
1695
  const ret = computeSelector(predicate);
1679
1696
  if (!isPromise(ret) && (checkReady ? isObservableValueReady(ret) : ret)) {
1680
1697
  value = ret;
1681
- // If value is truthy then run the effect
1682
- effect === null || effect === void 0 ? void 0 : effect(ret);
1683
- // Set cancel so that observe does not track
1698
+ // Set cancel so that observe does not track anymore
1684
1699
  e.cancel = true;
1685
1700
  }
1701
+ return value;
1702
+ }
1703
+ function doEffect() {
1704
+ // If value is truthy then run the effect
1705
+ effect === null || effect === void 0 ? void 0 : effect(value);
1686
1706
  }
1687
1707
  // Run in an observe
1688
- observe(run);
1708
+ observe(run, doEffect);
1689
1709
  // If first run resulted in a truthy value just return it.
1690
1710
  // It will have set e.cancel so no need to dispose
1691
1711
  if (isPromise(value)) {
@@ -1725,6 +1745,7 @@ const internal = {
1725
1745
  getNode,
1726
1746
  getProxy,
1727
1747
  globalState,
1748
+ observableFns,
1728
1749
  optimized,
1729
1750
  peek,
1730
1751
  set,
@@ -1746,10 +1767,13 @@ exports.deconstructObjectWithPath = deconstructObjectWithPath;
1746
1767
  exports.endBatch = endBatch;
1747
1768
  exports.endTracking = endTracking;
1748
1769
  exports.event = event;
1770
+ exports.extraPrimitiveActivators = extraPrimitiveActivators;
1771
+ exports.extraPrimitiveProps = extraPrimitiveProps;
1749
1772
  exports.findIDKey = findIDKey;
1750
1773
  exports.getNode = getNode;
1751
1774
  exports.getNodeValue = getNodeValue;
1752
1775
  exports.getObservableIndex = getObservableIndex;
1776
+ exports.hasOwnProperty = hasOwnProperty;
1753
1777
  exports.internal = internal;
1754
1778
  exports.isArray = isArray;
1755
1779
  exports.isBoolean = isBoolean;