@legendapp/state 3.0.0-beta.2 → 3.0.0-beta.21

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 (74) hide show
  1. package/.DS_Store +0 -0
  2. package/config/enableReactComponents.js +3 -1
  3. package/config/enableReactComponents.mjs +3 -1
  4. package/config/enableReactTracking.d.mts +2 -1
  5. package/config/enableReactTracking.d.ts +2 -1
  6. package/config/enableReactTracking.js +32 -13
  7. package/config/enableReactTracking.mjs +32 -13
  8. package/index.d.mts +13 -4
  9. package/index.d.ts +13 -4
  10. package/index.js +70 -22
  11. package/index.mjs +70 -22
  12. package/package.json +22 -1
  13. package/persist-plugins/async-storage.js +17 -9
  14. package/persist-plugins/async-storage.mjs +17 -9
  15. package/react-native.d.mts +4 -0
  16. package/react-native.d.ts +4 -0
  17. package/react-native.js +53 -0
  18. package/react-native.mjs +40 -0
  19. package/react-reactive/Components.d.mts +19 -0
  20. package/react-reactive/Components.d.ts +19 -0
  21. package/react-reactive/Components.js +53 -0
  22. package/react-reactive/Components.mjs +40 -0
  23. package/react-reactive/enableReactComponents.d.mts +3 -2
  24. package/react-reactive/enableReactComponents.d.ts +3 -2
  25. package/react-reactive/enableReactComponents.js +10 -3
  26. package/react-reactive/enableReactComponents.mjs +10 -3
  27. package/react-reactive/enableReactNativeComponents.d.mts +3 -20
  28. package/react-reactive/enableReactNativeComponents.d.ts +3 -20
  29. package/react-reactive/enableReactNativeComponents.js +8 -3
  30. package/react-reactive/enableReactNativeComponents.mjs +8 -3
  31. package/react-reactive/enableReactive.js +10 -3
  32. package/react-reactive/enableReactive.mjs +10 -3
  33. package/react-reactive/enableReactive.native.js +8 -3
  34. package/react-reactive/enableReactive.native.mjs +8 -3
  35. package/react-reactive/enableReactive.web.js +8 -3
  36. package/react-reactive/enableReactive.web.mjs +8 -3
  37. package/react-web.d.mts +6 -0
  38. package/react-web.d.ts +6 -0
  39. package/react-web.js +39 -0
  40. package/react-web.mjs +37 -0
  41. package/react.d.mts +38 -20
  42. package/react.d.ts +38 -20
  43. package/react.js +36 -23
  44. package/react.mjs +37 -25
  45. package/sync-plugins/crud.d.mts +24 -9
  46. package/sync-plugins/crud.d.ts +24 -9
  47. package/sync-plugins/crud.js +199 -108
  48. package/sync-plugins/crud.mjs +200 -109
  49. package/sync-plugins/firebase.d.mts +7 -3
  50. package/sync-plugins/firebase.d.ts +7 -3
  51. package/sync-plugins/firebase.js +4 -2
  52. package/sync-plugins/firebase.mjs +4 -2
  53. package/sync-plugins/keel.d.mts +9 -13
  54. package/sync-plugins/keel.d.ts +9 -13
  55. package/sync-plugins/keel.js +52 -41
  56. package/sync-plugins/keel.mjs +53 -37
  57. package/sync-plugins/supabase.d.mts +7 -3
  58. package/sync-plugins/supabase.d.ts +7 -3
  59. package/sync-plugins/supabase.js +87 -31
  60. package/sync-plugins/supabase.mjs +88 -32
  61. package/sync-plugins/tanstack-query.d.mts +5 -5
  62. package/sync-plugins/tanstack-query.d.ts +5 -5
  63. package/sync-plugins/tanstack-query.js +10 -1
  64. package/sync-plugins/tanstack-query.mjs +10 -1
  65. package/sync-plugins/tanstack-react-query.d.mts +4 -2
  66. package/sync-plugins/tanstack-react-query.d.ts +4 -2
  67. package/sync.d.mts +16 -8
  68. package/sync.d.ts +16 -8
  69. package/sync.js +267 -174
  70. package/sync.mjs +266 -174
  71. package/trace.js +5 -6
  72. package/trace.mjs +5 -6
  73. package/types/reactive-native.d.ts +19 -0
  74. package/types/reactive-web.d.ts +7 -0
package/sync.js CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var state = require('@legendapp/state');
4
+ var sync = require('@legendapp/state/sync');
4
5
 
5
6
  // src/sync/configureObservableSync.ts
6
7
  var observableSyncConfiguration = {};
