@legendapp/state 3.0.0-alpha.8 → 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.
- package/.DS_Store +0 -0
- package/config/configureLegendState.d.mts +13 -0
- package/config/configureLegendState.d.ts +13 -0
- package/config/configureLegendState.js +45 -0
- package/config/configureLegendState.mjs +43 -0
- 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/helpers/trackHistory.js +2 -2
- package/helpers/trackHistory.mjs +2 -2
- package/index.d.mts +104 -80
- package/index.d.ts +104 -80
- package/index.js +328 -318
- package/index.mjs +325 -316
- package/package.json +36 -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 +8 -4
- package/persist-plugins/async-storage.mjs +8 -5
- package/persist-plugins/indexeddb.d.mts +6 -4
- package/persist-plugins/indexeddb.d.ts +6 -4
- package/persist-plugins/indexeddb.js +35 -15
- package/persist-plugins/indexeddb.mjs +35 -16
- package/persist-plugins/mmkv.d.mts +5 -1
- package/persist-plugins/mmkv.d.ts +5 -1
- package/persist-plugins/mmkv.js +10 -5
- package/persist-plugins/mmkv.mjs +10 -6
- package/react-reactive/enableReactComponents.d.mts +9 -0
- package/react-reactive/enableReactComponents.d.ts +9 -0
- package/react-reactive/enableReactComponents.js +19 -0
- package/react-reactive/enableReactComponents.mjs +17 -0
- package/react-reactive/enableReactNativeComponents.d.mts +22 -0
- package/react-reactive/enableReactNativeComponents.d.ts +22 -0
- package/react-reactive/enableReactNativeComponents.js +53 -0
- package/react-reactive/enableReactNativeComponents.mjs +51 -0
- package/react-reactive/enableReactive.d.mts +5 -0
- package/react-reactive/enableReactive.d.ts +5 -0
- package/react-reactive/enableReactive.js +24 -0
- package/react-reactive/enableReactive.mjs +22 -0
- package/react-reactive/enableReactive.native.d.mts +5 -0
- package/react-reactive/enableReactive.native.d.ts +5 -0
- package/react-reactive/enableReactive.native.js +58 -0
- package/react-reactive/enableReactive.native.mjs +56 -0
- package/react-reactive/enableReactive.web.d.mts +5 -0
- package/react-reactive/enableReactive.web.d.ts +5 -0
- package/react-reactive/enableReactive.web.js +58 -0
- package/react-reactive/enableReactive.web.mjs +56 -0
- package/react.d.mts +39 -34
- package/react.d.ts +39 -34
- package/react.js +39 -17
- package/react.mjs +39 -17
- package/sync-plugins/crud.d.mts +21 -24
- package/sync-plugins/crud.d.ts +21 -24
- package/sync-plugins/crud.js +241 -140
- package/sync-plugins/crud.mjs +243 -142
- 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 +43 -26
- package/sync-plugins/keel.d.ts +43 -26
- package/sync-plugins/keel.js +145 -100
- package/sync-plugins/keel.mjs +147 -100
- package/sync-plugins/supabase.d.mts +19 -9
- package/sync-plugins/supabase.d.ts +19 -9
- package/sync-plugins/supabase.js +52 -22
- package/sync-plugins/supabase.mjs +53 -23
- package/sync-plugins/tanstack-query.d.mts +2 -2
- package/sync-plugins/tanstack-query.d.ts +2 -2
- package/sync-plugins/tanstack-query.js +22 -5
- package/sync-plugins/tanstack-query.mjs +22 -5
- package/sync-plugins/tanstack-react-query.d.mts +1 -1
- package/sync-plugins/tanstack-react-query.d.ts +1 -1
- package/sync-plugins/tanstack-react-query.js +8 -1
- package/sync-plugins/tanstack-react-query.mjs +8 -1
- package/sync.d.mts +74 -200
- package/sync.d.ts +74 -200
- package/sync.js +492 -293
- package/sync.mjs +498 -299
package/sync-plugins/keel.mjs
CHANGED
|
@@ -1,88 +1,99 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { observable, computeSelector, isFunction, isEmpty, when, internal } from '@legendapp/state';
|
|
3
|
-
import { removeNullUndefined } from '@legendapp/state/sync';
|
|
1
|
+
import { observable, isFunction, when, batch, isEmpty } from '@legendapp/state';
|
|
4
2
|
import { syncedCrud } from '@legendapp/state/sync-plugins/crud';
|
|
3
|
+
import ksuid from 'ksuid';
|
|
5
4
|
|
|
6
5
|
// src/sync-plugins/keel.ts
|
|
7
|
-
var { clone } = internal;
|
|
8
6
|
var KeelKeys = ["createdAt", "updatedAt"];
|
|
9
7
|
function generateKeelId() {
|
|
10
8
|
return ksuid.randomSync().string;
|
|
11
9
|
}
|
|
12
|
-
var keelConfig = {};
|
|
13
10
|
var modifiedClients = /* @__PURE__ */ new WeakSet();
|
|
14
|
-
var
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
var isAuthed$ = observable(false);
|
|
12
|
+
var isAuthing$ = observable(false);
|
|
13
|
+
async function ensureAuthToken(props, force) {
|
|
14
|
+
if (!force && isAuthed$.get()) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
const { client, refreshAuth } = props;
|
|
18
|
+
let isAuthed = await client.auth.isAuthenticated().then(({ data }) => data);
|
|
18
19
|
if (!isAuthed) {
|
|
19
|
-
|
|
20
|
+
if (!force && isAuthing$.get()) {
|
|
21
|
+
return when(
|
|
22
|
+
() => !isAuthing$.get(),
|
|
23
|
+
() => isAuthed$.get()
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
isAuthing$.set(true);
|
|
27
|
+
if (refreshAuth) {
|
|
28
|
+
await refreshAuth();
|
|
29
|
+
}
|
|
30
|
+
isAuthed = await client.auth.isAuthenticated().then(({ data }) => data);
|
|
31
|
+
if (!isAuthed) {
|
|
32
|
+
isAuthed = await client.auth.refresh().then(({ data }) => data);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (isAuthed) {
|
|
36
|
+
batch(() => {
|
|
37
|
+
isAuthed$.set(true);
|
|
38
|
+
isAuthing$.set(false);
|
|
39
|
+
});
|
|
40
|
+
} else {
|
|
41
|
+
setTimeout(() => ensureAuthToken(
|
|
42
|
+
props,
|
|
43
|
+
/*force*/
|
|
44
|
+
true
|
|
45
|
+
), 1e3);
|
|
20
46
|
}
|
|
21
47
|
return isAuthed;
|
|
22
48
|
}
|
|
23
|
-
async function handleApiError(error, retry) {
|
|
49
|
+
async function handleApiError(props, error, retry) {
|
|
24
50
|
if (error.type === "unauthorized" || error.type === "forbidden") {
|
|
25
51
|
console.warn("Keel token expired, refreshing...");
|
|
26
|
-
|
|
52
|
+
isAuthed$.set(false);
|
|
53
|
+
await ensureAuthToken(props);
|
|
27
54
|
}
|
|
28
55
|
}
|
|
29
56
|
function convertObjectToCreate(item) {
|
|
30
|
-
const cloned =
|
|
31
|
-
Object.keys(
|
|
57
|
+
const cloned = {};
|
|
58
|
+
Object.keys(item).forEach((key) => {
|
|
32
59
|
if (key.endsWith("Id")) {
|
|
33
|
-
if (
|
|
34
|
-
cloned[key.slice(0, -2)] = { id:
|
|
60
|
+
if (item[key]) {
|
|
61
|
+
cloned[key.slice(0, -2)] = { id: item[key] };
|
|
62
|
+
}
|
|
63
|
+
} else if (key !== "createdAt" && key !== "updatedAt") {
|
|
64
|
+
if (item[key] === void 0) {
|
|
65
|
+
cloned[key] = null;
|
|
66
|
+
} else {
|
|
67
|
+
cloned[key] = item[key];
|
|
35
68
|
}
|
|
36
|
-
delete cloned[key];
|
|
37
69
|
}
|
|
38
70
|
});
|
|
39
|
-
delete cloned.createdAt;
|
|
40
|
-
delete cloned.updatedAt;
|
|
41
71
|
return cloned;
|
|
42
72
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const queries = client.api.queries;
|
|
57
|
-
Object.keys(queries).forEach((key) => {
|
|
58
|
-
if (key.startsWith("list")) {
|
|
59
|
-
const oldFn = queries[key];
|
|
60
|
-
queries[key] = (i) => {
|
|
61
|
-
const realtimeKey = [key, ...Object.values(i.where || {})].filter((value) => value && typeof value !== "object").join("/");
|
|
62
|
-
const subscribe = ({ refresh }) => {
|
|
63
|
-
if (realtimeKey) {
|
|
64
|
-
return realtimePlugin.subscribe(realtimeKey, refresh);
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
return oldFn(i).then((ret) => {
|
|
68
|
-
if (subscribe) {
|
|
69
|
-
ret.subscribe = subscribe;
|
|
70
|
-
ret.subscribeKey = realtimeKey;
|
|
71
|
-
}
|
|
72
|
-
return ret;
|
|
73
|
-
});
|
|
73
|
+
var realtimeState = { current: {} };
|
|
74
|
+
function setupRealtime(props) {
|
|
75
|
+
const { client } = props;
|
|
76
|
+
if (client && !modifiedClients.has(client)) {
|
|
77
|
+
modifiedClients.add(client);
|
|
78
|
+
const queries = client.api.queries;
|
|
79
|
+
Object.keys(queries).forEach((key) => {
|
|
80
|
+
if (key.startsWith("list")) {
|
|
81
|
+
const origFn = queries[key];
|
|
82
|
+
queries[key] = (i) => {
|
|
83
|
+
realtimeState.current = {
|
|
84
|
+
lastAction: key,
|
|
85
|
+
lastParams: i
|
|
74
86
|
};
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
87
|
+
return origFn(i);
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
});
|
|
78
91
|
}
|
|
79
92
|
}
|
|
80
93
|
var NumPerPage = 200;
|
|
81
|
-
async function getAllPages(listFn, params) {
|
|
94
|
+
async function getAllPages(props, listFn, params) {
|
|
82
95
|
const allData = [];
|
|
83
96
|
let pageInfo = void 0;
|
|
84
|
-
let subscribe_;
|
|
85
|
-
let subscribeKey_;
|
|
86
97
|
const { first: firstParam } = params;
|
|
87
98
|
do {
|
|
88
99
|
const first = firstParam ? Math.min(firstParam - allData.length, NumPerPage) : NumPerPage;
|
|
@@ -94,13 +105,9 @@ async function getAllPages(listFn, params) {
|
|
|
94
105
|
pageInfo = void 0;
|
|
95
106
|
const ret = await listFn(paramsWithCursor);
|
|
96
107
|
if (ret) {
|
|
97
|
-
const { data, error
|
|
98
|
-
if (subscribe) {
|
|
99
|
-
subscribe_ = subscribe;
|
|
100
|
-
subscribeKey_ = subscribeKey;
|
|
101
|
-
}
|
|
108
|
+
const { data, error } = ret;
|
|
102
109
|
if (error) {
|
|
103
|
-
await handleApiError(error);
|
|
110
|
+
await handleApiError(props, error);
|
|
104
111
|
throw new Error(error.message);
|
|
105
112
|
} else if (data) {
|
|
106
113
|
pageInfo = data.pageInfo;
|
|
@@ -108,21 +115,25 @@ async function getAllPages(listFn, params) {
|
|
|
108
115
|
}
|
|
109
116
|
}
|
|
110
117
|
} while (pageInfo == null ? void 0 : pageInfo.hasNextPage);
|
|
111
|
-
return
|
|
118
|
+
return allData;
|
|
112
119
|
}
|
|
113
120
|
function syncedKeel(props) {
|
|
114
|
-
const { realtimePlugin } = keelConfig;
|
|
115
|
-
props = { ...keelConfig, ...props };
|
|
116
121
|
const {
|
|
117
122
|
get: getParam,
|
|
118
123
|
list: listParam,
|
|
119
124
|
create: createParam,
|
|
120
125
|
update: updateParam,
|
|
121
126
|
delete: deleteParam,
|
|
127
|
+
subscribe: subscribeParam,
|
|
122
128
|
first,
|
|
123
129
|
where: whereParam,
|
|
124
130
|
waitFor,
|
|
131
|
+
waitForSet,
|
|
125
132
|
fieldDeleted,
|
|
133
|
+
realtime,
|
|
134
|
+
mode,
|
|
135
|
+
onError,
|
|
136
|
+
requireAuth = true,
|
|
126
137
|
...rest
|
|
127
138
|
} = props;
|
|
128
139
|
const { changesSince } = props;
|
|
@@ -131,28 +142,38 @@ function syncedKeel(props) {
|
|
|
131
142
|
const subscribeFnKey$ = observable("");
|
|
132
143
|
const fieldCreatedAt = "createdAt";
|
|
133
144
|
const fieldUpdatedAt = "updatedAt";
|
|
145
|
+
const setupSubscribe = realtime ? async (getParams) => {
|
|
146
|
+
const { lastAction, lastParams } = realtimeState.current;
|
|
147
|
+
const { path, plugin } = realtime;
|
|
148
|
+
if (lastAction && path && plugin) {
|
|
149
|
+
const key = await path(lastAction, lastParams);
|
|
150
|
+
subscribeFn = () => realtime.plugin.subscribe(key, getParams);
|
|
151
|
+
subscribeFnKey$.set(key);
|
|
152
|
+
}
|
|
153
|
+
} : void 0;
|
|
134
154
|
const list = listParam ? async (listParams) => {
|
|
135
|
-
const { lastSync
|
|
155
|
+
const { lastSync } = listParams;
|
|
136
156
|
const queryBySync = !!lastSync && changesSince === "last-sync";
|
|
137
157
|
const where = Object.assign(
|
|
138
158
|
queryBySync ? { updatedAt: { after: new Date(lastSync + 1) } } : {},
|
|
139
159
|
isFunction(whereParam) ? whereParam() : whereParam
|
|
140
160
|
);
|
|
141
161
|
const params = { where, first };
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
162
|
+
realtimeState.current = {};
|
|
163
|
+
const promise = getAllPages(props, listParam, params);
|
|
164
|
+
if (realtime) {
|
|
165
|
+
setupSubscribe(listParams);
|
|
146
166
|
}
|
|
147
|
-
return
|
|
167
|
+
return promise;
|
|
148
168
|
} : void 0;
|
|
149
169
|
const get = getParam ? async (getParams) => {
|
|
150
170
|
const { refresh } = getParams;
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
171
|
+
realtimeState.current = {};
|
|
172
|
+
const promise = getParam({ refresh });
|
|
173
|
+
if (realtime) {
|
|
174
|
+
setupSubscribe(getParams);
|
|
155
175
|
}
|
|
176
|
+
const { data, error } = await promise;
|
|
156
177
|
if (error) {
|
|
157
178
|
throw new Error(error.message);
|
|
158
179
|
} else {
|
|
@@ -161,41 +182,54 @@ function syncedKeel(props) {
|
|
|
161
182
|
} : void 0;
|
|
162
183
|
const onSaved = ({ saved }) => {
|
|
163
184
|
if (saved) {
|
|
164
|
-
|
|
165
|
-
if (updatedAt && realtimePlugin) {
|
|
185
|
+
if (realtime == null ? void 0 : realtime.plugin) {
|
|
166
186
|
const subscribeFnKey = subscribeFnKey$.get();
|
|
167
187
|
if (subscribeFnKey) {
|
|
168
|
-
|
|
188
|
+
realtime == null ? void 0 : realtime.plugin.setSaved(subscribeFnKey);
|
|
169
189
|
}
|
|
170
190
|
}
|
|
171
191
|
}
|
|
172
192
|
};
|
|
173
|
-
const handleSetError = async (error, params,
|
|
174
|
-
var _a, _b
|
|
175
|
-
const { retryNum,
|
|
176
|
-
if (
|
|
193
|
+
const handleSetError = async (error, params, input, fn, from) => {
|
|
194
|
+
var _a, _b;
|
|
195
|
+
const { retryNum, update: update2 } = params;
|
|
196
|
+
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
197
|
if (__DEV__) {
|
|
178
198
|
console.log("Creating duplicate data already saved, just ignore.");
|
|
179
199
|
}
|
|
200
|
+
params.cancelRetry = true;
|
|
180
201
|
update2({
|
|
181
202
|
value: {},
|
|
182
203
|
mode: "assign"
|
|
183
204
|
});
|
|
205
|
+
} else if (from === "delete") {
|
|
206
|
+
if (error.message === "record not found") {
|
|
207
|
+
if (__DEV__) {
|
|
208
|
+
console.log("Deleting non-existing data, just ignore.");
|
|
209
|
+
}
|
|
210
|
+
params.cancelRetry = true;
|
|
211
|
+
}
|
|
184
212
|
} else if (error.type === "bad_request") {
|
|
185
|
-
|
|
213
|
+
onError == null ? void 0 : onError(new Error(error.message), params, {
|
|
214
|
+
error,
|
|
215
|
+
params,
|
|
216
|
+
input,
|
|
217
|
+
type: from,
|
|
218
|
+
action: fn.name || fn.toString()
|
|
219
|
+
});
|
|
186
220
|
if (retryNum > 4) {
|
|
187
|
-
cancelRetry
|
|
221
|
+
params.cancelRetry = true;
|
|
188
222
|
}
|
|
189
|
-
throw new Error(error.message);
|
|
223
|
+
throw new Error(error.message, { cause: { input } });
|
|
190
224
|
} else {
|
|
191
|
-
await handleApiError(error);
|
|
192
|
-
throw new Error(error.message);
|
|
225
|
+
await handleApiError(props, error);
|
|
226
|
+
throw new Error(error.message, { cause: { input } });
|
|
193
227
|
}
|
|
194
228
|
};
|
|
195
229
|
const create = createParam ? async (input, params) => {
|
|
196
230
|
const { data, error } = await createParam(convertObjectToCreate(input));
|
|
197
231
|
if (error) {
|
|
198
|
-
handleSetError(error, params,
|
|
232
|
+
await handleSetError(error, params, input, createParam, "create");
|
|
199
233
|
}
|
|
200
234
|
return data;
|
|
201
235
|
} : void 0;
|
|
@@ -203,45 +237,58 @@ function syncedKeel(props) {
|
|
|
203
237
|
const id = input.id;
|
|
204
238
|
const values = convertObjectToCreate(input);
|
|
205
239
|
delete values.id;
|
|
206
|
-
delete values.createdAt;
|
|
207
|
-
delete values.updatedAt;
|
|
208
240
|
if (!isEmpty(values)) {
|
|
209
241
|
const { data, error } = await updateParam({ where: { id }, values });
|
|
210
242
|
if (error) {
|
|
211
|
-
handleSetError(error, params,
|
|
243
|
+
await handleSetError(error, params, input, updateParam, "update");
|
|
212
244
|
}
|
|
213
245
|
return data;
|
|
214
246
|
}
|
|
215
247
|
} : void 0;
|
|
216
|
-
const deleteFn = deleteParam ? async (
|
|
217
|
-
const { data, error } = await deleteParam({ id });
|
|
248
|
+
const deleteFn = deleteParam ? async (value, params) => {
|
|
249
|
+
const { data, error } = await deleteParam({ id: value.id });
|
|
218
250
|
if (error) {
|
|
219
|
-
handleSetError(error, params,
|
|
251
|
+
await handleSetError(error, params, value, deleteParam, "delete");
|
|
220
252
|
}
|
|
221
253
|
return data;
|
|
222
254
|
} : void 0;
|
|
223
|
-
|
|
255
|
+
if (realtime) {
|
|
256
|
+
setupRealtime(props);
|
|
257
|
+
}
|
|
258
|
+
const subscribe = realtime ? (params) => {
|
|
224
259
|
let unsubscribe = void 0;
|
|
225
260
|
when(subscribeFnKey$, () => {
|
|
226
261
|
unsubscribe = subscribeFn(params);
|
|
227
262
|
});
|
|
263
|
+
const unsubscribeParam = subscribeParam == null ? void 0 : subscribeParam(params);
|
|
228
264
|
return () => {
|
|
229
265
|
unsubscribe == null ? void 0 : unsubscribe();
|
|
266
|
+
unsubscribeParam == null ? void 0 : unsubscribeParam();
|
|
230
267
|
};
|
|
231
|
-
};
|
|
268
|
+
} : subscribeParam;
|
|
232
269
|
return syncedCrud({
|
|
233
270
|
...rest,
|
|
234
271
|
as: asType,
|
|
272
|
+
mode: mode || "merge",
|
|
235
273
|
list,
|
|
236
274
|
create,
|
|
237
275
|
update,
|
|
238
276
|
delete: deleteFn,
|
|
239
|
-
waitFor: () =>
|
|
277
|
+
waitFor: () => {
|
|
278
|
+
ensureAuthToken(props);
|
|
279
|
+
return [requireAuth ? isAuthed$ : true, waitFor || true];
|
|
280
|
+
},
|
|
281
|
+
waitForSet: (params) => {
|
|
282
|
+
ensureAuthToken(props);
|
|
283
|
+
return [
|
|
284
|
+
requireAuth ? isAuthed$ : true,
|
|
285
|
+
() => waitForSet ? isFunction(waitForSet) ? waitForSet(params) : waitForSet : true
|
|
286
|
+
];
|
|
287
|
+
},
|
|
240
288
|
onSaved,
|
|
241
|
-
onSavedUpdate: "createdUpdatedAt",
|
|
242
289
|
fieldCreatedAt,
|
|
243
290
|
fieldUpdatedAt,
|
|
244
|
-
fieldDeleted
|
|
291
|
+
fieldDeleted,
|
|
245
292
|
changesSince,
|
|
246
293
|
updatePartial: true,
|
|
247
294
|
subscribe,
|
|
@@ -251,4 +298,4 @@ function syncedKeel(props) {
|
|
|
251
298
|
});
|
|
252
299
|
}
|
|
253
300
|
|
|
254
|
-
export { KeelKeys,
|
|
301
|
+
export { KeelKeys, generateKeelId, syncedKeel };
|
|
@@ -2,12 +2,17 @@ import { Observable } from '@legendapp/state';
|
|
|
2
2
|
import { SyncedOptions, SyncedOptionsGlobal, SyncedGetParams } from '@legendapp/state/sync';
|
|
3
3
|
import { SyncedCrudPropsBase, CrudAsOption, SyncedCrudReturnType, SyncedCrudPropsMany } from '@legendapp/state/sync-plugins/crud';
|
|
4
4
|
import { PostgrestQueryBuilder, PostgrestFilterBuilder } from '@supabase/postgrest-js';
|
|
5
|
-
import { SupabaseClient } from '@supabase/supabase-js';
|
|
5
|
+
import { SupabaseClient, PostgrestSingleResponse } from '@supabase/supabase-js';
|
|
6
|
+
import { FunctionsResponse } from '@supabase/functions-js';
|
|
6
7
|
|
|
8
|
+
type DatabaseOf<Client extends SupabaseClient> = Client extends SupabaseClient<infer TDB> ? TDB : never;
|
|
9
|
+
type SchemaNameOf<Client extends SupabaseClient> = keyof DatabaseOf<Client>;
|
|
10
|
+
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
11
|
+
type IsUnionOfStrings<T> = [T] extends [string] ? ([T] extends [UnionToIntersection<T>] ? false : true) : false;
|
|
7
12
|
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'];
|
|
13
|
+
type SupabaseTableOf<Client extends SupabaseClient, SchemaName extends SchemaNameOf<Client>> = DatabaseOf<Client>[SchemaName]['Tables'];
|
|
14
|
+
type SupabaseCollectionOf<Client extends SupabaseClient, SchemaName extends SchemaNameOf<Client>> = keyof SupabaseTableOf<Client, IsUnionOfStrings<SchemaName> extends true ? 'public' : SchemaName>;
|
|
15
|
+
type SupabaseRowOf<Client extends SupabaseClient, Collection extends SupabaseCollectionOf<Client, SchemaName>, SchemaName extends SchemaNameOf<Client>> = SupabaseTableOf<Client, SchemaName>[Collection]['Row'];
|
|
11
16
|
type SyncedSupabaseConfig<TRemote extends {
|
|
12
17
|
id: string | number;
|
|
13
18
|
}, TLocal> = Omit<SyncedCrudPropsBase<TRemote, TLocal>, 'create' | 'update' | 'delete'>;
|
|
@@ -20,20 +25,25 @@ interface SyncedSupabaseConfiguration extends Omit<SyncedSupabaseConfig<{
|
|
|
20
25
|
enabled?: Observable<boolean>;
|
|
21
26
|
as?: Exclude<CrudAsOption, 'value'>;
|
|
22
27
|
}
|
|
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> {
|
|
24
|
-
supabase
|
|
28
|
+
interface SyncedSupabaseProps<Client extends SupabaseClient<any, any>, Collection extends SupabaseCollectionOf<Client, SchemaName>, SchemaName extends SchemaNameOf<Client> = 'public', TOption extends CrudAsOption = 'object', TRemote extends SupabaseRowOf<Client, Collection, SchemaName> = SupabaseRowOf<Client, Collection, SchemaName>, TLocal = TRemote> extends SyncedSupabaseConfig<TRemote, TLocal>, Omit<SyncedCrudPropsMany<TRemote, TRemote, TOption>, 'list'> {
|
|
29
|
+
supabase?: Client;
|
|
25
30
|
collection: Collection;
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
schema?: SchemaName;
|
|
32
|
+
select?: (query: PostgrestQueryBuilder<SupabaseSchemaOf<Client>, SupabaseTableOf<Client, SchemaName>[Collection], Collection>) => PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>;
|
|
33
|
+
filter?: (select: PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>, params: SyncedGetParams<TRemote>) => PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>;
|
|
28
34
|
actions?: ('create' | 'read' | 'update' | 'delete')[];
|
|
29
35
|
realtime?: boolean | {
|
|
30
36
|
schema?: string;
|
|
31
37
|
filter?: string;
|
|
32
38
|
};
|
|
33
39
|
stringifyDates?: boolean;
|
|
40
|
+
list?: (...params: Parameters<Required<SyncedCrudPropsMany<TRemote, TLocal, TOption>>['list']>) => PromiseLike<PostgrestSingleResponse<TRemote[]>> | Promise<FunctionsResponse<NoInfer<TRemote>[]>>;
|
|
41
|
+
create?: (...params: Parameters<Required<SyncedCrudPropsBase<TRemote>>['create']>) => PromiseLike<PostgrestSingleResponse<TRemote>> | Promise<FunctionsResponse<NoInfer<TRemote>>>;
|
|
42
|
+
update?: (...params: Parameters<Required<SyncedCrudPropsBase<TRemote>>['update']>) => PromiseLike<PostgrestSingleResponse<TRemote>> | Promise<FunctionsResponse<NoInfer<TRemote>>>;
|
|
43
|
+
delete?: (...params: Parameters<Required<SyncedCrudPropsBase<TRemote>>['delete']>) => PromiseLike<PostgrestSingleResponse<TRemote>> | Promise<FunctionsResponse<NoInfer<TRemote>>>;
|
|
34
44
|
}
|
|
35
45
|
declare function getSyncedSupabaseConfiguration(): SyncedSupabaseConfiguration;
|
|
36
46
|
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>;
|
|
47
|
+
declare function syncedSupabase<Client extends SupabaseClient<any, any>, Collection extends SupabaseCollectionOf<Client, SchemaName> & string, SchemaName extends SchemaNameOf<Client> = 'public', 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
48
|
|
|
39
49
|
export { type SupabaseCollectionOf, type SupabaseRowOf, type SupabaseSchemaOf, type SupabaseTableOf, type SyncedSupabaseConfig, type SyncedSupabaseConfiguration, configureSyncedSupabase, getSyncedSupabaseConfiguration, syncedSupabase };
|
|
@@ -2,12 +2,17 @@ import { Observable } from '@legendapp/state';
|
|
|
2
2
|
import { SyncedOptions, SyncedOptionsGlobal, SyncedGetParams } from '@legendapp/state/sync';
|
|
3
3
|
import { SyncedCrudPropsBase, CrudAsOption, SyncedCrudReturnType, SyncedCrudPropsMany } from '@legendapp/state/sync-plugins/crud';
|
|
4
4
|
import { PostgrestQueryBuilder, PostgrestFilterBuilder } from '@supabase/postgrest-js';
|
|
5
|
-
import { SupabaseClient } from '@supabase/supabase-js';
|
|
5
|
+
import { SupabaseClient, PostgrestSingleResponse } from '@supabase/supabase-js';
|
|
6
|
+
import { FunctionsResponse } from '@supabase/functions-js';
|
|
6
7
|
|
|
8
|
+
type DatabaseOf<Client extends SupabaseClient> = Client extends SupabaseClient<infer TDB> ? TDB : never;
|
|
9
|
+
type SchemaNameOf<Client extends SupabaseClient> = keyof DatabaseOf<Client>;
|
|
10
|
+
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
11
|
+
type IsUnionOfStrings<T> = [T] extends [string] ? ([T] extends [UnionToIntersection<T>] ? false : true) : false;
|
|
7
12
|
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'];
|
|
13
|
+
type SupabaseTableOf<Client extends SupabaseClient, SchemaName extends SchemaNameOf<Client>> = DatabaseOf<Client>[SchemaName]['Tables'];
|
|
14
|
+
type SupabaseCollectionOf<Client extends SupabaseClient, SchemaName extends SchemaNameOf<Client>> = keyof SupabaseTableOf<Client, IsUnionOfStrings<SchemaName> extends true ? 'public' : SchemaName>;
|
|
15
|
+
type SupabaseRowOf<Client extends SupabaseClient, Collection extends SupabaseCollectionOf<Client, SchemaName>, SchemaName extends SchemaNameOf<Client>> = SupabaseTableOf<Client, SchemaName>[Collection]['Row'];
|
|
11
16
|
type SyncedSupabaseConfig<TRemote extends {
|
|
12
17
|
id: string | number;
|
|
13
18
|
}, TLocal> = Omit<SyncedCrudPropsBase<TRemote, TLocal>, 'create' | 'update' | 'delete'>;
|
|
@@ -20,20 +25,25 @@ interface SyncedSupabaseConfiguration extends Omit<SyncedSupabaseConfig<{
|
|
|
20
25
|
enabled?: Observable<boolean>;
|
|
21
26
|
as?: Exclude<CrudAsOption, 'value'>;
|
|
22
27
|
}
|
|
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> {
|
|
24
|
-
supabase
|
|
28
|
+
interface SyncedSupabaseProps<Client extends SupabaseClient<any, any>, Collection extends SupabaseCollectionOf<Client, SchemaName>, SchemaName extends SchemaNameOf<Client> = 'public', TOption extends CrudAsOption = 'object', TRemote extends SupabaseRowOf<Client, Collection, SchemaName> = SupabaseRowOf<Client, Collection, SchemaName>, TLocal = TRemote> extends SyncedSupabaseConfig<TRemote, TLocal>, Omit<SyncedCrudPropsMany<TRemote, TRemote, TOption>, 'list'> {
|
|
29
|
+
supabase?: Client;
|
|
25
30
|
collection: Collection;
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
schema?: SchemaName;
|
|
32
|
+
select?: (query: PostgrestQueryBuilder<SupabaseSchemaOf<Client>, SupabaseTableOf<Client, SchemaName>[Collection], Collection>) => PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>;
|
|
33
|
+
filter?: (select: PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>, params: SyncedGetParams<TRemote>) => PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>;
|
|
28
34
|
actions?: ('create' | 'read' | 'update' | 'delete')[];
|
|
29
35
|
realtime?: boolean | {
|
|
30
36
|
schema?: string;
|
|
31
37
|
filter?: string;
|
|
32
38
|
};
|
|
33
39
|
stringifyDates?: boolean;
|
|
40
|
+
list?: (...params: Parameters<Required<SyncedCrudPropsMany<TRemote, TLocal, TOption>>['list']>) => PromiseLike<PostgrestSingleResponse<TRemote[]>> | Promise<FunctionsResponse<NoInfer<TRemote>[]>>;
|
|
41
|
+
create?: (...params: Parameters<Required<SyncedCrudPropsBase<TRemote>>['create']>) => PromiseLike<PostgrestSingleResponse<TRemote>> | Promise<FunctionsResponse<NoInfer<TRemote>>>;
|
|
42
|
+
update?: (...params: Parameters<Required<SyncedCrudPropsBase<TRemote>>['update']>) => PromiseLike<PostgrestSingleResponse<TRemote>> | Promise<FunctionsResponse<NoInfer<TRemote>>>;
|
|
43
|
+
delete?: (...params: Parameters<Required<SyncedCrudPropsBase<TRemote>>['delete']>) => PromiseLike<PostgrestSingleResponse<TRemote>> | Promise<FunctionsResponse<NoInfer<TRemote>>>;
|
|
34
44
|
}
|
|
35
45
|
declare function getSyncedSupabaseConfiguration(): SyncedSupabaseConfiguration;
|
|
36
46
|
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>;
|
|
47
|
+
declare function syncedSupabase<Client extends SupabaseClient<any, any>, Collection extends SupabaseCollectionOf<Client, SchemaName> & string, SchemaName extends SchemaNameOf<Client> = 'public', 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
48
|
|
|
39
49
|
export { type SupabaseCollectionOf, type SupabaseRowOf, type SupabaseSchemaOf, type SupabaseTableOf, type SyncedSupabaseConfig, type SyncedSupabaseConfiguration, configureSyncedSupabase, getSyncedSupabaseConfiguration, syncedSupabase };
|