@legendapp/state 3.0.0-beta.4 → 3.0.0-beta.41

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 (79) hide show
  1. package/.DS_Store +0 -0
  2. package/README.md +2 -2
  3. package/config/enableReactComponents.js +3 -1
  4. package/config/enableReactComponents.mjs +3 -1
  5. package/config/enableReactTracking.d.mts +2 -1
  6. package/config/enableReactTracking.d.ts +2 -1
  7. package/config/enableReactTracking.js +32 -13
  8. package/config/enableReactTracking.mjs +32 -13
  9. package/index.d.mts +46 -8
  10. package/index.d.ts +46 -8
  11. package/index.js +267 -75
  12. package/index.mjs +267 -75
  13. package/package.json +35 -1
  14. package/persist-plugins/async-storage.js +17 -9
  15. package/persist-plugins/async-storage.mjs +17 -9
  16. package/persist-plugins/expo-sqlite.d.mts +19 -0
  17. package/persist-plugins/expo-sqlite.d.ts +19 -0
  18. package/persist-plugins/expo-sqlite.js +72 -0
  19. package/persist-plugins/expo-sqlite.mjs +69 -0
  20. package/persist-plugins/indexeddb.js +13 -3
  21. package/persist-plugins/indexeddb.mjs +13 -3
  22. package/react-native.d.mts +4 -0
  23. package/react-native.d.ts +4 -0
  24. package/react-native.js +53 -0
  25. package/react-native.mjs +40 -0
  26. package/react-reactive/Components.d.mts +19 -0
  27. package/react-reactive/Components.d.ts +19 -0
  28. package/react-reactive/Components.js +53 -0
  29. package/react-reactive/Components.mjs +40 -0
  30. package/react-reactive/enableReactComponents.d.mts +3 -2
  31. package/react-reactive/enableReactComponents.d.ts +3 -2
  32. package/react-reactive/enableReactComponents.js +10 -3
  33. package/react-reactive/enableReactComponents.mjs +10 -3
  34. package/react-reactive/enableReactNativeComponents.d.mts +3 -20
  35. package/react-reactive/enableReactNativeComponents.d.ts +3 -20
  36. package/react-reactive/enableReactNativeComponents.js +8 -3
  37. package/react-reactive/enableReactNativeComponents.mjs +8 -3
  38. package/react-reactive/enableReactive.js +10 -3
  39. package/react-reactive/enableReactive.mjs +10 -3
  40. package/react-reactive/enableReactive.native.js +8 -3
  41. package/react-reactive/enableReactive.native.mjs +8 -3
  42. package/react-reactive/enableReactive.web.js +8 -3
  43. package/react-reactive/enableReactive.web.mjs +8 -3
  44. package/react-web.d.mts +7 -0
  45. package/react-web.d.ts +7 -0
  46. package/react-web.js +39 -0
  47. package/react-web.mjs +37 -0
  48. package/react.d.mts +59 -26
  49. package/react.d.ts +59 -26
  50. package/react.js +136 -87
  51. package/react.mjs +135 -89
  52. package/sync-plugins/crud.d.mts +24 -9
  53. package/sync-plugins/crud.d.ts +24 -9
  54. package/sync-plugins/crud.js +267 -123
  55. package/sync-plugins/crud.mjs +268 -124
  56. package/sync-plugins/firebase.d.mts +7 -3
  57. package/sync-plugins/firebase.d.ts +7 -3
  58. package/sync-plugins/firebase.js +214 -64
  59. package/sync-plugins/firebase.mjs +215 -65
  60. package/sync-plugins/keel.d.mts +12 -13
  61. package/sync-plugins/keel.d.ts +12 -13
  62. package/sync-plugins/keel.js +60 -52
  63. package/sync-plugins/keel.mjs +61 -48
  64. package/sync-plugins/supabase.d.mts +10 -5
  65. package/sync-plugins/supabase.d.ts +10 -5
  66. package/sync-plugins/supabase.js +90 -33
  67. package/sync-plugins/supabase.mjs +91 -34
  68. package/sync-plugins/tanstack-query.d.mts +3 -3
  69. package/sync-plugins/tanstack-query.d.ts +3 -3
  70. package/sync-plugins/tanstack-query.js +1 -1
  71. package/sync-plugins/tanstack-query.mjs +1 -1
  72. package/sync.d.mts +17 -8
  73. package/sync.d.ts +17 -8
  74. package/sync.js +448 -307
  75. package/sync.mjs +446 -307
  76. package/trace.js +5 -6
  77. package/trace.mjs +5 -6
  78. package/types/reactive-native.d.ts +19 -0
  79. package/types/reactive-web.d.ts +7 -0
package/.DS_Store CHANGED
Binary file
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.
@@ -4,7 +4,9 @@ var react = require('@legendapp/state/react');
4
4
 
5
5
  // src/config/enableReactComponents.ts
