@legendapp/state 3.0.0-alpha.3 → 3.0.0-alpha.30
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.
- package/CHANGELOG.md +831 -1
- package/LICENSE +21 -1
- package/README.md +141 -1
- package/babel.js +0 -2
- package/babel.mjs +0 -2
- package/config/enable$GetSet.js +2 -1
- package/config/enable$GetSet.mjs +2 -1
- package/config/enableReactTracking.js +2 -1
- package/config/enableReactTracking.mjs +2 -1
- package/config/enableReactUse.js +2 -1
- package/config/enableReactUse.mjs +2 -1
- package/config/enable_PeekAssign.js +2 -1
- package/config/enable_PeekAssign.mjs +2 -1
- package/config.d.mts +13 -0
- package/config.d.ts +13 -0
- package/config.js +2052 -0
- package/config.mjs +2050 -0
- package/helpers/trackHistory.js +2 -2
- package/helpers/trackHistory.mjs +2 -2
- package/index.d.mts +21 -302
- package/index.d.ts +21 -302
- package/index.js +274 -318
- package/index.mjs +275 -317
- package/observableInterfaces-Dilj6F92.d.mts +282 -0
- package/observableInterfaces-Dilj6F92.d.ts +282 -0
- package/package.json +11 -1
- package/persist-plugins/async-storage.d.mts +6 -3
- package/persist-plugins/async-storage.d.ts +6 -3
- package/persist-plugins/async-storage.js +12 -4
- package/persist-plugins/async-storage.mjs +12 -5
- package/persist-plugins/indexeddb.d.mts +6 -4
- package/persist-plugins/indexeddb.d.ts +6 -4
- package/persist-plugins/indexeddb.js +16 -6
- package/persist-plugins/indexeddb.mjs +16 -7
- package/persist-plugins/mmkv.d.mts +5 -1
- package/persist-plugins/mmkv.d.ts +5 -1
- package/persist-plugins/mmkv.js +14 -5
- package/persist-plugins/mmkv.mjs +14 -6
- package/react.d.mts +18 -14
- package/react.d.ts +18 -14
- package/react.js +57 -32
- package/react.mjs +58 -33
- package/sync-plugins/_transformObjectFields.d.mts +31 -0
- package/sync-plugins/_transformObjectFields.d.ts +31 -0
- package/sync-plugins/_transformObjectFields.js +114 -0
- package/sync-plugins/_transformObjectFields.mjs +110 -0
- package/sync-plugins/crud.d.mts +15 -23
- package/sync-plugins/crud.d.ts +15 -23
- package/sync-plugins/crud.js +213 -134
- package/sync-plugins/crud.mjs +214 -135
- package/sync-plugins/fetch.js +12 -8
- package/sync-plugins/fetch.mjs +13 -9
- package/sync-plugins/firebase.d.mts +26 -0
- package/sync-plugins/firebase.d.ts +26 -0
- package/sync-plugins/firebase.js +373 -0
- package/sync-plugins/firebase.mjs +368 -0
- package/sync-plugins/keel.d.mts +27 -10
- package/sync-plugins/keel.d.ts +27 -10
- package/sync-plugins/keel.js +40 -21
- package/sync-plugins/keel.mjs +40 -21
- package/sync-plugins/supabase.d.mts +12 -7
- package/sync-plugins/supabase.d.ts +12 -7
- package/sync-plugins/supabase.js +24 -13
- package/sync-plugins/supabase.mjs +25 -14
- package/sync-plugins/tanstack-query.d.mts +2 -2
- package/sync-plugins/tanstack-query.d.ts +2 -2
- package/sync-plugins/tanstack-query.js +3 -2
- package/sync-plugins/tanstack-query.mjs +3 -2
- package/sync-plugins/tanstack-react-query.d.mts +1 -1
- package/sync-plugins/tanstack-react-query.d.ts +1 -1
- package/sync.d.mts +68 -197
- package/sync.d.ts +68 -197
- package/sync.js +448 -283
- package/sync.mjs +454 -289
- package/types/babel.d.ts +12 -1
- package/.DS_Store +0 -0
- /package/config/{enable_GetSet.d.mts → enable$GetSet.d.mts} +0 -0
- /package/config/{enable_GetSet.d.ts → enable$GetSet.d.ts} +0 -0
package/sync-plugins/keel.mjs
CHANGED
|
@@ -14,6 +14,9 @@ var modifiedClients = /* @__PURE__ */ new WeakSet();
|
|
|
14
14
|
var isEnabled$ = observable(true);
|
|
15
15
|
async function ensureAuthToken() {
|
|
16
16
|
await when(isEnabled$.get());
|
|
17
|
+
if (keelConfig.refreshAuth) {
|
|
18
|
+
await keelConfig.refreshAuth();
|
|
19
|
+
}
|
|
17
20
|
let isAuthed = await keelConfig.client.auth.isAuthenticated();
|
|
18
21
|
if (!isAuthed) {
|
|
19
22
|
isAuthed = await keelConfig.client.auth.refresh();
|
|
@@ -59,9 +62,9 @@ function configureSyncedKeel(config) {
|
|
|
59
62
|
const oldFn = queries[key];
|
|
60
63
|
queries[key] = (i) => {
|
|
61
64
|
const realtimeKey = [key, ...Object.values(i.where || {})].filter((value) => value && typeof value !== "object").join("/");
|
|
62
|
-
const subscribe = (
|
|
65
|
+
const subscribe = (params) => {
|
|
63
66
|
if (realtimeKey) {
|
|
64
|
-
return realtimePlugin.subscribe(realtimeKey,
|
|
67
|
+
return realtimePlugin.subscribe(realtimeKey, params);
|
|
65
68
|
}
|
|
66
69
|
};
|
|
67
70
|
return oldFn(i).then((ret) => {
|
|
@@ -122,7 +125,9 @@ function syncedKeel(props) {
|
|
|
122
125
|
first,
|
|
123
126
|
where: whereParam,
|
|
124
127
|
waitFor,
|
|
128
|
+
waitForSet,
|
|
125
129
|
fieldDeleted,
|
|
130
|
+
mode,
|
|
126
131
|
...rest
|
|
127
132
|
} = props;
|
|
128
133
|
const { changesSince } = props;
|
|
@@ -131,8 +136,15 @@ function syncedKeel(props) {
|
|
|
131
136
|
const subscribeFnKey$ = observable("");
|
|
132
137
|
const fieldCreatedAt = "createdAt";
|
|
133
138
|
const fieldUpdatedAt = "updatedAt";
|
|
139
|
+
const setupSubscribe = (doSubscribe, subscribeKey, lastSync) => {
|
|
140
|
+
subscribeFn = doSubscribe;
|
|
141
|
+
subscribeFnKey$.set(subscribeKey);
|
|
142
|
+
if (realtimePlugin && lastSync) {
|
|
143
|
+
realtimePlugin.setLatestChange(subscribeKey, new Date(lastSync));
|
|
144
|
+
}
|
|
145
|
+
};
|
|
134
146
|
const list = listParam ? async (listParams) => {
|
|
135
|
-
const { lastSync
|
|
147
|
+
const { lastSync } = listParams;
|
|
136
148
|
const queryBySync = !!lastSync && changesSince === "last-sync";
|
|
137
149
|
const where = Object.assign(
|
|
138
150
|
queryBySync ? { updatedAt: { after: new Date(lastSync + 1) } } : {},
|
|
@@ -141,8 +153,7 @@ function syncedKeel(props) {
|
|
|
141
153
|
const params = { where, first };
|
|
142
154
|
const { results, subscribe: subscribe2, subscribeKey } = await getAllPages(listParam, params);
|
|
143
155
|
if (subscribe2) {
|
|
144
|
-
|
|
145
|
-
subscribeFnKey$.set(subscribeKey);
|
|
156
|
+
setupSubscribe(() => subscribe2(listParams), subscribeKey, lastSync);
|
|
146
157
|
}
|
|
147
158
|
return results;
|
|
148
159
|
} : void 0;
|
|
@@ -150,8 +161,7 @@ function syncedKeel(props) {
|
|
|
150
161
|
const { refresh } = getParams;
|
|
151
162
|
const { data, error, subscribe: subscribe2, subscribeKey } = await getParam({ refresh });
|
|
152
163
|
if (subscribe2) {
|
|
153
|
-
|
|
154
|
-
subscribeFnKey$.set(subscribeKey);
|
|
164
|
+
setupSubscribe(() => subscribe2(getParams), subscribeKey);
|
|
155
165
|
}
|
|
156
166
|
if (error) {
|
|
157
167
|
throw new Error(error.message);
|
|
@@ -170,32 +180,40 @@ function syncedKeel(props) {
|
|
|
170
180
|
}
|
|
171
181
|
}
|
|
172
182
|
};
|
|
173
|
-
const handleSetError = async (error, params,
|
|
183
|
+
const handleSetError = async (error, params, input, fn, from) => {
|
|
174
184
|
var _a, _b, _c;
|
|
175
|
-
const { retryNum,
|
|
176
|
-
if (
|
|
185
|
+
const { retryNum, update: update2 } = params;
|
|
186
|
+
if (from === "create" && ((_a = error.message) == null ? void 0 : _a.includes("for the unique")) && ((_b = error.message) == null ? void 0 : _b.includes("must be unique"))) {
|
|
177
187
|
if (__DEV__) {
|
|
178
188
|
console.log("Creating duplicate data already saved, just ignore.");
|
|
179
189
|
}
|
|
190
|
+
params.cancelRetry = true;
|
|
180
191
|
update2({
|
|
181
192
|
value: {},
|
|
182
193
|
mode: "assign"
|
|
183
194
|
});
|
|
195
|
+
} else if (from === "delete") {
|
|
196
|
+
if (error.message === "record not found") {
|
|
197
|
+
if (__DEV__) {
|
|
198
|
+
console.log("Deleting non-existing data, just ignore.");
|
|
199
|
+
}
|
|
200
|
+
params.cancelRetry = true;
|
|
201
|
+
}
|
|
184
202
|
} else if (error.type === "bad_request") {
|
|
185
|
-
(_c = keelConfig.onError) == null ? void 0 : _c.call(keelConfig, error);
|
|
203
|
+
(_c = keelConfig.onError) == null ? void 0 : _c.call(keelConfig, { error, params, input, type: from, action: fn.name || fn.toString() });
|
|
186
204
|
if (retryNum > 4) {
|
|
187
|
-
cancelRetry
|
|
205
|
+
params.cancelRetry = true;
|
|
188
206
|
}
|
|
189
|
-
throw new Error(error.message);
|
|
207
|
+
throw new Error(error.message, { cause: { input } });
|
|
190
208
|
} else {
|
|
191
209
|
await handleApiError(error);
|
|
192
|
-
throw new Error(error.message);
|
|
210
|
+
throw new Error(error.message, { cause: { input } });
|
|
193
211
|
}
|
|
194
212
|
};
|
|
195
213
|
const create = createParam ? async (input, params) => {
|
|
196
214
|
const { data, error } = await createParam(convertObjectToCreate(input));
|
|
197
215
|
if (error) {
|
|
198
|
-
handleSetError(error, params,
|
|
216
|
+
await handleSetError(error, params, input, createParam, "create");
|
|
199
217
|
}
|
|
200
218
|
return data;
|
|
201
219
|
} : void 0;
|
|
@@ -208,15 +226,15 @@ function syncedKeel(props) {
|
|
|
208
226
|
if (!isEmpty(values)) {
|
|
209
227
|
const { data, error } = await updateParam({ where: { id }, values });
|
|
210
228
|
if (error) {
|
|
211
|
-
handleSetError(error, params,
|
|
229
|
+
await handleSetError(error, params, input, updateParam, "update");
|
|
212
230
|
}
|
|
213
231
|
return data;
|
|
214
232
|
}
|
|
215
233
|
} : void 0;
|
|
216
|
-
const deleteFn = deleteParam ? async (
|
|
217
|
-
const { data, error } = await deleteParam({ id });
|
|
234
|
+
const deleteFn = deleteParam ? async (value, params) => {
|
|
235
|
+
const { data, error } = await deleteParam({ id: value.id });
|
|
218
236
|
if (error) {
|
|
219
|
-
handleSetError(error, params,
|
|
237
|
+
await handleSetError(error, params, value, deleteParam, "delete");
|
|
220
238
|
}
|
|
221
239
|
return data;
|
|
222
240
|
} : void 0;
|
|
@@ -232,16 +250,17 @@ function syncedKeel(props) {
|
|
|
232
250
|
return syncedCrud({
|
|
233
251
|
...rest,
|
|
234
252
|
as: asType,
|
|
253
|
+
mode: mode || "merge",
|
|
235
254
|
list,
|
|
236
255
|
create,
|
|
237
256
|
update,
|
|
238
257
|
delete: deleteFn,
|
|
239
258
|
waitFor: () => isEnabled$.get() && (waitFor ? computeSelector(waitFor) : true),
|
|
259
|
+
waitForSet: (params) => isEnabled$.get() && (waitForSet ? isFunction(waitForSet) ? waitForSet(params) : waitForSet : true),
|
|
240
260
|
onSaved,
|
|
241
|
-
onSavedUpdate: "createdUpdatedAt",
|
|
242
261
|
fieldCreatedAt,
|
|
243
262
|
fieldUpdatedAt,
|
|
244
|
-
fieldDeleted
|
|
263
|
+
fieldDeleted,
|
|
245
264
|
changesSince,
|
|
246
265
|
updatePartial: true,
|
|
247
266
|
subscribe,
|
|
@@ -4,10 +4,14 @@ import { SyncedCrudPropsBase, CrudAsOption, SyncedCrudReturnType, SyncedCrudProp
|
|
|
4
4
|
import { PostgrestQueryBuilder, PostgrestFilterBuilder } from '@supabase/postgrest-js';
|
|
5
5
|
import { SupabaseClient } from '@supabase/supabase-js';
|
|
6
6
|
|
|
7
|
+
type DatabaseOf<Client extends SupabaseClient> = Client extends SupabaseClient<infer TDB> ? TDB : never;
|
|
8
|
+
type SchemaNameOf<Client extends SupabaseClient> = keyof DatabaseOf<Client>;
|
|
9
|
+
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
10
|
+
type IsUnionOfStrings<T> = [T] extends [string] ? ([T] extends [UnionToIntersection<T>] ? false : true) : false;
|
|
7
11
|
type SupabaseSchemaOf<Client extends SupabaseClient> = Client extends SupabaseClient<infer _, infer __, infer Schema> ? Schema : never;
|
|
8
|
-
type SupabaseTableOf<Client extends SupabaseClient
|
|
9
|
-
type SupabaseCollectionOf<Client extends SupabaseClient
|
|
10
|
-
type SupabaseRowOf<Client extends SupabaseClient, Collection extends SupabaseCollectionOf<Client>> = SupabaseTableOf<Client>[Collection]['Row'];
|
|
12
|
+
type SupabaseTableOf<Client extends SupabaseClient, SchemaName extends SchemaNameOf<Client>> = DatabaseOf<Client>[SchemaName]['Tables'];
|
|
13
|
+
type SupabaseCollectionOf<Client extends SupabaseClient, SchemaName extends SchemaNameOf<Client>> = keyof SupabaseTableOf<Client, IsUnionOfStrings<SchemaName> extends true ? 'public' : SchemaName>;
|
|
14
|
+
type SupabaseRowOf<Client extends SupabaseClient, Collection extends SupabaseCollectionOf<Client, SchemaName>, SchemaName extends SchemaNameOf<Client>> = SupabaseTableOf<Client, SchemaName>[Collection]['Row'];
|
|
11
15
|
type SyncedSupabaseConfig<TRemote extends {
|
|
12
16
|
id: string | number;
|
|
13
17
|
}, TLocal> = Omit<SyncedCrudPropsBase<TRemote, TLocal>, 'create' | 'update' | 'delete'>;
|
|
@@ -20,11 +24,12 @@ interface SyncedSupabaseConfiguration extends Omit<SyncedSupabaseConfig<{
|
|
|
20
24
|
enabled?: Observable<boolean>;
|
|
21
25
|
as?: Exclude<CrudAsOption, 'value'>;
|
|
22
26
|
}
|
|
23
|
-
interface SyncedSupabaseProps<Client extends SupabaseClient, Collection extends SupabaseCollectionOf<Client>, TOption extends CrudAsOption = 'object', TRemote extends SupabaseRowOf<Client, Collection> = SupabaseRowOf<Client, Collection>, TLocal = TRemote> extends SyncedSupabaseConfig<TRemote, TLocal>, SyncedCrudPropsMany<TRemote, TRemote, TOption> {
|
|
27
|
+
interface SyncedSupabaseProps<Client extends SupabaseClient<any, any>, Collection extends SupabaseCollectionOf<Client, SchemaName>, SchemaName extends SchemaNameOf<Client>, TOption extends CrudAsOption = 'object', TRemote extends SupabaseRowOf<Client, Collection, SchemaName> = SupabaseRowOf<Client, Collection, SchemaName>, TLocal = TRemote> extends SyncedSupabaseConfig<TRemote, TLocal>, SyncedCrudPropsMany<TRemote, TRemote, TOption> {
|
|
24
28
|
supabase: Client;
|
|
25
29
|
collection: Collection;
|
|
26
|
-
|
|
27
|
-
|
|
30
|
+
schema?: SchemaName;
|
|
31
|
+
select?: (query: PostgrestQueryBuilder<SupabaseSchemaOf<Client>, SupabaseTableOf<Client, SchemaName>[Collection], Collection>) => PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>;
|
|
32
|
+
filter?: (select: PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>, params: SyncedGetParams<TRemote>) => PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>;
|
|
28
33
|
actions?: ('create' | 'read' | 'update' | 'delete')[];
|
|
29
34
|
realtime?: boolean | {
|
|
30
35
|
schema?: string;
|
|
@@ -34,6 +39,6 @@ interface SyncedSupabaseProps<Client extends SupabaseClient, Collection extends
|
|
|
34
39
|
}
|
|
35
40
|
declare function getSyncedSupabaseConfiguration(): SyncedSupabaseConfiguration;
|
|
36
41
|
declare function configureSyncedSupabase(config: SyncedSupabaseConfiguration): void;
|
|
37
|
-
declare function syncedSupabase<Client extends SupabaseClient, Collection extends SupabaseCollectionOf<Client> & string, AsOption extends CrudAsOption = 'object', TRemote extends SupabaseRowOf<Client, Collection> = SupabaseRowOf<Client, Collection>, TLocal = TRemote>(props: SyncedSupabaseProps<Client, Collection, AsOption, TRemote, TLocal>): SyncedCrudReturnType<TLocal, AsOption>;
|
|
42
|
+
declare function syncedSupabase<Client extends SupabaseClient<any, any>, Collection extends SupabaseCollectionOf<Client, SchemaName> & string, SchemaName extends SchemaNameOf<Client>, AsOption extends CrudAsOption = 'object', TRemote extends SupabaseRowOf<Client, Collection, SchemaName> = SupabaseRowOf<Client, Collection, SchemaName>, TLocal = TRemote>(props: SyncedSupabaseProps<Client, Collection, SchemaName, AsOption, TRemote, TLocal>): SyncedCrudReturnType<TLocal, AsOption>;
|
|
38
43
|
|
|
39
44
|
export { type SupabaseCollectionOf, type SupabaseRowOf, type SupabaseSchemaOf, type SupabaseTableOf, type SyncedSupabaseConfig, type SyncedSupabaseConfiguration, configureSyncedSupabase, getSyncedSupabaseConfiguration, syncedSupabase };
|
|
@@ -4,10 +4,14 @@ import { SyncedCrudPropsBase, CrudAsOption, SyncedCrudReturnType, SyncedCrudProp
|
|
|
4
4
|
import { PostgrestQueryBuilder, PostgrestFilterBuilder } from '@supabase/postgrest-js';
|
|
5
5
|
import { SupabaseClient } from '@supabase/supabase-js';
|
|
6
6
|
|
|
7
|
+
type DatabaseOf<Client extends SupabaseClient> = Client extends SupabaseClient<infer TDB> ? TDB : never;
|
|
8
|
+
type SchemaNameOf<Client extends SupabaseClient> = keyof DatabaseOf<Client>;
|
|
9
|
+
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
10
|
+
type IsUnionOfStrings<T> = [T] extends [string] ? ([T] extends [UnionToIntersection<T>] ? false : true) : false;
|
|
7
11
|
type SupabaseSchemaOf<Client extends SupabaseClient> = Client extends SupabaseClient<infer _, infer __, infer Schema> ? Schema : never;
|
|
8
|
-
type SupabaseTableOf<Client extends SupabaseClient
|
|
9
|
-
type SupabaseCollectionOf<Client extends SupabaseClient
|
|
10
|
-
type SupabaseRowOf<Client extends SupabaseClient, Collection extends SupabaseCollectionOf<Client>> = SupabaseTableOf<Client>[Collection]['Row'];
|
|
12
|
+
type SupabaseTableOf<Client extends SupabaseClient, SchemaName extends SchemaNameOf<Client>> = DatabaseOf<Client>[SchemaName]['Tables'];
|
|
13
|
+
type SupabaseCollectionOf<Client extends SupabaseClient, SchemaName extends SchemaNameOf<Client>> = keyof SupabaseTableOf<Client, IsUnionOfStrings<SchemaName> extends true ? 'public' : SchemaName>;
|
|
14
|
+
type SupabaseRowOf<Client extends SupabaseClient, Collection extends SupabaseCollectionOf<Client, SchemaName>, SchemaName extends SchemaNameOf<Client>> = SupabaseTableOf<Client, SchemaName>[Collection]['Row'];
|
|
11
15
|
type SyncedSupabaseConfig<TRemote extends {
|
|
12
16
|
id: string | number;
|
|
13
17
|
}, TLocal> = Omit<SyncedCrudPropsBase<TRemote, TLocal>, 'create' | 'update' | 'delete'>;
|
|
@@ -20,11 +24,12 @@ interface SyncedSupabaseConfiguration extends Omit<SyncedSupabaseConfig<{
|
|
|
20
24
|
enabled?: Observable<boolean>;
|
|
21
25
|
as?: Exclude<CrudAsOption, 'value'>;
|
|
22
26
|
}
|
|
23
|
-
interface SyncedSupabaseProps<Client extends SupabaseClient, Collection extends SupabaseCollectionOf<Client>, TOption extends CrudAsOption = 'object', TRemote extends SupabaseRowOf<Client, Collection> = SupabaseRowOf<Client, Collection>, TLocal = TRemote> extends SyncedSupabaseConfig<TRemote, TLocal>, SyncedCrudPropsMany<TRemote, TRemote, TOption> {
|
|
27
|
+
interface SyncedSupabaseProps<Client extends SupabaseClient<any, any>, Collection extends SupabaseCollectionOf<Client, SchemaName>, SchemaName extends SchemaNameOf<Client>, TOption extends CrudAsOption = 'object', TRemote extends SupabaseRowOf<Client, Collection, SchemaName> = SupabaseRowOf<Client, Collection, SchemaName>, TLocal = TRemote> extends SyncedSupabaseConfig<TRemote, TLocal>, SyncedCrudPropsMany<TRemote, TRemote, TOption> {
|
|
24
28
|
supabase: Client;
|
|
25
29
|
collection: Collection;
|
|
26
|
-
|
|
27
|
-
|
|
30
|
+
schema?: SchemaName;
|
|
31
|
+
select?: (query: PostgrestQueryBuilder<SupabaseSchemaOf<Client>, SupabaseTableOf<Client, SchemaName>[Collection], Collection>) => PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>;
|
|
32
|
+
filter?: (select: PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>, params: SyncedGetParams<TRemote>) => PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>;
|
|
28
33
|
actions?: ('create' | 'read' | 'update' | 'delete')[];
|
|
29
34
|
realtime?: boolean | {
|
|
30
35
|
schema?: string;
|
|
@@ -34,6 +39,6 @@ interface SyncedSupabaseProps<Client extends SupabaseClient, Collection extends
|
|
|
34
39
|
}
|
|
35
40
|
declare function getSyncedSupabaseConfiguration(): SyncedSupabaseConfiguration;
|
|
36
41
|
declare function configureSyncedSupabase(config: SyncedSupabaseConfiguration): void;
|
|
37
|
-
declare function syncedSupabase<Client extends SupabaseClient, Collection extends SupabaseCollectionOf<Client> & string, AsOption extends CrudAsOption = 'object', TRemote extends SupabaseRowOf<Client, Collection> = SupabaseRowOf<Client, Collection>, TLocal = TRemote>(props: SyncedSupabaseProps<Client, Collection, AsOption, TRemote, TLocal>): SyncedCrudReturnType<TLocal, AsOption>;
|
|
42
|
+
declare function syncedSupabase<Client extends SupabaseClient<any, any>, Collection extends SupabaseCollectionOf<Client, SchemaName> & string, SchemaName extends SchemaNameOf<Client>, AsOption extends CrudAsOption = 'object', TRemote extends SupabaseRowOf<Client, Collection, SchemaName> = SupabaseRowOf<Client, Collection, SchemaName>, TLocal = TRemote>(props: SyncedSupabaseProps<Client, Collection, SchemaName, AsOption, TRemote, TLocal>): SyncedCrudReturnType<TLocal, AsOption>;
|
|
38
43
|
|
|
39
44
|
export { type SupabaseCollectionOf, type SupabaseRowOf, type SupabaseSchemaOf, type SupabaseTableOf, type SyncedSupabaseConfig, type SyncedSupabaseConfiguration, configureSyncedSupabase, getSyncedSupabaseConfiguration, syncedSupabase };
|
package/sync-plugins/supabase.js
CHANGED
|
@@ -24,6 +24,7 @@ function syncedSupabase(props) {
|
|
|
24
24
|
supabase: client,
|
|
25
25
|
collection,
|
|
26
26
|
select: selectFn,
|
|
27
|
+
schema,
|
|
27
28
|
filter,
|
|
28
29
|
actions,
|
|
29
30
|
fieldCreatedAt: fieldCreatedAtParam,
|
|
@@ -36,6 +37,7 @@ function syncedSupabase(props) {
|
|
|
36
37
|
waitFor,
|
|
37
38
|
waitForSet,
|
|
38
39
|
generateId,
|
|
40
|
+
mode,
|
|
39
41
|
...rest
|
|
40
42
|
} = props;
|
|
41
43
|
const fieldCreatedAt = fieldCreatedAtParam || (changesSince === "last-sync" ? "created_at" : void 0);
|
|
@@ -43,7 +45,8 @@ function syncedSupabase(props) {
|
|
|
43
45
|
const fieldDeleted = fieldDeletedParam || (changesSince === "last-sync" ? "deleted" : void 0);
|
|
44
46
|
const list = !actions || actions.includes("read") ? async (params) => {
|
|
45
47
|
const { lastSync } = params;
|
|
46
|
-
const
|
|
48
|
+
const clientSchema = schema ? client.schema(schema) : client;
|
|
49
|
+
const from = clientSchema.from(collection);
|
|
47
50
|
let select = selectFn ? selectFn(from) : from.select();
|
|
48
51
|
if (changesSince === "last-sync" && lastSync) {
|
|
49
52
|
const date = new Date(lastSync).toISOString();
|
|
@@ -58,8 +61,8 @@ function syncedSupabase(props) {
|
|
|
58
61
|
}
|
|
59
62
|
return data || [];
|
|
60
63
|
} : void 0;
|
|
61
|
-
const
|
|
62
|
-
const res = await client.from(collection).
|
|
64
|
+
const create = !actions || actions.includes("create") ? async (input) => {
|
|
65
|
+
const res = await client.from(collection).insert(input).select();
|
|
63
66
|
const { data, error } = res;
|
|
64
67
|
if (data) {
|
|
65
68
|
const created = data[0];
|
|
@@ -67,9 +70,17 @@ function syncedSupabase(props) {
|
|
|
67
70
|
} else {
|
|
68
71
|
throw new Error(error == null ? void 0 : error.message);
|
|
69
72
|
}
|
|
70
|
-
};
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
+
} : void 0;
|
|
74
|
+
const update = !actions || actions.includes("update") ? async (input) => {
|
|
75
|
+
const res = await client.from(collection).update(input).eq("id", input.id).select();
|
|
76
|
+
const { data, error } = res;
|
|
77
|
+
if (data) {
|
|
78
|
+
const created = data[0];
|
|
79
|
+
return created;
|
|
80
|
+
} else {
|
|
81
|
+
throw new Error(error == null ? void 0 : error.message);
|
|
82
|
+
}
|
|
83
|
+
} : void 0;
|
|
73
84
|
const deleteFn = !fieldDeleted && (!actions || actions.includes("delete")) ? async (input) => {
|
|
74
85
|
const id = input.id;
|
|
75
86
|
const res = await client.from(collection).delete().eq("id", id).select();
|
|
@@ -82,13 +93,13 @@ function syncedSupabase(props) {
|
|
|
82
93
|
}
|
|
83
94
|
} : void 0;
|
|
84
95
|
const subscribe = realtime ? ({ node, value$, update: update2 }) => {
|
|
85
|
-
const { filter: filter2, schema } = state.isObject(realtime) ? realtime : {};
|
|
96
|
+
const { filter: filter2, schema: schema2 } = state.isObject(realtime) ? realtime : {};
|
|
86
97
|
const channel = client.channel(`LS_${node.key || ""}${channelNum++}`).on(
|
|
87
98
|
"postgres_changes",
|
|
88
99
|
{
|
|
89
100
|
event: "*",
|
|
90
101
|
table: collection,
|
|
91
|
-
schema:
|
|
102
|
+
schema: schema2 || "public",
|
|
92
103
|
filter: filter2 || void 0
|
|
93
104
|
},
|
|
94
105
|
(payload) => {
|
|
@@ -101,15 +112,15 @@ function syncedSupabase(props) {
|
|
|
101
112
|
const valueDate = +new Date(valueDateStr);
|
|
102
113
|
if (valueDateStr && (!curDateStr || valueDate > +new Date(curDateStr))) {
|
|
103
114
|
update2({
|
|
104
|
-
value:
|
|
115
|
+
value: [value],
|
|
105
116
|
lastSync: valueDate,
|
|
106
117
|
mode: "merge"
|
|
107
118
|
});
|
|
108
119
|
}
|
|
109
120
|
} else if (eventType === "DELETE") {
|
|
110
|
-
|
|
121
|
+
old[state.symbolDelete] = true;
|
|
111
122
|
update2({
|
|
112
|
-
value:
|
|
123
|
+
value: [old]
|
|
113
124
|
});
|
|
114
125
|
}
|
|
115
126
|
}
|
|
@@ -123,6 +134,7 @@ function syncedSupabase(props) {
|
|
|
123
134
|
}
|
|
124
135
|
return crud.syncedCrud({
|
|
125
136
|
...rest,
|
|
137
|
+
mode: mode || "merge",
|
|
126
138
|
list,
|
|
127
139
|
create,
|
|
128
140
|
update,
|
|
@@ -132,11 +144,10 @@ function syncedSupabase(props) {
|
|
|
132
144
|
fieldUpdatedAt,
|
|
133
145
|
fieldDeleted,
|
|
134
146
|
updatePartial: false,
|
|
135
|
-
onSavedUpdate: "createdUpdatedAt",
|
|
136
147
|
transform,
|
|
137
148
|
generateId,
|
|
138
149
|
waitFor: () => isEnabled$.get() && (waitFor ? state.computeSelector(waitFor) : true),
|
|
139
|
-
waitForSet
|
|
150
|
+
waitForSet: (params) => isEnabled$.get() && (waitForSet ? state.isFunction(waitForSet) ? waitForSet(params) : waitForSet : true)
|
|
140
151
|
});
|
|
141
152
|
}
|
|
142
153
|
|
|
@@ -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
|
|
|
@@ -22,6 +22,7 @@ function syncedSupabase(props) {
|
|
|
22
22
|
supabase: client,
|
|
23
23
|
collection,
|
|
24
24
|
select: selectFn,
|
|
25
|
+
schema,
|
|
25
26
|
filter,
|
|
26
27
|
actions,
|
|
27
28
|
fieldCreatedAt: fieldCreatedAtParam,
|
|
@@ -34,6 +35,7 @@ function syncedSupabase(props) {
|
|
|
34
35
|
waitFor,
|
|
35
36
|
waitForSet,
|
|
36
37
|
generateId,
|
|
38
|
+
mode,
|
|
37
39
|
...rest
|
|
38
40
|
} = props;
|
|
39
41
|
const fieldCreatedAt = fieldCreatedAtParam || (changesSince === "last-sync" ? "created_at" : void 0);
|
|
@@ -41,7 +43,8 @@ function syncedSupabase(props) {
|
|
|
41
43
|
const fieldDeleted = fieldDeletedParam || (changesSince === "last-sync" ? "deleted" : void 0);
|
|
42
44
|
const list = !actions || actions.includes("read") ? async (params) => {
|
|
43
45
|
const { lastSync } = params;
|
|
44
|
-
const
|
|
46
|
+
const clientSchema = schema ? client.schema(schema) : client;
|
|
47
|
+
const from = clientSchema.from(collection);
|
|
45
48
|
let select = selectFn ? selectFn(from) : from.select();
|
|
46
49
|
if (changesSince === "last-sync" && lastSync) {
|
|
47
50
|
const date = new Date(lastSync).toISOString();
|
|
@@ -56,8 +59,8 @@ function syncedSupabase(props) {
|
|
|
56
59
|
}
|
|
57
60
|
return data || [];
|
|
58
61
|
} : void 0;
|
|
59
|
-
const
|
|
60
|
-
const res = await client.from(collection).
|
|
62
|
+
const create = !actions || actions.includes("create") ? async (input) => {
|
|
63
|
+
const res = await client.from(collection).insert(input).select();
|
|
61
64
|
const { data, error } = res;
|
|
62
65
|
if (data) {
|
|
63
66
|
const created = data[0];
|
|
@@ -65,9 +68,17 @@ function syncedSupabase(props) {
|
|
|
65
68
|
} else {
|
|
66
69
|
throw new Error(error == null ? void 0 : error.message);
|
|
67
70
|
}
|
|
68
|
-
};
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
+
} : void 0;
|
|
72
|
+
const update = !actions || actions.includes("update") ? async (input) => {
|
|
73
|
+
const res = await client.from(collection).update(input).eq("id", input.id).select();
|
|
74
|
+
const { data, error } = res;
|
|
75
|
+
if (data) {
|
|
76
|
+
const created = data[0];
|
|
77
|
+
return created;
|
|
78
|
+
} else {
|
|
79
|
+
throw new Error(error == null ? void 0 : error.message);
|
|
80
|
+
}
|
|
81
|
+
} : void 0;
|
|
71
82
|
const deleteFn = !fieldDeleted && (!actions || actions.includes("delete")) ? async (input) => {
|
|
72
83
|
const id = input.id;
|
|
73
84
|
const res = await client.from(collection).delete().eq("id", id).select();
|
|
@@ -80,13 +91,13 @@ function syncedSupabase(props) {
|
|
|
80
91
|
}
|
|
81
92
|
} : void 0;
|
|
82
93
|
const subscribe = realtime ? ({ node, value$, update: update2 }) => {
|
|
83
|
-
const { filter: filter2, schema } = isObject(realtime) ? realtime : {};
|
|
94
|
+
const { filter: filter2, schema: schema2 } = isObject(realtime) ? realtime : {};
|
|
84
95
|
const channel = client.channel(`LS_${node.key || ""}${channelNum++}`).on(
|
|
85
96
|
"postgres_changes",
|
|
86
97
|
{
|
|
87
98
|
event: "*",
|
|
88
99
|
table: collection,
|
|
89
|
-
schema:
|
|
100
|
+
schema: schema2 || "public",
|
|
90
101
|
filter: filter2 || void 0
|
|
91
102
|
},
|
|
92
103
|
(payload) => {
|
|
@@ -99,15 +110,15 @@ function syncedSupabase(props) {
|
|
|
99
110
|
const valueDate = +new Date(valueDateStr);
|
|
100
111
|
if (valueDateStr && (!curDateStr || valueDate > +new Date(curDateStr))) {
|
|
101
112
|
update2({
|
|
102
|
-
value:
|
|
113
|
+
value: [value],
|
|
103
114
|
lastSync: valueDate,
|
|
104
115
|
mode: "merge"
|
|
105
116
|
});
|
|
106
117
|
}
|
|
107
118
|
} else if (eventType === "DELETE") {
|
|
108
|
-
|
|
119
|
+
old[symbolDelete] = true;
|
|
109
120
|
update2({
|
|
110
|
-
value:
|
|
121
|
+
value: [old]
|
|
111
122
|
});
|
|
112
123
|
}
|
|
113
124
|
}
|
|
@@ -121,6 +132,7 @@ function syncedSupabase(props) {
|
|
|
121
132
|
}
|
|
122
133
|
return syncedCrud({
|
|
123
134
|
...rest,
|
|
135
|
+
mode: mode || "merge",
|
|
124
136
|
list,
|
|
125
137
|
create,
|
|
126
138
|
update,
|
|
@@ -130,11 +142,10 @@ function syncedSupabase(props) {
|
|
|
130
142
|
fieldUpdatedAt,
|
|
131
143
|
fieldDeleted,
|
|
132
144
|
updatePartial: false,
|
|
133
|
-
onSavedUpdate: "createdUpdatedAt",
|
|
134
145
|
transform,
|
|
135
146
|
generateId,
|
|
136
147
|
waitFor: () => isEnabled$.get() && (waitFor ? computeSelector(waitFor) : true),
|
|
137
|
-
waitForSet
|
|
148
|
+
waitForSet: (params) => isEnabled$.get() && (waitForSet ? isFunction(waitForSet) ? waitForSet(params) : waitForSet : true)
|
|
138
149
|
});
|
|
139
150
|
}
|
|
140
151
|
|
|
@@ -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>):
|
|
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>):
|
|
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
|
|
@@ -58,7 +58,8 @@ function syncedQuery(params) {
|
|
|
58
58
|
return sync.synced({
|
|
59
59
|
get,
|
|
60
60
|
set,
|
|
61
|
-
subscribe
|
|
61
|
+
subscribe,
|
|
62
|
+
...rest
|
|
62
63
|
});
|
|
63
64
|
}
|
|
64
65
|
|
|
@@ -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
|
|
@@ -56,7 +56,8 @@ function syncedQuery(params) {
|
|
|
56
56
|
return synced({
|
|
57
57
|
get,
|
|
58
58
|
set,
|
|
59
|
-
subscribe
|
|
59
|
+
subscribe,
|
|
60
|
+
...rest
|
|
60
61
|
});
|
|
61
62
|
}
|
|
62
63
|
|
|
@@ -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<
|
|
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<
|
|
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 };
|