@legendapp/state 2.0.0-next.8 → 2.0.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.
Files changed (85) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/config/enableReactNativeComponents.js +15 -0
  3. package/config/enableReactNativeComponents.js.map +1 -1
  4. package/config/enableReactNativeComponents.mjs +16 -1
  5. package/config/enableReactNativeComponents.mjs.map +1 -1
  6. package/index.d.ts +3 -3
  7. package/index.js +84 -93
  8. package/index.js.map +1 -1
  9. package/index.mjs +84 -94
  10. package/index.mjs.map +1 -1
  11. package/package.json +21 -1
  12. package/persist-plugins/async-storage.d.ts +14 -0
  13. package/persist-plugins/async-storage.js +100 -0
  14. package/persist-plugins/async-storage.js.map +1 -0
  15. package/persist-plugins/async-storage.mjs +98 -0
  16. package/persist-plugins/async-storage.mjs.map +1 -0
  17. package/persist-plugins/fetch.d.ts +10 -0
  18. package/persist-plugins/fetch.js +22 -0
  19. package/persist-plugins/fetch.js.map +1 -0
  20. package/persist-plugins/fetch.mjs +20 -0
  21. package/persist-plugins/fetch.mjs.map +1 -0
  22. package/persist-plugins/firebase.d.ts +51 -0
  23. package/persist-plugins/firebase.js +694 -0
  24. package/persist-plugins/firebase.js.map +1 -0
  25. package/persist-plugins/firebase.mjs +692 -0
  26. package/persist-plugins/firebase.mjs.map +1 -0
  27. package/persist-plugins/indexeddb.d.ts +2 -3
  28. package/persist-plugins/indexeddb.js +1 -16
  29. package/persist-plugins/indexeddb.js.map +1 -1
  30. package/persist-plugins/indexeddb.mjs +1 -16
  31. package/persist-plugins/indexeddb.mjs.map +1 -1
  32. package/persist-plugins/local-storage.d.ts +1 -2
  33. package/persist-plugins/local-storage.js +1 -5
  34. package/persist-plugins/local-storage.js.map +1 -1
  35. package/persist-plugins/local-storage.mjs +1 -5
  36. package/persist-plugins/local-storage.mjs.map +1 -1
  37. package/persist-plugins/mmkv.d.ts +4 -4
  38. package/persist-plugins/mmkv.js +6 -4
  39. package/persist-plugins/mmkv.js.map +1 -1
  40. package/persist-plugins/mmkv.mjs +6 -4
  41. package/persist-plugins/mmkv.mjs.map +1 -1
  42. package/persist-plugins/query.d.ts +20 -0
  43. package/persist-plugins/query.js +89 -0
  44. package/persist-plugins/query.js.map +1 -0
  45. package/persist-plugins/query.mjs +87 -0
  46. package/persist-plugins/query.mjs.map +1 -0
  47. package/persist.js +186 -140
  48. package/persist.js.map +1 -1
  49. package/persist.mjs +187 -141
  50. package/persist.mjs.map +1 -1
  51. package/react-hooks/usePersistedObservable.d.ts +2 -2
  52. package/react-hooks/usePersistedObservable.js +1 -6
  53. package/react-hooks/usePersistedObservable.js.map +1 -1
  54. package/react-hooks/usePersistedObservable.mjs +1 -6
  55. package/react-hooks/usePersistedObservable.mjs.map +1 -1
  56. package/react.d.ts +1 -0
  57. package/react.js +84 -36
  58. package/react.js.map +1 -1
  59. package/react.mjs +84 -38
  60. package/react.mjs.map +1 -1
  61. package/src/ObservableObject.d.ts +3 -3
  62. package/src/globals.d.ts +1 -3
  63. package/src/is.d.ts +1 -0
  64. package/src/observable.d.ts +2 -2
  65. package/src/observableInterfaces.d.ts +86 -63
  66. package/src/observe.d.ts +1 -1
  67. package/src/persist/observablePersistRemoteFunctionsAdapter.d.ts +2 -0
  68. package/src/persist/persistObservable.d.ts +10 -13
  69. package/src/persist-plugins/async-storage.d.ts +14 -0
  70. package/src/persist-plugins/fetch.d.ts +10 -0
  71. package/src/persist-plugins/firebase.d.ts +51 -0
  72. package/src/persist-plugins/indexeddb.d.ts +2 -3
  73. package/src/persist-plugins/local-storage.d.ts +1 -2
  74. package/src/persist-plugins/mmkv.d.ts +4 -4
  75. package/src/persist-plugins/query.d.ts +20 -0
  76. package/src/react/For.d.ts +0 -1
  77. package/src/react/Reactive.d.ts +1 -1
  78. package/src/react/react-globals.d.ts +3 -0
  79. package/src/react/reactInterfaces.d.ts +8 -5
  80. package/src/react/useObservableState.d.ts +2 -0
  81. package/src/react/useSelector.d.ts +1 -1
  82. package/src/react/useWhen.d.ts +3 -0
  83. package/src/react-hooks/usePersistedObservable.d.ts +2 -2
  84. package/src/trackSelector.d.ts +2 -2
  85. package/src/tracking.d.ts +2 -3
