@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
package/sync.mjs CHANGED
@@ -637,8 +637,11 @@ async function doChangeRemote(changeInfo) {
637
637
  );
638
638
  let didError = false;
639
639
  if (isPromise$1(savedPromise)) {
640
- await savedPromise.catch(() => {
640
+ await savedPromise.catch((error) => {
641
641
  didError = true;
642
+ if (!syncOptions.retry) {
643
+ onError(error);
644
+ }
642
645
  });
643
646
  }
644
647
  if (!didError) {
@@ -738,9 +741,20 @@ async function loadLocal(value$, syncOptions, syncState$, localState) {
738
741
  await when(initialized$);
739
742
  }
740
743
  if (persistPlugin.loadTable) {
741
- const promise = persistPlugin.loadTable(table, config);
742
- if (promise) {
743
- await promise;
744
+ try {
745
+ const promise = persistPlugin.loadTable(table, config);
746
+ if (promise) {
747
+ await promise;
748
+ }
749
+ } catch (err) {
750
+ if (process.env.NODE_ENV === "development") {
751
+ console.error(
752
+ "[legend-state] Error loading local cache. This would be a crashing error in production.",
753
+ err
754
+ );
755
+ } else {
756
+ throw err;
757
+ }
744
758
  }
745
759
  }
746
760
  const prevValue = getNodeValue(node);
@@ -843,7 +857,8 @@ function syncObservable(obs$, syncOptionsOrSynced) {
843
857
  localState.isApplyingPending = false;
844
858
  }
845
859
  };
846
- if (syncOptions.get) {
860
+ const { get, subscribe } = syncOptions;
861
+ if (get || subscribe) {
847
862
  sync = async () => {
848
863
  var _a;
849
864
  if (isSynced && (!getNodeValue(getNode(syncState$)).isSyncEnabled || shouldIgnoreUnobserved(node, sync))) {
@@ -856,8 +871,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
856
871
  }
857
872
  const lastSync = (_a = metadatas.get(obs$)) == null ? void 0 : _a.lastSync;
858
873
  const pending = localState.pendingChanges;
859
- const get = syncOptions.get;
860
- if (get) {
874
+ if (get || subscribe) {
861
875
  const { waitFor } = syncOptions;
862
876
  const runGet = () => {
863
877
  var _a2;
@@ -950,7 +964,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
950
964
  node.activationState.onChange = onChange;
951
965
  }
952
966
  if (!isSubscribed && syncOptions.subscribe) {
953
- const subscribe = syncOptions.subscribe;
967
+ const subscribe2 = syncOptions.subscribe;
954
968
  isSubscribed = true;
955
969
  const doSubscribe = () => {
956
970
  const subscribeParams = {
@@ -958,17 +972,27 @@ function syncObservable(obs$, syncOptionsOrSynced) {
958
972
  value$: obs$,
959
973
  lastSync,
960
974
  update: (params) => {
961
- when(syncState$.isLoaded, () => {
962
- when(waitFor || true, () => {
963
- params.mode || (params.mode = syncOptions.mode || "merge");
964
- onChange(params);
965
- });
966
- });
975
+ when(
976
+ () => !get || syncState$.isLoaded.get(),
977
+ () => {
978
+ when(waitFor || true, () => {
979
+ params.mode || (params.mode = syncOptions.mode || "merge");
980
+ onChange(params);
981
+ if (!syncState$.isLoaded.peek()) {
982
+ syncState$.assign({
983
+ isLoaded: syncStateValue.numPendingRemoteLoads < 1,
984
+ error: void 0,
985
+ isGetting: syncStateValue.numPendingGets > 0
986
+ });
987
+ }
988
+ });
989
+ }
990
+ );
967
991
  },
968
992
  refresh: () => when(syncState$.isLoaded, sync),
969
993
  onError: (error) => onGetError(error, { source: "subscribe", subscribeParams })
970
994
  };
971
- unsubscribe = subscribe(subscribeParams);
995
+ unsubscribe = subscribe2(subscribeParams);
972
996
  };
973
997
  if (waitFor) {
974
998
  whenReady(waitFor, doSubscribe);
@@ -977,85 +1001,87 @@ function syncObservable(obs$, syncOptionsOrSynced) {
977
1001
  }
978
1002
  }
979
1003
  const existingValue = getNodeValue(node);
980
- const onError = (error) => onGetError(error, { getParams, source: "get" });
981
- const getParams = {
982
- node,
983
- value$: obs$,
984
- value: isFunction(existingValue) || (existingValue == null ? void 0 : existingValue[symbolLinked]) ? void 0 : existingValue,
985
- mode: syncOptions.mode,
986
- refresh: sync,
987
- options: syncOptions,
988
- lastSync,
989
- updateLastSync: (lastSync2) => getParams.lastSync = lastSync2,
990
- onError,
991
- retryNum: 0,
992
- cancelRetry: false
993
- };
994
- let modeBeforeReset = void 0;
995
- const beforeGetParams = {
996
- value: getParams.value,
997
- lastSync,
998
- pendingChanges: pending && !isEmpty(pending) ? pending : void 0,
999
- clearPendingChanges: async () => {
1000
- localState.pendingChanges = {};
1001
- await updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
1002
- pending: localState.pendingChanges
1003
- });
1004
- },
1005
- resetCache: () => {
1006
- var _a3;
1007
- modeBeforeReset = getParams.mode;
1008
- getParams.mode = "set";
1009
- return (_a3 = syncStateValue.resetPersistence) == null ? void 0 : _a3.call(syncStateValue);
1010
- },
1011
- cancel: false
1012
- };
1013
- (_a2 = syncOptions.onBeforeGet) == null ? void 0 : _a2.call(syncOptions, beforeGetParams);
1014
- if (!beforeGetParams.cancel) {
1015
- syncState$.assign({
1016
- numPendingGets: (syncStateValue.numPendingGets || 0) + 1,
1017
- isGetting: true
1018
- });
1019
- const got = runWithRetry(
1020
- getParams,
1021
- syncOptions.retry,
1022
- (retryEvent) => {
1023
- const params = getParams;
1024
- params.cancelRetry = retryEvent.cancelRetry;
1025
- params.retryNum = retryEvent.retryNum;
1026
- return get(params);
1027
- },
1028
- onError
1029
- );
1030
- const numGets = node.numGets = (node.numGets || 0) + 1;
1031
- const handle = (value) => {
1032
- syncState$.numPendingGets.set((v) => v - 1);
1033
- if (isWaitingForLoad) {
1034
- isWaitingForLoad = false;
1035
- syncStateValue.numPendingRemoteLoads--;
1036
- }
1037
- if (numGets >= (node.getNumResolved || 0)) {
1038
- node.getNumResolved = node.numGets;
1039
- onChange({
1040
- value,
1041
- lastSync: getParams.lastSync,
1042
- mode: getParams.mode
1004
+ if (get) {
1005
+ const onError = (error) => onGetError(error, { getParams, source: "get" });
1006
+ const getParams = {
1007
+ node,
1008
+ value$: obs$,
1009
+ value: isFunction(existingValue) || (existingValue == null ? void 0 : existingValue[symbolLinked]) ? void 0 : existingValue,
1010
+ mode: syncOptions.mode,
1011
+ refresh: sync,
1012
+ options: syncOptions,
1013
+ lastSync,
1014
+ updateLastSync: (lastSync2) => getParams.lastSync = lastSync2,
1015
+ onError,
1016
+ retryNum: 0,
1017
+ cancelRetry: false
1018
+ };
1019
+ let modeBeforeReset = void 0;
1020
+ const beforeGetParams = {
1021
+ value: getParams.value,
1022
+ lastSync,
1023
+ pendingChanges: pending && !isEmpty(pending) ? pending : void 0,
1024
+ clearPendingChanges: async () => {
1025
+ localState.pendingChanges = {};
1026
+ await updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
1027
+ pending: localState.pendingChanges
1043
1028
  });
1044
- }
1045
- if (modeBeforeReset) {
1046
- getParams.mode = modeBeforeReset;
1047
- modeBeforeReset = void 0;
1048
- }
1029
+ },
1030
+ resetCache: () => {
1031
+ var _a3;
1032
+ modeBeforeReset = getParams.mode;
1033
+ getParams.mode = "set";
1034
+ return (_a3 = syncStateValue.resetPersistence) == null ? void 0 : _a3.call(syncStateValue);
1035
+ },
1036
+ cancel: false
1037
+ };
1038
+ (_a2 = syncOptions.onBeforeGet) == null ? void 0 : _a2.call(syncOptions, beforeGetParams);
1039
+ if (!beforeGetParams.cancel) {
1049
1040
  syncState$.assign({
1050
- isLoaded: syncStateValue.numPendingRemoteLoads < 1,
1051
- error: void 0,
1052
- isGetting: syncStateValue.numPendingGets > 0
1041
+ numPendingGets: (syncStateValue.numPendingGets || 0) + 1,
1042
+ isGetting: true
1053
1043
  });
1054
- };
1055
- if (isPromise$1(got)) {
1056
- got.then(handle).catch(onError);
1057
- } else {
1058
- handle(got);
1044
+ const got = runWithRetry(
1045
+ getParams,
1046
+ syncOptions.retry,
1047
+ (retryEvent) => {
1048
+ const params = getParams;
1049
+ params.cancelRetry = retryEvent.cancelRetry;
1050
+ params.retryNum = retryEvent.retryNum;
1051
+ return get(params);
1052
+ },
1053
+ onError
1054
+ );
1055
+ const numGets = node.numGets = (node.numGets || 0) + 1;
1056
+ const handle = (value) => {
1057
+ syncState$.numPendingGets.set((v) => v - 1);
1058
+ if (isWaitingForLoad) {
1059
+ isWaitingForLoad = false;
1060
+ syncStateValue.numPendingRemoteLoads--;
1061
+ }
1062
+ if (numGets >= (node.getNumResolved || 0)) {
1063
+ node.getNumResolved = node.numGets;
1064
+ onChange({
1065
+ value,
1066
+ lastSync: getParams.lastSync,
1067
+ mode: getParams.mode
1068
+ });
1069
+ }
1070
+ if (modeBeforeReset) {
1071
+ getParams.mode = modeBeforeReset;
1072
+ modeBeforeReset = void 0;
1073
+ }
1074
+ syncState$.assign({
1075
+ isLoaded: syncStateValue.numPendingRemoteLoads < 1,
1076
+ error: void 0,
1077
+ isGetting: syncStateValue.numPendingGets > 0
1078
+ });
1079
+ };
1080
+ if (isPromise$1(got)) {
1081
+ got.then(handle).catch(onError);
1082
+ } else {
1083
+ handle(got);
1084
+ }
1059
1085
  }
1060
1086
  }
1061
1087
  };
@@ -1127,7 +1153,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
1127
1153
  return true;
1128
1154
  };
1129
1155
  when(onAllPersistLoaded, function() {
1130
- if (syncOptions.get && syncOptions.syncMode === "auto") {
1156
+ if ((syncOptions.get || syncOptions.subscribe) && syncOptions.syncMode === "auto") {
1131
1157
  sync();
1132
1158
  }
1133
1159
  if ((syncOptions == null ? void 0 : syncOptions.set) || (syncOptions == null ? void 0 : syncOptions.persist)) {
package/trace.js CHANGED
@@ -19,13 +19,12 @@ function getNodePath(node) {
19
19
  // src/trace/useTraceListeners.ts
20
20
  var { optimized, tracking } = state.internal;
21
21
  function useTraceListeners(name) {
22
- if (process.env.NODE_ENV === "development" && tracking.current) {
22
+ if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && tracking.current) {
23
23
  tracking.current.traceListeners = traceNodes.bind(this, name);
24
24
  }
25
25
  }
26
26
  function traceNodes(name, nodes) {
27
- if (process.env.NODE_ENV === "development" && tracking.current) {
28
- tracking.current.traceListeners = void 0;
27
+ if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && nodes.size) {
29
28
  const arr = [];
30
29
  if (nodes) {
31
30
  for (const tracked of nodes.values()) {
@@ -45,7 +44,7 @@ ${arr.join("\n")}`
45
44
  }
46
45
  var { tracking: tracking2 } = state.internal;
47
46
  function useTraceUpdates(name) {
48
- if (process.env.NODE_ENV === "development" && tracking2.current) {
47
+ if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && tracking2.current) {
49
48
  tracking2.current.traceUpdates = replaceUpdateFn.bind(void 0, name);
50
49
  }
51
50
  }
@@ -54,13 +53,13 @@ function replaceUpdateFn(name, updateFn) {
54
53
  }
55
54
  function onChange(name, updateFn, params) {
56
55
  const { changes } = params;
57
- if (process.env.NODE_ENV === "development") {
56
+ if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") {
58
57
  changes.forEach(({ path, valueAtPath, prevAtPath }) => {
59
58
  console.log(`[legend-state] Rendering ${name ? name + " " : ""}because "${path}" changed:
60
59
  from: ${JSON.stringify(prevAtPath)}
61
60
  to: ${JSON.stringify(valueAtPath)}`);
62
61
  });
63
- return updateFn();
62
+ return updateFn(params);
64
63
  }
65
64
  }
66
65
  var { optimized: optimized2, tracking: tracking3 } = state.internal;
package/trace.mjs CHANGED
@@ -17,13 +17,12 @@ function getNodePath(node) {
17
17
  // src/trace/useTraceListeners.ts
18
18
  var { optimized, tracking } = internal;
19
19
  function useTraceListeners(name) {
20
- if (process.env.NODE_ENV === "development" && tracking.current) {
20
+ if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && tracking.current) {
21
21
  tracking.current.traceListeners = traceNodes.bind(this, name);
22
22
  }
23
23
  }
24
24
  function traceNodes(name, nodes) {
25
- if (process.env.NODE_ENV === "development" && tracking.current) {
26
- tracking.current.traceListeners = void 0;
25
+ if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && nodes.size) {
27
26
  const arr = [];
28
27
  if (nodes) {
29
28
  for (const tracked of nodes.values()) {
@@ -43,7 +42,7 @@ ${arr.join("\n")}`
43
42
  }
44
43
  var { tracking: tracking2 } = internal;
45
44
  function useTraceUpdates(name) {
46
- if (process.env.NODE_ENV === "development" && tracking2.current) {
45
+ if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && tracking2.current) {
47
46
  tracking2.current.traceUpdates = replaceUpdateFn.bind(void 0, name);
48
47
  }
49
48
  }
@@ -52,13 +51,13 @@ function replaceUpdateFn(name, updateFn) {
52
51
  }
53
52
  function onChange(name, updateFn, params) {
54
53
  const { changes } = params;
55
- if (process.env.NODE_ENV === "development") {
54
+ if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") {
56
55
  changes.forEach(({ path, valueAtPath, prevAtPath }) => {
57
56
  console.log(`[legend-state] Rendering ${name ? name + " " : ""}because "${path}" changed:
58
57
  from: ${JSON.stringify(prevAtPath)}
59
58
  to: ${JSON.stringify(valueAtPath)}`);
60
59
  });
61
- return updateFn();
60
+ return updateFn(params);
62
61
  }
63
62
  }
64
63
  var { optimized: optimized2, tracking: tracking3 } = internal;
@@ -0,0 +1,19 @@
1
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2
+ import type { IReactive } from '@legendapp/state/react';
3
+
4
+ declare module '@legendapp/state/react' {
5
+ interface IReactive {
6
+ ActivityIndicator: FCReactive<ActivityIndicator, ActivityIndicatorProps>;
7
+ Button: FCReactive<Button, ButtonProps>;
8
+ FlatList: FCReactive<FlatList, FlatListProps<any>>;
9
+ Image: FCReactive<Image, ImageProps>;
10
+ Pressable: FCReactive<typeof Pressable, PressableProps>;
11
+ ScrollView: FCReactive<ScrollView, ScrollViewProps>;
12
+ SectionList: FCReactive<SectionList, SectionListProps<any>>;
13
+ Switch: FCReactive<Switch, SwitchProps>;
14
+ Text: FCReactive<Text, TextProps>;
15
+ TextInput: FCReactive<TextInput, TextInputProps>;
16
+ TouchableWithoutFeedback: FCReactive<TouchableWithoutFeedback, TouchableWithoutFeedbackProps>;
17
+ View: FCReactive<View, ViewProps>;
18
+ }
19
+ }
@@ -0,0 +1,7 @@
1
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2
+ import type { IReactive, FCReactiveObject } from '@legendapp/state/react';
3
+
4
+ declare module '@legendapp/state/react' {
5
+ // eslint-disable-next-line @typescript-eslint/no-empty-interface
6
+ interface IReactive extends FCReactiveObject<JSX.IntrinsicElements> {}
7
+ }