6
6
  function enableReactComponents() {
7
- const bindInfo = { value: { handler: "onChange", getValue: (e) => e.target.value, defaultValue: "" } };
7
+ const bindInfo = {
8
+ value: { handler: "onChange", getValue: (e) => e.target.value, defaultValue: "" }
9
+ };
8
10
  const bindInfoInput = Object.assign(
9
11
  { checked: { handler: "onChange", getValue: (e) => e.target.checked } },
10
12
  bindInfo
@@ -2,7 +2,9 @@ import { configureReactive } from '@legendapp/state/react';
2
2
 
3
3
  // src/config/enableReactComponents.ts
4
4
  function enableReactComponents() {
5
- const bindInfo = { value: { handler: "onChange", getValue: (e) => e.target.value, defaultValue: "" } };
5
+ const bindInfo = {
6
+ value: { handler: "onChange", getValue: (e) => e.target.value, defaultValue: "" }
7
+ };
6
8
  const bindInfoInput = Object.assign(
7
9
  { checked: { handler: "onChange", getValue: (e) => e.target.checked } },
8
10
  bindInfo
@@ -1,7 +1,8 @@
1
1
  interface ReactTrackingOptions {
2
2
  auto?: boolean;
3
3
  warnUnobserved?: boolean;
4
+ warnMissingUse?: boolean;
4
5
  }
5
- declare function enableReactTracking({ auto, warnUnobserved }: ReactTrackingOptions): void;
6
+ declare function enableReactTracking({ auto, warnUnobserved, warnMissingUse }: 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
+ warnMissingUse?: boolean;
4
5
  }
5
- declare function enableReactTracking({ auto, warnUnobserved }: ReactTrackingOptions): void;
6
+ declare function enableReactTracking({ auto, warnUnobserved, warnMissingUse }: ReactTrackingOptions): void;
6
7
 
7
8
  export { enableReactTracking };
@@ -6,32 +6,51 @@ 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, warnMissingUse }) {
10
10
  const { get } = state.internal;
11
- if (auto || process.env.NODE_ENV === "development" && warnUnobserved) {
11
+ if (auto || process.env.NODE_ENV === "development" && (warnUnobserved || warnMissingUse)) {
12
12
  const ReactRenderContext = react.createContext(0);
13
- const needsSelector = () => {
14
- 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) {
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;
22
19
  }
20
+ } catch (e) {
21
+ }
22
+ return false;
23
+ };
24
+ const isObserved = () => {
25
+ return !!state.tracking.current;
26
+ };
27
+ const needsSelector = () => {
28
+ if (!isObserved()) {
29
+ return isInRender();
23
30
  }
24
31
  return false;
25
32
  };
26
33
  configureLegendState.configureLegendState({
27
34
  observableFunctions: {
28
35
  get: (node, options) => {
29
- if (needsSelector()) {
36
+ if (process.env.NODE_ENV === "development" && warnMissingUse) {
37
+ if (isInRender()) {
38
+ if (isObserved()) {
39
+ console.warn(
40
+ "[legend-state] Detected a `get()` call in an observer 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$"
41
+ );
42
+ } else {
43
+ console.warn(
44
+ "[legend-state] Detected a `get()` call in a component. You likely want to use the `use$` hook to be reactive to it changing, or change `get()` to `peek()` to get the value without tracking: https://legendapp.com/open-source/state/v3/react/react-api/#use$"
45
+ );
46
+ }
47
+ }
48
+ } else if (needsSelector()) {
30
49
  if (auto) {
31
50
  return react$1.useSelector(() => get(node, options), state.isObject(options) ? options : void 0);
32
51
  } else if (process.env.NODE_ENV === "development" && warnUnobserved) {
33
52
  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"
53
+ "[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
54
  );
36
55
  }
37
56
  }
@@ -4,32 +4,51 @@ 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, warnMissingUse }) {
8
8
  const { get } = internal;
9
- if (auto || process.env.NODE_ENV === "development" && warnUnobserved) {
9
+ if (auto || process.env.NODE_ENV === "development" && (warnUnobserved || warnMissingUse)) {
10
10
  const ReactRenderContext = createContext(0);
11
- const needsSelector = () => {
12
- 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) {
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;
20
17
  }
18
+ } catch (e) {
19
+ }
20
+ return false;
21
+ };
22
+ const isObserved = () => {
23
+ return !!tracking.current;
24
+ };
25
+ const needsSelector = () => {
26
+ if (!isObserved()) {
27
+ return isInRender();
21
28
  }
22
29
  return false;
23
30
  };
24
31
  configureLegendState({
25
32
  observableFunctions: {
26
33
  get: (node, options) => {
27
- if (needsSelector()) {
34
+ if (process.env.NODE_ENV === "development" && warnMissingUse) {
35
+ if (isInRender()) {
36
+ if (isObserved()) {
37
+ console.warn(
38
+ "[legend-state] Detected a `get()` call in an observer 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$"
39
+ );
40
+ } else {
41
+ console.warn(
42
+ "[legend-state] Detected a `get()` call in a component. You likely want to use the `use$` hook to be reactive to it changing, or change `get()` to `peek()` to get the value without tracking: https://legendapp.com/open-source/state/v3/react/react-api/#use$"
43
+ );
44
+ }
45
+ }
46
+ } else if (needsSelector()) {
28
47
  if (auto) {
29
48
  return useSelector(() => get(node, options), isObject(options) ? options : void 0);
30
49
  } else if (process.env.NODE_ENV === "development" && warnUnobserved) {
31
50
  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"
51
+ "[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
52
  );
34
53
  }
35
54
  }
package/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- type Primitive$1 = string | number | boolean | symbol | bigint | undefined | null | Date;
1
+ type Primitive$1 = string | number | boolean | symbol | bigint | undefined | null | Date | OpaqueObject<unknown>;
2
2
  type ArrayOverrideFnNames = 'find' | 'findIndex' | 'every' | 'some' | 'filter' | 'reduce' | 'reduceRight' | 'forEach' | 'map' | 'sort';
3
3
  type RemoveIndex<T> = {
4
4
  [K in keyof T as string extends K ? never : number extends K ? never : K]: T[K];
@@ -7,7 +7,7 @@ type BuiltIns = String | Boolean | Number | Date | Error | RegExp | Array<any> |
7
7
  type IsUserDefinedObject<T> = T extends Function | BuiltIns | any[] ? false : T extends object ? true : false;
8
8
  type RemoveObservables<T> = T extends ImmutableObservableBase<infer t> ? t : T extends ImmutableObservableBase<infer t>[] ? t[] : IsUserDefinedObject<T> extends true ? {
9
9
  [K in keyof T]: RemoveObservables<T[K]>;
10
- } : T extends ImmutableObservableBase<infer TObs> ? TObs : T extends () => infer TRet ? RemoveObservables<TRet> & T : T extends (key: infer TKey extends string | number) => infer TRet ? Record<TKey, RemoveObservables<TRet>> & T : T;
10
+ } : T extends ImmutableObservableBase<infer TObs> ? TObs : T extends () => infer TRet ? RemoveObservables<TRet> & T : T extends (key: infer TKey extends string | number) => infer TRet ? Record<TKey, RemoveObservables<TRet>> & T : T extends OpaqueObject<infer TObj> ? TObj : T;
11
11
  interface ObservableArray<T, U> extends ObservablePrimitive<T>, Pick<Array<Observable<U>>, ArrayOverrideFnNames>, Omit<RemoveIndex<Array<U>>, ArrayOverrideFnNames> {
12
12
  }
13
13
  interface ObservableObjectFns<T> {
@@ -108,14 +108,17 @@ declare function getNode(value$: ObservableParam): NodeInfo;
108
108
  declare function setNodeValue(node: NodeInfo, newValue: any): {
109
109
  prevValue: any;
110
110
  newValue: any;
111
+ parentValue: any;
111
112
  };
112
113
  declare function getNodeValue(node: NodeInfo): any;
114
+ declare function getChildNode(node: NodeInfo, key: string, asFunction?: Function): NodeInfo;
113
115
  declare function ensureNodeValue(node: NodeInfo): any;
114
116
  declare function findIDKey(obj: unknown | undefined, node: NodeInfo): string | ((value: any) => string) | undefined;
117
+ declare function getKeys(obj: Record<any, any> | Array<any> | undefined, isArr: boolean, isMap: boolean, isSet: boolean): string[];
115
118
 
116
119
  type TrackingType = undefined | true | symbol;
117
120
  interface GetOptions {
118
- shallow: boolean;
121
+ shallow?: boolean;
119
122
  }
120
123
  type OpaqueObject<T> = T & {
121
124
  [symbolOpaque]: true;
@@ -146,12 +149,13 @@ interface Change {
146
149
  type RecordValue<T> = T extends Record<string, infer t> ? t : never;
147
150
  type ArrayValue<T> = T extends Array<infer t> ? t : never;
148
151
  type ObservableValue<T> = T extends Observable<infer t> ? t : never;
149
- type Selector<T> = ObservableParam<T> | ObservableEvent | (() => T) | T;
152
+ type Selector<T> = ObservableParam<T> | ObservableEvent | (() => ObservableParam<T>) | (() => T) | T;
150
153
  type ClassConstructor<I, Args extends any[] = any[]> = new (...args: Args) => I;
151
154
  type ObservableListenerDispose = () => void;
152
155
  interface ObservableRoot {
153
156
  _: any;
154
157
  set?: (value: any) => void;
158
+ isLoadingLocal?: boolean;
155
159
  }
156
160
  type Primitive = boolean | string | number | Date;
157
161
  type NotPrimitive<T> = T extends Primitive ? never : T;
@@ -187,6 +191,7 @@ interface BaseNodeInfo {
187
191
  numListenersRecursive: number;
188
192
  state?: Observable<ObservableSyncState>;
189
193
  activated?: boolean;
194
+ isPlain?: boolean;
190
195
  recursivelyAutoActivated?: boolean;
191
196
  activationState?: LinkedOptions & {
192
197
  onError?: () => void;
@@ -246,12 +251,20 @@ interface UpdateFnParams<T = any> {
246
251
  value: T;
247
252
  mode?: GetMode;
248
253
  lastSync?: number | undefined;
254
+ changes?: Change[];
255
+ }
256
+ interface UpdateSetFnParams<T = any> extends UpdateFnParams<T> {
257
+ lastSync?: never;
249
258
  }
250
259
  type UpdateFn<T = any> = (params: UpdateFnParams<T>) => void;
260
+ type UpdateSetFn<T = any> = (params: UpdateSetFnParams<T>) => void;
251
261
  type Linked<T> = T;
252
262
  interface ObserveOptions {
253
263
  immediate?: boolean;
254
264
  }
265
+ interface ObservableSyncStateOptions {
266
+ resetLastSync?: boolean;
267
+ }
255
268
  interface ObservableSyncStateBase {
256
269
  isPersistLoaded: boolean;
257
270
  isPersistEnabled: boolean;
@@ -262,7 +275,7 @@ interface ObservableSyncStateBase {
262
275
  isSetting?: boolean;
263
276
  numPendingGets?: number;
264
277
  numPendingSets?: number;
265
- sync: () => Promise<void>;
278
+ sync: (options?: ObservableSyncStateOptions) => Promise<void>;
266
279
  getPendingChanges: () => Record<string, {
267
280
  p: any;
268
281
  v?: any;
@@ -288,12 +301,15 @@ interface RetryOptions {
288
301
  declare const ObservableHint: {
289
302
  opaque: <T extends object>(value: T) => OpaqueObject<T>;
290
303
  plain: <T extends object>(value: T) => PlainObject<T>;
304
+ function: <T extends object>(value: T) => PlainObject<T>;
291
305
  };
292
306
 
293
307
  declare function getProxy(node: NodeInfo, p?: string, asFunction?: Function): Observable;
294
308
  declare function set(node: NodeInfo, newValue?: any): void;
295
309
  declare function get(node: NodeInfo, options?: TrackingType | GetOptions): any;
296
310
  declare function peek(node: NodeInfo): any;
311
+ declare function deactivateNode(node: NodeInfo): void;
312
+ declare function reactivateNode(node: NodeInfo, lazyFn: Function): void;
297
313
  declare function isObserved(node: NodeInfo): boolean;
298
314
  declare function shouldIgnoreUnobserved(node: NodeInfo, refreshFn: () => void): true | undefined;
299
315
 
@@ -307,7 +323,7 @@ declare function computed<T, T2 = T>(get: (() => RecursiveValueOrFunction<T>) |
307
323
 
308
324
  declare function event(): ObservableEvent;
309
325
 
310
- declare function computeSelector<T>(selector: Selector<T>, e?: ObserveEvent<T>, retainObservable?: boolean): T;
326
+ declare function computeSelector<T>(selector: Selector<T>, getOptions?: GetOptions, e?: ObserveEvent<T>, retainObservable?: boolean): T;
311
327
  declare function getObservableIndex(value$: ObservableParam): number;
312
328
  declare function opaqueObject<T extends object>(value: T): OpaqueObject<T>;
313
329
  declare function getValueAtPath(obj: Record<string, any>, path: string[]): any;
@@ -357,7 +373,7 @@ declare function proxy<T>(get: (key: string) => T): Observable<Record<string, T>
357
373
 
358
374
  declare function syncState(obs: ObservableParam): Observable<ObservableSyncState>;
359
375
 
360
- declare function trackSelector<T>(selector: Selector<T>, update: (params: ListenerParams) => void, observeEvent?: ObserveEvent<T>, observeOptions?: ObserveOptions, createResubscribe?: boolean): {
376
+ declare function trackSelector<T>(selector: Selector<T>, update: (params: ListenerParams) => void, getOptions?: GetOptions, observeEvent?: ObserveEvent<T>, observeOptions?: ObserveOptions, createResubscribe?: boolean): {
361
377
  nodes: Map<NodeInfo, TrackingNode> | undefined;
362
378
  value: T;
363
379
  dispose: (() => void) | undefined;
@@ -381,13 +397,33 @@ interface ObservablePrimitiveState {
381
397
  }
382
398
  declare function ObservablePrimitiveClass<T>(this: ObservablePrimitive<T> & ObservablePrimitiveState, node: NodeInfo): void;
383
399
 
400
+ type MiddlewareEventType = 'listener-added' | 'listener-removed' | 'listeners-cleared';
401
+ interface MiddlewareEvent {
402
+ type: MiddlewareEventType;
403
+ node: NodeInfo;
404
+ listener?: NodeListener;
405
+ timestamp: number;
406
+ }
407
+ type MiddlewareHandler = (event: MiddlewareEvent) => void;
408
+ /**
409
+ * Register a middleware handler for a specific node and event type
410
+ * @param node The node to register the middleware handler for
411
+ * @param type The event type to handle
412
+ * @param handler The middleware handler function
413
+ * @returns A function to remove the handler
414
+ */
415
+ declare function registerMiddleware(node: NodeInfo, type: MiddlewareEventType, handler: MiddlewareHandler): () => void;
416
+
384
417
  declare const internal: {
385
418
  createPreviousHandler: typeof createPreviousHandler;
386
419
  clone: typeof clone;
420
+ deactivateNode: typeof deactivateNode;
387
421
  deepMerge: typeof deepMerge;
388
422
  ensureNodeValue: typeof ensureNodeValue;
389
423
  findIDKey: typeof findIDKey;
390
424
  get: typeof get;
425
+ getChildNode: typeof getChildNode;
426
+ getKeys: typeof getKeys;
391
427
  getNode: typeof getNode;
392
428
  getNodeValue: typeof getNodeValue;
393
429
  getPathType: typeof getPathType;
@@ -414,6 +450,8 @@ declare const internal: {
414
450
  observableFns: Map<string, (node: NodeInfo, ...args: any[]) => any>;
415
451
  optimized: symbol;
416
452
  peek: typeof peek;
453
+ reactivateNode: typeof reactivateNode;
454
+ registerMiddleware: typeof registerMiddleware;
417
455
  safeParse: typeof safeParse;
418
456
  safeStringify: typeof safeStringify;
419
457
  set: typeof set;
@@ -426,4 +464,4 @@ declare const internal: {
426
464
  };
427
465
  };
428
466
 
429
- export { type ArrayValue, type Change, type ChildNodeInfo, type ClassConstructor, type GetMode, type GetOptions, type ImmutableObservableBase, type Linked, type LinkedOptions, type ListenerFn, type ListenerParams, type NodeInfo, type NodeListener, type NotPrimitive, type Observable, type ObservableBoolean, type ObservableEvent, ObservableHint, type ObservableListenerDispose, type ObservableMap, type ObservableObject, type ObservableObjectFns, type ObservableParam, type ObservablePrimitive, type ObservableRoot, type ObservableState, type ObservableSyncState, type ObservableSyncStateBase, type ObservableValue, type ObserveEvent, type ObserveEventCallback, type ObserveOptions, type OpaqueObject, type PlainObject, type Primitive, type RecordValue, type RecursiveValueOrFunction, type RemoveObservables, type RetryOptions, type RootNodeInfo, type Selector, type SetParams, type TrackingNode, type TrackingState, type TrackingType, type TypeAtPath, type UpdateFn, type UpdateFnParams, type WaitForSet, type WaitForSetFnParams, applyChange, applyChanges, batch, beginBatch, computeSelector, computed, constructObjectWithPath, deconstructObjectWithPath, endBatch, event, getObservableIndex, hasOwnProperty, internal, isArray, isBoolean, isDate, isEmpty, isFunction, isMap, isNullOrUndefined, isNumber, isObject, isObservable, isObservableValueReady, isObserved, isPlainObject, isPrimitive, isPromise, isSet, isString, isSymbol, linked, mergeIntoObservable, observable, observablePrimitive, observe, opaqueObject, proxy, setAtPath, setSilently, shouldIgnoreUnobserved, syncState, trackSelector, when, whenReady };
467
+ export { type ArrayValue, type Change, type ChildNodeInfo, type ClassConstructor, type GetMode, type GetOptions, type ImmutableObservableBase, type Linked, type LinkedOptions, type ListenerFn, type ListenerParams, type NodeInfo, type NodeListener, type NotPrimitive, type Observable, type ObservableBoolean, type ObservableEvent, ObservableHint, type ObservableListenerDispose, type ObservableMap, type ObservableObject, type ObservableObjectFns, type ObservableParam, type ObservablePrimitive, type ObservableRoot, type ObservableState, type ObservableSyncState, type ObservableSyncStateBase, type ObservableSyncStateOptions, type ObservableValue, type ObserveEvent, type ObserveEventCallback, type ObserveOptions, type OpaqueObject, type PlainObject, type Primitive, type RecordValue, type RecursiveValueOrFunction, type RemoveObservables, type RetryOptions, type RootNodeInfo, type Selector, type SetParams, type TrackingNode, type TrackingState, type TrackingType, type TypeAtPath, type UpdateFn, type UpdateFnParams, type UpdateSetFn, type UpdateSetFnParams, type WaitForSet, type WaitForSetFnParams, applyChange, applyChanges, batch, beginBatch, computeSelector, computed, constructObjectWithPath, deconstructObjectWithPath, endBatch, event, getObservableIndex, hasOwnProperty, internal, isArray, isBoolean, isDate, isEmpty, isFunction, isMap, isNullOrUndefined, isNumber, isObject, isObservable, isObservableValueReady, isObserved, isPlainObject, isPrimitive, isPromise, isSet, isString, isSymbol, linked, mergeIntoObservable, observable, observablePrimitive, observe, opaqueObject, proxy, setAtPath, setSilently, shouldIgnoreUnobserved, syncState, trackSelector, when, whenReady };
package/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- type Primitive$1 = string | number | boolean | symbol | bigint | undefined | null | Date;
1
+ type Primitive$1 = string | number | boolean | symbol | bigint | undefined | null | Date | OpaqueObject<unknown>;
2
2
  type ArrayOverrideFnNames = 'find' | 'findIndex' | 'every' | 'some' | 'filter' | 'reduce' | 'reduceRight' | 'forEach' | 'map' | 'sort';
3
3
  type RemoveIndex<T> = {
4
4
  [K in keyof T as string extends K ? never : number extends K ? never : K]: T[K];
@@ -7,7 +7,7 @@ type BuiltIns = String | Boolean | Number | Date | Error | RegExp | Array<any> |
7
7
  type IsUserDefinedObject<T> = T extends Function | BuiltIns | any[] ? false : T extends object ? true : false;
8
8
  type RemoveObservables<T> = T extends ImmutableObservableBase<infer t> ? t : T extends ImmutableObservableBase<infer t>[] ? t[] : IsUserDefinedObject<T> extends true ? {
9
9
  [K in keyof T]: RemoveObservables<T[K]>;
10
- } : T extends ImmutableObservableBase<infer TObs> ? TObs : T extends () => infer TRet ? RemoveObservables<TRet> & T : T extends (key: infer TKey extends string | number) => infer TRet ? Record<TKey, RemoveObservables<TRet>> & T : T;
10
+ } : T extends ImmutableObservableBase<infer TObs> ? TObs : T extends () => infer TRet ? RemoveObservables<TRet> & T : T extends (key: infer TKey extends string | number) => infer TRet ? Record<TKey, RemoveObservables<TRet>> & T : T extends OpaqueObject<infer TObj> ? TObj : T;
11
11
  interface ObservableArray<T, U> extends ObservablePrimitive<T>, Pick<Array<Observable<U>>, ArrayOverrideFnNames>, Omit<RemoveIndex<Array<U>>, ArrayOverrideFnNames> {
12
12
  }
13
13
  interface ObservableObjectFns<T> {
@@ -108,14 +108,17 @@ declare function getNode(value$: ObservableParam): NodeInfo;
108
108
  declare function setNodeValue(node: NodeInfo, newValue: any): {
109
109
  prevValue: any;
110
110
  newValue: any;
111
+ parentValue: any;
111
112
  };
112
113
  declare function getNodeValue(node: NodeInfo): any;
114
+ declare function getChildNode(node: NodeInfo, key: string, asFunction?: Function): NodeInfo;
113
115
  declare function ensureNodeValue(node: NodeInfo): any;
114
116
  declare function findIDKey(obj: unknown | undefined, node: NodeInfo): string | ((value: any) => string) | undefined;
117
+ declare function getKeys(obj: Record<any, any> | Array<any> | undefined, isArr: boolean, isMap: boolean, isSet: boolean): string[];
115
118
 
116
119
  type TrackingType = undefined | true | symbol;
117
120
  interface GetOptions {
118
- shallow: boolean;
121
+ shallow?: boolean;
119
122
  }
120
123
  type OpaqueObject<T> = T & {
121
124
  [symbolOpaque]: true;
@@ -146,12 +149,13 @@ interface Change {
146
149
  type RecordValue<T> = T extends Record<string, infer t> ? t : never;
147
150
  type ArrayValue<T> = T extends Array<infer t> ? t : never;
148
151
  type ObservableValue<T> = T extends Observable<infer t> ? t : never;
149
- type Selector<T> = ObservableParam<T> | ObservableEvent | (() => T) | T;
152
+ type Selector<T> = ObservableParam<T> | ObservableEvent | (() => ObservableParam<T>) | (() => T) | T;
150
153
  type ClassConstructor<I, Args extends any[] = any[]> = new (...args: Args) => I;
151
154
  type ObservableListenerDispose = () => void;
152
155
  interface ObservableRoot {
153
156
  _: any;
154
157
  set?: (value: any) => void;
158
+ isLoadingLocal?: boolean;
155
159
  }
156
160
  type Primitive = boolean | string | number | Date;
157
161
  type NotPrimitive<T> = T extends Primitive ? never : T;
@@ -187,6 +191,7 @@ interface BaseNodeInfo {
187
191
  numListenersRecursive: number;
188
192
  state?: Observable<ObservableSyncState>;
189
193
  activated?: boolean;
194
+ isPlain?: boolean;
190
195
  recursivelyAutoActivated?: boolean;
191
196
  activationState?: LinkedOptions & {
192
197
  onError?: () => void;
@@ -246,12 +251,20 @@ interface UpdateFnParams<T = any> {
246
251
  value: T;
247
252
  mode?: GetMode;
248
253
  lastSync?: number | undefined;
254
+ changes?: Change[];
255
+ }
256
+ interface UpdateSetFnParams<T = any> extends UpdateFnParams<T> {
257
+ lastSync?: never;
249
258
  }
250
259
  type UpdateFn<T = any> = (params: UpdateFnParams<T>) => void;
260
+ type UpdateSetFn<T = any> = (params: UpdateSetFnParams<T>) => void;
251
261
  type Linked<T> = T;
252
262
  interface ObserveOptions {
253
263
  immediate?: boolean;
254
264
  }
265
+ interface ObservableSyncStateOptions {
266
+ resetLastSync?: boolean;
267
+ }
255
268
  interface ObservableSyncStateBase {
256
269
  isPersistLoaded: boolean;
257
270
  isPersistEnabled: boolean;
@@ -262,7 +275,7 @@ interface ObservableSyncStateBase {
262
275
  isSetting?: boolean;
263
276
  numPendingGets?: number;
264
277
  numPendingSets?: number;
265
- sync: () => Promise<void>;
278
+ sync: (options?: ObservableSyncStateOptions) => Promise<void>;
266
279
  getPendingChanges: () => Record<string, {
267
280
  p: any;
268
281
  v?: any;
@@ -288,12 +301,15 @@ interface RetryOptions {
288
301
  declare const ObservableHint: {
289
302
  opaque: <T extends object>(value: T) => OpaqueObject<T>;
290
303
  plain: <T extends object>(value: T) => PlainObject<T>;
304
+ function: <T extends object>(value: T) => PlainObject<T>;
291
305
  };
292
306
 
293
307
  declare function getProxy(node: NodeInfo, p?: string, asFunction?: Function): Observable;
294
308
  declare function set(node: NodeInfo, newValue?: any): void;
295
309
  declare function get(node: NodeInfo, options?: TrackingType | GetOptions): any;
296
310
  declare function peek(node: NodeInfo): any;
311
+ declare function deactivateNode(node: NodeInfo): void;
312
+ declare function reactivateNode(node: NodeInfo, lazyFn: Function): void;
297
313
  declare function isObserved(node: NodeInfo): boolean;
298
314
  declare function shouldIgnoreUnobserved(node: NodeInfo, refreshFn: () => void): true | undefined;
299
315
 
@@ -307,7 +323,7 @@ declare function computed<T, T2 = T>(get: (() => RecursiveValueOrFunction<T>) |
307
323
 
308
324
  declare function event(): ObservableEvent;
309
325
 
310
- declare function computeSelector<T>(selector: Selector<T>, e?: ObserveEvent<T>, retainObservable?: boolean): T;
326
+ declare function computeSelector<T>(selector: Selector<T>, getOptions?: GetOptions, e?: ObserveEvent<T>, retainObservable?: boolean): T;
311
327
  declare function getObservableIndex(value$: ObservableParam): number;
312
328
  declare function opaqueObject<T extends object>(value: T): OpaqueObject<T>;
313
329
  declare function getValueAtPath(obj: Record<string, any>, path: string[]): any;
@@ -357,7 +373,7 @@ declare function proxy<T>(get: (key: string) => T): Observable<Record<string, T>
357
373
 
358
374
  declare function syncState(obs: ObservableParam): Observable<ObservableSyncState>;
359
375
 
360
- declare function trackSelector<T>(selector: Selector<T>, update: (params: ListenerParams) => void, observeEvent?: ObserveEvent<T>, observeOptions?: ObserveOptions, createResubscribe?: boolean): {
376
+ declare function trackSelector<T>(selector: Selector<T>, update: (params: ListenerParams) => void, getOptions?: GetOptions, observeEvent?: ObserveEvent<T>, observeOptions?: ObserveOptions, createResubscribe?: boolean): {
361
377
  nodes: Map<NodeInfo, TrackingNode> | undefined;
362
378
  value: T;
363
379
  dispose: (() => void) | undefined;
@@ -381,13 +397,33 @@ interface ObservablePrimitiveState {
381
397
  }
382
398
  declare function ObservablePrimitiveClass<T>(this: ObservablePrimitive<T> & ObservablePrimitiveState, node: NodeInfo): void;
383
399
 
400
+ type MiddlewareEventType = 'listener-added' | 'listener-removed' | 'listeners-cleared';
401
+ interface MiddlewareEvent {
402
+ type: MiddlewareEventType;
403
+ node: NodeInfo;
404
+ listener?: NodeListener;
405
+ timestamp: number;
406
+ }
407
+ type MiddlewareHandler = (event: MiddlewareEvent) => void;
408
+ /**
409
+ * Register a middleware handler for a specific node and event type
410
+ * @param node The node to register the middleware handler for
411
+ * @param type The event type to handle
412
+ * @param handler The middleware handler function
413
+ * @returns A function to remove the handler
414
+ */
415
+ declare function registerMiddleware(node: NodeInfo, type: MiddlewareEventType, handler: MiddlewareHandler): () => void;
416
+
384
417
  declare const internal: {
385
418
  createPreviousHandler: typeof createPreviousHandler;
386
419
  clone: typeof clone;
420
+ deactivateNode: typeof deactivateNode;
387
421
  deepMerge: typeof deepMerge;
388
422
  ensureNodeValue: typeof ensureNodeValue;
389
423
  findIDKey: typeof findIDKey;
390
424
  get: typeof get;
425
+ getChildNode: typeof getChildNode;
426
+ getKeys: typeof getKeys;
391
427
  getNode: typeof getNode;
392
428
  getNodeValue: typeof getNodeValue;
393
429
  getPathType: typeof getPathType;
@@ -414,6 +450,8 @@ declare const internal: {
414
450
  observableFns: Map<string, (node: NodeInfo, ...args: any[]) => any>;
415
451
  optimized: symbol;
416
452
  peek: typeof peek;
453
+ reactivateNode: typeof reactivateNode;
454
+ registerMiddleware: typeof registerMiddleware;
417
455
  safeParse: typeof safeParse;
418
456
  safeStringify: typeof safeStringify;
419
457
  set: typeof set;
@@ -426,4 +464,4 @@ declare const internal: {
426
464
  };
427
465
  };
428
466
 
429
- export { type ArrayValue, type Change, type ChildNodeInfo, type ClassConstructor, type GetMode, type GetOptions, type ImmutableObservableBase, type Linked, type LinkedOptions, type ListenerFn, type ListenerParams, type NodeInfo, type NodeListener, type NotPrimitive, type Observable, type ObservableBoolean, type ObservableEvent, ObservableHint, type ObservableListenerDispose, type ObservableMap, type ObservableObject, type ObservableObjectFns, type ObservableParam, type ObservablePrimitive, type ObservableRoot, type ObservableState, type ObservableSyncState, type ObservableSyncStateBase, type ObservableValue, type ObserveEvent, type ObserveEventCallback, type ObserveOptions, type OpaqueObject, type PlainObject, type Primitive, type RecordValue, type RecursiveValueOrFunction, type RemoveObservables, type RetryOptions, type RootNodeInfo, type Selector, type SetParams, type TrackingNode, type TrackingState, type TrackingType, type TypeAtPath, type UpdateFn, type UpdateFnParams, type WaitForSet, type WaitForSetFnParams, applyChange, applyChanges, batch, beginBatch, computeSelector, computed, constructObjectWithPath, deconstructObjectWithPath, endBatch, event, getObservableIndex, hasOwnProperty, internal, isArray, isBoolean, isDate, isEmpty, isFunction, isMap, isNullOrUndefined, isNumber, isObject, isObservable, isObservableValueReady, isObserved, isPlainObject, isPrimitive, isPromise, isSet, isString, isSymbol, linked, mergeIntoObservable, observable, observablePrimitive, observe, opaqueObject, proxy, setAtPath, setSilently, shouldIgnoreUnobserved, syncState, trackSelector, when, whenReady };
467
+ export { type ArrayValue, type Change, type ChildNodeInfo, type ClassConstructor, type GetMode, type GetOptions, type ImmutableObservableBase, type Linked, type LinkedOptions, type ListenerFn, type ListenerParams, type NodeInfo, type NodeListener, type NotPrimitive, type Observable, type ObservableBoolean, type ObservableEvent, ObservableHint, type ObservableListenerDispose, type ObservableMap, type ObservableObject, type ObservableObjectFns, type ObservableParam, type ObservablePrimitive, type ObservableRoot, type ObservableState, type ObservableSyncState, type ObservableSyncStateBase, type ObservableSyncStateOptions, type ObservableValue, type ObserveEvent, type ObserveEventCallback, type ObserveOptions, type OpaqueObject, type PlainObject, type Primitive, type RecordValue, type RecursiveValueOrFunction, type RemoveObservables, type RetryOptions, type RootNodeInfo, type Selector, type SetParams, type TrackingNode, type TrackingState, type TrackingType, type TypeAtPath, type UpdateFn, type UpdateFnParams, type UpdateSetFn, type UpdateSetFnParams, type WaitForSet, type WaitForSetFnParams, applyChange, applyChanges, batch, beginBatch, computeSelector, computed, constructObjectWithPath, deconstructObjectWithPath, endBatch, event, getObservableIndex, hasOwnProperty, internal, isArray, isBoolean, isDate, isEmpty, isFunction, isMap, isNullOrUndefined, isNumber, isObject, isObservable, isObservableValueReady, isObserved, isPlainObject, isPrimitive, isPromise, isSet, isString, isSymbol, linked, mergeIntoObservable, observable, observablePrimitive, observe, opaqueObject, proxy, setAtPath, setSilently, shouldIgnoreUnobserved, syncState, trackSelector, when, whenReady };