@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.mjs CHANGED
@@ -48,55 +48,14 @@ function isChildNodeValue(node) {
48
48
  return !!node.parent;
49
49
  }
50
50
 
51
- let trackCount = 0;
52
- const trackingQueue = [];
53
- const tracking = {
54
- current: undefined,
55
- inRender: false,
56
- };
57
- function beginTracking(inRender) {
58
- // Keep a copy of the previous tracking context so it can be restored
59
- // when this context is complete
60
- trackingQueue.push(tracking.current);
61
- trackCount++;
62
- tracking.inRender = inRender;
63
- tracking.current = {};
64
- }
65
- function endTracking(fromRender) {
66
- // Restore the previous tracking context
67
- trackCount--;
68
- if (trackCount < 0) {
69
- trackCount = 0;
70
- }
71
- if (fromRender) {
72
- tracking.inRender = false;
73
- }
74
- tracking.current = trackingQueue.pop();
75
- }
76
- function updateTracking(node, track) {
77
- if (trackCount) {
78
- const tracker = tracking.current;
79
- if (tracker) {
80
- if (!tracker.nodes) {
81
- tracker.nodes = new Map();
82
- }
83
- const existing = tracker.nodes.get(node);
84
- if (existing) {
85
- existing.track = existing.track || track;
86
- existing.num++;
87
- }
88
- else {
89
- tracker.nodes.set(node, { node, track, num: 1 });
90
- }
91
- }
92
- }
93
- }
94
-
95
51
  const symbolToPrimitive = Symbol.toPrimitive;
96
52
  const symbolGetNode = Symbol('getNode');
97
53
  const symbolDelete = /* @__PURE__ */ Symbol('delete');
98
54
  const symbolOpaque = Symbol('opaque');
99
55
  const optimized = Symbol('optimized');
