@legendapp/state 3.0.0-beta.4 → 3.0.0-beta.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/.DS_Store +0 -0
  2. package/README.md +2 -2
  3. package/config/enableReactComponents.js +3 -1
  4. package/config/enableReactComponents.mjs +3 -1
  5. package/config/enableReactTracking.d.mts +2 -1
  6. package/config/enableReactTracking.d.ts +2 -1
  7. package/config/enableReactTracking.js +32 -13
  8. package/config/enableReactTracking.mjs +32 -13
  9. package/index.d.mts +46 -8
  10. package/index.d.ts +46 -8
  11. package/index.js +267 -75
  12. package/index.mjs +267 -75
  13. package/package.json +35 -1
  14. package/persist-plugins/async-storage.js +17 -9
  15. package/persist-plugins/async-storage.mjs +17 -9
  16. package/persist-plugins/expo-sqlite.d.mts +19 -0
  17. package/persist-plugins/expo-sqlite.d.ts +19 -0
  18. package/persist-plugins/expo-sqlite.js +72 -0
  19. package/persist-plugins/expo-sqlite.mjs +69 -0
  20. package/persist-plugins/indexeddb.js +13 -3
  21. package/persist-plugins/indexeddb.mjs +13 -3
  22. package/react-native.d.mts +4 -0
  23. package/react-native.d.ts +4 -0
  24. package/react-native.js +53 -0
  25. package/react-native.mjs +40 -0
  26. package/react-reactive/Components.d.mts +19 -0
  27. package/react-reactive/Components.d.ts +19 -0
  28. package/react-reactive/Components.js +53 -0
  29. package/react-reactive/Components.mjs +40 -0
  30. package/react-reactive/enableReactComponents.d.mts +3 -2
  31. package/react-reactive/enableReactComponents.d.ts +3 -2
  32. package/react-reactive/enableReactComponents.js +10 -3
  33. package/react-reactive/enableReactComponents.mjs +10 -3
  34. package/react-reactive/enableReactNativeComponents.d.mts +3 -20
  35. package/react-reactive/enableReactNativeComponents.d.ts +3 -20
  36. package/react-reactive/enableReactNativeComponents.js +8 -3
  37. package/react-reactive/enableReactNativeComponents.mjs +8 -3
  38. package/react-reactive/enableReactive.js +10 -3
  39. package/react-reactive/enableReactive.mjs +10 -3
  40. package/react-reactive/enableReactive.native.js +8 -3
  41. package/react-reactive/enableReactive.native.mjs +8 -3
  42. package/react-reactive/enableReactive.web.js +8 -3
  43. package/react-reactive/enableReactive.web.mjs +8 -3
  44. package/react-web.d.mts +7 -0
  45. package/react-web.d.ts +7 -0
  46. package/react-web.js +39 -0
  47. package/react-web.mjs +37 -0
  48. package/react.d.mts +59 -26
  49. package/react.d.ts +59 -26
  50. package/react.js +136 -87
  51. package/react.mjs +135 -89
  52. package/sync-plugins/crud.d.mts +24 -9
  53. package/sync-plugins/crud.d.ts +24 -9
  54. package/sync-plugins/crud.js +267 -123
  55. package/sync-plugins/crud.mjs +268 -124
  56. package/sync-plugins/firebase.d.mts +7 -3
  57. package/sync-plugins/firebase.d.ts +7 -3
  58. package/sync-plugins/firebase.js +214 -64
  59. package/sync-plugins/firebase.mjs +215 -65
  60. package/sync-plugins/keel.d.mts +12 -13
  61. package/sync-plugins/keel.d.ts +12 -13
  62. package/sync-plugins/keel.js +60 -52
  63. package/sync-plugins/keel.mjs +61 -48
  64. package/sync-plugins/supabase.d.mts +10 -5
  65. package/sync-plugins/supabase.d.ts +10 -5
  66. package/sync-plugins/supabase.js +90 -33
  67. package/sync-plugins/supabase.mjs +91 -34
  68. package/sync-plugins/tanstack-query.d.mts +3 -3
  69. package/sync-plugins/tanstack-query.d.ts +3 -3
  70. package/sync-plugins/tanstack-query.js +1 -1
  71. package/sync-plugins/tanstack-query.mjs +1 -1
  72. package/sync.d.mts +17 -8
  73. package/sync.d.ts +17 -8
  74. package/sync.js +448 -307
  75. package/sync.mjs +446 -307
  76. package/trace.js +5 -6
  77. package/trace.mjs +5 -6
  78. package/types/reactive-native.d.ts +19 -0
  79. package/types/reactive-web.d.ts +7 -0
