@legendapp/state 2.2.0-next.65 → 2.2.0-next.67

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 (65) hide show
  1. package/index.js +29 -15
  2. package/index.js.map +1 -1
  3. package/index.mjs +29 -15
  4. package/index.mjs.map +1 -1
  5. package/package.json +21 -21
  6. package/{cache-plugins → persist-plugins}/async-storage.d.ts +3 -3
  7. package/{cache-plugins → persist-plugins}/async-storage.js +4 -4
  8. package/persist-plugins/async-storage.js.map +1 -0
  9. package/{cache-plugins → persist-plugins}/async-storage.mjs +4 -4
  10. package/persist-plugins/async-storage.mjs.map +1 -0
  11. package/persist-plugins/firebase.js.map +1 -1
  12. package/persist-plugins/firebase.mjs.map +1 -1
  13. package/persist-plugins/indexeddb.d.ts +25 -0
  14. package/{cache-plugins → persist-plugins}/indexeddb.js +2 -2
  15. package/persist-plugins/indexeddb.js.map +1 -0
  16. package/{cache-plugins → persist-plugins}/indexeddb.mjs +2 -2
  17. package/persist-plugins/indexeddb.mjs.map +1 -0
  18. package/persist-plugins/local-storage.d.ts +20 -0
  19. package/{cache-plugins → persist-plugins}/local-storage.js +10 -10
  20. package/persist-plugins/local-storage.js.map +1 -0
  21. package/{cache-plugins → persist-plugins}/local-storage.mjs +8 -8
  22. package/persist-plugins/local-storage.mjs.map +1 -0
  23. package/persist-plugins/mmkv.d.ts +14 -0
  24. package/{cache-plugins → persist-plugins}/mmkv.js +3 -3
  25. package/persist-plugins/mmkv.js.map +1 -0
  26. package/{cache-plugins → persist-plugins}/mmkv.mjs +3 -3
  27. package/persist-plugins/mmkv.mjs.map +1 -0
  28. package/persist.js +56 -53
  29. package/persist.js.map +1 -1
  30. package/persist.mjs +56 -53
  31. package/persist.mjs.map +1 -1
  32. package/react-hooks/usePersistedObservable.d.ts +2 -2
  33. package/src/helpers.ts +28 -14
  34. package/src/observableInterfaces.ts +2 -3
  35. package/src/persist/persistObservable.ts +24 -20
  36. package/src/{cache-plugins → persist-plugins}/async-storage.ts +6 -6
  37. package/src/persist-plugins/firebase.ts +3 -3
  38. package/src/{cache-plugins → persist-plugins}/indexeddb.ts +17 -17
  39. package/src/{cache-plugins → persist-plugins}/local-storage.ts +8 -8
  40. package/src/{cache-plugins → persist-plugins}/mmkv.ts +13 -13
  41. package/src/persistTypes.ts +15 -22
  42. package/src/react-hooks/usePersistedObservable.ts +2 -2
  43. package/src/sync/syncObservable.ts +93 -84
  44. package/src/sync/syncObservableAdapter.ts +2 -2
  45. package/src/sync/synced.ts +2 -2
  46. package/src/sync-plugins/fetch.ts +3 -3
  47. package/src/syncTypes.ts +19 -20
  48. package/sync-plugins/fetch.d.ts +2 -2
  49. package/sync-plugins/fetch.js.map +1 -1
  50. package/sync-plugins/fetch.mjs.map +1 -1
  51. package/sync.js +56 -53
  52. package/sync.js.map +1 -1
  53. package/sync.mjs +56 -53
  54. package/sync.mjs.map +1 -1
  55. package/cache-plugins/async-storage.js.map +0 -1
  56. package/cache-plugins/async-storage.mjs.map +0 -1
  57. package/cache-plugins/indexeddb.d.ts +0 -25
  58. package/cache-plugins/indexeddb.js.map +0 -1
  59. package/cache-plugins/indexeddb.mjs.map +0 -1
  60. package/cache-plugins/local-storage.d.ts +0 -20
  61. package/cache-plugins/local-storage.js.map +0 -1
  62. package/cache-plugins/local-storage.mjs.map +0 -1
  63. package/cache-plugins/mmkv.d.ts +0 -14
  64. package/cache-plugins/mmkv.js.map +0 -1
  65. package/cache-plugins/mmkv.mjs.map +0 -1