package/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 1.11.1
2
+
3
+ - Removed the deprecation warning about reactive props since that might affect a lot of people and we can migrate that more slowly.
4
+
1
5
  ## 1.11.0
2
6
 
3
7
  - This version displays deprecation warnings to prepare for version 2.0 release which will remove the deprecated features. See https://legendapp.com/open-source/state/migrating/ for details on migration or disabling the warning.
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var react$1 = require('react');
3
4
  var react = require('@legendapp/state/react');
4
5
  var reactNative = require('react-native');
5
6
 
@@ -34,6 +35,20 @@ function enableReactNativeComponents() {
34
35
  defaultValue: false,
35
36
  },
36
37
  },
38
+ FlatList: {
39
+ data: {
40
+ selector: (propsOut, p) => {
41
+ const state = react$1.useRef(0);
42
+ // Increment renderNum whenever the array changes shallowly
43
+ const [renderNum, value] = react.useSelector(() => [state.current++, p.get(true)]);
44
+ // Set extraData to renderNum so that it will re-render when renderNum changes.
45
+ // This is necessary because the observable array is mutable so changes to it
46
+ // won't trigger re-renders by default.
47
+ propsOut.extraData = renderNum;
48
+ return value;
49
+ },
50
+ },
51
+ },
37
52
  },
38
53
  });
39
54
  }
