@legendapp/state 3.0.0-alpha.9 → 3.0.0-beta.0

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 (86) hide show
  1. package/.DS_Store +0 -0
  2. package/config/configureLegendState.d.mts +13 -0
  3. package/config/configureLegendState.d.ts +13 -0
  4. package/config/configureLegendState.js +45 -0
  5. package/config/configureLegendState.mjs +43 -0
  6. package/config/enable$GetSet.js +2 -1
  7. package/config/enable$GetSet.mjs +2 -1
  8. package/config/enableReactTracking.js +2 -1
  9. package/config/enableReactTracking.mjs +2 -1
  10. package/config/enableReactUse.js +2 -1
  11. package/config/enableReactUse.mjs +2 -1
  12. package/config/enable_PeekAssign.js +2 -1
  13. package/config/enable_PeekAssign.mjs +2 -1
  14. package/helpers/trackHistory.js +2 -2
  15. package/helpers/trackHistory.mjs +2 -2
  16. package/index.d.mts +103 -79
  17. package/index.d.ts +103 -79
  18. package/index.js +326 -316
  19. package/index.mjs +323 -314
  20. package/package.json +36 -1
  21. package/persist-plugins/async-storage.d.mts +6 -3
  22. package/persist-plugins/async-storage.d.ts +6 -3
  23. package/persist-plugins/async-storage.js +8 -4
  24. package/persist-plugins/async-storage.mjs +8 -5
  25. package/persist-plugins/indexeddb.d.mts +6 -4
  26. package/persist-plugins/indexeddb.d.ts +6 -4
  27. package/persist-plugins/indexeddb.js +35 -15
  28. package/persist-plugins/indexeddb.mjs +35 -16
  29. package/persist-plugins/mmkv.d.mts +5 -1
  30. package/persist-plugins/mmkv.d.ts +5 -1
  31. package/persist-plugins/mmkv.js +10 -5
  32. package/persist-plugins/mmkv.mjs +10 -6
  33. package/react-reactive/enableReactComponents.d.mts +9 -0
  34. package/react-reactive/enableReactComponents.d.ts +9 -0
  35. package/react-reactive/enableReactComponents.js +19 -0
  36. package/react-reactive/enableReactComponents.mjs +17 -0
  37. package/react-reactive/enableReactNativeComponents.d.mts +22 -0
  38. package/react-reactive/enableReactNativeComponents.d.ts +22 -0
  39. package/react-reactive/enableReactNativeComponents.js +53 -0
  40. package/react-reactive/enableReactNativeComponents.mjs +51 -0
  41. package/react-reactive/enableReactive.d.mts +5 -0
  42. package/react-reactive/enableReactive.d.ts +5 -0
  43. package/react-reactive/enableReactive.js +24 -0
  44. package/react-reactive/enableReactive.mjs +22 -0
  45. package/react-reactive/enableReactive.native.d.mts +5 -0
  46. package/react-reactive/enableReactive.native.d.ts +5 -0
  47. package/react-reactive/enableReactive.native.js +58 -0
  48. package/react-reactive/enableReactive.native.mjs +56 -0
  49. package/react-reactive/enableReactive.web.d.mts +5 -0
  50. package/react-reactive/enableReactive.web.d.ts +5 -0
  51. package/react-reactive/enableReactive.web.js +58 -0
  52. package/react-reactive/enableReactive.web.mjs +56 -0
  53. package/react.d.mts +39 -34
  54. package/react.d.ts +39 -34
  55. package/react.js +39 -17
  56. package/react.mjs +39 -17
  57. package/sync-plugins/crud.d.mts +21 -23
  58. package/sync-plugins/crud.d.ts +21 -23
  59. package/sync-plugins/crud.js +224 -112
  60. package/sync-plugins/crud.mjs +226 -114
  61. package/sync-plugins/fetch.js +12 -8
  62. package/sync-plugins/fetch.mjs +13 -9
  63. package/sync-plugins/firebase.d.mts +27 -0
  64. package/sync-plugins/firebase.d.ts +27 -0
  65. package/sync-plugins/firebase.js +373 -0
  66. package/sync-plugins/firebase.mjs +368 -0
  67. package/sync-plugins/keel.d.mts +43 -26
  68. package/sync-plugins/keel.d.ts +43 -26
  69. package/sync-plugins/keel.js +145 -99
  70. package/sync-plugins/keel.mjs +147 -99
  71. package/sync-plugins/supabase.d.mts +19 -9
  72. package/sync-plugins/supabase.d.ts +19 -9
  73. package/sync-plugins/supabase.js +52 -21
  74. package/sync-plugins/supabase.mjs +53 -22
  75. package/sync-plugins/tanstack-query.d.mts +2 -2
  76. package/sync-plugins/tanstack-query.d.ts +2 -2
  77. package/sync-plugins/tanstack-query.js +22 -5
  78. package/sync-plugins/tanstack-query.mjs +22 -5
  79. package/sync-plugins/tanstack-react-query.d.mts +1 -1
  80. package/sync-plugins/tanstack-react-query.d.ts +1 -1
  81. package/sync-plugins/tanstack-react-query.js +8 -1
  82. package/sync-plugins/tanstack-react-query.mjs +8 -1
  83. package/sync.d.mts +74 -200
  84. package/sync.d.ts +74 -200
  85. package/sync.js +495 -281
  86. package/sync.mjs +500 -286
