@legendapp/state 3.0.0-beta.16 → 3.0.0-beta.18

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.
@@ -1,7 +1,8 @@
1
1
  interface ReactTrackingOptions {
2
2
  auto?: boolean;
3
3
  warnUnobserved?: boolean;
4
+ warnGet?: boolean;
4
5
  }
5
- declare function enableReactTracking({ auto, warnUnobserved }: ReactTrackingOptions): void;
6
+ declare function enableReactTracking({ auto, warnUnobserved, warnGet }: ReactTrackingOptions): void;
6
7
 
7
8
  export { enableReactTracking };
@@ -1,7 +1,8 @@
1
1
  interface ReactTrackingOptions {
2
2
  auto?: boolean;
3
3
  warnUnobserved?: boolean;
4
+ warnGet?: boolean;
4
5
  }
5
- declare function enableReactTracking({ auto, warnUnobserved }: ReactTrackingOptions): void;
6
+ declare function enableReactTracking({ auto, warnUnobserved, warnGet }: ReactTrackingOptions): void;
6
7
 
7
8
  export { enableReactTracking };
@@ -6,32 +6,42 @@ var react$1 = require('@legendapp/state/react');
6
6
  var react = require('react');
7
7
 
8
8
  // src/config/enableReactTracking.ts
9
- function enableReactTracking({ auto, warnUnobserved }) {
9
+ function enableReactTracking({ auto, warnUnobserved, warnGet }) {
10
10
  const { get } = state.internal;
11
- if (auto || process.env.NODE_ENV === "development" && warnUnobserved) {
11
+ if (auto || process.env.NODE_ENV === "development" && (warnUnobserved || warnGet)) {
12
12
  const ReactRenderContext = react.createContext(0);
13
+ const isInRender = () => {
14
+ try {
15
+ const dispatcher = react.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher.current;
16
+ if (dispatcher) {
17
+ react.useContext(ReactRenderContext);
18
+ return true;
19
+ }
20
+ } catch (e) {
21
+ }
22
+ return false;
23
+ };
13
24
  const needsSelector = () => {
14
25
  if (!state.tracking.current) {
15
- try {
16
- const dispatcher = react.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher.current;
17
- if (dispatcher) {
18
- react.useContext(ReactRenderContext);
19
- return true;
20
- }
21
- } catch (e) {
22
- }
26
+ return isInRender();
23
27
  }
24
28
  return false;
25
29
  };
26
30
  configureLegendState.configureLegendState({
27
31
  observableFunctions: {
28
32
  get: (node, options) => {
29
- if (needsSelector()) {
33
+ if (process.env.NODE_ENV === "development" && warnUnobserved) {
34
+ if (isInRender()) {
35
+ console.warn(
36
+ "[legend-state] Detected a `get()` call in a React component. It is recommended to use the `use$` hook instead to be compatible with React Compiler: https://legendapp.com/open-source/state/v3/react/react-api/#use$"
37
+ );
38
+ }
39
+ } else if (needsSelector()) {
30
40
  if (auto) {
31
41
  return react$1.useSelector(() => get(node, options), state.isObject(options) ? options : void 0);
32
42
  } else if (process.env.NODE_ENV === "development" && warnUnobserved) {
33
43
  console.warn(
34
- "[legend-state] Detected a `get()` call in an unobserved component. You may want to wrap it in observer: https://legendapp.com/open-source/state/react-api/#observer-hoc"
44
+ "[legend-state] Detected a `get()` call in an unobserved component. You may want to wrap it in observer: https://legendapp.com/open-source/state/v3/react/react-api/#observer"
35
45
  );
36
46
  }
37
47
  }
@@ -4,32 +4,42 @@ import { useSelector } from '@legendapp/state/react';
4
4
  import { createContext, __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, useContext } from 'react';
5
5
 
6
6
  // src/config/enableReactTracking.ts
7
- function enableReactTracking({ auto, warnUnobserved }) {
7
+ function enableReactTracking({ auto, warnUnobserved, warnGet }) {
8
8
  const { get } = internal;
9
- if (auto || process.env.NODE_ENV === "development" && warnUnobserved) {
9
+ if (auto || process.env.NODE_ENV === "development" && (warnUnobserved || warnGet)) {
10
10
  const ReactRenderContext = createContext(0);
11
+ const isInRender = () => {
12
+ try {
13
+ const dispatcher = __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher.current;
14
+ if (dispatcher) {
15
+ useContext(ReactRenderContext);
16
+ return true;
17
+ }
18
+ } catch (e) {
19
+ }
20
+ return false;
21
+ };
11
22
  const needsSelector = () => {
12
23
  if (!tracking.current) {
13
- try {
14
- const dispatcher = __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher.current;
15
- if (dispatcher) {
16
- useContext(ReactRenderContext);
17
- return true;
18
- }
19
- } catch (e) {
20
- }
24
+ return isInRender();
21
25
  }
22
26
  return false;
23
27
  };
24
28
  configureLegendState({
25
29
  observableFunctions: {
26
30
  get: (node, options) => {
27
- if (needsSelector()) {
31
+ if (process.env.NODE_ENV === "development" && warnUnobserved) {
32
+ if (isInRender()) {
33
+ console.warn(
34
+ "[legend-state] Detected a `get()` call in a React component. It is recommended to use the `use$` hook instead to be compatible with React Compiler: https://legendapp.com/open-source/state/v3/react/react-api/#use$"
35
+ );
36
+ }
37
+ } else if (needsSelector()) {
28
38
  if (auto) {
29
39
  return useSelector(() => get(node, options), isObject(options) ? options : void 0);
30
40
  } else if (process.env.NODE_ENV === "development" && warnUnobserved) {
31
41
  console.warn(
32
- "[legend-state] Detected a `get()` call in an unobserved component. You may want to wrap it in observer: https://legendapp.com/open-source/state/react-api/#observer-hoc"
42
+ "[legend-state] Detected a `get()` call in an unobserved component. You may want to wrap it in observer: https://legendapp.com/open-source/state/v3/react/react-api/#observer"
33
43
  );
34
44
  }
35
45
  }
package/index.d.mts CHANGED
@@ -116,7 +116,7 @@ declare function findIDKey(obj: unknown | undefined, node: NodeInfo): string | (
116
116
 
117
117
  type TrackingType = undefined | true | symbol;
118
118
  interface GetOptions {
119
- shallow: boolean;
119
+ shallow?: boolean;
120
120
  }
121
121
  type OpaqueObject<T> = T & {
122
122
  [symbolOpaque]: true;
@@ -315,7 +315,7 @@ declare function computed<T, T2 = T>(get: (() => RecursiveValueOrFunction<T>) |
315
315
 
316
316
  declare function event(): ObservableEvent;
317
317
 
318
- declare function computeSelector<T>(selector: Selector<T>, e?: ObserveEvent<T>, retainObservable?: boolean): T;
318
+ declare function computeSelector<T>(selector: Selector<T>, getOptions?: GetOptions, e?: ObserveEvent<T>, retainObservable?: boolean): T;
319
319
  declare function getObservableIndex(value$: ObservableParam): number;
320
320
  declare function opaqueObject<T extends object>(value: T): OpaqueObject<T>;
321
321
  declare function getValueAtPath(obj: Record<string, any>, path: string[]): any;
@@ -365,7 +365,7 @@ declare function proxy<T>(get: (key: string) => T): Observable<Record<string, T>
365
365
 
366
366
  declare function syncState(obs: ObservableParam): Observable<ObservableSyncState>;
367
367
 
368
- declare function trackSelector<T>(selector: Selector<T>, update: (params: ListenerParams) => void, observeEvent?: ObserveEvent<T>, observeOptions?: ObserveOptions, createResubscribe?: boolean): {
368
+ declare function trackSelector<T>(selector: Selector<T>, update: (params: ListenerParams) => void, getOptions?: GetOptions, observeEvent?: ObserveEvent<T>, observeOptions?: ObserveOptions, createResubscribe?: boolean): {
369
369
  nodes: Map<NodeInfo, TrackingNode> | undefined;
370
370
  value: T;
371
371
  dispose: (() => void) | undefined;
package/index.d.ts CHANGED
@@ -116,7 +116,7 @@ declare function findIDKey(obj: unknown | undefined, node: NodeInfo): string | (
116
116
 
117
117
  type TrackingType = undefined | true | symbol;
118
118
  interface GetOptions {
119
- shallow: boolean;
119
+ shallow?: boolean;
120
120
  }
121
121
  type OpaqueObject<T> = T & {
122
122
  [symbolOpaque]: true;
@@ -315,7 +315,7 @@ declare function computed<T, T2 = T>(get: (() => RecursiveValueOrFunction<T>) |
315
315
 
316
316
  declare function event(): ObservableEvent;
317
317
 
318
- declare function computeSelector<T>(selector: Selector<T>, e?: ObserveEvent<T>, retainObservable?: boolean): T;
318
+ declare function computeSelector<T>(selector: Selector<T>, getOptions?: GetOptions, e?: ObserveEvent<T>, retainObservable?: boolean): T;
319
319
  declare function getObservableIndex(value$: ObservableParam): number;
320
320
  declare function opaqueObject<T extends object>(value: T): OpaqueObject<T>;
321
321
  declare function getValueAtPath(obj: Record<string, any>, path: string[]): any;
@@ -365,7 +365,7 @@ declare function proxy<T>(get: (key: string) => T): Observable<Record<string, T>
365
365
 
366
366
  declare function syncState(obs: ObservableParam): Observable<ObservableSyncState>;
367
367
 
368
- declare function trackSelector<T>(selector: Selector<T>, update: (params: ListenerParams) => void, observeEvent?: ObserveEvent<T>, observeOptions?: ObserveOptions, createResubscribe?: boolean): {
368
+ declare function trackSelector<T>(selector: Selector<T>, update: (params: ListenerParams) => void, getOptions?: GetOptions, observeEvent?: ObserveEvent<T>, observeOptions?: ObserveOptions, createResubscribe?: boolean): {
369
369
  nodes: Map<NodeInfo, TrackingNode> | undefined;
370
370
  value: T;
371
371
  dispose: (() => void) | undefined;
package/index.js CHANGED
@@ -283,12 +283,12 @@ var ObservableHint = {
283
283
  };
284
284
 
285
285
  // src/helpers.ts
286
- function computeSelector(selector, e, retainObservable) {
286
+ function computeSelector(selector, getOptions, e, retainObservable) {
287
287
  let c = selector;
288
288
  if (!isObservable(c) && isFunction(c)) {
289
289
  c = e ? c(e) : c();
290
290
  }
291
- return isObservable(c) && !retainObservable ? c.get() : c;
291
+ return isObservable(c) && !retainObservable ? c.get(getOptions) : c;
292
292
  }
293
293
  function getObservableIndex(value$) {
294
294
  const node = getNode(value$);
@@ -972,13 +972,13 @@ function updateTracking(node, track) {
972
972
  }
973
973
 
974
974
  // src/trackSelector.ts
975
- function trackSelector(selector, update, observeEvent, observeOptions, createResubscribe) {
975
+ function trackSelector(selector, update, getOptions, observeEvent, observeOptions, createResubscribe) {
976
976
  var _a;
977
977
  let dispose;
978
978
  let resubscribe;
979
979
  let updateFn = update;
980
980
  beginTracking();
981
- const value = selector ? computeSelector(selector, observeEvent, observeOptions == null ? void 0 : observeOptions.fromComputed) : selector;
981
+ const value = selector ? computeSelector(selector, getOptions, observeEvent, observeOptions == null ? void 0 : observeOptions.fromComputed) : selector;
982
982
  const tracker = tracking.current;
983
983
  const nodes = tracker.nodes;
984
984
  endTracking();
@@ -1026,7 +1026,11 @@ function observe(selectorOrRun, reactionOrOptions, options) {
1026
1026
  beginBatch();
1027
1027
  delete e.value;
1028
1028
  dispose == null ? void 0 : dispose();
1029
- const { dispose: _dispose, value, nodes } = trackSelector(selectorOrRun, update, e, options);
1029
+ const {
1030
+ dispose: _dispose,
1031
+ value,
1032
+ nodes
1033
+ } = trackSelector(selectorOrRun, update, void 0, e, options);
1030
1034
  dispose = _dispose;
1031
1035
  e.value = value;
1032
1036
  e.nodes = nodes;
@@ -1071,10 +1075,13 @@ function _when(predicate, effect, checkReady) {
1071
1075
  let isOk = true;
1072
1076
  if (isArray(ret)) {
1073
1077
  for (let i = 0; i < ret.length; i++) {
1074
- if (isObservable(ret[i])) {
1075
- ret[i] = computeSelector(ret[i]);
1078
+ let item = ret[i];
1079
+ if (isObservable(item)) {
1080
+ item = computeSelector(item);
1081
+ } else if (isFunction(item)) {
1082
+ item = item();
1076
1083
  }
1077
- isOk = isOk && !!(checkReady ? isObservableValueReady(ret[i]) : ret[i]);
1084
+ isOk = isOk && !!(checkReady ? isObservableValueReady(item) : item);
1078
1085
  }
1079
1086
  } else {
1080
1087
  isOk = checkReady ? isObservableValueReady(ret) : ret;
package/index.mjs CHANGED
@@ -281,12 +281,12 @@ var ObservableHint = {
281
281
  };
282
282
 
283
283
  // src/helpers.ts
284
- function computeSelector(selector, e, retainObservable) {
284
+ function computeSelector(selector, getOptions, e, retainObservable) {
285
285
  let c = selector;
286
286
  if (!isObservable(c) && isFunction(c)) {
287
287
  c = e ? c(e) : c();
288
288
  }
289
- return isObservable(c) && !retainObservable ? c.get() : c;
289
+ return isObservable(c) && !retainObservable ? c.get(getOptions) : c;
290
290
  }
291
291
  function getObservableIndex(value$) {
292
292
  const node = getNode(value$);
@@ -970,13 +970,13 @@ function updateTracking(node, track) {
970
970
  }
971
971
 
972
972
  // src/trackSelector.ts
973
- function trackSelector(selector, update, observeEvent, observeOptions, createResubscribe) {
973
+ function trackSelector(selector, update, getOptions, observeEvent, observeOptions, createResubscribe) {
974
974
  var _a;
975
975
  let dispose;
976
976
  let resubscribe;
977
977
  let updateFn = update;
978
978
  beginTracking();
979
- const value = selector ? computeSelector(selector, observeEvent, observeOptions == null ? void 0 : observeOptions.fromComputed) : selector;
979
+ const value = selector ? computeSelector(selector, getOptions, observeEvent, observeOptions == null ? void 0 : observeOptions.fromComputed) : selector;
980
980
  const tracker = tracking.current;
981
981
  const nodes = tracker.nodes;
982
982
  endTracking();
@@ -1024,7 +1024,11 @@ function observe(selectorOrRun, reactionOrOptions, options) {
1024
1024
  beginBatch();
1025
1025
  delete e.value;
1026
1026
  dispose == null ? void 0 : dispose();
1027
- const { dispose: _dispose, value, nodes } = trackSelector(selectorOrRun, update, e, options);
1027
+ const {
1028
+ dispose: _dispose,
1029
+ value,
1030
+ nodes
1031
+ } = trackSelector(selectorOrRun, update, void 0, e, options);
1028
1032
  dispose = _dispose;
1029
1033
  e.value = value;
1030
1034
  e.nodes = nodes;
@@ -1069,10 +1073,13 @@ function _when(predicate, effect, checkReady) {
1069
1073
  let isOk = true;
1070
1074
  if (isArray(ret)) {
1071
1075
  for (let i = 0; i < ret.length; i++) {
1072
- if (isObservable(ret[i])) {
1073
- ret[i] = computeSelector(ret[i]);
1076
+ let item = ret[i];
1077
+ if (isObservable(item)) {
1078
+ item = computeSelector(item);
1079
+ } else if (isFunction(item)) {
1080
+ item = item();
1074
1081
  }
1075
- isOk = isOk && !!(checkReady ? isObservableValueReady(ret[i]) : ret[i]);
1082
+ isOk = isOk && !!(checkReady ? isObservableValueReady(item) : item);
1076
1083
  }
1077
1084
  } else {
1078
1085
  isOk = checkReady ? isObservableValueReady(ret) : ret;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@legendapp/state",
3
- "version": "3.0.0-beta.16",
3
+ "version": "3.0.0-beta.18",
4
4
  "description": "legend-state",
5
5
  "sideEffects": false,
6
6
  "private": false,
package/react.d.mts CHANGED
@@ -1,11 +1,19 @@
1
1
  import * as React from 'react';
2
- import { ReactNode, ReactElement, FC, LegacyRef, DependencyList, ReducerWithoutAction, ReducerStateWithoutAction, DispatchWithoutAction, Reducer, ReducerState, Dispatch, ReducerAction, ComponentClass } from 'react';
3
- import { ObservableParam, Observable, ObservableBoolean, Selector, RecursiveValueOrFunction, ObserveOptions, ObserveEvent, ObserveEventCallback } from '@legendapp/state';
2
+ import { ReactNode, ReactElement, NamedExoticComponent, FC, LegacyRef, DependencyList, ReducerWithoutAction, ReducerStateWithoutAction, DispatchWithoutAction, Reducer, ReducerState, Dispatch, ReducerAction, ComponentClass } from 'react';
3
+ import { ObservableParam, Observable, ObservableBoolean, Selector, GetOptions, RecursiveValueOrFunction, ObserveOptions, ObserveEvent, ObserveEventCallback } from '@legendapp/state';
4
+ import { IReactive as IReactive$1 } from '@legendapp/state/react';
4
5
 
5
6
  declare function Computed({ children }: {
6
7
  children: ObservableParam | (() => ReactNode);
7
8
  }): ReactElement;
8
9
 
10
+ declare const Memo$1: NamedExoticComponent<{
11
+ children: any;
12
+ scoped?: boolean;
13
+ }>;
14
+ type ReactiveProxy = typeof Memo$1 & IReactive$1;
15
+ declare const $: ReactiveProxy;
16
+
9
17
  type ForItemProps<T, TProps = {}> = {
10
18
  item$: Observable<T>;
11
19
  id?: string;
@@ -26,7 +34,10 @@ declare function usePauseProvider(): {
26
34
  isPaused$: ObservableBoolean;
27
35
  };
28
36
 
29
- declare const Memo: React.MemoExoticComponent<typeof Computed>;
37
+ declare const Memo: NamedExoticComponent<{
38
+ children: any;
39
+ scoped?: boolean;
40
+ }>;
30
41
 
31
42
  interface IReactive {
32
43
  }
@@ -84,7 +95,7 @@ type FCReactiveObject<T> = {
84
95
  type FCReactive<P, P2> = P & FC<ShapeWithNew$<P2> & {
85
96
  ref?: LegacyRef<P> | undefined;
86
97
  }>;
87
- interface UseSelectorOptions {
98
+ interface UseSelectorOptions extends GetOptions {
88
99
  suspense?: boolean;
89
100
  skipCheck?: boolean;
90
101
  }
@@ -172,4 +183,4 @@ declare function configureReactive({ components, binders, }: {
172
183
  binders?: Record<string, BindKeys>;
173
184
  }): void;
174
185
 
175
- export { type BindKey, type BindKeys, Computed, type ExtractFCPropsType, type FCReactive, type FCReactiveObject, For, type IReactive, Memo, type ObjectShapeWith$, type ReactifyProps, Reactive, type ShapeWith$, type ShapeWithNew$, type ShapeWithPick$, Show, Switch, type UseObserveOptions, type UseSelectorOptions, configureReactive, hasSymbol, observer, reactive, reactiveComponents, reactiveObserver, useComputed, useEffectOnce, useIsMounted, useMount, useMountOnce, useObservable, useObservableReducer, useObserve, useObserveEffect, usePauseProvider, useSelector, useUnmount, useUnmountOnce, useWhen, useWhenReady };
186
+ export { $, type BindKey, type BindKeys, Computed, type ExtractFCPropsType, type FCReactive, type FCReactiveObject, For, type IReactive, Memo, type ObjectShapeWith$, type ReactifyProps, Reactive, type ShapeWith$, type ShapeWithNew$, type ShapeWithPick$, Show, Switch, type UseObserveOptions, type UseSelectorOptions, configureReactive, hasSymbol, observer, reactive, reactiveComponents, reactiveObserver, useSelector as use$, useComputed, useEffectOnce, useIsMounted, useMount, useMountOnce, useObservable, useObservableReducer, useObserve, useObserveEffect, usePauseProvider, useSelector, useUnmount, useUnmountOnce, useWhen, useWhenReady };
package/react.d.ts CHANGED
@@ -1,11 +1,19 @@
1
1
  import * as React from 'react';
2
- import { ReactNode, ReactElement, FC, LegacyRef, DependencyList, ReducerWithoutAction, ReducerStateWithoutAction, DispatchWithoutAction, Reducer, ReducerState, Dispatch, ReducerAction, ComponentClass } from 'react';
3
- import { ObservableParam, Observable, ObservableBoolean, Selector, RecursiveValueOrFunction, ObserveOptions, ObserveEvent, ObserveEventCallback } from '@legendapp/state';
2
+ import { ReactNode, ReactElement, NamedExoticComponent, FC, LegacyRef, DependencyList, ReducerWithoutAction, ReducerStateWithoutAction, DispatchWithoutAction, Reducer, ReducerState, Dispatch, ReducerAction, ComponentClass } from 'react';
3
+ import { ObservableParam, Observable, ObservableBoolean, Selector, GetOptions, RecursiveValueOrFunction, ObserveOptions, ObserveEvent, ObserveEventCallback } from '@legendapp/state';
4
+ import { IReactive as IReactive$1 } from '@legendapp/state/react';
4
5
 
5
6
  declare function Computed({ children }: {
6
7
  children: ObservableParam | (() => ReactNode);
7
8
  }): ReactElement;
8
9
 
10
+ declare const Memo$1: NamedExoticComponent<{
11
+ children: any;
12
+ scoped?: boolean;
13
+ }>;
14
+ type ReactiveProxy = typeof Memo$1 & IReactive$1;
15
+ declare const $: ReactiveProxy;
16
+
9
17
  type ForItemProps<T, TProps = {}> = {
10
18
  item$: Observable<T>;
11
19
  id?: string;
@@ -26,7 +34,10 @@ declare function usePauseProvider(): {
26
34
  isPaused$: ObservableBoolean;
27
35
  };
28
36
 
29
- declare const Memo: React.MemoExoticComponent<typeof Computed>;
37
+ declare const Memo: NamedExoticComponent<{
38
+ children: any;
39
+ scoped?: boolean;
40
+ }>;
30
41
 
31
42
  interface IReactive {
32
43
  }
@@ -84,7 +95,7 @@ type FCReactiveObject<T> = {
84
95
  type FCReactive<P, P2> = P & FC<ShapeWithNew$<P2> & {
85
96
  ref?: LegacyRef<P> | undefined;
86
97
  }>;
87
- interface UseSelectorOptions {
98
+ interface UseSelectorOptions extends GetOptions {
88
99
  suspense?: boolean;
89
100
  skipCheck?: boolean;
90
101
  }
@@ -172,4 +183,4 @@ declare function configureReactive({ components, binders, }: {
172
183
  binders?: Record<string, BindKeys>;
173
184
  }): void;
174
185
 
175
- export { type BindKey, type BindKeys, Computed, type ExtractFCPropsType, type FCReactive, type FCReactiveObject, For, type IReactive, Memo, type ObjectShapeWith$, type ReactifyProps, Reactive, type ShapeWith$, type ShapeWithNew$, type ShapeWithPick$, Show, Switch, type UseObserveOptions, type UseSelectorOptions, configureReactive, hasSymbol, observer, reactive, reactiveComponents, reactiveObserver, useComputed, useEffectOnce, useIsMounted, useMount, useMountOnce, useObservable, useObservableReducer, useObserve, useObserveEffect, usePauseProvider, useSelector, useUnmount, useUnmountOnce, useWhen, useWhenReady };
186
+ export { $, type BindKey, type BindKeys, Computed, type ExtractFCPropsType, type FCReactive, type FCReactiveObject, For, type IReactive, Memo, type ObjectShapeWith$, type ReactifyProps, Reactive, type ShapeWith$, type ShapeWithNew$, type ShapeWithPick$, Show, Switch, type UseObserveOptions, type UseSelectorOptions, configureReactive, hasSymbol, observer, reactive, reactiveComponents, reactiveObserver, useSelector as use$, useComputed, useEffectOnce, useIsMounted, useMount, useMountOnce, useObservable, useObservableReducer, useObserve, useObserveEffect, usePauseProvider, useSelector, useUnmount, useUnmountOnce, useWhen, useWhenReady };
package/react.js CHANGED
@@ -45,6 +45,7 @@ function createSelectorFunctions(options, isPaused$) {
45
45
  } = state.trackSelector(
46
46
  _selector,
47
47
  _update,
48
+ options,
48
49
  void 0,
49
50
  void 0,
50
51
  /*createResubscribe*/
@@ -103,7 +104,7 @@ function createSelectorFunctions(options, isPaused$) {
103
104
  function useSelector(selector, options) {
104
105
  var _a;
105
106
  if (reactGlobals.inObserver && state.isObservable(selector) && !(options == null ? void 0 : options.suspense)) {
106
- return state.computeSelector(selector);
107
+ return state.computeSelector(selector, options);
107
108
  }
108
109
  let value;
109
110
  try {
@@ -138,6 +139,25 @@ function useSelector(selector, options) {
138
139
  function Computed({ children }) {
139
140
  return useSelector(() => state.computeSelector(state.computeSelector(children)), { skipCheck: true });
140
141
  }
142
+
143
+ // src/react/configureReactive.ts
144
+ var ReactiveFns = /* @__PURE__ */ new Map();
145
+ var ReactiveFnBinders = /* @__PURE__ */ new Map();
146
+ function configureReactive({
147
+ components,
148
+ binders
149
+ }) {
150
+ if (components) {
151
+ for (const key in components) {
152
+ ReactiveFns.set(key, components[key]);
153
+ }
154
+ }
155
+ if (binders) {
156
+ for (const key in binders) {
157
+ ReactiveFnBinders.set(key, binders[key]);
158
+ }
159
+ }
160
+ }
141
161
  var hasSymbol = typeof Symbol === "function" && Symbol.for;
142
162
  var didWarnProps = false;
143
163
  function createReactiveComponent(component, observe3, reactive2, keysReactive, bindKeys) {
@@ -265,7 +285,42 @@ function reactiveComponents(components) {
265
285
  );
266
286
  }
267
287
 
268
- // src/react/For.tsx
288
+ // src/react/$.tsx
289
+ var Memo = React.memo(
290
+ Computed,
291
+ (prev, next) => next.scoped ? prev.children === next.children : true
292
+ );
293
+ var setReactProps = /* @__PURE__ */ new Set([
294
+ "$$typeof",
295
+ "defaultProps",
296
+ "propTypes",
297
+ "tag",
298
+ "PropTypes",
299
+ "displayName",
300
+ "getDefaultProps",
301
+ "type",
302
+ "compare"
303
+ ]);
304
+ var reactives = {};
305
+ var $ = new Proxy(Memo, {
306
+ get(target, p) {
307
+ if (Object.hasOwn(target, p) || setReactProps.has(p)) {
308
+ return target[p];
309
+ }
310
+ if (!reactives[p]) {
311
+ const Component = ReactiveFns.get(p) || p;
312
+ const render = React.forwardRef((props, ref) => {
313
+ const propsOut = { ...props };
314
+ if (ref && (state.isFunction(ref) || !state.isEmpty(ref))) {
315
+ propsOut.ref = ref;
316
+ }
317
+ return React.createElement(Component, propsOut);
318
+ });
319
+ reactives[p] = reactive(render, [], ReactiveFnBinders.get(p));
320
+ }
321
+ return reactives[p];
322
+ }
323
+ });
269
324
  var { findIDKey, getNode, optimized } = state.internal;
270
325
  var autoMemoCache = /* @__PURE__ */ new Map();
271
326
  function For({
@@ -340,28 +395,10 @@ function For({
340
395
  }
341
396
  return out;
342
397
  }
343
- var Memo = React.memo(Computed, () => true);
344
-
345
- // src/react/configureReactive.ts
346
- var ReactiveFns = /* @__PURE__ */ new Map();
347
- var ReactiveFnBinders = /* @__PURE__ */ new Map();
348
- function configureReactive({
349
- components,
350
- binders
351
- }) {
352
- if (components) {
353
- for (const key in components) {
354
- ReactiveFns.set(key, components[key]);
355
- }
356
- }
357
- if (binders) {
358
- for (const key in binders) {
359
- ReactiveFnBinders.set(key, binders[key]);
360
- }
361
- }
362
- }
363
-
364
- // src/react/Reactive.tsx
398
+ var Memo2 = React.memo(
399
+ Computed,
400
+ (prev, next) => next.scoped ? prev.children === next.children : true
401
+ );
365
402
  var Reactive = new Proxy(
366
403
  {},
367
404
  {
@@ -520,7 +557,7 @@ function useObserve(selector, reactionOrOptions, options) {
520
557
  ref.current.reaction = reaction;
521
558
  if (!ref.current.dispose) {
522
559
  ref.current.dispose = state.observe(
523
- (e) => state.computeSelector(ref.current.selector, e),
560
+ (e) => state.computeSelector(ref.current.selector, void 0, e),
524
561
  (e) => {
525
562
  var _a, _b;
526
563
  return (_b = (_a = ref.current).reaction) == null ? void 0 : _b.call(_a, e);
@@ -570,9 +607,10 @@ function useWhenReady(predicate, effect) {
570
607
  return React.useMemo(() => state.whenReady(predicate, effect), []);
571
608
  }
572
609
 
610
+ exports.$ = $;
573
611
  exports.Computed = Computed;
574
612
  exports.For = For;
575
- exports.Memo = Memo;
613
+ exports.Memo = Memo2;
576
614
  exports.Reactive = Reactive;
577
615
  exports.Show = Show;
578
616
  exports.Switch = Switch;
@@ -582,6 +620,7 @@ exports.observer = observer;
582
620
  exports.reactive = reactive;
583
621
  exports.reactiveComponents = reactiveComponents;
584
622
  exports.reactiveObserver = reactiveObserver;
623
+ exports.use$ = useSelector;
585
624
  exports.useComputed = useComputed;
586
625
  exports.useEffectOnce = useEffectOnce;
587
626
  exports.useIsMounted = useIsMounted;
package/react.mjs CHANGED
@@ -39,6 +39,7 @@ function createSelectorFunctions(options, isPaused$) {
39
39
  } = trackSelector(
40
40
  _selector,
41
41
  _update,
42
+ options,
42
43
  void 0,
43
44
  void 0,
44
45
  /*createResubscribe*/
@@ -97,7 +98,7 @@ function createSelectorFunctions(options, isPaused$) {
97
98
  function useSelector(selector, options) {
98
99
  var _a;
99
100
  if (reactGlobals.inObserver && isObservable(selector) && !(options == null ? void 0 : options.suspense)) {
100
- return computeSelector(selector);
101
+ return computeSelector(selector, options);
101
102
  }
102
103
  let value;
103
104
  try {
@@ -132,6 +133,25 @@ function useSelector(selector, options) {
132
133
  function Computed({ children }) {
133
134
  return useSelector(() => computeSelector(computeSelector(children)), { skipCheck: true });
134
135
  }
136
+
137
+ // src/react/configureReactive.ts
138
+ var ReactiveFns = /* @__PURE__ */ new Map();
139
+ var ReactiveFnBinders = /* @__PURE__ */ new Map();
140
+ function configureReactive({
141
+ components,
142
+ binders
143
+ }) {
144
+ if (components) {
145
+ for (const key in components) {
146
+ ReactiveFns.set(key, components[key]);
147
+ }
148
+ }
149
+ if (binders) {
150
+ for (const key in binders) {
151
+ ReactiveFnBinders.set(key, binders[key]);
152
+ }
153
+ }
154
+ }
135
155
  var hasSymbol = typeof Symbol === "function" && Symbol.for;
136
156
  var didWarnProps = false;
137
157
  function createReactiveComponent(component, observe3, reactive2, keysReactive, bindKeys) {
@@ -259,7 +279,42 @@ function reactiveComponents(components) {
259
279
  );
260
280
  }
261
281
 
262
- // src/react/For.tsx
282
+ // src/react/$.tsx
283
+ var Memo = memo(
284
+ Computed,
285
+ (prev, next) => next.scoped ? prev.children === next.children : true
286
+ );
287
+ var setReactProps = /* @__PURE__ */ new Set([
288
+ "$$typeof",
289
+ "defaultProps",
290
+ "propTypes",
291
+ "tag",
292
+ "PropTypes",
293
+ "displayName",
294
+ "getDefaultProps",
295
+ "type",
296
+ "compare"
297
+ ]);
298
+ var reactives = {};
299
+ var $ = new Proxy(Memo, {
300
+ get(target, p) {
301
+ if (Object.hasOwn(target, p) || setReactProps.has(p)) {
302
+ return target[p];
303
+ }
304
+ if (!reactives[p]) {
305
+ const Component = ReactiveFns.get(p) || p;
306
+ const render = forwardRef((props, ref) => {
307
+ const propsOut = { ...props };
308
+ if (ref && (isFunction(ref) || !isEmpty(ref))) {
309
+ propsOut.ref = ref;
310
+ }
311
+ return createElement(Component, propsOut);
312
+ });
313
+ reactives[p] = reactive(render, [], ReactiveFnBinders.get(p));
314
+ }
315
+ return reactives[p];
316
+ }
317
+ });
263
318
  var { findIDKey, getNode, optimized } = internal;
264
319
  var autoMemoCache = /* @__PURE__ */ new Map();
265
320
  function For({
@@ -334,28 +389,10 @@ function For({
334
389
  }
335
390
  return out;
336
391
  }
337
- var Memo = memo(Computed, () => true);
338
-
339
- // src/react/configureReactive.ts
340
- var ReactiveFns = /* @__PURE__ */ new Map();
341
- var ReactiveFnBinders = /* @__PURE__ */ new Map();
342
- function configureReactive({
343
- components,
344
- binders
345
- }) {
346
- if (components) {
347
- for (const key in components) {
348
- ReactiveFns.set(key, components[key]);
349
- }
350
- }
351
- if (binders) {
352
- for (const key in binders) {
353
- ReactiveFnBinders.set(key, binders[key]);
354
- }
355
- }
356
- }
357
-
358
- // src/react/Reactive.tsx
392
+ var Memo2 = memo(
393
+ Computed,
394
+ (prev, next) => next.scoped ? prev.children === next.children : true
395
+ );
359
396
  var Reactive = new Proxy(
360
397
  {},
361
398
  {
@@ -514,7 +551,7 @@ function useObserve(selector, reactionOrOptions, options) {
514
551
  ref.current.reaction = reaction;
515
552
  if (!ref.current.dispose) {
516
553
  ref.current.dispose = observe(
517
- (e) => computeSelector(ref.current.selector, e),
554
+ (e) => computeSelector(ref.current.selector, void 0, e),
518
555
  (e) => {
519
556
  var _a, _b;
520
557
  return (_b = (_a = ref.current).reaction) == null ? void 0 : _b.call(_a, e);
@@ -564,4 +601,4 @@ function useWhenReady(predicate, effect) {
564
601
  return useMemo(() => whenReady(predicate, effect), []);
565
602
  }
566
603
 
567
- export { Computed, For, Memo, Reactive, Show, Switch, configureReactive, hasSymbol, observer, reactive, reactiveComponents, reactiveObserver, useComputed, useEffectOnce, useIsMounted, useMount, useMountOnce, useObservable, useObservableReducer, useObserve, useObserveEffect, usePauseProvider, useSelector, useUnmount, useUnmountOnce, useWhen, useWhenReady };
604
+ export { $, Computed, For, Memo2 as Memo, Reactive, Show, Switch, configureReactive, hasSymbol, observer, reactive, reactiveComponents, reactiveObserver, useSelector as use$, useComputed, useEffectOnce, useIsMounted, useMount, useMountOnce, useObservable, useObservableReducer, useObserve, useObserveEffect, usePauseProvider, useSelector, useUnmount, useUnmountOnce, useWhen, useWhenReady };
@@ -25,12 +25,7 @@ function computeLastSync(data, fieldUpdatedAt, fieldCreatedAt) {
25
25
  }
26
26
  return newLastSync;
27
27
  }
28
- var queuedRetries = {
29
- create: /* @__PURE__ */ new Map(),
30
- update: /* @__PURE__ */ new Map(),
31
- delete: /* @__PURE__ */ new Map()
32
- };
33
- function retrySet(params, retry, action, itemKey, itemValue, change, actionFn, saveResult) {
28
+ function retrySet(params, retry, action, itemKey, itemValue, change, queuedRetries, actionFn, saveResult) {
34
29
  if (action === "delete") {
35
30
  if (queuedRetries.create.has(itemKey)) {
36
31
  queuedRetries.create.delete(itemKey);
@@ -84,6 +79,11 @@ function syncedCrud(props) {
84
79
  } = props;
85
80
  const fieldId = fieldIdProp || "id";
86
81
  const pendingCreates = /* @__PURE__ */ new Set();
82
+ const queuedRetries = {
83
+ create: /* @__PURE__ */ new Map(),
84
+ update: /* @__PURE__ */ new Map(),
85
+ delete: /* @__PURE__ */ new Map()
86
+ };
87
87
  let asType = props.as;
88
88
  if (!asType) {
89
89
  asType = getFn ? "value" : "object";
@@ -240,7 +240,7 @@ function syncedCrud(props) {
240
240
  const changed = asMap ? Array.from(valueAtPath.entries()) : Object.entries(valueAtPath);
241
241
  for (let i = 0; i < changed.length; i++) {
242
242
  const [key, value2] = changed[i];
243
- const prev = asMap ? prevAtPath.get(key) : prevAtPath[key];
243
+ const prev = prevAtPath ? asMap ? prevAtPath.get(key) : prevAtPath[key] : void 0;
244
244
  if (state.isNullOrUndefined(value2) && !state.isNullOrUndefined(prev)) {
245
245
  deletes.add(prev);
246
246
  return false;
@@ -367,6 +367,7 @@ function syncedCrud(props) {
367
367
  itemKey,
368
368
  createObj,
369
369
  changesById.get(itemKey),
370
+ queuedRetries,
370
371
  createFn,
371
372
  saveResult
372
373
  ).then(() => {
@@ -387,6 +388,7 @@ function syncedCrud(props) {
387
388
  itemKey,
388
389
  changed,
389
390
  changesById.get(itemKey),
391
+ queuedRetries,
390
392
  updateFn,
391
393
  saveResult
392
394
  );
@@ -410,6 +412,7 @@ function syncedCrud(props) {
410
412
  itemKey,
411
413
  valuePrevious,
412
414
  changesById.get(itemKey),
415
+ queuedRetries,
413
416
  deleteFn,
414
417
  saveResult
415
418
  );
@@ -422,6 +425,7 @@ function syncedCrud(props) {
422
425
  itemKey,
423
426
  { [fieldId]: itemKey, [fieldDeleted]: true },
424
427
  changesById.get(itemKey),
428
+ queuedRetries,
425
429
  updateFn,
426
430
  saveResult
427
431
  );
@@ -23,12 +23,7 @@ function computeLastSync(data, fieldUpdatedAt, fieldCreatedAt) {
23
23
  }
24
24
  return newLastSync;
25
25
  }
26
- var queuedRetries = {
27
- create: /* @__PURE__ */ new Map(),
28
- update: /* @__PURE__ */ new Map(),
29
- delete: /* @__PURE__ */ new Map()
30
- };
31
- function retrySet(params, retry, action, itemKey, itemValue, change, actionFn, saveResult) {
26
+ function retrySet(params, retry, action, itemKey, itemValue, change, queuedRetries, actionFn, saveResult) {
32
27
  if (action === "delete") {
33
28
  if (queuedRetries.create.has(itemKey)) {
34
29
  queuedRetries.create.delete(itemKey);
@@ -82,6 +77,11 @@ function syncedCrud(props) {
82
77
  } = props;
83
78
  const fieldId = fieldIdProp || "id";
84
79
  const pendingCreates = /* @__PURE__ */ new Set();
80
+ const queuedRetries = {
81
+ create: /* @__PURE__ */ new Map(),
82
+ update: /* @__PURE__ */ new Map(),
83
+ delete: /* @__PURE__ */ new Map()
84
+ };
85
85
  let asType = props.as;
86
86
  if (!asType) {
87
87
  asType = getFn ? "value" : "object";
@@ -238,7 +238,7 @@ function syncedCrud(props) {
238
238
  const changed = asMap ? Array.from(valueAtPath.entries()) : Object.entries(valueAtPath);
239
239
  for (let i = 0; i < changed.length; i++) {
240
240
  const [key, value2] = changed[i];
241
- const prev = asMap ? prevAtPath.get(key) : prevAtPath[key];
241
+ const prev = prevAtPath ? asMap ? prevAtPath.get(key) : prevAtPath[key] : void 0;
242
242
  if (isNullOrUndefined(value2) && !isNullOrUndefined(prev)) {
243
243
  deletes.add(prev);
244
244
  return false;
@@ -365,6 +365,7 @@ function syncedCrud(props) {
365
365
  itemKey,
366
366
  createObj,
367
367
  changesById.get(itemKey),
368
+ queuedRetries,
368
369
  createFn,
369
370
  saveResult
370
371
  ).then(() => {
@@ -385,6 +386,7 @@ function syncedCrud(props) {
385
386
  itemKey,
386
387
  changed,
387
388
  changesById.get(itemKey),
389
+ queuedRetries,
388
390
  updateFn,
389
391
  saveResult
390
392
  );
@@ -408,6 +410,7 @@ function syncedCrud(props) {
408
410
  itemKey,
409
411
  valuePrevious,
410
412
  changesById.get(itemKey),
413
+ queuedRetries,
411
414
  deleteFn,
412
415
  saveResult
413
416
  );
@@ -420,6 +423,7 @@ function syncedCrud(props) {
420
423
  itemKey,
421
424
  { [fieldId]: itemKey, [fieldDeleted]: true },
422
425
  changesById.get(itemKey),
426
+ queuedRetries,
423
427
  updateFn,
424
428
  saveResult
425
429
  );
@@ -13,7 +13,7 @@ type APIError = {
13
13
  type: string;
14
14
  message: string;
15
15
  requestId?: string;
16
- error?: Error;
16
+ error?: unknown;
17
17
  };
18
18
  type APIResult<T> = Result<T, APIError>;
19
19
  type Data<T> = {
@@ -25,7 +25,6 @@ type Err<U> = {
25
25
  error: U;
26
26
  };
27
27
  type Result<T, U> = NonNullable<Data<T> | Err<U>>;
28
- declare function generateKeelId(): string;
29
28
  interface KeelGetParams {
30
29
  }
31
30
  interface KeelListParams<Where = {}> {
@@ -63,7 +62,7 @@ interface SyncedKeelPropsManyWhere<TRemote extends {
63
62
  }, TLocal, AOption extends CrudAsOption, Where extends Record<string, any>> extends SyncedKeelPropsManyBase<TRemote, TLocal, AOption> {
64
63
  list?: (params: KeelListParams<NoInfer<Where>>) => Promise<CrudResult<APIResult<{
65
64
  results: TRemote[];
66
- pageInfo: any;
65
+ pageInfo?: any;
67
66
  }>>>;
68
67
  where?: Where | (() => Where);
69
68
  }
@@ -72,7 +71,7 @@ interface SyncedKeelPropsManyNoWhere<TRemote extends {
72
71
  }, TLocal, AOption extends CrudAsOption> extends SyncedKeelPropsManyBase<TRemote, TLocal, AOption> {
73
72
  list?: (params: KeelListParams<{}>) => Promise<CrudResult<APIResult<{
74
73
  results: TRemote[];
75
- pageInfo: any;
74
+ pageInfo?: any;
76
75
  }>>>;
77
76
  where?: never | {};
78
77
  }
@@ -99,8 +98,8 @@ interface SyncedKeelPropsBase<TRemote extends {
99
98
  create?: (i: NoInfer<Partial<TRemote>>) => Promise<APIResult<NoInfer<TRemote>>>;
100
99
  update?: (params: {
101
100
  where: any;
102
- values?: Partial<TRemote>;
103
- }) => Promise<APIResult<TRemote>>;
101
+ values?: NoInfer<Partial<TRemote>>;
102
+ }) => Promise<APIResult<NoInfer<TRemote>>>;
104
103
  delete?: (params: {
105
104
  id: string;
106
105
  }) => Promise<APIResult<string>>;
@@ -119,4 +118,4 @@ declare function syncedKeel<TRemote extends {
119
118
  id: string;
120
119
  }, TLocal = TRemote, TOption extends CrudAsOption = 'object', Where extends Record<string, any> = {}>(props: SyncedKeelPropsBase<TRemote, TLocal> & SyncedKeelPropsMany<TRemote, TLocal, TOption, Where>): SyncedCrudReturnType<TLocal, Exclude<TOption, 'value'>>;
121
120
 
122
- export { type KeelClient, type KeelErrorParams, type KeelGetParams, type KeelKey, KeelKeys, type KeelListParams, type KeelObjectBase, type KeelRealtimePlugin, type OmitKeelBuiltins, type SyncedKeelPropsBase, generateKeelId, syncedKeel };
121
+ export { type KeelClient, type KeelErrorParams, type KeelGetParams, type KeelKey, KeelKeys, type KeelListParams, type KeelObjectBase, type KeelRealtimePlugin, type OmitKeelBuiltins, type SyncedKeelPropsBase, syncedKeel };
@@ -13,7 +13,7 @@ type APIError = {
13
13
  type: string;
14
14
  message: string;
15
15
  requestId?: string;
16
- error?: Error;
16
+ error?: unknown;
17
17
  };
18
18
  type APIResult<T> = Result<T, APIError>;
19
19
  type Data<T> = {
@@ -25,7 +25,6 @@ type Err<U> = {
25
25
  error: U;
26
26
  };
27
27
  type Result<T, U> = NonNullable<Data<T> | Err<U>>;
28
- declare function generateKeelId(): string;
29
28
  interface KeelGetParams {
30
29
  }
31
30
  interface KeelListParams<Where = {}> {
@@ -63,7 +62,7 @@ interface SyncedKeelPropsManyWhere<TRemote extends {
63
62
  }, TLocal, AOption extends CrudAsOption, Where extends Record<string, any>> extends SyncedKeelPropsManyBase<TRemote, TLocal, AOption> {
64
63
  list?: (params: KeelListParams<NoInfer<Where>>) => Promise<CrudResult<APIResult<{
65
64
  results: TRemote[];
66
- pageInfo: any;
65
+ pageInfo?: any;
67
66
  }>>>;
68
67
  where?: Where | (() => Where);
69
68
  }
@@ -72,7 +71,7 @@ interface SyncedKeelPropsManyNoWhere<TRemote extends {
72
71
  }, TLocal, AOption extends CrudAsOption> extends SyncedKeelPropsManyBase<TRemote, TLocal, AOption> {
73
72
  list?: (params: KeelListParams<{}>) => Promise<CrudResult<APIResult<{
74
73
  results: TRemote[];
75
- pageInfo: any;
74
+ pageInfo?: any;
76
75
  }>>>;
77
76
  where?: never | {};
78
77
  }
@@ -99,8 +98,8 @@ interface SyncedKeelPropsBase<TRemote extends {
99
98
  create?: (i: NoInfer<Partial<TRemote>>) => Promise<APIResult<NoInfer<TRemote>>>;
100
99
  update?: (params: {
101
100
  where: any;
102
- values?: Partial<TRemote>;
103
- }) => Promise<APIResult<TRemote>>;
101
+ values?: NoInfer<Partial<TRemote>>;
102
+ }) => Promise<APIResult<NoInfer<TRemote>>>;
104
103
  delete?: (params: {
105
104
  id: string;
106
105
  }) => Promise<APIResult<string>>;
@@ -119,4 +118,4 @@ declare function syncedKeel<TRemote extends {
119
118
  id: string;
120
119
  }, TLocal = TRemote, TOption extends CrudAsOption = 'object', Where extends Record<string, any> = {}>(props: SyncedKeelPropsBase<TRemote, TLocal> & SyncedKeelPropsMany<TRemote, TLocal, TOption, Where>): SyncedCrudReturnType<TLocal, Exclude<TOption, 'value'>>;
121
120
 
122
- export { type KeelClient, type KeelErrorParams, type KeelGetParams, type KeelKey, KeelKeys, type KeelListParams, type KeelObjectBase, type KeelRealtimePlugin, type OmitKeelBuiltins, type SyncedKeelPropsBase, generateKeelId, syncedKeel };
121
+ export { type KeelClient, type KeelErrorParams, type KeelGetParams, type KeelKey, KeelKeys, type KeelListParams, type KeelObjectBase, type KeelRealtimePlugin, type OmitKeelBuiltins, type SyncedKeelPropsBase, syncedKeel };
@@ -3,17 +3,9 @@
3
3
  var state = require('@legendapp/state');
4
4
  var sync = require('@legendapp/state/sync');
5
5
  var crud = require('@legendapp/state/sync-plugins/crud');
6
- var ksuid = require('ksuid');
7
-
8
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
-
10
- var ksuid__default = /*#__PURE__*/_interopDefault(ksuid);
11
6
 
12
7
  // src/sync-plugins/keel.ts
13
8
  var KeelKeys = ["createdAt", "updatedAt"];
14
- function generateKeelId() {
15
- return ksuid__default.default.randomSync().string;
16
- }
17
9
  var modifiedClients = /* @__PURE__ */ new WeakSet();
18
10
  var isAuthed$ = state.observable(false);
19
11
  var isAuthing$ = state.observable(false);
@@ -320,11 +312,9 @@ function syncedKeel(props) {
320
312
  changesSince,
321
313
  updatePartial: true,
322
314
  subscribe,
323
- generateId: generateKeelId,
324
315
  get
325
316
  });
326
317
  }
327
318
 
328
319
  exports.KeelKeys = KeelKeys;
329
- exports.generateKeelId = generateKeelId;
330
320
  exports.syncedKeel = syncedKeel;
@@ -1,13 +1,9 @@
1
1
  import { observable, isFunction, when, batch, isEmpty } from '@legendapp/state';
2
2
  import { createRevertChanges } from '@legendapp/state/sync';
3
3
  import { syncedCrud } from '@legendapp/state/sync-plugins/crud';
4
- import ksuid from 'ksuid';
5
4
 
6
5
  // src/sync-plugins/keel.ts
7
6
  var KeelKeys = ["createdAt", "updatedAt"];
8
- function generateKeelId() {
9
- return ksuid.randomSync().string;
10
- }
11
7
  var modifiedClients = /* @__PURE__ */ new WeakSet();
12
8
  var isAuthed$ = observable(false);
13
9
  var isAuthing$ = observable(false);
@@ -314,9 +310,8 @@ function syncedKeel(props) {
314
310
  changesSince,
315
311
  updatePartial: true,
316
312
  subscribe,
317
- generateId: generateKeelId,
318
313
  get
319
314
  });
320
315
  }
321
316
 
322
- export { KeelKeys, generateKeelId, syncedKeel };
317
+ export { KeelKeys, syncedKeel };
package/sync.js CHANGED
@@ -36,12 +36,12 @@ function diffObjects(obj1, obj2, deep = false) {
36
36
  return diff;
37
37
  }
38
38
  function deepEqual(a, b, ignoreFields, nullVsUndefined) {
39
- if (a === b) {
39
+ if (a === b)
40
40
  return true;
41
- }
42
- if (state.isNullOrUndefined(a) !== state.isNullOrUndefined(b)) {
41
+ if (state.isNullOrUndefined(a) !== state.isNullOrUndefined(b))
43
42
  return false;
44
- }
43
+ if (!state.isObject(a) || !state.isObject(b))
44
+ return a === b;
45
45
  if (nullVsUndefined) {
46
46
  a = removeNullUndefined(
47
47
  a,
@@ -54,8 +54,18 @@ function deepEqual(a, b, ignoreFields, nullVsUndefined) {
54
54
  true
55
55
  );
56
56
  }
57
- const replacer = ignoreFields ? (key, value) => ignoreFields.includes(key) ? void 0 : value : void 0;
58
- return JSON.stringify(a, replacer) === JSON.stringify(b, replacer);
57
+ const keysA = Object.keys(a).filter((key) => !(ignoreFields == null ? void 0 : ignoreFields.includes(key)));
58
+ const keysB = Object.keys(b).filter((key) => !(ignoreFields == null ? void 0 : ignoreFields.includes(key)));
59
+ if (keysA.length !== keysB.length)
60
+ return false;
61
+ return keysA.every((key) => {
62
+ if (!Object.prototype.hasOwnProperty.call(b, key))
63
+ return false;
64
+ if (state.isDate(a[key]) && state.isDate(b[key])) {
65
+ return a[key].getTime() === b[key].getTime();
66
+ }
67
+ return deepEqual(a[key], b[key], ignoreFields, nullVsUndefined);
68
+ });
59
69
  }
60
70
  function combineTransforms(...transforms) {
61
71
  return {
@@ -309,8 +319,25 @@ function mergeChanges(changes) {
309
319
  existing.valueAtPath = change.valueAtPath;
310
320
  }
311
321
  } else {
312
- changesByPath.set(pathStr, change);
313
- changesOut.push(change);
322
+ let found = false;
323
+ for (let u = 0; u < change.path.length; u++) {
324
+ const path = change.path.slice(0, u).join("/");
325
+ if (changesByPath.has(path)) {
326
+ const remaining = change.path.slice(u);
327
+ state.setAtPath(
328
+ changesByPath.get(path).valueAtPath,
329
+ remaining,
330
+ change.pathTypes.slice(u),
331
+ change.valueAtPath
332
+ );
333
+ found = true;
334
+ break;
335
+ }
336
+ }
337
+ if (!found) {
338
+ changesByPath.set(pathStr, change);
339
+ changesOut.push(change);
340
+ }
314
341
  }
315
342
  }
316
343
  return changesOut;
@@ -860,27 +887,33 @@ function syncObservable(obs$, syncOptionsOrSynced) {
860
887
  syncState$.isLoaded.set(!syncState$.numPendingRemoteLoads.peek());
861
888
  let isSynced = false;
862
889
  let isSubscribed = false;
890
+ let isApplyingPendingAfterSync = false;
863
891
  let unsubscribe = void 0;
864
892
  const applyPending = (pending) => {
865
893
  if (pending && !state.isEmpty(pending)) {
866
- localState.isApplyingPending = true;
867
894
  const keys = Object.keys(pending);
895
+ const value = getNodeValue(node);
868
896
  const changes = [];
869
897
  for (let i = 0; i < keys.length; i++) {
870
898
  const key = keys[i];
871
899
  const path = key.split("/").filter((p2) => p2 !== "");
872
- const { p, v, t } = pending[key];
873
- changes.push({ path, valueAtPath: v, prevAtPath: p, pathTypes: t });
900
+ const { p, t, v } = pending[key];
901
+ const valueAtPath = getValueAtPath(value, path);
902
+ if (isApplyingPendingAfterSync || !deepEqual(valueAtPath, v)) {
903
+ changes.push({ path, valueAtPath: v, prevAtPath: p, pathTypes: t });
904
+ }
905
+ }
906
+ if (changes.length > 0) {
907
+ localState.isApplyingPending = true;
908
+ onObsChange(obs$, syncState$, localState, syncOptions, {
909
+ value,
910
+ isFromPersist: false,
911
+ isFromSync: false,
912
+ getPrevious: createPreviousHandler(value, changes),
913
+ changes
914
+ });
915
+ localState.isApplyingPending = false;
874
916
  }
875
- const value = getNodeValue(node);
876
- onObsChange(obs$, syncState$, localState, syncOptions, {
877
- value,
878
- isFromPersist: false,
879
- isFromSync: false,
880
- getPrevious: createPreviousHandler(value, changes),
881
- changes
882
- });
883
- localState.isApplyingPending = false;
884
917
  }
885
918
  };
886
919
  const { get, subscribe } = syncOptions;
@@ -917,10 +950,10 @@ function syncObservable(obs$, syncOptionsOrSynced) {
917
950
  const { v, t } = pending2[key];
918
951
  if (t.length === 0 || !value) {
919
952
  const oldValue = clone2(value);
920
- pending2[key].p = oldValue;
953
+ pending2[key].p = key ? oldValue[key] : oldValue;
921
954
  if (state.isObject(value) && state.isObject(v)) {
922
- Object.assign(value, v);
923
- } else {
955
+ Object.assign(value, key ? { [key]: v } : v);
956
+ } else if (!key) {
924
957
  value = v;
925
958
  }
926
959
  } else if (value[p[0]] !== void 0) {
@@ -932,6 +965,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
932
965
  } else {
933
966
  const oldValue = clone2(value);
934
967
  pending2[key].p = getValueAtPath(oldValue, p);
968
+ didChangeMetadata = true;
935
969
  value = state.setAtPath(
936
970
  value,
937
971
  p,
@@ -952,7 +986,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
952
986
  }
953
987
  });
954
988
  if (didChangeMetadata && syncOptions.persist) {
955
- updateMetadata(obs$, localState, syncState$, syncOptions, {
989
+ updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
956
990
  pending: pending2
957
991
  });
958
992
  }
@@ -1129,14 +1163,17 @@ function syncObservable(obs$, syncOptionsOrSynced) {
1129
1163
  }
1130
1164
  if (!isSynced) {
1131
1165
  isSynced = true;
1132
- await state.when(syncState$.isLoaded);
1166
+ isApplyingPendingAfterSync = true;
1133
1167
  applyPending(pending);
1168
+ isApplyingPendingAfterSync = false;
1134
1169
  }
1135
1170
  };
1136
1171
  syncStateValue.sync = sync;
1137
1172
  } else {
1138
1173
  if (!isSynced) {
1174
+ isApplyingPendingAfterSync = true;
1139
1175
  applyPending(localState.pendingChanges);
1176
+ isApplyingPendingAfterSync = false;
1140
1177
  }
1141
1178
  }
1142
1179
  syncStateValue.reset = async () => {
package/sync.mjs CHANGED
@@ -34,12 +34,12 @@ function diffObjects(obj1, obj2, deep = false) {
34
34
  return diff;
35
35
  }
36
36
  function deepEqual(a, b, ignoreFields, nullVsUndefined) {
37
- if (a === b) {
37
+ if (a === b)
38
38
  return true;
39
- }
40
- if (isNullOrUndefined(a) !== isNullOrUndefined(b)) {
39
+ if (isNullOrUndefined(a) !== isNullOrUndefined(b))
41
40
  return false;
42
- }
41
+ if (!isObject(a) || !isObject(b))
42
+ return a === b;
43
43
  if (nullVsUndefined) {
44
44
  a = removeNullUndefined(
45
45
  a,
@@ -52,8 +52,18 @@ function deepEqual(a, b, ignoreFields, nullVsUndefined) {
52
52
  true
53
53
  );
54
54
  }
55
- const replacer = ignoreFields ? (key, value) => ignoreFields.includes(key) ? void 0 : value : void 0;
56
- return JSON.stringify(a, replacer) === JSON.stringify(b, replacer);
55
+ const keysA = Object.keys(a).filter((key) => !(ignoreFields == null ? void 0 : ignoreFields.includes(key)));
56
+ const keysB = Object.keys(b).filter((key) => !(ignoreFields == null ? void 0 : ignoreFields.includes(key)));
57
+ if (keysA.length !== keysB.length)
58
+ return false;
59
+ return keysA.every((key) => {
60
+ if (!Object.prototype.hasOwnProperty.call(b, key))
61
+ return false;
62
+ if (isDate(a[key]) && isDate(b[key])) {
63
+ return a[key].getTime() === b[key].getTime();
64
+ }
65
+ return deepEqual(a[key], b[key], ignoreFields, nullVsUndefined);
66
+ });
57
67
  }
58
68
  function combineTransforms(...transforms) {
59
69
  return {
@@ -307,8 +317,25 @@ function mergeChanges(changes) {
307
317
  existing.valueAtPath = change.valueAtPath;
308
318
  }
309
319
  } else {
310
- changesByPath.set(pathStr, change);
311
- changesOut.push(change);
320
+ let found = false;
321
+ for (let u = 0; u < change.path.length; u++) {
322
+ const path = change.path.slice(0, u).join("/");
323
+ if (changesByPath.has(path)) {
324
+ const remaining = change.path.slice(u);
325
+ setAtPath(
326
+ changesByPath.get(path).valueAtPath,
327
+ remaining,
328
+ change.pathTypes.slice(u),
329
+ change.valueAtPath
330
+ );
331
+ found = true;
332
+ break;
333
+ }
334
+ }
335
+ if (!found) {
336
+ changesByPath.set(pathStr, change);
337
+ changesOut.push(change);
338
+ }
312
339
  }
313
340
  }
314
341
  return changesOut;
@@ -858,27 +885,33 @@ function syncObservable(obs$, syncOptionsOrSynced) {
858
885
  syncState$.isLoaded.set(!syncState$.numPendingRemoteLoads.peek());
859
886
  let isSynced = false;
860
887
  let isSubscribed = false;
888
+ let isApplyingPendingAfterSync = false;
861
889
  let unsubscribe = void 0;
862
890
  const applyPending = (pending) => {
863
891
  if (pending && !isEmpty(pending)) {
864
- localState.isApplyingPending = true;
865
892
  const keys = Object.keys(pending);
893
+ const value = getNodeValue(node);
866
894
  const changes = [];
867
895
  for (let i = 0; i < keys.length; i++) {
868
896
  const key = keys[i];
869
897
  const path = key.split("/").filter((p2) => p2 !== "");
870
- const { p, v, t } = pending[key];
871
- changes.push({ path, valueAtPath: v, prevAtPath: p, pathTypes: t });
898
+ const { p, t, v } = pending[key];
899
+ const valueAtPath = getValueAtPath(value, path);
900
+ if (isApplyingPendingAfterSync || !deepEqual(valueAtPath, v)) {
901
+ changes.push({ path, valueAtPath: v, prevAtPath: p, pathTypes: t });
902
+ }
903
+ }
904
+ if (changes.length > 0) {
905
+ localState.isApplyingPending = true;
906
+ onObsChange(obs$, syncState$, localState, syncOptions, {
907
+ value,
908
+ isFromPersist: false,
909
+ isFromSync: false,
910
+ getPrevious: createPreviousHandler(value, changes),
911
+ changes
912
+ });
913
+ localState.isApplyingPending = false;
872
914
  }
873
- const value = getNodeValue(node);
874
- onObsChange(obs$, syncState$, localState, syncOptions, {
875
- value,
876
- isFromPersist: false,
877
- isFromSync: false,
878
- getPrevious: createPreviousHandler(value, changes),
879
- changes
880
- });
881
- localState.isApplyingPending = false;
882
915
  }
883
916
  };
884
917
  const { get, subscribe } = syncOptions;
@@ -915,10 +948,10 @@ function syncObservable(obs$, syncOptionsOrSynced) {
915
948
  const { v, t } = pending2[key];
916
949
  if (t.length === 0 || !value) {
917
950
  const oldValue = clone2(value);
918
- pending2[key].p = oldValue;
951
+ pending2[key].p = key ? oldValue[key] : oldValue;
919
952
  if (isObject(value) && isObject(v)) {
920
- Object.assign(value, v);
921
- } else {
953
+ Object.assign(value, key ? { [key]: v } : v);
954
+ } else if (!key) {
922
955
  value = v;
923
956
  }
924
957
  } else if (value[p[0]] !== void 0) {
@@ -930,6 +963,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
930
963
  } else {
931
964
  const oldValue = clone2(value);
932
965
  pending2[key].p = getValueAtPath(oldValue, p);
966
+ didChangeMetadata = true;
933
967
  value = setAtPath(
934
968
  value,
935
969
  p,
@@ -950,7 +984,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
950
984
  }
951
985
  });
952
986
  if (didChangeMetadata && syncOptions.persist) {
953
- updateMetadata(obs$, localState, syncState$, syncOptions, {
987
+ updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
954
988
  pending: pending2
955
989
  });
956
990
  }
@@ -1127,14 +1161,17 @@ function syncObservable(obs$, syncOptionsOrSynced) {
1127
1161
  }
1128
1162
  if (!isSynced) {
1129
1163
  isSynced = true;
1130
- await when(syncState$.isLoaded);
1164
+ isApplyingPendingAfterSync = true;
1131
1165
  applyPending(pending);
1166
+ isApplyingPendingAfterSync = false;
1132
1167
  }
1133
1168
  };
1134
1169
  syncStateValue.sync = sync;
1135
1170
  } else {
1136
1171
  if (!isSynced) {
1172
+ isApplyingPendingAfterSync = true;
1137
1173
  applyPending(localState.pendingChanges);
1174
+ isApplyingPendingAfterSync = false;
1138
1175
  }
1139
1176
  }
1140
1177
  syncStateValue.reset = async () => {