@@ -1 +1 @@
1
- {"version":3,"file":"enableReactNativeComponents.js","sources":["../../../../src/config/enableReactNativeComponents.ts"],"sourcesContent":[null],"names":["configureReactive","ActivityIndicator","Button","FlatList","Image","Pressable","ScrollView","SectionList","Switch","Text","TextInput","TouchableWithoutFeedback","View"],"mappings":";;;;;SA4BgB,2BAA2B,GAAA;AACvC,IAAAA,uBAAiB,CAAC;AACd,QAAA,UAAU,EAAE;AACR,YAAA,iBAAiB,EAAEC,6BAAiB;AACpC,YAAA,MAAM,EAAEC,kBAAM;AACd,YAAA,QAAQ,EAAEC,oBAAQ;AAClB,YAAA,KAAK,EAAEC,iBAAK;AACZ,YAAA,SAAS,EAAEC,qBAAS;AACpB,YAAA,UAAU,EAAEC,sBAAU;AACtB,YAAA,WAAW,EAAEC,uBAAW;AACxB,YAAA,MAAM,EAAEC,kBAAM;AACd,YAAA,IAAI,EAAEC,gBAAI;AACV,YAAA,SAAS,EAAEC,qBAAS;AACpB,YAAA,wBAAwB,EAAEC,oCAAwB;AAClD,YAAA,IAAI,EAAEC,gBAAI;AACb,SAAA;AACD,QAAA,OAAO,EAAE;AACL,YAAA,SAAS,EAAE;AACP,gBAAA,KAAK,EAAE;AACH,oBAAA,OAAO,EAAE,UAAU;oBACnB,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,IAAI;AACnC,oBAAA,YAAY,EAAE,EAAE;AACnB,iBAAA;AACJ,aAAA;AACD,YAAA,MAAM,EAAE;AACJ,gBAAA,KAAK,EAAE;AACH,oBAAA,OAAO,EAAE,eAAe;AACxB,oBAAA,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC;AAClB,oBAAA,YAAY,EAAE,KAAK;AACtB,iBAAA;AACJ,aAAA;AACJ,SAAA;AACJ,KAAA,CAAC,CAAC;AACP;;;;"}
1
+ {"version":3,"file":"enableReactNativeComponents.js","sources":["../../../../src/config/enableReactNativeComponents.ts"],"sourcesContent":[null],"names":["configureReactive","ActivityIndicator","Button","FlatList","Image","Pressable","ScrollView","SectionList","Switch","Text","TextInput","TouchableWithoutFeedback","View","useRef","useSelector"],"mappings":";;;;;;SA8BgB,2BAA2B,GAAA;AACvC,IAAAA,uBAAiB,CAAC;AACd,QAAA,UAAU,EAAE;AACR,YAAA,iBAAiB,EAAEC,6BAAiB;AACpC,YAAA,MAAM,EAAEC,kBAAM;AACd,YAAA,QAAQ,EAAEC,oBAAQ;AAClB,YAAA,KAAK,EAAEC,iBAAK;AACZ,YAAA,SAAS,EAAEC,qBAAS;AACpB,YAAA,UAAU,EAAEC,sBAAU;AACtB,YAAA,WAAW,EAAEC,uBAAW;AACxB,YAAA,MAAM,EAAEC,kBAAM;AACd,YAAA,IAAI,EAAEC,gBAAI;AACV,YAAA,SAAS,EAAEC,qBAAS;AACpB,YAAA,wBAAwB,EAAEC,oCAAwB;AAClD,YAAA,IAAI,EAAEC,gBAAI;AACb,SAAA;AACD,QAAA,OAAO,EAAE;AACL,YAAA,SAAS,EAAE;AACP,gBAAA,KAAK,EAAE;AACH,oBAAA,OAAO,EAAE,UAAU;oBACnB,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,IAAI;AACnC,oBAAA,YAAY,EAAE,EAAE;AACnB,iBAAA;AACJ,aAAA;AACD,YAAA,MAAM,EAAE;AACJ,gBAAA,KAAK,EAAE;AACH,oBAAA,OAAO,EAAE,eAAe;AACxB,oBAAA,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC;AAClB,oBAAA,YAAY,EAAE,KAAK;AACtB,iBAAA;AACJ,aAAA;AACD,YAAA,QAAQ,EAAE;AACN,gBAAA,IAAI,EAAE;AACF,oBAAA,QAAQ,EAAE,CAAC,QAA6B,EAAE,CAAkB,KAAI;AAC5D,wBAAA,MAAM,KAAK,GAAGC,cAAM,CAAC,CAAC,CAAC,CAAC;;wBAExB,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,GAAGC,iBAAW,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;;;;AAK7E,wBAAA,QAAQ,CAAC,SAAS,GAAG,SAAS,CAAC;AAE/B,wBAAA,OAAO,KAAK,CAAC;qBAChB;AACJ,iBAAA;AACJ,aAAA;AACJ,SAAA;AACJ,KAAA,CAAC,CAAC;AACP;;;;"}
@@ -1,4 +1,5 @@
1
- import { configureReactive } from '@legendapp/state/react';
1
+ import { useRef } from 'react';
2
+ import { configureReactive, useSelector } from '@legendapp/state/react';
2
3
  import { ActivityIndicator, Button, FlatList, Image, Pressable, ScrollView, SectionList, Switch, Text, TextInput, TouchableWithoutFeedback, View } from 'react-native';
3
4
 
4
5
  function enableReactNativeComponents() {
@@ -32,6 +33,20 @@ function enableReactNativeComponents() {
32
33
  defaultValue: false,
33
34
  },
34
35
  },
36
+ FlatList: {
37
+ data: {
38
+ selector: (propsOut, p) => {
39
+ const state = useRef(0);
40
+ // Increment renderNum whenever the array changes shallowly
41
+ const [renderNum, value] = useSelector(() => [state.current++, p.get(true)]);
42
+ // Set extraData to renderNum so that it will re-render when renderNum changes.
43
+ // This is necessary because the observable array is mutable so changes to it
44
+ // won't trigger re-renders by default.
45
+ propsOut.extraData = renderNum;
46
+ return value;
47
+ },
48
+ },
49
+ },
35
50
  },
36
51
  });
37
52
  }