@@ -1,4 +1,4 @@
1
- import { observable, computeSelector, isObject, symbolDelete } from '@legendapp/state';
1
+ import { observable, computeSelector, isFunction, isObject, symbolDelete } from '@legendapp/state';
2
2
  import { removeNullUndefined, transformStringifyDates, combineTransforms } from '@legendapp/state/sync';
3
3
  import { syncedCrud } from '@legendapp/state/sync-plugins/crud';
4
4
 
@@ -16,12 +16,22 @@ function configureSyncedSupabase(config) {
16
16
  }
17
17
  Object.assign(supabaseConfig, removeNullUndefined(rest));
18
18
  }
19
+ function wrapSupabaseFn(fn) {
20
+ return async (...args) => {
21
+ const { data, error } = await fn(...args);
22
+ if (error) {
23
+ throw new Error(error.message);
24
+ }
25
+ return data;
26
+ };
27
+ }
19
28
  function syncedSupabase(props) {
20
29
  props = { ...supabaseConfig, ...props };
21
30
  const {
22
- supabase: client,
31
+ supabase,
23
32
  collection,
24
33
  select: selectFn,
34
+ schema,
25
35
  filter,
26
36
  actions,
27
37
  fieldCreatedAt: fieldCreatedAtParam,
@@ -34,14 +44,21 @@ function syncedSupabase(props) {
34
44
  waitFor,
35
45
  waitForSet,
36
46
  generateId,
47
+ mode,
48
+ list: listParam,
49
+ create: createParam,
50
+ update: updateParam,
51
+ delete: deleteParam,
37
52
  ...rest
38
53
  } = props;
54
+ const client = supabase;
39
55
  const fieldCreatedAt = fieldCreatedAtParam || (changesSince === "last-sync" ? "created_at" : void 0);
40
56
  const fieldUpdatedAt = fieldUpdatedAtParam || (changesSince === "last-sync" ? "updated_at" : void 0);
41
57
  const fieldDeleted = fieldDeletedParam || (changesSince === "last-sync" ? "deleted" : void 0);
42
- const list = !actions || actions.includes("read") ? async (params) => {
58
+ const list = !actions || actions.includes("read") ? listParam ? wrapSupabaseFn(listParam) : async (params) => {
43
59
  const { lastSync } = params;
44
- const from = client.from(collection);
60
+ const clientSchema = schema ? client.schema(schema) : client;
61
+ const from = clientSchema.from(collection);
45
62
  let select = selectFn ? selectFn(from) : from.select();
46
63
  if (changesSince === "last-sync" && lastSync) {
47
64
  const date = new Date(lastSync).toISOString();
@@ -56,8 +73,8 @@ function syncedSupabase(props) {
56
73
  }
57
74
  return data || [];
58
75
  } : void 0;
59
- const upsert = async (input) => {
60
- const res = await client.from(collection).upsert(input).select();
76
+ const create = createParam ? wrapSupabaseFn(createParam) : !actions || actions.includes("create") ? async (input) => {
77
+ const res = await client.from(collection).insert(input).select();
61
78
  const { data, error } = res;
62
79
  if (data) {
63
80
  const created = data[0];
@@ -65,10 +82,18 @@ function syncedSupabase(props) {
65
82
  } else {
66
83
  throw new Error(error == null ? void 0 : error.message);
67
84
  }
68
- };
69
- const create = !actions || actions.includes("create") ? upsert : void 0;
70
- const update = !actions || actions.includes("update") ? upsert : void 0;
71
- const deleteFn = !fieldDeleted && (!actions || actions.includes("delete")) ? async (input) => {
85
+ } : void 0;
86
+ const update = !actions || actions.includes("update") ? updateParam ? wrapSupabaseFn(updateParam) : async (input) => {
87
+ const res = await client.from(collection).update(input).eq("id", input.id).select();
88
+ const { data, error } = res;
89
+ if (data) {
90
+ const created = data[0];
91
+ return created;
92
+ } else {
93
+ throw new Error(error == null ? void 0 : error.message);
94
+ }
95
+ } : void 0;
96
+ const deleteFn = !fieldDeleted && (!actions || actions.includes("delete")) ? deleteParam ? wrapSupabaseFn(deleteParam) : async (input) => {
72
97
  const id = input.id;
73
98
  const res = await client.from(collection).delete().eq("id", id).select();
74
99
  const { data, error } = res;
@@ -80,13 +105,13 @@ function syncedSupabase(props) {
80
105
  }
81
106
  } : void 0;
82
107
  const subscribe = realtime ? ({ node, value$, update: update2 }) => {
83
- const { filter: filter2, schema } = isObject(realtime) ? realtime : {};
108
+ const { filter: filter2, schema: schema2 } = isObject(realtime) ? realtime : {};
84
109
  const channel = client.channel(`LS_${node.key || ""}${channelNum++}`).on(
85
110
  "postgres_changes",
86
111
  {
87
112
  event: "*",
88
113
  table: collection,
89
- schema: schema || "public",
114
+ schema: schema2 || "public",
90
115
  filter: filter2 || void 0
91
116
  },
92
117
  (payload) => {
@@ -94,25 +119,30 @@ function syncedSupabase(props) {
94
119
  const { eventType, new: value, old } = payload;
95
120
  if (eventType === "INSERT" || eventType === "UPDATE") {
96
121
  const cur = (_a = value$.peek()) == null ? void 0 : _a[value.id];
97
- const curDateStr = cur && (fieldUpdatedAt && cur[fieldUpdatedAt] || fieldCreatedAt || cur[fieldCreatedAt]);
98
- const valueDateStr = fieldUpdatedAt && value[fieldUpdatedAt] || fieldCreatedAt && value[fieldCreatedAt];
99
- const valueDate = +new Date(valueDateStr);
100
- if (valueDateStr && (!curDateStr || valueDate > +new Date(curDateStr))) {
122
+ let isOk = !fieldUpdatedAt;
123
+ let lastSync = void 0;
124
+ if (!isOk) {
125
+ const curDateStr = cur && (fieldUpdatedAt && cur[fieldUpdatedAt] || fieldCreatedAt || cur[fieldCreatedAt]);
126
+ const valueDateStr = fieldUpdatedAt && value[fieldUpdatedAt] || fieldCreatedAt && value[fieldCreatedAt];
127
+ lastSync = +new Date(valueDateStr);
128
+ isOk = valueDateStr && (!curDateStr || lastSync > +new Date(curDateStr));
129
+ }
130
+ if (isOk) {
101
131
  update2({
102
- value: { [value.id]: value },
103
- lastSync: valueDate,
132
+ value: [value],
133
+ lastSync,
104
134
  mode: "merge"
105
135
  });
106
136
  }
107
137
  } else if (eventType === "DELETE") {
108
- const { id } = old;
138
+ old[symbolDelete] = true;
109
139
  update2({
110
- value: { [id]: symbolDelete }
140
+ value: [old]
111
141
  });
112
142
  }
113
143
  }
114
144
  ).subscribe();
115
- return channel.unsubscribe;
145
+ return () => channel.unsubscribe();
116
146
  } : void 0;
117
147
  let transform = transformParam;
118
148
  if (stringifyDates) {
@@ -121,6 +151,7 @@ function syncedSupabase(props) {
121
151
  }
122
152
  return syncedCrud({
123
153
  ...rest,
154
+ mode: mode || "merge",
124
155
  list,
125
156
  create,
126
157
  update,
@@ -133,7 +164,7 @@ function syncedSupabase(props) {
133
164
  transform,
134
165
  generateId,
135
166
  waitFor: () => isEnabled$.get() && (waitFor ? computeSelector(waitFor) : true),
136
- waitForSet
167
+ waitForSet: (params) => isEnabled$.get() && (waitForSet ? isFunction(waitForSet) ? waitForSet(params) : waitForSet : true)
137
168
  });
138
169
  }
139
170
 
@@ -4,11 +4,11 @@ import { QueryKey, QueryObserverOptions, QueryClient, MutationObserverOptions, D
4
4
  interface ObservableQueryOptions<TQueryFnData, TError, TData, TQueryKey extends QueryKey> extends Omit<QueryObserverOptions<TQueryFnData, TError, TData, TQueryKey>, 'queryKey'> {
5
5
  queryKey?: TQueryKey | (() => TQueryKey);
6
6
  }
7
- interface SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey extends QueryKey> extends SyncedOptions<TData> {
7
+ interface SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey extends QueryKey> extends Omit<SyncedOptions<TData>, 'get' | 'set'> {
8
8
  queryClient: QueryClient;
9
9
  query: ObservableQueryOptions<TQueryFnData, TError, TData, TQueryKey>;
10
10
  mutation?: MutationObserverOptions<TData, TError, void>;
11
11
  }
12
- declare function syncedQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(params: SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey>): NonNullable<TData>;
12
+ declare function syncedQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(params: SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey>): TData;
13
13
 
14
14
  export { type ObservableQueryOptions, type SyncedQueryParams, syncedQuery };
@@ -4,11 +4,11 @@ import { QueryKey, QueryObserverOptions, QueryClient, MutationObserverOptions, D
4
4
  interface ObservableQueryOptions<TQueryFnData, TError, TData, TQueryKey extends QueryKey> extends Omit<QueryObserverOptions<TQueryFnData, TError, TData, TQueryKey>, 'queryKey'> {
5
5
  queryKey?: TQueryKey | (() => TQueryKey);
6
6
  }
7
- interface SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey extends QueryKey> extends SyncedOptions<TData> {
7
+ interface SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey extends QueryKey> extends Omit<SyncedOptions<TData>, 'get' | 'set'> {
8
8
  queryClient: QueryClient;
9
9
  query: ObservableQueryOptions<TQueryFnData, TError, TData, TQueryKey>;
10
10
  mutation?: MutationObserverOptions<TData, TError, void>;
11
11
  }
12
- declare function syncedQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(params: SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey>): NonNullable<TData>;
12
+ declare function syncedQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(params: SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey>): TData;
13
13
 
14
14
  export { type ObservableQueryOptions, type SyncedQueryParams, syncedQuery };
@@ -6,7 +6,7 @@ var queryCore = require('@tanstack/query-core');
6
6
 
7
7
  // src/sync-plugins/tanstack-query.ts
8
8
  function syncedQuery(params) {
9
- const { query: options, mutation: mutationOptions, queryClient } = params;
9
+ const { query: options, mutation: mutationOptions, queryClient, ...rest } = params;
10
10
  const Observer = queryCore.QueryObserver;
11
11
  const defaultedOptions = queryClient.defaultQueryOptions(
12
12
  options
@@ -14,6 +14,7 @@ function syncedQuery(params) {
14
14
  let observer = void 0;
15
15
  let latestOptions = defaultedOptions;
16
16
  let queryKeyFromFn;
17
+ let resolveInitialPromise = void 0;
17
18
  const origQueryKey = options.queryKey;
18
19
  const isKeyFunction = state.isFunction(origQueryKey);
19
20
  const updateQueryOptions = (obj) => {
@@ -33,14 +34,29 @@ function syncedQuery(params) {
33
34
  });
34
35
  }
35
36
  observer = new Observer(queryClient, latestOptions);
36
- const get = () => {
37
- const result = observer.getOptimisticResult(latestOptions);
38
- return result.data;
37
+ let isFirstRun = true;
38
+ const get = async () => {
39
+ if (isFirstRun) {
40
+ isFirstRun = false;
41
+ const result = observer.getOptimisticResult(latestOptions);
42
+ if (result.isLoading) {
43
+ await new Promise((resolve) => {
44
+ resolveInitialPromise = resolve;
45
+ });
46
+ }
47
+ return result.data;
48
+ } else {
49
+ observer.refetch();
50
+ }
39
51
  };
40
52
  const subscribe = ({ update }) => {
41
53
  const unsubscribe = observer.subscribe(
42
54
  queryCore.notifyManager.batchCalls((result) => {
43
55
  if (result.status === "success") {
56
+ if (resolveInitialPromise) {
57
+ resolveInitialPromise(result.data);
58
+ resolveInitialPromise = void 0;
59
+ }
44
60
  update({ value: result.data });
45
61
  }
46
62
  })
@@ -58,7 +74,8 @@ function syncedQuery(params) {
58
74
  return sync.synced({
59
75
  get,
60
76
  set,
61
- subscribe
77
+ subscribe,
78
+ ...rest
62
79
  });
63
80
  }
64
81
 
@@ -4,7 +4,7 @@ import { MutationObserver, QueryObserver, notifyManager } from '@tanstack/query-
4
4
 
5
5
  // src/sync-plugins/tanstack-query.ts
6
6
  function syncedQuery(params) {
7
- const { query: options, mutation: mutationOptions, queryClient } = params;
7
+ const { query: options, mutation: mutationOptions, queryClient, ...rest } = params;
8
8
  const Observer = QueryObserver;
9
9
  const defaultedOptions = queryClient.defaultQueryOptions(
10
10
  options
@@ -12,6 +12,7 @@ function syncedQuery(params) {
12
12
  let observer = void 0;
13
13
  let latestOptions = defaultedOptions;
14
14
  let queryKeyFromFn;
15
+ let resolveInitialPromise = void 0;
15
16
  const origQueryKey = options.queryKey;
16
17
  const isKeyFunction = isFunction(origQueryKey);
17
18
  const updateQueryOptions = (obj) => {
@@ -31,14 +32,29 @@ function syncedQuery(params) {
31
32
  });
32
33
  }
33
34
  observer = new Observer(queryClient, latestOptions);
34
- const get = () => {
35
- const result = observer.getOptimisticResult(latestOptions);
36
- return result.data;
35
+ let isFirstRun = true;
36
+ const get = async () => {
37
+ if (isFirstRun) {
38
+ isFirstRun = false;
39
+ const result = observer.getOptimisticResult(latestOptions);
40
+ if (result.isLoading) {
41
+ await new Promise((resolve) => {
42
+ resolveInitialPromise = resolve;
43
+ });
44
+ }
45
+ return result.data;
46
+ } else {
47
+ observer.refetch();
48
+ }
37
49
  };
38
50
  const subscribe = ({ update }) => {
39
51
  const unsubscribe = observer.subscribe(
40
52
  notifyManager.batchCalls((result) => {
41
53
  if (result.status === "success") {
54
+ if (resolveInitialPromise) {
55
+ resolveInitialPromise(result.data);
56
+ resolveInitialPromise = void 0;
57
+ }
42
58
  update({ value: result.data });
43
59
  }
44
60
  })
@@ -56,7 +72,8 @@ function syncedQuery(params) {
56
72
  return synced({
57
73
  get,
58
74
  set,
59
- subscribe
75
+ subscribe,
76
+ ...rest
60
77
  });
61
78
  }
62
79
 
@@ -3,6 +3,6 @@ import { DefaultError, QueryKey } 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<NonNullable<Synced<TData>>>;
6
+ declare function useObservableSyncedQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(params: SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey>): Observable<Synced<TData>>;
7
7
 
8
8
  export { useObservableSyncedQuery };
@@ -3,6 +3,6 @@ import { DefaultError, QueryKey } 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<NonNullable<Synced<TData>>>;
6
+ declare function useObservableSyncedQuery<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(params: SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey>): Observable<Synced<TData>>;
7
7
 
8
8
  export { useObservableSyncedQuery };
@@ -2,10 +2,17 @@
2
2
 
3
3
  var react = require('@legendapp/state/react');
4
4
  var tanstackQuery = require('@legendapp/state/sync-plugins/tanstack-query');
5
+ var reactQuery = require('@tanstack/react-query');
5
6
 
6
7
  // src/sync-plugins/tanstack-react-query.ts
7
8
  function useObservableSyncedQuery(params) {
8
- return react.useObservable(tanstackQuery.syncedQuery(params));
9
+ const queryClient = params.queryClient || reactQuery.useQueryClient();
10
+ return react.useObservable(
11
+ tanstackQuery.syncedQuery({
12
+ ...params,
13
+ queryClient
14
+ })
15
+ );
9
16
  }
10
17
 
11
18
  exports.useObservableSyncedQuery = useObservableSyncedQuery;
@@ -1,9 +1,16 @@
1
1
  import { useObservable } from '@legendapp/state/react';
2
2
  import { syncedQuery } from '@legendapp/state/sync-plugins/tanstack-query';
3
+ import { useQueryClient } from '@tanstack/react-query';
3
4
 
4
5
  // src/sync-plugins/tanstack-react-query.ts
5
6
  function useObservableSyncedQuery(params) {
6
- return useObservable(syncedQuery(params));
7
+ const queryClient = params.queryClient || useQueryClient();
8
+ return useObservable(
9
+ syncedQuery({
10
+ ...params,
11
+ queryClient
12
+ })
13
+ );
7
14
  }
8
15
 
9
16
  export { useObservableSyncedQuery };