56
+ // TODOV3 Remove these
57
+ const extraPrimitiveActivators = new Map();
58
+ const extraPrimitiveProps = new Map();
100
59
  const globalState = {
101
60
  isLoadingLocal: false,
102
61
  isLoadingRemote: false,
@@ -114,15 +73,6 @@ function checkActivate(node) {
114
73
  function getNode(obs) {
115
74
  return obs && obs[symbolGetNode];
116
75
  }
117
- function get(node, track) {
118
- // Track by default
119
- updateTracking(node, track);
120
- return peek(node);
121
- }
122
- function peek(node) {
123
- checkActivate(node);
124
- return getNodeValue(node);
125
- }
126
76
  function setNodeValue(node, newValue) {
127
77
  var _a;
128
78
  const parentNode = (_a = node.parent) !== null && _a !== void 0 ? _a : node;
@@ -186,6 +136,7 @@ function getChildNode(node, key) {
186
136
  root: node.root,
187
137
  parent: node,
188
138
  key,
139
+ lazy: true,
189
140
  };
190
141
  if (!node.children) {
191
142
  node.children = new Map();
@@ -476,6 +427,25 @@ function endBatch(force) {
476
427
  }
477
428
  }
478
429
 
430
+ function createObservable(value, makePrimitive, createObject, createPrimitive) {
431
+ const valueIsPromise = isPromise(value);
432
+ const root = {
433
+ _: value,
434
+ };
435
+ const node = {
436
+ root,
437
+ lazy: true,
438
+ };
439
+ const prim = makePrimitive || isActualPrimitive(value);
440
+ const obs = prim
441
+ ? new createPrimitive(node)
442
+ : createObject(node);
443
+ if (valueIsPromise) {
444
+ extractPromise(node, value);
445
+ }
446
+ return obs;
447
+ }
448
+
479
449
  function onChange(node, callback, options = {}) {
480
450
  const { initial, immediate, noArgs } = options;
481
451
  const { trackingType } = options;
@@ -514,6 +484,45 @@ function onChange(node, callback, options = {}) {
514
484
  return () => listeners.delete(listener);
515
485
  }
516
486
 
487
+ let trackCount = 0;
488
+ const trackingQueue = [];
489
+ const tracking = {
490
+ current: undefined,
491
+ };
492
+ function beginTracking() {
493
+ // Keep a copy of the previous tracking context so it can be restored
494
+ // when this context is complete
495
+ trackingQueue.push(tracking.current);
496
+ trackCount++;
497
+ tracking.current = {};
498
+ }
499
+ function endTracking() {
500
+ // Restore the previous tracking context
501
+ trackCount--;
502
+ if (trackCount < 0) {
503
+ trackCount = 0;
504
+ }
505
+ tracking.current = trackingQueue.pop();
506
+ }
507
+ function updateTracking(node, track) {
508
+ if (trackCount) {
509
+ const tracker = tracking.current;
510
+ if (tracker) {
511
+ if (!tracker.nodes) {
512
+ tracker.nodes = new Map();
513
+ }
514
+ const existing = tracker.nodes.get(node);
515
+ if (existing) {
516
+ existing.track = existing.track || track;
517
+ existing.num++;
518
+ }
519
+ else {
520
+ tracker.nodes.set(node, { node, track, num: 1 });
521
+ }
522
+ }
523
+ }
524
+ }
525
+
517
526
  const ArrayModifiers = new Set([
518
527
  'copyWithin',
519
528
  'fill',
@@ -676,7 +685,6 @@ function updateNodes(parent, obj, prevValue) {
676
685
  const prev = isMap ? prevValue === null || prevValue === void 0 ? void 0 : prevValue.get(key) : prevValue === null || prevValue === void 0 ? void 0 : prevValue[key];
677
686
  let isDiff = value !== prev;
678
687
  if (isDiff) {
679
- extractFunctionOrComputed(parent, obj, key, value);
680
688
  const id = idField && value
681
689
  ? isIdFieldFunction
682
690
  ? idField(value)
@@ -758,7 +766,7 @@ function getProxy(node, p) {
758
766
  if (p !== undefined)
759
767
  node = getChildNode(node, p);
760
768
  // Create a proxy if not already cached and return it
761
- return node.proxy || (node.proxy = new Proxy(node, proxyHandler));
769
+ return (node.proxy || (node.proxy = new Proxy(node, proxyHandler)));
762
770
  }
763
771
  const proxyHandler = {
764
772
  get(node, p, receiver) {
@@ -771,12 +779,13 @@ const proxyHandler = {
771
779
  if (p === symbolGetNode) {
772
780
  return node;
773
781
  }
782
+ const value = peek(node);
774
783
  // If this node is linked to another observable then forward to the target's handler.
775
784
  // The exception is onChange because it needs to listen to this node for changes.
785
+ // This needs to be below peek because it activates there.
776
786
  if (node.linkedToNode && p !== 'onChange') {
777
787
  return proxyHandler.get(node.linkedToNode, p, receiver);
778
788
  }
779
- const value = peek(node);
780
789
  if (value instanceof Map || value instanceof WeakMap || value instanceof Set || value instanceof WeakSet) {
781
790
  const ret = handlerMapSet(node, p, value);
782
791
  if (ret !== undefined) {
@@ -815,6 +824,20 @@ const proxyHandler = {
815
824
  if (property) {
816
825
  return property.get(node);
817
826
  }
827
+ // TODOV3 Remove this
828
+ const isValuePrimitive = isPrimitive(value);
829
+ // If accessing a key that doesn't already exist, and this node has been activated with extra keys
830
+ // then return the values that were set. This is used by enableLegendStateReact for example.
831
+ if (value === undefined || value === null || isValuePrimitive) {
832
+ if (extraPrimitiveProps.size && (node.isActivatedPrimitive || extraPrimitiveActivators.has(p))) {
833
+ node.isActivatedPrimitive = true;
834
+ const vPrim = extraPrimitiveProps.get(p);
835
+ if (vPrim !== undefined) {
836
+ return isFunction(vPrim) ? vPrim(getProxy(node)) : vPrim;
837
+ }
838
+ }
839
+ }
840
+ // /TODOV3 Remove this
818
841
  const vProp = value === null || value === void 0 ? void 0 : value[p];
819
842
  if (isObject(value) && value[symbolOpaque]) {
820
843
  return vProp;
@@ -874,6 +897,9 @@ const proxyHandler = {
874
897
  if (fnOrComputed) {
875
898
  return fnOrComputed;
876
899
  }
900
+ if (p === 'state' && node.state) {
901
+ return node.state;
902
+ }
877
903
  // Return an observable proxy to the property
878
904
  return getProxy(node, p);
879
905
  },
@@ -984,7 +1010,7 @@ function setKey(node, key, newValue, level) {
984
1010
  if (savedValue !== prevValue) {
985
1011
  updateNodesAndNotify(node, savedValue, prevValue, childNode, isPrim, isRoot, level);
986
1012
  }
987
- extractFunctionOrComputed(node, parentValue, key, newValue);
1013
+ extractFunctionOrComputed(node, parentValue, key, savedValue);
988
1014
  return isFunc ? savedValue : isRoot ? getProxy(node) : getProxy(node, key);
989
1015
  }
990
1016
  function assign(node, value) {
@@ -1112,16 +1138,20 @@ function updateNodesAndNotify(node, newValue, prevValue, childNode, isPrim, isRo
1112
1138
  endBatch();
1113
1139
  }
1114
1140
  function extractPromise(node, value) {
1115
- value.status = 'pending';
1141
+ if (!node.state) {
1142
+ node.state = createObservable({
1143
+ isLoaded: false,
1144
+ }, false, getProxy);
1145
+ }
1116
1146
  value
1117
1147
  .then((value) => {
1118
1148
  set(node, value);
1149
+ node.state.isLoaded.set(true);
1119
1150
  })
1120
1151
  .catch((error) => {
1121
- set(node, { error, status: 'rejected' });
1152
+ node.state.error.set(error);
1122
1153
  });
1123
1154
  }
1124
- const __devExtractFunctionsAndComputedsNodes = process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test' ? new Set() : undefined;
1125
1155
  function extractFunctionOrComputed(node, obj, k, v) {
1126
1156
  if (isPromise(v)) {
1127
1157
  extractPromise(getChildNode(node, k), v);
@@ -1140,21 +1170,26 @@ function extractFunctionOrComputed(node, obj, k, v) {
1140
1170
  }
1141
1171
  }
1142
1172
  }
1143
- function extractFunctionsAndComputeds(node, obj) {
1144
- if ((process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') &&
1145
- typeof __devExtractFunctionsAndComputedsNodes !== 'undefined') {
1146
- if (__devExtractFunctionsAndComputedsNodes.has(obj)) {
1147
- console.error('[legend-state] Circular reference detected in object. You may want to use opaqueObject to stop traversing child nodes.', obj);
1148
- return false;
1149
- }
1150
- __devExtractFunctionsAndComputedsNodes.add(obj);
1151
- }
1152
- for (const k in obj) {
1153
- const v = obj[k];
1154
- if (v && extractFunctionOrComputed(node, obj, k, v) && !v[symbolOpaque]) {
1155
- extractFunctionsAndComputeds(getChildNode(node, k), v);
1173
+ function get(node, options) {
1174
+ const track = options ? (isObject(options) ? options.shallow : options) : undefined;
1175
+ // Track by default
1176
+ updateTracking(node, track);
1177
+ return peek(node);
1178
+ }
1179
+ function peek(node) {
1180
+ const value = getNodeValue(node);
1181
+ // If node is not yet lazily computed go do that
1182
+ if (node.lazy) {
1183
+ delete node.lazy;
1184
+ for (const key in value) {
1185
+ if (hasOwnProperty.call(value, key)) {
1186
+ extractFunctionOrComputed(node, value, key, value[key]);
1187
+ }
1156
1188
  }
1157
1189
  }
1190
+ // Check if computed needs to activate
1191
+ checkActivate(node);
1192
+ return value;
1158
1193
  }
1159
1194
 
1160
1195
  function isObservable(obs) {
@@ -1224,11 +1259,14 @@ function setAtPath(obj, path, pathTypes, value, fullObj, restore) {
1224
1259
  }
1225
1260
  return obj;
1226
1261
  }
1227
- function setInObservableAtPath(obs, path, value, mode) {
1262
+ function setInObservableAtPath(obs, path, pathTypes, value, mode) {
1228
1263
  let o = obs;
1229
1264
  let v = value;
1230
1265
  for (let i = 0; i < path.length; i++) {
1231
1266
  const p = path[i];
1267
+ if (!o.peek()[p] && pathTypes[i] === 'array') {
1268
+ o[p].set([]);
1269
+ }
1232
1270
  o = o[p];
1233
1271
  v = v[p];
1234
1272
  }
@@ -1293,7 +1331,7 @@ function _mergeIntoObservable(target, source) {
1293
1331
  }
1294
1332
  return target;
1295
1333
  }
1296
- function constructObjectWithPath(path, value, pathTypes) {
1334
+ function constructObjectWithPath(path, pathTypes, value) {
1297
1335
  let out;
1298
1336
  if (path.length > 0) {
1299
1337
  let o = (out = {});
@@ -1308,11 +1346,11 @@ function constructObjectWithPath(path, value, pathTypes) {
1308
1346
  }
1309
1347
  return out;
1310
1348
  }
1311
- function deconstructObjectWithPath(path, value) {
1349
+ function deconstructObjectWithPath(path, pathTypes, value) {
1312
1350
  let o = value;
1313
1351
  for (let i = 0; i < path.length; i++) {
1314
1352
  const p = path[i];
1315
- o = o[p];
1353
+ o = o ? o[p] : pathTypes[i] === 'array' ? [] : {};
1316
1354
  }
1317
1355
  return o;
1318
1356
  }
@@ -1365,36 +1403,11 @@ ObservablePrimitiveClass.prototype.delete = function () {
1365
1403
  return this;
1366
1404
  };
1367
1405
 
1368
- function createObservable(value, makePrimitive) {
1369
- const valueIsPromise = isPromise(value);
1370
- const root = {
1371
- _: value,
1372
- };
1373
- const node = {
1374
- root,
1375
- };
1376
- const prim = makePrimitive || isActualPrimitive(value);
1377
- const obs = prim
1378
- ? new ObservablePrimitiveClass(node)
1379
- : getProxy(node);
1380
- if (valueIsPromise) {
1381
- extractPromise(node, value);
1382
- }
1383
- else if (!prim) {
1384
- if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
1385
- __devExtractFunctionsAndComputedsNodes.clear();
1386
- }
1387
- if (value) {
1388
- extractFunctionsAndComputeds(node, value);
1389
- }
1390
- }
1391
- return obs;
1392
- }
1393
1406
  function observable(value) {
1394
- return createObservable(value);
1407
+ return createObservable(value, false, getProxy, ObservablePrimitiveClass);
1395
1408
  }
1396
1409
  function observablePrimitive(value) {
1397
- return createObservable(value, /*makePrimitive*/ true);
1410
+ return createObservable(value, true, getProxy, ObservablePrimitiveClass);
1398
1411
  }
1399
1412
 
1400
1413
  function setupTracking(nodes, update, noArgs, immediate) {
@@ -1414,7 +1427,7 @@ function setupTracking(nodes, update, noArgs, immediate) {
1414
1427
  };
1415
1428
  }
1416
1429
 
1417
- function trackSelector(selector, update, observeEvent, observeOptions, createResubscribe, inRender) {
1430
+ function trackSelector(selector, update, observeEvent, observeOptions, createResubscribe) {
1418
1431
  var _a;
1419
1432
  let nodes;
1420
1433
  let value;
@@ -1422,23 +1435,21 @@ function trackSelector(selector, update, observeEvent, observeOptions, createRes
1422
1435
  let tracker;
1423
1436
  let resubscribe;
1424
1437
  let updateFn = update;
1425
- let noArgs = true;
1426
1438
  if (isObservable(selector)) {
1427
1439
  value = selector.peek();
1428
- dispose = selector.onChange(update, { noArgs: true });
1429
- resubscribe = createResubscribe ? selector.onChange(update, { noArgs: true }) : undefined;
1440
+ dispose = selector.onChange(update);
1441
+ resubscribe = createResubscribe ? selector.onChange(update) : undefined;
1430
1442
  }
1431
1443
  else {
1432
1444
  // Compute the selector inside a tracking context
1433
- beginTracking(inRender);
1434
- value = selector ? computeSelector(selector, observeEvent, observeOptions === null || observeOptions === void 0 ? void 0 : observeOptions.retainObservable) : selector;
1445
+ beginTracking();
1446
+ value = selector ? computeSelector(selector, observeEvent, observeOptions === null || observeOptions === void 0 ? void 0 : observeOptions.fromComputed) : selector;
1435
1447
  tracker = tracking.current;
1436
1448
  nodes = tracker.nodes;
1437
- endTracking(inRender);
1449
+ endTracking();
1438
1450
  if ((process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') && tracker && nodes) {
1439
1451
  (_a = tracker.traceListeners) === null || _a === void 0 ? void 0 : _a.call(tracker, nodes);
1440
1452
  if (tracker.traceUpdates) {
1441
- noArgs = false;
1442
1453
  updateFn = tracker.traceUpdates(update);
1443
1454
  }
1444
1455
  // Clear tracing so it doesn't leak to other components
@@ -1450,8 +1461,8 @@ function trackSelector(selector, update, observeEvent, observeOptions, createRes
1450
1461
  // Do tracing if it was requested
1451
1462
  // useSyncExternalStore doesn't subscribe until after the component mount.
1452
1463
  // We want to subscribe immediately so we don't miss any updates
1453
- dispose = setupTracking(nodes, updateFn, noArgs, observeOptions === null || observeOptions === void 0 ? void 0 : observeOptions.immediate);
1454
- resubscribe = createResubscribe ? () => setupTracking(nodes, updateFn, noArgs) : undefined;
1464
+ dispose = setupTracking(nodes, updateFn, false, observeOptions === null || observeOptions === void 0 ? void 0 : observeOptions.immediate);
1465
+ resubscribe = createResubscribe ? () => setupTracking(nodes, updateFn) : undefined;
1455
1466
  }
1456
1467
  return { value, dispose, resubscribe };
1457
1468
  }
@@ -1485,15 +1496,17 @@ function observe(selectorOrRun, reactionOrOptions, options) {
1485
1496
  e.onCleanupReaction();
1486
1497
  e.onCleanupReaction = undefined;
1487
1498
  }
1499
+ endBatch();
1488
1500
  // Call the reaction if there is one and the value changed
1489
- if (reaction && (e.num > 0 || !isEvent(selectorOrRun)) && e.previous !== e.value) {
1501
+ if (reaction &&
1502
+ (e.num > 0 || !isEvent(selectorOrRun)) &&
1503
+ (e.previous !== e.value || (options === null || options === void 0 ? void 0 : options.fromComputed))) {
1490
1504
  reaction(e);
1491
1505
  }
1492
1506
  // Update the previous value
1493
1507
  e.previous = e.value;
1494
1508
  // Increment the counter
1495
1509
  e.num++;
1496
- endBatch();
1497
1510
  };
1498
1511
  update();
1499
1512
  // Return function calling dispose because dispose may be changed in update()
@@ -1580,7 +1593,7 @@ function computed(compute, set$1) {
1580
1593
  else {
1581
1594
  setInner(value);
1582
1595
  }
1583
- }, { immediate: true, retainObservable: true });
1596
+ }, { immediate: true, fromComputed: true });
1584
1597
  };
1585
1598
  if (set$1) {
1586
1599
  node.root.set = (value) => {
@@ -1670,20 +1683,27 @@ function proxy(get, set) {
1670
1683
  }
1671
1684
 
1672
1685
  function _when(predicate, effect, checkReady) {
1686
+ // If predicate is a regular Promise skip all the observable stuff
1687
+ if (isPromise(predicate)) {
1688
+ return effect ? predicate.then(effect) : predicate;
1689
+ }
1673
1690
  let value;
1674
1691
  // Create a wrapping fn that calls the effect if predicate returns true
1675
1692
  function run(e) {
1676
1693
  const ret = computeSelector(predicate);
1677
1694
  if (!isPromise(ret) && (checkReady ? isObservableValueReady(ret) : ret)) {
1678
1695
  value = ret;
1679
- // If value is truthy then run the effect
1680
- effect === null || effect === void 0 ? void 0 : effect(ret);
1681
- // Set cancel so that observe does not track
1696
+ // Set cancel so that observe does not track anymore
1682
1697
  e.cancel = true;
1683
1698
  }
1699
+ return value;
1700
+ }
1701
+ function doEffect() {
1702
+ // If value is truthy then run the effect
1703
+ effect === null || effect === void 0 ? void 0 : effect(value);
1684
1704
  }
1685
1705
  // Run in an observe
1686
- observe(run);
1706
+ observe(run, doEffect);
1687
1707
  // If first run resulted in a truthy value just return it.
1688
1708
  // It will have set e.cancel so no need to dispose
1689
1709
  if (isPromise(value)) {
@@ -1723,6 +1743,7 @@ const internal = {
1723
1743
  getNode,
1724
1744
  getProxy,
1725
1745
  globalState,
1746
+ observableFns,
1726
1747
  optimized,
1727
1748
  peek,
1728
1749
  set,
@@ -1731,5 +1752,5 @@ const internal = {
1731
1752
  symbolDelete,
1732
1753
  };
1733
1754
 
1734
- export { ObservablePrimitiveClass, batch, beginBatch, beginTracking, checkActivate, computeSelector, computed, configureLegendState, constructObjectWithPath, deconstructObjectWithPath, endBatch, endTracking, event, findIDKey, getNode, getNodeValue, getObservableIndex, internal, isArray, isBoolean, isEmpty, isFunction, isObject, isObservable, isObservableValueReady, isPrimitive, isPromise, isString, isSymbol, lockObservable, mergeIntoObservable, observable, observablePrimitive, observe, opaqueObject, optimized, proxy, setAtPath, setInObservableAtPath, setSilently, setupTracking, symbolDelete, trackSelector, tracking, updateTracking, when, whenReady };
1755
+ export { ObservablePrimitiveClass, batch, beginBatch, beginTracking, checkActivate, computeSelector, computed, configureLegendState, constructObjectWithPath, deconstructObjectWithPath, endBatch, endTracking, event, extraPrimitiveActivators, extraPrimitiveProps, findIDKey, getNode, getNodeValue, getObservableIndex, hasOwnProperty, internal, isArray, isBoolean, isEmpty, isFunction, isObject, isObservable, isObservableValueReady, isPrimitive, isPromise, isString, isSymbol, lockObservable, mergeIntoObservable, observable, observablePrimitive, observe, opaqueObject, optimized, proxy, setAtPath, setInObservableAtPath, setSilently, setupTracking, symbolDelete, trackSelector, tracking, updateTracking, when, whenReady };
1735
1756
  //# sourceMappingURL=index.mjs.map