@@ -1 +1 @@
1
- {"version":3,"file":"enableReactNativeComponents.mjs","sources":["../../../../src/config/enableReactNativeComponents.ts"],"sourcesContent":[null],"names":[],"mappings":";;;SA4BgB,2BAA2B,GAAA;AACvC,IAAA,iBAAiB,CAAC;AACd,QAAA,UAAU,EAAE;AACR,YAAA,iBAAiB,EAAE,iBAAiB;AACpC,YAAA,MAAM,EAAE,MAAM;AACd,YAAA,QAAQ,EAAE,QAAQ;AAClB,YAAA,KAAK,EAAE,KAAK;AACZ,YAAA,SAAS,EAAE,SAAS;AACpB,YAAA,UAAU,EAAE,UAAU;AACtB,YAAA,WAAW,EAAE,WAAW;AACxB,YAAA,MAAM,EAAE,MAAM;AACd,YAAA,IAAI,EAAE,IAAI;AACV,YAAA,SAAS,EAAE,SAAS;AACpB,YAAA,wBAAwB,EAAE,wBAAwB;AAClD,YAAA,IAAI,EAAE,IAAI;AACb,SAAA;AACD,QAAA,OAAO,EAAE;AACL,YAAA,SAAS,EAAE;AACP,gBAAA,KAAK,EAAE;AACH,oBAAA,OAAO,EAAE,UAAU;oBACnB,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,IAAI;AACnC,oBAAA,YAAY,EAAE,EAAE;AACnB,iBAAA;AACJ,aAAA;AACD,YAAA,MAAM,EAAE;AACJ,gBAAA,KAAK,EAAE;AACH,oBAAA,OAAO,EAAE,eAAe;AACxB,oBAAA,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC;AAClB,oBAAA,YAAY,EAAE,KAAK;AACtB,iBAAA;AACJ,aAAA;AACJ,SAAA;AACJ,KAAA,CAAC,CAAC;AACP;;;;"}
1
+ {"version":3,"file":"enableReactNativeComponents.mjs","sources":["../../../../src/config/enableReactNativeComponents.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;SA8BgB,2BAA2B,GAAA;AACvC,IAAA,iBAAiB,CAAC;AACd,QAAA,UAAU,EAAE;AACR,YAAA,iBAAiB,EAAE,iBAAiB;AACpC,YAAA,MAAM,EAAE,MAAM;AACd,YAAA,QAAQ,EAAE,QAAQ;AAClB,YAAA,KAAK,EAAE,KAAK;AACZ,YAAA,SAAS,EAAE,SAAS;AACpB,YAAA,UAAU,EAAE,UAAU;AACtB,YAAA,WAAW,EAAE,WAAW;AACxB,YAAA,MAAM,EAAE,MAAM;AACd,YAAA,IAAI,EAAE,IAAI;AACV,YAAA,SAAS,EAAE,SAAS;AACpB,YAAA,wBAAwB,EAAE,wBAAwB;AAClD,YAAA,IAAI,EAAE,IAAI;AACb,SAAA;AACD,QAAA,OAAO,EAAE;AACL,YAAA,SAAS,EAAE;AACP,gBAAA,KAAK,EAAE;AACH,oBAAA,OAAO,EAAE,UAAU;oBACnB,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,IAAI;AACnC,oBAAA,YAAY,EAAE,EAAE;AACnB,iBAAA;AACJ,aAAA;AACD,YAAA,MAAM,EAAE;AACJ,gBAAA,KAAK,EAAE;AACH,oBAAA,OAAO,EAAE,eAAe;AACxB,oBAAA,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC;AAClB,oBAAA,YAAY,EAAE,KAAK;AACtB,iBAAA;AACJ,aAAA;AACD,YAAA,QAAQ,EAAE;AACN,gBAAA,IAAI,EAAE;AACF,oBAAA,QAAQ,EAAE,CAAC,QAA6B,EAAE,CAAkB,KAAI;AAC5D,wBAAA,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;;wBAExB,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;;;;AAK7E,wBAAA,QAAQ,CAAC,SAAS,GAAG,SAAS,CAAC;AAE/B,wBAAA,OAAO,KAAK,CAAC;qBAChB;AACJ,iBAAA;AACJ,aAAA;AACJ,SAAA;AACJ,KAAA,CAAC,CAAC;AACP;;;;"}
package/index.d.ts CHANGED
@@ -3,15 +3,15 @@ export { computed } from './src/computed';
3
3
  export { configureLegendState } from './src/config';
4
4
  export { event } from './src/event';
5
5
  export { computeSelector, constructObjectWithPath, deconstructObjectWithPath, getObservableIndex, isObservable, isObservableValueReady, lockObservable, mergeIntoObservable, opaqueObject, setAtPath, setInObservableAtPath, setSilently, } from './src/helpers';
6
- export { isArray, isBoolean, isEmpty, isFunction, isObject, isPrimitive, isPromise, isString, isSymbol, } from './src/is';
6
+ export { hasOwnProperty, isArray, isBoolean, isEmpty, isFunction, isObject, isPrimitive, isPromise, isString, isSymbol, } from './src/is';
7
7
  export { observable, observablePrimitive } from './src/observable';
8
8
  export * from './src/observableInterfaces';
9
9
  export { observe } from './src/observe';
10
10
  export { proxy } from './src/proxy';
11
11
  export { trackSelector } from './src/trackSelector';
12
12
  export { when, whenReady } from './src/when';
13
- import { getProxy, set } from './src/ObservableObject';
14
- import { ensureNodeValue, findIDKey, get, getNode, peek, setNodeValue } from './src/globals';
13
+ import { get, getProxy, peek, set } from './src/ObservableObject';
14
+ import { ensureNodeValue, findIDKey, getNode, setNodeValue } from './src/globals';
15
15
  import { setAtPath } from './src/helpers';
16
16
  export declare const internal: {
17
17
  ensureNodeValue: typeof ensureNodeValue;
package/index.js CHANGED
@@ -50,50 +50,6 @@ 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');
@@ -116,15 +72,6 @@ function checkActivate(node) {
116
72
  function getNode(obs) {
117
73
  return obs && obs[symbolGetNode];
118
74
  }
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
75
  function setNodeValue(node, newValue) {
129
76
  var _a;
130
77
  const parentNode = (_a = node.parent) !== null && _a !== void 0 ? _a : node;
@@ -188,6 +135,7 @@ function getChildNode(node, key) {
188
135
  root: node.root,
189
136
  parent: node,
190
137
  key,
138
+ lazy: true,
191
139
  };
192
140
  if (!node.children) {
193
141
  node.children = new Map();
@@ -516,6 +464,45 @@ function onChange(node, callback, options = {}) {
516
464
  return () => listeners.delete(listener);
517
465
  }
518
466
 
467
+ let trackCount = 0;
468
+ const trackingQueue = [];
469
+ const tracking = {
470
+ current: undefined,
471
+ };
472
+ function beginTracking() {
473
+ // Keep a copy of the previous tracking context so it can be restored
474
+ // when this context is complete
475
+ trackingQueue.push(tracking.current);
476
+ trackCount++;
477
+ tracking.current = {};
478
+ }
479
+ function endTracking() {
480
+ // Restore the previous tracking context
481
+ trackCount--;
482
+ if (trackCount < 0) {
483
+ trackCount = 0;
484
+ }
485
+ tracking.current = trackingQueue.pop();
486
+ }
487
+ function updateTracking(node, track) {
488
+ if (trackCount) {
489
+ const tracker = tracking.current;
490
+ if (tracker) {
491
+ if (!tracker.nodes) {
492
+ tracker.nodes = new Map();
493
+ }
494
+ const existing = tracker.nodes.get(node);
495
+ if (existing) {
496
+ existing.track = existing.track || track;
497
+ existing.num++;
498
+ }
499
+ else {
500
+ tracker.nodes.set(node, { node, track, num: 1 });
501
+ }
502
+ }
503
+ }
504
+ }
505
+
519
506
  const ArrayModifiers = new Set([
520
507
  'copyWithin',
521
508
  'fill',
@@ -678,7 +665,6 @@ function updateNodes(parent, obj, prevValue) {
678
665
  const prev = isMap ? prevValue === null || prevValue === void 0 ? void 0 : prevValue.get(key) : prevValue === null || prevValue === void 0 ? void 0 : prevValue[key];
679
666
  let isDiff = value !== prev;
680
667
  if (isDiff) {
681
- extractFunctionOrComputed(parent, obj, key, value);
682
668
  const id = idField && value
683
669
  ? isIdFieldFunction
684
670
  ? idField(value)
@@ -773,12 +759,13 @@ const proxyHandler = {
773
759
  if (p === symbolGetNode) {
774
760
  return node;
775
761
  }
762
+ const value = peek(node);
776
763
  // If this node is linked to another observable then forward to the target's handler.
777
764
  // The exception is onChange because it needs to listen to this node for changes.
765
+ // This needs to be below peek because it activates there.
778
766
  if (node.linkedToNode && p !== 'onChange') {
779
767
  return proxyHandler.get(node.linkedToNode, p, receiver);
780
768
  }
781
- const value = peek(node);
782
769
  if (value instanceof Map || value instanceof WeakMap || value instanceof Set || value instanceof WeakSet) {
783
770
  const ret = handlerMapSet(node, p, value);
784
771
  if (ret !== undefined) {
@@ -986,7 +973,7 @@ function setKey(node, key, newValue, level) {
986
973
  if (savedValue !== prevValue) {
987
974
  updateNodesAndNotify(node, savedValue, prevValue, childNode, isPrim, isRoot, level);
988
975
  }
989
- extractFunctionOrComputed(node, parentValue, key, newValue);
976
+ extractFunctionOrComputed(node, parentValue, key, savedValue);
990
977
  return isFunc ? savedValue : isRoot ? getProxy(node) : getProxy(node, key);
991
978
  }
992
979
  function assign(node, value) {
@@ -1123,7 +1110,6 @@ function extractPromise(node, value) {
1123
1110
  set(node, { error, status: 'rejected' });
1124
1111
  });
1125
1112
  }
1126
- const __devExtractFunctionsAndComputedsNodes = process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test' ? new Set() : undefined;
1127
1113
  function extractFunctionOrComputed(node, obj, k, v) {
1128
1114
  if (isPromise(v)) {
1129
1115
  extractPromise(getChildNode(node, k), v);
@@ -1142,21 +1128,25 @@ function extractFunctionOrComputed(node, obj, k, v) {
1142
1128
  }
1143
1129
  }
1144
1130
  }
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);
1131
+ function get(node, track) {
1132
+ // Track by default
1133
+ updateTracking(node, track);
1134
+ return peek(node);
1135
+ }
1136
+ function peek(node) {
1137
+ const value = getNodeValue(node);
1138
+ // If node is not yet lazily computed go do that
1139
+ if (node.lazy) {
1140
+ delete node.lazy;
1141
+ for (const key in value) {
1142
+ if (hasOwnProperty.call(value, key)) {
1143
+ extractFunctionOrComputed(node, value, key, value[key]);
1144
+ }
1158
1145
  }
1159
1146
  }
1147
+ // Check if computed needs to activate
1148
+ checkActivate(node);
1149
+ return value;
1160
1150
  }
1161
1151
 
1162
1152
  function isObservable(obs) {
@@ -1374,6 +1364,7 @@ function createObservable(value, makePrimitive) {
1374
1364
  };
1375
1365
  const node = {
1376
1366
  root,
1367
+ lazy: true,
1377
1368
  };
1378
1369
  const prim = makePrimitive || isActualPrimitive(value);
1379
1370
  const obs = prim
@@ -1382,14 +1373,6 @@ function createObservable(value, makePrimitive) {
1382
1373
  if (valueIsPromise) {
1383
1374
  extractPromise(node, value);
1384
1375
  }
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
1376
  return obs;
1394
1377
  }
1395
1378
  function observable(value) {
@@ -1416,7 +1399,7 @@ function setupTracking(nodes, update, noArgs, immediate) {
1416
1399
  };
1417
1400
  }
1418
1401
 
1419
- function trackSelector(selector, update, observeEvent, observeOptions, createResubscribe, inRender) {
1402
+ function trackSelector(selector, update, observeEvent, observeOptions, createResubscribe) {
1420
1403
  var _a;
1421
1404
  let nodes;
1422
1405
  let value;
@@ -1424,23 +1407,21 @@ function trackSelector(selector, update, observeEvent, observeOptions, createRes
1424
1407
  let tracker;
1425
1408
  let resubscribe;
1426
1409
  let updateFn = update;
1427
- let noArgs = true;
1428
1410
  if (isObservable(selector)) {
1429
1411
  value = selector.peek();
1430
- dispose = selector.onChange(update, { noArgs: true });
1431
- resubscribe = createResubscribe ? selector.onChange(update, { noArgs: true }) : undefined;
1412
+ dispose = selector.onChange(update);
1413
+ resubscribe = createResubscribe ? selector.onChange(update) : undefined;
1432
1414
  }
1433
1415
  else {
1434
1416
  // Compute the selector inside a tracking context
1435
- beginTracking(inRender);
1417
+ beginTracking();
1436
1418
  value = selector ? computeSelector(selector, observeEvent, observeOptions === null || observeOptions === void 0 ? void 0 : observeOptions.retainObservable) : selector;
1437
1419
  tracker = tracking.current;
1438
1420
  nodes = tracker.nodes;
1439
- endTracking(inRender);
1421
+ endTracking();
1440
1422
  if ((process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') && tracker && nodes) {
1441
1423
  (_a = tracker.traceListeners) === null || _a === void 0 ? void 0 : _a.call(tracker, nodes);
1442
1424
  if (tracker.traceUpdates) {
1443
- noArgs = false;
1444
1425
  updateFn = tracker.traceUpdates(update);
1445
1426
  }
1446
1427
  // Clear tracing so it doesn't leak to other components
@@ -1452,8 +1433,8 @@ function trackSelector(selector, update, observeEvent, observeOptions, createRes
1452
1433
  // Do tracing if it was requested
1453
1434
  // useSyncExternalStore doesn't subscribe until after the component mount.
1454
1435
  // 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;
1436
+ dispose = setupTracking(nodes, updateFn, false, observeOptions === null || observeOptions === void 0 ? void 0 : observeOptions.immediate);
1437
+ resubscribe = createResubscribe ? () => setupTracking(nodes, updateFn) : undefined;
1457
1438
  }
1458
1439
  return { value, dispose, resubscribe };
1459
1440
  }
@@ -1467,6 +1448,7 @@ function observe(selectorOrRun, reactionOrOptions, options) {
1467
1448
  options = reactionOrOptions;
1468
1449
  }
1469
1450
  let dispose;
1451
+ let isFirstRun = true;
1470
1452
  const e = { num: 0 };
1471
1453
  // Wrap it in a function so it doesn't pass all the arguments to run()
1472
1454
  const update = function () {
@@ -1487,15 +1469,16 @@ function observe(selectorOrRun, reactionOrOptions, options) {
1487
1469
  e.onCleanupReaction();
1488
1470
  e.onCleanupReaction = undefined;
1489
1471
  }
1472
+ endBatch();
1490
1473
  // Call the reaction if there is one and the value changed
1491
- if (reaction && (e.num > 0 || !isEvent(selectorOrRun)) && e.previous !== e.value) {
1474
+ if (reaction && (e.num > 0 || !isEvent(selectorOrRun)) && (isFirstRun || e.previous !== e.value)) {
1492
1475
  reaction(e);
1493
1476
  }
1494
1477
  // Update the previous value
1495
1478
  e.previous = e.value;
1496
1479
  // Increment the counter
1497
1480
  e.num++;
1498
- endBatch();
1481
+ isFirstRun = false;
1499
1482
  };
1500
1483
  update();
1501
1484
  // Return function calling dispose because dispose may be changed in update()
@@ -1672,20 +1655,27 @@ function proxy(get, set) {
1672
1655
  }
1673
1656
 
1674
1657
  function _when(predicate, effect, checkReady) {
1658
+ // If predicate is a regular Promise skip all the observable stuff
1659
+ if (isPromise(predicate)) {
1660
+ return effect ? predicate.then(effect) : predicate;
1661
+ }
1675
1662
  let value;
1676
1663
  // Create a wrapping fn that calls the effect if predicate returns true
1677
1664
  function run(e) {
1678
1665
  const ret = computeSelector(predicate);
1679
1666
  if (!isPromise(ret) && (checkReady ? isObservableValueReady(ret) : ret)) {
1680
1667
  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
1668
+ // Set cancel so that observe does not track anymore
1684
1669
  e.cancel = true;
1685
1670
  }
1671
+ return value;
1672
+ }
1673
+ function doEffect() {
1674
+ // If value is truthy then run the effect
1675
+ effect === null || effect === void 0 ? void 0 : effect(value);
1686
1676
  }
1687
1677
  // Run in an observe
1688
- observe(run);
1678
+ observe(run, doEffect);
1689
1679
  // If first run resulted in a truthy value just return it.
1690
1680
  // It will have set e.cancel so no need to dispose
1691
1681
  if (isPromise(value)) {
@@ -1750,6 +1740,7 @@ exports.findIDKey = findIDKey;
1750
1740
  exports.getNode = getNode;
1751
1741
  exports.getNodeValue = getNodeValue;
1752
1742
  exports.getObservableIndex = getObservableIndex;
1743
+ exports.hasOwnProperty = hasOwnProperty;
1753
1744
  exports.internal = internal;
1754
1745
  exports.isArray = isArray;
1755
1746
  exports.isBoolean = isBoolean;