@legendapp/state 3.0.0-alpha.1 → 3.0.0-alpha.3

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 (327) hide show
  1. package/.DS_Store +0 -0
  2. package/CHANGELOG.md +1 -831
  3. package/LICENSE +1 -21
  4. package/README.md +1 -141
  5. package/as/arrayAsRecord.d.mts +5 -0
  6. package/as/arrayAsRecord.d.ts +5 -0
  7. package/as/arrayAsRecord.js +28 -0
  8. package/as/arrayAsRecord.mjs +26 -0
  9. package/as/arrayAsSet.d.mts +5 -0
  10. package/as/arrayAsSet.d.ts +5 -0
  11. package/as/arrayAsSet.js +13 -0
  12. package/as/arrayAsSet.mjs +11 -0
  13. package/as/arrayAsString.d.mts +5 -0
  14. package/as/arrayAsString.d.ts +5 -0
  15. package/as/arrayAsString.js +13 -0
  16. package/as/arrayAsString.mjs +11 -0
  17. package/as/numberAsString.d.mts +5 -0
  18. package/as/numberAsString.d.ts +5 -0
  19. package/as/numberAsString.js +13 -0
  20. package/as/numberAsString.mjs +11 -0
  21. package/as/recordAsArray.d.mts +5 -0
  22. package/as/recordAsArray.d.ts +5 -0
  23. package/as/recordAsArray.js +25 -0
  24. package/as/recordAsArray.mjs +23 -0
  25. package/as/recordAsString.d.mts +5 -0
  26. package/as/recordAsString.d.ts +5 -0
  27. package/as/recordAsString.js +13 -0
  28. package/as/recordAsString.mjs +11 -0
  29. package/as/setAsArray.d.mts +5 -0
  30. package/as/setAsArray.d.ts +5 -0
  31. package/as/setAsArray.js +13 -0
  32. package/as/setAsArray.mjs +11 -0
  33. package/as/setAsString.d.mts +5 -0
  34. package/as/setAsString.d.ts +5 -0
  35. package/as/setAsString.js +13 -0
  36. package/as/setAsString.mjs +11 -0
  37. package/as/stringAsArray.d.mts +5 -0
  38. package/as/stringAsArray.d.ts +5 -0
  39. package/as/stringAsArray.js +13 -0
  40. package/as/stringAsArray.mjs +11 -0
  41. package/as/stringAsNumber.d.mts +5 -0
  42. package/as/stringAsNumber.d.ts +5 -0
  43. package/as/stringAsNumber.js +16 -0
  44. package/as/stringAsNumber.mjs +14 -0
  45. package/as/stringAsRecord.d.mts +5 -0
  46. package/as/stringAsRecord.d.ts +5 -0
  47. package/as/stringAsRecord.js +15 -0
  48. package/as/stringAsRecord.mjs +13 -0
  49. package/as/stringAsSet.d.mts +5 -0
  50. package/as/stringAsSet.d.ts +5 -0
  51. package/as/stringAsSet.js +13 -0
  52. package/as/stringAsSet.mjs +11 -0
  53. package/babel.d.mts +21 -0
  54. package/babel.d.ts +21 -2
  55. package/babel.js +57 -53
  56. package/babel.mjs +65 -0
  57. package/config/enable$GetSet.js +13 -14
  58. package/config/enable$GetSet.mjs +13 -14
  59. package/config/enableReactComponents.d.mts +9 -0
  60. package/config/enableReactComponents.d.ts +4 -2
  61. package/config/enableReactComponents.js +13 -10
  62. package/config/enableReactComponents.mjs +13 -10
  63. package/config/enableReactNativeComponents.d.mts +22 -0
  64. package/config/enableReactNativeComponents.d.ts +6 -4
  65. package/config/enableReactNativeComponents.js +43 -47
  66. package/config/enableReactNativeComponents.mjs +43 -47
  67. package/config/enableReactTracking.d.mts +7 -0
  68. package/config/enableReactTracking.d.ts +3 -2
  69. package/config/enableReactTracking.js +33 -38
  70. package/config/enableReactTracking.mjs +33 -38
  71. package/config/enableReactUse.d.mts +10 -0
  72. package/config/enableReactUse.d.ts +4 -1
  73. package/config/enableReactUse.js +15 -14
  74. package/config/enableReactUse.mjs +15 -14
  75. package/config/{enable$GetSet.d.ts → enable_GetSet.d.mts} +4 -2
  76. package/config/enable_GetSet.d.ts +10 -0
  77. package/config/enable_PeekAssign.d.mts +10 -0
  78. package/config/enable_PeekAssign.d.ts +4 -2
  79. package/config/enable_PeekAssign.js +13 -14
  80. package/config/enable_PeekAssign.mjs +13 -14
  81. package/helpers/pageHash.d.mts +9 -0
  82. package/helpers/pageHash.d.ts +2 -0
  83. package/helpers/pageHash.js +25 -30
  84. package/helpers/pageHash.mjs +25 -30
  85. package/helpers/pageHashParams.d.mts +9 -0
  86. package/helpers/pageHashParams.d.ts +2 -0
  87. package/helpers/pageHashParams.js +34 -37
  88. package/helpers/pageHashParams.mjs +34 -37
  89. package/helpers/time.d.mts +6 -0
  90. package/helpers/time.d.ts +6 -3
  91. package/helpers/time.js +17 -17
  92. package/helpers/time.mjs +17 -17
  93. package/helpers/trackHistory.d.mts +6 -0
  94. package/helpers/trackHistory.d.ts +4 -2
  95. package/helpers/trackHistory.js +13 -16
  96. package/helpers/trackHistory.mjs +13 -16
  97. package/helpers/undoRedo.d.mts +37 -0
  98. package/helpers/undoRedo.d.ts +5 -3
  99. package/helpers/undoRedo.js +59 -94
  100. package/helpers/undoRedo.mjs +59 -94
  101. package/index.d.mts +404 -0
  102. package/index.d.ts +371 -28
  103. package/index.js +2015 -2166
  104. package/index.mjs +2015 -2166
  105. package/package.json +254 -195
  106. package/persist-plugins/async-storage.d.mts +18 -0
  107. package/persist-plugins/async-storage.d.ts +6 -3
  108. package/persist-plugins/async-storage.js +79 -86
  109. package/persist-plugins/async-storage.mjs +79 -86
  110. package/persist-plugins/indexeddb.d.mts +29 -0
  111. package/persist-plugins/indexeddb.d.ts +6 -3
  112. package/persist-plugins/indexeddb.js +331 -352
  113. package/persist-plugins/indexeddb.mjs +331 -352
  114. package/persist-plugins/local-storage.d.mts +23 -0
  115. package/persist-plugins/local-storage.d.ts +8 -5
  116. package/persist-plugins/local-storage.js +74 -76
  117. package/persist-plugins/local-storage.mjs +74 -76
  118. package/persist-plugins/mmkv.d.mts +18 -0
  119. package/persist-plugins/mmkv.d.ts +6 -3
  120. package/persist-plugins/mmkv.js +82 -86
  121. package/persist-plugins/mmkv.mjs +82 -86
  122. package/react-hooks/createObservableHook.d.mts +5 -0
  123. package/react-hooks/createObservableHook.d.ts +4 -1
  124. package/react-hooks/createObservableHook.js +29 -30
  125. package/react-hooks/createObservableHook.mjs +25 -30
  126. package/react-hooks/useHover.d.mts +5 -0
  127. package/react-hooks/useHover.d.ts +5 -3
  128. package/react-hooks/useHover.js +29 -29
  129. package/react-hooks/useHover.mjs +29 -29
  130. package/react-hooks/useMeasure.d.mts +9 -0
  131. package/react-hooks/useMeasure.d.ts +5 -2
  132. package/react-hooks/useMeasure.js +30 -32
  133. package/react-hooks/useMeasure.mjs +30 -32
  134. package/react-hooks/useObservableNextRouter.d.mts +35 -0
  135. package/react-hooks/useObservableNextRouter.d.ts +9 -7
  136. package/react-hooks/useObservableNextRouter.js +64 -77
  137. package/react-hooks/useObservableNextRouter.mjs +60 -77
  138. package/react.d.mts +157 -0
  139. package/react.d.ts +157 -21
  140. package/react.js +458 -749
  141. package/react.mjs +457 -752
  142. package/sync-plugins/crud.d.mts +54 -0
  143. package/sync-plugins/crud.d.ts +12 -10
  144. package/sync-plugins/crud.js +253 -270
  145. package/sync-plugins/crud.mjs +253 -270
  146. package/sync-plugins/fetch.d.mts +21 -0
  147. package/sync-plugins/fetch.d.ts +7 -4
  148. package/sync-plugins/fetch.js +50 -37
  149. package/sync-plugins/fetch.mjs +50 -37
  150. package/sync-plugins/keel.d.mts +108 -0
  151. package/sync-plugins/keel.d.ts +17 -15
  152. package/sync-plugins/keel.js +229 -462
  153. package/sync-plugins/keel.mjs +227 -464
  154. package/sync-plugins/supabase.d.mts +39 -0
  155. package/sync-plugins/supabase.d.ts +16 -14
  156. package/sync-plugins/supabase.js +128 -128
  157. package/sync-plugins/supabase.mjs +128 -128
  158. package/sync-plugins/tanstack-query.d.mts +14 -0
  159. package/sync-plugins/tanstack-query.d.ts +7 -4
  160. package/sync-plugins/tanstack-query.js +51 -57
  161. package/sync-plugins/tanstack-query.mjs +51 -57
  162. package/sync-plugins/tanstack-react-query.d.mts +8 -0
  163. package/sync-plugins/tanstack-react-query.d.ts +6 -1
  164. package/sync-plugins/tanstack-react-query.js +2 -2
  165. package/sync-plugins/tanstack-react-query.mjs +2 -2
  166. package/sync.d.mts +351 -0
  167. package/sync.d.ts +349 -9
  168. package/sync.js +910 -964
  169. package/sync.mjs +920 -974
  170. package/trace.d.mts +9 -0
  171. package/trace.d.ts +9 -4
  172. package/trace.js +72 -62
  173. package/trace.mjs +72 -62
  174. package/types/babel.d.ts +1 -12
  175. package/babel.js.map +0 -1
  176. package/config/enable$GetSet.js.map +0 -1
  177. package/config/enable$GetSet.mjs.map +0 -1
  178. package/config/enableReactComponents.js.map +0 -1
  179. package/config/enableReactComponents.mjs.map +0 -1
  180. package/config/enableReactNativeComponents.js.map +0 -1
  181. package/config/enableReactNativeComponents.mjs.map +0 -1
  182. package/config/enableReactTracking.js.map +0 -1
  183. package/config/enableReactTracking.mjs.map +0 -1
  184. package/config/enableReactUse.js.map +0 -1
  185. package/config/enableReactUse.mjs.map +0 -1
  186. package/config/enable_PeekAssign.js.map +0 -1
  187. package/config/enable_PeekAssign.mjs.map +0 -1
  188. package/helpers/pageHash.js.map +0 -1
  189. package/helpers/pageHash.mjs.map +0 -1
  190. package/helpers/pageHashParams.js.map +0 -1
  191. package/helpers/pageHashParams.mjs.map +0 -1
  192. package/helpers/time.js.map +0 -1
  193. package/helpers/time.mjs.map +0 -1
  194. package/helpers/trackHistory.js.map +0 -1
  195. package/helpers/trackHistory.mjs.map +0 -1
  196. package/helpers/undoRedo.js.map +0 -1
  197. package/helpers/undoRedo.mjs.map +0 -1
  198. package/history.d.ts +0 -1
  199. package/history.js +0 -24
  200. package/history.js.map +0 -1
  201. package/history.mjs +0 -22
  202. package/history.mjs.map +0 -1
  203. package/index.js.map +0 -1
  204. package/index.mjs.map +0 -1
  205. package/persist-plugins/async-storage.js.map +0 -1
  206. package/persist-plugins/async-storage.mjs.map +0 -1
  207. package/persist-plugins/indexeddb.js.map +0 -1
  208. package/persist-plugins/indexeddb.mjs.map +0 -1
  209. package/persist-plugins/local-storage.js.map +0 -1
  210. package/persist-plugins/local-storage.mjs.map +0 -1
  211. package/persist-plugins/mmkv.js.map +0 -1
  212. package/persist-plugins/mmkv.mjs.map +0 -1
  213. package/react-hooks/createObservableHook.js.map +0 -1
  214. package/react-hooks/createObservableHook.mjs.map +0 -1
  215. package/react-hooks/useHover.js.map +0 -1
  216. package/react-hooks/useHover.mjs.map +0 -1
  217. package/react-hooks/useMeasure.js.map +0 -1
  218. package/react-hooks/useMeasure.mjs.map +0 -1
  219. package/react-hooks/useObservableNextRouter.js.map +0 -1
  220. package/react-hooks/useObservableNextRouter.mjs.map +0 -1
  221. package/react.js.map +0 -1
  222. package/react.mjs.map +0 -1
  223. package/src/ObservableObject.ts +0 -1350
  224. package/src/ObservablePrimitive.ts +0 -62
  225. package/src/babel/index.ts +0 -83
  226. package/src/batching.ts +0 -357
  227. package/src/computed.ts +0 -18
  228. package/src/config/enable$GetSet.ts +0 -30
  229. package/src/config/enableReactComponents.ts +0 -26
  230. package/src/config/enableReactNativeComponents.ts +0 -102
  231. package/src/config/enableReactTracking.ts +0 -62
  232. package/src/config/enableReactUse.ts +0 -32
  233. package/src/config/enable_PeekAssign.ts +0 -31
  234. package/src/config.ts +0 -47
  235. package/src/createObservable.ts +0 -47
  236. package/src/event.ts +0 -26
  237. package/src/globals.ts +0 -235
  238. package/src/helpers/pageHash.ts +0 -41
  239. package/src/helpers/pageHashParams.ts +0 -55
  240. package/src/helpers/time.ts +0 -30
  241. package/src/helpers/trackHistory.ts +0 -29
  242. package/src/helpers/undoRedo.ts +0 -111
  243. package/src/helpers.ts +0 -231
  244. package/src/is.ts +0 -63
  245. package/src/linked.ts +0 -17
  246. package/src/observable.ts +0 -32
  247. package/src/observableInterfaces.ts +0 -151
  248. package/src/observableTypes.ts +0 -232
  249. package/src/observe.ts +0 -89
  250. package/src/old-plugins/firebase.ts +0 -1053
  251. package/src/onChange.ts +0 -146
  252. package/src/persist/configureObservablePersistence.ts +0 -7
  253. package/src/persist/fieldTransformer.ts +0 -149
  254. package/src/persist/observablePersistRemoteFunctionsAdapter.ts +0 -39
  255. package/src/persist/persistObservable.ts +0 -1034
  256. package/src/persist-plugins/async-storage.ts +0 -99
  257. package/src/persist-plugins/indexeddb.ts +0 -439
  258. package/src/persist-plugins/local-storage.ts +0 -86
  259. package/src/persist-plugins/mmkv.ts +0 -91
  260. package/src/proxy.ts +0 -28
  261. package/src/react/Computed.tsx +0 -8
  262. package/src/react/For.tsx +0 -116
  263. package/src/react/Memo.tsx +0 -4
  264. package/src/react/Reactive.tsx +0 -53
  265. package/src/react/Show.tsx +0 -33
  266. package/src/react/Switch.tsx +0 -43
  267. package/src/react/react-globals.ts +0 -3
  268. package/src/react/reactInterfaces.ts +0 -32
  269. package/src/react/reactive-observer.tsx +0 -210
  270. package/src/react/useComputed.ts +0 -36
  271. package/src/react/useEffectOnce.ts +0 -41
  272. package/src/react/useIsMounted.ts +0 -16
  273. package/src/react/useMount.ts +0 -15
  274. package/src/react/useObservable.ts +0 -24
  275. package/src/react/useObservableReducer.ts +0 -52
  276. package/src/react/useObservableState.ts +0 -30
  277. package/src/react/useObserve.ts +0 -54
  278. package/src/react/useObserveEffect.ts +0 -40
  279. package/src/react/usePauseProvider.tsx +0 -16
  280. package/src/react/useSelector.ts +0 -167
  281. package/src/react/useUnmount.ts +0 -8
  282. package/src/react/useWhen.ts +0 -9
  283. package/src/react-hooks/createObservableHook.ts +0 -53
  284. package/src/react-hooks/useHover.ts +0 -40
  285. package/src/react-hooks/useMeasure.ts +0 -48
  286. package/src/react-hooks/useObservableNextRouter.ts +0 -137
  287. package/src/retry.ts +0 -71
  288. package/src/setupTracking.ts +0 -26
  289. package/src/sync/activateSyncedNode.ts +0 -128
  290. package/src/sync/configureObservableSync.ts +0 -7
  291. package/src/sync/persistTypes.ts +0 -216
  292. package/src/sync/syncHelpers.ts +0 -180
  293. package/src/sync/syncObservable.ts +0 -1056
  294. package/src/sync/syncObservableAdapter.ts +0 -31
  295. package/src/sync/syncTypes.ts +0 -189
  296. package/src/sync/synced.ts +0 -21
  297. package/src/sync-plugins/crud.ts +0 -412
  298. package/src/sync-plugins/fetch.ts +0 -80
  299. package/src/sync-plugins/keel.ts +0 -495
  300. package/src/sync-plugins/supabase.ts +0 -249
  301. package/src/sync-plugins/tanstack-query.ts +0 -113
  302. package/src/sync-plugins/tanstack-react-query.ts +0 -12
  303. package/src/trace/traceHelpers.ts +0 -11
  304. package/src/trace/useTraceListeners.ts +0 -34
  305. package/src/trace/useTraceUpdates.ts +0 -24
  306. package/src/trace/useVerifyNotTracking.ts +0 -33
  307. package/src/trace/useVerifyOneRender.ts +0 -10
  308. package/src/trackSelector.ts +0 -52
  309. package/src/tracking.ts +0 -43
  310. package/src/types/babel.d.ts +0 -12
  311. package/src/when.ts +0 -75
  312. package/sync-plugins/crud.js.map +0 -1
  313. package/sync-plugins/crud.mjs.map +0 -1
  314. package/sync-plugins/fetch.js.map +0 -1
  315. package/sync-plugins/fetch.mjs.map +0 -1
  316. package/sync-plugins/keel.js.map +0 -1
  317. package/sync-plugins/keel.mjs.map +0 -1
  318. package/sync-plugins/supabase.js.map +0 -1
  319. package/sync-plugins/supabase.mjs.map +0 -1
  320. package/sync-plugins/tanstack-query.js.map +0 -1
  321. package/sync-plugins/tanstack-query.mjs.map +0 -1
  322. package/sync-plugins/tanstack-react-query.js.map +0 -1
  323. package/sync-plugins/tanstack-react-query.mjs.map +0 -1
  324. package/sync.js.map +0 -1
  325. package/sync.mjs.map +0 -1
  326. package/trace.js.map +0 -1
  327. package/trace.mjs.map +0 -1
package/index.mjs CHANGED
@@ -1,2455 +1,2304 @@
1
- const hasOwnProperty = Object.prototype.hasOwnProperty;
1
+ // src/is.ts
2
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
2
3
  function isArray(obj) {
3
- return Array.isArray(obj);
4
+ return Array.isArray(obj);
4
5
  }
5
6
  function isString(obj) {
6
- return typeof obj === 'string';
7
+ return typeof obj === "string";
7
8
  }
8
9
  function isObject(obj) {
9
- return !!obj && typeof obj === 'object' && !(obj instanceof Date) && !isArray(obj);
10
+ return !!obj && typeof obj === "object" && !(obj instanceof Date) && !isArray(obj);
10
11
  }
11
12
  function isFunction(obj) {
12
- return typeof obj === 'function';
13
+ return typeof obj === "function";
13
14
  }
14
15
  function isPrimitive(arg) {
15
- const type = typeof arg;
16
- return arg !== undefined && (isDate(arg) || (type !== 'object' && type !== 'function'));
16
+ const type = typeof arg;
17
+ return arg !== void 0 && (isDate(arg) || type !== "object" && type !== "function");
17
18
  }
18
19
  function isDate(obj) {
19
- return obj instanceof Date;
20
+ return obj instanceof Date;
20
21
  }
21
22
  function isSymbol(obj) {
22
- return typeof obj === 'symbol';
23
+ return typeof obj === "symbol";
23
24
  }
24
25
  function isBoolean(obj) {
25
- return typeof obj === 'boolean';
26
+ return typeof obj === "boolean";
26
27
  }
27
28
  function isPromise(obj) {
28
- return obj instanceof Promise;
29
+ return obj instanceof Promise;
29
30
  }
30
31
  function isMap(obj) {
31
- return obj instanceof Map;
32
+ return obj instanceof Map;
32
33
  }
33
34
  function isNumber(obj) {
34
- const n = obj;
35
- return n - n < 1;
35
+ const n = obj;
36
+ return n - n < 1;
36
37
  }
