@legendapp/state 3.0.0-beta.1 → 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 +114 -91
  35. package/sync.mjs +114 -91
  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
@@ -741,9 +741,20 @@ async function loadLocal(value$, syncOptions, syncState$, localState) {
741
741
  await when(initialized$);
742
742
  }
743
743
  if (persistPlugin.loadTable) {
744
- const promise = persistPlugin.loadTable(table, config);
745
- if (promise) {
746
- 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
+ }
747
758
  }
748
759
  }
749
760
  const prevValue = getNodeValue(node);
@@ -846,7 +857,8 @@ function syncObservable(obs$, syncOptionsOrSynced) {
846
857
  localState.isApplyingPending = false;
847
858
  }
848
859
  };
849
- if (syncOptions.get) {
860
+ const { get, subscribe } = syncOptions;
861
+ if (get || subscribe) {
850
862
  sync = async () => {
851
863
  var _a;
852
864
  if (isSynced && (!getNodeValue(getNode(syncState$)).isSyncEnabled || shouldIgnoreUnobserved(node, sync))) {
@@ -859,8 +871,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
859
871
  }
860
872
  const lastSync = (_a = metadatas.get(obs$)) == null ? void 0 : _a.lastSync;
861
873
  const pending = localState.pendingChanges;
862
- const get = syncOptions.get;
863
- if (get) {
874
+ if (get || subscribe) {
864
875
  const { waitFor } = syncOptions;
865
876
  const runGet = () => {
866
877
  var _a2;
@@ -953,7 +964,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
953
964
  node.activationState.onChange = onChange;
954
965
  }
955
966
  if (!isSubscribed && syncOptions.subscribe) {
956
- const subscribe = syncOptions.subscribe;
967
+ const subscribe2 = syncOptions.subscribe;
957
968
  isSubscribed = true;
958
969
  const doSubscribe = () => {
959
970
  const subscribeParams = {
@@ -961,17 +972,27 @@ function syncObservable(obs$, syncOptionsOrSynced) {
961
972
  value$: obs$,
962
973
  lastSync,
963
974
  update: (params) => {
964
- when(syncState$.isLoaded, () => {
965
- when(waitFor || true, () => {
966
- params.mode || (params.mode = syncOptions.mode || "merge");
967
- onChange(params);
968
- });
969
- });
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
+ );
970
991
  },
971
992
  refresh: () => when(syncState$.isLoaded, sync),
972
993
  onError: (error) => onGetError(error, { source: "subscribe", subscribeParams })
973
994
  };
974
- unsubscribe = subscribe(subscribeParams);
995
+ unsubscribe = subscribe2(subscribeParams);
975
996
  };
976
997
  if (waitFor) {
977
998
  whenReady(waitFor, doSubscribe);
@@ -980,85 +1001,87 @@ function syncObservable(obs$, syncOptionsOrSynced) {
980
1001
  }
981
1002
  }
982
1003
  const existingValue = getNodeValue(node);
983
- const onError = (error) => onGetError(error, { getParams, source: "get" });
984
- const getParams = {
985
- node,
986
- value$: obs$,
987
- value: isFunction(existingValue) || (existingValue == null ? void 0 : existingValue[symbolLinked]) ? void 0 : existingValue,
988
- mode: syncOptions.mode,
989
- refresh: sync,
990
- options: syncOptions,
991
- lastSync,
992
- updateLastSync: (lastSync2) => getParams.lastSync = lastSync2,
993
- onError,
994
- retryNum: 0,
995
- cancelRetry: false
996
- };
997
- let modeBeforeReset = void 0;
998
- const beforeGetParams = {
999
- value: getParams.value,
1000
- lastSync,
1001
- pendingChanges: pending && !isEmpty(pending) ? pending : void 0,
1002
- clearPendingChanges: async () => {
1003
- localState.pendingChanges = {};
1004
- await updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
1005
- pending: localState.pendingChanges
1006
- });
1007
- },
1008
- resetCache: () => {
1009
- var _a3;
1010
- modeBeforeReset = getParams.mode;
1011
- getParams.mode = "set";
1012
- return (_a3 = syncStateValue.resetPersistence) == null ? void 0 : _a3.call(syncStateValue);
1013
- },
1014
- cancel: false
1015
- };
1016
- (_a2 = syncOptions.onBeforeGet) == null ? void 0 : _a2.call(syncOptions, beforeGetParams);
1017
- if (!beforeGetParams.cancel) {
1018
- syncState$.assign({
1019
- numPendingGets: (syncStateValue.numPendingGets || 0) + 1,
1020
- isGetting: true
1021
- });
1022
- const got = runWithRetry(
1023
- getParams,
1024
- syncOptions.retry,
1025
- (retryEvent) => {
1026
- const params = getParams;
1027
- params.cancelRetry = retryEvent.cancelRetry;
1028
- params.retryNum = retryEvent.retryNum;
1029
- return get(params);
1030
- },
1031
- onError
1032
- );
1033
- const numGets = node.numGets = (node.numGets || 0) + 1;
1034
- const handle = (value) => {
1035
- syncState$.numPendingGets.set((v) => v - 1);
1036
- if (isWaitingForLoad) {
1037
- isWaitingForLoad = false;
1038
- syncStateValue.numPendingRemoteLoads--;
1039
- }
1040
- if (numGets >= (node.getNumResolved || 0)) {
1041
- node.getNumResolved = node.numGets;
1042
- onChange({
1043
- value,
1044
- lastSync: getParams.lastSync,
1045
- 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
1046
1028
  });
1047
- }
1048
- if (modeBeforeReset) {
1049
- getParams.mode = modeBeforeReset;
1050
- modeBeforeReset = void 0;
1051
- }
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) {
1052
1040
  syncState$.assign({
1053
- isLoaded: syncStateValue.numPendingRemoteLoads < 1,
1054
- error: void 0,
1055
- isGetting: syncStateValue.numPendingGets > 0
1041
+ numPendingGets: (syncStateValue.numPendingGets || 0) + 1,
1042
+ isGetting: true
1056
1043
  });
1057
- };
1058
- if (isPromise$1(got)) {
1059
- got.then(handle).catch(onError);
1060
- } else {
1061
- 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
+ }
1062
1085
  }
1063
1086
  }
1064
1087
  };
@@ -1130,7 +1153,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
1130
1153
  return true;
1131
1154
  };
1132
1155
  when(onAllPersistLoaded, function() {
1133
- if (syncOptions.get && syncOptions.syncMode === "auto") {
1156
+ if ((syncOptions.get || syncOptions.subscribe) && syncOptions.syncMode === "auto") {
1134
1157
  sync();
1135
1158
  }
1136
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
+ }