@legendapp/state 3.0.0-beta.30 → 3.0.0-beta.32

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.
package/README.md CHANGED
@@ -72,7 +72,7 @@ Legend-State includes a powerful [sync and persistence system](../../usage/persi
72
72
  Local persistence plugins for the browser and React Native are included, with sync plugins for [Keel](https://www.keel.so), [Supabase](https://www.supabase.com), [TanStack Query](https://tanstack.com/query), and `fetch`.
73
73
 
74
74
  ```js
75
- const state$ = observable(
75
+ const state$ = observable({
76
76
  users: syncedKeel({
77
77
  list: queries.getUsers,
78
78
  create: mutations.createUsers,
@@ -87,7 +87,7 @@ const state$ = observable(
87
87
  }),
88
88
  // direct link to my user within the users observable
89
89
  me: () => state$.users['myuid']
90
- )
90
+ })
91
91
 
92
92
  observe(() => {
93
93
  // get() activates through to state$.users and starts syncing.
package/index.d.mts CHANGED
@@ -111,6 +111,7 @@ declare function setNodeValue(node: NodeInfo, newValue: any): {
111
111
  parentValue: any;
112
112
  };
113
113
  declare function getNodeValue(node: NodeInfo): any;
114
+ declare function getChildNode(node: NodeInfo, key: string, asFunction?: Function): NodeInfo;
114
115
  declare function ensureNodeValue(node: NodeInfo): any;
115
116
  declare function findIDKey(obj: unknown | undefined, node: NodeInfo): string | ((value: any) => string) | undefined;
116
117
  declare function getKeys(obj: Record<any, any> | Array<any> | undefined, isArr: boolean, isMap: boolean, isSet: boolean): string[];
@@ -148,7 +149,7 @@ interface Change {
148
149
  type RecordValue<T> = T extends Record<string, infer t> ? t : never;
149
150
  type ArrayValue<T> = T extends Array<infer t> ? t : never;
150
151
  type ObservableValue<T> = T extends Observable<infer t> ? t : never;
151
- type Selector<T> = ObservableParam<T> | ObservableEvent | (() => T) | T;
152
+ type Selector<T> = ObservableParam<T> | ObservableEvent | (() => ObservableParam<T>) | (() => T) | T;
152
153
  type ClassConstructor<I, Args extends any[] = any[]> = new (...args: Args) => I;
153
154
  type ObservableListenerDispose = () => void;
154
155
  interface ObservableRoot {
@@ -304,6 +305,8 @@ declare function getProxy(node: NodeInfo, p?: string, asFunction?: Function): Ob
304
305
  declare function set(node: NodeInfo, newValue?: any): void;
305
306
  declare function get(node: NodeInfo, options?: TrackingType | GetOptions): any;
306
307
  declare function peek(node: NodeInfo): any;
308
+ declare function deactivateNode(node: NodeInfo): void;
309
+ declare function reactivateNode(node: NodeInfo, lazyFn: Function): void;
307
310
  declare function isObserved(node: NodeInfo): boolean;
308
311
  declare function shouldIgnoreUnobserved(node: NodeInfo, refreshFn: () => void): true | undefined;
309
312
 
@@ -411,10 +414,12 @@ declare function registerMiddleware(node: NodeInfo, type: MiddlewareEventType, h
411
414
  declare const internal: {
412
415
  createPreviousHandler: typeof createPreviousHandler;
413
416
  clone: typeof clone;
417
+ deactivateNode: typeof deactivateNode;
414
418
  deepMerge: typeof deepMerge;
415
419
  ensureNodeValue: typeof ensureNodeValue;
416
420
  findIDKey: typeof findIDKey;
417
421
  get: typeof get;
422
+ getChildNode: typeof getChildNode;
418
423
  getKeys: typeof getKeys;
419
424
  getNode: typeof getNode;
420
425
  getNodeValue: typeof getNodeValue;
@@ -442,6 +447,7 @@ declare const internal: {
442
447
  observableFns: Map<string, (node: NodeInfo, ...args: any[]) => any>;
443
448
  optimized: symbol;
444
449
  peek: typeof peek;
450
+ reactivateNode: typeof reactivateNode;
445
451
  registerMiddleware: typeof registerMiddleware;
446
452
  safeParse: typeof safeParse;
447
453
  safeStringify: typeof safeStringify;
package/index.d.ts CHANGED
@@ -111,6 +111,7 @@ declare function setNodeValue(node: NodeInfo, newValue: any): {
111
111
  parentValue: any;
112
112
  };
113
113
  declare function getNodeValue(node: NodeInfo): any;
114
+ declare function getChildNode(node: NodeInfo, key: string, asFunction?: Function): NodeInfo;
114
115
  declare function ensureNodeValue(node: NodeInfo): any;
115
116
  declare function findIDKey(obj: unknown | undefined, node: NodeInfo): string | ((value: any) => string) | undefined;
116
117
  declare function getKeys(obj: Record<any, any> | Array<any> | undefined, isArr: boolean, isMap: boolean, isSet: boolean): string[];
@@ -148,7 +149,7 @@ interface Change {
148
149
  type RecordValue<T> = T extends Record<string, infer t> ? t : never;
149
150
  type ArrayValue<T> = T extends Array<infer t> ? t : never;
150
151
  type ObservableValue<T> = T extends Observable<infer t> ? t : never;
151
- type Selector<T> = ObservableParam<T> | ObservableEvent | (() => T) | T;
152
+ type Selector<T> = ObservableParam<T> | ObservableEvent | (() => ObservableParam<T>) | (() => T) | T;
152
153
  type ClassConstructor<I, Args extends any[] = any[]> = new (...args: Args) => I;
153
154
  type ObservableListenerDispose = () => void;
154
155
  interface ObservableRoot {
@@ -304,6 +305,8 @@ declare function getProxy(node: NodeInfo, p?: string, asFunction?: Function): Ob
304
305
  declare function set(node: NodeInfo, newValue?: any): void;
305
306
  declare function get(node: NodeInfo, options?: TrackingType | GetOptions): any;
306
307
  declare function peek(node: NodeInfo): any;
308
+ declare function deactivateNode(node: NodeInfo): void;
309
+ declare function reactivateNode(node: NodeInfo, lazyFn: Function): void;
307
310
  declare function isObserved(node: NodeInfo): boolean;
308
311
  declare function shouldIgnoreUnobserved(node: NodeInfo, refreshFn: () => void): true | undefined;
309
312
 
@@ -411,10 +414,12 @@ declare function registerMiddleware(node: NodeInfo, type: MiddlewareEventType, h
411
414
  declare const internal: {
412
415
  createPreviousHandler: typeof createPreviousHandler;
413
416
  clone: typeof clone;
417
+ deactivateNode: typeof deactivateNode;
414
418
  deepMerge: typeof deepMerge;
415
419
  ensureNodeValue: typeof ensureNodeValue;
416
420
  findIDKey: typeof findIDKey;
417
421
  get: typeof get;
422
+ getChildNode: typeof getChildNode;
418
423
  getKeys: typeof getKeys;
419
424
  getNode: typeof getNode;
420
425
  getNodeValue: typeof getNodeValue;
@@ -442,6 +447,7 @@ declare const internal: {
442
447
  observableFns: Map<string, (node: NodeInfo, ...args: any[]) => any>;
443
448
  optimized: symbol;
444
449
  peek: typeof peek;
450
+ reactivateNode: typeof reactivateNode;
445
451
  registerMiddleware: typeof registerMiddleware;
446
452
  safeParse: typeof safeParse;
447
453
  safeStringify: typeof safeStringify;
package/index.js CHANGED
@@ -2007,11 +2007,14 @@ function checkProperty(value, key) {
2007
2007
  return value[key];
2008
2008
  }
2009
2009
  }
2010
- function reactivateNode(node, lazyFn) {
2010
+ function deactivateNode(node) {
2011
2011
  var _a, _b;
2012
2012
  (_a = node.activatedObserveDispose) == null ? void 0 : _a.call(node);
2013
2013
  (_b = node.linkedToNodeDispose) == null ? void 0 : _b.call(node);
2014
2014
  node.activatedObserveDispose = node.linkedToNodeDispose = node.linkedToNode = void 0;
2015
+ }
2016
+ function reactivateNode(node, lazyFn) {
2017
+ deactivateNode(node);
2015
2018
  node.lazyFn = lazyFn;
2016
2019
  node.lazy = true;
2017
2020
  }
@@ -2059,7 +2062,7 @@ function activateNodeFunction(node, lazyFn) {
2059
2062
  node.dirtyFn = refreshFn;
2060
2063
  globalState.dirtyNodes.add(node);
2061
2064
  }
2062
- node.activatedObserveDispose = observe(
2065
+ const observeDispose = observe(
2063
2066
  () => {
2064
2067
  var _a, _b, _c, _d;
2065
2068
  if (isFirst) {
@@ -2162,6 +2165,10 @@ function activateNodeFunction(node, lazyFn) {
2162
2165
  },
2163
2166
  { fromComputed: true }
2164
2167
  );
2168
+ node.activatedObserveDispose = () => {
2169
+ observeDispose == null ? void 0 : observeDispose();
2170
+ disposes.forEach((fn) => fn());
2171
+ };
2165
2172
  return activatedValue;
2166
2173
  }
2167
2174
  function activateNodeBase(node, value) {
@@ -2448,10 +2455,12 @@ function syncState(obs) {
2448
2455
  var internal = {
2449
2456
  createPreviousHandler,
2450
2457
  clone,
2458
+ deactivateNode,
2451
2459
  deepMerge,
2452
2460
  ensureNodeValue,
2453
2461
  findIDKey,
2454
2462
  get,
2463
+ getChildNode,
2455
2464
  getKeys,
2456
2465
  getNode,
2457
2466
  getNodeValue,
@@ -2465,6 +2474,7 @@ var internal = {
2465
2474
  observableFns,
2466
2475
  optimized,
2467
2476
  peek,
2477
+ reactivateNode,
2468
2478
  registerMiddleware,
2469
2479
  safeParse,
2470
2480
  safeStringify,
package/index.mjs CHANGED
@@ -2005,11 +2005,14 @@ function checkProperty(value, key) {
2005
2005
  return value[key];
2006
2006
  }
2007
2007
  }
2008
- function reactivateNode(node, lazyFn) {
2008
+ function deactivateNode(node) {
2009
2009
  var _a, _b;
2010
2010
  (_a = node.activatedObserveDispose) == null ? void 0 : _a.call(node);
2011
2011
  (_b = node.linkedToNodeDispose) == null ? void 0 : _b.call(node);
2012
2012
  node.activatedObserveDispose = node.linkedToNodeDispose = node.linkedToNode = void 0;
2013
+ }
2014
+ function reactivateNode(node, lazyFn) {
2015
+ deactivateNode(node);
2013
2016
  node.lazyFn = lazyFn;
2014
2017
  node.lazy = true;
2015
2018
  }
@@ -2057,7 +2060,7 @@ function activateNodeFunction(node, lazyFn) {
2057
2060
  node.dirtyFn = refreshFn;
2058
2061
  globalState.dirtyNodes.add(node);
2059
2062
  }
2060
- node.activatedObserveDispose = observe(
2063
+ const observeDispose = observe(
2061
2064
  () => {
2062
2065
  var _a, _b, _c, _d;
2063
2066
  if (isFirst) {
@@ -2160,6 +2163,10 @@ function activateNodeFunction(node, lazyFn) {
2160
2163
  },
2161
2164
  { fromComputed: true }
2162
2165
  );
2166
+ node.activatedObserveDispose = () => {
2167
+ observeDispose == null ? void 0 : observeDispose();
2168
+ disposes.forEach((fn) => fn());
2169
+ };
2163
2170
  return activatedValue;
2164
2171
  }
2165
2172
  function activateNodeBase(node, value) {
@@ -2446,10 +2453,12 @@ function syncState(obs) {
2446
2453
  var internal = {
2447
2454
  createPreviousHandler,
2448
2455
  clone,
2456
+ deactivateNode,
2449
2457
  deepMerge,
2450
2458
  ensureNodeValue,
2451
2459
  findIDKey,
2452
2460
  get,
2461
+ getChildNode,
2453
2462
  getKeys,
2454
2463
  getNode,
2455
2464
  getNodeValue,
@@ -2463,6 +2472,7 @@ var internal = {
2463
2472
  observableFns,
2464
2473
  optimized,
2465
2474
  peek,
2475
+ reactivateNode,
2466
2476
  registerMiddleware,
2467
2477
  safeParse,
2468
2478
  safeStringify,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@legendapp/state",
3
- "version": "3.0.0-beta.30",
3
+ "version": "3.0.0-beta.32",
4
4
  "description": "legend-state",
5
5
  "sideEffects": false,
6
6
  "private": false,
package/react.js CHANGED
@@ -411,38 +411,6 @@ function Switch({
411
411
  const child = children[useSelector(value)];
412
412
  return (_b = child ? child() : (_a = children["default"]) == null ? void 0 : _a.call(children)) != null ? _b : null;
413
413
  }
414
- function useObservable(initialValue, deps) {
415
- var _a;
416
- const ref = React.useRef({});
417
- ref.current.value = initialValue;
418
- const depsObs$ = deps ? useObservable(deps) : void 0;
419
- if (!((_a = ref.current) == null ? void 0 : _a.obs$)) {
420
- const value = depsObs$ ? state.isFunction(initialValue) && initialValue.length === 1 ? (p) => {
421
- depsObs$.get();
422
- return ref.current.value(p);
423
- } : () => {
424
- depsObs$.get();
425
- return state.computeSelector(ref.current.value);
426
- } : initialValue;
427
- ref.current.obs$ = state.observable(value);
428
- }
429
- if (depsObs$) {
430
- depsObs$.set(deps);
431
- }
432
- return ref.current.obs$;
433
- }
434
-
435
- // src/react/useComputed.ts
436
- function useComputed(get, set, deps) {
437
- if (!deps && state.isArray(set)) {
438
- deps = set;
439
- set = void 0;
440
- }
441
- return useObservable(
442
- set ? state.linked({ get, set: ({ value }) => set(value) }) : get,
443
- deps
444
- );
445
- }
446
414
  var useEffectOnce = (effect, deps) => {
447
415
  if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") {
448
416
  const refDispose = React.useRef({ num: 0 });
@@ -471,6 +439,8 @@ var useEffectOnce = (effect, deps) => {
471
439
  React.useEffect(effect, deps);
472
440
  }
473
441
  };
442
+
443
+ // src/react/useMount.ts
474
444
  function useMount(fn) {
475
445
  return useEffectOnce(() => {
476
446
  const ret = fn();
@@ -481,6 +451,54 @@ function useMount(fn) {
481
451
  }
482
452
  var useMountOnce = useMount;
483
453
 
454
+ // src/react/useUnmount.ts
455
+ function useUnmount(fn) {
456
+ return useMount(() => fn);
457
+ }
458
+ var useUnmountOnce = useUnmount;
459
+
460
+ // src/react/useObservable.ts
461
+ var { deactivateNode } = state.internal;
462
+ function useObservable(initialValue, deps) {
463
+ var _a;
464
+ const ref = React.useRef({});
465
+ ref.current.value = initialValue;
466
+ const depsObs$ = deps ? useObservable(deps) : void 0;
467
+ if (!((_a = ref.current) == null ? void 0 : _a.obs$)) {
468
+ const value = depsObs$ ? state.isFunction(initialValue) && initialValue.length === 1 ? (p) => {
469
+ depsObs$.get();
470
+ return ref.current.value(p);
471
+ } : () => {
472
+ depsObs$.get();
473
+ return state.computeSelector(ref.current.value);
474
+ } : initialValue;
475
+ ref.current.obs$ = state.observable(value);
476
+ }
477
+ if (depsObs$) {
478
+ depsObs$.set(deps);
479
+ }
480
+ useUnmount(() => {
481
+ const obs = ref.current.obs$;
482
+ if (obs) {
483
+ const node = state.getNode(obs);
484
+ deactivateNode(node);
485
+ }
486
+ });
487
+ return ref.current.obs$;
488
+ }
489
+
490
+ // src/react/useComputed.ts
491
+ function useComputed(get, set, deps) {
492
+ if (!deps && state.isArray(set)) {
493
+ deps = set;
494
+ set = void 0;
495
+ }
496
+ return useObservable(
497
+ set ? state.linked({ get, set: ({ value }) => set(value) }) : get,
498
+ deps
499
+ );
500
+ }
501
+
484
502
  // src/react/useIsMounted.ts
485
503
  function useIsMounted() {
486
504
  const obs = useObservable(false);
@@ -500,14 +518,6 @@ function useObservableReducer(reducer, initializerArg, initializer) {
500
518
  };
501
519
  return [obs, dispatch];
502
520
  }
503
-
504
- // src/react/useUnmount.ts
505
- function useUnmount(fn) {
506
- return useMount(() => fn);
507
- }
508
- var useUnmountOnce = useUnmount;
509
-
510
- // src/react/useObserve.ts
511
521
  function useObserve(selector, reactionOrOptions, options) {
512
522
  let reaction;
513
523
  if (state.isFunction(reactionOrOptions)) {
@@ -517,15 +527,15 @@ function useObserve(selector, reactionOrOptions, options) {
517
527
  }
518
528
  const deps = options == null ? void 0 : options.deps;
519
529
  const depsObs$ = deps ? useObservable(deps) : void 0;
520
- if (depsObs$) {
521
- depsObs$.set(deps);
522
- }
523
530
  const ref = React.useRef({});
524
531
  ref.current.selector = deps ? () => {
525
532
  depsObs$ == null ? void 0 : depsObs$.get();
526
533
  return state.computeSelector(selector);
527
534
  } : selector;
528
535
  ref.current.reaction = reaction;
536
+ if (depsObs$) {
537
+ depsObs$.set(deps);
538
+ }
529
539
  if (!ref.current.dispose) {
530
540
  ref.current.dispose = state.observe(
531
541
  (e) => state.computeSelector(ref.current.selector, void 0, e),
@@ -549,13 +559,13 @@ function useObserveEffect(selector, reactionOrOptions, options) {
549
559
  } else {
550
560
  options = reactionOrOptions;
551
561
  }
562
+ const ref = React.useRef({ selector });
563
+ ref.current = { selector, reaction };
552
564
  const deps = options == null ? void 0 : options.deps;
553
565
  const depsObs$ = deps ? useObservable(deps) : void 0;
554
566
  if (depsObs$) {
555
567
  depsObs$.set(deps);
556
568
  }
557
- const ref = React.useRef({ selector });
558
- ref.current = { selector, reaction };
559
569
  useMountOnce(
560
570
  () => state.observe(
561
571
  (e) => {
package/react.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { isFunction, isEmpty, observable, computeSelector, isArray, isMap, isObservableValueReady, linked, isPromise, observe, when, whenReady, internal, trackSelector, isPrimitive, isObservable } from '@legendapp/state';
1
+ import { isFunction, isEmpty, observable, computeSelector, isArray, isMap, isObservableValueReady, isPromise, getNode as getNode$1, linked, observe, when, whenReady, internal, trackSelector, isPrimitive, isObservable } from '@legendapp/state';
2
2
  import React, { memo, forwardRef, createElement, useState, useContext, useMemo, useRef, useEffect, createContext, useCallback } from 'react';
3
3
  import { useSyncExternalStore } from 'use-sync-external-store/shim/index.js';
4
4
  import { enableReactive } from '@legendapp/state/react-reactive/enableReactive';
@@ -405,38 +405,6 @@ function Switch({
405
405
  const child = children[useSelector(value)];
406
406
  return (_b = child ? child() : (_a = children["default"]) == null ? void 0 : _a.call(children)) != null ? _b : null;
407
407
  }
408
- function useObservable(initialValue, deps) {
409
- var _a;
410
- const ref = useRef({});
411
- ref.current.value = initialValue;
412
- const depsObs$ = deps ? useObservable(deps) : void 0;
413
- if (!((_a = ref.current) == null ? void 0 : _a.obs$)) {
414
- const value = depsObs$ ? isFunction(initialValue) && initialValue.length === 1 ? (p) => {
415
- depsObs$.get();
416
- return ref.current.value(p);
417
- } : () => {
418
- depsObs$.get();
419
- return computeSelector(ref.current.value);
420
- } : initialValue;
421
- ref.current.obs$ = observable(value);
422
- }
423
- if (depsObs$) {
424
- depsObs$.set(deps);
425
- }
426
- return ref.current.obs$;
427
- }
428
-
429
- // src/react/useComputed.ts
430
- function useComputed(get, set, deps) {
431
- if (!deps && isArray(set)) {
432
- deps = set;
433
- set = void 0;
434
- }
435
- return useObservable(
436
- set ? linked({ get, set: ({ value }) => set(value) }) : get,
437
- deps
438
- );
439
- }
440
408
  var useEffectOnce = (effect, deps) => {
441
409
  if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") {
442
410
  const refDispose = useRef({ num: 0 });
@@ -465,6 +433,8 @@ var useEffectOnce = (effect, deps) => {
465
433
  useEffect(effect, deps);
466
434
  }
467
435
  };
436
+
437
+ // src/react/useMount.ts
468
438
  function useMount(fn) {
469
439
  return useEffectOnce(() => {
470
440
  const ret = fn();
@@ -475,6 +445,54 @@ function useMount(fn) {
475
445
  }
476
446
  var useMountOnce = useMount;
477
447
 
448
+ // src/react/useUnmount.ts
449
+ function useUnmount(fn) {
450
+ return useMount(() => fn);
451
+ }
452
+ var useUnmountOnce = useUnmount;
453
+
454
+ // src/react/useObservable.ts
455
+ var { deactivateNode } = internal;
456
+ function useObservable(initialValue, deps) {
457
+ var _a;
458
+ const ref = useRef({});
459
+ ref.current.value = initialValue;
460
+ const depsObs$ = deps ? useObservable(deps) : void 0;
461
+ if (!((_a = ref.current) == null ? void 0 : _a.obs$)) {
462
+ const value = depsObs$ ? isFunction(initialValue) && initialValue.length === 1 ? (p) => {
463
+ depsObs$.get();
464
+ return ref.current.value(p);
465
+ } : () => {
466
+ depsObs$.get();
467
+ return computeSelector(ref.current.value);
468
+ } : initialValue;
469
+ ref.current.obs$ = observable(value);
470
+ }
471
+ if (depsObs$) {
472
+ depsObs$.set(deps);
473
+ }
474
+ useUnmount(() => {
475
+ const obs = ref.current.obs$;
476
+ if (obs) {
477
+ const node = getNode$1(obs);
478
+ deactivateNode(node);
479
+ }
480
+ });
481
+ return ref.current.obs$;
482
+ }
483
+
484
+ // src/react/useComputed.ts
485
+ function useComputed(get, set, deps) {
486
+ if (!deps && isArray(set)) {
487
+ deps = set;
488
+ set = void 0;
489
+ }
490
+ return useObservable(
491
+ set ? linked({ get, set: ({ value }) => set(value) }) : get,
492
+ deps
493
+ );
494
+ }
495
+
478
496
  // src/react/useIsMounted.ts
479
497
  function useIsMounted() {
480
498
  const obs = useObservable(false);
@@ -494,14 +512,6 @@ function useObservableReducer(reducer, initializerArg, initializer) {
494
512
  };
495
513
  return [obs, dispatch];
496
514
  }
497
-
498
- // src/react/useUnmount.ts
499
- function useUnmount(fn) {
500
- return useMount(() => fn);
501
- }
502
- var useUnmountOnce = useUnmount;
503
-
504
- // src/react/useObserve.ts
505
515
  function useObserve(selector, reactionOrOptions, options) {
506
516
  let reaction;
507
517
  if (isFunction(reactionOrOptions)) {
@@ -511,15 +521,15 @@ function useObserve(selector, reactionOrOptions, options) {
511
521
  }
512
522
  const deps = options == null ? void 0 : options.deps;
513
523
  const depsObs$ = deps ? useObservable(deps) : void 0;
514
- if (depsObs$) {
515
- depsObs$.set(deps);
516
- }
517
524
  const ref = useRef({});
518
525
  ref.current.selector = deps ? () => {
519
526
  depsObs$ == null ? void 0 : depsObs$.get();
520
527
  return computeSelector(selector);
521
528
  } : selector;
522
529
  ref.current.reaction = reaction;
530
+ if (depsObs$) {
531
+ depsObs$.set(deps);
532
+ }
523
533
  if (!ref.current.dispose) {
524
534
  ref.current.dispose = observe(
525
535
  (e) => computeSelector(ref.current.selector, void 0, e),
@@ -543,13 +553,13 @@ function useObserveEffect(selector, reactionOrOptions, options) {
543
553
  } else {
544
554
  options = reactionOrOptions;
545
555
  }
556
+ const ref = useRef({ selector });
557
+ ref.current = { selector, reaction };
546
558
  const deps = options == null ? void 0 : options.deps;
547
559
  const depsObs$ = deps ? useObservable(deps) : void 0;
548
560
  if (depsObs$) {
549
561
  depsObs$.set(deps);
550
562
  }
551
- const ref = useRef({ selector });
552
- ref.current = { selector, reaction };
553
563
  useMountOnce(
554
564
  () => observe(
555
565
  (e) => {
@@ -4,16 +4,18 @@ var state = require('@legendapp/state');
4
4
  var sync = require('@legendapp/state/sync');
5
5
 
6
6
  // src/sync-plugins/crud.ts
7
- var { clone, getKeys } = state.internal;
7
+ var { clone, getKeys, setNodeValue, getChildNode } = state.internal;
8
8
  var { waitForSet, runWithRetry } = sync.internal;
9
9
  function transformOut(data, transform) {
10
10
  return transform ? transform(clone(data)) : data;
11
11
  }
12
- function ensureId(obj, fieldId, generateId) {
12
+ function ensureId(obj, fieldId, generateId, node) {
13
13
  if (!obj[fieldId]) {
14
14
  obj[fieldId] = generateId();
15
+ if (node) {
16
+ setNodeValue(node, obj);
17
+ }
15
18
  }
16
- return obj[fieldId];
17
19
  }
18
20
  function computeLastSync(data, fieldUpdatedAt, fieldCreatedAt) {
19
21
  let newLastSync = 0;
@@ -210,11 +212,11 @@ function syncedCrud(props) {
210
212
  const { path, prevAtPath, valueAtPath, pathTypes } = change;
211
213
  if (asType === "value") {
212
214
  if (value) {
213
- let id = value == null ? void 0 : value[fieldId];
214
215
  let isCreate = fieldCreatedAt ? !value[fieldCreatedAt] : !prevAtPath;
215
- if (state.isNullOrUndefined(id) && generateId) {
216
- id = ensureId(value, fieldId, generateId);
216
+ if (state.isNullOrUndefined(value[fieldId]) && generateId) {
217
+ ensureId(value, fieldId, generateId, node);
217
218
  }
219
+ const id = value[fieldId];
218
220
  if (!state.isNullOrUndefined(id)) {
219
221
  changesById.set(id, change);
220
222
  if (pendingCreates.has(id)) {
@@ -253,6 +255,14 @@ function syncedCrud(props) {
253
255
  } else {
254
256
  let itemsChanged = [];
255
257
  if (path.length === 0) {
258
+ if (asArray && generateId) {
259
+ for (let i = 0; i < valueAtPath.length; i++) {
260
+ const value2 = valueAtPath[i];
261
+ if (value2 && !value2[fieldId]) {
262
+ ensureId(value2, fieldId, generateId, getChildNode(node, i + ""));
263
+ }
264
+ }
265
+ }
256
266
  const valueAsObject = asArray ? arrayToRecord(valueAtPath, fieldId) : valueAtPath;
257
267
  const prevAsObject = asArray ? arrayToRecord(prevAtPath, fieldId) : prevAtPath;
258
268
  const keys = getKeys(valueAsObject, false, asMap, false);
@@ -289,6 +299,9 @@ function syncedCrud(props) {
289
299
  changesById.set(prevAtPath[fieldId], change);
290
300
  }
291
301
  } else {
302
+ if (generateId) {
303
+ ensureId(itemValue, fieldId, generateId, getChildNode(node, itemKey + ""));
304
+ }
292
305
  const previous = state.setAtPath(
293
306
  clone(itemValue),
294
307
  path.slice(1),
@@ -301,9 +314,6 @@ function syncedCrud(props) {
301
314
  itemsChanged == null ? void 0 : itemsChanged.forEach(([item, prev, fullValue]) => {
302
315
  const isCreate = !pendingCreates.has(item[fieldId]) && (fieldCreatedAt ? !item[fieldCreatedAt] && !(prev == null ? void 0 : prev[fieldCreatedAt]) : fieldUpdatedAt ? !item[fieldUpdatedAt] && !(prev == null ? void 0 : prev[fieldCreatedAt]) : state.isNullOrUndefined(prev));
303
316
  if (isCreate) {
304
- if (generateId) {
305
- ensureId(item, fieldId, generateId);
306
- }
307
317
  if (!item[fieldId]) {
308
318
  console.error("[legend-state]: added item without an id");
309
319
  }
@@ -2,16 +2,18 @@ import { isPromise, isNullOrUndefined, applyChanges, setAtPath, symbolDelete, is
2
2
  import { synced, deepEqual, internal as internal$1, diffObjects } from '@legendapp/state/sync';
3
3
 
4
4
  // src/sync-plugins/crud.ts
5
- var { clone, getKeys } = internal;
5
+ var { clone, getKeys, setNodeValue, getChildNode } = internal;
6
6
  var { waitForSet, runWithRetry } = internal$1;
7
7
  function transformOut(data, transform) {
8
8
  return transform ? transform(clone(data)) : data;
9
9
  }
10
- function ensureId(obj, fieldId, generateId) {
10
+ function ensureId(obj, fieldId, generateId, node) {
11
11
  if (!obj[fieldId]) {
12
12
  obj[fieldId] = generateId();
13
+ if (node) {
14
+ setNodeValue(node, obj);
15
+ }
13
16
  }
14
- return obj[fieldId];
15
17
  }
16
18
  function computeLastSync(data, fieldUpdatedAt, fieldCreatedAt) {
17
19
  let newLastSync = 0;
@@ -208,11 +210,11 @@ function syncedCrud(props) {
208
210
  const { path, prevAtPath, valueAtPath, pathTypes } = change;
209
211
  if (asType === "value") {
210
212
  if (value) {
211
- let id = value == null ? void 0 : value[fieldId];
212
213
  let isCreate = fieldCreatedAt ? !value[fieldCreatedAt] : !prevAtPath;
213
- if (isNullOrUndefined(id) && generateId) {
214
- id = ensureId(value, fieldId, generateId);
214
+ if (isNullOrUndefined(value[fieldId]) && generateId) {
215
+ ensureId(value, fieldId, generateId, node);
215
216
  }
217
+ const id = value[fieldId];
216
218
  if (!isNullOrUndefined(id)) {
217
219
  changesById.set(id, change);
218
220
  if (pendingCreates.has(id)) {
@@ -251,6 +253,14 @@ function syncedCrud(props) {
251
253
  } else {
252
254
  let itemsChanged = [];
253
255
  if (path.length === 0) {
256
+ if (asArray && generateId) {
257
+ for (let i = 0; i < valueAtPath.length; i++) {
258
+ const value2 = valueAtPath[i];
259
+ if (value2 && !value2[fieldId]) {
260
+ ensureId(value2, fieldId, generateId, getChildNode(node, i + ""));
261
+ }
262
+ }
263
+ }
254
264
  const valueAsObject = asArray ? arrayToRecord(valueAtPath, fieldId) : valueAtPath;
255
265
  const prevAsObject = asArray ? arrayToRecord(prevAtPath, fieldId) : prevAtPath;
256
266
  const keys = getKeys(valueAsObject, false, asMap, false);
@@ -287,6 +297,9 @@ function syncedCrud(props) {
287
297
  changesById.set(prevAtPath[fieldId], change);
288
298
  }
289
299
  } else {
300
+ if (generateId) {
301
+ ensureId(itemValue, fieldId, generateId, getChildNode(node, itemKey + ""));
302
+ }
290
303
  const previous = setAtPath(
291
304
  clone(itemValue),
292
305
  path.slice(1),
@@ -299,9 +312,6 @@ function syncedCrud(props) {
299
312
  itemsChanged == null ? void 0 : itemsChanged.forEach(([item, prev, fullValue]) => {
300
313
  const isCreate = !pendingCreates.has(item[fieldId]) && (fieldCreatedAt ? !item[fieldCreatedAt] && !(prev == null ? void 0 : prev[fieldCreatedAt]) : fieldUpdatedAt ? !item[fieldUpdatedAt] && !(prev == null ? void 0 : prev[fieldCreatedAt]) : isNullOrUndefined(prev));
301
314
  if (isCreate) {
302
- if (generateId) {
303
- ensureId(item, fieldId, generateId);
304
- }
305
315
  if (!item[fieldId]) {
306
316
  console.error("[legend-state]: added item without an id");
307
317
  }