37
38
  function isEmpty(obj) {
38
- // Looping and returning false on the first property is faster than Object.keys(obj).length === 0
39
- // https://jsbench.me/qfkqv692c8
40
- if (!obj)
41
- return false;
42
- if (isArray(obj))
43
- return obj.length === 0;
44
- for (const key in obj) {
45
- if (hasOwnProperty.call(obj, key)) {
46
- return false;
47
- }
39
+ if (!obj)
40
+ return false;
41
+ if (isArray(obj))
42
+ return obj.length === 0;
43
+ for (const key in obj) {
44
+ if (hasOwnProperty.call(obj, key)) {
45
+ return false;
48
46
  }
49
- return true;
47
+ }
48
+ return true;
50
49
  }
51
50
  function isNullOrUndefined(value) {
52
- return value === undefined || value === null;
51
+ return value === void 0 || value === null;
53
52
  }
54
- const setPrimitives = new Set(['boolean', 'string', 'number']);
55
- /** @internal */
53
+ var setPrimitives = /* @__PURE__ */ new Set(["boolean", "string", "number"]);
56
54
  function isActualPrimitive(arg) {
57
- return setPrimitives.has(typeof arg);
55
+ return setPrimitives.has(typeof arg);
58
56
  }
59
- /** @internal */
60
57
  function isChildNodeValue(node) {
61
- return !!node.parent;
58
+ return !!node.parent;
62
59
  }
63
60
 
64
- const symbolToPrimitive = Symbol.toPrimitive;
65
- const symbolGetNode = Symbol('getNode');
66
- const symbolDelete = /* @__PURE__ */ Symbol('delete');
67
- const symbolOpaque = Symbol('opaque');
68
- const optimized = Symbol('optimized');
69
- const symbolLinked = Symbol('linked');
70
- const globalState = {
71
- isLoadingLocal: false,
72
- isMerging: false,
73
- isLoadingRemote: false,
74
- activateSyncedNode: undefined,
75
- pendingNodes: new Map(),
76
- dirtyNodes: new Set(),
77
- replacer: undefined,
78
- reviver: undefined,
61
+ // src/globals.ts
62
+ var symbolToPrimitive = Symbol.toPrimitive;
63
+ var symbolGetNode = Symbol("getNode");
64
+ var symbolDelete = /* @__PURE__ */ Symbol("delete");
65
+ var symbolOpaque = Symbol("opaque");
66
+ var optimized = Symbol("optimized");
67
+ var symbolLinked = Symbol("linked");
68
+ var globalState = {
69
+ isLoadingLocal: false,
70
+ isMerging: false,
71
+ isLoadingRemote: false,
72
+ activateSyncedNode: void 0,
73
+ pendingNodes: /* @__PURE__ */ new Map(),
74
+ dirtyNodes: /* @__PURE__ */ new Set(),
75
+ replacer: void 0,
76
+ reviver: void 0
79
77
  };
80
78
  function getPathType(value) {
81
- return isArray(value) ? 'array' : isMap(value) ? 'map' : value instanceof Set ? 'set' : 'object';
79
+ return isArray(value) ? "array" : isMap(value) ? "map" : value instanceof Set ? "set" : "object";
82
80
  }
83
81
  function replacer(key, value) {
84
- if (isMap(value)) {
85
- return {
86
- __LSType: 'Map',
87
- value: Array.from(value.entries()), // or with spread: value: [...value]
88
- };
89
- }
90
- else if (value instanceof Set) {
91
- return {
92
- __LSType: 'Set',
93
- value: Array.from(value), // or with spread: value: [...value]
94
- };
95
- }
96
- else if (globalState.replacer) {
97
- value = globalState.replacer(key, value);
98
- }
99
- return value;
82
+ if (isMap(value)) {
83
+ return {
84
+ __LSType: "Map",
85
+ value: Array.from(value.entries())
86
+ // or with spread: value: [...value]
87
+ };
88
+ } else if (value instanceof Set) {
89
+ return {
90
+ __LSType: "Set",
91
+ value: Array.from(value)
92
+ // or with spread: value: [...value]
93
+ };
94
+ } else if (globalState.replacer) {
95
+ value = globalState.replacer(key, value);
96
+ }
97
+ return value;
100
98
  }
101
- const ISO8601 = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/;
99
+ var ISO8601 = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/;
102
100
  function reviver(key, value) {
103
- if (value) {
104
- if (typeof value === 'string' && ISO8601.test(value)) {
105
- return new Date(value);
106
- }
107
- if (typeof value === 'object') {
108
- if (value.__LSType === 'Map') {
109
- return new Map(value.value);
110
- }
111
- else if (value.__LSType === 'Set') {
112
- return new Set(value.value);
113
- }
114
- }
115
- if (globalState.reviver) {
116
- value = globalState.reviver(key, value);
117
- }
101
+ if (value) {
102
+ if (typeof value === "string" && ISO8601.test(value)) {
103
+ return new Date(value);
118
104
  }
119
- return value;
105
+ if (typeof value === "object") {
106
+ if (value.__LSType === "Map") {
107
+ return new Map(value.value);
108
+ } else if (value.__LSType === "Set") {
109
+ return new Set(value.value);
110
+ }
111
+ }
112
+ if (globalState.reviver) {
113
+ value = globalState.reviver(key, value);
114
+ }
115
+ }
116
+ return value;
120
117
  }
121
118
  function safeStringify(value) {
122
- return JSON.stringify(value, replacer);
119
+ return JSON.stringify(value, replacer);
123
120
  }
124
121
  function safeParse(value) {
125
- return JSON.parse(value, reviver);
122
+ return JSON.parse(value, reviver);
126
123
  }
127
124
  function clone(value) {
128
- return safeParse(safeStringify(value));
125
+ return safeParse(safeStringify(value));
129
126
  }
130
127
  function isObservable(value$) {
131
- return !!value$ && !!value$[symbolGetNode];
128
+ return !!value$ && !!value$[symbolGetNode];
132
129
  }
133
130
  function getNode(value$) {
134
- return value$ && value$[symbolGetNode];
131
+ return value$ && value$[symbolGetNode];
135
132
  }
136
133
  function isEvent(value$) {
137
- var _a;
138
- return value$ && ((_a = value$[symbolGetNode]) === null || _a === void 0 ? void 0 : _a.isEvent);
134
+ var _a;
135
+ return value$ && ((_a = value$[symbolGetNode]) == null ? void 0 : _a.isEvent);
139
136
  }
140
137
  function setNodeValue(node, newValue) {
141
- var _a, _b, _c;
142
- const parentNode = (_a = node.parent) !== null && _a !== void 0 ? _a : node;
143
- const key = node.parent ? node.key : '_';
144
- const isDelete = newValue === symbolDelete;
145
- if (isDelete)
146
- newValue = undefined;
147
- // Get the value of the parent
148
- const parentValue = node.parent ? ensureNodeValue(parentNode) : parentNode.root;
149
- // Save the previous value first
150
- const prevValue = parentValue[key];
151
- const isFunc = isFunction(newValue);
152
- // Compute newValue if newValue is a function or an observable
153
- newValue = !parentNode.isAssigning && isFunc && !isFunction(prevValue) ? newValue(prevValue) : newValue;
154
- if (!globalState.isMerging ||
155
- isNullOrUndefined(prevValue) ||
156
- isFunction(prevValue) ||
157
- !((_c = (_b = node.parent) === null || _b === void 0 ? void 0 : _b.functions) === null || _c === void 0 ? void 0 : _c.get(key))) {
158
- try {
159
- parentNode.isSetting = (parentNode.isSetting || 0) + 1;
160
- const useMapFn = isMap(parentValue);
161
- // Save the new value
162
- if (isDelete) {
163
- if (useMapFn) {
164
- parentValue.delete(key);
165
- }
166
- else {
167
- delete parentValue[key];
168
- }
169
- }
170
- else {
171
- const useMapFn = isMap(parentValue);
172
- if (useMapFn) {
173
- parentValue.set(key, newValue);
174
- }
175
- else {
176
- parentValue[key] = newValue;
177
- }
178
- }
179
- }
180
- finally {
181
- parentNode.isSetting--;
182
- }
183
- }
184
- return { prevValue, newValue };
185
- }
186
- const arrNodeKeys = [];
138
+ var _a, _b, _c;
139
+ const parentNode = (_a = node.parent) != null ? _a : node;
140
+ const key = node.parent ? node.key : "_";
141
+ const isDelete = newValue === symbolDelete;
142
+ if (isDelete)
143
+ newValue = void 0;
144
+ const parentValue = node.parent ? ensureNodeValue(parentNode) : parentNode.root;
145
+ const prevValue = parentValue[key];
146
+ const isFunc = isFunction(newValue);
147
+ newValue = !parentNode.isAssigning && isFunc && !isFunction(prevValue) ? newValue(prevValue) : newValue;
148
+ if (!globalState.isMerging || isNullOrUndefined(prevValue) || isFunction(prevValue) || !((_c = (_b = node.parent) == null ? void 0 : _b.functions) == null ? void 0 : _c.get(key))) {
149
+ try {
150
+ parentNode.isSetting = (parentNode.isSetting || 0) + 1;
151
+ const useMapFn = isMap(parentValue);
152
+ if (isDelete) {
153
+ if (useMapFn) {
154
+ parentValue.delete(key);
155
+ } else {
156
+ delete parentValue[key];
157
+ }
158
+ } else {
159
+ const useMapFn2 = isMap(parentValue);
160
+ if (useMapFn2) {
161
+ parentValue.set(key, newValue);
162
+ } else {
163
+ parentValue[key] = newValue;
164
+ }
165
+ }
166
+ } finally {
167
+ parentNode.isSetting--;
168
+ }
169
+ }
170
+ return { prevValue, newValue };
171
+ }
172
+ var arrNodeKeys = [];
187
173
  function getNodeValue(node) {
188
- let count = 0;
189
- let n = node;
190
- while (isChildNodeValue(n)) {
191
- arrNodeKeys[count++] = n.key;
192
- n = n.parent;
193
- }
194
- let child = node.root._;
195
- for (let i = count - 1; child && i >= 0; i--) {
196
- const key = arrNodeKeys[i];
197
- child = key !== 'size' && (isMap(child) || child instanceof WeakMap) ? child.get(key) : child[key];
198
- }
199
- return child;
174
+ let count = 0;
175
+ let n = node;
176
+ while (isChildNodeValue(n)) {
177
+ arrNodeKeys[count++] = n.key;
178
+ n = n.parent;
179
+ }
180
+ let child = node.root._;
181
+ for (let i = count - 1; child && i >= 0; i--) {
182
+ const key = arrNodeKeys[i];
183
+ child = key !== "size" && (isMap(child) || child instanceof WeakMap) ? child.get(key) : child[key];
184
+ }
185
+ return child;
200
186
  }
201
187
  function getChildNode(node, key, asFunction) {
202
- var _a, _b;
203
- // Get the child by key
204
- let child = (_a = node.children) === null || _a === void 0 ? void 0 : _a.get(key);
205
- // Create the child node if it doesn't already exist
206
- if (!child) {
207
- child = {
208
- root: node.root,
209
- parent: node,
210
- key,
211
- lazy: true,
212
- numListenersRecursive: 0,
213
- };
214
- // Lookup functions are bound with the child key
215
- if (((_b = node.lazyFn) === null || _b === void 0 ? void 0 : _b.length) === 1) {
216
- asFunction = node.lazyFn.bind(node, key);
217
- }
218
- if (isFunction(asFunction)) {
219
- child = Object.assign(() => { }, child);
220
- child.lazyFn = asFunction;
221
- }
222
- if (!node.children) {
223
- node.children = new Map();
224
- }
225
- node.children.set(key, child);
188
+ var _a, _b;
189
+ let child = (_a = node.children) == null ? void 0 : _a.get(key);
190
+ if (!child) {
191
+ child = {
192
+ root: node.root,
193
+ parent: node,
194
+ key,
195
+ lazy: true,
196
+ numListenersRecursive: 0
197
+ };
198
+ if (((_b = node.lazyFn) == null ? void 0 : _b.length) === 1) {
199
+ asFunction = node.lazyFn.bind(node, key);
226
200
  }
227
- return child;
201
+ if (isFunction(asFunction)) {
202
+ child = Object.assign(() => {
203
+ }, child);
204
+ child.lazyFn = asFunction;
205
+ }
206
+ if (!node.children) {
207
+ node.children = /* @__PURE__ */ new Map();
208
+ }
209
+ node.children.set(key, child);
210
+ }
211
+ return child;
228
212
  }
229
213
  function ensureNodeValue(node) {
230
- let value = getNodeValue(node);
231
- if (!value || isFunction(value)) {
232
- if (isChildNodeValue(node)) {
233
- const parent = ensureNodeValue(node.parent);
234
- value = parent[node.key] = {};
235
- }
236
- else {
237
- value = node.root._ = {};
238
- }
214
+ let value = getNodeValue(node);
215
+ if (!value || isFunction(value)) {
216
+ if (isChildNodeValue(node)) {
217
+ const parent = ensureNodeValue(node.parent);
218
+ value = parent[node.key] = {};
219
+ } else {
220
+ value = node.root._ = {};
239
221
  }
240
- return value;
222
+ }
223
+ return value;
241
224
  }
242
225
  function findIDKey(obj, node) {
243
- var _a, _b;
244
- let idKey = isObservable(obj)
245
- ? undefined
246
- : isObject(obj)
247
- ? 'id' in obj
248
- ? 'id'
249
- : 'key' in obj
250
- ? 'key'
251
- : '_id' in obj
252
- ? '_id'
253
- : '__id' in obj
254
- ? '__id'
255
- : undefined
256
- : undefined;
257
- if (!idKey && node.parent) {
258
- const k = node.key + '_keyExtractor';
259
- const keyExtractor = (_b = (_a = node.functions) === null || _a === void 0 ? void 0 : _a.get(k)) !== null && _b !== void 0 ? _b : getNodeValue(node.parent)[node.key + '_keyExtractor'];
260
- if (keyExtractor && isFunction(keyExtractor)) {
261
- idKey = keyExtractor;
262
- }
226
+ var _a, _b;
227
+ let idKey = isObservable(obj) ? void 0 : isObject(obj) ? "id" in obj ? "id" : "key" in obj ? "key" : "_id" in obj ? "_id" : "__id" in obj ? "__id" : void 0 : void 0;
228
+ if (!idKey && node.parent) {
229
+ const k = node.key + "_keyExtractor";
230
+ const keyExtractor = (_b = (_a = node.functions) == null ? void 0 : _a.get(k)) != null ? _b : getNodeValue(node.parent)[node.key + "_keyExtractor"];
231
+ if (keyExtractor && isFunction(keyExtractor)) {
232
+ idKey = keyExtractor;
263
233
  }
264
- return idKey;
234
+ }
235
+ return idKey;
265
236
  }
266
237
  function extractFunction(node, key, fnOrComputed) {
267
- if (!node.functions) {
268
- node.functions = new Map();
269
- }
270
- node.functions.set(key, fnOrComputed);
238
+ if (!node.functions) {
239
+ node.functions = /* @__PURE__ */ new Map();
240
+ }
241
+ node.functions.set(key, fnOrComputed);
271
242
  }
272
243
  function equals(a, b) {
273
- return a === b || (isDate(a) && isDate(b) && +a === +b);
244
+ return a === b || isDate(a) && isDate(b) && +a === +b;
274
245
  }
275
246
 
247
+ // src/helpers.ts
276
248
  function computeSelector(selector, e, retainObservable) {
277
- let c = selector;
278
- if (!isObservable(c) && isFunction(c)) {
279
- c = e ? c(e) : c();
280
- }
281
- return isObservable(c) && !retainObservable ? c.get() : c;
249
+ let c = selector;
250
+ if (!isObservable(c) && isFunction(c)) {
251
+ c = e ? c(e) : c();
252
+ }
253
+ return isObservable(c) && !retainObservable ? c.get() : c;
282
254
  }
283
255
  function getObservableIndex(value$) {
284
- const node = getNode(value$);
285
- const n = +node.key;
286
- return isNumber(n) ? n : -1;
256
+ const node = getNode(value$);
257
+ const n = +node.key;
258
+ return isNumber(n) ? n : -1;
287
259
  }
288
260
  function opaqueObject(value) {
289
- if (value) {
290
- value[symbolOpaque] = true;
291
- }
292
- return value;
261
+ if (value) {
262
+ value[symbolOpaque] = true;
263
+ }
264
+ return value;
293
265
  }
294
- const getValueAtPathReducer = (o, p) => o && o[p];
295
- function getValueAtPath$1(obj, path) {
296
- return path.reduce(getValueAtPathReducer, obj);
266
+ var getValueAtPathReducer = (o, p) => o && o[p];
267
+ function getValueAtPath(obj, path) {
268
+ return path.reduce(getValueAtPathReducer, obj);
297
269
  }
298
270
  function setAtPath(obj, path, pathTypes, value, mode, fullObj, restore) {
299
- let p = undefined;
300
- let o = obj;
301
- if (path.length > 0) {
302
- let oFull = fullObj;
303
- for (let i = 0; i < path.length; i++) {
304
- p = path[i];
305
- if (o[p] === symbolDelete) {
306
- // If this was previously deleted, restore it
307
- if (oFull) {
308
- o[p] = oFull[p];
309
- restore === null || restore === void 0 ? void 0 : restore(path.slice(0, i + 1), o[p]);
310
- }
311
- return obj;
312
- }
313
- else if (o[p] === undefined && value === undefined && i === path.length - 1) {
314
- // If setting undefined and the key is undefined, no need to initialize or set it
315
- return obj;
316
- }
317
- else if (o[p] === undefined || o[p] === null) {
318
- o[p] = initializePathType(pathTypes[i]);
319
- }
320
- if (i < path.length - 1) {
321
- o = o[p];
322
- if (oFull) {
323
- oFull = oFull[p];
324
- }
325
- }
271
+ let p = void 0;
272
+ let o = obj;
273
+ if (path.length > 0) {
274
+ let oFull = fullObj;
275
+ for (let i = 0; i < path.length; i++) {
276
+ p = path[i];
277
+ if (o[p] === symbolDelete) {
278
+ if (oFull) {
279
+ o[p] = oFull[p];
280
+ restore == null ? void 0 : restore(path.slice(0, i + 1), o[p]);
281
+ }
282
+ return obj;
283
+ } else if (o[p] === void 0 && value === void 0 && i === path.length - 1) {
284
+ return obj;
285
+ } else if (o[p] === void 0 || o[p] === null) {
286
+ o[p] = initializePathType(pathTypes[i]);
287
+ }
288
+ if (i < path.length - 1) {
289
+ o = o[p];
290
+ if (oFull) {
291
+ oFull = oFull[p];
326
292
  }
293
+ }
327
294
  }
328
- // Don't set if the value is the same. This prevents creating a new key
329
- // when setting undefined on an object without this key
330
- if (p === undefined) {
331
- if (mode === 'merge') {
332
- obj = _mergeIntoObservable(obj, value);
333
- }
334
- else {
335
- obj = value;
336
- }
295
+ }
296
+ if (p === void 0) {
297
+ if (mode === "merge") {
298
+ obj = _mergeIntoObservable(obj, value);
299
+ } else {
300
+ obj = value;
337
301
  }
338
- else {
339
- if (mode === 'merge') {
340
- o[p] = _mergeIntoObservable(o[p], value);
341
- }
342
- else if (isMap(o)) {
343
- o.set(p, value);
344
- }
345
- else {
346
- o[p] = value;
347
- }
302
+ } else {
303
+ if (mode === "merge") {
304
+ o[p] = _mergeIntoObservable(o[p], value);
305
+ } else if (isMap(o)) {
306
+ o.set(p, value);
307
+ } else {
308
+ o[p] = value;
348
309
  }
349
- return obj;
310
+ }
311
+ return obj;
350
312
  }
351
313
  function setInObservableAtPath(value$, path, pathTypes, value, mode) {
352
- let o = value$;
353
- let v = value;
354
- for (let i = 0; i < path.length; i++) {
355
- const p = path[i];
356
- if (!o.peek()[p]) {
357
- o[p].set(initializePathType(pathTypes[i]));
358
- }
359
- o = o[p];
360
- v = v[p];
361
- }
362
- if (v === symbolDelete) {
363
- o.delete();
364
- }
365
- // Assign if possible, or set otherwise
366
- else if (mode === 'assign' && o.assign && isObject(o.peek())) {
367
- o.assign(v);
368
- }
369
- else if (mode === 'merge') {
370
- mergeIntoObservable(o, v);
371
- }
372
- else {
373
- o.set(v);
374
- }
314
+ let o = value$;
315
+ let v = value;
316
+ for (let i = 0; i < path.length; i++) {
317
+ const p = path[i];
318
+ if (!o.peek()[p]) {
319
+ o[p].set(initializePathType(pathTypes[i]));
320
+ }
321
+ o = o[p];
322
+ v = v[p];
323
+ }
324
+ if (v === symbolDelete) {
325
+ o.delete();
326
+ } else if (mode === "assign" && o.assign && isObject(o.peek())) {
327
+ o.assign(v);
328
+ } else if (mode === "merge") {
329
+ mergeIntoObservable(o, v);
330
+ } else {
331
+ o.set(v);
332
+ }
375
333
  }
376
334
  function mergeIntoObservable(target, ...sources) {
377
- beginBatch();
378
- globalState.isMerging = true;
379
- for (let i = 0; i < sources.length; i++) {
380
- target = _mergeIntoObservable(target, sources[i]);
381
- }
382
- globalState.isMerging = false;
383
- endBatch();
384
- return target;
385
- }
386
- function _mergeIntoObservable(target, source) {
387
- var _a;
388
- if (isObservable(source)) {
389
- source = source.peek();
390
- }
391
- const needsSet = isObservable(target);
392
- const targetValue = needsSet ? target.peek() : target;
393
- const isTargetArr = isArray(targetValue);
394
- const isTargetObj = !isTargetArr && isObject(targetValue);
395
- if ((isTargetObj && isObject(source) && !isEmpty(targetValue)) || (isTargetArr && targetValue.length > 0)) {
396
- const keys = Object.keys(source);
397
- for (let i = 0; i < keys.length; i++) {
398
- const key = keys[i];
399
- const sourceValue = source[key];
400
- if (sourceValue === symbolDelete) {
401
- needsSet && ((_a = target[key]) === null || _a === void 0 ? void 0 : _a.delete)
402
- ? target[key].delete()
403
- : delete target[key];
404
- }
405
- else {
406
- const isObj = isObject(sourceValue);
407
- const isArr = !isObj && isArray(sourceValue);
408
- const targetChild = target[key];
409
- if ((isObj || isArr) && targetChild && (needsSet || !isEmpty(targetChild))) {
410
- if (!needsSet && (!targetChild || (isObj ? !isObject(targetChild) : !isArray(targetChild)))) {
411
- target[key] = sourceValue;
412
- }
413
- else {
414
- _mergeIntoObservable(targetChild, sourceValue);
415
- }
416
- }
417
- else {
418
- needsSet
419
- ? targetChild.set(sourceValue)
420
- : (target[key] = sourceValue);
421
- }
422
- }
423
- }
424
- }
425
- else if (source !== undefined) {
426
- needsSet ? target.set(source) : (target = source);
427
- }
428
- return target;
335
+ beginBatch();
336
+ globalState.isMerging = true;
337
+ for (let i = 0; i < sources.length; i++) {
338
+ target = _mergeIntoObservable(
339
+ target,
340
+ sources[i],
341
+ /*assign*/
342
+ i < sources.length - 1
343
+ );
344
+ }
345
+ globalState.isMerging = false;
346
+ endBatch();
347
+ return target;
348
+ }
349
+ function _mergeIntoObservable(target, source, assign2) {
350
+ var _a;
351
+ if (isObservable(source)) {
352
+ source = source.peek();
353
+ }
354
+ const needsSet = isObservable(target);
355
+ const targetValue = needsSet ? target.peek() : target;
356
+ const isTargetArr = isArray(targetValue);
357
+ const isTargetObj = !isTargetArr && isObject(targetValue);
358
+ if (isTargetObj && isObject(source) && !isEmpty(targetValue) || isTargetArr && targetValue.length > 0) {
359
+ const keys = Object.keys(source);
360
+ for (let i = 0; i < keys.length; i++) {
361
+ const key = keys[i];
362
+ const sourceValue = source[key];
363
+ if (sourceValue === symbolDelete) {
364
+ needsSet && ((_a = target[key]) == null ? void 0 : _a.delete) ? target[key].delete() : delete target[key];
365
+ } else {
366
+ const isObj = isObject(sourceValue);
367
+ const isArr = !isObj && isArray(sourceValue);
368
+ const targetChild = target[key];
369
+ if ((isObj || isArr) && targetChild && (needsSet || !isEmpty(targetChild))) {
370
+ if (!needsSet && (!targetChild || (isObj ? !isObject(targetChild) : !isArray(targetChild)))) {
371
+ target[key] = assign2 ? isArr ? [...sourceValue] : { ...sourceValue } : sourceValue;
372
+ } else {
373
+ _mergeIntoObservable(targetChild, sourceValue);
374
+ }
375
+ } else {
376
+ if (needsSet) {
377
+ targetChild.set(sourceValue);
378
+ } else {
379
+ const toSet = isObject(sourceValue) ? { ...sourceValue } : isArray(sourceValue) ? [...sourceValue] : sourceValue;
380
+ target[key] = toSet;
381
+ }
382
+ }
383
+ }
384
+ }
385
+ } else if (source !== void 0) {
386
+ needsSet ? target.set(source) : target = assign2 ? isArray(source) ? [...source] : { ...source } : source;
387
+ }
388
+ return target;
429
389
  }
430
390
  function constructObjectWithPath(path, pathTypes, value) {
431
- let out;
432
- if (path.length > 0) {
433
- let o = (out = {});
434
- for (let i = 0; i < path.length; i++) {
435
- const p = path[i];
436
- o[p] = i === path.length - 1 ? value : initializePathType(pathTypes[i]);
437
- o = o[p];
438
- }
439
- }
440
- else {
441
- out = value;
391
+ let out;
392
+ if (path.length > 0) {
393
+ let o = out = {};
394
+ for (let i = 0; i < path.length; i++) {
395
+ const p = path[i];
396
+ o[p] = i === path.length - 1 ? value : initializePathType(pathTypes[i]);
397
+ o = o[p];
442
398
  }
443
- return out;
399
+ } else {
400
+ out = value;
401
+ }
402
+ return out;
444
403
  }
445
404
  function deconstructObjectWithPath(path, pathTypes, value) {
446
- let o = value;
447
- for (let i = 0; i < path.length; i++) {
448
- const p = path[i];
449
- o = o ? o[p] : initializePathType(pathTypes[i]);
450
- }
451
- return o;
405
+ let o = value;
406
+ for (let i = 0; i < path.length; i++) {
407
+ const p = path[i];
408
+ o = o ? o[p] : initializePathType(pathTypes[i]);
409
+ }
410
+ return o;
452
411
  }
453
412
  function isObservableValueReady(value) {
454
- return !!value && ((!isObject(value) && !isArray(value)) || !isEmpty(value));
413
+ return !!value && (!isObject(value) && !isArray(value) || !isEmpty(value));
455
414
  }
456
415
  function setSilently(value$, newValue) {
457
- const node = getNode(value$);
458
- return setNodeValue(node, newValue).newValue;
416
+ const node = getNode(value$);
417
+ return setNodeValue(node, newValue).newValue;
459
418
  }
460
419
  function initializePathType(pathType) {
461
- switch (pathType) {
462
- case 'array':
463
- return [];
464
- case 'object':
465
- return {};
466
- case 'map':
467
- return new Map();
468
- case 'set':
469
- return new Set();
470
- }
420
+ switch (pathType) {
421
+ case "array":
422
+ return [];
423
+ case "object":
424
+ return {};
425
+ case "map":
426
+ return /* @__PURE__ */ new Map();
427
+ case "set":
428
+ return /* @__PURE__ */ new Set();
429
+ }
471
430
  }
472
431
  function applyChange(value, change, applyPrevious) {
473
- const { path, valueAtPath, prevAtPath, pathTypes } = change;
474
- return setAtPath(value, path, pathTypes, applyPrevious ? prevAtPath : valueAtPath);
432
+ const { path, valueAtPath, prevAtPath, pathTypes } = change;
433
+ return setAtPath(value, path, pathTypes, applyPrevious ? prevAtPath : valueAtPath);
475
434
  }
476
435
  function applyChanges(value, changes, applyPrevious) {
477
- for (let i = 0; i < changes.length; i++) {
478
- value = applyChange(value, changes[i], applyPrevious);
479
- }
480
- return value;
436
+ for (let i = 0; i < changes.length; i++) {
437
+ value = applyChange(value, changes[i], applyPrevious);
438
+ }
439
+ return value;
481
440
  }
482
441
 
483
- let timeout;
484
- let numInBatch = 0;
485
- let isRunningBatch = false;
486
- let didDelayEndBatch = false;
487
- let _batchMap = new Map();
442
+ // src/batching.ts
443
+ var timeout;
444
+ var numInBatch = 0;
445
+ var isRunningBatch = false;
446
+ var didDelayEndBatch = false;
447
+ var _batchMap = /* @__PURE__ */ new Map();
488
448
  function onActionTimeout() {
489
- if (_batchMap.size > 0) {
490
- if (process.env.NODE_ENV === 'development') {
491
- console.error('Forcibly completing observableBatcher because end() was never called. This may be due to an uncaught error between begin() and end().');
492
- }
493
- endBatch(/*force*/ true);
494
- }
449
+ if (_batchMap.size > 0) {
450
+ if (process.env.NODE_ENV === "development") {
451
+ console.error(
452
+ "Forcibly completing observableBatcher because end() was never called. This may be due to an uncaught error between begin() and end()."
453
+ );
454
+ }
455
+ endBatch(
456
+ /*force*/
457
+ true
458
+ );
459
+ }
495
460
  }
496
461
  function isArraySubset(mainArr, subsetArr) {
497
- for (let i = 0; i < mainArr.length; i++) {
498
- if (mainArr[i] !== subsetArr[i]) {
499
- return false;
500
- }
462
+ for (let i = 0; i < mainArr.length; i++) {
463
+ if (mainArr[i] !== subsetArr[i]) {
464
+ return false;
501
465
  }
502
- return true;
466
+ }
467
+ return true;
503
468
  }
504
469
  function createPreviousHandlerInner(value, changes) {
505
- try {
506
- // Clones the current state and inject the previous data at the changed path
507
- return applyChanges(value ? clone(value) : {}, changes, true);
508
- }
509
- catch (_a) {
510
- return undefined;
511
- }
470
+ try {
471
+ return applyChanges(value ? clone(value) : {}, changes, true);
472
+ } catch (e) {
473
+ return void 0;
474
+ }
512
475
  }
513
476
  function createPreviousHandler(value, changes) {
514
- // Create a function that generates the previous state
515
- // We don't want to always do this because cloning is expensive
516
- // so it's better to run on demand.
517
- return function () {
518
- return createPreviousHandlerInner(value, changes);
519
- };
477
+ return function() {
478
+ return createPreviousHandlerInner(value, changes);
479
+ };
520
480
  }
521
481
  function notify(node, value, prev, level, whenOptimizedOnlyIf) {
522
- // Run immediate listeners if there are any
523
- const changesInBatch = new Map();
524
- computeChangesRecursive(changesInBatch, node,
525
- /*loading*/ globalState.isLoadingLocal,
526
- /*remote*/ globalState.isLoadingRemote, value, [], [], value, prev,
527
- /*immediate*/ true, level, whenOptimizedOnlyIf);
528
- if (changesInBatch.size) {
529
- batchNotifyChanges(changesInBatch, /*immediate*/ true);
530
- }
531
- // Update the current batch
532
- const existing = _batchMap.get(node);
533
- if (existing) {
534
- existing.value = value;
535
- // TODO: level, whenOptimizedOnlyIf
536
- }
537
- else {
538
- _batchMap.set(node, {
539
- value,
540
- prev,
541
- level,
542
- whenOptimizedOnlyIf,
543
- remote: globalState.isLoadingRemote,
544
- loading: globalState.isLoadingLocal,
545
- });
546
- }
547
- // If not in a batch run it immediately
548
- if (numInBatch <= 0) {
549
- runBatch();
550
- }
482
+ const changesInBatch = /* @__PURE__ */ new Map();
483
+ computeChangesRecursive(
484
+ changesInBatch,
485
+ node,
486
+ /*loading*/
487
+ globalState.isLoadingLocal,
488
+ /*remote*/
489
+ globalState.isLoadingRemote,
490
+ value,
491
+ [],
492
+ [],
493
+ value,
494
+ prev,
495
+ /*immediate*/
496
+ true,
497
+ level,
498
+ whenOptimizedOnlyIf
499
+ );
500
+ if (changesInBatch.size) {
501
+ batchNotifyChanges(
502
+ changesInBatch,
503
+ /*immediate*/
504
+ true
505
+ );
506
+ }
507
+ const existing = _batchMap.get(node);
508
+ if (existing) {
509
+ existing.value = value;
510
+ } else {
511
+ _batchMap.set(node, {
512
+ value,
513
+ prev,
514
+ level,
515
+ whenOptimizedOnlyIf,
516
+ remote: globalState.isLoadingRemote,
517
+ loading: globalState.isLoadingLocal
518
+ });
519
+ }
520
+ if (numInBatch <= 0) {
521
+ runBatch();
522
+ }
551
523
  }
552
524
  function computeChangesAtNode(changesInBatch, node, loading, remote, value, path, pathTypes, valueAtPath, prevAtPath, immediate, level, whenOptimizedOnlyIf) {
553
- // If there are listeners at this node compute the changes that need to be run
554
- if (immediate ? node.listenersImmediate : node.listeners) {
555
- const change = {
556
- path,
557
- pathTypes,
558
- valueAtPath,
559
- prevAtPath,
560
- };
561
- const changeInBatch = changesInBatch.get(node);
562
- // If the node itself has been changed then we can ignore all the child changes
563
- if (changeInBatch && path.length > 0) {
564
- const { changes } = changeInBatch;
565
- if (!isArraySubset(changes[0].path, change.path)) {
566
- changes.push(change);
567
- }
568
- }
569
- else {
570
- changesInBatch.set(node, {
571
- level,
572
- value,
573
- remote,
574
- loading,
575
- whenOptimizedOnlyIf,
576
- changes: [change],
577
- });
578
- }
579
- }
525
+ if (immediate ? node.listenersImmediate : node.listeners) {
526
+ const change = {
527
+ path,
528
+ pathTypes,
529
+ valueAtPath,
530
+ prevAtPath
531
+ };
532
+ const changeInBatch = changesInBatch.get(node);
533
+ if (changeInBatch && path.length > 0) {
534
+ const { changes } = changeInBatch;
535
+ if (!isArraySubset(changes[0].path, change.path)) {
536
+ changes.push(change);
537
+ }
538
+ } else {
539
+ changesInBatch.set(node, {
540
+ level,
541
+ value,
542
+ remote,
543
+ loading,
544
+ whenOptimizedOnlyIf,
545
+ changes: [change]
546
+ });
547
+ }
548
+ }
580
549
  }
581
550
  function computeChangesRecursive(changesInBatch, node, loading, remote, value, path, pathTypes, valueAtPath, prevAtPath, immediate, level, whenOptimizedOnlyIf) {
582
- // Do the compute at this node
583
- computeChangesAtNode(changesInBatch, node, loading, remote, value, path, pathTypes, valueAtPath, prevAtPath, immediate, level, whenOptimizedOnlyIf);
584
- if (node.linkedFromNodes) {
585
- for (const linkedFromNode of node.linkedFromNodes) {
586
- const childNode = getNodeAtPath(linkedFromNode, path);
587
- computeChangesRecursive(changesInBatch, childNode, loading, remote, valueAtPath, [], [], valueAtPath, prevAtPath, immediate, 0, whenOptimizedOnlyIf);
588
- }
589
- }
590
- // If not root notify up through parents
591
- if (node.parent) {
592
- const parent = node.parent;
593
- if (parent) {
594
- const parentValue = getNodeValue(parent);
595
- computeChangesRecursive(changesInBatch, parent, loading, remote, parentValue, [node.key].concat(path), [getPathType(value)].concat(pathTypes), valueAtPath, prevAtPath, immediate, level + 1, whenOptimizedOnlyIf);
596
- }
597
- }
551
+ computeChangesAtNode(
552
+ changesInBatch,
553
+ node,
554
+ loading,
555
+ remote,
556
+ value,
557
+ path,
558
+ pathTypes,
559
+ valueAtPath,
560
+ prevAtPath,
561
+ immediate,
562
+ level,
563
+ whenOptimizedOnlyIf
564
+ );
565
+ if (node.linkedFromNodes) {
566
+ for (const linkedFromNode of node.linkedFromNodes) {
567
+ const childNode = getNodeAtPath(linkedFromNode, path);
568
+ computeChangesRecursive(
569
+ changesInBatch,
570
+ childNode,
571
+ loading,
572
+ remote,
573
+ valueAtPath,
574
+ [],
575
+ [],
576
+ valueAtPath,
577
+ prevAtPath,
578
+ immediate,
579
+ 0,
580
+ whenOptimizedOnlyIf
581
+ );
582
+ }
583
+ }
584
+ if (node.parent) {
585
+ const parent = node.parent;
586
+ if (parent) {
587
+ const parentValue = getNodeValue(parent);
588
+ computeChangesRecursive(
589
+ changesInBatch,
590
+ parent,
591
+ loading,
592
+ remote,
593
+ parentValue,
594
+ [node.key].concat(path),
595
+ [getPathType(value)].concat(pathTypes),
596
+ valueAtPath,
597
+ prevAtPath,
598
+ immediate,
599
+ level + 1,
600
+ whenOptimizedOnlyIf
601
+ );
602
+ }
603
+ }
598
604
  }
599
605
  function batchNotifyChanges(changesInBatch, immediate) {
600
- const listenersNotified = new Set();
601
- // For each change in the batch, notify all of the listeners
602
- changesInBatch.forEach(({ changes, level, value, loading, remote, whenOptimizedOnlyIf }, node) => {
603
- const listeners = immediate ? node.listenersImmediate : node.listeners;
604
- if (listeners) {
605
- let listenerParams;
606
- // Need to convert to an array here instead of using a for...of loop because listeners can change while iterating
607
- const arr = Array.from(listeners);
608
- for (let i = 0; i < arr.length; i++) {
609
- const listenerFn = arr[i];
610
- const { track, noArgs, listener } = listenerFn;
611
- if (!listenersNotified.has(listener)) {
612
- const ok = track === true ? level <= 0 : track === optimized ? whenOptimizedOnlyIf && level <= 0 : true;
613
- // Notify if listener is not shallow or if this is the first level
614
- if (ok) {
615
- // Create listenerParams if not already created
616
- if (!noArgs && !listenerParams) {
617
- listenerParams = {
618
- value,
619
- loading,
620
- remote,
621
- getPrevious: createPreviousHandler(value, changes),
622
- changes,
623
- };
624
- }
625
- if (!track) {
626
- listenersNotified.add(listener);
627
- }
628
- listener(listenerParams);
629
- }
630
- }
606
+ const listenersNotified = /* @__PURE__ */ new Set();
607
+ changesInBatch.forEach(({ changes, level, value, loading, remote, whenOptimizedOnlyIf }, node) => {
608
+ const listeners = immediate ? node.listenersImmediate : node.listeners;
609
+ if (listeners) {
610
+ let listenerParams;
611
+ const arr = Array.from(listeners);
612
+ for (let i = 0; i < arr.length; i++) {
613
+ const listenerFn = arr[i];
614
+ const { track, noArgs, listener } = listenerFn;
615
+ if (!listenersNotified.has(listener)) {
616
+ const ok = track === true ? level <= 0 : track === optimized ? whenOptimizedOnlyIf && level <= 0 : true;
617
+ if (ok) {
618
+ if (!noArgs && !listenerParams) {
619
+ listenerParams = {
620
+ value,
621
+ loading,
622
+ remote,
623
+ getPrevious: createPreviousHandler(value, changes),
624
+ changes
625
+ };
631
626
  }
627
+ if (!track) {
628
+ listenersNotified.add(listener);
629
+ }
630
+ listener(listenerParams);
631
+ }
632
632
  }
633
- });
633
+ }
634
+ }
635
+ });
634
636
  }
635
637
  function runBatch() {
636
- const dirtyNodes = Array.from(globalState.dirtyNodes);
637
- globalState.dirtyNodes.clear();
638
- dirtyNodes.forEach((node) => {
639
- const dirtyFn = node.dirtyFn;
640
- if (dirtyFn) {
641
- node.dirtyFn = undefined;
642
- dirtyFn();
643
- }
644
- });
645
- // Save batch locally and reset _batchMap first because a new batch could begin while looping over callbacks.
646
- // This can happen with computeds for example.
647
- const map = _batchMap;
648
- _batchMap = new Map();
649
- const changesInBatch = new Map();
650
- // First compute all of the changes at each node. It's important to do this first before
651
- // running all the notifications because createPreviousHandler depends on knowing
652
- // all of the changes happening at the node.
653
- map.forEach(({ value, prev, level, loading, remote, whenOptimizedOnlyIf }, node) => {
654
- computeChangesRecursive(changesInBatch, node, loading, remote, value, [], [], value, prev, false, level, whenOptimizedOnlyIf);
655
- });
656
- // Once all changes are computed, notify all listeners for each node with the computed changes.
657
- if (changesInBatch.size) {
658
- batchNotifyChanges(changesInBatch, false);
659
- }
638
+ const dirtyNodes = Array.from(globalState.dirtyNodes);
639
+ globalState.dirtyNodes.clear();
640
+ dirtyNodes.forEach((node) => {
641
+ const dirtyFn = node.dirtyFn;
642
+ if (dirtyFn) {
643
+ node.dirtyFn = void 0;
644
+ dirtyFn();
645
+ }
646
+ });
647
+ const map = _batchMap;
648
+ _batchMap = /* @__PURE__ */ new Map();
649
+ const changesInBatch = /* @__PURE__ */ new Map();
650
+ map.forEach(({ value, prev, level, loading, remote, whenOptimizedOnlyIf }, node) => {
651
+ computeChangesRecursive(
652
+ changesInBatch,
653
+ node,
654
+ loading,
655
+ remote,
656
+ value,
657
+ [],
658
+ [],
659
+ value,
660
+ prev,
661
+ false,
662
+ level,
663
+ whenOptimizedOnlyIf
664
+ );
665
+ });
666
+ if (changesInBatch.size) {
667
+ batchNotifyChanges(changesInBatch, false);
668
+ }
660
669
  }
661
670
  function batch(fn) {
662
- beginBatch();
663
- try {
664
- fn();
665
- }
666
- finally {
667
- endBatch();
668
- }
671
+ beginBatch();
672
+ try {
673
+ fn();
674
+ } finally {
675
+ endBatch();
676
+ }
669
677
  }
670
678
  function beginBatch() {
671
- numInBatch++;
672
- if (!timeout) {
673
- timeout = setTimeout(onActionTimeout, 0);
674
- }
679
+ numInBatch++;
680
+ if (!timeout) {
681
+ timeout = setTimeout(onActionTimeout, 0);
682
+ }
675
683
  }
676
684
  function endBatch(force) {
677
- numInBatch--;
678
- if (numInBatch <= 0 || force) {
679
- if (isRunningBatch) {
680
- // Don't want to run multiple endBatches recursively, so just note that an endBatch
681
- // was delayed so that the top level endBatch will run endBatch again after it's done.
682
- didDelayEndBatch = true;
683
- }
684
- else {
685
- if (timeout) {
686
- clearTimeout(timeout);
687
- timeout = undefined;
688
- }
689
- numInBatch = 0;
690
- isRunningBatch = true;
691
- runBatch();
692
- isRunningBatch = false;
693
- // If an endBatch was delayed run it now
694
- if (didDelayEndBatch) {
695
- didDelayEndBatch = false;
696
- endBatch(true);
697
- }
698
- }
699
- }
685
+ numInBatch--;
686
+ if (numInBatch <= 0 || force) {
687
+ if (isRunningBatch) {
688
+ didDelayEndBatch = true;
689
+ } else {
690
+ if (timeout) {
691
+ clearTimeout(timeout);
692
+ timeout = void 0;
693
+ }
694
+ numInBatch = 0;
695
+ isRunningBatch = true;
696
+ runBatch();
697
+ isRunningBatch = false;
698
+ if (didDelayEndBatch) {
699
+ didDelayEndBatch = false;
700
+ endBatch(true);
701
+ }
702
+ }
703
+ }
700
704
  }
701
705
  function getNodeAtPath(obj, path) {
702
- let o = obj;
703
- for (let i = 0; i < path.length; i++) {
704
- const p = path[i];
705
- o = getChildNode(o, p);
706
- }
707
- return o;
706
+ let o = obj;
707
+ for (let i = 0; i < path.length; i++) {
708
+ const p = path[i];
709
+ o = getChildNode(o, p);
710
+ }
711
+ return o;
708
712
  }
709
713
 
714
+ // src/linked.ts
710
715
  function linked(params, options) {
711
- if (isFunction(params)) {
712
- params = { get: params };
713
- }
714
- if (options) {
715
- params = { ...params, ...options };
716
- }
717
- const ret = function () {
718
- return { [symbolLinked]: params };
719
- };
720
- ret.prototype[symbolLinked] = params;
721
- return ret;
716
+ if (isFunction(params)) {
717
+ params = { get: params };
718
+ }
719
+ if (options) {
720
+ params = { ...params, ...options };
721
+ }
722
+ const ret = function() {
723
+ return { [symbolLinked]: params };
724
+ };
725
+ ret.prototype[symbolLinked] = params;
726
+ return ret;
722
727
  }
723
728
 
724
- function createObservable(value, makePrimitive, extractPromise, createObject, createPrimitive) {
725
- if (isObservable(value)) {
726
- return value;
727
- }
728
- const valueIsPromise = isPromise(value);
729
- const valueIsFunction = isFunction(value);
730
- const root = {
731
- _: value,
732
- };
733
- let node = {
734
- root,
735
- lazy: true,
736
- numListenersRecursive: 0,
737
- };
738
- if (valueIsFunction) {
739
- node = Object.assign(() => { }, node);
740
- node.lazyFn = value;
741
- }
742
- const prim = makePrimitive || isActualPrimitive(value);
743
- const obs = prim
744
- ? new createPrimitive(node)
745
- : createObject(node);
746
- if (valueIsPromise) {
747
- setNodeValue(node, undefined);
748
- extractPromise(node, value);
749
- }
750
- return obs;
729
+ // src/createObservable.ts
730
+ function createObservable(value, makePrimitive, extractPromise2, createObject, createPrimitive) {
731
+ if (isObservable(value)) {
732
+ return value;
733
+ }
734
+ const valueIsPromise = isPromise(value);
735
+ const valueIsFunction = isFunction(value);
736
+ const root = {
737
+ _: value
738
+ };
739
+ let node = {
740
+ root,
741
+ lazy: true,
742
+ numListenersRecursive: 0
743
+ };
744
+ if (valueIsFunction) {
745
+ node = Object.assign(() => {
746
+ }, node);
747
+ node.lazyFn = value;
748
+ }
749
+ const prim = makePrimitive || isActualPrimitive(value);
750
+ const obs = prim ? new createPrimitive(node) : createObject(node);
751
+ if (valueIsPromise) {
752
+ setNodeValue(node, void 0);
753
+ extractPromise2(node, value);
754
+ }
755
+ return obs;
751
756
  }
752
757
 
758
+ // src/onChange.ts
753
759
  function onChange(node, callback, options = {}, fromLinks) {
754
- var _a;
755
- const { initial, immediate, noArgs } = options;
756
- const { trackingType } = options;
757
- let listeners = immediate ? node.listenersImmediate : node.listeners;
758
- if (!listeners) {
759
- listeners = new Set();
760
- if (immediate) {
761
- node.listenersImmediate = listeners;
762
- }
763
- else {
764
- node.listeners = listeners;
765
- }
766
- }
767
- const listener = {
768
- listener: callback,
769
- track: trackingType,
770
- noArgs,
771
- };
772
- listeners.add(listener);
773
- if (initial) {
774
- const value = getNodeValue(node);
775
- callback({
776
- value,
777
- loading: true,
778
- remote: false,
779
- changes: [
780
- {
781
- path: [],
782
- pathTypes: [],
783
- prevAtPath: value,
784
- valueAtPath: value,
785
- },
786
- ],
787
- getPrevious: () => undefined,
788
- });
789
- }
790
- let extraDisposes;
791
- function addLinkedNodeListeners(childNode, cb = callback, from) {
792
- // Don't add listeners for the same node more than once
793
- if (!(fromLinks === null || fromLinks === void 0 ? void 0 : fromLinks.has(childNode))) {
794
- fromLinks || (fromLinks = new Set());
795
- fromLinks.add(from || node);
796
- cb || (cb = callback);
797
- const childOptions = {
798
- trackingType: true,
799
- ...options,
800
- };
801
- // onChange for the linked node
802
- extraDisposes = [...(extraDisposes || []), onChange(childNode, cb, childOptions, fromLinks)];
803
- }
804
- }
805
- // Add listeners for linked to nodes
806
- if (node.linkedToNode) {
807
- addLinkedNodeListeners(node.linkedToNode);
808
- }
809
- // Add listeners for linked from nodes
810
- (_a = node.linkedFromNodes) === null || _a === void 0 ? void 0 : _a.forEach((linkedFromNode) => addLinkedNodeListeners(linkedFromNode));
811
- // Go up through the parents and add listeners for linked from nodes
812
- node.numListenersRecursive++;
813
- let parent = node.parent;
814
- let pathParent = [node.key];
815
- while (parent) {
816
- if (parent.linkedFromNodes) {
817
- for (const linkedFromNode of parent.linkedFromNodes) {
818
- if (!(fromLinks === null || fromLinks === void 0 ? void 0 : fromLinks.has(linkedFromNode))) {
819
- const cb = createCb(linkedFromNode, pathParent, callback);
820
- addLinkedNodeListeners(linkedFromNode, cb, parent);
821
- }
822
- }
823
- }
824
- parent.numListenersRecursive++;
825
- pathParent = [parent.key, ...pathParent];
826
- parent = parent.parent;
827
- }
828
- return () => {
829
- listeners.delete(listener);
830
- extraDisposes === null || extraDisposes === void 0 ? void 0 : extraDisposes.forEach((fn) => fn());
831
- let parent = node;
832
- while (parent) {
833
- parent.numListenersRecursive--;
834
- parent = parent.parent;
835
- }
836
- };
760
+ var _a;
761
+ const { initial, immediate, noArgs } = options;
762
+ const { trackingType } = options;
763
+ let listeners = immediate ? node.listenersImmediate : node.listeners;
764
+ if (!listeners) {
765
+ listeners = /* @__PURE__ */ new Set();
766
+ if (immediate) {
767
+ node.listenersImmediate = listeners;
768
+ } else {
769
+ node.listeners = listeners;
770
+ }
771
+ }
772
+ const listener = {
773
+ listener: callback,
774
+ track: trackingType,
775
+ noArgs
776
+ };
777
+ listeners.add(listener);
778
+ if (initial) {
779
+ const value = getNodeValue(node);
780
+ callback({
781
+ value,
782
+ loading: true,
783
+ remote: false,
784
+ changes: [
785
+ {
786
+ path: [],
787
+ pathTypes: [],
788
+ prevAtPath: value,
789
+ valueAtPath: value
790
+ }
791
+ ],
792
+ getPrevious: () => void 0
793
+ });
794
+ }
795
+ let extraDisposes;
796
+ function addLinkedNodeListeners(childNode, cb = callback, from) {
797
+ if (!(fromLinks == null ? void 0 : fromLinks.has(childNode))) {
798
+ fromLinks || (fromLinks = /* @__PURE__ */ new Set());
799
+ fromLinks.add(from || node);
800
+ cb || (cb = callback);
801
+ const childOptions = {
802
+ trackingType: true,
803
+ ...options
804
+ };
805
+ extraDisposes = [...extraDisposes || [], onChange(childNode, cb, childOptions, fromLinks)];
806
+ }
807
+ }
808
+ if (node.linkedToNode) {
809
+ addLinkedNodeListeners(node.linkedToNode);
810
+ }
811
+ (_a = node.linkedFromNodes) == null ? void 0 : _a.forEach((linkedFromNode) => addLinkedNodeListeners(linkedFromNode));
812
+ node.numListenersRecursive++;
813
+ let parent = node.parent;
814
+ let pathParent = [node.key];
815
+ while (parent) {
816
+ if (parent.linkedFromNodes) {
817
+ for (const linkedFromNode of parent.linkedFromNodes) {
818
+ if (!(fromLinks == null ? void 0 : fromLinks.has(linkedFromNode))) {
819
+ const cb = createCb(linkedFromNode, pathParent, callback);
820
+ addLinkedNodeListeners(linkedFromNode, cb, parent);
821
+ }
822
+ }
823
+ }
824
+ parent.numListenersRecursive++;
825
+ pathParent = [parent.key, ...pathParent];
826
+ parent = parent.parent;
827
+ }
828
+ return () => {
829
+ listeners.delete(listener);
830
+ extraDisposes == null ? void 0 : extraDisposes.forEach((fn) => fn());
831
+ let parent2 = node;
832
+ while (parent2) {
833
+ parent2.numListenersRecursive--;
834
+ parent2 = parent2.parent;
835
+ }
836
+ };
837
837
  }
838
838
  function createCb(linkedFromNode, path, callback) {
839
- // Create a callback for a path that calls it with the current value at the path
840
- let { valueAtPath: prevAtPath } = getValueAtPath(getNodeValue(linkedFromNode), path);
841
- return function ({ value: valueA, loading, remote }) {
842
- const { valueAtPath } = getValueAtPath(valueA, path);
843
- if (valueAtPath !== prevAtPath) {
844
- callback({
845
- value: valueAtPath,
846
- loading,
847
- remote,
848
- changes: [
849
- {
850
- path: [],
851
- pathTypes: [],
852
- prevAtPath,
853
- valueAtPath,
854
- },
855
- ],
856
- getPrevious: () => prevAtPath,
857
- });
858
- }
859
- prevAtPath = valueAtPath;
860
- };
861
- }
862
- function getValueAtPath(obj, path) {
863
- let o = obj;
864
- const pathTypes = [];
865
- for (let i = 0; o && i < path.length; i++) {
866
- pathTypes.push(isArray(o) ? 'array' : 'object');
867
- const p = path[i];
868
- o = o[p];
869
- }
870
- return { valueAtPath: o, pathTypes };
839
+ let { valueAtPath: prevAtPath } = getValueAtPath2(getNodeValue(linkedFromNode), path);
840
+ return function({ value: valueA, loading, remote }) {
841
+ const { valueAtPath } = getValueAtPath2(valueA, path);
842
+ if (valueAtPath !== prevAtPath) {
843
+ callback({
844
+ value: valueAtPath,
845
+ loading,
846
+ remote,
847
+ changes: [
848
+ {
849
+ path: [],
850
+ pathTypes: [],
851
+ prevAtPath,
852
+ valueAtPath
853
+ }
854
+ ],
855
+ getPrevious: () => prevAtPath
856
+ });
857
+ }
858
+ prevAtPath = valueAtPath;
859
+ };
860
+ }
861
+ function getValueAtPath2(obj, path) {
862
+ let o = obj;
863
+ const pathTypes = [];
864
+ for (let i = 0; o && i < path.length; i++) {
865
+ pathTypes.push(isArray(o) ? "array" : "object");
866
+ const p = path[i];
867
+ o = o[p];
868
+ }
869
+ return { valueAtPath: o, pathTypes };
871
870
  }
872
871
 
872
+ // src/setupTracking.ts
873
873
  function setupTracking(nodes, update, noArgs, immediate) {
874
- let listeners = [];
875
- // Listen to tracked nodes
876
- nodes === null || nodes === void 0 ? void 0 : nodes.forEach((tracked) => {
877
- const { node, track } = tracked;
878
- listeners.push(onChange(node, update, { trackingType: track, immediate, noArgs }));
879
- });
880
- return () => {
881
- if (listeners) {
882
- for (let i = 0; i < listeners.length; i++) {
883
- listeners[i]();
884
- }
885
- listeners = undefined;
886
- }
887
- };
874
+ let listeners = [];
875
+ nodes == null ? void 0 : nodes.forEach((tracked) => {
876
+ const { node, track } = tracked;
877
+ listeners.push(onChange(node, update, { trackingType: track, immediate, noArgs }));
878
+ });
879
+ return () => {
880
+ if (listeners) {
881
+ for (let i = 0; i < listeners.length; i++) {
882
+ listeners[i]();
883
+ }
884
+ listeners = void 0;
885
+ }
886
+ };
888
887
  }
889
888
 
890
- let trackCount = 0;
891
- const trackingQueue = [];
892
- const tracking = {
893
- current: undefined,
889
+ // src/tracking.ts
890
+ var trackCount = 0;
891
+ var trackingQueue = [];
892
+ var tracking = {
893
+ current: void 0
894
894
  };
895
895
  function beginTracking() {
896
- // Keep a copy of the previous tracking context so it can be restored
897
- // when this context is complete
898
- trackingQueue.push(tracking.current);
899
- trackCount++;
900
- tracking.current = {};
896
+ trackingQueue.push(tracking.current);
897
+ trackCount++;
898
+ tracking.current = {};
901
899
  }
902
900
  function endTracking() {
903
- // Restore the previous tracking context
904
- trackCount--;
905
- if (trackCount < 0) {
906
- trackCount = 0;
907
- }
908
- tracking.current = trackingQueue.pop();
901
+ trackCount--;
902
+ if (trackCount < 0) {
903
+ trackCount = 0;
904
+ }
905
+ tracking.current = trackingQueue.pop();
909
906
  }
910
907
  function updateTracking(node, track) {
911
- if (trackCount) {
912
- const tracker = tracking.current;
913
- if (tracker) {
914
- if (!tracker.nodes) {
915
- tracker.nodes = new Map();
916
- }
917
- const existing = tracker.nodes.get(node);
918
- if (existing) {
919
- existing.track = existing.track || track;
920
- existing.num++;
921
- }
922
- else {
923
- tracker.nodes.set(node, { node, track, num: 1 });
924
- }
925
- }
926
- }
908
+ if (trackCount) {
909
+ const tracker = tracking.current;
910
+ if (tracker) {
911
+ if (!tracker.nodes) {
912
+ tracker.nodes = /* @__PURE__ */ new Map();
913
+ }
914
+ const existing = tracker.nodes.get(node);
915
+ if (existing) {
916
+ existing.track = existing.track || track;
917
+ existing.num++;
918
+ } else {
919
+ tracker.nodes.set(node, { node, track, num: 1 });
920
+ }
921
+ }
922
+ }
927
923
  }
928
924
 
925
+ // src/trackSelector.ts
929
926
  function trackSelector(selector, update, observeEvent, observeOptions, createResubscribe) {
930
- var _a;
931
- let dispose;
932
- let resubscribe;
933
- let updateFn = update;
934
- beginTracking();
935
- const value = selector ? computeSelector(selector, observeEvent, observeOptions === null || observeOptions === void 0 ? void 0 : observeOptions.fromComputed) : selector;
936
- const tracker = tracking.current;
937
- const nodes = tracker.nodes;
938
- endTracking();
939
- if ((process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') && tracker && nodes) {
940
- (_a = tracker.traceListeners) === null || _a === void 0 ? void 0 : _a.call(tracker, nodes);
941
- if (tracker.traceUpdates) {
942
- updateFn = tracker.traceUpdates(update);
943
- }
944
- // Clear tracing so it doesn't leak to other components
945
- tracker.traceListeners = undefined;
946
- tracker.traceUpdates = undefined;
947
- }
948
- if (!(observeEvent === null || observeEvent === void 0 ? void 0 : observeEvent.cancel)) {
949
- // Do tracing if it was requested
950
- // useSyncExternalStore doesn't subscribe until after the component mount.
951
- // We want to subscribe immediately so we don't miss any updates
952
- dispose = setupTracking(nodes, updateFn, false, observeOptions === null || observeOptions === void 0 ? void 0 : observeOptions.immediate);
953
- if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
954
- resubscribe = createResubscribe
955
- ? () => {
956
- dispose === null || dispose === void 0 ? void 0 : dispose();
957
- dispose = setupTracking(nodes, updateFn);
958
- return dispose;
959
- }
960
- : undefined;
961
- }
962
- }
963
- return { nodes, value, dispose, resubscribe };
927
+ var _a;
928
+ let dispose;
929
+ let resubscribe;
930
+ let updateFn = update;
931
+ beginTracking();
932
+ const value = selector ? computeSelector(selector, observeEvent, observeOptions == null ? void 0 : observeOptions.fromComputed) : selector;
933
+ const tracker = tracking.current;
934
+ const nodes = tracker.nodes;
935
+ endTracking();
936
+ if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && tracker && nodes) {
937
+ (_a = tracker.traceListeners) == null ? void 0 : _a.call(tracker, nodes);
938
+ if (tracker.traceUpdates) {
939
+ updateFn = tracker.traceUpdates(update);
940
+ }
941
+ tracker.traceListeners = void 0;
942
+ tracker.traceUpdates = void 0;
943
+ }
944
+ if (!(observeEvent == null ? void 0 : observeEvent.cancel)) {
945
+ dispose = setupTracking(nodes, updateFn, false, observeOptions == null ? void 0 : observeOptions.immediate);
946
+ if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") {
947
+ resubscribe = createResubscribe ? () => {
948
+ dispose == null ? void 0 : dispose();
949
+ dispose = setupTracking(nodes, updateFn);
950
+ return dispose;
951
+ } : void 0;
952
+ }
953
+ }
954
+ return { nodes, value, dispose, resubscribe };
964
955
  }
965
956
 
957
+ // src/observe.ts
966
958
  function observe(selectorOrRun, reactionOrOptions, options) {
967
- let reaction;
968
- if (isFunction(reactionOrOptions)) {
969
- reaction = reactionOrOptions;
970
- }
971
- else {
972
- options = reactionOrOptions;
973
- }
974
- let dispose;
975
- const e = { num: 0 };
976
- // Wrap it in a function so it doesn't pass all the arguments to run()
977
- const update = function () {
978
- if (e.onCleanup) {
979
- e.onCleanup();
980
- e.onCleanup = undefined;
981
- }
982
- // Run in a batch so changes don't happen until we're done tracking here
983
- beginBatch();
984
- // Run the function/selector
985
- delete e.value;
986
- // Dispose listeners from previous run
987
- dispose === null || dispose === void 0 ? void 0 : dispose();
988
- const { dispose: _dispose, value, nodes } = trackSelector(selectorOrRun, update, e, options);
989
- dispose = _dispose;
990
- e.value = value;
991
- e.nodes = nodes;
992
- e.refresh = update;
993
- if (e.onCleanupReaction) {
994
- e.onCleanupReaction();
995
- e.onCleanupReaction = undefined;
996
- }
997
- endBatch();
998
- // Call the reaction if there is one and the value changed
999
- if (reaction &&
1000
- ((options === null || options === void 0 ? void 0 : options.fromComputed) ||
1001
- ((e.num > 0 || !isEvent(selectorOrRun)) &&
1002
- (e.previous !== e.value || typeof e.value === 'object')))) {
1003
- reaction(e);
1004
- }
1005
- // Update the previous value
1006
- e.previous = e.value;
1007
- // Increment the counter
1008
- e.num++;
1009
- };
1010
- update();
1011
- // Return function calling dispose because dispose may be changed in update()
1012
- return () => {
1013
- var _a, _b;
1014
- (_a = e.onCleanup) === null || _a === void 0 ? void 0 : _a.call(e);
1015
- e.onCleanup = undefined;
1016
- (_b = e.onCleanupReaction) === null || _b === void 0 ? void 0 : _b.call(e);
1017
- e.onCleanupReaction = undefined;
1018
- dispose === null || dispose === void 0 ? void 0 : dispose();
1019
- };
959
+ let reaction;
960
+ if (isFunction(reactionOrOptions)) {
961
+ reaction = reactionOrOptions;
962
+ } else {
963
+ options = reactionOrOptions;
964
+ }
965
+ let dispose;
966
+ const e = { num: 0 };
967
+ const update = function() {
968
+ if (e.onCleanup) {
969
+ e.onCleanup();
970
+ e.onCleanup = void 0;
971
+ }
972
+ beginBatch();
973
+ delete e.value;
974
+ dispose == null ? void 0 : dispose();
975
+ const { dispose: _dispose, value, nodes } = trackSelector(selectorOrRun, update, e, options);
976
+ dispose = _dispose;
977
+ e.value = value;
978
+ e.nodes = nodes;
979
+ e.refresh = update;
980
+ if (e.onCleanupReaction) {
981
+ e.onCleanupReaction();
982
+ e.onCleanupReaction = void 0;
983
+ }
984
+ endBatch();
985
+ if (reaction && ((options == null ? void 0 : options.fromComputed) || (e.num > 0 || !isEvent(selectorOrRun)) && (e.previous !== e.value || typeof e.value === "object"))) {
986
+ reaction(e);
987
+ }
988
+ e.previous = e.value;
989
+ e.num++;
990
+ };
991
+ update();
992
+ return () => {
993
+ var _a, _b;
994
+ (_a = e.onCleanup) == null ? void 0 : _a.call(e);
995
+ e.onCleanup = void 0;
996
+ (_b = e.onCleanupReaction) == null ? void 0 : _b.call(e);
997
+ e.onCleanupReaction = void 0;
998
+ dispose == null ? void 0 : dispose();
999
+ };
1020
1000
  }
1021
1001
 
1002
+ // src/when.ts
1022
1003
  function _when(predicate, effect, checkReady) {
1023
- // If predicate is a regular Promise skip all the observable stuff
1024
- if (isPromise(predicate)) {
1025
- return effect ? predicate.then(effect) : predicate;
1026
- }
1027
- let value;
1028
- let effectValue;
1029
- // Create a wrapping fn that calls the effect if predicate returns true
1030
- function run(e) {
1031
- const ret = computeSelector(predicate);
1032
- if (isPromise(ret)) {
1033
- value = ret;
1034
- // We want value to be the Promise but return undefined
1035
- // so it doesn't run the effect with the Promise as the value
1036
- return undefined;
1037
- }
1038
- else if (!isPromise(ret) && (checkReady ? isObservableValueReady(ret) : ret)) {
1039
- value = ret;
1040
- // Set cancel so that observe does not track anymore
1041
- e.cancel = true;
1042
- }
1043
- return value;
1044
- }
1045
- function doEffect() {
1046
- // If value is truthy then run the effect
1047
- effectValue = effect === null || effect === void 0 ? void 0 : effect(value);
1048
- }
1049
- // Run in an observe
1050
- observe(run, doEffect);
1051
- // If first run resulted in a truthy value just return it.
1052
- // It will have set e.cancel so no need to dispose
1053
- if (isPromise(value)) {
1054
- return effect ? value.then(effect) : value;
1055
- }
1056
- else if (value !== undefined) {
1057
- return effect ? effectValue : Promise.resolve(value);
1058
- }
1059
- else {
1060
- // Wrap it in a promise
1061
- const promise = new Promise((resolve) => {
1062
- if (effect) {
1063
- const originalEffect = effect;
1064
- effect = ((value) => {
1065
- const effectValue = originalEffect(value);
1066
- resolve(isPromise(effectValue) ? effectValue.then((value) => value) : effectValue);
1067
- });
1068
- }
1069
- else {
1070
- effect = resolve;
1071
- }
1072
- });
1073
- return promise;
1004
+ if (isPromise(predicate)) {
1005
+ return effect ? predicate.then(effect) : predicate;
1006
+ }
1007
+ let value;
1008
+ let effectValue;
1009
+ function run(e) {
1010
+ const ret = computeSelector(predicate);
1011
+ if (isPromise(ret)) {
1012
+ value = ret;
1013
+ return void 0;
1014
+ } else if (!isPromise(ret) && (checkReady ? isObservableValueReady(ret) : ret)) {
1015
+ value = ret;
1016
+ e.cancel = true;
1074
1017
  }
1018
+ return value;
1019
+ }
1020
+ function doEffect() {
1021
+ effectValue = effect == null ? void 0 : effect(value);
1022
+ }
1023
+ observe(run, doEffect);
1024
+ if (isPromise(value)) {
1025
+ return effect ? value.then(effect) : value;
1026
+ } else if (value !== void 0) {
1027
+ return effect ? effectValue : Promise.resolve(value);
1028
+ } else {
1029
+ const promise = new Promise((resolve) => {
1030
+ if (effect) {
1031
+ const originalEffect = effect;
1032
+ effect = (value2) => {
1033
+ const effectValue2 = originalEffect(value2);
1034
+ resolve(isPromise(effectValue2) ? effectValue2.then((value3) => value3) : effectValue2);
1035
+ };
1036
+ } else {
1037
+ effect = resolve;
1038
+ }
1039
+ });
1040
+ return promise;
1041
+ }
1075
1042
  }
1076
1043
  function when(predicate, effect) {
1077
- return _when(predicate, effect, false);
1044
+ return _when(predicate, effect, false);
1078
1045
  }
1079
1046
  function whenReady(predicate, effect) {
1080
- return _when(predicate, effect, true);
1047
+ return _when(predicate, effect, true);
1081
1048
  }
1082
1049
 
1083
- const ArrayModifiers = new Set([
1084
- 'copyWithin',
1085
- 'fill',
1086
- 'from',
1087
- 'pop',
1088
- 'push',
1089
- 'reverse',
1090
- 'shift',
1091
- 'sort',
1092
- 'splice',
1093
- 'unshift',
1050
+ // src/ObservableObject.ts
1051
+ var ArrayModifiers = /* @__PURE__ */ new Set([
1052
+ "copyWithin",
1053
+ "fill",
1054
+ "from",
1055
+ "pop",
1056
+ "push",
1057
+ "reverse",
1058
+ "shift",
1059
+ "sort",
1060
+ "splice",
1061
+ "unshift"
1094
1062
  ]);
1095
- const ArrayLoopers = new Set([
1096
- 'every',
1097
- 'filter',
1098
- 'find',
1099
- 'findIndex',
1100
- 'forEach',
1101
- 'join',
1102
- 'map',
1103
- 'reduce',
1104
- 'some',
1063
+ var ArrayLoopers = /* @__PURE__ */ new Set([
1064
+ "every",
1065
+ "filter",
1066
+ "find",
1067
+ "findIndex",
1068
+ "forEach",
1069
+ "join",
1070
+ "map",
1071
+ "reduce",
1072
+ "some"
1105
1073
  ]);
1106
- const ArrayLoopersReturn = new Set(['filter', 'find']);
1107
- const observableProperties = new Map();
1108
- const observableFns = new Map([
1109
- ['get', get],
1110
- ['set', set],
1111
- ['peek', peek],
1112
- ['onChange', onChange],
1113
- ['assign', assign],
1114
- ['delete', deleteFn],
1115
- ['toggle', toggle],
1074
+ var ArrayLoopersReturn = /* @__PURE__ */ new Set(["filter", "find"]);
1075
+ var observableProperties = /* @__PURE__ */ new Map();
1076
+ var observableFns = /* @__PURE__ */ new Map([
1077
+ ["get", get],
1078
+ ["set", set],
1079
+ ["peek", peek],
1080
+ ["onChange", onChange],
1081
+ ["assign", assign],
1082
+ ["delete", deleteFn],
1083
+ ["toggle", toggle]
1116
1084
  ]);
1117
- if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
1118
- // eslint-disable-next-line no-var
1119
- var __devUpdateNodes = new Set();
1085
+ if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") {
1086
+ __devUpdateNodes = /* @__PURE__ */ new Set();
1120
1087
  }
1088
+ var __devUpdateNodes;
1121
1089
  function collectionSetter(node, target, prop, ...args) {
1122
- var _a;
1123
- if (prop === 'push' && args.length === 1) {
1124
- // Fast path for push to just append to the end
1125
- setKey(node, target.length + '', args[0]);
1126
- }
1127
- else {
1128
- const prevValue = target.slice();
1129
- const ret = target[prop].apply(target, args);
1130
- if (node) {
1131
- const hasParent = isChildNodeValue(node);
1132
- const key = hasParent ? node.key : '_';
1133
- const parentValue = hasParent ? getNodeValue(node.parent) : node.root;
1134
- // Set the object to the previous value first
1135
- parentValue[key] = prevValue;
1136
- // Then set with the new value so it notifies with the correct prevValue
1137
- setKey((_a = node.parent) !== null && _a !== void 0 ? _a : node, key, target);
1138
- }
1139
- // Return the original value
1140
- return ret;
1090
+ var _a;
1091
+ if (prop === "push" && args.length === 1) {
1092
+ setKey(node, target.length + "", args[0]);
1093
+ } else {
1094
+ const prevValue = target.slice();
1095
+ const ret = target[prop].apply(target, args);
1096
+ if (node) {
1097
+ const hasParent = isChildNodeValue(node);
1098
+ const key = hasParent ? node.key : "_";
1099
+ const parentValue = hasParent ? getNodeValue(node.parent) : node.root;
1100
+ parentValue[key] = prevValue;
1101
+ setKey((_a = node.parent) != null ? _a : node, key, target);
1141
1102
  }
1103
+ return ret;
1104
+ }
1142
1105
  }
1143
- function getKeys(obj, isArr, isMap) {
1144
- return isArr ? undefined : obj ? (isMap ? Array.from(obj.keys()) : Object.keys(obj)) : [];
1106
+ function getKeys(obj, isArr, isMap2) {
1107
+ return isArr ? void 0 : obj ? isMap2 ? Array.from(obj.keys()) : Object.keys(obj) : [];
1145
1108
  }
1146
1109
  function updateNodes(parent, obj, prevValue) {
1147
- var _a, _b, _c;
1148
- if ((process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') &&
1149
- typeof __devUpdateNodes !== 'undefined' &&
1150
- isObject(obj)) {
1151
- if (__devUpdateNodes.has(obj)) {
1152
- console.error('[legend-state] Circular reference detected in object. You may want to use opaqueObject to stop traversing child nodes.', obj);
1153
- return false;
1154
- }
1155
- __devUpdateNodes.add(obj);
1156
- }
1157
- if ((isObject(obj) && obj[symbolOpaque]) ||
1158
- (isObject(prevValue) && prevValue[symbolOpaque])) {
1159
- const isDiff = obj !== prevValue;
1160
- if (isDiff) {
1161
- if (parent.listeners || parent.listenersImmediate) {
1162
- notify(parent, obj, prevValue, 0);
1163
- }
1164
- }
1165
- if ((process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') &&
1166
- typeof __devUpdateNodes !== 'undefined' &&
1167
- obj !== undefined) {
1168
- __devUpdateNodes.delete(obj);
1169
- }
1170
- return isDiff;
1171
- }
1172
- const isArr = isArray(obj);
1173
- let prevChildrenById;
1174
- let moved;
1175
- const isCurMap = isMap(obj);
1176
- const isPrevMap = isMap(prevValue);
1177
- const keys = getKeys(obj, isArr, isCurMap);
1178
- const keysPrev = getKeys(prevValue, isArr, isPrevMap);
1179
- const length = ((_a = (keys || obj)) === null || _a === void 0 ? void 0 : _a.length) || 0;
1180
- const lengthPrev = ((_b = (keysPrev || prevValue)) === null || _b === void 0 ? void 0 : _b.length) || 0;
1181
- let idField;
1182
- let isIdFieldFunction;
1183
- let hasADiff = false;
1184
- let retValue;
1185
- if (isArr && isArray(prevValue)) {
1186
- // Construct a map of previous indices for computing move
1187
- if (prevValue.length > 0) {
1188
- const firstPrevValue = prevValue[0];
1189
- if (firstPrevValue !== undefined) {
1190
- idField = findIDKey(firstPrevValue, parent);
1191
- if (idField) {
1192
- isIdFieldFunction = isFunction(idField);
1193
- prevChildrenById = new Map();
1194
- moved = [];
1195
- }
1196
- const keysSeen = process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test'
1197
- ? new Set()
1198
- : undefined;
1199
- if (parent.children) {
1200
- for (let i = 0; i < prevValue.length; i++) {
1201
- const p = prevValue[i];
1202
- if (p) {
1203
- const child = parent.children.get(i + '');
1204
- if (child) {
1205
- if (!obj[i]) {
1206
- // If the previous value is not in the new array and it
1207
- // is an activated, disable its listeners
1208
- handleDeletedChild(child, p);
1209
- }
1210
- if (idField) {
1211
- const key = isIdFieldFunction
1212
- ? idField(p)
1213
- : p[idField];
1214
- if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
1215
- if (keysSeen.has(key)) {
1216
- console.warn(`[legend-state] Warning: Multiple elements in array have the same ID. Key field: ${idField}, Array:`, prevValue);
1217
- }
1218
- keysSeen.add(key);
1219
- }
1220
- prevChildrenById.set(key, child);
1221
- }
1222
- }
1223
- }
1224
- }
1225
- }
1226
- }
1227
- }
1228
- }
1229
- else if (prevValue && (!obj || isObject(obj))) {
1230
- // For keys that have been removed from object, notify and update children recursively
1231
- const lengthPrev = keysPrev.length;
1232
- for (let i = 0; i < lengthPrev; i++) {
1233
- const key = keysPrev[i];
1234
- if (!keys.includes(key)) {
1235
- hasADiff = true;
1236
- const child = getChildNode(parent, key);
1237
- const prev = isPrevMap ? prevValue.get(key) : prevValue[key];
1238
- if (prev !== undefined) {
1239
- handleDeletedChild(child, prev);
1240
- }
1241
- }
1242
- }
1243
- }
1244
- if (obj && !isPrimitive(obj)) {
1245
- hasADiff = hasADiff || length !== lengthPrev;
1246
- const isArrDiff = hasADiff;
1247
- let didMove = false;
1248
- for (let i = 0; i < length; i++) {
1249
- const key = isArr ? i + '' : keys[i];
1250
- let value = isCurMap ? obj.get(key) : obj[key];
1251
- const prev = isPrevMap ? prevValue === null || prevValue === void 0 ? void 0 : prevValue.get(key) : prevValue === null || prevValue === void 0 ? void 0 : prevValue[key];
1252
- let isDiff = !equals(value, prev);
1253
- if (isDiff) {
1254
- const id = idField && value
1255
- ? isIdFieldFunction
1256
- ? idField(value)
1257
- : value[idField]
1258
- : undefined;
1259
- const existingChild = (_c = parent.children) === null || _c === void 0 ? void 0 : _c.get(key);
1260
- if (isObservable(value)) {
1261
- const valueNode = getNode(value);
1262
- if ((existingChild === null || existingChild === void 0 ? void 0 : existingChild.linkedToNode) === valueNode) {
1263
- const targetValue = getNodeValue(valueNode);
1264
- isCurMap ? obj.set(key, targetValue) : (obj[key] = targetValue);
1265
- continue;
1266
- }
1267
- const obs = value;
1268
- value = () => obs;
1269
- }
1270
- let child = getChildNode(parent, key, value);
1271
- if (!child.lazy && (isFunction(value) || isObservable(value))) {
1272
- reactivateNode(child, value);
1273
- peekInternal(child);
1274
- }
1275
- // Detect moves within an array. Need to move the original proxy to the new position to keep
1276
- // the proxy stable, so that listeners to this node will be unaffected by the array shift.
1277
- if (isArr && id !== undefined) {
1278
- // Find the previous position of this element in the array
1279
- const prevChild = id !== undefined ? prevChildrenById === null || prevChildrenById === void 0 ? void 0 : prevChildrenById.get(id) : undefined;
1280
- if (!prevChild) {
1281
- // This id was not in the array before so it does not need to notify children
1282
- // It does need to notify itself so isDiff should remain.
1283
- hasADiff = true;
1284
- }
1285
- else if (prevChild !== undefined && prevChild.key !== key) {
1286
- const valuePrevChild = prevValue[prevChild.key];
1287
- // If array length changed then move the original node to the current position.
1288
- // That should be faster than notifying every single element that
1289
- // it's in a new position.
1290
- if (isArrDiff) {
1291
- child = prevChild;
1292
- parent.children.delete(child.key);
1293
- child.key = key;
1294
- moved.push([key, child]);
1295
- }
1296
- didMove = true;
1297
- // And check for diff against the previous value in the previous position
1298
- isDiff = valuePrevChild !== value;
1299
- }
1110
+ var _a, _b, _c;
1111
+ if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && typeof __devUpdateNodes !== "undefined" && isObject(obj)) {
1112
+ if (__devUpdateNodes.has(obj)) {
1113
+ console.error(
1114
+ "[legend-state] Circular reference detected in object. You may want to use opaqueObject to stop traversing child nodes.",
1115
+ obj
1116
+ );
1117
+ return false;
1118
+ }
1119
+ __devUpdateNodes.add(obj);
1120
+ }
1121
+ if (isObject(obj) && obj[symbolOpaque] || isObject(prevValue) && prevValue[symbolOpaque]) {
1122
+ const isDiff = obj !== prevValue;
1123
+ if (isDiff) {
1124
+ if (parent.listeners || parent.listenersImmediate) {
1125
+ notify(parent, obj, prevValue, 0);
1126
+ }
1127
+ }
1128
+ if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && typeof __devUpdateNodes !== "undefined" && obj !== void 0) {
1129
+ __devUpdateNodes.delete(obj);
1130
+ }
1131
+ return isDiff;
1132
+ }
1133
+ const isArr = isArray(obj);
1134
+ let prevChildrenById;
1135
+ let moved;
1136
+ const isCurMap = isMap(obj);
1137
+ const isPrevMap = isMap(prevValue);
1138
+ const keys = getKeys(obj, isArr, isCurMap);
1139
+ const keysPrev = getKeys(prevValue, isArr, isPrevMap);
1140
+ const length = ((_a = keys || obj) == null ? void 0 : _a.length) || 0;
1141
+ const lengthPrev = ((_b = keysPrev || prevValue) == null ? void 0 : _b.length) || 0;
1142
+ let idField;
1143
+ let isIdFieldFunction;
1144
+ let hasADiff = false;
1145
+ let retValue;
1146
+ if (isArr && isArray(prevValue)) {
1147
+ if (prevValue.length > 0) {
1148
+ const firstPrevValue = prevValue[0];
1149
+ if (firstPrevValue !== void 0) {
1150
+ idField = findIDKey(firstPrevValue, parent);
1151
+ if (idField) {
1152
+ isIdFieldFunction = isFunction(idField);
1153
+ prevChildrenById = /* @__PURE__ */ new Map();
1154
+ moved = [];
1155
+ }
1156
+ const keysSeen = process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test" ? /* @__PURE__ */ new Set() : void 0;
1157
+ if (parent.children) {
1158
+ for (let i = 0; i < prevValue.length; i++) {
1159
+ const p = prevValue[i];
1160
+ if (p) {
1161
+ const child = parent.children.get(i + "");
1162
+ if (child) {
1163
+ if (!obj[i]) {
1164
+ handleDeletedChild(child, p);
1300
1165
  }
1301
- if (isDiff) {
1302
- // Array has a new / modified element
1303
- // If object iterate through its children
1304
- if (isFunction(value) || isObservable(value)) {
1305
- extractFunctionOrComputed(parent, key, value);
1306
- }
1307
- else if (isPrimitive(value)) {
1308
- hasADiff = true;
1309
- }
1310
- else {
1311
- // Always need to updateNodes so we notify through all children
1312
- const updatedNodes = updateNodes(child, value, prev);
1313
- hasADiff = hasADiff || updatedNodes;
1314
- isDiff = updatedNodes;
1315
- }
1316
- }
1317
- if (isDiff || (isArr && !isArrDiff)) {
1318
- // Notify for this child if this element is different and it has listeners
1319
- // Or if the position changed in an array whose length did not change
1320
- // But do not notify child if the parent is an array with changing length -
1321
- // the array's listener will cover it
1322
- if (child.listeners || child.listenersImmediate) {
1323
- notify(child, value, prev, 0, !isArrDiff);
1166
+ if (idField) {
1167
+ const key = isIdFieldFunction ? idField(p) : p[idField];
1168
+ if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") {
1169
+ if (keysSeen.has(key)) {
1170
+ console.warn(
1171
+ `[legend-state] Warning: Multiple elements in array have the same ID. Key field: ${idField}, Array:`,
1172
+ prevValue
1173
+ );
1324
1174
  }
1175
+ keysSeen.add(key);
1176
+ }
1177
+ prevChildrenById.set(key, child);
1325
1178
  }
1179
+ }
1326
1180
  }
1327
- }
1328
- if (moved) {
1329
- for (let i = 0; i < moved.length; i++) {
1330
- const [key, child] = moved[i];
1331
- parent.children.set(key, child);
1181
+ }
1182
+ }
1183
+ }
1184
+ }
1185
+ } else if (prevValue && (!obj || isObject(obj))) {
1186
+ const lengthPrev2 = keysPrev.length;
1187
+ for (let i = 0; i < lengthPrev2; i++) {
1188
+ const key = keysPrev[i];
1189
+ if (!keys.includes(key)) {
1190
+ hasADiff = true;
1191
+ const child = getChildNode(parent, key);
1192
+ const prev = isPrevMap ? prevValue.get(key) : prevValue[key];
1193
+ if (prev !== void 0) {
1194
+ handleDeletedChild(child, prev);
1195
+ }
1196
+ }
1197
+ }
1198
+ }
1199
+ if (obj && !isPrimitive(obj)) {
1200
+ hasADiff = hasADiff || length !== lengthPrev;
1201
+ const isArrDiff = hasADiff;
1202
+ let didMove = false;
1203
+ for (let i = 0; i < length; i++) {
1204
+ const key = isArr ? i + "" : keys[i];
1205
+ let value = isCurMap ? obj.get(key) : obj[key];
1206
+ const prev = isPrevMap ? prevValue == null ? void 0 : prevValue.get(key) : prevValue == null ? void 0 : prevValue[key];
1207
+ let isDiff = !equals(value, prev);
1208
+ if (isDiff) {
1209
+ const id = idField && value ? isIdFieldFunction ? idField(value) : value[idField] : void 0;
1210
+ const existingChild = (_c = parent.children) == null ? void 0 : _c.get(key);
1211
+ if (isObservable(value)) {
1212
+ const valueNode = getNode(value);
1213
+ if ((existingChild == null ? void 0 : existingChild.linkedToNode) === valueNode) {
1214
+ const targetValue = getNodeValue(valueNode);
1215
+ isCurMap ? obj.set(key, targetValue) : obj[key] = targetValue;
1216
+ continue;
1217
+ }
1218
+ const obs = value;
1219
+ value = () => obs;
1220
+ }
1221
+ let child = getChildNode(parent, key, value);
1222
+ if (!child.lazy && (isFunction(value) || isObservable(value))) {
1223
+ reactivateNode(child, value);
1224
+ peekInternal(child);
1225
+ }
1226
+ if (isArr && id !== void 0) {
1227
+ const prevChild = id !== void 0 ? prevChildrenById == null ? void 0 : prevChildrenById.get(id) : void 0;
1228
+ if (!prevChild) {
1229
+ hasADiff = true;
1230
+ } else if (prevChild !== void 0 && prevChild.key !== key) {
1231
+ const valuePrevChild = prevValue[prevChild.key];
1232
+ if (isArrDiff) {
1233
+ child = prevChild;
1234
+ parent.children.delete(child.key);
1235
+ child.key = key;
1236
+ moved.push([key, child]);
1332
1237
  }
1238
+ didMove = true;
1239
+ isDiff = valuePrevChild !== value;
1240
+ }
1333
1241
  }
1334
- // The full array does not need to re-render if the length is the same
1335
- // So don't notify shallow listeners
1336
- retValue = hasADiff || didMove;
1337
- }
1338
- else if (prevValue !== undefined) {
1339
- // If value got set to undefined, it has a diff
1340
- retValue = true;
1341
- }
1342
- if ((process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') &&
1343
- typeof __devUpdateNodes !== 'undefined' &&
1344
- obj !== undefined) {
1345
- __devUpdateNodes.delete(obj);
1346
- }
1347
- return retValue !== null && retValue !== void 0 ? retValue : false;
1242
+ if (isDiff) {
1243
+ if (isFunction(value) || isObservable(value)) {
1244
+ extractFunctionOrComputed(parent, key, value);
1245
+ } else if (isPrimitive(value)) {
1246
+ hasADiff = true;
1247
+ } else {
1248
+ const updatedNodes = updateNodes(child, value, prev);
1249
+ hasADiff = hasADiff || updatedNodes;
1250
+ isDiff = updatedNodes;
1251
+ }
1252
+ }
1253
+ if (isDiff || isArr && !isArrDiff) {
1254
+ if (child.listeners || child.listenersImmediate) {
1255
+ notify(child, value, prev, 0, !isArrDiff);
1256
+ }
1257
+ }
1258
+ }
1259
+ }
1260
+ if (moved) {
1261
+ for (let i = 0; i < moved.length; i++) {
1262
+ const [key, child] = moved[i];
1263
+ parent.children.set(key, child);
1264
+ }
1265
+ }
1266
+ retValue = hasADiff || didMove;
1267
+ } else if (prevValue !== void 0) {
1268
+ retValue = true;
1269
+ }
1270
+ if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && typeof __devUpdateNodes !== "undefined" && obj !== void 0) {
1271
+ __devUpdateNodes.delete(obj);
1272
+ }
1273
+ return retValue != null ? retValue : false;
1348
1274
  }
1349
1275
  function handleDeletedChild(child, p) {
1350
- var _a, _b;
1351
- // If the previous value is not in the new array and it
1352
- // is an activated, disable its listeners
1353
- (_a = child.linkedToNodeDispose) === null || _a === void 0 ? void 0 : _a.call(child);
1354
- (_b = child.activatedObserveDispose) === null || _b === void 0 ? void 0 : _b.call(child);
1355
- if (!isPrimitive(p)) {
1356
- updateNodes(child, undefined, p);
1357
- }
1358
- if (child.listeners || child.listenersImmediate) {
1359
- notify(child, undefined, p, 0);
1360
- }
1276
+ var _a, _b;
1277
+ (_a = child.linkedToNodeDispose) == null ? void 0 : _a.call(child);
1278
+ (_b = child.activatedObserveDispose) == null ? void 0 : _b.call(child);
1279
+ if (!isPrimitive(p)) {
1280
+ updateNodes(child, void 0, p);
1281
+ }
1282
+ if (child.listeners || child.listenersImmediate) {
1283
+ notify(child, void 0, p, 0);
1284
+ }
1361
1285
  }
1362
1286
  function getProxy(node, p, asFunction) {
1363
- // Get the child node if p prop
1364
- if (p !== undefined)
1365
- node = getChildNode(node, p, asFunction);
1366
- // Create a proxy if not already cached and return it
1367
- return (node.proxy || (node.proxy = new Proxy(node, proxyHandler)));
1287
+ if (p !== void 0)
1288
+ node = getChildNode(node, p, asFunction);
1289
+ return node.proxy || (node.proxy = new Proxy(node, proxyHandler));
1368
1290
  }
1369
1291
  function flushPending() {
1370
- // Need to short circuit the computed batching because the user called get() or peek()
1371
- // in which case the set needs to run immediately so that the values are up to date.
1372
- if (globalState.pendingNodes.size > 0) {
1373
- const nodes = Array.from(globalState.pendingNodes.values());
1374
- globalState.pendingNodes.clear();
1375
- nodes.forEach((fn) => fn());
1376
- }
1377
- }
1378
- const proxyHandler = {
1379
- get(node, p, receiver) {
1380
- var _a, _b;
1381
- if (p === symbolToPrimitive) {
1382
- throw new Error(process.env.NODE_ENV === 'development'
1383
- ? '[legend-state] observable should not be used as a primitive. You may have forgotten to use .get() or .peek() to get the value of the observable.'
1384
- : '[legend-state] observable is not a primitive.');
1385
- }
1386
- if (p === symbolGetNode) {
1387
- return node;
1388
- }
1389
- if (p === 'apply') {
1390
- const nodeValue = getNodeValue(node);
1391
- if (isFunction(nodeValue)) {
1392
- return nodeValue.apply;
1393
- }
1394
- }
1395
- let value = peekInternal(node, /*activateRecursive*/ p === 'get' || p === 'peek');
1396
- // If this node is linked to another observable then forward to the target's handler.
1397
- // The exception is onChange because it needs to listen to this node for changes.
1398
- // This needs to be below peek because it activates there.
1399
- const targetNode = node.linkedToNode || (value === null || value === void 0 ? void 0 : value[symbolGetNode]);
1400
- if (targetNode && p !== 'onChange') {
1401
- return proxyHandler.get(targetNode, p, receiver);
1402
- }
1403
- if (isMap(value) || value instanceof WeakMap || value instanceof Set || value instanceof WeakSet) {
1404
- const ret = handlerMapSet(node, p, value);
1405
- if (ret !== undefined) {
1406
- return ret;
1407
- }
1408
- }
1409
- const fn = observableFns.get(p);
1410
- // If this is an observable function, call it
1411
- if (fn) {
1412
- if (p === 'get' || p === 'peek') {
1413
- flushPending();
1414
- }
1415
- return function (a, b, c) {
1416
- const l = arguments.length;
1417
- // Array call and apply are slow so micro-optimize this hot path.
1418
- // The observable functions depends on the number of arguments so we have to
1419
- // call it with the correct arguments, not just undefined
1420
- switch (l) {
1421
- case 0:
1422
- return fn(node);
1423
- case 1:
1424
- return fn(node, a);
1425
- case 2:
1426
- return fn(node, a, b);
1427
- default:
1428
- return fn(node, a, b, c);
1429
- }
1292
+ if (globalState.pendingNodes.size > 0) {
1293
+ const nodes = Array.from(globalState.pendingNodes.values());
1294
+ globalState.pendingNodes.clear();
1295
+ nodes.forEach((fn) => fn());
1296
+ }
1297
+ }
1298
+ var proxyHandler = {
1299
+ get(node, p, receiver) {
1300
+ var _a, _b;
1301
+ if (p === symbolToPrimitive) {
1302
+ throw new Error(
1303
+ process.env.NODE_ENV === "development" ? "[legend-state] observable should not be used as a primitive. You may have forgotten to use .get() or .peek() to get the value of the observable." : "[legend-state] observable is not a primitive."
1304
+ );
1305
+ }
1306
+ if (p === symbolGetNode) {
1307
+ return node;
1308
+ }
1309
+ if (p === "apply") {
1310
+ const nodeValue = getNodeValue(node);
1311
+ if (isFunction(nodeValue)) {
1312
+ return nodeValue.apply;
1313
+ }
1314
+ }
1315
+ let value = peekInternal(
1316
+ node,
1317
+ /*activateRecursive*/
1318
+ p === "get" || p === "peek"
1319
+ );
1320
+ const targetNode = node.linkedToNode || (value == null ? void 0 : value[symbolGetNode]);
1321
+ if (targetNode && p !== "onChange") {
1322
+ return proxyHandler.get(targetNode, p, receiver);
1323
+ }
1324
+ if (isMap(value) || value instanceof WeakMap || value instanceof Set || value instanceof WeakSet) {
1325
+ const ret = handlerMapSet(node, p, value);
1326
+ if (ret !== void 0) {
1327
+ return ret;
1328
+ }
1329
+ }
1330
+ const fn = observableFns.get(p);
1331
+ if (fn) {
1332
+ if (p === "get" || p === "peek") {
1333
+ flushPending();
1334
+ }
1335
+ return function(a, b, c) {
1336
+ const l = arguments.length;
1337
+ switch (l) {
1338
+ case 0:
1339
+ return fn(node);
1340
+ case 1:
1341
+ return fn(node, a);
1342
+ case 2:
1343
+ return fn(node, a, b);
1344
+ default:
1345
+ return fn(node, a, b, c);
1346
+ }
1347
+ };
1348
+ }
1349
+ const property = observableProperties.get(p);
1350
+ if (property) {
1351
+ return property.get(node);
1352
+ }
1353
+ let vProp = value == null ? void 0 : value[p];
1354
+ if (isObject(value) && value[symbolOpaque]) {
1355
+ return vProp;
1356
+ }
1357
+ const fnOrComputed = (_a = node.functions) == null ? void 0 : _a.get(p);
1358
+ if (fnOrComputed) {
1359
+ if (isObservable(fnOrComputed)) {
1360
+ return fnOrComputed;
1361
+ } else {
1362
+ return getProxy(node, p, fnOrComputed);
1363
+ }
1364
+ } else {
1365
+ vProp = checkProperty(value, p);
1366
+ }
1367
+ if (isNullOrUndefined(value) && vProp === void 0 && (ArrayModifiers.has(p) || ArrayLoopers.has(p))) {
1368
+ value = [];
1369
+ setNodeValue(node, value);
1370
+ vProp = value[p];
1371
+ }
1372
+ if (isFunction(vProp)) {
1373
+ if (isArray(value)) {
1374
+ if (ArrayModifiers.has(p)) {
1375
+ return (...args) => collectionSetter(node, value, p, ...args);
1376
+ } else if (ArrayLoopers.has(p)) {
1377
+ updateTracking(node, true);
1378
+ return function(cbOrig, thisArg) {
1379
+ const isReduce = p === "reduce";
1380
+ const cbWrapped = isReduce ? (previousValue, currentValue, currentIndex, array) => {
1381
+ return cbOrig(
1382
+ previousValue,
1383
+ getProxy(node, currentIndex + "", currentValue),
1384
+ currentIndex,
1385
+ array
1386
+ );
1387
+ } : (val, index, array) => {
1388
+ return cbOrig(getProxy(node, index + "", val), index, array);
1430
1389
  };
1431
- }
1432
- const property = observableProperties.get(p);
1433
- if (property) {
1434
- return property.get(node);
1435
- }
1436
- let vProp = value === null || value === void 0 ? void 0 : value[p];
1437
- if (isObject(value) && value[symbolOpaque]) {
1438
- return vProp;
1439
- }
1440
- const fnOrComputed = (_a = node.functions) === null || _a === void 0 ? void 0 : _a.get(p);
1441
- if (fnOrComputed) {
1442
- if (isObservable(fnOrComputed)) {
1443
- return fnOrComputed;
1390
+ if (isReduce || !ArrayLoopersReturn.has(p)) {
1391
+ return value[p](cbWrapped, thisArg);
1444
1392
  }
1445
- else {
1446
- return getProxy(node, p, fnOrComputed);
1447
- }
1448
- }
1449
- else {
1450
- vProp = checkProperty(value, p);
1451
- }
1452
- if (isNullOrUndefined(value) && vProp === undefined && (ArrayModifiers.has(p) || ArrayLoopers.has(p))) {
1453
- value = [];
1454
- setNodeValue(node, value);
1455
- vProp = value[p];
1456
- }
1457
- // Handle function calls
1458
- if (isFunction(vProp)) {
1459
- if (isArray(value)) {
1460
- if (ArrayModifiers.has(p)) {
1461
- // Call the wrapped modifier function
1462
- return (...args) => collectionSetter(node, value, p, ...args);
1393
+ const isFind = p === "find";
1394
+ const out = [];
1395
+ for (let i = 0; i < value.length; i++) {
1396
+ if (cbWrapped(value[i], i, value)) {
1397
+ const proxy2 = getProxy(node, i + "");
1398
+ if (isFind) {
1399
+ return proxy2;
1463
1400
  }
1464
- else if (ArrayLoopers.has(p)) {
1465
- // Update that this node was accessed for observers
1466
- updateTracking(node, true);
1467
- return function (cbOrig, thisArg) {
1468
- const isReduce = p === 'reduce';
1469
- // Callbacks are given the Proxy rather than the underlying data
1470
- const cbWrapped = isReduce
1471
- ? (previousValue, currentValue, currentIndex, array) => {
1472
- return cbOrig(previousValue, getProxy(node, currentIndex + '', currentValue), currentIndex, array);
1473
- }
1474
- : (val, index, array) => {
1475
- return cbOrig(getProxy(node, index + '', val), index, array);
1476
- };
1477
- if (isReduce || !ArrayLoopersReturn.has(p)) {
1478
- return value[p](cbWrapped, thisArg);
1479
- }
1480
- const isFind = p === 'find';
1481
- const out = [];
1482
- for (let i = 0; i < value.length; i++) {
1483
- if (cbWrapped(value[i], i, value)) {
1484
- const proxy = getProxy(node, i + '');
1485
- // find returns the first match, otherwise it returns an array
1486
- if (isFind) {
1487
- return proxy;
1488
- }
1489
- out.push(proxy);
1490
- }
1491
- }
1492
- return isFind ? undefined : out;
1493
- };
1494
- }
1495
- }
1496
- extractFunctionOrComputed(node, p, vProp);
1497
- const fnOrComputed2 = (_b = node.functions) === null || _b === void 0 ? void 0 : _b.get(p);
1498
- if (fnOrComputed2) {
1499
- return getProxy(node, p, fnOrComputed2);
1500
- }
1501
- // Return the function bound to the value
1502
- return vProp.bind(value);
1503
- }
1504
- // Accessing primitive returns the raw value
1505
- if (isPrimitive(vProp)) {
1506
- // Update that this primitive node was accessed for observers
1507
- if (isArray(value) && p === 'length') {
1508
- updateTracking(node, true);
1509
- return vProp;
1401
+ out.push(proxy2);
1402
+ }
1510
1403
  }
1511
- }
1512
- // Return an observable proxy to the property
1513
- return getProxy(node, p);
1514
- },
1515
- // Forward all proxy properties to the target's value
1516
- getPrototypeOf(node) {
1517
- const value = getNodeValue(node);
1518
- return value !== null && typeof value === 'object' ? Reflect.getPrototypeOf(value) : null;
1519
- },
1520
- ownKeys(node) {
1521
- // TODO: Temporary workaround to fix a bug - the first peek may not return the correct value
1522
- // if the value is a cached. This fixes the test "cache with initial ownKeys"
1523
- peekInternal(node);
1524
- const value = get(node, true);
1525
- if (isPrimitive(value))
1526
- return [];
1527
- const keys = value ? Reflect.ownKeys(value) : [];
1528
- // This is required to fix this error:
1529
- // TypeError: 'getOwnPropertyDescriptor' on proxy: trap reported non-configurability for
1530
- // property 'length' which is either non-existent or configurable in the proxy node
1531
- if (isArray(value) && keys[keys.length - 1] === 'length') {
1532
- keys.splice(keys.length - 1, 1);
1533
- }
1534
- if (isFunction(node)) {
1535
- const reflectedKeys = Reflect.ownKeys(node);
1536
- ['caller', 'arguments', 'prototype'].forEach((key) => reflectedKeys.includes(key) && keys.push(key));
1537
- }
1538
- return keys;
1539
- },
1540
- getOwnPropertyDescriptor(node, prop) {
1541
- if (prop === 'caller' || prop === 'arguments' || prop === 'prototype') {
1542
- return { configurable: false, enumerable: false };
1543
- }
1544
- const value = getNodeValue(node);
1545
- return isPrimitive(value) ? undefined : Reflect.getOwnPropertyDescriptor(value, prop);
1546
- },
1547
- set(node, prop, value) {
1548
- // If this assignment comes from within an observable function it's allowed
1549
- if (node.isSetting) {
1550
- return Reflect.set(node, prop, value);
1551
- }
1552
- if (node.isAssigning) {
1553
- setKey(node, prop, value);
1554
- return true;
1555
- }
1556
- const property = observableProperties.get(prop);
1557
- if (property) {
1558
- property.set(node, value);
1559
- return true;
1560
- }
1561
- if (process.env.NODE_ENV === 'development') {
1562
- console.warn('[legend-state]: Error: Cannot set a value directly:', prop, value);
1563
- }
1564
- return false;
1565
- },
1566
- deleteProperty(node, prop) {
1567
- // If this delete comes from within an observable function it's allowed
1568
- if (node.isSetting) {
1569
- return Reflect.deleteProperty(node, prop);
1570
- }
1571
- else {
1572
- if (process.env.NODE_ENV === 'development') {
1573
- console.warn('[legend-state]: Error: Cannot delete a value directly:', prop);
1574
- }
1575
- return false;
1576
- }
1577
- },
1578
- has(node, prop) {
1579
- const value = getNodeValue(node);
1580
- return Reflect.has(value, prop);
1581
- },
1582
- apply(target, thisArg, argArray) {
1583
- // If it's a function call it as a function
1584
- if (isObservable(thisArg)) {
1585
- thisArg = thisArg.peek();
1586
- }
1587
- return Reflect.apply(target.lazyFn || target, thisArg, argArray);
1588
- },
1404
+ return isFind ? void 0 : out;
1405
+ };
1406
+ }
1407
+ }
1408
+ extractFunctionOrComputed(node, p, vProp);
1409
+ const fnOrComputed2 = (_b = node.functions) == null ? void 0 : _b.get(p);
1410
+ if (fnOrComputed2) {
1411
+ return getProxy(node, p, fnOrComputed2);
1412
+ }
1413
+ return vProp.bind(value);
1414
+ }
1415
+ if (isPrimitive(vProp)) {
1416
+ if (isArray(value) && p === "length") {
1417
+ updateTracking(node, true);
1418
+ return vProp;
1419
+ }
1420
+ }
1421
+ return getProxy(node, p);
1422
+ },
1423
+ // Forward all proxy properties to the target's value
1424
+ getPrototypeOf(node) {
1425
+ const value = getNodeValue(node);
1426
+ return value !== null && typeof value === "object" ? Reflect.getPrototypeOf(value) : null;
1427
+ },
1428
+ ownKeys(node) {
1429
+ peekInternal(node);
1430
+ const value = get(node, true);
1431
+ if (isPrimitive(value))
1432
+ return [];
1433
+ const keys = value ? Reflect.ownKeys(value) : [];
1434
+ if (isArray(value) && keys[keys.length - 1] === "length") {
1435
+ keys.splice(keys.length - 1, 1);
1436
+ }
1437
+ if (isFunction(node)) {
1438
+ const reflectedKeys = Reflect.ownKeys(node);
1439
+ ["caller", "arguments", "prototype"].forEach((key) => reflectedKeys.includes(key) && keys.push(key));
1440
+ }
1441
+ return keys;
1442
+ },
1443
+ getOwnPropertyDescriptor(node, prop) {
1444
+ if (prop === "caller" || prop === "arguments" || prop === "prototype") {
1445
+ return { configurable: false, enumerable: false };
1446
+ }
1447
+ const value = getNodeValue(node);
1448
+ return isPrimitive(value) ? void 0 : Reflect.getOwnPropertyDescriptor(value, prop);
1449
+ },
1450
+ set(node, prop, value) {
1451
+ if (node.isSetting) {
1452
+ return Reflect.set(node, prop, value);
1453
+ }
1454
+ if (node.isAssigning) {
1455
+ setKey(node, prop, value);
1456
+ return true;
1457
+ }
1458
+ const property = observableProperties.get(prop);
1459
+ if (property) {
1460
+ property.set(node, value);
1461
+ return true;
1462
+ }
1463
+ if (process.env.NODE_ENV === "development") {
1464
+ console.warn("[legend-state]: Error: Cannot set a value directly:", prop, value);
1465
+ }
1466
+ return false;
1467
+ },
1468
+ deleteProperty(node, prop) {
1469
+ if (node.isSetting) {
1470
+ return Reflect.deleteProperty(node, prop);
1471
+ } else {
1472
+ if (process.env.NODE_ENV === "development") {
1473
+ console.warn("[legend-state]: Error: Cannot delete a value directly:", prop);
1474
+ }
1475
+ return false;
1476
+ }
1477
+ },
1478
+ has(node, prop) {
1479
+ const value = getNodeValue(node);
1480
+ return Reflect.has(value, prop);
1481
+ },
1482
+ apply(target, thisArg, argArray) {
1483
+ if (isObservable(thisArg)) {
1484
+ thisArg = thisArg.peek();
1485
+ }
1486
+ return Reflect.apply(target.lazyFn || target, thisArg, argArray);
1487
+ }
1589
1488
  };
1590
1489
  function set(node, newValue) {
1591
- if (node.parent) {
1592
- setKey(node.parent, node.key, newValue);
1593
- }
1594
- else {
1595
- setKey(node, '_', newValue);
1596
- }
1490
+ if (node.parent) {
1491
+ setKey(node.parent, node.key, newValue);
1492
+ } else {
1493
+ setKey(node, "_", newValue);
1494
+ }
1597
1495
  }
1598
1496
  function toggle(node) {
1599
- const value = getNodeValue(node);
1600
- if (value === undefined || value === null || isBoolean(value)) {
1601
- set(node, !value);
1602
- }
1603
- else if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
1604
- throw new Error('[legend-state] Cannot toggle a non-boolean value');
1605
- }
1497
+ const value = getNodeValue(node);
1498
+ if (value === void 0 || value === null || isBoolean(value)) {
1499
+ set(node, !value);
1500
+ } else if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") {
1501
+ throw new Error("[legend-state] Cannot toggle a non-boolean value");
1502
+ }
1606
1503
  }
1607
1504
  function setKey(node, key, newValue, level) {
1608
- if (process.env.NODE_ENV === 'development') {
1609
- if (typeof HTMLElement !== 'undefined' && newValue instanceof HTMLElement) {
1610
- console.warn(`[legend-state] Set an HTMLElement into state. You probably don't want to do that.`);
1611
- }
1612
- }
1613
- const isRoot = !node.parent && key === '_';
1614
- if (node.parent && !getNodeValue(node) && !isFunction(newValue)) {
1615
- set(node, { [key]: newValue });
1616
- }
1617
- // Get the child node for updating and notifying
1618
- const childNode = isRoot ? node : getChildNode(node, key, newValue);
1619
- if (isObservable(newValue)) {
1620
- setToObservable(childNode, newValue);
1621
- }
1622
- else {
1623
- // Set the raw value on the parent object
1624
- const { newValue: savedValue, prevValue } = setNodeValue(childNode, newValue);
1625
- const isPrim = isPrimitive(savedValue) || savedValue instanceof Date;
1626
- if (!equals(savedValue, prevValue)) {
1627
- updateNodesAndNotify(node, savedValue, prevValue, childNode, isPrim, isRoot, level);
1628
- }
1629
- if (!isPrim) {
1630
- childNode.needsExtract = true;
1631
- }
1632
- extractFunctionOrComputed(node, key, savedValue);
1633
- }
1505
+ if (process.env.NODE_ENV === "development") {
1506
+ if (typeof HTMLElement !== "undefined" && newValue instanceof HTMLElement) {
1507
+ console.warn(`[legend-state] Set an HTMLElement into state. You probably don't want to do that.`);
1508
+ }
1509
+ }
1510
+ const isRoot = !node.parent && key === "_";
1511
+ if (node.parent && !getNodeValue(node) && !isFunction(newValue)) {
1512
+ set(node, { [key]: newValue });
1513
+ }
1514
+ const childNode = isRoot ? node : getChildNode(node, key, newValue);
1515
+ if (isObservable(newValue)) {
1516
+ setToObservable(childNode, newValue);
1517
+ } else {
1518
+ const { newValue: savedValue, prevValue } = setNodeValue(childNode, newValue);
1519
+ const isPrim = isPrimitive(savedValue) || savedValue instanceof Date;
1520
+ if (!equals(savedValue, prevValue)) {
1521
+ updateNodesAndNotify(node, savedValue, prevValue, childNode, isPrim, isRoot, level);
1522
+ }
1523
+ if (!isPrim) {
1524
+ childNode.needsExtract = true;
1525
+ }
1526
+ extractFunctionOrComputed(node, key, savedValue);
1527
+ }
1634
1528
  }
1635
1529
  function assign(node, value) {
1636
- const proxy = getProxy(node);
1637
- beginBatch();
1638
- if (isPrimitive(node.root._)) {
1639
- node.root._ = {};
1640
- }
1641
- if (isMap(value)) {
1642
- const currentValue = getNodeValue(node);
1643
- if (isMap(currentValue)) {
1644
- value.forEach((value, key) => currentValue.set(key, value));
1645
- }
1646
- }
1647
- else {
1648
- // Set inAssign to allow setting on safe observables
1649
- node.isAssigning = (node.isAssigning || 0) + 1;
1650
- try {
1651
- // TODO: If current value is a Map how to assign into the Map?
1652
- Object.assign(proxy, value);
1653
- }
1654
- finally {
1655
- node.isAssigning--;
1656
- }
1530
+ const proxy2 = getProxy(node);
1531
+ beginBatch();
1532
+ if (isPrimitive(node.root._)) {
1533
+ node.root._ = {};
1534
+ }
1535
+ if (isMap(value)) {
1536
+ const currentValue = getNodeValue(node);
1537
+ if (isMap(currentValue)) {
1538
+ value.forEach((value2, key) => currentValue.set(key, value2));
1539
+ }
1540
+ } else {
1541
+ node.isAssigning = (node.isAssigning || 0) + 1;
1542
+ try {
1543
+ Object.assign(proxy2, value);
1544
+ } finally {
1545
+ node.isAssigning--;
1657
1546
  }
1658
- endBatch();
1659
- return proxy;
1547
+ }
1548
+ endBatch();
1549
+ return proxy2;
1660
1550
  }
1661
1551
  function deleteFn(node, key) {
1662
- // If called without a key, delete by key from the parent node
1663
- if (key === undefined && isChildNodeValue(node)) {
1664
- key = node.key;
1665
- node = node.parent;
1666
- }
1667
- const value = getNodeValue(node);
1668
- if (isArray(value)) {
1669
- collectionSetter(node, value, 'splice', key, 1);
1670
- }
1671
- else {
1672
- setKey(node, key !== null && key !== void 0 ? key : '_', symbolDelete, /*level*/ -1);
1673
- }
1552
+ if (key === void 0 && isChildNodeValue(node)) {
1553
+ key = node.key;
1554
+ node = node.parent;
1555
+ }
1556
+ const value = getNodeValue(node);
1557
+ if (isArray(value)) {
1558
+ collectionSetter(node, value, "splice", key, 1);
1559
+ } else {
1560
+ setKey(
1561
+ node,
1562
+ key != null ? key : "_",
1563
+ symbolDelete,
1564
+ /*level*/
1565
+ -1
1566
+ );
1567
+ }
1674
1568
  }
1675
1569
  function handlerMapSet(node, p, value) {
1676
- const vProp = value === null || value === void 0 ? void 0 : value[p];
1677
- if (p === 'size') {
1678
- return getProxy(node, p);
1679
- }
1680
- else if (isFunction(vProp)) {
1681
- return function (a, b, c) {
1682
- const l = arguments.length;
1683
- const valueMap = value;
1684
- if (p === 'get') {
1685
- if (l > 0 && typeof a !== 'boolean' && a !== optimized) {
1686
- return getProxy(node, a);
1687
- }
1688
- }
1689
- else if (p === 'set') {
1690
- if (l === 2) {
1691
- const prev = valueMap.get(a);
1692
- const ret = valueMap.set(a, b);
1693
- if (prev !== b) {
1694
- updateNodesAndNotify(getChildNode(node, a), b, prev);
1695
- }
1696
- return ret;
1697
- }
1698
- else if (l === 1 && isMap(value)) {
1699
- set(node, a);
1700
- }
1701
- }
1702
- else if (p === 'delete') {
1703
- if (l > 0) {
1704
- // Support Set by just returning a if it doesn't have get, meaning it's not a Map
1705
- const prev = value.get ? valueMap.get(a) : a;
1706
- const ret = value.delete(a);
1707
- if (ret) {
1708
- updateNodesAndNotify(getChildNode(node, a), undefined, prev);
1709
- }
1710
- return ret;
1711
- }
1712
- }
1713
- else if (p === 'clear') {
1714
- const prev = new Map(valueMap);
1715
- const size = valueMap.size;
1716
- valueMap.clear();
1717
- if (size) {
1718
- updateNodesAndNotify(node, value, prev);
1719
- }
1720
- return;
1721
- }
1722
- else if (p === 'add') {
1723
- const prev = new Set(value);
1724
- const ret = value.add(a);
1725
- if (!value.has(p)) {
1726
- notify(node, ret, prev, 0);
1727
- }
1728
- return ret;
1729
- }
1730
- // TODO: This is duplicated from proxy handler, how to dedupe with best performance?
1731
- const fn = observableFns.get(p);
1732
- if (fn) {
1733
- // Array call and apply are slow so micro-optimize this hot path.
1734
- // The observable functions depends on the number of arguments so we have to
1735
- // call it with the correct arguments, not just undefined
1736
- switch (l) {
1737
- case 0:
1738
- return fn(node);
1739
- case 1:
1740
- return fn(node, a);
1741
- case 2:
1742
- return fn(node, a, b);
1743
- default:
1744
- return fn(node, a, b, c);
1745
- }
1746
- }
1747
- else {
1748
- return value[p](a, b);
1749
- }
1750
- };
1751
- }
1570
+ const vProp = value == null ? void 0 : value[p];
1571
+ if (p === "size") {
1572
+ return getProxy(node, p);
1573
+ } else if (isFunction(vProp)) {
1574
+ return function(a, b, c) {
1575
+ const l = arguments.length;
1576
+ const valueMap = value;
1577
+ if (p === "get") {
1578
+ if (l > 0 && typeof a !== "boolean" && a !== optimized) {
1579
+ return getProxy(node, a);
1580
+ }
1581
+ } else if (p === "set") {
1582
+ if (l === 2) {
1583
+ const prev = valueMap.get(a);
1584
+ const ret = valueMap.set(a, b);
1585
+ if (prev !== b) {
1586
+ updateNodesAndNotify(getChildNode(node, a), b, prev);
1587
+ }
1588
+ return ret;
1589
+ } else if (l === 1 && isMap(value)) {
1590
+ set(node, a);
1591
+ }
1592
+ } else if (p === "delete") {
1593
+ if (l > 0) {
1594
+ const prev = value.get ? valueMap.get(a) : a;
1595
+ const ret = value.delete(a);
1596
+ if (ret) {
1597
+ updateNodesAndNotify(getChildNode(node, a), void 0, prev);
1598
+ }
1599
+ return ret;
1600
+ }
1601
+ } else if (p === "clear") {
1602
+ const prev = new Map(valueMap);
1603
+ const size = valueMap.size;
1604
+ valueMap.clear();
1605
+ if (size) {
1606
+ updateNodesAndNotify(node, value, prev);
1607
+ }
1608
+ return;
1609
+ } else if (p === "add") {
1610
+ const prev = new Set(value);
1611
+ const ret = value.add(a);
1612
+ if (!value.has(p)) {
1613
+ notify(node, ret, prev, 0);
1614
+ }
1615
+ return ret;
1616
+ }
1617
+ const fn = observableFns.get(p);
1618
+ if (fn) {
1619
+ switch (l) {
1620
+ case 0:
1621
+ return fn(node);
1622
+ case 1:
1623
+ return fn(node, a);
1624
+ case 2:
1625
+ return fn(node, a, b);
1626
+ default:
1627
+ return fn(node, a, b, c);
1628
+ }
1629
+ } else {
1630
+ return value[p](a, b);
1631
+ }
1632
+ };
1633
+ }
1752
1634
  }
1753
1635
  function updateNodesAndNotify(node, newValue, prevValue, childNode, isPrim, isRoot, level) {
1754
- if (!childNode)
1755
- childNode = node;
1756
- // Make sure we don't call too many listeners for every property set
1757
- beginBatch();
1758
- if (isPrim === undefined) {
1759
- isPrim = isPrimitive(newValue);
1760
- }
1761
- let hasADiff = isPrim;
1762
- let whenOptimizedOnlyIf = false;
1763
- // If new value is an object or array update notify down the tree
1764
- if (!isPrim || (prevValue && !isPrimitive(prevValue))) {
1765
- if ((process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') &&
1766
- typeof __devUpdateNodes !== 'undefined') {
1767
- __devUpdateNodes.clear();
1768
- }
1769
- hasADiff = updateNodes(childNode, newValue, prevValue);
1770
- if (isArray(newValue)) {
1771
- whenOptimizedOnlyIf = (newValue === null || newValue === void 0 ? void 0 : newValue.length) !== (prevValue === null || prevValue === void 0 ? void 0 : prevValue.length);
1772
- }
1773
- }
1774
- if (isPrim || !newValue || (isEmpty(newValue) && !isEmpty(prevValue)) ? newValue !== prevValue : hasADiff) {
1775
- // Notify for this element if something inside it has changed
1776
- notify(isPrim && isRoot ? node : childNode, newValue, prevValue, (level !== null && level !== void 0 ? level : prevValue === undefined) ? -1 : hasADiff ? 0 : 1, whenOptimizedOnlyIf);
1777
- }
1778
- endBatch();
1636
+ if (!childNode)
1637
+ childNode = node;
1638
+ beginBatch();
1639
+ if (isPrim === void 0) {
1640
+ isPrim = isPrimitive(newValue);
1641
+ }
1642
+ let hasADiff = isPrim;
1643
+ let whenOptimizedOnlyIf = false;
1644
+ if (!isPrim || prevValue && !isPrimitive(prevValue)) {
1645
+ if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && typeof __devUpdateNodes !== "undefined") {
1646
+ __devUpdateNodes.clear();
1647
+ }
1648
+ hasADiff = updateNodes(childNode, newValue, prevValue);
1649
+ if (isArray(newValue)) {
1650
+ whenOptimizedOnlyIf = (newValue == null ? void 0 : newValue.length) !== (prevValue == null ? void 0 : prevValue.length);
1651
+ }
1652
+ }
1653
+ if (isPrim || !newValue || isEmpty(newValue) && !isEmpty(prevValue) ? newValue !== prevValue : hasADiff) {
1654
+ notify(
1655
+ isPrim && isRoot ? node : childNode,
1656
+ newValue,
1657
+ prevValue,
1658
+ (level != null ? level : prevValue === void 0) ? -1 : hasADiff ? 0 : 1,
1659
+ whenOptimizedOnlyIf
1660
+ );
1661
+ }
1662
+ endBatch();
1779
1663
  }
1780
1664
  function extractPromise(node, value, setter) {
1781
- if (!node.state) {
1782
- node.state = createObservable({
1783
- isLoaded: false,
1784
- }, false, extractPromise, getProxy);
1785
- }
1786
- value
1787
- .then((value) => {
1788
- setter ? setter({ value }) : set(node, value);
1789
- node.state.assign({
1790
- isLoaded: true,
1791
- error: undefined,
1792
- });
1793
- })
1794
- .catch((error) => {
1795
- node.state.error.set(error);
1665
+ if (!node.state) {
1666
+ node.state = createObservable(
1667
+ {
1668
+ isLoaded: false
1669
+ },
1670
+ false,
1671
+ extractPromise,
1672
+ getProxy
1673
+ );
1674
+ }
1675
+ value.then((value2) => {
1676
+ setter ? setter({ value: value2 }) : set(node, value2);
1677
+ node.state.assign({
1678
+ isLoaded: true,
1679
+ error: void 0
1796
1680
  });
1681
+ }).catch((error) => {
1682
+ node.state.error.set(error);
1683
+ });
1797
1684
  }
1798
1685
  function extractFunctionOrComputed(node, k, v) {
1799
- // We want to extract these types of values from the observable's raw value so that
1800
- // the raw value does not contain Promises, Observables or functions
1801
- if (isPromise(v)) {
1802
- const childNode = getChildNode(node, k);
1803
- extractPromise(childNode, v);
1804
- setNodeValue(childNode, undefined);
1805
- return undefined;
1806
- }
1807
- else if (isObservable(v)) {
1808
- const fn = () => v;
1809
- extractFunction(node, k, fn);
1810
- const childNode = getChildNode(node, k, fn);
1811
- const targetNode = getNode(v);
1812
- // Set node to target's value if activating or it's already activated
1813
- const initialValue = peek(targetNode);
1814
- setNodeValue(childNode, initialValue);
1815
- return getNodeValue(childNode);
1816
- }
1817
- else if (typeof v === 'function') {
1818
- extractFunction(node, k, v);
1819
- return k;
1820
- }
1686
+ if (isPromise(v)) {
1687
+ const childNode = getChildNode(node, k);
1688
+ extractPromise(childNode, v);
1689
+ setNodeValue(childNode, void 0);
1690
+ return void 0;
1691
+ } else if (isObservable(v)) {
1692
+ const fn = () => v;
1693
+ extractFunction(node, k, fn);
1694
+ const childNode = getChildNode(node, k, fn);
1695
+ const targetNode = getNode(v);
1696
+ const initialValue = peek(targetNode);
1697
+ setNodeValue(childNode, initialValue);
1698
+ return getNodeValue(childNode);
1699
+ } else if (typeof v === "function") {
1700
+ extractFunction(node, k, v);
1701
+ return k;
1702
+ }
1821
1703
  }
1822
1704
  function get(node, options) {
1823
- const track = options ? (isObject(options) ? options.shallow : options) : undefined;
1824
- // Track by default
1825
- updateTracking(node, track);
1826
- return peek(node);
1705
+ const track = options ? isObject(options) ? options.shallow : options : void 0;
1706
+ updateTracking(node, track);
1707
+ return peek(node);
1827
1708
  }
1828
1709
  function peek(node) {
1829
- return peekInternal(node, true);
1710
+ return peekInternal(node, true);
1830
1711
  }
1831
- let isFlushing = false;
1712
+ var isFlushing = false;
1832
1713
  function peekInternal(node, activateRecursive) {
1833
- var _a;
1834
- isFlushing = true;
1835
- // Need to refresh all dirty children when getting
1836
- if (activateRecursive && ((_a = node.dirtyChildren) === null || _a === void 0 ? void 0 : _a.size)) {
1837
- const dirty = Array.from(node.dirtyChildren);
1838
- node.dirtyChildren.clear();
1839
- dirty.forEach((node) => node.dirtyFn && peekInternal(node));
1840
- }
1841
- if (node.dirtyFn) {
1842
- const dirtyFn = node.dirtyFn;
1843
- node.dirtyFn = undefined;
1844
- globalState.dirtyNodes.delete(node);
1845
- dirtyFn();
1846
- }
1847
- isFlushing = false;
1848
- let value = getNodeValue(node);
1849
- value = checkLazy(node, value, !!activateRecursive);
1850
- return value;
1714
+ var _a;
1715
+ isFlushing = true;
1716
+ if (activateRecursive && ((_a = node.dirtyChildren) == null ? void 0 : _a.size)) {
1717
+ const dirty = Array.from(node.dirtyChildren);
1718
+ node.dirtyChildren.clear();
1719
+ dirty.forEach((node2) => node2.dirtyFn && peekInternal(node2));
1720
+ }
1721
+ if (node.dirtyFn) {
1722
+ const dirtyFn = node.dirtyFn;
1723
+ node.dirtyFn = void 0;
1724
+ globalState.dirtyNodes.delete(node);
1725
+ dirtyFn();
1726
+ }
1727
+ isFlushing = false;
1728
+ let value = getNodeValue(node);
1729
+ value = checkLazy(node, value, !!activateRecursive);
1730
+ return value;
1851
1731
  }
1852
1732
  function checkLazy(node, value, activateRecursive) {
1853
- const origValue = value;
1854
- // If node is not yet lazily computed go do that
1855
- const lazy = node.lazy;
1856
- if (lazy) {
1857
- const lazyFn = node.lazyFn;
1858
- delete node.lazy;
1859
- if (isFunction(lazyFn)) {
1860
- if (lazyFn.length === 1) {
1861
- // This is a lookup function, so return a record object
1862
- value = {};
1863
- }
1864
- else {
1865
- if (node.parent) {
1866
- const parentValue = getNodeValue(node.parent);
1867
- if (parentValue) {
1868
- delete parentValue[node.key];
1869
- }
1870
- else {
1871
- node.root._ = undefined;
1872
- }
1873
- }
1874
- value = activateNodeFunction(node, lazyFn);
1875
- }
1876
- }
1877
- else if (isObservable(value)) {
1878
- value = extractFunctionOrComputed(node.parent, node.key, value);
1879
- }
1880
- }
1881
- if ((lazy || node.needsExtract) && !isObservable(value) && !isPrimitive(value)) {
1882
- // If this is a purposeful get, check descendants for observable or auto activated linked
1883
- if (activateRecursive) {
1884
- recursivelyAutoActivate(value, node);
1885
- }
1886
- // If this is an extractable node, extract it from parent before it's accessed
1733
+ const origValue = value;
1734
+ const lazy = node.lazy;
1735
+ if (lazy) {
1736
+ const lazyFn = node.lazyFn;
1737
+ delete node.lazy;
1738
+ if (isFunction(lazyFn)) {
1739
+ if (lazyFn.length === 1) {
1740
+ value = {};
1741
+ } else {
1887
1742
  if (node.parent) {
1888
- extractFunctionOrComputed(node.parent, node.key, origValue);
1889
- }
1743
+ const parentValue = getNodeValue(node.parent);
1744
+ if (parentValue) {
1745
+ delete parentValue[node.key];
1746
+ } else {
1747
+ node.root._ = void 0;
1748
+ }
1749
+ }
1750
+ value = activateNodeFunction(node, lazyFn);
1751
+ }
1752
+ } else if (isObservable(value)) {
1753
+ value = extractFunctionOrComputed(node.parent, node.key, value);
1754
+ }
1755
+ }
1756
+ if ((lazy || node.needsExtract) && !isObservable(value) && !isPrimitive(value)) {
1757
+ if (activateRecursive) {
1758
+ recursivelyAutoActivate(value, node);
1890
1759
  }
1891
- return value;
1760
+ if (node.parent) {
1761
+ extractFunctionOrComputed(node.parent, node.key, origValue);
1762
+ }
1763
+ }
1764
+ return value;
1892
1765
  }
1893
1766
  function checkProperty(value, key) {
1894
- if (value) {
1895
- const property = Object.getOwnPropertyDescriptor(value, key);
1896
- if (property === null || property === void 0 ? void 0 : property.get) {
1897
- delete value[key];
1898
- value[key] = property.set
1899
- ? linked({
1900
- get: property.get,
1901
- set: ({ value }) => property.set(value),
1902
- })
1903
- : property.get;
1904
- }
1905
- return value[key];
1906
- }
1767
+ if (value) {
1768
+ const property = Object.getOwnPropertyDescriptor(value, key);
1769
+ if (property == null ? void 0 : property.get) {
1770
+ delete value[key];
1771
+ value[key] = property.set ? linked({
1772
+ get: property.get,
1773
+ set: ({ value: value2 }) => property.set(value2)
1774
+ }) : property.get;
1775
+ }
1776
+ return value[key];
1777
+ }
1907
1778
  }
1908
1779
  function reactivateNode(node, lazyFn) {
1909
- var _a, _b;
1910
- (_a = node.activatedObserveDispose) === null || _a === void 0 ? void 0 : _a.call(node);
1911
- (_b = node.linkedToNodeDispose) === null || _b === void 0 ? void 0 : _b.call(node);
1912
- node.activatedObserveDispose = node.linkedToNodeDispose = node.linkedToNode = undefined;
1913
- node.lazyFn = lazyFn;
1914
- node.lazy = true;
1780
+ var _a, _b;
1781
+ (_a = node.activatedObserveDispose) == null ? void 0 : _a.call(node);
1782
+ (_b = node.linkedToNodeDispose) == null ? void 0 : _b.call(node);
1783
+ node.activatedObserveDispose = node.linkedToNodeDispose = node.linkedToNode = void 0;
1784
+ node.lazyFn = lazyFn;
1785
+ node.lazy = true;
1915
1786
  }
1916
1787
  function isObserved(node) {
1917
- var _a, _b;
1918
- let parent = node;
1919
- let hasListeners = node.numListenersRecursive > 0;
1920
- while (parent && !hasListeners) {
1921
- if (!!((_a = parent.listeners) === null || _a === void 0 ? void 0 : _a.size) || !!((_b = parent.listenersImmediate) === null || _b === void 0 ? void 0 : _b.size)) {
1922
- hasListeners = true;
1923
- }
1924
- parent = parent.parent;
1788
+ var _a, _b;
1789
+ let parent = node;
1790
+ let hasListeners = node.numListenersRecursive > 0;
1791
+ while (parent && !hasListeners) {
1792
+ if (!!((_a = parent.listeners) == null ? void 0 : _a.size) || !!((_b = parent.listenersImmediate) == null ? void 0 : _b.size)) {
1793
+ hasListeners = true;
1925
1794
  }
1926
- return hasListeners;
1795
+ parent = parent.parent;
1796
+ }
1797
+ return hasListeners;
1927
1798
  }
1928
1799
  function shouldIgnoreUnobserved(node, refreshFn) {
1929
- if (!isFlushing) {
1930
- const hasListeners = isObserved(node);
1931
- if (!hasListeners) {
1932
- if (refreshFn) {
1933
- node.dirtyFn = refreshFn;
1934
- }
1935
- let parent = node;
1936
- while (parent) {
1937
- if (!parent.dirtyChildren) {
1938
- parent.dirtyChildren = new Set();
1939
- }
1940
- parent.dirtyChildren.add(node);
1941
- parent = parent.parent;
1942
- }
1943
- return true;
1800
+ if (!isFlushing) {
1801
+ const hasListeners = isObserved(node);
1802
+ if (!hasListeners) {
1803
+ if (refreshFn) {
1804
+ node.dirtyFn = refreshFn;
1805
+ }
1806
+ let parent = node;
1807
+ while (parent) {
1808
+ if (!parent.dirtyChildren) {
1809
+ parent.dirtyChildren = /* @__PURE__ */ new Set();
1944
1810
  }
1811
+ parent.dirtyChildren.add(node);
1812
+ parent = parent.parent;
1813
+ }
1814
+ return true;
1945
1815
  }
1816
+ }
1946
1817
  }
1947
1818
  function activateNodeFunction(node, lazyFn) {
1948
- // let prevTarget$: Observable<any>;
1949
- // let curTarget$: Observable<any>;
1950
- let update;
1951
- let wasPromise;
1952
- let ignoreThisUpdate;
1953
- let isFirst = true;
1954
- const activateFn = lazyFn;
1955
- let activatedValue;
1956
- let disposes = [];
1957
- let refreshFn;
1958
- function markDirty() {
1959
- node.dirtyFn = refreshFn;
1960
- globalState.dirtyNodes.add(node);
1961
- }
1962
- node.activatedObserveDispose = observe(() => {
1963
- var _a, _b, _c, _d;
1964
- // Set it to undefined so that the activation function gets undefined
1965
- // if it peeks itself
1966
- if (isFirst) {
1967
- isFirst = false;
1968
- setNodeValue(node, undefined);
1969
- }
1970
- else if (!isFlushing && refreshFn) {
1971
- if (shouldIgnoreUnobserved(node, refreshFn)) {
1972
- ignoreThisUpdate = true;
1973
- return;
1974
- }
1975
- }
1976
- // Run the function at this node
1977
- let value = activateFn();
1978
- let didSetToObs = false;
1979
- // If target is an observable, make this node a link to it
1980
- if (isObservable(value)) {
1981
- didSetToObs = true;
1982
- value = setToObservable(node, value);
1983
- }
1984
- if (isFunction(value)) {
1985
- value = value();
1986
- }
1987
- const activated = !isObservable(value)
1988
- ? value === null || value === void 0 ? void 0 : value[symbolLinked]
1989
- : undefined;
1990
- if (activated) {
1991
- node.activationState = activated;
1992
- value = undefined;
1993
- }
1994
- ignoreThisUpdate = false;
1995
- wasPromise = isPromise(value);
1996
- // Activate this node if not activated already (may be called recursively)
1997
- // TODO: Is calling recursively bad? If so can it be fixed?
1998
- if (!node.activated) {
1999
- node.activated = true;
2000
- let activateNodeFn = activateNodeBase;
2001
- // If this is a Synced then run it through persistence instead of base
2002
- if (activated === null || activated === void 0 ? void 0 : activated.synced) {
2003
- activateNodeFn = globalState.activateSyncedNode;
2004
- ignoreThisUpdate = true;
2005
- }
2006
- const result = activateNodeFn(node, value);
2007
- update = result.update;
2008
- let newValue = result.value;
2009
- if (!didSetToObs && isObservable(newValue)) {
2010
- newValue = setToObservable(node, newValue);
2011
- }
2012
- value = newValue !== null && newValue !== void 0 ? newValue : activated === null || activated === void 0 ? void 0 : activated.initial;
2013
- }
2014
- else if (node.activationState) {
2015
- const activated = node.activationState;
2016
- if ((_b = (_a = node.state) === null || _a === void 0 ? void 0 : _a.peek()) === null || _b === void 0 ? void 0 : _b.sync) {
2017
- node.state.sync();
2018
- ignoreThisUpdate = true;
1819
+ let update;
1820
+ let wasPromise;
1821
+ let ignoreThisUpdate;
1822
+ let isFirst = true;
1823
+ const activateFn = lazyFn;
1824
+ let activatedValue;
1825
+ let disposes = [];
1826
+ let refreshFn;
1827
+ function markDirty() {
1828
+ node.dirtyFn = refreshFn;
1829
+ globalState.dirtyNodes.add(node);
1830
+ }
1831
+ node.activatedObserveDispose = observe(
1832
+ () => {
1833
+ var _a, _b, _c, _d;
1834
+ if (isFirst) {
1835
+ isFirst = false;
1836
+ setNodeValue(node, void 0);
1837
+ } else if (!isFlushing && refreshFn) {
1838
+ if (shouldIgnoreUnobserved(node, refreshFn)) {
1839
+ ignoreThisUpdate = true;
1840
+ return;
1841
+ }
1842
+ }
1843
+ let value = activateFn();
1844
+ let didSetToObs = false;
1845
+ if (isObservable(value)) {
1846
+ didSetToObs = true;
1847
+ value = setToObservable(node, value);
1848
+ }
1849
+ if (isFunction(value)) {
1850
+ value = value();
1851
+ }
1852
+ const activated = !isObservable(value) ? value == null ? void 0 : value[symbolLinked] : void 0;
1853
+ if (activated) {
1854
+ node.activationState = activated;
1855
+ value = void 0;
1856
+ }
1857
+ ignoreThisUpdate = false;
1858
+ wasPromise = isPromise(value);
1859
+ if (!node.activated) {
1860
+ node.activated = true;
1861
+ let activateNodeFn = activateNodeBase;
1862
+ if (activated == null ? void 0 : activated.synced) {
1863
+ activateNodeFn = globalState.activateSyncedNode;
1864
+ ignoreThisUpdate = true;
1865
+ }
1866
+ const result = activateNodeFn(node, value);
1867
+ update = result.update;
1868
+ let newValue = result.value;
1869
+ if (!didSetToObs && isObservable(newValue)) {
1870
+ newValue = setToObservable(node, newValue);
1871
+ }
1872
+ value = newValue != null ? newValue : activated == null ? void 0 : activated.initial;
1873
+ } else if (node.activationState) {
1874
+ const activated2 = node.activationState;
1875
+ if ((_b = (_a = node.state) == null ? void 0 : _a.peek()) == null ? void 0 : _b.sync) {
1876
+ node.state.sync();
1877
+ ignoreThisUpdate = true;
1878
+ } else {
1879
+ value = (_d = (_c = activated2.get) == null ? void 0 : _c.call(activated2)) != null ? _d : activated2.initial;
1880
+ }
1881
+ }
1882
+ wasPromise = wasPromise || isPromise(value);
1883
+ return value;
1884
+ },
1885
+ (e) => {
1886
+ const { value, nodes, refresh } = e;
1887
+ refreshFn = refresh;
1888
+ if (!ignoreThisUpdate) {
1889
+ if (!wasPromise || !globalState.isLoadingRemote) {
1890
+ if (wasPromise) {
1891
+ if (node.activationState) {
1892
+ const { initial } = node.activationState;
1893
+ if (value && isPromise(value)) {
1894
+ extractPromise(node, value, update);
1895
+ }
1896
+ if (isFunction(getNodeValue(node))) {
1897
+ setNodeValue(node, initial != null ? initial : void 0);
1898
+ }
1899
+ } else if (node.activated) {
1900
+ extractPromise(node, value, update);
1901
+ if (isFunction(getNodeValue(node))) {
1902
+ setNodeValue(node, void 0);
1903
+ }
2019
1904
  }
2020
- else {
2021
- value = (_d = (_c = activated.get) === null || _c === void 0 ? void 0 : _c.call(activated)) !== null && _d !== void 0 ? _d : activated.initial;
1905
+ } else {
1906
+ activatedValue = value;
1907
+ if (node.state.isLoaded.peek()) {
1908
+ node.isComputing = true;
1909
+ set(node, value);
1910
+ node.isComputing = false;
1911
+ } else {
1912
+ setNodeValue(node, value);
1913
+ node.state.assign({
1914
+ isLoaded: true,
1915
+ error: void 0
1916
+ });
2022
1917
  }
1918
+ }
2023
1919
  }
2024
- // value is undefined if it's in a persisted retry
2025
- wasPromise = wasPromise || isPromise(value);
2026
- return value;
2027
- }, (e) => {
2028
- const { value, nodes, refresh } = e;
2029
- refreshFn = refresh;
2030
- if (!ignoreThisUpdate) {
2031
- if (!wasPromise || !globalState.isLoadingRemote) {
2032
- if (wasPromise) {
2033
- if (node.activationState) {
2034
- const { initial } = node.activationState;
2035
- if (value && isPromise(value)) {
2036
- // Extract the promise to make it set the value/error when it comes in
2037
- extractPromise(node, value, update);
2038
- }
2039
- // Set this to undefined only if it's replacing the activation function,
2040
- // so we don't overwrite it if it already has real data from either local
2041
- // cache or a previous run
2042
- if (isFunction(getNodeValue(node))) {
2043
- setNodeValue(node, initial !== null && initial !== void 0 ? initial : undefined);
2044
- }
2045
- }
2046
- else if (node.activated) {
2047
- // Extract the promise to make it set the value/error when it comes in
2048
- extractPromise(node, value, update);
2049
- // Set this to undefined only if it's replacing the activation function,
2050
- // so we don't overwrite it if it already has real data from either local
2051
- // cache or a previous run
2052
- if (isFunction(getNodeValue(node))) {
2053
- setNodeValue(node, undefined);
2054
- }
2055
- }
2056
- }
2057
- else {
2058
- activatedValue = value;
2059
- if (node.state.isLoaded.peek()) {
2060
- node.isComputing = true;
2061
- set(node, value);
2062
- node.isComputing = false;
2063
- }
2064
- else {
2065
- setNodeValue(node, value);
2066
- node.state.assign({
2067
- isLoaded: true,
2068
- error: undefined,
2069
- });
2070
- }
2071
- }
2072
- }
2073
- disposes.forEach((fn) => fn());
2074
- disposes = [];
2075
- nodes === null || nodes === void 0 ? void 0 : nodes.forEach(({ node, track }) => {
2076
- disposes.push(onChange(node, markDirty, { immediate: true, trackingType: track }));
2077
- });
2078
- }
2079
- e.cancel = true;
2080
- }, { fromComputed: true });
2081
- return activatedValue;
1920
+ disposes.forEach((fn) => fn());
1921
+ disposes = [];
1922
+ nodes == null ? void 0 : nodes.forEach(({ node: node2, track }) => {
1923
+ disposes.push(onChange(node2, markDirty, { immediate: true, trackingType: track }));
1924
+ });
1925
+ }
1926
+ e.cancel = true;
1927
+ },
1928
+ { fromComputed: true }
1929
+ );
1930
+ return activatedValue;
2082
1931
  }
2083
1932
  function activateNodeBase(node, value) {
2084
- if (!node.state) {
2085
- node.state = createObservable({
2086
- isLoaded: false,
2087
- }, false, extractPromise, getProxy);
2088
- }
2089
- if (node.activationState) {
2090
- const { set: setFn, get: getFn, initial } = node.activationState;
2091
- value = getFn === null || getFn === void 0 ? void 0 : getFn();
2092
- if (value == undefined || value === null) {
2093
- value = initial;
2094
- }
2095
- if (setFn) {
2096
- let allChanges = [];
2097
- let latestValue = undefined;
2098
- let runNumber = 0;
2099
- const runChanges = (listenerParams) => {
2100
- // Don't call the set if this is the first value coming in
2101
- if (allChanges.length > 0) {
2102
- let changes;
2103
- let value;
2104
- let loading = false;
2105
- let remote = false;
2106
- let getPrevious;
2107
- if (listenerParams) {
2108
- changes = listenerParams.changes;
2109
- value = listenerParams.value;
2110
- loading = listenerParams.loading;
2111
- remote = listenerParams.remote;
2112
- getPrevious = listenerParams.getPrevious;
2113
- }
2114
- else {
2115
- // If this is called by flushPending then get the change array
2116
- // that we've been building up.
2117
- changes = allChanges;
2118
- value = latestValue;
2119
- getPrevious = createPreviousHandler(value, changes);
2120
- }
2121
- allChanges = [];
2122
- latestValue = undefined;
2123
- globalState.pendingNodes.delete(node);
2124
- runNumber++;
2125
- const thisRunNumber = runNumber;
2126
- const run = () => {
2127
- if (thisRunNumber !== runNumber) {
2128
- // set may get called multiple times before it loads so ignore any previous runs
2129
- return;
2130
- }
2131
- node.isComputing = true;
2132
- setFn({
2133
- value,
2134
- changes,
2135
- loading,
2136
- remote,
2137
- getPrevious,
2138
- });
2139
- node.isComputing = false;
2140
- };
2141
- whenReady(node.state.isLoaded, run);
2142
- }
2143
- };
2144
- const onChangeImmediate = ({ value, changes }) => {
2145
- if (!node.isComputing) {
2146
- if (changes.length > 1 || !isFunction(changes[0].prevAtPath)) {
2147
- latestValue = value;
2148
- if (allChanges.length > 0) {
2149
- changes = changes.filter((change) => !isArraySubset(allChanges[0].path, change.path));
2150
- }
2151
- allChanges.push(...changes);
2152
- globalState.pendingNodes.set(node, runChanges);
2153
- }
2154
- }
2155
- };
2156
- // Create an immediate listener to mark this node as pending. Then actually run
2157
- // the changes at the end of the batch so everything is properly batched.
2158
- // However, this can be short circuited if the user calls get() or peek()
2159
- // in which case the set needs to run immediately so that the values are up to date.
2160
- onChange(node, onChangeImmediate, { immediate: true });
2161
- onChange(node, runChanges);
2162
- }
2163
- }
2164
- const update = ({ value }) => {
2165
- if (!node.isComputing) {
1933
+ if (!node.state) {
1934
+ node.state = createObservable(
1935
+ {
1936
+ isLoaded: false
1937
+ },
1938
+ false,
1939
+ extractPromise,
1940
+ getProxy
1941
+ );
1942
+ }
1943
+ if (node.activationState) {
1944
+ const { set: setFn, get: getFn, initial } = node.activationState;
1945
+ value = getFn == null ? void 0 : getFn();
1946
+ if (value == void 0 || value === null) {
1947
+ value = initial;
1948
+ }
1949
+ if (setFn) {
1950
+ let allChanges = [];
1951
+ let latestValue = void 0;
1952
+ let runNumber = 0;
1953
+ const runChanges = (listenerParams) => {
1954
+ if (allChanges.length > 0) {
1955
+ let changes;
1956
+ let value2;
1957
+ let loading = false;
1958
+ let remote = false;
1959
+ let getPrevious;
1960
+ if (listenerParams) {
1961
+ changes = listenerParams.changes;
1962
+ value2 = listenerParams.value;
1963
+ loading = listenerParams.loading;
1964
+ remote = listenerParams.remote;
1965
+ getPrevious = listenerParams.getPrevious;
1966
+ } else {
1967
+ changes = allChanges;
1968
+ value2 = latestValue;
1969
+ getPrevious = createPreviousHandler(value2, changes);
1970
+ }
1971
+ allChanges = [];
1972
+ latestValue = void 0;
1973
+ globalState.pendingNodes.delete(node);
1974
+ runNumber++;
1975
+ const thisRunNumber = runNumber;
1976
+ const run = () => {
1977
+ if (thisRunNumber !== runNumber) {
1978
+ return;
1979
+ }
2166
1980
  node.isComputing = true;
2167
- set(node, value);
1981
+ setFn({
1982
+ value: value2,
1983
+ changes,
1984
+ loading,
1985
+ remote,
1986
+ getPrevious
1987
+ });
2168
1988
  node.isComputing = false;
1989
+ };
1990
+ whenReady(node.state.isLoaded, run);
2169
1991
  }
2170
- };
2171
- return { update, value };
1992
+ };
1993
+ const onChangeImmediate = ({ value: value2, changes }) => {
1994
+ if (!node.isComputing) {
1995
+ if (changes.length > 1 || !isFunction(changes[0].prevAtPath)) {
1996
+ latestValue = value2;
1997
+ if (allChanges.length > 0) {
1998
+ changes = changes.filter((change) => !isArraySubset(allChanges[0].path, change.path));
1999
+ }
2000
+ allChanges.push(...changes);
2001
+ globalState.pendingNodes.set(node, runChanges);
2002
+ }
2003
+ }
2004
+ };
2005
+ onChange(node, onChangeImmediate, { immediate: true });
2006
+ onChange(node, runChanges);
2007
+ }
2008
+ }
2009
+ const update = ({ value: value2 }) => {
2010
+ if (!node.isComputing) {
2011
+ node.isComputing = true;
2012
+ set(node, value2);
2013
+ node.isComputing = false;
2014
+ }
2015
+ };
2016
+ return { update, value };
2172
2017
  }
2173
2018
  function setToObservable(node, value) {
2174
- var _a;
2175
- // If the computed is a proxy to another observable
2176
- // link it to the target observable
2177
- const linkedNode = getNode(value);
2178
- if (linkedNode !== node && (linkedNode === null || linkedNode === void 0 ? void 0 : linkedNode.linkedToNode) !== node) {
2179
- node.linkedToNode = linkedNode;
2180
- linkedNode.linkedFromNodes || (linkedNode.linkedFromNodes = new Set());
2181
- linkedNode.linkedFromNodes.add(node);
2182
- (_a = node.linkedToNodeDispose) === null || _a === void 0 ? void 0 : _a.call(node);
2183
- node.linkedToNodeDispose = onChange(linkedNode, () => {
2184
- value = peekInternal(linkedNode);
2185
- set(node, value);
2186
- }, { initial: true }, new Set([node]));
2187
- }
2188
- return value;
2019
+ var _a;
2020
+ const linkedNode = getNode(value);
2021
+ if (linkedNode !== node && (linkedNode == null ? void 0 : linkedNode.linkedToNode) !== node) {
2022
+ node.linkedToNode = linkedNode;
2023
+ linkedNode.linkedFromNodes || (linkedNode.linkedFromNodes = /* @__PURE__ */ new Set());
2024
+ linkedNode.linkedFromNodes.add(node);
2025
+ (_a = node.linkedToNodeDispose) == null ? void 0 : _a.call(node);
2026
+ node.linkedToNodeDispose = onChange(
2027
+ linkedNode,
2028
+ () => {
2029
+ value = peekInternal(linkedNode);
2030
+ set(node, value);
2031
+ },
2032
+ { initial: true },
2033
+ /* @__PURE__ */ new Set([node])
2034
+ );
2035
+ }
2036
+ return value;
2189
2037
  }
2190
2038
  function recursivelyAutoActivate(obj, node) {
2191
- if (isObject(obj) || isArray(obj)) {
2192
- const pathStack = []; // Maintain a stack for path tracking
2193
- const getNodeAtPath = () => {
2194
- var _a;
2195
- let childNode = node;
2196
- for (let i = 0; i < pathStack.length; i++) {
2197
- const { key } = pathStack[i];
2198
- const value = (_a = getNodeValue(childNode)) === null || _a === void 0 ? void 0 : _a[key];
2199
- childNode = getChildNode(childNode, key, isFunction(value) ? value : undefined);
2200
- peekInternal(childNode);
2201
- }
2202
- return childNode;
2203
- };
2204
- recursivelyAutoActivateInner(obj, pathStack, getNodeAtPath);
2205
- }
2206
- }
2207
- function recursivelyAutoActivateInner(obj, pathStack, getNodeAtPath) {
2208
- var _a;
2209
- for (const key in obj) {
2210
- if (hasOwnProperty.call(obj, key)) {
2211
- const value = obj[key];
2212
- if (isObservable(value)) {
2213
- const childNode = getNodeAtPath();
2214
- extractFunctionOrComputed(childNode, key, value);
2215
- delete childNode.lazy;
2216
- }
2217
- else {
2218
- const linkedOptions = isFunction(value) && ((_a = value.prototype) === null || _a === void 0 ? void 0 : _a[symbolLinked]);
2219
- if (linkedOptions) {
2220
- const activate = linkedOptions.activate;
2221
- if (!activate || activate === 'auto') {
2222
- const childNode = getNodeAtPath();
2223
- peek(getChildNode(childNode, key, value));
2224
- }
2225
- }
2226
- }
2227
- if (typeof value === 'object') {
2228
- pathStack.push({ key, value });
2229
- recursivelyAutoActivateInner(value, pathStack, getNodeAtPath); // Recursively traverse
2230
- pathStack.pop();
2231
- }
2232
- }
2233
- }
2039
+ if (isObject(obj) || isArray(obj)) {
2040
+ const pathStack = [];
2041
+ const getNodeAtPath2 = () => {
2042
+ var _a;
2043
+ let childNode = node;
2044
+ for (let i = 0; i < pathStack.length; i++) {
2045
+ const { key } = pathStack[i];
2046
+ const value = (_a = getNodeValue(childNode)) == null ? void 0 : _a[key];
2047
+ childNode = getChildNode(childNode, key, isFunction(value) ? value : void 0);
2048
+ peekInternal(childNode);
2049
+ }
2050
+ return childNode;
2051
+ };
2052
+ recursivelyAutoActivateInner(obj, pathStack, getNodeAtPath2);
2053
+ }
2054
+ }
2055
+ function recursivelyAutoActivateInner(obj, pathStack, getNodeAtPath2) {
2056
+ var _a;
2057
+ for (const key in obj) {
2058
+ if (hasOwnProperty.call(obj, key)) {
2059
+ const value = obj[key];
2060
+ if (isObservable(value)) {
2061
+ const childNode = getNodeAtPath2();
2062
+ extractFunctionOrComputed(childNode, key, value);
2063
+ delete childNode.lazy;
2064
+ } else {
2065
+ const linkedOptions = isFunction(value) && ((_a = value.prototype) == null ? void 0 : _a[symbolLinked]);
2066
+ if (linkedOptions) {
2067
+ const activate = linkedOptions.activate;
2068
+ if (!activate || activate === "auto") {
2069
+ const childNode = getNodeAtPath2();
2070
+ peek(getChildNode(childNode, key, value));
2071
+ }
2072
+ }
2073
+ }
2074
+ if (typeof value === "object") {
2075
+ pathStack.push({ key, value });
2076
+ recursivelyAutoActivateInner(value, pathStack, getNodeAtPath2);
2077
+ pathStack.pop();
2078
+ }
2079
+ }
2080
+ }
2234
2081
  }
2235
2082
 
2236
- const fns = ['get', 'set', 'peek', 'onChange', 'toggle'];
2083
+ // src/ObservablePrimitive.ts
2084
+ var fns = ["get", "set", "peek", "onChange", "toggle"];
2237
2085
  function ObservablePrimitiveClass(node) {
2238
- this._node = node;
2239
- // Bind to this
2240
- for (let i = 0; i < fns.length; i++) {
2241
- const key = fns[i];
2242
- this[key] = this[key].bind(this);
2243
- }
2086
+ this._node = node;
2087
+ for (let i = 0; i < fns.length; i++) {
2088
+ const key = fns[i];
2089
+ this[key] = this[key].bind(this);
2090
+ }
2244
2091
  }
2245
- // Add observable functions to prototype
2246
2092
  function proto(key, fn) {
2247
- ObservablePrimitiveClass.prototype[key] = function (...args) {
2248
- return fn.call(this, this._node, ...args);
2249
- };
2093
+ ObservablePrimitiveClass.prototype[key] = function(...args) {
2094
+ return fn.call(this, this._node, ...args);
2095
+ };
2250
2096
  }
2251
- proto('peek', (node) => {
2252
- flushPending();
2253
- return peek(node);
2097
+ proto("peek", (node) => {
2098
+ flushPending();
2099
+ return peek(node);
2254
2100
  });
2255
- proto('get', (node, options) => {
2256
- flushPending();
2257
- return get(node, options);
2101
+ proto("get", (node, options) => {
2102
+ flushPending();
2103
+ return get(node, options);
2258
2104
  });
2259
- proto('set', set);
2260
- proto('onChange', onChange);
2261
- // Getters
2105
+ proto("set", set);
2106
+ proto("onChange", onChange);
2262
2107
  Object.defineProperty(ObservablePrimitiveClass.prototype, symbolGetNode, {
2263
- configurable: true,
2264
- get() {
2265
- return this._node;
2266
- },
2108
+ configurable: true,
2109
+ get() {
2110
+ return this._node;
2111
+ }
2267
2112
  });
2268
- ObservablePrimitiveClass.prototype.toggle = function () {
2269
- const value = this.peek();
2270
- if (value === undefined || value === null || isBoolean(value)) {
2271
- this.set(!value);
2272
- }
2273
- else if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
2274
- throw new Error('[legend-state] Cannot toggle a non-boolean value');
2275
- }
2113
+ ObservablePrimitiveClass.prototype.toggle = function() {
2114
+ const value = this.peek();
2115
+ if (value === void 0 || value === null || isBoolean(value)) {
2116
+ this.set(!value);
2117
+ } else if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") {
2118
+ throw new Error("[legend-state] Cannot toggle a non-boolean value");
2119
+ }
2276
2120
  };
2277
- ObservablePrimitiveClass.prototype.delete = function () {
2278
- this.set(undefined);
2279
- return this;
2121
+ ObservablePrimitiveClass.prototype.delete = function() {
2122
+ this.set(void 0);
2123
+ return this;
2280
2124
  };
2281
2125
 
2126
+ // src/observable.ts
2282
2127
  function observable(value) {
2283
- return createObservable(value, false, extractPromise, getProxy, ObservablePrimitiveClass);
2128
+ return createObservable(value, false, extractPromise, getProxy, ObservablePrimitiveClass);
2284
2129
  }
2285
2130
  function observablePrimitive(value) {
2286
- return createObservable(value, true, extractPromise, getProxy, ObservablePrimitiveClass);
2131
+ return createObservable(value, true, extractPromise, getProxy, ObservablePrimitiveClass);
2287
2132
  }
2288
2133
  function syncState(obs) {
2289
- const node = getNode(obs);
2290
- if (!node.state) {
2291
- peekInternal(node);
2292
- }
2293
- if (!node.state) {
2294
- node.state = observable({});
2295
- }
2296
- return node.state;
2134
+ const node = getNode(obs);
2135
+ if (!node.state) {
2136
+ peekInternal(node);
2137
+ }
2138
+ if (!node.state) {
2139
+ node.state = observable({});
2140
+ }
2141
+ return node.state;
2297
2142
  }
2298
2143
 
2299
- function computed(get, set) {
2300
- return observable(set ? linked({ get: get, set: ({ value }) => set(value) }) : get);
2144
+ // src/computed.ts
2145
+ function computed(get2, set2) {
2146
+ return observable(
2147
+ set2 ? linked({ get: get2, set: ({ value }) => set2(value) }) : get2
2148
+ );
2301
2149
  }
2302
2150
 
2303
- function configureLegendState({ observableFunctions, observableProperties: observableProperties$1, jsonReplacer, jsonReviver, }) {
2304
- if (observableFunctions) {
2305
- for (const key in observableFunctions) {
2306
- const fn = observableFunctions[key];
2307
- observableFns.set(key, fn);
2308
- ObservablePrimitiveClass.prototype[key] = function (...args) {
2309
- return fn.call(this, this._node, ...args);
2310
- };
2311
- }
2312
- }
2313
- if (observableProperties$1) {
2314
- for (const key in observableProperties$1) {
2315
- const fns = observableProperties$1[key];
2316
- observableProperties.set(key, fns);
2317
- Object.defineProperty(ObservablePrimitiveClass.prototype, key, {
2318
- configurable: true,
2319
- get() {
2320
- return fns.get.call(this, this._node);
2321
- },
2322
- set(value) {
2323
- return fns.set.call(this, this._node, value);
2324
- },
2325
- });
2151
+ // src/config.ts
2152
+ function configureLegendState({
2153
+ observableFunctions,
2154
+ observableProperties: observableProperties2,
2155
+ jsonReplacer,
2156
+ jsonReviver
2157
+ }) {
2158
+ if (observableFunctions) {
2159
+ for (const key in observableFunctions) {
2160
+ const fn = observableFunctions[key];
2161
+ observableFns.set(key, fn);
2162
+ ObservablePrimitiveClass.prototype[key] = function(...args) {
2163
+ return fn.call(this, this._node, ...args);
2164
+ };
2165
+ }
2166
+ }
2167
+ if (observableProperties2) {
2168
+ for (const key in observableProperties2) {
2169
+ const fns2 = observableProperties2[key];
2170
+ observableProperties.set(key, fns2);
2171
+ Object.defineProperty(ObservablePrimitiveClass.prototype, key, {
2172
+ configurable: true,
2173
+ get() {
2174
+ return fns2.get.call(this, this._node);
2175
+ },
2176
+ set(value) {
2177
+ return fns2.set.call(this, this._node, value);
2326
2178
  }
2179
+ });
2327
2180
  }
2328
- if (jsonReplacer) {
2329
- globalState.replacer = jsonReplacer;
2330
- }
2331
- if (jsonReviver) {
2332
- globalState.reviver = jsonReviver;
2333
- }
2181
+ }
2182
+ if (jsonReplacer) {
2183
+ globalState.replacer = jsonReplacer;
2184
+ }
2185
+ if (jsonReviver) {
2186
+ globalState.reviver = jsonReviver;
2187
+ }
2334
2188
  }
2335
2189
 
2190
+ // src/event.ts
2336
2191
  function event() {
2337
- // event simply wraps around a number observable
2338
- // which increments its value to dispatch change events
2339
- const obs = observable(0);
2340
- const node = getNode(obs);
2341
- node.isEvent = true;
2342
- return {
2343
- fire: function () {
2344
- // Notify increments the value so that the observable changes
2345
- obs.set((v) => v + 1);
2346
- },
2347
- on: function (cb) {
2348
- return obs.onChange(cb);
2349
- },
2350
- get: function () {
2351
- // Return the value so that when will be truthy
2352
- return obs.get();
2353
- },
2354
- // @ts-expect-error eslint doesn't like adding symbols to the object but this does work
2355
- [symbolGetNode]: node,
2356
- };
2192
+ const obs = observable(0);
2193
+ const node = getNode(obs);
2194
+ node.isEvent = true;
2195
+ return {
2196
+ fire: function() {
2197
+ obs.set((v) => v + 1);
2198
+ },
2199
+ on: function(cb) {
2200
+ return obs.onChange(cb);
2201
+ },
2202
+ get: function() {
2203
+ return obs.get();
2204
+ },
2205
+ // @ts-expect-error eslint doesn't like adding symbols to the object but this does work
2206
+ [symbolGetNode]: node
2207
+ };
2357
2208
  }
2358
2209
 
2359
- function proxy(get, set) {
2360
- return observable((key) => set
2361
- ? linked({
2362
- get: () => get(key),
2363
- set: ({ value }) => set(key, value),
2364
- })
2365
- : get(key));
2210
+ // src/proxy.ts
2211
+ function proxy(get2, set2) {
2212
+ return observable(
2213
+ (key) => set2 ? linked({
2214
+ get: () => get2(key),
2215
+ set: ({ value }) => set2(key, value)
2216
+ }) : get2(key)
2217
+ );
2366
2218
  }
2367
2219
 
2220
+ // src/retry.ts
2368
2221
  function calculateRetryDelay(retryOptions, attemptNum) {
2369
- const { backoff, delay = 1000, infinite, times = 3, maxDelay = 30000 } = retryOptions;
2370
- if (infinite || attemptNum < times) {
2371
- const delayTime = Math.min(delay * (backoff === 'constant' ? 1 : 2 ** attemptNum), maxDelay);
2372
- return delayTime;
2373
- }
2374
- return null;
2222
+ const { backoff, delay = 1e3, infinite, times = 3, maxDelay = 3e4 } = retryOptions;
2223
+ if (infinite || attemptNum < times) {
2224
+ const delayTime = Math.min(delay * (backoff === "constant" ? 1 : 2 ** attemptNum), maxDelay);
2225
+ return delayTime;
2226
+ }
2227
+ return null;
2375
2228
  }
2376
2229
  function createRetryTimeout(retryOptions, attemptNum, fn) {
2377
- const delayTime = calculateRetryDelay(retryOptions, attemptNum);
2378
- if (delayTime) {
2379
- return setTimeout(fn, delayTime);
2380
- }
2230
+ const delayTime = calculateRetryDelay(retryOptions, attemptNum);
2231
+ if (delayTime) {
2232
+ return setTimeout(fn, delayTime);
2233
+ }
2381
2234
  }
2382
2235
  function runWithRetry(node, state, fn) {
2383
- const { waitFor } = node.activationState;
2384
- const { retry } = state;
2385
- const e = { cancel: false };
2386
- let value = undefined;
2387
- if (waitFor) {
2388
- value = whenReady(waitFor, () => {
2389
- node.activationState.waitFor = undefined;
2390
- return fn(e);
2391
- });
2392
- }
2393
- else {
2394
- value = fn(e);
2395
- }
2396
- if (isPromise(value) && retry) {
2397
- let timeoutRetry;
2398
- return new Promise((resolve) => {
2399
- const run = () => {
2400
- value
2401
- .then((val) => {
2402
- node.activationState.persistedRetry = false;
2403
- resolve(val);
2404
- })
2405
- .catch(() => {
2406
- state.attemptNum++;
2407
- if (timeoutRetry) {
2408
- clearTimeout(timeoutRetry);
2409
- }
2410
- if (!e.cancel) {
2411
- timeoutRetry = createRetryTimeout(retry, state.attemptNum, () => {
2412
- value = fn(e);
2413
- run();
2414
- });
2415
- }
2416
- })
2417
- .finally(() => {
2418
- node.activationState.persistedRetry = false;
2419
- });
2420
- };
2421
- run();
2236
+ const { waitFor } = node.activationState;
2237
+ const { retry } = state;
2238
+ const e = { cancel: false };
2239
+ let value = void 0;
2240
+ if (waitFor) {
2241
+ value = whenReady(waitFor, () => {
2242
+ node.activationState.waitFor = void 0;
2243
+ return fn(e);
2244
+ });
2245
+ } else {
2246
+ value = fn(e);
2247
+ }
2248
+ if (isPromise(value) && retry) {
2249
+ let timeoutRetry;
2250
+ return new Promise((resolve) => {
2251
+ const run = () => {
2252
+ value.then((val) => {
2253
+ node.activationState.persistedRetry = false;
2254
+ resolve(val);
2255
+ }).catch(() => {
2256
+ state.attemptNum++;
2257
+ if (timeoutRetry) {
2258
+ clearTimeout(timeoutRetry);
2259
+ }
2260
+ if (!e.cancel) {
2261
+ timeoutRetry = createRetryTimeout(retry, state.attemptNum, () => {
2262
+ value = fn(e);
2263
+ run();
2264
+ });
2265
+ }
2266
+ }).finally(() => {
2267
+ node.activationState.persistedRetry = false;
2422
2268
  });
2423
- }
2424
- return value;
2269
+ };
2270
+ run();
2271
+ });
2272
+ }
2273
+ return value;
2425
2274
  }
2426
2275
 
2427
- const internal = {
2428
- createPreviousHandler,
2429
- clone,
2430
- ensureNodeValue,
2431
- findIDKey,
2432
- get,
2433
- getNode,
2434
- getNodeValue,
2435
- getPathType,
2436
- getProxy,
2437
- getValueAtPath: getValueAtPath$1,
2438
- globalState,
2439
- initializePathType,
2440
- observableFns,
2441
- optimized,
2442
- peek,
2443
- runWithRetry,
2444
- safeParse,
2445
- safeStringify,
2446
- set,
2447
- setAtPath,
2448
- setNodeValue,
2449
- symbolLinked,
2450
- symbolDelete,
2451
- tracking,
2276
+ // index.ts
2277
+ var internal = {
2278
+ createPreviousHandler,
2279
+ clone,
2280
+ ensureNodeValue,
2281
+ findIDKey,
2282
+ get,
2283
+ getNode,
2284
+ getNodeValue,
2285
+ getPathType,
2286
+ getProxy,
2287
+ getValueAtPath,
2288
+ globalState,
2289
+ initializePathType,
2290
+ observableFns,
2291
+ optimized,
2292
+ peek,
2293
+ runWithRetry,
2294
+ safeParse,
2295
+ safeStringify,
2296
+ set,
2297
+ setAtPath,
2298
+ setNodeValue,
2299
+ symbolLinked,
2300
+ symbolDelete,
2301
+ tracking
2452
2302
  };
2453
2303
 
2454
2304
  export { ObservablePrimitiveClass, applyChange, applyChanges, batch, beginBatch, beginTracking, computeSelector, computed, configureLegendState, constructObjectWithPath, deconstructObjectWithPath, endBatch, endTracking, event, findIDKey, getNode, getNodeValue, getObservableIndex, hasOwnProperty, internal, isArray, isBoolean, isDate, isEmpty, isFunction, isMap, isNullOrUndefined, isNumber, isObject, isObservable, isObservableValueReady, isObserved, isPrimitive, isPromise, isString, isSymbol, linked, mergeIntoObservable, observable, observablePrimitive, observe, opaqueObject, optimized, proxy, setAtPath, setInObservableAtPath, setSilently, setupTracking, shouldIgnoreUnobserved, symbolDelete, syncState, trackSelector, tracking, updateTracking, when, whenReady };
2455
- //# sourceMappingURL=index.mjs.map