@legendapp/state 3.0.0-alpha.3 → 3.0.0-alpha.31
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 +2066 -0
- package/config.mjs +2064 -0
- package/helpers/trackHistory.js +2 -2
- package/helpers/trackHistory.mjs +2 -2
- package/index.d.mts +25 -302
- package/index.d.ts +25 -302
- package/index.js +293 -322
- package/index.mjs +294 -321
- package/observableInterfaces-CZR3_8mM.d.mts +283 -0
- package/observableInterfaces-CZR3_8mM.d.ts +283 -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/crud.d.mts +21 -24
- package/sync-plugins/crud.d.ts +21 -24
- package/sync-plugins/crud.js +240 -139
- package/sync-plugins/crud.mjs +242 -141
- package/sync-plugins/fetch.js +12 -8
- package/sync-plugins/fetch.mjs +13 -9
- package/sync-plugins/firebase.d.mts +27 -0
- package/sync-plugins/firebase.d.ts +27 -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 +51 -32
- package/sync-plugins/keel.mjs +52 -33
- 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 +71 -197
- package/sync.d.ts +71 -197
- package/sync.js +465 -284
- package/sync.mjs +471 -290
- 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.js
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var ksuid = require('ksuid');
|
|
4
3
|
var state = require('@legendapp/state');
|
|
5
4
|
var sync = require('@legendapp/state/sync');
|
|
6
5
|
var crud = require('@legendapp/state/sync-plugins/crud');
|
|
6
|
+
var ksuid = require('ksuid');
|
|
7
7
|
|
|
8
8
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
9
|
|
|
10
10
|
var ksuid__default = /*#__PURE__*/_interopDefault(ksuid);
|
|
11
11
|
|
|
12
12
|
// src/sync-plugins/keel.ts
|
|
13
|
-
var { clone } = state.internal;
|
|
14
13
|
var KeelKeys = ["createdAt", "updatedAt"];
|
|
15
14
|
function generateKeelId() {
|
|
16
15
|
return ksuid__default.default.randomSync().string;
|
|
@@ -20,6 +19,9 @@ var modifiedClients = /* @__PURE__ */ new WeakSet();
|
|
|
20
19
|
var isEnabled$ = state.observable(true);
|
|
21
20
|
async function ensureAuthToken() {
|
|
22
21
|
await state.when(isEnabled$.get());
|
|
22
|
+
if (keelConfig.refreshAuth) {
|
|
23
|
+
await keelConfig.refreshAuth();
|
|
24
|
+
}
|
|
23
25
|
let isAuthed = await keelConfig.client.auth.isAuthenticated();
|
|
24
26
|
if (!isAuthed) {
|
|
25
27
|
isAuthed = await keelConfig.client.auth.refresh();
|
|
@@ -33,17 +35,20 @@ async function handleApiError(error, retry) {
|
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
37
|
function convertObjectToCreate(item) {
|
|
36
|
-
const cloned =
|
|
37
|
-
Object.keys(
|
|
38
|
+
const cloned = {};
|
|
39
|
+
Object.keys(item).forEach((key) => {
|
|
38
40
|
if (key.endsWith("Id")) {
|
|
39
|
-
if (
|
|
40
|
-
cloned[key.slice(0, -2)] = { id:
|
|
41
|
+
if (item[key]) {
|
|
42
|
+
cloned[key.slice(0, -2)] = { id: item[key] };
|
|
43
|
+
}
|
|
44
|
+
} else if (key !== "createdAt" && key !== "updatedAt") {
|
|
45
|
+
if (item[key] === void 0) {
|
|
46
|
+
cloned[key] = null;
|
|
47
|
+
} else {
|
|
48
|
+
cloned[key] = item[key];
|
|
41
49
|
}
|
|
42
|
-
delete cloned[key];
|
|
43
50
|
}
|
|
44
51
|
});
|
|
45
|
-
delete cloned.createdAt;
|
|
46
|
-
delete cloned.updatedAt;
|
|
47
52
|
return cloned;
|
|
48
53
|
}
|
|
49
54
|
function getSyncedKeelConfiguration() {
|
|
@@ -65,9 +70,9 @@ function configureSyncedKeel(config) {
|
|
|
65
70
|
const oldFn = queries[key];
|
|
66
71
|
queries[key] = (i) => {
|
|
67
72
|
const realtimeKey = [key, ...Object.values(i.where || {})].filter((value) => value && typeof value !== "object").join("/");
|
|
68
|
-
const subscribe = (
|
|
73
|
+
const subscribe = (params) => {
|
|
69
74
|
if (realtimeKey) {
|
|
70
|
-
return realtimePlugin.subscribe(realtimeKey,
|
|
75
|
+
return realtimePlugin.subscribe(realtimeKey, params);
|
|
71
76
|
}
|
|
72
77
|
};
|
|
73
78
|
return oldFn(i).then((ret) => {
|
|
@@ -128,7 +133,9 @@ function syncedKeel(props) {
|
|
|
128
133
|
first,
|
|
129
134
|
where: whereParam,
|
|
130
135
|
waitFor,
|
|
136
|
+
waitForSet,
|
|
131
137
|
fieldDeleted,
|
|
138
|
+
mode,
|
|
132
139
|
...rest
|
|
133
140
|
} = props;
|
|
134
141
|
const { changesSince } = props;
|
|
@@ -137,8 +144,15 @@ function syncedKeel(props) {
|
|
|
137
144
|
const subscribeFnKey$ = state.observable("");
|
|
138
145
|
const fieldCreatedAt = "createdAt";
|
|
139
146
|
const fieldUpdatedAt = "updatedAt";
|
|
147
|
+
const setupSubscribe = (doSubscribe, subscribeKey, lastSync) => {
|
|
148
|
+
subscribeFn = doSubscribe;
|
|
149
|
+
subscribeFnKey$.set(subscribeKey);
|
|
150
|
+
if (realtimePlugin && lastSync) {
|
|
151
|
+
realtimePlugin.setLatestChange(subscribeKey, new Date(lastSync));
|
|
152
|
+
}
|
|
153
|
+
};
|
|
140
154
|
const list = listParam ? async (listParams) => {
|
|
141
|
-
const { lastSync
|
|
155
|
+
const { lastSync } = listParams;
|
|
142
156
|
const queryBySync = !!lastSync && changesSince === "last-sync";
|
|
143
157
|
const where = Object.assign(
|
|
144
158
|
queryBySync ? { updatedAt: { after: new Date(lastSync + 1) } } : {},
|
|
@@ -147,8 +161,7 @@ function syncedKeel(props) {
|
|
|
147
161
|
const params = { where, first };
|
|
148
162
|
const { results, subscribe: subscribe2, subscribeKey } = await getAllPages(listParam, params);
|
|
149
163
|
if (subscribe2) {
|
|
150
|
-
|
|
151
|
-
subscribeFnKey$.set(subscribeKey);
|
|
164
|
+
setupSubscribe(() => subscribe2(listParams), subscribeKey, lastSync);
|
|
152
165
|
}
|
|
153
166
|
return results;
|
|
154
167
|
} : void 0;
|
|
@@ -156,8 +169,7 @@ function syncedKeel(props) {
|
|
|
156
169
|
const { refresh } = getParams;
|
|
157
170
|
const { data, error, subscribe: subscribe2, subscribeKey } = await getParam({ refresh });
|
|
158
171
|
if (subscribe2) {
|
|
159
|
-
|
|
160
|
-
subscribeFnKey$.set(subscribeKey);
|
|
172
|
+
setupSubscribe(() => subscribe2(getParams), subscribeKey);
|
|
161
173
|
}
|
|
162
174
|
if (error) {
|
|
163
175
|
throw new Error(error.message);
|
|
@@ -176,32 +188,40 @@ function syncedKeel(props) {
|
|
|
176
188
|
}
|
|
177
189
|
}
|
|
178
190
|
};
|
|
179
|
-
const handleSetError = async (error, params,
|
|
191
|
+
const handleSetError = async (error, params, input, fn, from) => {
|
|
180
192
|
var _a, _b, _c;
|
|
181
|
-
const { retryNum,
|
|
182
|
-
if (
|
|
193
|
+
const { retryNum, update: update2 } = params;
|
|
194
|
+
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"))) {
|
|
183
195
|
if (__DEV__) {
|
|
184
196
|
console.log("Creating duplicate data already saved, just ignore.");
|
|
185
197
|
}
|
|
198
|
+
params.cancelRetry = true;
|
|
186
199
|
update2({
|
|
187
200
|
value: {},
|
|
188
201
|
mode: "assign"
|
|
189
202
|
});
|
|
203
|
+
} else if (from === "delete") {
|
|
204
|
+
if (error.message === "record not found") {
|
|
205
|
+
if (__DEV__) {
|
|
206
|
+
console.log("Deleting non-existing data, just ignore.");
|
|
207
|
+
}
|
|
208
|
+
params.cancelRetry = true;
|
|
209
|
+
}
|
|
190
210
|
} else if (error.type === "bad_request") {
|
|
191
|
-
(_c = keelConfig.onError) == null ? void 0 : _c.call(keelConfig, error);
|
|
211
|
+
(_c = keelConfig.onError) == null ? void 0 : _c.call(keelConfig, { error, params, input, type: from, action: fn.name || fn.toString() });
|
|
192
212
|
if (retryNum > 4) {
|
|
193
|
-
cancelRetry
|
|
213
|
+
params.cancelRetry = true;
|
|
194
214
|
}
|
|
195
|
-
throw new Error(error.message);
|
|
215
|
+
throw new Error(error.message, { cause: { input } });
|
|
196
216
|
} else {
|
|
197
217
|
await handleApiError(error);
|
|
198
|
-
throw new Error(error.message);
|
|
218
|
+
throw new Error(error.message, { cause: { input } });
|
|
199
219
|
}
|
|
200
220
|
};
|
|
201
221
|
const create = createParam ? async (input, params) => {
|
|
202
222
|
const { data, error } = await createParam(convertObjectToCreate(input));
|
|
203
223
|
if (error) {
|
|
204
|
-
handleSetError(error, params,
|
|
224
|
+
await handleSetError(error, params, input, createParam, "create");
|
|
205
225
|
}
|
|
206
226
|
return data;
|
|
207
227
|
} : void 0;
|
|
@@ -209,20 +229,18 @@ function syncedKeel(props) {
|
|
|
209
229
|
const id = input.id;
|
|
210
230
|
const values = convertObjectToCreate(input);
|
|
211
231
|
delete values.id;
|
|
212
|
-
delete values.createdAt;
|
|
213
|
-
delete values.updatedAt;
|
|
214
232
|
if (!state.isEmpty(values)) {
|
|
215
233
|
const { data, error } = await updateParam({ where: { id }, values });
|
|
216
234
|
if (error) {
|
|
217
|
-
handleSetError(error, params,
|
|
235
|
+
await handleSetError(error, params, input, updateParam, "update");
|
|
218
236
|
}
|
|
219
237
|
return data;
|
|
220
238
|
}
|
|
221
239
|
} : void 0;
|
|
222
|
-
const deleteFn = deleteParam ? async (
|
|
223
|
-
const { data, error } = await deleteParam({ id });
|
|
240
|
+
const deleteFn = deleteParam ? async (value, params) => {
|
|
241
|
+
const { data, error } = await deleteParam({ id: value.id });
|
|
224
242
|
if (error) {
|
|
225
|
-
handleSetError(error, params,
|
|
243
|
+
await handleSetError(error, params, value, deleteParam, "delete");
|
|
226
244
|
}
|
|
227
245
|
return data;
|
|
228
246
|
} : void 0;
|
|
@@ -238,16 +256,17 @@ function syncedKeel(props) {
|
|
|
238
256
|
return crud.syncedCrud({
|
|
239
257
|
...rest,
|
|
240
258
|
as: asType,
|
|
259
|
+
mode: mode || "merge",
|
|
241
260
|
list,
|
|
242
261
|
create,
|
|
243
262
|
update,
|
|
244
263
|
delete: deleteFn,
|
|
245
264
|
waitFor: () => isEnabled$.get() && (waitFor ? state.computeSelector(waitFor) : true),
|
|
265
|
+
waitForSet: (params) => isEnabled$.get() && (waitForSet ? state.isFunction(waitForSet) ? waitForSet(params) : waitForSet : true),
|
|
246
266
|
onSaved,
|
|
247
|
-
onSavedUpdate: "createdUpdatedAt",
|
|
248
267
|
fieldCreatedAt,
|
|
249
268
|
fieldUpdatedAt,
|
|
250
|
-
fieldDeleted
|
|
269
|
+
fieldDeleted,
|
|
251
270
|
changesSince,
|
|
252
271
|
updatePartial: true,
|
|
253
272
|
subscribe,
|
package/sync-plugins/keel.mjs
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { observable, computeSelector, isFunction, isEmpty, when, internal } from '@legendapp/state';
|
|
1
|
+
import { observable, computeSelector, isFunction, isEmpty, when } from '@legendapp/state';
|
|
3
2
|
import { removeNullUndefined } from '@legendapp/state/sync';
|
|
4
3
|
import { syncedCrud } from '@legendapp/state/sync-plugins/crud';
|
|
4
|
+
import ksuid from 'ksuid';
|
|
5
5
|
|
|
6
6
|
// src/sync-plugins/keel.ts
|
|
7
|
-
var { clone } = internal;
|
|
8
7
|
var KeelKeys = ["createdAt", "updatedAt"];
|
|
9
8
|
function generateKeelId() {
|
|
10
9
|
return ksuid.randomSync().string;
|
|
@@ -14,6 +13,9 @@ var modifiedClients = /* @__PURE__ */ new WeakSet();
|
|
|
14
13
|
var isEnabled$ = observable(true);
|
|
15
14
|
async function ensureAuthToken() {
|
|
16
15
|
await when(isEnabled$.get());
|
|
16
|
+
if (keelConfig.refreshAuth) {
|
|
17
|
+
await keelConfig.refreshAuth();
|
|
18
|
+
}
|
|
17
19
|
let isAuthed = await keelConfig.client.auth.isAuthenticated();
|
|
18
20
|
if (!isAuthed) {
|
|
19
21
|
isAuthed = await keelConfig.client.auth.refresh();
|
|
@@ -27,17 +29,20 @@ async function handleApiError(error, retry) {
|
|
|
27
29
|
}
|
|
28
30
|
}
|
|
29
31
|
function convertObjectToCreate(item) {
|
|
30
|
-
const cloned =
|
|
31
|
-
Object.keys(
|
|
32
|
+
const cloned = {};
|
|
33
|
+
Object.keys(item).forEach((key) => {
|
|
32
34
|
if (key.endsWith("Id")) {
|
|
33
|
-
if (
|
|
34
|
-
cloned[key.slice(0, -2)] = { id:
|
|
35
|
+
if (item[key]) {
|
|
36
|
+
cloned[key.slice(0, -2)] = { id: item[key] };
|
|
37
|
+
}
|
|
38
|
+
} else if (key !== "createdAt" && key !== "updatedAt") {
|
|
39
|
+
if (item[key] === void 0) {
|
|
40
|
+
cloned[key] = null;
|
|
41
|
+
} else {
|
|
42
|
+
cloned[key] = item[key];
|
|
35
43
|
}
|
|
36
|
-
delete cloned[key];
|
|
37
44
|
}
|
|
38
45
|
});
|
|
39
|
-
delete cloned.createdAt;
|
|
40
|
-
delete cloned.updatedAt;
|
|
41
46
|
return cloned;
|
|
42
47
|
}
|
|
43
48
|
function getSyncedKeelConfiguration() {
|
|
@@ -59,9 +64,9 @@ function configureSyncedKeel(config) {
|
|
|
59
64
|
const oldFn = queries[key];
|
|
60
65
|
queries[key] = (i) => {
|
|
61
66
|
const realtimeKey = [key, ...Object.values(i.where || {})].filter((value) => value && typeof value !== "object").join("/");
|
|
62
|
-
const subscribe = (
|
|
67
|
+
const subscribe = (params) => {
|
|
63
68
|
if (realtimeKey) {
|
|
64
|
-
return realtimePlugin.subscribe(realtimeKey,
|
|
69
|
+
return realtimePlugin.subscribe(realtimeKey, params);
|
|
65
70
|
}
|
|
66
71
|
};
|
|
67
72
|
return oldFn(i).then((ret) => {
|
|
@@ -122,7 +127,9 @@ function syncedKeel(props) {
|
|
|
122
127
|
first,
|
|
123
128
|
where: whereParam,
|
|
124
129
|
waitFor,
|
|
130
|
+
waitForSet,
|
|
125
131
|
fieldDeleted,
|
|
132
|
+
mode,
|
|
126
133
|
...rest
|
|
127
134
|
} = props;
|
|
128
135
|
const { changesSince } = props;
|
|
@@ -131,8 +138,15 @@ function syncedKeel(props) {
|
|
|
131
138
|
const subscribeFnKey$ = observable("");
|
|
132
139
|
const fieldCreatedAt = "createdAt";
|
|
133
140
|
const fieldUpdatedAt = "updatedAt";
|
|
141
|
+
const setupSubscribe = (doSubscribe, subscribeKey, lastSync) => {
|
|
142
|
+
subscribeFn = doSubscribe;
|
|
143
|
+
subscribeFnKey$.set(subscribeKey);
|
|
144
|
+
if (realtimePlugin && lastSync) {
|
|
145
|
+
realtimePlugin.setLatestChange(subscribeKey, new Date(lastSync));
|
|
146
|
+
}
|
|
147
|
+
};
|
|
134
148
|
const list = listParam ? async (listParams) => {
|
|
135
|
-
const { lastSync
|
|
149
|
+
const { lastSync } = listParams;
|
|
136
150
|
const queryBySync = !!lastSync && changesSince === "last-sync";
|
|
137
151
|
const where = Object.assign(
|
|
138
152
|
queryBySync ? { updatedAt: { after: new Date(lastSync + 1) } } : {},
|
|
@@ -141,8 +155,7 @@ function syncedKeel(props) {
|
|
|
141
155
|
const params = { where, first };
|
|
142
156
|
const { results, subscribe: subscribe2, subscribeKey } = await getAllPages(listParam, params);
|
|
143
157
|
if (subscribe2) {
|
|
144
|
-
|
|
145
|
-
subscribeFnKey$.set(subscribeKey);
|
|
158
|
+
setupSubscribe(() => subscribe2(listParams), subscribeKey, lastSync);
|
|
146
159
|
}
|
|
147
160
|
return results;
|
|
148
161
|
} : void 0;
|
|
@@ -150,8 +163,7 @@ function syncedKeel(props) {
|
|
|
150
163
|
const { refresh } = getParams;
|
|
151
164
|
const { data, error, subscribe: subscribe2, subscribeKey } = await getParam({ refresh });
|
|
152
165
|
if (subscribe2) {
|
|
153
|
-
|
|
154
|
-
subscribeFnKey$.set(subscribeKey);
|
|
166
|
+
setupSubscribe(() => subscribe2(getParams), subscribeKey);
|
|
155
167
|
}
|
|
156
168
|
if (error) {
|
|
157
169
|
throw new Error(error.message);
|
|
@@ -170,32 +182,40 @@ function syncedKeel(props) {
|
|
|
170
182
|
}
|
|
171
183
|
}
|
|
172
184
|
};
|
|
173
|
-
const handleSetError = async (error, params,
|
|
185
|
+
const handleSetError = async (error, params, input, fn, from) => {
|
|
174
186
|
var _a, _b, _c;
|
|
175
|
-
const { retryNum,
|
|
176
|
-
if (
|
|
187
|
+
const { retryNum, update: update2 } = params;
|
|
188
|
+
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
189
|
if (__DEV__) {
|
|
178
190
|
console.log("Creating duplicate data already saved, just ignore.");
|
|
179
191
|
}
|
|
192
|
+
params.cancelRetry = true;
|
|
180
193
|
update2({
|
|
181
194
|
value: {},
|
|
182
195
|
mode: "assign"
|
|
183
196
|
});
|
|
197
|
+
} else if (from === "delete") {
|
|
198
|
+
if (error.message === "record not found") {
|
|
199
|
+
if (__DEV__) {
|
|
200
|
+
console.log("Deleting non-existing data, just ignore.");
|
|
201
|
+
}
|
|
202
|
+
params.cancelRetry = true;
|
|
203
|
+
}
|
|
184
204
|
} else if (error.type === "bad_request") {
|
|
185
|
-
(_c = keelConfig.onError) == null ? void 0 : _c.call(keelConfig, error);
|
|
205
|
+
(_c = keelConfig.onError) == null ? void 0 : _c.call(keelConfig, { error, params, input, type: from, action: fn.name || fn.toString() });
|
|
186
206
|
if (retryNum > 4) {
|
|
187
|
-
cancelRetry
|
|
207
|
+
params.cancelRetry = true;
|
|
188
208
|
}
|
|
189
|
-
throw new Error(error.message);
|
|
209
|
+
throw new Error(error.message, { cause: { input } });
|
|
190
210
|
} else {
|
|
191
211
|
await handleApiError(error);
|
|
192
|
-
throw new Error(error.message);
|
|
212
|
+
throw new Error(error.message, { cause: { input } });
|
|
193
213
|
}
|
|
194
214
|
};
|
|
195
215
|
const create = createParam ? async (input, params) => {
|
|
196
216
|
const { data, error } = await createParam(convertObjectToCreate(input));
|
|
197
217
|
if (error) {
|
|
198
|
-
handleSetError(error, params,
|
|
218
|
+
await handleSetError(error, params, input, createParam, "create");
|
|
199
219
|
}
|
|
200
220
|
return data;
|
|
201
221
|
} : void 0;
|
|
@@ -203,20 +223,18 @@ function syncedKeel(props) {
|
|
|
203
223
|
const id = input.id;
|
|
204
224
|
const values = convertObjectToCreate(input);
|
|
205
225
|
delete values.id;
|
|
206
|
-
delete values.createdAt;
|
|
207
|
-
delete values.updatedAt;
|
|
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
|
|