package/src/helpers.ts CHANGED
@@ -41,37 +41,49 @@ export function setAtPath<T extends object>(
41
41
  path: string[],
42
42
  pathTypes: TypeAtPath[],
43
43
  value: any,
44
+ mode?: 'set' | 'merge',
44
45
  fullObj?: T,
45
46
  restore?: (path: string[], value: any) => void,
46
47
  ) {
47
48
  let o: Record<string, any> = obj;
48
49
  let oFull: Record<string, any> | undefined = fullObj;
50
+ let p: string | undefined = undefined;
49
51
  if (path.length > 0) {
50
52
  for (let i = 0; i < path.length; i++) {
51
- const p = path[i];
52
- if (i === path.length - 1) {
53
- // Don't set if the value is the same. This prevents creating a new key
54
- // when setting undefined on an object without this key
55
- if (o[p] !== value) {
56
- o[p] = value;
57
- }
58
- } else if (o[p] === symbolDelete) {
53
+ p = path[i];
54
+ if (o[p] === symbolDelete) {
59
55
  // If this was previously deleted, restore it
60
56
  if (oFull) {
61
57
  o[p] = oFull[p];
62
58
  restore?.(path.slice(0, i + 1), o[p]);
63
59
  }
64
- break;
60
+ return obj;
65
61
  } else if (o[p] === undefined || o[p] === null) {
66
62
  o[p] = initializePathType(pathTypes[i]);
67
63
  }
68
- o = o[p];
69
- if (oFull) {
70
- oFull = oFull[p];
64
+ if (i < path.length - 1) {
65
+ o = o[p];
66
+ if (oFull) {
67
+ oFull = oFull[p];
68
+ }
71
69
  }
72
70
  }
71
+ }
72
+
73
+ // Don't set if the value is the same. This prevents creating a new key
74
+ // when setting undefined on an object without this key
75
+ if (p === undefined) {
76
+ if (mode === 'merge') {
77
+ obj = _mergeIntoObservable(obj, value);
78
+ } else {
79
+ obj = value;
80
+ }
73
81
  } else {
74
- obj = value;
82
+ if (mode === 'merge') {
83
+ o[p] = _mergeIntoObservable(o[p], value);
84
+ } else {
85
+ o[p] = value;
86
+ }
75
87
  }
76
88
 
77
89
  return obj;
@@ -81,7 +93,7 @@ export function setInObservableAtPath(
81
93
  path: string[],
82
94
  pathTypes: TypeAtPath[],
83
95
  value: any,
84
- mode: 'assign' | 'set',
96
+ mode: 'assign' | 'set' | 'merge',
85
97
  ) {
86
98
  let o: Record<string, any> = obs;
87
99
  let v = value;
@@ -100,6 +112,8 @@ export function setInObservableAtPath(
100
112
  // Assign if possible, or set otherwise
101
113
  else if (mode === 'assign' && (o as Observable).assign && isObject(o.peek())) {
102
114
  (o as Observable<{}>).assign(v);
115
+ } else if (mode === 'merge') {
116
+ mergeIntoObservable(o, v);
103
117
  } else {
104
118
  o.set(v);
105
119
  }
@@ -1,6 +1,6 @@
1
1
  import type { symbolOpaque } from './globals';
2
2
  import type { Observable, ObservableParam } from './observableTypes';
3
- import { GetMode, ObservableSyncState, SyncedParams } from './syncTypes';
3
+ import { GetMode, ObservableSyncState, SyncedOptions } from './syncTypes';
4
4
 
5
5
  export type TrackingType = undefined | true | symbol; // true === shallow
6
6
 
@@ -67,7 +67,6 @@ export interface TrackingState {
67
67
  interface BaseNodeValue {
68
68
  children?: Map<string, ChildNodeValue>;
69
69
  proxy?: object;
70
- // TODOV3 Remove this
71
70
  root: ObservableRoot;
72
71
  listeners?: Set<NodeValueListener>;
73
72
  listenersImmediate?: Set<NodeValueListener>;
@@ -86,7 +85,7 @@ interface BaseNodeValue {
86
85
  needsExtract?: boolean;
87
86
  state?: Observable<ObservableSyncState>;
88
87
  activated?: boolean;
89
- activationState?: SyncedParams & { onError?: () => void; persistedRetry?: boolean };
88
+ activationState?: SyncedOptions & { onError?: () => void; persistedRetry?: boolean };
90
89
  dirtyFn?: () => void;
91
90
  }
92
91
 
@@ -12,9 +12,9 @@ import type {
12
12
  ObservablePersistRemoteFunctions,
13
13
  ObservablePersistState,
14
14
  PersistMetadata,
15
- PersistOptions,
16
- PersistOptionsLocal,
17
- PersistOptionsRemote,
15
+ LegacyPersistOptions,
16
+ LegacyPersistOptionsLocal,
17
+ LegacyPersistOptionsRemote,
18
18
  PersistTransform,
19
19
  TypeAtPath,
20
20
  } from '@legendapp/state';
@@ -77,15 +77,15 @@ interface PreppedChangeRemote {
77
77
 
78
78
  type ChangeWithPathStr = Change & { pathStr: string };
79
79
 
80
- function parseLocalConfig(config: string | PersistOptionsLocal | undefined): {
80
+ function parseLocalConfig(config: string | LegacyPersistOptionsLocal | undefined): {
81
81
  table: string;
82
- config: PersistOptionsLocal;
82
+ config: LegacyPersistOptionsLocal;
83
83
  } {
84
84
  return config
85
85
  ? isString(config)
86
86
  ? { table: config, config: { name: config } }
87
87
  : { table: config.name, config }
88
- : ({} as { table: string; config: PersistOptionsLocal });
88
+ : ({} as { table: string; config: LegacyPersistOptionsLocal });
89
89
  }
90
90
 
91
91
  function doInOrder<T>(arg1: T | Promise<T>, arg2: (value: T) => void): any {
@@ -155,7 +155,7 @@ async function updateMetadataImmediate<T>(
155
155
  obs: ObservableParam<any>,
156
156
  localState: LocalState,
157
157
  syncState: Observable<ObservablePersistState>,
158
- persistOptions: PersistOptions<T>,
158
+ persistOptions: LegacyPersistOptions<T>,
159
159
  newMetadata: PersistMetadata,
160
160
  ) {
161
161
  const saves = Array.from(promisesLocalSaves);
@@ -194,14 +194,15 @@ function updateMetadata<T>(
194
194
  obs: ObservableParam<any>,
195
195
  localState: LocalState,
196
196
  syncState: ObservableObject<ObservablePersistState>,
197
- persistOptions: PersistOptions<T>,
197
+ persistOptions: LegacyPersistOptions<T>,
198
198
  newMetadata: PersistMetadata,
199
199
  ) {
200
200
  if (localState.timeoutSaveMetadata) {
201
201
  clearTimeout(localState.timeoutSaveMetadata);
202
202
  }
203
203
  localState.timeoutSaveMetadata = setTimeout(
204
- () => updateMetadataImmediate(obs, localState, syncState, persistOptions as PersistOptions<T>, newMetadata),
204
+ () =>
205
+ updateMetadataImmediate(obs, localState, syncState, persistOptions as LegacyPersistOptions<T>, newMetadata),
205
206
  persistOptions?.remote?.metadataTimeout || 0,
206
207
  );
207
208
  }
@@ -212,7 +213,7 @@ interface QueuedChange<T = any> {
212
213
  obs: Observable<T>;
213
214
  syncState: ObservableObject<ObservablePersistState>;
214
215
  localState: LocalState;
215
- persistOptions: PersistOptions<T>;
216
+ persistOptions: LegacyPersistOptions<T>;
216
217
  changes: ListenerParams['changes'];
217
218
  }
218
219
 
@@ -566,7 +567,7 @@ async function doChangeRemote(changeInfo: PreppedChangeRemote | undefined) {
566
567
  const local = persistOptions.local;
567
568
  const { table, config: configLocal } = parseLocalConfig(local!);
568
569
  const { offlineBehavior, allowSetIfError, onBeforeSet, onSetError, waitForSet, onAfterSet } =
569
- persistOptions.remote || ({} as PersistOptionsRemote);
570
+ persistOptions.remote || ({} as LegacyPersistOptionsRemote);
570
571
  const shouldSaveMetadata = local && offlineBehavior === 'retry';
571
572
 
572
573
  if (changesRemote.length > 0) {
@@ -668,7 +669,7 @@ function onObsChange<T>(
668
669
  obs: Observable<T>,
669
670
  syncState: ObservableObject<ObservablePersistState>,
670
671
  localState: LocalState,
671
- persistOptions: PersistOptions<T>,
672
+ persistOptions: LegacyPersistOptions<T>,
672
673
  { changes, loading, remote }: ListenerParams,
673
674
  ) {
674
675
  if (!loading) {
@@ -692,7 +693,7 @@ function onObsChange<T>(
692
693
 
693
694
  async function loadLocal<T>(
694
695
  obs: ObservableParam<T>,
695
- persistOptions: PersistOptions<any>,
696
+ persistOptions: LegacyPersistOptions<any>,
696
697
  syncState: ObservableObject<ObservablePersistState>,
697
698
  localState: LocalState,
698
699
  ) {
@@ -796,14 +797,17 @@ async function loadLocal<T>(
796
797
  syncState.isLoadedLocal.set(true);
797
798
  }
798
799
 
799
- export function persistObservable<T>(observable: ObservableParam<T>, persistOptions: PersistOptions<T>): Observable<T>;
800
+ export function persistObservable<T>(
801
+ observable: ObservableParam<T>,
802
+ persistOptions: LegacyPersistOptions<T>,
803
+ ): Observable<T>;
800
804
  export function persistObservable<T>(
801
805
  initial: T | (() => T) | (() => Promise<T>),
802
- persistOptions: PersistOptions<T>,
806
+ persistOptions: LegacyPersistOptions<T>,
803
807
  ): Observable<T>;
804
808
  export function persistObservable<T>(
805
809
  initialOrObservable: ObservableParam<T> | T | (() => T) | (() => Promise<T>),
806
- persistOptions: PersistOptions<T>,
810
+ persistOptions: LegacyPersistOptions<T>,
807
811
  ): Observable<T> {
808
812
  const obs$ = (
809
813
  isObservable(initialOrObservable)
@@ -820,7 +824,7 @@ export function persistObservable<T>(
820
824
  removeNullUndefined(persistOptions.remote),
821
825
  );
822
826
  }
823
- let { remote } = persistOptions as { remote: PersistOptionsRemote<T> };
827
+ let { remote } = persistOptions as { remote: LegacyPersistOptionsRemote<T> };
824
828
  const { local } = persistOptions;
825
829
  const remotePersistence = persistOptions.pluginRemote! || observablePersistConfiguration?.pluginRemote;
826
830
  const localState: LocalState = {};
@@ -871,7 +875,7 @@ export function persistObservable<T>(
871
875
  get({
872
876
  state: syncState,
873
877
  obs: obs$,
874
- options: persistOptions as PersistOptions<any>,
878
+ options: persistOptions as LegacyPersistOptions<any>,
875
879
  lastSync,
876
880
  dateModified: lastSync,
877
881
  onError: (error: Error) => {
@@ -945,7 +949,7 @@ export function persistObservable<T>(
945
949
  }
946
950
  }
947
951
  if (lastSync && local) {
948
- updateMetadata(obs$, localState, syncState, persistOptions as PersistOptions<T>, {
952
+ updateMetadata(obs$, localState, syncState, persistOptions as LegacyPersistOptions<T>, {
949
953
  lastSync,
950
954
  });
951
955
  }
@@ -1014,7 +1018,7 @@ export function persistObservable<T>(
1014
1018
  }
1015
1019
 
1016
1020
  obs$.onChange(
1017
- onObsChange.bind(this, obs$ as any, syncState, localState, persistOptions as PersistOptions<any>),
1021
+ onObsChange.bind(this, obs$ as any, syncState, localState, persistOptions as LegacyPersistOptions<any>),
1018
1022
  );
1019
1023
  });
1020
1024
 
@@ -1,10 +1,10 @@
1
1
  import type {
2
2
  Change,
3
- ObservablePersistLocal,
3
+ ObservablePersistPlugin,
4
4
  ObservablePersistenceConfigLocalGlobalOptions,
5
5
  PersistMetadata,
6
6
  } from '@legendapp/state';
7
- import { isArray, setAtPath, internal } from '@legendapp/state';
7
+ import { internal, isArray, setAtPath } from '@legendapp/state';
8
8
  import type { AsyncStorageStatic } from '@react-native-async-storage/async-storage';
9
9
 
10
10
  const MetadataSuffix = '__m';
@@ -13,7 +13,7 @@ let AsyncStorage: AsyncStorageStatic;
13
13
 
14
14
  const { safeParse, safeStringify } = internal;
15
15
 
16
- export class ObservablePersistAsyncStorage implements ObservablePersistLocal {
16
+ export class ObservablePersistAsyncStorage implements ObservablePersistPlugin {
17
17
  private data: Record<string, any> = {};
18
18
 
19
19
  // Init
@@ -58,11 +58,11 @@ export class ObservablePersistAsyncStorage implements ObservablePersistLocal {
58
58
  }
59
59
  }
60
60
  // Gets
61
- public getTable(table: string) {
62
- return this.data[table] ?? {};
61
+ public getTable(table: string, init: object) {
62
+ return this.data[table] ?? init ?? {};
63
63
  }
64
64
  public getMetadata(table: string): PersistMetadata {
65
- return this.getTable(table + MetadataSuffix);
65
+ return this.getTable(table + MetadataSuffix, {});
66
66
  }
67
67
  // Sets
68
68
  public set(table: string, changes: Change[]): Promise<void> {
@@ -5,7 +5,7 @@ import {
5
5
  ObservablePersistRemoteSetParams,
6
6
  ObservablePrimitive,
7
7
  ObservableParam,
8
- PersistOptions,
8
+ LegacyPersistOptions,
9
9
  QueryByModified,
10
10
  TypeAtPath,
11
11
  batch,
@@ -82,7 +82,7 @@ type SaveInfoDictionary<T = any> = {
82
82
  };
83
83
 
84
84
  interface PendingSaves {
85
- options: PersistOptions;
85
+ options: LegacyPersistOptions;
86
86
  saves: SaveInfoDictionary;
87
87
  }
88
88
 
@@ -564,7 +564,7 @@ class ObservablePersistFirebaseBase implements ObservablePersistRemoteClass {
564
564
  return {};
565
565
  }
566
566
  private _constructBatch(
567
- options: PersistOptions,
567
+ options: LegacyPersistOptions,
568
568
  batch: Record<string, string | object>,
569
569
  basePath: string,
570
570
  saves: SaveInfoDictionary,
@@ -1,10 +1,10 @@
1
1
  import type {
2
2
  Change,
3
3
  Observable,
4
- ObservableCachePluginOptions,
5
- ObservablePersistLocal,
4
+ ObservablePersistPluginOptions,
5
+ ObservablePersistPlugin,
6
6
  PersistMetadata,
7
- PersistOptionsLocal,
7
+ PersistOptions,
8
8
  } from '@legendapp/state';
9
9
  import { isPrimitive, isPromise, observable, setAtPath, when } from '@legendapp/state';
10
10
 
@@ -14,14 +14,14 @@ function requestToPromise(request: IDBRequest) {
14
14
  return new Promise<void>((resolve) => (request.onsuccess = () => resolve()));
15
15
  }
16
16
 
17
- export class ObservablePersistIndexedDB implements ObservablePersistLocal {
17
+ export class ObservablePersistIndexedDB implements ObservablePersistPlugin {
18
18
  private tableData: Record<string, any> = {};
19
19
  private tableMetadata: Record<string, any> = {};
20
20
  private tablesAdjusted: Map<string, Observable<boolean>> = new Map();
21
21
  private db: IDBDatabase | undefined;
22
22
  private isSaveTaskQueued = false;
23
23
  private pendingSaves = new Map<
24
- PersistOptionsLocal,
24
+ PersistOptions,
25
25
  Record<string, { tableName: string; tablePrev?: any; items: Set<string> }>
26
26
  >();
27
27
  private promisesQueued: (() => void)[] = [];
@@ -30,7 +30,7 @@ export class ObservablePersistIndexedDB implements ObservablePersistLocal {
30
30
  this.doSave = this.doSave.bind(this);
31
31
  }
32
32
 
33
- public async initialize(config: ObservableCachePluginOptions) {
33
+ public async initialize(config: ObservablePersistPluginOptions) {
34
34
  if (typeof indexedDB === 'undefined') return;
35
35
  if (process.env.NODE_ENV === 'development' && !config?.indexedDB) {
36
36
  console.error('[legend-state] Must configure ObservablePersistIndexedDB');
@@ -75,7 +75,7 @@ export class ObservablePersistIndexedDB implements ObservablePersistLocal {
75
75
  };
76
76
  });
77
77
  }
78
- public loadTable(table: string, config: PersistOptionsLocal): void | Promise<void> {
78
+ public loadTable(table: string, config: PersistOptions): void | Promise<void> {
79
79
  if (!this.tableData[table]) {
80
80
  const transaction = this.db!.transaction(table, 'readonly');
81
81
 
@@ -94,7 +94,7 @@ export class ObservablePersistIndexedDB implements ObservablePersistLocal {
94
94
  } else {
95
95
  const obsLoaded = observable(false);
96
96
  this.tablesAdjusted.set(tableName, obsLoaded);
97
- const data = this.getTable(table, config);
97
+ const data = this.getTable(table, {}, config);
98
98
  let hasPromise = false;
99
99
  let promises: Promise<any>[];
100
100
  if (data) {
@@ -122,7 +122,7 @@ export class ObservablePersistIndexedDB implements ObservablePersistLocal {
122
122
  }
123
123
  }
124
124
  }
125
- public getTable(table: string, config: PersistOptionsLocal) {
125
+ public getTable(table: string, init: object, config: PersistOptions) {
126
126
  const configIDB = config.indexedDB;
127
127
  const prefix = configIDB?.prefixID;
128
128
  const data = this.tableData[prefix ? table + '/' + prefix : table];
@@ -132,11 +132,11 @@ export class ObservablePersistIndexedDB implements ObservablePersistLocal {
132
132
  return data;
133
133
  }
134
134
  }
135
- public getMetadata(table: string, config: PersistOptionsLocal) {
135
+ public getMetadata(table: string, config: PersistOptions) {
136
136
  const { tableName } = this.getMetadataTableName(table, config);
137
137
  return this.tableMetadata[tableName];
138
138
  }
139
- public async setMetadata(table: string, metadata: PersistMetadata, config: PersistOptionsLocal) {
139
+ public async setMetadata(table: string, metadata: PersistMetadata, config: PersistOptions) {
140
140
  const { tableName, tableNameBase } = this.getMetadataTableName(table, config);
141
141
  // Assign new metadata into the table, and make sure it has the id
142
142
  this.tableMetadata[tableName] = Object.assign(metadata, {
@@ -146,14 +146,14 @@ export class ObservablePersistIndexedDB implements ObservablePersistLocal {
146
146
  const store = this.transactionStore(table);
147
147
  return store.put(metadata);
148
148
  }
149
- public async deleteMetadata(table: string, config: PersistOptionsLocal): Promise<void> {
149
+ public async deleteMetadata(table: string, config: PersistOptions): Promise<void> {
150
150
  const { tableName, tableNameBase } = this.getMetadataTableName(table, config);
151
151
  delete this.tableMetadata[tableName];
152
152
  const store = this.transactionStore(table);
153
153
  const key = tableNameBase + MetadataSuffix;
154
154
  store.delete(key);
155
155
  }
156
- public async set(table: string, changes: Change[], config: PersistOptionsLocal) {
156
+ public async set(table: string, changes: Change[], config: PersistOptions) {
157
157
  if (typeof indexedDB === 'undefined') return;
158
158
 
159
159
  if (!this.pendingSaves.has(config)) {
@@ -249,7 +249,7 @@ export class ObservablePersistIndexedDB implements ObservablePersistLocal {
249
249
 
250
250
  promisesQueued.forEach((resolve) => resolve());
251
251
  }
252
- public async deleteTable(table: string, config: PersistOptionsLocal): Promise<void> {
252
+ public async deleteTable(table: string, config: PersistOptions): Promise<void> {
253
253
  const configIDB = config.indexedDB;
254
254
  const prefixID = configIDB?.prefixID;
255
255
  const tableName = prefixID ? table + '/' + prefixID : table;
@@ -289,7 +289,7 @@ export class ObservablePersistIndexedDB implements ObservablePersistLocal {
289
289
  }
290
290
  }
291
291
  // Private
292
- private getMetadataTableName(table: string, config: PersistOptionsLocal) {
292
+ private getMetadataTableName(table: string, config: PersistOptions) {
293
293
  const configIDB = config.indexedDB;
294
294
  let name = '';
295
295
  if (configIDB) {
@@ -357,7 +357,7 @@ export class ObservablePersistIndexedDB implements ObservablePersistLocal {
357
357
  const transaction = this.db!.transaction(table, 'readwrite');
358
358
  return transaction.objectStore(table);
359
359
  }
360
- private _setItem(table: string, key: string, value: any, store: IDBObjectStore, config: PersistOptionsLocal) {
360
+ private _setItem(table: string, key: string, value: any, store: IDBObjectStore, config: PersistOptions) {
361
361
  if (!value) {
362
362
  if (this.tableData[table]) {
363
363
  delete this.tableData[table][key];
@@ -399,7 +399,7 @@ export class ObservablePersistIndexedDB implements ObservablePersistLocal {
399
399
  prev: object,
400
400
  value: Record<string, any>,
401
401
  store: IDBObjectStore,
402
- config: PersistOptionsLocal,
402
+ config: PersistOptions,
403
403
  ) {
404
404
  const keys = Object.keys(value);
405
405
  let lastSet: IDBRequest | undefined;
@@ -1,30 +1,30 @@
1
- import type { Change, ObservableCachePlugin, PersistMetadata } from '@legendapp/state';
1
+ import type { Change, ObservablePersistPlugin, PersistMetadata } from '@legendapp/state';
2
2
  import { internal, setAtPath } from '@legendapp/state';
3
3
 
4
4
  const MetadataSuffix = '__m';
5
5
 
6
6
  const { safeParse, safeStringify } = internal;
7
7
 
8
- export class ObservableCacheLocalStorageBase implements ObservableCachePlugin {
8
+ export class ObservablePersistLocalStorageBase implements ObservablePersistPlugin {
9
9
  private data: Record<string, any> = {};
10
10
  private storage: Storage | undefined;
11
11
  constructor(storage: Storage | undefined) {
12
12
  this.storage = storage;
13
13
  }
14
- public getTable(table: string) {
14
+ public getTable(table: string, init: any) {
15
15
  if (!this.storage) return undefined;
16
16
  if (this.data[table] === undefined) {
17
17
  try {
18
18
  const value = this.storage.getItem(table);
19
- this.data[table] = value ? safeParse(value) : undefined;
19
+ this.data[table] = value ? safeParse(value) : init;
20
20
  } catch {
21
- console.error('[legend-state] ObservableCacheLocalStorageBase failed to parse', table);
21
+ console.error('[legend-state] ObservablePersistLocalStorageBase failed to parse', table);
22
22
  }
23
23
  }
24
24
  return this.data[table];
25
25
  }
26
26
  public getMetadata(table: string): PersistMetadata {
27
- return this.getTable(table + MetadataSuffix);
27
+ return this.getTable(table + MetadataSuffix, {});
28
28
  }
29
29
  public set(table: string, changes: Change[]): void {
30
30
  if (!this.data[table]) {
@@ -64,7 +64,7 @@ export class ObservableCacheLocalStorageBase implements ObservableCachePlugin {
64
64
  }
65
65
  }
66
66
  }
67
- export class ObservableCacheLocalStorage extends ObservableCacheLocalStorageBase {
67
+ export class ObservablePersistLocalStorage extends ObservablePersistLocalStorageBase {
68
68
  constructor() {
69
69
  super(
70
70
  typeof localStorage !== 'undefined'
@@ -76,7 +76,7 @@ export class ObservableCacheLocalStorage extends ObservableCacheLocalStorageBase
76
76
  );
77
77
  }
78
78
  }
79
- export class ObservableCacheSessionStorage extends ObservableCacheLocalStorageBase {
79
+ export class ObservablePersistSessionStorage extends ObservablePersistLocalStorageBase {
80
80
  constructor() {
81
81
  super(
82
82
  typeof sessionStorage !== 'undefined'
@@ -1,4 +1,4 @@
1
- import type { Change, ObservablePersistLocal, PersistMetadata, PersistOptionsLocal } from '@legendapp/state';
1
+ import type { Change, ObservablePersistPlugin, PersistMetadata, PersistOptions } from '@legendapp/state';
2
2
  import { internal, setAtPath } from '@legendapp/state';
3
3
  import { MMKV } from 'react-native-mmkv';
4
4
 
@@ -7,7 +7,7 @@ const MetadataSuffix = '__m';
7
7
 
8
8
  const { safeParse, safeStringify } = internal;
9
9
 
10
- export class ObservablePersistMMKV implements ObservablePersistLocal {
10
+ export class ObservablePersistMMKV implements ObservablePersistPlugin {
11
11
  private data: Record<string, any> = {};
12
12
  private storages = new Map<symbol | string, MMKV>([
13
13
  [
@@ -18,23 +18,23 @@ export class ObservablePersistMMKV implements ObservablePersistLocal {
18
18
  ],
19
19
  ]);
20
20
  // Gets
21
- public getTable<T = any>(table: string, config: PersistOptionsLocal): T {
21
+ public getTable<T = any>(table: string, init: object, config: PersistOptions): T {
22
22
  const storage = this.getStorage(config);
23
23
  if (this.data[table] === undefined) {
24
24
  try {
25
25
  const value = storage.getString(table);
26
- this.data[table] = value ? safeParse(value) : undefined;
26
+ this.data[table] = value ? safeParse(value) : init;
27
27
  } catch {
28
28
  console.error('[legend-state] MMKV failed to parse', table);
29
29
  }
30
30
  }
31
31
  return this.data[table];
32
32
  }
33
- public getMetadata(table: string, config: PersistOptionsLocal): PersistMetadata {
34
- return this.getTable(table + MetadataSuffix, config);
33
+ public getMetadata(table: string, config: PersistOptions): PersistMetadata {
34
+ return this.getTable(table + MetadataSuffix, {}, config);
35
35
  }
36
36
  // Sets
37
- public set(table: string, changes: Change[], config: PersistOptionsLocal) {
37
+ public set(table: string, changes: Change[], config: PersistOptions) {
38
38
  if (!this.data[table]) {
39
39
  this.data[table] = {};
40
40
  }
@@ -44,19 +44,19 @@ export class ObservablePersistMMKV implements ObservablePersistLocal {
44
44
  }
45
45
  this.save(table, config);
46
46
  }
47
- public setMetadata(table: string, metadata: PersistMetadata, config: PersistOptionsLocal) {
47
+ public setMetadata(table: string, metadata: PersistMetadata, config: PersistOptions) {
48
48
  return this.setValue(table + MetadataSuffix, metadata, config);
49
49
  }
50
- public deleteTable(table: string, config: PersistOptionsLocal): void {
50
+ public deleteTable(table: string, config: PersistOptions): void {
51
51
  const storage = this.getStorage(config);
52
52
  delete this.data[table];
53
53
  storage.delete(table);
54
54
  }
55
- public deleteMetadata(table: string, config: PersistOptionsLocal) {
55
+ public deleteMetadata(table: string, config: PersistOptions) {
56
56
  this.deleteTable(table + MetadataSuffix, config);
57
57
  }
58
58
  // Private
59
- private getStorage(config: PersistOptionsLocal): MMKV {
59
+ private getStorage(config: PersistOptions): MMKV {
60
60
  const { mmkv } = config;
61
61
  if (mmkv) {
62
62
  const key = JSON.stringify(mmkv);
@@ -70,11 +70,11 @@ export class ObservablePersistMMKV implements ObservablePersistLocal {
70
70
  return this.storages.get(symbolDefault)!;
71
71
  }
72
72
  }
73
- private async setValue(table: string, value: any, config: PersistOptionsLocal) {
73
+ private async setValue(table: string, value: any, config: PersistOptions) {
74
74
  this.data[table] = value;
75
75
  this.save(table, config);
76
76
  }
77
- private save(table: string, config: PersistOptionsLocal) {
77
+ private save(table: string, config: PersistOptions) {
78
78
  const storage = this.getStorage(config);
79
79
  const v = this.data[table];
80
80
  if (v !== undefined) {
@@ -6,7 +6,7 @@ import type { AsyncStorageStatic } from '@react-native-async-storage/async-stora
6
6
  // @ts-ignore
7
7
  import type { DatabaseReference, Query } from 'firebase/database';
8
8
 
9
- import type { GetMode } from './syncTypes';
9
+ import type { GetMode, PersistMetadata } from './syncTypes';
10
10
  import type {
11
11
  ArrayValue,
12
12
  Change,
@@ -24,7 +24,7 @@ export interface PersistTransform<TOrig = any, TSaved = TOrig> {
24
24
  save?: (value: TOrig) => TSaved | Promise<TSaved>;
25
25
  }
26
26
 
27
- export interface PersistOptionsLocal<T = any> {
27
+ export interface LegacyPersistOptionsLocal<T = any> {
28
28
  name: string;
29
29
  transform?: PersistTransform<T>;
30
30
  fieldTransforms?: FieldTransforms<T>;
@@ -36,7 +36,7 @@ export interface PersistOptionsLocal<T = any> {
36
36
  };
37
37
  options?: any;
38
38
  }
39
- export type PersistOptionsRemote<T = any> = ObservablePersistenceConfigRemoteGlobalOptions & {
39
+ export type LegacyPersistOptionsRemote<T = any> = ObservablePersistenceConfigRemoteGlobalOptions & {
40
40
  readonly?: boolean;
41
41
  waitForGet?: Selector<any>;
42
42
  waitForSet?: LinkedParams['waitForSet'];
@@ -92,29 +92,22 @@ export interface ObservablePersistenceConfig {
92
92
  localOptions?: ObservablePersistenceConfigLocalGlobalOptions;
93
93
  remoteOptions?: ObservablePersistenceConfigRemoteGlobalOptions;
94
94
  }
95
- export interface PersistOptions<T = any> {
96
- local?: string | PersistOptionsLocal<T>;
97
- remote?: PersistOptionsRemote<T>;
95
+ export interface LegacyPersistOptions<T = any> {
96
+ local?: string | LegacyPersistOptionsLocal<T>;
97
+ remote?: LegacyPersistOptionsRemote<T>;
98
98
  pluginLocal?: ClassConstructor<ObservablePersistLocal>;
99
99
  pluginRemote?: ClassConstructor<ObservablePersistRemoteClass> | ObservablePersistRemoteFunctions<T>;
100
100
  }
101
101
 
102
- export interface PersistMetadata {
103
- id?: '__legend_metadata';
104
- // modified ?: number;
105
- lastSync?: number;
106
- pending?: any;
107
- }
108
-
109
102
  export interface ObservablePersistLocal {
110
103
  initialize?(config: ObservablePersistenceConfigLocalGlobalOptions): void | Promise<void>;
111
- loadTable?(table: string, config: PersistOptionsLocal): Promise<any> | void;
112
- getTable<T = any>(table: string, config: PersistOptionsLocal): T;
113
- set(table: string, changes: Change[], config: PersistOptionsLocal): Promise<any> | void;
114
- deleteTable(table: string, config: PersistOptionsLocal): Promise<any> | void;
115
- getMetadata(table: string, config: PersistOptionsLocal): PersistMetadata;
116
- setMetadata(table: string, metadata: PersistMetadata, config: PersistOptionsLocal): Promise<any> | void;
117
- deleteMetadata(table: string, config: PersistOptionsLocal): Promise<any> | void;
104
+ loadTable?(table: string, config: LegacyPersistOptionsLocal): Promise<any> | void;
105
+ getTable<T = any>(table: string, config: LegacyPersistOptionsLocal): T;
106
+ set(table: string, changes: Change[], config: LegacyPersistOptionsLocal): Promise<any> | void;
107
+ deleteTable(table: string, config: LegacyPersistOptionsLocal): Promise<any> | void;
108
+ getMetadata(table: string, config: LegacyPersistOptionsLocal): PersistMetadata;
109
+ setMetadata(table: string, metadata: PersistMetadata, config: LegacyPersistOptionsLocal): Promise<any> | void;
110
+ deleteMetadata(table: string, config: LegacyPersistOptionsLocal): Promise<any> | void;
118
111
  }
119
112
  export interface ObservableOnChangeParams {
120
113
  value: unknown;
@@ -127,14 +120,14 @@ export interface ObservableOnChangeParams {
127
120
  export interface ObservablePersistRemoteSetParams<T> {
128
121
  syncState: Observable<ObservablePersistState>;
129
122
  obs: ObservableParam<T>;
130
- options: PersistOptions<T>;
123
+ options: LegacyPersistOptions<T>;
131
124
  changes: Change[];
132
125
  value: T;
133
126
  }
134
127
  export interface ObservablePersistRemoteGetParams<T> {
135
128
  state: Observable<ObservablePersistState>;
136
129
  obs: ObservableParam<T>;
137
- options: PersistOptions<T>;
130
+ options: LegacyPersistOptions<T>;
138
131
  dateModified?: number;
139
132
  lastSync?: number;
140
133
  mode?: GetMode;