@legendapp/state 3.0.0-beta.2 → 3.0.0-beta.20
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/enableReactComponents.js +3 -1
- package/config/enableReactComponents.mjs +3 -1
- package/config/enableReactTracking.d.mts +2 -1
- package/config/enableReactTracking.d.ts +2 -1
- package/config/enableReactTracking.js +32 -13
- package/config/enableReactTracking.mjs +32 -13
- package/index.d.mts +13 -4
- package/index.d.ts +13 -4
- package/index.js +70 -22
- package/index.mjs +70 -22
- package/package.json +22 -1
- package/persist-plugins/async-storage.js +17 -9
- package/persist-plugins/async-storage.mjs +17 -9
- package/react-native.d.mts +4 -0
- package/react-native.d.ts +4 -0
- package/react-native.js +53 -0
- package/react-native.mjs +40 -0
- package/react-reactive/Components.d.mts +19 -0
- package/react-reactive/Components.d.ts +19 -0
- package/react-reactive/Components.js +53 -0
- package/react-reactive/Components.mjs +40 -0
- package/react-reactive/enableReactComponents.d.mts +3 -2
- package/react-reactive/enableReactComponents.d.ts +3 -2
- package/react-reactive/enableReactComponents.js +10 -3
- package/react-reactive/enableReactComponents.mjs +10 -3
- package/react-reactive/enableReactNativeComponents.d.mts +3 -20
- package/react-reactive/enableReactNativeComponents.d.ts +3 -20
- package/react-reactive/enableReactNativeComponents.js +8 -3
- package/react-reactive/enableReactNativeComponents.mjs +8 -3
- package/react-reactive/enableReactive.js +10 -3
- package/react-reactive/enableReactive.mjs +10 -3
- package/react-reactive/enableReactive.native.js +8 -3
- package/react-reactive/enableReactive.native.mjs +8 -3
- package/react-reactive/enableReactive.web.js +8 -3
- package/react-reactive/enableReactive.web.mjs +8 -3
- package/react-web.d.mts +6 -0
- package/react-web.d.ts +6 -0
- package/react-web.js +39 -0
- package/react-web.mjs +37 -0
- package/react.d.mts +38 -20
- package/react.d.ts +38 -20
- package/react.js +36 -23
- package/react.mjs +37 -25
- package/sync-plugins/crud.d.mts +24 -9
- package/sync-plugins/crud.d.ts +24 -9
- package/sync-plugins/crud.js +199 -108
- package/sync-plugins/crud.mjs +200 -109
- package/sync-plugins/firebase.d.mts +7 -3
- package/sync-plugins/firebase.d.ts +7 -3
- package/sync-plugins/firebase.js +4 -2
- package/sync-plugins/firebase.mjs +4 -2
- package/sync-plugins/keel.d.mts +9 -13
- package/sync-plugins/keel.d.ts +9 -13
- package/sync-plugins/keel.js +52 -41
- package/sync-plugins/keel.mjs +53 -37
- package/sync-plugins/supabase.d.mts +7 -3
- package/sync-plugins/supabase.d.ts +7 -3
- package/sync-plugins/supabase.js +87 -31
- package/sync-plugins/supabase.mjs +88 -32
- package/sync-plugins/tanstack-query.d.mts +5 -5
- package/sync-plugins/tanstack-query.d.ts +5 -5
- package/sync-plugins/tanstack-query.js +10 -1
- package/sync-plugins/tanstack-query.mjs +10 -1
- package/sync-plugins/tanstack-react-query.d.mts +4 -2
- package/sync-plugins/tanstack-react-query.d.ts +4 -2
- package/sync.d.mts +16 -8
- package/sync.d.ts +16 -8
- package/sync.js +267 -174
- package/sync.mjs +266 -174
- package/trace.js +5 -6
- package/trace.mjs +5 -6
- package/types/reactive-native.d.ts +19 -0
- package/types/reactive-web.d.ts +7 -0
package/sync-plugins/keel.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { SyncedGetSetSubscribeBaseParams
|
|
2
|
-
import { SyncedCrudPropsBase, SyncedCrudReturnType, CrudAsOption, SyncedCrudPropsSingle, CrudResult, SyncedCrudPropsMany } from '@legendapp/state/sync-plugins/crud';
|
|
1
|
+
import { SyncedGetSetSubscribeBaseParams } from '@legendapp/state/sync';
|
|
2
|
+
import { CrudErrorParams, SyncedCrudPropsBase, SyncedCrudReturnType, CrudAsOption, SyncedCrudPropsSingle, CrudResult, SyncedCrudPropsMany } from '@legendapp/state/sync-plugins/crud';
|
|
3
3
|
|
|
4
4
|
interface KeelObjectBase {
|
|
5
5
|
id: string;
|
|
@@ -13,6 +13,7 @@ type APIError = {
|
|
|
13
13
|
type: string;
|
|
14
14
|
message: string;
|
|
15
15
|
requestId?: string;
|
|
16
|
+
error?: unknown;
|
|
16
17
|
};
|
|
17
18
|
type APIResult<T> = Result<T, APIError>;
|
|
18
19
|
type Data<T> = {
|
|
@@ -24,7 +25,6 @@ type Err<U> = {
|
|
|
24
25
|
error: U;
|
|
25
26
|
};
|
|
26
27
|
type Result<T, U> = NonNullable<Data<T> | Err<U>>;
|
|
27
|
-
declare function generateKeelId(): string;
|
|
28
28
|
interface KeelGetParams {
|
|
29
29
|
}
|
|
30
30
|
interface KeelListParams<Where = {}> {
|
|
@@ -62,7 +62,7 @@ interface SyncedKeelPropsManyWhere<TRemote extends {
|
|
|
62
62
|
}, TLocal, AOption extends CrudAsOption, Where extends Record<string, any>> extends SyncedKeelPropsManyBase<TRemote, TLocal, AOption> {
|
|
63
63
|
list?: (params: KeelListParams<NoInfer<Where>>) => Promise<CrudResult<APIResult<{
|
|
64
64
|
results: TRemote[];
|
|
65
|
-
pageInfo
|
|
65
|
+
pageInfo?: any;
|
|
66
66
|
}>>>;
|
|
67
67
|
where?: Where | (() => Where);
|
|
68
68
|
}
|
|
@@ -71,7 +71,7 @@ interface SyncedKeelPropsManyNoWhere<TRemote extends {
|
|
|
71
71
|
}, TLocal, AOption extends CrudAsOption> extends SyncedKeelPropsManyBase<TRemote, TLocal, AOption> {
|
|
72
72
|
list?: (params: KeelListParams<{}>) => Promise<CrudResult<APIResult<{
|
|
73
73
|
results: TRemote[];
|
|
74
|
-
pageInfo
|
|
74
|
+
pageInfo?: any;
|
|
75
75
|
}>>>;
|
|
76
76
|
where?: never | {};
|
|
77
77
|
}
|
|
@@ -88,12 +88,8 @@ interface SyncedKeelPropsSingle<TRemote extends {
|
|
|
88
88
|
list?: never;
|
|
89
89
|
as?: never;
|
|
90
90
|
}
|
|
91
|
-
interface
|
|
92
|
-
type: 'create' | 'update' | 'delete';
|
|
93
|
-
params: SyncedSetParams<any>;
|
|
94
|
-
input: any;
|
|
91
|
+
interface KeelErrorParams extends CrudErrorParams {
|
|
95
92
|
action: string;
|
|
96
|
-
error: APIResult<any>['error'];
|
|
97
93
|
}
|
|
98
94
|
interface SyncedKeelPropsBase<TRemote extends {
|
|
99
95
|
id: string;
|
|
@@ -102,7 +98,7 @@ interface SyncedKeelPropsBase<TRemote extends {
|
|
|
102
98
|
create?: (i: NoInfer<Partial<TRemote>>) => Promise<APIResult<NoInfer<TRemote>>>;
|
|
103
99
|
update?: (params: {
|
|
104
100
|
where: any;
|
|
105
|
-
values?: Partial<TRemote
|
|
101
|
+
values?: Partial<NoInfer<TRemote>>;
|
|
106
102
|
}) => Promise<APIResult<TRemote>>;
|
|
107
103
|
delete?: (params: {
|
|
108
104
|
id: string;
|
|
@@ -113,7 +109,7 @@ interface SyncedKeelPropsBase<TRemote extends {
|
|
|
113
109
|
};
|
|
114
110
|
refreshAuth?: () => void | Promise<void>;
|
|
115
111
|
requireAuth?: boolean;
|
|
116
|
-
onError?: (error: Error,
|
|
112
|
+
onError?: (error: Error, params: KeelErrorParams) => void;
|
|
117
113
|
}
|
|
118
114
|
declare function syncedKeel<TRemote extends {
|
|
119
115
|
id: string;
|
|
@@ -122,4 +118,4 @@ declare function syncedKeel<TRemote extends {
|
|
|
122
118
|
id: string;
|
|
123
119
|
}, TLocal = TRemote, TOption extends CrudAsOption = 'object', Where extends Record<string, any> = {}>(props: SyncedKeelPropsBase<TRemote, TLocal> & SyncedKeelPropsMany<TRemote, TLocal, TOption, Where>): SyncedCrudReturnType<TLocal, Exclude<TOption, 'value'>>;
|
|
124
120
|
|
|
125
|
-
export { type KeelClient, type KeelGetParams, type KeelKey, KeelKeys, type KeelListParams, type KeelObjectBase, type KeelRealtimePlugin, type OmitKeelBuiltins, type SyncedKeelPropsBase,
|
|
121
|
+
export { type KeelClient, type KeelErrorParams, type KeelGetParams, type KeelKey, KeelKeys, type KeelListParams, type KeelObjectBase, type KeelRealtimePlugin, type OmitKeelBuiltins, type SyncedKeelPropsBase, syncedKeel };
|
package/sync-plugins/keel.js
CHANGED
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var state = require('@legendapp/state');
|
|
4
|
+
var sync = require('@legendapp/state/sync');
|
|
4
5
|
var crud = require('@legendapp/state/sync-plugins/crud');
|
|
5
|
-
var ksuid = require('ksuid');
|
|
6
|
-
|
|
7
|
-
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
-
|
|
9
|
-
var ksuid__default = /*#__PURE__*/_interopDefault(ksuid);
|
|
10
6
|
|
|
11
7
|
// src/sync-plugins/keel.ts
|
|
12
8
|
var KeelKeys = ["createdAt", "updatedAt"];
|
|
13
|
-
function generateKeelId() {
|
|
14
|
-
return ksuid__default.default.randomSync().string;
|
|
15
|
-
}
|
|
16
9
|
var modifiedClients = /* @__PURE__ */ new WeakSet();
|
|
17
10
|
var isAuthed$ = state.observable(false);
|
|
18
11
|
var isAuthing$ = state.observable(false);
|
|
@@ -52,12 +45,17 @@ async function ensureAuthToken(props, force) {
|
|
|
52
45
|
}
|
|
53
46
|
return isAuthed;
|
|
54
47
|
}
|
|
55
|
-
async function handleApiError(props, error
|
|
48
|
+
async function handleApiError(props, error) {
|
|
49
|
+
var _a;
|
|
56
50
|
if (error.type === "unauthorized" || error.type === "forbidden") {
|
|
57
51
|
console.warn("Keel token expired, refreshing...");
|
|
58
52
|
isAuthed$.set(false);
|
|
59
53
|
await ensureAuthToken(props);
|
|
54
|
+
return true;
|
|
55
|
+
} else if (((_a = error.error) == null ? void 0 : _a.message) === "Failed to fetch") {
|
|
56
|
+
throw error.error;
|
|
60
57
|
}
|
|
58
|
+
return false;
|
|
61
59
|
}
|
|
62
60
|
function convertObjectToCreate(item) {
|
|
63
61
|
const cloned = {};
|
|
@@ -97,7 +95,7 @@ function setupRealtime(props) {
|
|
|
97
95
|
}
|
|
98
96
|
}
|
|
99
97
|
var NumPerPage = 200;
|
|
100
|
-
async function getAllPages(props, listFn, params) {
|
|
98
|
+
async function getAllPages(props, listFn, params, listParams, onError) {
|
|
101
99
|
const allData = [];
|
|
102
100
|
let pageInfo = void 0;
|
|
103
101
|
const { first: firstParam } = params;
|
|
@@ -113,8 +111,17 @@ async function getAllPages(props, listFn, params) {
|
|
|
113
111
|
if (ret) {
|
|
114
112
|
const { data, error } = ret;
|
|
115
113
|
if (error) {
|
|
116
|
-
await handleApiError(props, error);
|
|
117
|
-
|
|
114
|
+
const handled = await handleApiError(props, error);
|
|
115
|
+
if (!handled) {
|
|
116
|
+
const err = new Error(error.message, { cause: { error } });
|
|
117
|
+
onError(err, {
|
|
118
|
+
getParams: listParams,
|
|
119
|
+
type: "get",
|
|
120
|
+
source: "list",
|
|
121
|
+
action: listFn.name || listFn.toString(),
|
|
122
|
+
retry: listParams
|
|
123
|
+
});
|
|
124
|
+
}
|
|
118
125
|
} else if (data) {
|
|
119
126
|
pageInfo = data.pageInfo;
|
|
120
127
|
allData.push(...data.results);
|
|
@@ -138,7 +145,6 @@ function syncedKeel(props) {
|
|
|
138
145
|
fieldDeleted,
|
|
139
146
|
realtime,
|
|
140
147
|
mode,
|
|
141
|
-
onError,
|
|
142
148
|
requireAuth = true,
|
|
143
149
|
...rest
|
|
144
150
|
} = props;
|
|
@@ -158,7 +164,7 @@ function syncedKeel(props) {
|
|
|
158
164
|
}
|
|
159
165
|
} : void 0;
|
|
160
166
|
const list = listParam ? async (listParams) => {
|
|
161
|
-
const { lastSync } = listParams;
|
|
167
|
+
const { lastSync, onError } = listParams;
|
|
162
168
|
const queryBySync = !!lastSync && changesSince === "last-sync";
|
|
163
169
|
const where = Object.assign(
|
|
164
170
|
queryBySync ? { updatedAt: { after: new Date(lastSync + 1) } } : {},
|
|
@@ -166,14 +172,14 @@ function syncedKeel(props) {
|
|
|
166
172
|
);
|
|
167
173
|
const params = { where, first };
|
|
168
174
|
realtimeState.current = {};
|
|
169
|
-
const promise = getAllPages(props, listParam, params);
|
|
175
|
+
const promise = getAllPages(props, listParam, params, listParams, onError);
|
|
170
176
|
if (realtime) {
|
|
171
177
|
setupSubscribe(listParams);
|
|
172
178
|
}
|
|
173
179
|
return promise;
|
|
174
180
|
} : void 0;
|
|
175
181
|
const get = getParam ? async (getParams) => {
|
|
176
|
-
const { refresh } = getParams;
|
|
182
|
+
const { refresh, onError } = getParams;
|
|
177
183
|
realtimeState.current = {};
|
|
178
184
|
const promise = getParam({ refresh });
|
|
179
185
|
if (realtime) {
|
|
@@ -181,7 +187,17 @@ function syncedKeel(props) {
|
|
|
181
187
|
}
|
|
182
188
|
const { data, error } = await promise;
|
|
183
189
|
if (error) {
|
|
184
|
-
|
|
190
|
+
const handled = await handleApiError(props, error);
|
|
191
|
+
if (!handled) {
|
|
192
|
+
const err = new Error(error.message, { cause: { error } });
|
|
193
|
+
onError(err, {
|
|
194
|
+
getParams,
|
|
195
|
+
type: "get",
|
|
196
|
+
source: "get",
|
|
197
|
+
action: getParam.name || getParam.toString(),
|
|
198
|
+
retry: getParams
|
|
199
|
+
});
|
|
200
|
+
}
|
|
185
201
|
} else {
|
|
186
202
|
return data;
|
|
187
203
|
}
|
|
@@ -198,7 +214,7 @@ function syncedKeel(props) {
|
|
|
198
214
|
};
|
|
199
215
|
const handleSetError = async (error, params, input, fn, from) => {
|
|
200
216
|
var _a, _b;
|
|
201
|
-
const {
|
|
217
|
+
const { update: update2, onError } = params;
|
|
202
218
|
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"))) {
|
|
203
219
|
if (__DEV__) {
|
|
204
220
|
console.log("Creating duplicate data already saved, just ignore.");
|
|
@@ -208,28 +224,25 @@ function syncedKeel(props) {
|
|
|
208
224
|
value: {},
|
|
209
225
|
mode: "assign"
|
|
210
226
|
});
|
|
211
|
-
} else if (from === "delete") {
|
|
212
|
-
if (
|
|
213
|
-
|
|
214
|
-
console.log("Deleting non-existing data, just ignore.");
|
|
215
|
-
}
|
|
216
|
-
params.cancelRetry = true;
|
|
217
|
-
}
|
|
218
|
-
} else if (error.type === "bad_request") {
|
|
219
|
-
onError == null ? void 0 : onError(new Error(error.message), params, {
|
|
220
|
-
error,
|
|
221
|
-
params,
|
|
222
|
-
input,
|
|
223
|
-
type: from,
|
|
224
|
-
action: fn.name || fn.toString()
|
|
225
|
-
});
|
|
226
|
-
if (retryNum > 4) {
|
|
227
|
-
params.cancelRetry = true;
|
|
227
|
+
} else if (from === "delete" && error.message === "record not found") {
|
|
228
|
+
if (__DEV__) {
|
|
229
|
+
console.log("Deleting non-existing data, just ignore.");
|
|
228
230
|
}
|
|
229
|
-
|
|
231
|
+
params.cancelRetry = true;
|
|
230
232
|
} else {
|
|
231
|
-
await handleApiError(props, error);
|
|
232
|
-
|
|
233
|
+
const handled = await handleApiError(props, error);
|
|
234
|
+
if (!handled) {
|
|
235
|
+
const err = new Error(error.message, { cause: { error } });
|
|
236
|
+
onError(err, {
|
|
237
|
+
setParams: params,
|
|
238
|
+
input,
|
|
239
|
+
type: "set",
|
|
240
|
+
source: from,
|
|
241
|
+
action: fn.name || fn.toString(),
|
|
242
|
+
retry: params,
|
|
243
|
+
revert: sync.createRevertChanges(params.value$, params.changes)
|
|
244
|
+
});
|
|
245
|
+
}
|
|
233
246
|
}
|
|
234
247
|
};
|
|
235
248
|
const create = createParam ? async (input, params) => {
|
|
@@ -274,6 +287,7 @@ function syncedKeel(props) {
|
|
|
274
287
|
} : subscribeParam;
|
|
275
288
|
return crud.syncedCrud({
|
|
276
289
|
...rest,
|
|
290
|
+
// Workaround for type errors
|
|
277
291
|
as: asType,
|
|
278
292
|
mode: mode || "merge",
|
|
279
293
|
list,
|
|
@@ -298,12 +312,9 @@ function syncedKeel(props) {
|
|
|
298
312
|
changesSince,
|
|
299
313
|
updatePartial: true,
|
|
300
314
|
subscribe,
|
|
301
|
-
generateId: generateKeelId,
|
|
302
|
-
// @ts-expect-error This errors because of the get/list union type
|
|
303
315
|
get
|
|
304
316
|
});
|
|
305
317
|
}
|
|
306
318
|
|
|
307
319
|
exports.KeelKeys = KeelKeys;
|
|
308
|
-
exports.generateKeelId = generateKeelId;
|
|
309
320
|
exports.syncedKeel = syncedKeel;
|
package/sync-plugins/keel.mjs
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import { observable, isFunction, when, batch, isEmpty } from '@legendapp/state';
|
|
2
|
+
import { createRevertChanges } from '@legendapp/state/sync';
|
|
2
3
|
import { syncedCrud } from '@legendapp/state/sync-plugins/crud';
|
|
3
|
-
import ksuid from 'ksuid';
|
|
4
4
|
|
|
5
5
|
// src/sync-plugins/keel.ts
|
|
6
6
|
var KeelKeys = ["createdAt", "updatedAt"];
|
|
7
|
-
function generateKeelId() {
|
|
8
|
-
return ksuid.randomSync().string;
|
|
9
|
-
}
|
|
10
7
|
var modifiedClients = /* @__PURE__ */ new WeakSet();
|
|
11
8
|
var isAuthed$ = observable(false);
|
|
12
9
|
var isAuthing$ = observable(false);
|
|
@@ -46,12 +43,17 @@ async function ensureAuthToken(props, force) {
|
|
|
46
43
|
}
|
|
47
44
|
return isAuthed;
|
|
48
45
|
}
|
|
49
|
-
async function handleApiError(props, error
|
|
46
|
+
async function handleApiError(props, error) {
|
|
47
|
+
var _a;
|
|
50
48
|
if (error.type === "unauthorized" || error.type === "forbidden") {
|
|
51
49
|
console.warn("Keel token expired, refreshing...");
|
|
52
50
|
isAuthed$.set(false);
|
|
53
51
|
await ensureAuthToken(props);
|
|
52
|
+
return true;
|
|
53
|
+
} else if (((_a = error.error) == null ? void 0 : _a.message) === "Failed to fetch") {
|
|
54
|
+
throw error.error;
|
|
54
55
|
}
|
|
56
|
+
return false;
|
|
55
57
|
}
|
|
56
58
|
function convertObjectToCreate(item) {
|
|
57
59
|
const cloned = {};
|
|
@@ -91,7 +93,7 @@ function setupRealtime(props) {
|
|
|
91
93
|
}
|
|
92
94
|
}
|
|
93
95
|
var NumPerPage = 200;
|
|
94
|
-
async function getAllPages(props, listFn, params) {
|
|
96
|
+
async function getAllPages(props, listFn, params, listParams, onError) {
|
|
95
97
|
const allData = [];
|
|
96
98
|
let pageInfo = void 0;
|
|
97
99
|
const { first: firstParam } = params;
|
|
@@ -107,8 +109,17 @@ async function getAllPages(props, listFn, params) {
|
|
|
107
109
|
if (ret) {
|
|
108
110
|
const { data, error } = ret;
|
|
109
111
|
if (error) {
|
|
110
|
-
await handleApiError(props, error);
|
|
111
|
-
|
|
112
|
+
const handled = await handleApiError(props, error);
|
|
113
|
+
if (!handled) {
|
|
114
|
+
const err = new Error(error.message, { cause: { error } });
|
|
115
|
+
onError(err, {
|
|
116
|
+
getParams: listParams,
|
|
117
|
+
type: "get",
|
|
118
|
+
source: "list",
|
|
119
|
+
action: listFn.name || listFn.toString(),
|
|
120
|
+
retry: listParams
|
|
121
|
+
});
|
|
122
|
+
}
|
|
112
123
|
} else if (data) {
|
|
113
124
|
pageInfo = data.pageInfo;
|
|
114
125
|
allData.push(...data.results);
|
|
@@ -132,7 +143,6 @@ function syncedKeel(props) {
|
|
|
132
143
|
fieldDeleted,
|
|
133
144
|
realtime,
|
|
134
145
|
mode,
|
|
135
|
-
onError,
|
|
136
146
|
requireAuth = true,
|
|
137
147
|
...rest
|
|
138
148
|
} = props;
|
|
@@ -152,7 +162,7 @@ function syncedKeel(props) {
|
|
|
152
162
|
}
|
|
153
163
|
} : void 0;
|
|
154
164
|
const list = listParam ? async (listParams) => {
|
|
155
|
-
const { lastSync } = listParams;
|
|
165
|
+
const { lastSync, onError } = listParams;
|
|
156
166
|
const queryBySync = !!lastSync && changesSince === "last-sync";
|
|
157
167
|
const where = Object.assign(
|
|
158
168
|
queryBySync ? { updatedAt: { after: new Date(lastSync + 1) } } : {},
|
|
@@ -160,14 +170,14 @@ function syncedKeel(props) {
|
|
|
160
170
|
);
|
|
161
171
|
const params = { where, first };
|
|
162
172
|
realtimeState.current = {};
|
|
163
|
-
const promise = getAllPages(props, listParam, params);
|
|
173
|
+
const promise = getAllPages(props, listParam, params, listParams, onError);
|
|
164
174
|
if (realtime) {
|
|
165
175
|
setupSubscribe(listParams);
|
|
166
176
|
}
|
|
167
177
|
return promise;
|
|
168
178
|
} : void 0;
|
|
169
179
|
const get = getParam ? async (getParams) => {
|
|
170
|
-
const { refresh } = getParams;
|
|
180
|
+
const { refresh, onError } = getParams;
|
|
171
181
|
realtimeState.current = {};
|
|
172
182
|
const promise = getParam({ refresh });
|
|
173
183
|
if (realtime) {
|
|
@@ -175,7 +185,17 @@ function syncedKeel(props) {
|
|
|
175
185
|
}
|
|
176
186
|
const { data, error } = await promise;
|
|
177
187
|
if (error) {
|
|
178
|
-
|
|
188
|
+
const handled = await handleApiError(props, error);
|
|
189
|
+
if (!handled) {
|
|
190
|
+
const err = new Error(error.message, { cause: { error } });
|
|
191
|
+
onError(err, {
|
|
192
|
+
getParams,
|
|
193
|
+
type: "get",
|
|
194
|
+
source: "get",
|
|
195
|
+
action: getParam.name || getParam.toString(),
|
|
196
|
+
retry: getParams
|
|
197
|
+
});
|
|
198
|
+
}
|
|
179
199
|
} else {
|
|
180
200
|
return data;
|
|
181
201
|
}
|
|
@@ -192,7 +212,7 @@ function syncedKeel(props) {
|
|
|
192
212
|
};
|
|
193
213
|
const handleSetError = async (error, params, input, fn, from) => {
|
|
194
214
|
var _a, _b;
|
|
195
|
-
const {
|
|
215
|
+
const { update: update2, onError } = params;
|
|
196
216
|
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"))) {
|
|
197
217
|
if (__DEV__) {
|
|
198
218
|
console.log("Creating duplicate data already saved, just ignore.");
|
|
@@ -202,28 +222,25 @@ function syncedKeel(props) {
|
|
|
202
222
|
value: {},
|
|
203
223
|
mode: "assign"
|
|
204
224
|
});
|
|
205
|
-
} else if (from === "delete") {
|
|
206
|
-
if (
|
|
207
|
-
|
|
208
|
-
console.log("Deleting non-existing data, just ignore.");
|
|
209
|
-
}
|
|
210
|
-
params.cancelRetry = true;
|
|
211
|
-
}
|
|
212
|
-
} else if (error.type === "bad_request") {
|
|
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
|
-
});
|
|
220
|
-
if (retryNum > 4) {
|
|
221
|
-
params.cancelRetry = true;
|
|
225
|
+
} else if (from === "delete" && error.message === "record not found") {
|
|
226
|
+
if (__DEV__) {
|
|
227
|
+
console.log("Deleting non-existing data, just ignore.");
|
|
222
228
|
}
|
|
223
|
-
|
|
229
|
+
params.cancelRetry = true;
|
|
224
230
|
} else {
|
|
225
|
-
await handleApiError(props, error);
|
|
226
|
-
|
|
231
|
+
const handled = await handleApiError(props, error);
|
|
232
|
+
if (!handled) {
|
|
233
|
+
const err = new Error(error.message, { cause: { error } });
|
|
234
|
+
onError(err, {
|
|
235
|
+
setParams: params,
|
|
236
|
+
input,
|
|
237
|
+
type: "set",
|
|
238
|
+
source: from,
|
|
239
|
+
action: fn.name || fn.toString(),
|
|
240
|
+
retry: params,
|
|
241
|
+
revert: createRevertChanges(params.value$, params.changes)
|
|
242
|
+
});
|
|
243
|
+
}
|
|
227
244
|
}
|
|
228
245
|
};
|
|
229
246
|
const create = createParam ? async (input, params) => {
|
|
@@ -268,6 +285,7 @@ function syncedKeel(props) {
|
|
|
268
285
|
} : subscribeParam;
|
|
269
286
|
return syncedCrud({
|
|
270
287
|
...rest,
|
|
288
|
+
// Workaround for type errors
|
|
271
289
|
as: asType,
|
|
272
290
|
mode: mode || "merge",
|
|
273
291
|
list,
|
|
@@ -292,10 +310,8 @@ function syncedKeel(props) {
|
|
|
292
310
|
changesSince,
|
|
293
311
|
updatePartial: true,
|
|
294
312
|
subscribe,
|
|
295
|
-
generateId: generateKeelId,
|
|
296
|
-
// @ts-expect-error This errors because of the get/list union type
|
|
297
313
|
get
|
|
298
314
|
});
|
|
299
315
|
}
|
|
300
316
|
|
|
301
|
-
export { KeelKeys,
|
|
317
|
+
export { KeelKeys, syncedKeel };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
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
|
-
import { PostgrestQueryBuilder, PostgrestFilterBuilder } from '@supabase/postgrest-js';
|
|
5
|
-
import { SupabaseClient, PostgrestSingleResponse } from '@supabase/supabase-js';
|
|
6
4
|
import { FunctionsResponse } from '@supabase/functions-js';
|
|
5
|
+
import { PostgrestFilterBuilder, PostgrestQueryBuilder } from '@supabase/postgrest-js';
|
|
6
|
+
import { SupabaseClient, PostgrestSingleResponse } from '@supabase/supabase-js';
|
|
7
7
|
|
|
8
8
|
type DatabaseOf<Client extends SupabaseClient> = Client extends SupabaseClient<infer TDB> ? TDB : never;
|
|
9
9
|
type SchemaNameOf<Client extends SupabaseClient> = keyof DatabaseOf<Client>;
|
|
@@ -29,7 +29,7 @@ interface SyncedSupabaseProps<Client extends SupabaseClient<any, any>, Collectio
|
|
|
29
29
|
supabase?: Client;
|
|
30
30
|
collection: Collection;
|
|
31
31
|
schema?: SchemaName;
|
|
32
|
-
select?:
|
|
32
|
+
select?: never;
|
|
33
33
|
filter?: (select: PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>, params: SyncedGetParams<TRemote>) => PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>;
|
|
34
34
|
actions?: ('create' | 'read' | 'update' | 'delete')[];
|
|
35
35
|
realtime?: boolean | {
|
|
@@ -42,8 +42,12 @@ interface SyncedSupabaseProps<Client extends SupabaseClient<any, any>, Collectio
|
|
|
42
42
|
update?: (...params: Parameters<Required<SyncedCrudPropsBase<TRemote>>['update']>) => PromiseLike<PostgrestSingleResponse<TRemote>> | Promise<FunctionsResponse<NoInfer<TRemote>>>;
|
|
43
43
|
delete?: (...params: Parameters<Required<SyncedCrudPropsBase<TRemote>>['delete']>) => PromiseLike<PostgrestSingleResponse<TRemote>> | Promise<FunctionsResponse<NoInfer<TRemote>>>;
|
|
44
44
|
}
|
|
45
|
+
interface SyncedSupabasePropsWithSelect<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 Omit<SyncedSupabaseProps<Client, Collection, SchemaName, TOption, TRemote, TLocal>, 'select'> {
|
|
46
|
+
select: (query: PostgrestQueryBuilder<SupabaseSchemaOf<Client>, SupabaseTableOf<Client, SchemaName>[Collection], Collection>) => PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>;
|
|
47
|
+
}
|
|
45
48
|
declare function getSyncedSupabaseConfiguration(): SyncedSupabaseConfiguration;
|
|
46
49
|
declare function configureSyncedSupabase(config: SyncedSupabaseConfiguration): void;
|
|
50
|
+
declare function syncedSupabase<Client extends SupabaseClient<any, any>, Collection extends SupabaseCollectionOf<Client, SchemaName> & string, SchemaName extends SchemaNameOf<Client> = 'public', AsOption extends CrudAsOption = 'object', TRemote = SupabaseRowOf<Client, Collection, SchemaName>, TLocal = TRemote>(props: SyncedSupabasePropsWithSelect<Client, Collection, SchemaName, AsOption, TRemote, TLocal>): SyncedCrudReturnType<TLocal, AsOption>;
|
|
47
51
|
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>;
|
|
48
52
|
|
|
49
53
|
export { type SupabaseCollectionOf, type SupabaseRowOf, type SupabaseSchemaOf, type SupabaseTableOf, type SyncedSupabaseConfig, type SyncedSupabaseConfiguration, configureSyncedSupabase, getSyncedSupabaseConfiguration, syncedSupabase };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
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
|
-
import { PostgrestQueryBuilder, PostgrestFilterBuilder } from '@supabase/postgrest-js';
|
|
5
|
-
import { SupabaseClient, PostgrestSingleResponse } from '@supabase/supabase-js';
|
|
6
4
|
import { FunctionsResponse } from '@supabase/functions-js';
|
|
5
|
+
import { PostgrestFilterBuilder, PostgrestQueryBuilder } from '@supabase/postgrest-js';
|
|
6
|
+
import { SupabaseClient, PostgrestSingleResponse } from '@supabase/supabase-js';
|
|
7
7
|
|
|
8
8
|
type DatabaseOf<Client extends SupabaseClient> = Client extends SupabaseClient<infer TDB> ? TDB : never;
|
|
9
9
|
type SchemaNameOf<Client extends SupabaseClient> = keyof DatabaseOf<Client>;
|
|
@@ -29,7 +29,7 @@ interface SyncedSupabaseProps<Client extends SupabaseClient<any, any>, Collectio
|
|
|
29
29
|
supabase?: Client;
|
|
30
30
|
collection: Collection;
|
|
31
31
|
schema?: SchemaName;
|
|
32
|
-
select?:
|
|
32
|
+
select?: never;
|
|
33
33
|
filter?: (select: PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>, params: SyncedGetParams<TRemote>) => PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>;
|
|
34
34
|
actions?: ('create' | 'read' | 'update' | 'delete')[];
|
|
35
35
|
realtime?: boolean | {
|
|
@@ -42,8 +42,12 @@ interface SyncedSupabaseProps<Client extends SupabaseClient<any, any>, Collectio
|
|
|
42
42
|
update?: (...params: Parameters<Required<SyncedCrudPropsBase<TRemote>>['update']>) => PromiseLike<PostgrestSingleResponse<TRemote>> | Promise<FunctionsResponse<NoInfer<TRemote>>>;
|
|
43
43
|
delete?: (...params: Parameters<Required<SyncedCrudPropsBase<TRemote>>['delete']>) => PromiseLike<PostgrestSingleResponse<TRemote>> | Promise<FunctionsResponse<NoInfer<TRemote>>>;
|
|
44
44
|
}
|
|
45
|
+
interface SyncedSupabasePropsWithSelect<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 Omit<SyncedSupabaseProps<Client, Collection, SchemaName, TOption, TRemote, TLocal>, 'select'> {
|
|
46
|
+
select: (query: PostgrestQueryBuilder<SupabaseSchemaOf<Client>, SupabaseTableOf<Client, SchemaName>[Collection], Collection>) => PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>;
|
|
47
|
+
}
|
|
45
48
|
declare function getSyncedSupabaseConfiguration(): SyncedSupabaseConfiguration;
|
|
46
49
|
declare function configureSyncedSupabase(config: SyncedSupabaseConfiguration): void;
|
|
50
|
+
declare function syncedSupabase<Client extends SupabaseClient<any, any>, Collection extends SupabaseCollectionOf<Client, SchemaName> & string, SchemaName extends SchemaNameOf<Client> = 'public', AsOption extends CrudAsOption = 'object', TRemote = SupabaseRowOf<Client, Collection, SchemaName>, TLocal = TRemote>(props: SyncedSupabasePropsWithSelect<Client, Collection, SchemaName, AsOption, TRemote, TLocal>): SyncedCrudReturnType<TLocal, AsOption>;
|
|
47
51
|
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>;
|
|
48
52
|
|
|
49
53
|
export { type SupabaseCollectionOf, type SupabaseRowOf, type SupabaseSchemaOf, type SupabaseTableOf, type SyncedSupabaseConfig, type SyncedSupabaseConfiguration, configureSyncedSupabase, getSyncedSupabaseConfiguration, syncedSupabase };
|