@legendapp/state 3.0.0-beta.0 → 3.0.0-beta.11

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 (39) hide show
  1. package/index.d.mts +2 -0
  2. package/index.d.ts +2 -0
  3. package/index.js +9 -3
  4. package/index.mjs +9 -3
  5. package/package.json +7 -1
  6. package/persist-plugins/async-storage.js +17 -9
  7. package/persist-plugins/async-storage.mjs +17 -9
  8. package/react-reactive/enableReactComponents.d.mts +3 -2
  9. package/react-reactive/enableReactComponents.d.ts +3 -2
  10. package/react-reactive/enableReactComponents.js +7 -2
  11. package/react-reactive/enableReactComponents.mjs +7 -2
  12. package/react-reactive/enableReactNativeComponents.d.mts +3 -20
  13. package/react-reactive/enableReactNativeComponents.d.ts +3 -20
  14. package/react-reactive/enableReactNativeComponents.js +8 -3
  15. package/react-reactive/enableReactNativeComponents.mjs +8 -3
  16. package/react-reactive/enableReactive.js +7 -2
  17. package/react-reactive/enableReactive.mjs +7 -2
  18. package/react-reactive/enableReactive.native.js +8 -3
  19. package/react-reactive/enableReactive.native.mjs +8 -3
  20. package/react-reactive/enableReactive.web.js +8 -3
  21. package/react-reactive/enableReactive.web.mjs +8 -3
  22. package/react.d.mts +9 -7
  23. package/react.d.ts +9 -7
  24. package/sync-plugins/crud.js +22 -24
  25. package/sync-plugins/crud.mjs +22 -24
  26. package/sync-plugins/supabase.js +14 -6
  27. package/sync-plugins/supabase.mjs +14 -6
  28. package/sync-plugins/tanstack-query.d.mts +5 -5
  29. package/sync-plugins/tanstack-query.d.ts +5 -5
  30. package/sync-plugins/tanstack-query.js +17 -2
  31. package/sync-plugins/tanstack-query.mjs +17 -2
  32. package/sync-plugins/tanstack-react-query.d.mts +4 -2
  33. package/sync-plugins/tanstack-react-query.d.ts +4 -2
  34. package/sync.js +118 -92
  35. package/sync.mjs +118 -92
  36. package/trace.js +5 -6
  37. package/trace.mjs +5 -6
  38. package/types/reactive-native.d.ts +19 -0
  39. package/types/reactive-web.d.ts +7 -0