@@ -35,12 +36,12 @@ function diffObjects(obj1, obj2, deep = false) {
35
36
  return diff;
36
37
  }
37
38
  function deepEqual(a, b, ignoreFields, nullVsUndefined) {
38
- if (a === b) {
39
+ if (a === b)
39
40
  return true;
40
- }
41
- if (state.isNullOrUndefined(a) !== state.isNullOrUndefined(b)) {
41
+ if (state.isNullOrUndefined(a) !== state.isNullOrUndefined(b))
42
42
  return false;
43
- }
43
+ if (!state.isObject(a) || !state.isObject(b))
44
+ return a === b;
44
45
  if (nullVsUndefined) {
45
46
  a = removeNullUndefined(
46
47
  a,
@@ -53,8 +54,18 @@ function deepEqual(a, b, ignoreFields, nullVsUndefined) {
53
54
  true
54
55
  );
55
56
  }
56
- const replacer = ignoreFields ? (key, value) => ignoreFields.includes(key) ? void 0 : value : void 0;
57
- return JSON.stringify(a, replacer) === JSON.stringify(b, replacer);
57
+ const keysA = Object.keys(a).filter((key) => !(ignoreFields == null ? void 0 : ignoreFields.includes(key)));
58
+ const keysB = Object.keys(b).filter((key) => !(ignoreFields == null ? void 0 : ignoreFields.includes(key)));
59
+ if (keysA.length !== keysB.length)
60
+ return false;
61
+ return keysA.every((key) => {
62
+ if (!Object.prototype.hasOwnProperty.call(b, key))
63
+ return false;
64
+ if (state.isDate(a[key]) && state.isDate(b[key])) {
65
+ return a[key].getTime() === b[key].getTime();
66
+ }
67
+ return deepEqual(a[key], b[key], ignoreFields, nullVsUndefined);
68
+ });
58
69
  }
59
70
  function combineTransforms(...transforms) {
60
71
  return {
@@ -161,13 +172,13 @@ function createRetryTimeout(retryOptions, retryNum, fn) {
161
172
  }
162
173
  }
163
174
  var mapRetryTimeouts = /* @__PURE__ */ new Map();
164
- function runWithRetry(state, retryOptions, fn, onError) {
175
+ function runWithRetry(state, retryOptions, retryId, fn) {
165
176
  try {
166
177
  let value = fn(state);
167
178
  if (isPromise(value) && retryOptions) {
168
179
  let timeoutRetry;
169
- if (mapRetryTimeouts.has(state.node)) {
170
- clearTimeout(mapRetryTimeouts.get(state.node));
180
+ if (mapRetryTimeouts.has(retryId)) {
181
+ clearTimeout(mapRetryTimeouts.get(retryId));
171
182
  }
172
183
  return new Promise((resolve, reject) => {
173
184
  const run = () => {
@@ -178,9 +189,6 @@ function runWithRetry(state, retryOptions, fn, onError) {
178
189
  if (timeoutRetry) {
179
190
  clearTimeout(timeoutRetry);
180
191
  }
181
- if (onError) {
182
- onError(error, state);
183
- }
184
192
  if (!state.cancelRetry) {
185
193
  const timeout = createRetryTimeout(retryOptions, state.retryNum, () => {
186
194
  value = fn(state);
@@ -190,7 +198,7 @@ function runWithRetry(state, retryOptions, fn, onError) {
190
198
  state.cancelRetry = true;
191
199
  reject(error);
192
200
  } else {
193
- mapRetryTimeouts.set(state.node, timeout);
201
+ mapRetryTimeouts.set(retryId, timeout);
194
202
  timeoutRetry = timeout;
195
203
  }
196
204
  }
@@ -210,9 +218,23 @@ async function waitForSet(waitForSet2, changes, value, params = {}) {
210
218
  await state.when(waitFn);
211
219
  }
212
220
  }
221
+ var { clone } = state.internal;
222
+ function createRevertChanges(obs$, changes) {
223
+ return () => {
224
+ const previous = state.applyChanges(
225
+ clone(obs$.peek()),
226
+ changes,
227
+ /*applyPrevious*/
228
+ true
229
+ );
230
+ sync.onChangeRemote(() => {
231
+ obs$.set(previous);
232
+ });
233
+ };
234
+ }
213
235
 
214
236
  // src/sync/syncObservable.ts
215
- var { clone, deepMerge, getNode, getNodeValue, getValueAtPath, globalState, symbolLinked, createPreviousHandler } = state.internal;
237
+ var { clone: clone2, deepMerge, getNode, getNodeValue, getValueAtPath, globalState, symbolLinked, createPreviousHandler } = state.internal;
216
238
  var mapSyncPlugins = /* @__PURE__ */ new WeakMap();
217
239
  var allSyncStates = /* @__PURE__ */ new Map();
218
240
  var metadatas = /* @__PURE__ */ new WeakMap();
@@ -223,7 +245,7 @@ function parseLocalConfig(config) {
223
245
  function doInOrder(arg1, arg2) {
224
246
  return state.isPromise(arg1) ? arg1.then(arg2) : arg2(arg1);
225
247
  }
226
- function onChangeRemote(cb) {
248
+ function onChangeRemote2(cb) {
227
249
  state.endBatch(true);
228
250
  globalState.isLoadingRemote = true;
229
251
  state.beginBatch();
@@ -275,10 +297,10 @@ function updateMetadata(value$, localState, syncState2, syncOptions, newMetadata
275
297
  if (localState.timeoutSaveMetadata) {
276
298
  clearTimeout(localState.timeoutSaveMetadata);
277
299
  }
278
- localState.timeoutSaveMetadata = setTimeout(
279
- () => updateMetadataImmediate(value$, localState, syncState2, syncOptions, newMetadata),
280
- 0
281
- );
300
+ metadatas.set(value$, { ...metadatas.get(value$) || {}, ...newMetadata });
301
+ localState.timeoutSaveMetadata = setTimeout(() => {
302
+ updateMetadataImmediate(value$, localState, syncState2, syncOptions, metadatas.get(value$));
303
+ }, 0);
282
304
  }
283
305
  var _queuedChanges = [];
284
306
  var _queuedRemoteChanges = /* @__PURE__ */ new Map();
@@ -297,8 +319,25 @@ function mergeChanges(changes) {
297
319
  existing.valueAtPath = change.valueAtPath;
298
320
  }
299
321
  } else {
300
- changesByPath.set(pathStr, change);
301
- changesOut.push(change);
322
+ let found = false;
323
+ for (let u = 0; u < change.path.length; u++) {
324
+ const path = change.path.slice(0, u).join("/");
325
+ if (changesByPath.has(path)) {
326
+ const remaining = change.path.slice(u);
327
+ state.setAtPath(
328
+ changesByPath.get(path).valueAtPath,
329
+ remaining,
330
+ change.pathTypes.slice(u),
331
+ change.valueAtPath
332
+ );
333
+ found = true;
334
+ break;
335
+ }
336
+ }
337
+ if (!found) {
338
+ changesByPath.set(pathStr, change);
339
+ changesOut.push(change);
340
+ }
302
341
  }
303
342
  }
304
343
  return changesOut;
@@ -580,7 +619,7 @@ async function doChangeRemote(changeInfo) {
580
619
  if (waitForSetParam) {
581
620
  await waitForSet(waitForSetParam, changesRemote, obs$.peek());
582
621
  }
583
- let value = clone(obs$.peek());
622
+ let value = clone2(obs$.peek());
584
623
  const transformSave = (_a = syncOptions == null ? void 0 : syncOptions.transform) == null ? void 0 : _a.save;
585
624
  if (transformSave) {
586
625
  value = transformSave(value);
@@ -593,33 +632,41 @@ async function doChangeRemote(changeInfo) {
593
632
  onBeforeSet == null ? void 0 : onBeforeSet(beforeSetParams);
594
633
  if (!beforeSetParams.cancel) {
595
634
  let updateResult = void 0;
596
- let errorHandled = false;
597
- const onError = (error, retryParams) => {
635
+ let lastErrorHandled;
636
+ const onSetError = (error, params, noThrow) => {
598
637
  var _a2;
599
- state$.error.set(error);
600
- if (!errorHandled) {
601
- (_a2 = syncOptions.onError) == null ? void 0 : _a2.call(syncOptions, error, {
602
- setParams,
603
- source: "set",
604
- value$: obs$,
605
- retryParams
606
- });
638
+ if (lastErrorHandled !== error) {
639
+ if (!params) {
640
+ params = {
641
+ setParams,
642
+ source: "set",
643
+ type: "set",
644
+ input: value,
645
+ retry: setParams,
646
+ revert: createRevertChanges(setParams.value$, setParams.changes)
647
+ };
648
+ }
649
+ state$.error.set(error);
650
+ (_a2 = syncOptions.onError) == null ? void 0 : _a2.call(syncOptions, error, params);
651
+ lastErrorHandled = error;
652
+ if (!noThrow) {
653
+ throw error;
654
+ }
607
655
  }
608
- errorHandled = true;
609
656
  };
610
657
  const setParams = {
611
658
  node,
612
659
  value$: obs$,
613
660
  changes: changesRemote,
614
661
  value,
615
- onError,
662
+ onError: onSetError,
616
663
  update: (params) => {
617
664
  if (updateResult) {
618
- const { value: value2, lastSync, mode } = params;
665
+ const { value: value2, mode, changes } = params;
619
666
  updateResult = {
620
- lastSync: Math.max(updateResult.lastSync || 0, lastSync || 0),
621
667
  value: deepMerge(updateResult.value, value2),
622
- mode
668
+ mode,
669
+ changes: changes ? [...updateResult.changes || [], ...changes] : updateResult.changes
623
670
  };
624
671
  } else {
625
672
  updateResult = params;
@@ -629,26 +676,23 @@ async function doChangeRemote(changeInfo) {
629
676
  retryNum: 0,
630
677
  cancelRetry: false
631
678
  };
632
- const savedPromise = runWithRetry(
633
- setParams,
634
- syncOptions.retry,
635
- async () => {
636
- return syncOptions.set(setParams);
637
- },
638
- onError
639
- );
679
+ const savedPromise = runWithRetry(setParams, syncOptions.retry, node, async () => {
680
+ return syncOptions.set(setParams);
681
+ });
640
682
  let didError = false;
641
683
  if (state.isPromise(savedPromise)) {
642
684
  await savedPromise.catch((error) => {
643
685
  didError = true;
644
686
  if (!syncOptions.retry) {
645
- onError(error);
687
+ onSetError(error, void 0, true);
646
688
  }
647
689
  });
648
690
  }
649
- if (!didError) {
650
- const pathStrs = Array.from(new Set(changesRemote.map((change) => change.pathStr)));
651
- const { value: changes, lastSync } = updateResult || {};
691
+ if (!didError || (updateResult == null ? void 0 : updateResult.changes)) {
692
+ const { value: updateValue, changes: updateChanges = changesRemote } = updateResult || {};
693
+ const pathStrs = Array.from(
694
+ new Set(updateChanges.map((change) => change.pathStr))
695
+ );
652
696
  if (pathStrs.length > 0) {
653
697
  let transformedChanges = void 0;
654
698
  const metadata = {};
@@ -665,18 +709,15 @@ async function doChangeRemote(changeInfo) {
665
709
  delete pending[pathStr];
666
710
  }
667
711
  }
668
- if (lastSync) {
669
- metadata.lastSync = lastSync;
670
- }
671
712
  }
672
- if (changes && !state.isEmpty(changes)) {
673
- transformedChanges = transformLoadData(changes, syncOptions, false, "set");
713
+ if (updateValue && !state.isEmpty(updateValue)) {
714
+ transformedChanges = transformLoadData(updateValue, syncOptions, false, "set");
674
715
  }
675
716
  if (transformedChanges !== void 0) {
676
717
  if (state.isPromise(transformedChanges)) {
677
718
  transformedChanges = await transformedChanges;
678
719
  }
679
- onChangeRemote(() => state.mergeIntoObservable(obs$, transformedChanges));
720
+ onChangeRemote2(() => state.mergeIntoObservable(obs$, transformedChanges));
680
721
  }
681
722
  if (saveLocal) {
682
723
  if (shouldSaveMetadata && !state.isEmpty(metadata)) {
@@ -743,9 +784,20 @@ async function loadLocal(value$, syncOptions, syncState$, localState) {
743
784
  await state.when(initialized$);
744
785
  }
745
786
  if (persistPlugin.loadTable) {
746
- const promise = persistPlugin.loadTable(table, config);
747
- if (promise) {
748
- await promise;
787
+ try {
788
+ const promise = persistPlugin.loadTable(table, config);
789
+ if (promise) {
790
+ await promise;
791
+ }
792
+ } catch (err) {
793
+ if (process.env.NODE_ENV === "development") {
794
+ console.error(
795
+ "[legend-state] Error loading local cache. This would be a crashing error in production.",
796
+ err
797
+ );
798
+ } else {
799
+ throw err;
800
+ }
749
801
  }
750
802
  }
751
803
  const prevValue = getNodeValue(node);
@@ -764,12 +816,14 @@ async function loadLocal(value$, syncOptions, syncState$, localState) {
764
816
  if (state.isPromise(value)) {
765
817
  value = await value;
766
818
  }
819
+ node.root.isLoadingLocal = true;
767
820
  state.internal.globalState.isLoadingLocal = true;
768
821
  if (value === null && (!prevValue || prevValue[symbolLinked])) {
769
822
  value$.set(value);
770
823
  } else {
771
824
  state.mergeIntoObservable(value$, value);
772
825
  }
826
+ node.root.isLoadingLocal = false;
773
827
  state.internal.globalState.isLoadingLocal = false;
774
828
  }
775
829
  syncStateValue.numPendingLocalLoads--;
@@ -808,14 +862,24 @@ function syncObservable(obs$, syncOptionsOrSynced) {
808
862
  const syncStateValue = getNodeValue(getNode(syncState$));
809
863
  allSyncStates.set(syncState$, node);
810
864
  syncStateValue.getPendingChanges = () => localState.pendingChanges;
811
- let errorHandled = false;
812
- const onGetError = (error, params) => {
865
+ let lastErrorHandled;
866
+ const onGetError = (error, params, noThrow) => {
813
867
  var _a;
814
- syncState$.error.set(error);
815
- if (!errorHandled) {
816
- (_a = syncOptions.onError) == null ? void 0 : _a.call(syncOptions, error, { ...params, value$: obs$ });
868
+ if (lastErrorHandled !== error) {
869
+ if (!params) {
870
+ params = {
871
+ source: "get",
872
+ type: "get",
873
+ retry: params
874
+ };
875
+ }
876
+ syncState$.error.set(error);
877
+ (_a = syncOptions.onError) == null ? void 0 : _a.call(syncOptions, error, params);
878
+ lastErrorHandled = error;
879
+ if (!noThrow) {
880
+ throw error;
881
+ }
817
882
  }
818
- errorHandled = true;
819
883
  };
820
884
  loadLocal(obs$, syncOptions, syncState$, localState);
821
885
  let isWaitingForLoad = !!syncOptions.get;
@@ -825,30 +889,37 @@ function syncObservable(obs$, syncOptionsOrSynced) {
825
889
  syncState$.isLoaded.set(!syncState$.numPendingRemoteLoads.peek());
826
890
  let isSynced = false;
827
891
  let isSubscribed = false;
892
+ let isApplyingPendingAfterSync = false;
828
893
  let unsubscribe = void 0;
829
894
  const applyPending = (pending) => {
830
895
  if (pending && !state.isEmpty(pending)) {
831
- localState.isApplyingPending = true;
832
896
  const keys = Object.keys(pending);
897
+ const value = getNodeValue(node);
833
898
  const changes = [];
834
899
  for (let i = 0; i < keys.length; i++) {
835
900
  const key = keys[i];
836
901
  const path = key.split("/").filter((p2) => p2 !== "");
837
- const { p, v, t } = pending[key];
838
- changes.push({ path, valueAtPath: v, prevAtPath: p, pathTypes: t });
902
+ const { p, t, v } = pending[key];
903
+ const valueAtPath = getValueAtPath(value, path);
904
+ if (isApplyingPendingAfterSync || !deepEqual(valueAtPath, v)) {
905
+ changes.push({ path, valueAtPath: v, prevAtPath: p, pathTypes: t });
906
+ }
907
+ }
908
+ if (changes.length > 0) {
909
+ localState.isApplyingPending = true;
910
+ onObsChange(obs$, syncState$, localState, syncOptions, {
911
+ value,
912
+ isFromPersist: false,
913
+ isFromSync: false,
914
+ getPrevious: createPreviousHandler(value, changes),
915
+ changes
916
+ });
917
+ localState.isApplyingPending = false;
839
918
  }
840
- const value = getNodeValue(node);
841
- onObsChange(obs$, syncState$, localState, syncOptions, {
842
- value,
843
- isFromPersist: false,
844
- isFromSync: false,
845
- getPrevious: createPreviousHandler(value, changes),
846
- changes
847
- });
848
- localState.isApplyingPending = false;
849
919
  }
850
920
  };
851
- if (syncOptions.get) {
921
+ const { get, subscribe } = syncOptions;
922
+ if (get || subscribe) {
852
923
  sync = async () => {
853
924
  var _a;
854
925
  if (isSynced && (!getNodeValue(getNode(syncState$)).isSyncEnabled || state.shouldIgnoreUnobserved(node, sync))) {
@@ -861,8 +932,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
861
932
  }
862
933
  const lastSync = (_a = metadatas.get(obs$)) == null ? void 0 : _a.lastSync;
863
934
  const pending = localState.pendingChanges;
864
- const get = syncOptions.get;
865
- if (get) {
935
+ if (get || subscribe) {
866
936
  const { waitFor } = syncOptions;
867
937
  const runGet = () => {
868
938
  var _a2;
@@ -881,11 +951,11 @@ function syncObservable(obs$, syncOptionsOrSynced) {
881
951
  const p = key.split("/").filter((k) => k !== "");
882
952
  const { v, t } = pending2[key];
883
953
  if (t.length === 0 || !value) {
884
- const oldValue = clone(value);
885
- pending2[key].p = oldValue;
954
+ const oldValue = clone2(value);
955
+ pending2[key].p = key ? oldValue[key] : oldValue;
886
956
  if (state.isObject(value) && state.isObject(v)) {
887
- Object.assign(value, v);
888
- } else {
957
+ Object.assign(value, key ? { [key]: v } : v);
958
+ } else if (!key) {
889
959
  value = v;
890
960
  }
891
961
  } else if (value[p[0]] !== void 0) {
@@ -895,8 +965,9 @@ function syncObservable(obs$, syncOptionsOrSynced) {
895
965
  delete pending2[key];
896
966
  didChangeMetadata = true;
897
967
  } else {
898
- const oldValue = clone(value);
968
+ const oldValue = clone2(value);
899
969
  pending2[key].p = getValueAtPath(oldValue, p);
970
+ didChangeMetadata = true;
900
971
  value = state.setAtPath(
901
972
  value,
902
973
  p,
@@ -917,12 +988,12 @@ function syncObservable(obs$, syncOptionsOrSynced) {
917
988
  }
918
989
  });
919
990
  if (didChangeMetadata && syncOptions.persist) {
920
- updateMetadata(obs$, localState, syncState$, syncOptions, {
991
+ updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
921
992
  pending: pending2
922
993
  });
923
994
  }
924
995
  }
925
- onChangeRemote(() => {
996
+ onChangeRemote2(() => {
926
997
  if (state.isPlainObject(value)) {
927
998
  value = state.ObservableHint.plain(value);
928
999
  }
@@ -955,7 +1026,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
955
1026
  node.activationState.onChange = onChange;
956
1027
  }
957
1028
  if (!isSubscribed && syncOptions.subscribe) {
958
- const subscribe = syncOptions.subscribe;
1029
+ const subscribe2 = syncOptions.subscribe;
959
1030
  isSubscribed = true;
960
1031
  const doSubscribe = () => {
961
1032
  const subscribeParams = {
@@ -963,17 +1034,32 @@ function syncObservable(obs$, syncOptionsOrSynced) {
963
1034
  value$: obs$,
964
1035
  lastSync,
965
1036
  update: (params) => {
966
- state.when(syncState$.isLoaded, () => {
967
- state.when(waitFor || true, () => {
968
- params.mode || (params.mode = syncOptions.mode || "merge");
969
- onChange(params);
970
- });
971
- });
1037
+ state.when(
1038
+ () => !get || syncState$.isLoaded.get(),
1039
+ () => {
1040
+ state.when(waitFor || true, () => {
1041
+ params.mode || (params.mode = syncOptions.mode || "merge");
1042
+ onChange(params);
1043
+ if (!syncState$.isLoaded.peek()) {
1044
+ syncState$.assign({
1045
+ isLoaded: syncStateValue.numPendingRemoteLoads < 1,
1046
+ error: void 0,
1047
+ isGetting: syncStateValue.numPendingGets > 0
1048
+ });
1049
+ }
1050
+ });
1051
+ }
1052
+ );
972
1053
  },
973
1054
  refresh: () => state.when(syncState$.isLoaded, sync),
974
- onError: (error) => onGetError(error, { source: "subscribe", subscribeParams })
1055
+ onError: (error) => onGetError(error, {
1056
+ source: "subscribe",
1057
+ subscribeParams,
1058
+ type: "get",
1059
+ retry: {}
1060
+ })
975
1061
  };
976
- unsubscribe = subscribe(subscribeParams);
1062
+ unsubscribe = subscribe2(subscribeParams);
977
1063
  };
978
1064
  if (waitFor) {
979
1065
  state.whenReady(waitFor, doSubscribe);
@@ -982,85 +1068,87 @@ function syncObservable(obs$, syncOptionsOrSynced) {
982
1068
  }
983
1069
  }
984
1070
  const existingValue = getNodeValue(node);
985
- const onError = (error) => onGetError(error, { getParams, source: "get" });
986
- const getParams = {
987
- node,
988
- value$: obs$,
989
- value: state.isFunction(existingValue) || (existingValue == null ? void 0 : existingValue[symbolLinked]) ? void 0 : existingValue,
990
- mode: syncOptions.mode,
991
- refresh: sync,
992
- options: syncOptions,
993
- lastSync,
994
- updateLastSync: (lastSync2) => getParams.lastSync = lastSync2,
995
- onError,
996
- retryNum: 0,
997
- cancelRetry: false
998
- };
999
- let modeBeforeReset = void 0;
1000
- const beforeGetParams = {
1001
- value: getParams.value,
1002
- lastSync,
1003
- pendingChanges: pending && !state.isEmpty(pending) ? pending : void 0,
1004
- clearPendingChanges: async () => {
1005
- localState.pendingChanges = {};
1006
- await updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
1007
- pending: localState.pendingChanges
1071
+ if (get) {
1072
+ const getParams = {
1073
+ node,
1074
+ value$: obs$,
1075
+ value: state.isFunction(existingValue) || (existingValue == null ? void 0 : existingValue[symbolLinked]) ? void 0 : existingValue,
1076
+ mode: syncOptions.mode,
1077
+ refresh: sync,
1078
+ options: syncOptions,
1079
+ lastSync,
1080
+ updateLastSync: (lastSync2) => getParams.lastSync = lastSync2,
1081
+ onError: onGetError,
1082
+ retryNum: 0,
1083
+ cancelRetry: false
1084
+ };
1085
+ let modeBeforeReset = void 0;
1086
+ const beforeGetParams = {
1087
+ value: getParams.value,
1088
+ lastSync,
1089
+ pendingChanges: pending && !state.isEmpty(pending) ? pending : void 0,
1090
+ clearPendingChanges: async () => {
1091
+ localState.pendingChanges = {};
1092
+ await updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
1093
+ pending: localState.pendingChanges
1094
+ });
1095
+ },
1096
+ resetCache: () => {
1097
+ var _a3;
1098
+ modeBeforeReset = getParams.mode;
1099
+ getParams.mode = "set";
1100
+ return (_a3 = syncStateValue.resetPersistence) == null ? void 0 : _a3.call(syncStateValue);
1101
+ },
1102
+ cancel: false
1103
+ };
1104
+ (_a2 = syncOptions.onBeforeGet) == null ? void 0 : _a2.call(syncOptions, beforeGetParams);
1105
+ if (!beforeGetParams.cancel) {
1106
+ syncState$.assign({
1107
+ numPendingGets: (syncStateValue.numPendingGets || 0) + 1,
1108
+ isGetting: true
1008
1109
  });
1009
- },
1010
- resetCache: () => {
1011
- var _a3;
1012
- modeBeforeReset = getParams.mode;
1013
- getParams.mode = "set";
1014
- return (_a3 = syncStateValue.resetPersistence) == null ? void 0 : _a3.call(syncStateValue);
1015
- },
1016
- cancel: false
1017
- };
1018
- (_a2 = syncOptions.onBeforeGet) == null ? void 0 : _a2.call(syncOptions, beforeGetParams);
1019
- if (!beforeGetParams.cancel) {
1020
- syncState$.assign({
1021
- numPendingGets: (syncStateValue.numPendingGets || 0) + 1,
1022
- isGetting: true
1023
- });
1024
- const got = runWithRetry(
1025
- getParams,
1026
- syncOptions.retry,
1027
- (retryEvent) => {
1110
+ const got = runWithRetry(getParams, syncOptions.retry, node, (retryEvent) => {
1028
1111
  const params = getParams;
1029
1112
  params.cancelRetry = retryEvent.cancelRetry;
1030
1113
  params.retryNum = retryEvent.retryNum;
1031
1114
  return get(params);
1032
- },
1033
- onError
1034
- );
1035
- const numGets = node.numGets = (node.numGets || 0) + 1;
1036
- const handle = (value) => {
1037
- syncState$.numPendingGets.set((v) => v - 1);
1038
- if (isWaitingForLoad) {
1039
- isWaitingForLoad = false;
1040
- syncStateValue.numPendingRemoteLoads--;
1041
- }
1042
- if (numGets >= (node.getNumResolved || 0)) {
1043
- node.getNumResolved = node.numGets;
1044
- onChange({
1045
- value,
1046
- lastSync: getParams.lastSync,
1047
- mode: getParams.mode
1115
+ });
1116
+ const numGets = node.numGets = (node.numGets || 0) + 1;
1117
+ const handle = (value) => {
1118
+ syncState$.numPendingGets.set((v) => v - 1);
1119
+ if (isWaitingForLoad) {
1120
+ isWaitingForLoad = false;
1121
+ syncStateValue.numPendingRemoteLoads--;
1122
+ }
1123
+ if (numGets >= (node.getNumResolved || 0)) {
1124
+ node.getNumResolved = node.numGets;
1125
+ onChange({
1126
+ value,
1127
+ lastSync: getParams.lastSync,
1128
+ mode: getParams.mode
1129
+ });
1130
+ }
1131
+ if (modeBeforeReset) {
1132
+ getParams.mode = modeBeforeReset;
1133
+ modeBeforeReset = void 0;
1134
+ }
1135
+ syncState$.assign({
1136
+ isLoaded: syncStateValue.numPendingRemoteLoads < 1,
1137
+ error: void 0,
1138
+ isGetting: syncStateValue.numPendingGets > 0
1048
1139
  });
1140
+ };
1141
+ if (state.isPromise(got)) {
1142
+ got.then(handle).catch((error) => {
1143
+ onGetError(
1144
+ error,
1145
+ { getParams, source: "get", type: "get", retry: getParams },
1146
+ true
1147
+ );
1148
+ });
1149
+ } else {
1150
+ handle(got);
1049
1151
  }
1050
- if (modeBeforeReset) {
1051
- getParams.mode = modeBeforeReset;
1052
- modeBeforeReset = void 0;
1053
- }
1054
- syncState$.assign({
1055
- isLoaded: syncStateValue.numPendingRemoteLoads < 1,
1056
- error: void 0,
1057
- isGetting: syncStateValue.numPendingGets > 0
1058
- });
1059
- };
1060
- if (state.isPromise(got)) {
1061
- got.then(handle).catch(onError);
1062
- } else {
1063
- handle(got);
1064
1152
  }
1065
1153
  }
1066
1154
  };
@@ -1077,14 +1165,17 @@ function syncObservable(obs$, syncOptionsOrSynced) {
1077
1165
  }
1078
1166
  if (!isSynced) {
1079
1167
  isSynced = true;
1080
- await state.when(syncState$.isLoaded);
1168
+ isApplyingPendingAfterSync = true;
1081
1169
  applyPending(pending);
1170
+ isApplyingPendingAfterSync = false;
1082
1171
  }
1083
1172
  };
1084
1173
  syncStateValue.sync = sync;
1085
1174
  } else {
1086
1175
  if (!isSynced) {
1176
+ isApplyingPendingAfterSync = true;
1087
1177
  applyPending(localState.pendingChanges);
1178
+ isApplyingPendingAfterSync = false;
1088
1179
  }
1089
1180
  }
1090
1181
  syncStateValue.reset = async () => {
@@ -1110,7 +1201,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
1110
1201
  unsubscribe == null ? void 0 : unsubscribe();
1111
1202
  unsubscribe = void 0;
1112
1203
  const promise = syncStateValue.resetPersistence();
1113
- onChangeRemote(() => {
1204
+ onChangeRemote2(() => {
1114
1205
  var _a;
1115
1206
  obs$.set((_a = syncOptions.initial) != null ? _a : void 0);
1116
1207
  });
@@ -1132,7 +1223,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
1132
1223
  return true;
1133
1224
  };
1134
1225
  state.when(onAllPersistLoaded, function() {
1135
- if (syncOptions.get && syncOptions.syncMode === "auto") {
1226
+ if ((syncOptions.get || syncOptions.subscribe) && syncOptions.syncMode === "auto") {
1136
1227
  sync();
1137
1228
  }
1138
1229
  if ((syncOptions == null ? void 0 : syncOptions.set) || (syncOptions == null ? void 0 : syncOptions.persist)) {
@@ -1215,19 +1306,21 @@ function configureSynced(fnOrOrigOptions, origOptions) {
1215
1306
  }
1216
1307
 
1217
1308
  // sync.ts
1218
- var internal4 = {
1309
+ var internal5 = {
1219
1310
  observableSyncConfiguration,
1220
- waitForSet
1311
+ waitForSet,
1312
+ runWithRetry
1221
1313
  };
1222
1314
 
1223
1315
  exports.combineTransforms = combineTransforms;
1224
1316
  exports.configureObservableSync = configureObservableSync;
1225
1317
  exports.configureSynced = configureSynced;
1318
+ exports.createRevertChanges = createRevertChanges;
1226
1319
  exports.deepEqual = deepEqual;
1227
1320
  exports.diffObjects = diffObjects;
1228
- exports.internal = internal4;
1321
+ exports.internal = internal5;
1229
1322
  exports.mapSyncPlugins = mapSyncPlugins;
1230
- exports.onChangeRemote = onChangeRemote;
1323
+ exports.onChangeRemote = onChangeRemote2;
1231
1324
  exports.removeNullUndefined = removeNullUndefined;
1232
1325
  exports.syncObservable = syncObservable;
1233
1326
  exports.synced = synced;