@@ -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, retry) {
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 = {};
@@ -81,23 +79,20 @@ function setupRealtime(props) {
81
79
  const { client } = props;
82
80
  if (client && !modifiedClients.has(client)) {
83
81
  modifiedClients.add(client);
84
- const queries = client.api.queries;
85
- Object.keys(queries).forEach((key) => {
86
- if (key.startsWith("list")) {
87
- const origFn = queries[key];
88
- queries[key] = (i) => {
89
- realtimeState.current = {
90
- lastAction: key,
91
- lastParams: i
92
- };
93
- return origFn(i);
82
+ const originalRawRequest = client.client.rawRequest;
83
+ client.client.rawRequest = (action, body) => {
84
+ if (action.startsWith("list")) {
85
+ realtimeState.current = {
86
+ lastAction: action,
87
+ lastParams: body
94
88
  };
95
89
  }
96
- });
90
+ return originalRawRequest(action, body);
91
+ };
97
92
  }
98
93
  }
99
94
  var NumPerPage = 200;
100
- async function getAllPages(props, listFn, params) {
95
+ async function getAllPages(props, listFn, params, listParams, onError) {
101
96
  const allData = [];
102
97
  let pageInfo = void 0;
103
98
  const { first: firstParam } = params;
@@ -113,8 +108,17 @@ async function getAllPages(props, listFn, params) {
113
108
  if (ret) {
114
109
  const { data, error } = ret;
115
110
  if (error) {
116
- await handleApiError(props, error);
117
- throw new Error(error.message);
111
+ const handled = await handleApiError(props, error);
112
+ if (!handled) {
113
+ const err = new Error(error.message, { cause: { error } });
114
+ onError(err, {
115
+ getParams: listParams,
116
+ type: "get",
117
+ source: "list",
118
+ action: listFn.name || listFn.toString(),
119
+ retry: listParams
120
+ });
121
+ }
118
122
  } else if (data) {
119
123
  pageInfo = data.pageInfo;
120
124
  allData.push(...data.results);
@@ -138,7 +142,6 @@ function syncedKeel(props) {
138
142
  fieldDeleted,
139
143
  realtime,
140
144
  mode,
141
- onError,
142
145
  requireAuth = true,
143
146
  ...rest
144
147
  } = props;
@@ -158,7 +161,7 @@ function syncedKeel(props) {
158
161
  }
159
162
  } : void 0;
160
163
  const list = listParam ? async (listParams) => {
161
- const { lastSync } = listParams;
164
+ const { lastSync, onError } = listParams;
162
165
  const queryBySync = !!lastSync && changesSince === "last-sync";
163
166
  const where = Object.assign(
164
167
  queryBySync ? { updatedAt: { after: new Date(lastSync + 1) } } : {},
@@ -166,14 +169,14 @@ function syncedKeel(props) {
166
169
  );
167
170
  const params = { where, first };
168
171
  realtimeState.current = {};
169
- const promise = getAllPages(props, listParam, params);
172
+ const promise = getAllPages(props, listParam, params, listParams, onError);
170
173
  if (realtime) {
171
174
  setupSubscribe(listParams);
172
175
  }
173
176
  return promise;
174
177
  } : void 0;
175
178
  const get = getParam ? async (getParams) => {
176
- const { refresh } = getParams;
179
+ const { refresh, onError } = getParams;
177
180
  realtimeState.current = {};
178
181
  const promise = getParam({ refresh });
179
182
  if (realtime) {
@@ -181,7 +184,17 @@ function syncedKeel(props) {
181
184
  }
182
185
  const { data, error } = await promise;
183
186
  if (error) {
184
- throw new Error(error.message);
187
+ const handled = await handleApiError(props, error);
188
+ if (!handled) {
189
+ const err = new Error(error.message, { cause: { error } });
190
+ onError(err, {
191
+ getParams,
192
+ type: "get",
193
+ source: "get",
194
+ action: getParam.name || getParam.toString(),
195
+ retry: getParams
196
+ });
197
+ }
185
198
  } else {
186
199
  return data;
187
200
  }
@@ -198,7 +211,7 @@ function syncedKeel(props) {
198
211
  };
199
212
  const handleSetError = async (error, params, input, fn, from) => {
200
213
  var _a, _b;
201
- const { retryNum, update: update2 } = params;
214
+ const { update: update2, onError } = params;
202
215
  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
216
  if (__DEV__) {
204
217
  console.log("Creating duplicate data already saved, just ignore.");
@@ -208,28 +221,25 @@ function syncedKeel(props) {
208
221
  value: {},
209
222
  mode: "assign"
210
223
  });
211
- } else if (from === "delete") {
212
- if (error.message === "record not found") {
213
- if (__DEV__) {
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;
224
+ } else if (from === "delete" && error.message === "record not found") {
225
+ if (__DEV__) {
226
+ console.log("Deleting non-existing data, just ignore.");
228
227
  }
229
- throw new Error(error.message, { cause: { input } });
228
+ params.cancelRetry = true;
230
229
  } else {
231
- await handleApiError(props, error);
232
- throw new Error(error.message, { cause: { input } });
230
+ const handled = await handleApiError(props, error);
231
+ if (!handled) {
232
+ const err = new Error(error.message, { cause: { error } });
233
+ onError(err, {
234
+ setParams: params,
235
+ input,
236
+ type: "set",
237
+ source: from,
238
+ action: fn.name || fn.toString(),
239
+ retry: params,
240
+ revert: sync.createRevertChanges(params.value$, params.changes)
241
+ });
242
+ }
233
243
  }
234
244
  };
235
245
  const create = createParam ? async (input, params) => {
@@ -274,6 +284,7 @@ function syncedKeel(props) {
274
284
  } : subscribeParam;
275
285
  return crud.syncedCrud({
276
286
  ...rest,
287
+ // Workaround for type errors
277
288
  as: asType,
278
289
  mode: mode || "merge",
279
290
  list,
@@ -298,12 +309,9 @@ function syncedKeel(props) {
298
309
  changesSince,
299
310
  updatePartial: true,
300
311
  subscribe,
301
- generateId: generateKeelId,
302
- // @ts-expect-error This errors because of the get/list union type
303
312
  get
304
313
  });
305
314
  }
306
315
 
307
316
  exports.KeelKeys = KeelKeys;
308
- exports.generateKeelId = generateKeelId;
309
317
  exports.syncedKeel = syncedKeel;
@@ -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, retry) {
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 = {};
@@ -75,23 +77,20 @@ function setupRealtime(props) {
75
77
  const { client } = props;
76
78
  if (client && !modifiedClients.has(client)) {
77
79
  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
86
- };
87
- return origFn(i);
80
+ const originalRawRequest = client.client.rawRequest;
81
+ client.client.rawRequest = (action, body) => {
82
+ if (action.startsWith("list")) {
83
+ realtimeState.current = {
84
+ lastAction: action,
85
+ lastParams: body
88
86
  };
89
87
  }
90
- });
88
+ return originalRawRequest(action, body);
89
+ };
91
90
  }
92
91
  }
93
92
  var NumPerPage = 200;
94
- async function getAllPages(props, listFn, params) {
93
+ async function getAllPages(props, listFn, params, listParams, onError) {
95
94
  const allData = [];
96
95
  let pageInfo = void 0;
97
96
  const { first: firstParam } = params;
@@ -107,8 +106,17 @@ async function getAllPages(props, listFn, params) {
107
106
  if (ret) {
108
107
  const { data, error } = ret;
109
108
  if (error) {
110
- await handleApiError(props, error);
111
- throw new Error(error.message);
109
+ const handled = await handleApiError(props, error);
110
+ if (!handled) {
111
+ const err = new Error(error.message, { cause: { error } });
112
+ onError(err, {
113
+ getParams: listParams,
114
+ type: "get",
115
+ source: "list",
116
+ action: listFn.name || listFn.toString(),
117
+ retry: listParams
118
+ });
119
+ }
112
120
  } else if (data) {
113
121
  pageInfo = data.pageInfo;
114
122
  allData.push(...data.results);
@@ -132,7 +140,6 @@ function syncedKeel(props) {
132
140
  fieldDeleted,
133
141
  realtime,
134
142
  mode,
135
- onError,
136
143
  requireAuth = true,
137
144
  ...rest
138
145
  } = props;
@@ -152,7 +159,7 @@ function syncedKeel(props) {
152
159
  }
153
160
  } : void 0;
154
161
  const list = listParam ? async (listParams) => {
155
- const { lastSync } = listParams;
162
+ const { lastSync, onError } = listParams;
156
163
  const queryBySync = !!lastSync && changesSince === "last-sync";
157
164
  const where = Object.assign(
158
165
  queryBySync ? { updatedAt: { after: new Date(lastSync + 1) } } : {},
@@ -160,14 +167,14 @@ function syncedKeel(props) {
160
167
  );
161
168
  const params = { where, first };
162
169
  realtimeState.current = {};
163
- const promise = getAllPages(props, listParam, params);
170
+ const promise = getAllPages(props, listParam, params, listParams, onError);
164
171
  if (realtime) {
165
172
  setupSubscribe(listParams);
166
173
  }
167
174
  return promise;
168
175
  } : void 0;
169
176
  const get = getParam ? async (getParams) => {
170
- const { refresh } = getParams;
177
+ const { refresh, onError } = getParams;
171
178
  realtimeState.current = {};
172
179
  const promise = getParam({ refresh });
173
180
  if (realtime) {
@@ -175,7 +182,17 @@ function syncedKeel(props) {
175
182
  }
176
183
  const { data, error } = await promise;
177
184
  if (error) {
178
- throw new Error(error.message);
185
+ const handled = await handleApiError(props, error);
186
+ if (!handled) {
187
+ const err = new Error(error.message, { cause: { error } });
188
+ onError(err, {
189
+ getParams,
190
+ type: "get",
191
+ source: "get",
192
+ action: getParam.name || getParam.toString(),
193
+ retry: getParams
194
+ });
195
+ }
179
196
  } else {
180
197
  return data;
181
198
  }
@@ -192,7 +209,7 @@ function syncedKeel(props) {
192
209
  };
193
210
  const handleSetError = async (error, params, input, fn, from) => {
194
211
  var _a, _b;
195
- const { retryNum, update: update2 } = params;
212
+ const { update: update2, onError } = params;
196
213
  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
214
  if (__DEV__) {
198
215
  console.log("Creating duplicate data already saved, just ignore.");
@@ -202,28 +219,25 @@ function syncedKeel(props) {
202
219
  value: {},
203
220
  mode: "assign"
204
221
  });
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
- }
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;
222
+ } else if (from === "delete" && error.message === "record not found") {
223
+ if (__DEV__) {
224
+ console.log("Deleting non-existing data, just ignore.");
222
225
  }
223
- throw new Error(error.message, { cause: { input } });
226
+ params.cancelRetry = true;
224
227
  } else {
225
- await handleApiError(props, error);
226
- throw new Error(error.message, { cause: { input } });
228
+ const handled = await handleApiError(props, error);
229
+ if (!handled) {
230
+ const err = new Error(error.message, { cause: { error } });
231
+ onError(err, {
232
+ setParams: params,
233
+ input,
234
+ type: "set",
235
+ source: from,
236
+ action: fn.name || fn.toString(),
237
+ retry: params,
238
+ revert: createRevertChanges(params.value$, params.changes)
239
+ });
240
+ }
227
241
  }
228
242
  };
229
243
  const create = createParam ? async (input, params) => {
@@ -268,6 +282,7 @@ function syncedKeel(props) {
268
282
  } : subscribeParam;
269
283
  return syncedCrud({
270
284
  ...rest,
285
+ // Workaround for type errors
271
286
  as: asType,
272
287
  mode: mode || "merge",
273
288
  list,
@@ -292,10 +307,8 @@ function syncedKeel(props) {
292
307
  changesSince,
293
308
  updatePartial: true,
294
309
  subscribe,
295
- generateId: generateKeelId,
296
- // @ts-expect-error This errors because of the get/list union type
297
310
  get
298
311
  });
299
312
  }
300
313
 
301
- export { KeelKeys, generateKeelId, syncedKeel };
314
+ 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>;
@@ -11,7 +11,8 @@ type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
11
11
  type IsUnionOfStrings<T> = [T] extends [string] ? ([T] extends [UnionToIntersection<T>] ? false : true) : false;
12
12
  type SupabaseSchemaOf<Client extends SupabaseClient> = Client extends SupabaseClient<infer _, infer __, infer Schema> ? Schema : never;
13
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>;
14
+ type SupabaseViewOf<Client extends SupabaseClient, SchemaName extends SchemaNameOf<Client>> = DatabaseOf<Client>[SchemaName]['Views'];
15
+ type SupabaseCollectionOf<Client extends SupabaseClient, SchemaName extends SchemaNameOf<Client>> = keyof SupabaseTableOf<Client, IsUnionOfStrings<SchemaName> extends true ? 'public' : SchemaName> | keyof SupabaseViewOf<Client, IsUnionOfStrings<SchemaName> extends true ? 'public' : SchemaName>;
15
16
  type SupabaseRowOf<Client extends SupabaseClient, Collection extends SupabaseCollectionOf<Client, SchemaName>, SchemaName extends SchemaNameOf<Client>> = SupabaseTableOf<Client, SchemaName>[Collection]['Row'];
16
17
  type SyncedSupabaseConfig<TRemote extends {
17
18
  id: string | number;
@@ -29,7 +30,7 @@ interface SyncedSupabaseProps<Client extends SupabaseClient<any, any>, Collectio
29
30
  supabase?: Client;
30
31
  collection: Collection;
31
32
  schema?: SchemaName;
32
- select?: (query: PostgrestQueryBuilder<SupabaseSchemaOf<Client>, SupabaseTableOf<Client, SchemaName>[Collection], Collection>) => PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>;
33
+ select?: never;
33
34
  filter?: (select: PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>, params: SyncedGetParams<TRemote>) => PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>;
34
35
  actions?: ('create' | 'read' | 'update' | 'delete')[];
35
36
  realtime?: boolean | {
@@ -42,8 +43,12 @@ interface SyncedSupabaseProps<Client extends SupabaseClient<any, any>, Collectio
42
43
  update?: (...params: Parameters<Required<SyncedCrudPropsBase<TRemote>>['update']>) => PromiseLike<PostgrestSingleResponse<TRemote>> | Promise<FunctionsResponse<NoInfer<TRemote>>>;
43
44
  delete?: (...params: Parameters<Required<SyncedCrudPropsBase<TRemote>>['delete']>) => PromiseLike<PostgrestSingleResponse<TRemote>> | Promise<FunctionsResponse<NoInfer<TRemote>>>;
44
45
  }
46
+ 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'> {
47
+ select: (query: PostgrestQueryBuilder<SupabaseSchemaOf<Client>, SupabaseTableOf<Client, SchemaName>[Collection], Collection>) => PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>;
48
+ }
45
49
  declare function getSyncedSupabaseConfiguration(): SyncedSupabaseConfiguration;
46
50
  declare function configureSyncedSupabase(config: SyncedSupabaseConfiguration): void;
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 = SupabaseRowOf<Client, Collection, SchemaName>, TLocal = TRemote>(props: SyncedSupabasePropsWithSelect<Client, Collection, SchemaName, AsOption, TRemote, TLocal>): SyncedCrudReturnType<TLocal, AsOption>;
47
52
  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
53
 
49
- export { type SupabaseCollectionOf, type SupabaseRowOf, type SupabaseSchemaOf, type SupabaseTableOf, type SyncedSupabaseConfig, type SyncedSupabaseConfiguration, configureSyncedSupabase, getSyncedSupabaseConfiguration, syncedSupabase };
54
+ export { type SupabaseCollectionOf, type SupabaseRowOf, type SupabaseSchemaOf, type SupabaseTableOf, type SupabaseViewOf, 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>;
@@ -11,7 +11,8 @@ type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
11
11
  type IsUnionOfStrings<T> = [T] extends [string] ? ([T] extends [UnionToIntersection<T>] ? false : true) : false;
12
12
  type SupabaseSchemaOf<Client extends SupabaseClient> = Client extends SupabaseClient<infer _, infer __, infer Schema> ? Schema : never;
13
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>;
14
+ type SupabaseViewOf<Client extends SupabaseClient, SchemaName extends SchemaNameOf<Client>> = DatabaseOf<Client>[SchemaName]['Views'];
15
+ type SupabaseCollectionOf<Client extends SupabaseClient, SchemaName extends SchemaNameOf<Client>> = keyof SupabaseTableOf<Client, IsUnionOfStrings<SchemaName> extends true ? 'public' : SchemaName> | keyof SupabaseViewOf<Client, IsUnionOfStrings<SchemaName> extends true ? 'public' : SchemaName>;
15
16
  type SupabaseRowOf<Client extends SupabaseClient, Collection extends SupabaseCollectionOf<Client, SchemaName>, SchemaName extends SchemaNameOf<Client>> = SupabaseTableOf<Client, SchemaName>[Collection]['Row'];
16
17
  type SyncedSupabaseConfig<TRemote extends {
17
18
  id: string | number;
@@ -29,7 +30,7 @@ interface SyncedSupabaseProps<Client extends SupabaseClient<any, any>, Collectio
29
30
  supabase?: Client;
30
31
  collection: Collection;
31
32
  schema?: SchemaName;
32
- select?: (query: PostgrestQueryBuilder<SupabaseSchemaOf<Client>, SupabaseTableOf<Client, SchemaName>[Collection], Collection>) => PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>;
33
+ select?: never;
33
34
  filter?: (select: PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>, params: SyncedGetParams<TRemote>) => PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>;
34
35
  actions?: ('create' | 'read' | 'update' | 'delete')[];
35
36
  realtime?: boolean | {
@@ -42,8 +43,12 @@ interface SyncedSupabaseProps<Client extends SupabaseClient<any, any>, Collectio
42
43
  update?: (...params: Parameters<Required<SyncedCrudPropsBase<TRemote>>['update']>) => PromiseLike<PostgrestSingleResponse<TRemote>> | Promise<FunctionsResponse<NoInfer<TRemote>>>;
43
44
  delete?: (...params: Parameters<Required<SyncedCrudPropsBase<TRemote>>['delete']>) => PromiseLike<PostgrestSingleResponse<TRemote>> | Promise<FunctionsResponse<NoInfer<TRemote>>>;
44
45
  }
46
+ 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'> {
47
+ select: (query: PostgrestQueryBuilder<SupabaseSchemaOf<Client>, SupabaseTableOf<Client, SchemaName>[Collection], Collection>) => PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>;
48
+ }
45
49
  declare function getSyncedSupabaseConfiguration(): SyncedSupabaseConfiguration;
46
50
  declare function configureSyncedSupabase(config: SyncedSupabaseConfiguration): void;
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 = SupabaseRowOf<Client, Collection, SchemaName>, TLocal = TRemote>(props: SyncedSupabasePropsWithSelect<Client, Collection, SchemaName, AsOption, TRemote, TLocal>): SyncedCrudReturnType<TLocal, AsOption>;
47
52
  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
53
 
49
- export { type SupabaseCollectionOf, type SupabaseRowOf, type SupabaseSchemaOf, type SupabaseTableOf, type SyncedSupabaseConfig, type SyncedSupabaseConfiguration, configureSyncedSupabase, getSyncedSupabaseConfiguration, syncedSupabase };
54
+ export { type SupabaseCollectionOf, type SupabaseRowOf, type SupabaseSchemaOf, type SupabaseTableOf, type SupabaseViewOf, type SyncedSupabaseConfig, type SyncedSupabaseConfiguration, configureSyncedSupabase, getSyncedSupabaseConfiguration, syncedSupabase };