@@ -256,40 +256,38 @@ function syncedCrud(props) {
256
256
  const saveResult = async (itemKey, input, data, isCreate) => {
257
257
  var _a;
258
258
  if (data) {
259
- const saved = (transform == null ? void 0 : transform.load) ? await transform.load(data, "set") : data;
259
+ let saved = (transform == null ? void 0 : transform.load) ? await transform.load(data, "set") : data;
260
260
  const isChild = itemKey !== "undefined" && asType !== "value";
261
261
  const currentPeeked = state.getNodeValue(node);
262
262
  const currentValue = isChild ? (_a = asType === "array" && state.isArray(currentPeeked) ? currentPeeked.find((v) => v[fieldId] === itemKey) : void 0) != null ? _a : currentPeeked[itemKey] : currentPeeked;
263
- const dataOnSaved = {
264
- saved,
265
- input,
266
- currentValue,
267
- isCreate,
268
- props
269
- };
270
- let savedOut = saved;
271
- if (savedOut && !state.isNullOrUndefined(currentValue)) {
272
- savedOut = clone(savedOut);
273
- Object.keys(savedOut).forEach((key) => {
263
+ if (saved && !state.isNullOrUndefined(currentValue)) {
264
+ if (onSaved) {
265
+ const ret = onSaved({
266
+ saved,
267
+ input,
268
+ currentValue,
269
+ isCreate,
270
+ props
271
+ });
272
+ if (ret) {
273
+ saved = ret;
274
+ }
275
+ }
276
+ saved = clone(saved);
277
+ Object.keys(saved).forEach((key) => {
274
278
  const i = input[key];
275
279
  const c = currentValue[key];
276
280
  if (
277
281
  // value is already the new value, can ignore
278
- savedOut[key] === c || // user has changed local value
279
- key !== "id" && i !== c
282
+ saved[key] === c || // user has changed local value
283
+ key !== fieldId && i !== c
280
284
  ) {
281
- delete savedOut[key];
285
+ delete saved[key];
282
286
  }
283
287
  });
284
- if (onSaved) {
285
- const ret = onSaved(dataOnSaved);
286
- if (ret) {
287
- savedOut = ret;
288
- }
289
- }
290
- const createdAt = fieldCreatedAt ? savedOut[fieldCreatedAt] : void 0;
291
- const updatedAt = fieldUpdatedAt ? savedOut[fieldUpdatedAt] : void 0;
292
- const value2 = itemKey !== "undefined" && asType !== "value" ? { [itemKey]: savedOut } : savedOut;
288
+ const createdAt = fieldCreatedAt ? saved[fieldCreatedAt] : void 0;
289
+ const updatedAt = fieldUpdatedAt ? saved[fieldUpdatedAt] : void 0;
290
+ const value2 = itemKey !== "undefined" && asType !== "value" ? { [itemKey]: saved } : saved;
293
291
  update({
294
292
  value: value2,
295
293
  lastSync: updatedAt || createdAt ? +new Date(updatedAt || createdAt) : void 0,
@@ -254,40 +254,38 @@ function syncedCrud(props) {
254
254
  const saveResult = async (itemKey, input, data, isCreate) => {
255
255
  var _a;
256
256
  if (data) {
257
- const saved = (transform == null ? void 0 : transform.load) ? await transform.load(data, "set") : data;
257
+ let saved = (transform == null ? void 0 : transform.load) ? await transform.load(data, "set") : data;
258
258
  const isChild = itemKey !== "undefined" && asType !== "value";
259
259
  const currentPeeked = getNodeValue(node);
260
260
  const currentValue = isChild ? (_a = asType === "array" && isArray(currentPeeked) ? currentPeeked.find((v) => v[fieldId] === itemKey) : void 0) != null ? _a : currentPeeked[itemKey] : currentPeeked;
261
- const dataOnSaved = {
262
- saved,
263
- input,
264
- currentValue,
265
- isCreate,
266
- props
267
- };
268
- let savedOut = saved;
269
- if (savedOut && !isNullOrUndefined(currentValue)) {
270
- savedOut = clone(savedOut);
271
- Object.keys(savedOut).forEach((key) => {
261
+ if (saved && !isNullOrUndefined(currentValue)) {
262
+ if (onSaved) {
263
+ const ret = onSaved({
264
+ saved,
265
+ input,
266
+ currentValue,
267
+ isCreate,
268
+ props
269
+ });
270
+ if (ret) {
271
+ saved = ret;
272
+ }
273
+ }
274
+ saved = clone(saved);
275
+ Object.keys(saved).forEach((key) => {
272
276
  const i = input[key];
273
277
  const c = currentValue[key];
274
278
  if (
275
279
  // value is already the new value, can ignore
276
- savedOut[key] === c || // user has changed local value
277
- key !== "id" && i !== c
280
+ saved[key] === c || // user has changed local value
281
+ key !== fieldId && i !== c
278
282
  ) {
279
- delete savedOut[key];
283
+ delete saved[key];
280
284
  }
281
285
  });
282
- if (onSaved) {
283
- const ret = onSaved(dataOnSaved);
284
- if (ret) {
285
- savedOut = ret;
286
- }
287
- }
288
- const createdAt = fieldCreatedAt ? savedOut[fieldCreatedAt] : void 0;
289
- const updatedAt = fieldUpdatedAt ? savedOut[fieldUpdatedAt] : void 0;
290
- const value2 = itemKey !== "undefined" && asType !== "value" ? { [itemKey]: savedOut } : savedOut;
286
+ const createdAt = fieldCreatedAt ? saved[fieldCreatedAt] : void 0;
287
+ const updatedAt = fieldUpdatedAt ? saved[fieldUpdatedAt] : void 0;
288
+ const value2 = itemKey !== "undefined" && asType !== "value" ? { [itemKey]: saved } : saved;
291
289
  update({
292
290
  value: value2,
293
291
  lastSync: updatedAt || createdAt ? +new Date(updatedAt || createdAt) : void 0,
@@ -36,9 +36,9 @@ function syncedSupabase(props) {
36
36
  schema,
37
37
  filter,
38
38
  actions,
39
- fieldCreatedAt: fieldCreatedAtParam,
40
- fieldUpdatedAt: fieldUpdatedAtParam,
41
- fieldDeleted: fieldDeletedParam,
39
+ fieldCreatedAt,
40
+ fieldUpdatedAt,
41
+ fieldDeleted,
42
42
  realtime,
43
43
  changesSince,
44
44
  transform: transformParam,
@@ -54,9 +54,17 @@ function syncedSupabase(props) {
54
54
  ...rest
55
55
  } = props;
56
56
  const client = supabase;
57
- const fieldCreatedAt = fieldCreatedAtParam || (changesSince === "last-sync" ? "created_at" : void 0);
58
- const fieldUpdatedAt = fieldUpdatedAtParam || (changesSince === "last-sync" ? "updated_at" : void 0);
59
- const fieldDeleted = fieldDeletedParam || (changesSince === "last-sync" ? "deleted" : void 0);
57
+ if (process.env.NODE_ENV === "development" && changesSince === "last-sync") {
58
+ if (!fieldCreatedAt) {
59
+ console.warn("[legend-state] fieldCreatedAt is required when using last-sync mode");
60
+ }
61
+ if (!fieldUpdatedAt) {
62
+ console.warn("[legend-state] fieldUpdatedAt is required when using last-sync mode");
63
+ }
64
+ if (!fieldDeleted) {
65
+ console.warn("[legend-state] fieldDeleted is required when using last-sync mode");
66
+ }
67
+ }
60
68
  const list = !actions || actions.includes("read") ? listParam ? wrapSupabaseFn(listParam) : async (params) => {
61
69
  const { lastSync } = params;
62
70
  const clientSchema = schema ? client.schema(schema) : client;
@@ -34,9 +34,9 @@ function syncedSupabase(props) {
34
34
  schema,
35
35
  filter,
36
36
  actions,
37
- fieldCreatedAt: fieldCreatedAtParam,
38
- fieldUpdatedAt: fieldUpdatedAtParam,
39
- fieldDeleted: fieldDeletedParam,
37
+ fieldCreatedAt,
38
+ fieldUpdatedAt,
39
+ fieldDeleted,
40
40
  realtime,
41
41
  changesSince,
42
42
  transform: transformParam,
@@ -52,9 +52,17 @@ function syncedSupabase(props) {
52
52
  ...rest
53
53
  } = props;
54
54
  const client = supabase;
55
- const fieldCreatedAt = fieldCreatedAtParam || (changesSince === "last-sync" ? "created_at" : void 0);
56
- const fieldUpdatedAt = fieldUpdatedAtParam || (changesSince === "last-sync" ? "updated_at" : void 0);
57
- const fieldDeleted = fieldDeletedParam || (changesSince === "last-sync" ? "deleted" : void 0);
55
+ if (process.env.NODE_ENV === "development" && changesSince === "last-sync") {
56
+ if (!fieldCreatedAt) {
57
+ console.warn("[legend-state] fieldCreatedAt is required when using last-sync mode");
58
+ }
59
+ if (!fieldUpdatedAt) {
60
+ console.warn("[legend-state] fieldUpdatedAt is required when using last-sync mode");
61
+ }
62
+ if (!fieldDeleted) {
63
+ console.warn("[legend-state] fieldDeleted is required when using last-sync mode");
64
+ }
65
+ }
58
66
  const list = !actions || actions.includes("read") ? listParam ? wrapSupabaseFn(listParam) : async (params) => {
59
67
  const { lastSync } = params;
60
68
  const clientSchema = schema ? client.schema(schema) : client;
@@ -1,14 +1,14 @@
1
- import { SyncedOptions } from '@legendapp/state/sync';
1
+ import { SyncedOptions, Synced } from '@legendapp/state/sync';
2
2
  import { QueryKey, QueryObserverOptions, QueryClient, MutationObserverOptions, DefaultError } from '@tanstack/query-core';
3
3
 
4
- interface ObservableQueryOptions<TQueryFnData, TError, TData, TQueryKey extends QueryKey> extends Omit<QueryObserverOptions<TQueryFnData, TError, TData, TQueryKey>, 'queryKey'> {
4
+ interface ObservableQueryOptions<TQueryFnData, TError, TData, TQueryKey extends QueryKey> extends Omit<QueryObserverOptions<TQueryFnData, TError, TData, TData, TQueryKey>, 'queryKey'> {
5
5
  queryKey?: TQueryKey | (() => TQueryKey);
6
6
  }
7
- interface SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey extends QueryKey> extends Omit<SyncedOptions<TData>, 'get' | 'set'> {
7
+ interface SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey extends QueryKey> extends Omit<SyncedOptions<TData>, 'get' | 'set' | 'retry'> {
8
8
  queryClient: QueryClient;
9
9
  query: ObservableQueryOptions<TQueryFnData, TError, TData, TQueryKey>;
10
- mutation?: MutationObserverOptions<TData, TError, void>;
10
+ mutation?: MutationObserverOptions<TQueryFnData, TError, TData>;
11
11
  }
12
- declare function syncedQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(params: SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey>): TData;
12
+ declare function syncedQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(params: SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey>): Synced<TData>;
13
13
 
14
14
  export { type ObservableQueryOptions, type SyncedQueryParams, syncedQuery };
@@ -1,14 +1,14 @@
1
- import { SyncedOptions } from '@legendapp/state/sync';
1
+ import { SyncedOptions, Synced } from '@legendapp/state/sync';
2
2
  import { QueryKey, QueryObserverOptions, QueryClient, MutationObserverOptions, DefaultError } from '@tanstack/query-core';
3
3
 
4
- interface ObservableQueryOptions<TQueryFnData, TError, TData, TQueryKey extends QueryKey> extends Omit<QueryObserverOptions<TQueryFnData, TError, TData, TQueryKey>, 'queryKey'> {
4
+ interface ObservableQueryOptions<TQueryFnData, TError, TData, TQueryKey extends QueryKey> extends Omit<QueryObserverOptions<TQueryFnData, TError, TData, TData, TQueryKey>, 'queryKey'> {
5
5
  queryKey?: TQueryKey | (() => TQueryKey);
6
6
  }
7
- interface SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey extends QueryKey> extends Omit<SyncedOptions<TData>, 'get' | 'set'> {
7
+ interface SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey extends QueryKey> extends Omit<SyncedOptions<TData>, 'get' | 'set' | 'retry'> {
8
8
  queryClient: QueryClient;
9
9
  query: ObservableQueryOptions<TQueryFnData, TError, TData, TQueryKey>;
10
- mutation?: MutationObserverOptions<TData, TError, void>;
10
+ mutation?: MutationObserverOptions<TQueryFnData, TError, TData>;
11
11
  }
12
- declare function syncedQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(params: SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey>): TData;
12
+ declare function syncedQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(params: SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey>): Synced<TData>;
13
13
 
14
14
  export { type ObservableQueryOptions, type SyncedQueryParams, syncedQuery };
@@ -5,8 +5,14 @@ var sync = require('@legendapp/state/sync');
5
5
  var queryCore = require('@tanstack/query-core');
6
6
 
7
7
  // src/sync-plugins/tanstack-query.ts
8
+ var nextMutationKey = 0;
8
9
  function syncedQuery(params) {
9
- const { query: options, mutation: mutationOptions, queryClient, ...rest } = params;
10
+ const { query: options, mutation: mutationOptions, queryClient, initial: initialParam, ...rest } = params;
11
+ if (initialParam !== void 0) {
12
+ const initialValue = state.isFunction(initialParam) ? initialParam() : initialParam;
13
+ options.initialData = initialValue;
14
+ }
15
+ const initial = options.initialData;
10
16
  const Observer = queryCore.QueryObserver;
11
17
  const defaultedOptions = queryClient.defaultQueryOptions(
12
18
  options
@@ -66,8 +72,16 @@ function syncedQuery(params) {
66
72
  };
67
73
  let set = void 0;
68
74
  if (mutationOptions) {
69
- const mutator = new queryCore.MutationObserver(queryClient, mutationOptions);
75
+ const options2 = {
76
+ mutationKey: ["LS-mutation", nextMutationKey++],
77
+ ...mutationOptions
78
+ };
79
+ const mutator = new queryCore.MutationObserver(queryClient, options2);
70
80
  set = ({ value }) => {
81
+ const mutationCache = queryClient.getMutationCache();
82
+ mutationCache.findAll({ mutationKey: options2.mutationKey }).forEach((mutation) => {
83
+ mutationCache.remove(mutation);
84
+ });
71
85
  return mutator.mutate(value);
72
86
  };
73
87
  }
@@ -75,6 +89,7 @@ function syncedQuery(params) {
75
89
  get,
76
90
  set,
77
91
  subscribe,
92
+ initial,
78
93
  ...rest
79
94
  });
80
95
  }
@@ -3,8 +3,14 @@ import { synced } from '@legendapp/state/sync';
3
3
  import { MutationObserver, QueryObserver, notifyManager } from '@tanstack/query-core';
4
4
 
5
5
  // src/sync-plugins/tanstack-query.ts
6
+ var nextMutationKey = 0;
6
7
  function syncedQuery(params) {
7
- const { query: options, mutation: mutationOptions, queryClient, ...rest } = params;
8
+ const { query: options, mutation: mutationOptions, queryClient, initial: initialParam, ...rest } = params;
9
+ if (initialParam !== void 0) {
10
+ const initialValue = isFunction(initialParam) ? initialParam() : initialParam;
11
+ options.initialData = initialValue;
12
+ }
13
+ const initial = options.initialData;
8
14
  const Observer = QueryObserver;
9
15
  const defaultedOptions = queryClient.defaultQueryOptions(
10
16
  options
@@ -64,8 +70,16 @@ function syncedQuery(params) {
64
70
  };
65
71
  let set = void 0;
66
72
  if (mutationOptions) {
67
- const mutator = new MutationObserver(queryClient, mutationOptions);
73
+ const options2 = {
74
+ mutationKey: ["LS-mutation", nextMutationKey++],
75
+ ...mutationOptions
76
+ };
77
+ const mutator = new MutationObserver(queryClient, options2);
68
78
  set = ({ value }) => {
79
+ const mutationCache = queryClient.getMutationCache();
80
+ mutationCache.findAll({ mutationKey: options2.mutationKey }).forEach((mutation) => {
81
+ mutationCache.remove(mutation);
82
+ });
69
83
  return mutator.mutate(value);
70
84
  };
71
85
  }
@@ -73,6 +87,7 @@ function syncedQuery(params) {
73
87
  get,
74
88
  set,
75
89
  subscribe,
90
+ initial,
76
91
  ...rest
77
92
  });
78
93
  }
@@ -1,8 +1,10 @@
1
1
  import { SyncedQueryParams } from '@legendapp/state/sync-plugins/tanstack-query';
2
- import { DefaultError, QueryKey } from '@tanstack/query-core';
2
+ import { DefaultError, QueryKey, QueryClient } from '@tanstack/query-core';
3
3
  import { Observable } from '@legendapp/state';
4
4
  import { Synced } from '@legendapp/state/sync';
5
5
 
6
- declare function useObservableSyncedQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(params: SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey>): Observable<Synced<TData>>;
6
+ declare function useObservableSyncedQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(params: Omit<SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey>, 'queryClient'> & {
7
+ queryClient?: QueryClient;
8
+ }): Observable<Synced<TData>>;
7
9
 
8
10
  export { useObservableSyncedQuery };
@@ -1,8 +1,10 @@
1
1
  import { SyncedQueryParams } from '@legendapp/state/sync-plugins/tanstack-query';
2
- import { DefaultError, QueryKey } from '@tanstack/query-core';
2
+ import { DefaultError, QueryKey, QueryClient } from '@tanstack/query-core';
3
3
  import { Observable } from '@legendapp/state';
4
4
  import { Synced } from '@legendapp/state/sync';
5
5
 
6
- declare function useObservableSyncedQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(params: SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey>): Observable<Synced<TData>>;
6
+ declare function useObservableSyncedQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(params: Omit<SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey>, 'queryClient'> & {
7
+ queryClient?: QueryClient;
8
+ }): Observable<Synced<TData>>;
7
9
 
8
10
  export { useObservableSyncedQuery };
package/sync.js CHANGED
@@ -639,8 +639,11 @@ async function doChangeRemote(changeInfo) {
639
639
  );
640
640
  let didError = false;
641
641
  if (state.isPromise(savedPromise)) {
642
- await savedPromise.catch(() => {
642
+ await savedPromise.catch((error) => {
643
643
  didError = true;
644
+ if (!syncOptions.retry) {
645
+ onError(error);
646
+ }
644
647
  });
645
648
  }
646
649
  if (!didError) {
@@ -740,9 +743,20 @@ async function loadLocal(value$, syncOptions, syncState$, localState) {
740
743
  await state.when(initialized$);
741
744
  }
742
745
  if (persistPlugin.loadTable) {
743
- const promise = persistPlugin.loadTable(table, config);
744
- if (promise) {
745
- await promise;
746
+ try {
747
+ const promise = persistPlugin.loadTable(table, config);
748
+ if (promise) {
749
+ await promise;
750
+ }
751
+ } catch (err) {
752
+ if (process.env.NODE_ENV === "development") {
753
+ console.error(
754
+ "[legend-state] Error loading local cache. This would be a crashing error in production.",
755
+ err
756
+ );
757
+ } else {
758
+ throw err;
759
+ }
746
760
  }
747
761
  }
748
762
  const prevValue = getNodeValue(node);
@@ -845,7 +859,8 @@ function syncObservable(obs$, syncOptionsOrSynced) {
845
859
  localState.isApplyingPending = false;
846
860
  }
847
861
  };
848
- if (syncOptions.get) {
862
+ const { get, subscribe } = syncOptions;
863
+ if (get || subscribe) {
849
864
  sync = async () => {
850
865
  var _a;
851
866
  if (isSynced && (!getNodeValue(getNode(syncState$)).isSyncEnabled || state.shouldIgnoreUnobserved(node, sync))) {
@@ -858,8 +873,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
858
873
  }
859
874
  const lastSync = (_a = metadatas.get(obs$)) == null ? void 0 : _a.lastSync;
860
875
  const pending = localState.pendingChanges;
861
- const get = syncOptions.get;
862
- if (get) {
876
+ if (get || subscribe) {
863
877
  const { waitFor } = syncOptions;
864
878
  const runGet = () => {
865
879
  var _a2;
@@ -952,7 +966,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
952
966
  node.activationState.onChange = onChange;
953
967
  }
954
968
  if (!isSubscribed && syncOptions.subscribe) {
955
- const subscribe = syncOptions.subscribe;
969
+ const subscribe2 = syncOptions.subscribe;
956
970
  isSubscribed = true;
957
971
  const doSubscribe = () => {
958
972
  const subscribeParams = {
@@ -960,17 +974,27 @@ function syncObservable(obs$, syncOptionsOrSynced) {
960
974
  value$: obs$,
961
975
  lastSync,
962
976
  update: (params) => {
963
- state.when(syncState$.isLoaded, () => {
964
- state.when(waitFor || true, () => {
965
- params.mode || (params.mode = syncOptions.mode || "merge");
966
- onChange(params);
967
- });
968
- });
977
+ state.when(
978
+ () => !get || syncState$.isLoaded.get(),
979
+ () => {
980
+ state.when(waitFor || true, () => {
981
+ params.mode || (params.mode = syncOptions.mode || "merge");
982
+ onChange(params);
983
+ if (!syncState$.isLoaded.peek()) {
984
+ syncState$.assign({
985
+ isLoaded: syncStateValue.numPendingRemoteLoads < 1,
986
+ error: void 0,
987
+ isGetting: syncStateValue.numPendingGets > 0
988
+ });
989
+ }
990
+ });
991
+ }
992
+ );
969
993
  },
970
994
  refresh: () => state.when(syncState$.isLoaded, sync),
971
995
  onError: (error) => onGetError(error, { source: "subscribe", subscribeParams })
972
996
  };
973
- unsubscribe = subscribe(subscribeParams);
997
+ unsubscribe = subscribe2(subscribeParams);
974
998
  };
975
999
  if (waitFor) {
976
1000
  state.whenReady(waitFor, doSubscribe);
@@ -979,85 +1003,87 @@ function syncObservable(obs$, syncOptionsOrSynced) {
979
1003
  }
980
1004
  }
981
1005
  const existingValue = getNodeValue(node);
982
- const onError = (error) => onGetError(error, { getParams, source: "get" });
983
- const getParams = {
984
- node,
985
- value$: obs$,
986
- value: state.isFunction(existingValue) || (existingValue == null ? void 0 : existingValue[symbolLinked]) ? void 0 : existingValue,
987
- mode: syncOptions.mode,
988
- refresh: sync,
989
- options: syncOptions,
990
- lastSync,
991
- updateLastSync: (lastSync2) => getParams.lastSync = lastSync2,
992
- onError,
993
- retryNum: 0,
994
- cancelRetry: false
995
- };
996
- let modeBeforeReset = void 0;
997
- const beforeGetParams = {
998
- value: getParams.value,
999
- lastSync,
1000
- pendingChanges: pending && !state.isEmpty(pending) ? pending : void 0,
1001
- clearPendingChanges: async () => {
1002
- localState.pendingChanges = {};
1003
- await updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
1004
- pending: localState.pendingChanges
1005
- });
1006
- },
1007
- resetCache: () => {
1008
- var _a3;
1009
- modeBeforeReset = getParams.mode;
1010
- getParams.mode = "set";
1011
- return (_a3 = syncStateValue.resetPersistence) == null ? void 0 : _a3.call(syncStateValue);
1012
- },
1013
- cancel: false
1014
- };
1015
- (_a2 = syncOptions.onBeforeGet) == null ? void 0 : _a2.call(syncOptions, beforeGetParams);
1016
- if (!beforeGetParams.cancel) {
1017
- syncState$.assign({
1018
- numPendingGets: (syncStateValue.numPendingGets || 0) + 1,
1019
- isGetting: true
1020
- });
1021
- const got = runWithRetry(
1022
- getParams,
1023
- syncOptions.retry,
1024
- (retryEvent) => {
1025
- const params = getParams;
1026
- params.cancelRetry = retryEvent.cancelRetry;
1027
- params.retryNum = retryEvent.retryNum;
1028
- return get(params);
1029
- },
1030
- onError
1031
- );
1032
- const numGets = node.numGets = (node.numGets || 0) + 1;
1033
- const handle = (value) => {
1034
- syncState$.numPendingGets.set((v) => v - 1);
1035
- if (isWaitingForLoad) {
1036
- isWaitingForLoad = false;
1037
- syncStateValue.numPendingRemoteLoads--;
1038
- }
1039
- if (numGets >= (node.getNumResolved || 0)) {
1040
- node.getNumResolved = node.numGets;
1041
- onChange({
1042
- value,
1043
- lastSync: getParams.lastSync,
1044
- mode: getParams.mode
1006
+ if (get) {
1007
+ const onError = (error) => onGetError(error, { getParams, source: "get" });
1008
+ const getParams = {
1009
+ node,
1010
+ value$: obs$,
1011
+ value: state.isFunction(existingValue) || (existingValue == null ? void 0 : existingValue[symbolLinked]) ? void 0 : existingValue,
1012
+ mode: syncOptions.mode,
1013
+ refresh: sync,
1014
+ options: syncOptions,
1015
+ lastSync,
1016
+ updateLastSync: (lastSync2) => getParams.lastSync = lastSync2,
1017
+ onError,
1018
+ retryNum: 0,
1019
+ cancelRetry: false
1020
+ };
1021
+ let modeBeforeReset = void 0;
1022
+ const beforeGetParams = {
1023
+ value: getParams.value,
1024
+ lastSync,
1025
+ pendingChanges: pending && !state.isEmpty(pending) ? pending : void 0,
1026
+ clearPendingChanges: async () => {
1027
+ localState.pendingChanges = {};
1028
+ await updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
1029
+ pending: localState.pendingChanges
1045
1030
  });
1046
- }
1047
- if (modeBeforeReset) {
1048
- getParams.mode = modeBeforeReset;
1049
- modeBeforeReset = void 0;
1050
- }
1031
+ },
1032
+ resetCache: () => {
1033
+ var _a3;
1034
+ modeBeforeReset = getParams.mode;
1035
+ getParams.mode = "set";
1036
+ return (_a3 = syncStateValue.resetPersistence) == null ? void 0 : _a3.call(syncStateValue);
1037
+ },
1038
+ cancel: false
1039
+ };
1040
+ (_a2 = syncOptions.onBeforeGet) == null ? void 0 : _a2.call(syncOptions, beforeGetParams);
1041
+ if (!beforeGetParams.cancel) {
1051
1042
  syncState$.assign({
1052
- isLoaded: syncStateValue.numPendingRemoteLoads < 1,
1053
- error: void 0,
1054
- isGetting: syncStateValue.numPendingGets > 0
1043
+ numPendingGets: (syncStateValue.numPendingGets || 0) + 1,
1044
+ isGetting: true
1055
1045
  });
1056
- };
1057
- if (state.isPromise(got)) {
1058
- got.then(handle).catch(onError);
1059
- } else {
1060
- handle(got);
1046
+ const got = runWithRetry(
1047
+ getParams,
1048
+ syncOptions.retry,
1049
+ (retryEvent) => {
1050
+ const params = getParams;
1051
+ params.cancelRetry = retryEvent.cancelRetry;
1052
+ params.retryNum = retryEvent.retryNum;
1053
+ return get(params);
1054
+ },
1055
+ onError
1056
+ );
1057
+ const numGets = node.numGets = (node.numGets || 0) + 1;
1058
+ const handle = (value) => {
1059
+ syncState$.numPendingGets.set((v) => v - 1);
1060
+ if (isWaitingForLoad) {
1061
+ isWaitingForLoad = false;
1062
+ syncStateValue.numPendingRemoteLoads--;
1063
+ }
1064
+ if (numGets >= (node.getNumResolved || 0)) {
1065
+ node.getNumResolved = node.numGets;
1066
+ onChange({
1067
+ value,
1068
+ lastSync: getParams.lastSync,
1069
+ mode: getParams.mode
1070
+ });
1071
+ }
1072
+ if (modeBeforeReset) {
1073
+ getParams.mode = modeBeforeReset;
1074
+ modeBeforeReset = void 0;
1075
+ }
1076
+ syncState$.assign({
1077
+ isLoaded: syncStateValue.numPendingRemoteLoads < 1,
1078
+ error: void 0,
1079
+ isGetting: syncStateValue.numPendingGets > 0
1080
+ });
1081
+ };
1082
+ if (state.isPromise(got)) {
1083
+ got.then(handle).catch(onError);
1084
+ } else {
1085
+ handle(got);
1086
+ }
1061
1087
  }
1062
1088
  }
1063
1089
  };
@@ -1129,7 +1155,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
1129
1155
  return true;
1130
1156
  };
1131
1157
  state.when(onAllPersistLoaded, function() {
1132
- if (syncOptions.get && syncOptions.syncMode === "auto") {
1158
+ if ((syncOptions.get || syncOptions.subscribe) && syncOptions.syncMode === "auto") {
1133
1159
  sync();
1134
1160
  }
1135
1161
  if ((syncOptions == null ? void 0 : syncOptions.set) || (syncOptions == null ? void 0 : syncOptions.persist)) {