@basictech/react 0.7.0-beta.2 → 0.7.0-beta.4

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/dist/index.mjs CHANGED
@@ -250,363 +250,8 @@ var BasicSync = class extends Dexie2 {
250
250
  }
251
251
  };
252
252
 
253
- // src/db_ts.ts
254
- var DBError = class extends Error {
255
- constructor(message, status, response, originalError) {
256
- super(message);
257
- this.status = status;
258
- this.response = response;
259
- this.originalError = originalError;
260
- this.name = "DBError";
261
- }
262
- };
263
- var QueryBuilder = class {
264
- constructor(tableClient, tableSchema) {
265
- this.tableClient = tableClient;
266
- this.tableSchema = tableSchema;
267
- }
268
- params = {};
269
- // Reserved fields that are always allowed
270
- reservedFields = ["created_at", "updated_at", "id"];
271
- // Validate field existence in schema
272
- validateField(field) {
273
- if (this.tableSchema && !this.reservedFields.includes(field)) {
274
- if (!this.tableSchema.fields || !(field in this.tableSchema.fields)) {
275
- throw new Error(`Invalid field: "${field}". Field does not exist in table schema.`);
276
- }
277
- }
278
- }
279
- // Validate operator based on field type
280
- validateOperator(field, operator, value) {
281
- if (!this.tableSchema || this.reservedFields.includes(field)) {
282
- return;
283
- }
284
- const fieldInfo = this.tableSchema.fields[field];
285
- if (!fieldInfo)
286
- return;
287
- switch (operator) {
288
- case "gt":
289
- case "gte":
290
- case "lt":
291
- case "lte":
292
- if (fieldInfo.type !== "number" && fieldInfo.type !== "string") {
293
- throw new Error(`Operator "${operator}" can only be used with number or string fields. Field "${field}" is type "${fieldInfo.type}".`);
294
- }
295
- break;
296
- case "like":
297
- case "ilike":
298
- if (fieldInfo.type !== "string") {
299
- throw new Error(`Operator "${operator}" can only be used with string fields. Field "${field}" is type "${fieldInfo.type}".`);
300
- }
301
- if (typeof value !== "string") {
302
- throw new Error(`Operator "${operator}" requires a string value. Received: ${typeof value}`);
303
- }
304
- break;
305
- case "in":
306
- if (!Array.isArray(value)) {
307
- throw new Error(`Operator "in" requires an array value. Received: ${typeof value}`);
308
- }
309
- break;
310
- case "is":
311
- if (value !== null && typeof value !== "boolean") {
312
- throw new Error(`Operator "is" requires null or boolean. Received: ${typeof value}`);
313
- }
314
- break;
315
- }
316
- }
317
- // Add ordering to query with schema validation
318
- order(field, direction = "asc") {
319
- this.validateField(field);
320
- this.params.order = `${field}.${direction}`;
321
- return this;
322
- }
323
- // Add filtering to query
324
- filter(conditions) {
325
- if (!this.params.filters) {
326
- this.params.filters = {};
327
- }
328
- for (const [field, condition] of Object.entries(conditions)) {
329
- this.validateField(field);
330
- if (condition === null || typeof condition !== "object") {
331
- this.params.filters[field] = condition;
332
- } else {
333
- this.params.filters[field] = condition;
334
- }
335
- }
336
- return this;
337
- }
338
- // Add limit to query
339
- limit(count) {
340
- this.params.limit = count;
341
- return this;
342
- }
343
- // Add offset to query for pagination
344
- offset(count) {
345
- this.params.offset = count;
346
- return this;
347
- }
348
- // Auto-execute when awaited
349
- then(onfulfilled, onrejected) {
350
- return this.tableClient.executeQuery(this.params).then(onfulfilled, onrejected);
351
- }
352
- // Auto-execute when awaited with catch
353
- catch(onrejected) {
354
- return this.tableClient.executeQuery(this.params).catch(onrejected);
355
- }
356
- // Auto-execute when awaited with finally
357
- finally(onfinally) {
358
- return this.tableClient.executeQuery(this.params).finally(onfinally);
359
- }
360
- };
361
- var TableClient = class {
362
- constructor(baseUrl, projectId, token, table, getToken, schema) {
363
- this.baseUrl = baseUrl;
364
- this.projectId = projectId;
365
- this.token = token;
366
- this.table = table;
367
- this.getToken = getToken;
368
- this.schema = schema;
369
- if (schema && schema.tables && schema.tables[table]) {
370
- this.tableSchema = schema.tables[table];
371
- }
372
- }
373
- tableSchema;
374
- async headers() {
375
- const token = await this.getToken();
376
- return {
377
- Authorization: `Bearer ${token}`,
378
- "Content-Type": "application/json"
379
- };
380
- }
381
- async handleRequest(request) {
382
- try {
383
- const res = await request;
384
- if (!res.ok) {
385
- let errorMessage = `Request failed with status ${res.status}`;
386
- let errorData;
387
- try {
388
- const json2 = await res.json();
389
- errorData = json2;
390
- if (json2.error || json2.message) {
391
- const errorDetails = typeof json2.error === "object" ? JSON.stringify(json2.error) : json2.error;
392
- const messageDetails = typeof json2.message === "object" ? JSON.stringify(json2.message) : json2.message;
393
- errorMessage = `${res.status} ${res.statusText}: ${messageDetails || errorDetails || "Unknown error"}`;
394
- }
395
- } catch (e) {
396
- console.log("Failed to parse error response:", e);
397
- errorMessage = `${res.status} ${res.statusText}`;
398
- }
399
- throw new DBError(
400
- errorMessage,
401
- res.status,
402
- errorData
403
- );
404
- }
405
- const json = await res.json();
406
- return json.data;
407
- } catch (error) {
408
- console.log("Caught error:", error);
409
- if (error instanceof Error) {
410
- console.log("Error type:", error.constructor.name);
411
- console.log("Error stack:", error.stack);
412
- }
413
- if (error instanceof DBError) {
414
- throw error;
415
- }
416
- if (error instanceof TypeError && error.message === "Network request failed") {
417
- throw new DBError(
418
- "Network request failed. Please check your internet connection and try again.",
419
- void 0,
420
- void 0,
421
- error
422
- );
423
- }
424
- throw new DBError(
425
- `Unexpected error: ${error instanceof Error ? error.message : "Unknown error"}`,
426
- void 0,
427
- void 0,
428
- error instanceof Error ? error : void 0
429
- );
430
- }
431
- }
432
- // Build query string from query options
433
- buildQueryParams(query) {
434
- if (!query)
435
- return "";
436
- const params = [];
437
- if (query.id) {
438
- params.push(`id=${query.id}`);
439
- }
440
- if (query.filters) {
441
- for (const [field, condition] of Object.entries(query.filters)) {
442
- this.addFilterParam(params, field, condition);
443
- }
444
- }
445
- if (query.order) {
446
- params.push(`order=${query.order}`);
447
- }
448
- if (query.limit !== void 0 && query.limit >= 0) {
449
- params.push(`limit=${query.limit}`);
450
- }
451
- if (query.offset !== void 0 && query.offset >= 0) {
452
- params.push(`offset=${query.offset}`);
453
- }
454
- return params.length > 0 ? `?${params.join("&")}` : "";
455
- }
456
- // Helper method to build filter parameters
457
- addFilterParam(params, field, condition, negate = false) {
458
- if (condition === null || typeof condition !== "object") {
459
- if (condition === null) {
460
- params.push(`${field}=${negate ? "not." : ""}is.null`);
461
- } else if (typeof condition === "boolean") {
462
- params.push(`${field}=${negate ? "not." : ""}is.${condition}`);
463
- } else if (typeof condition === "number") {
464
- params.push(`${field}=${negate ? "not." : ""}eq.${condition}`);
465
- } else {
466
- params.push(`${field}=${negate ? "not." : ""}eq.${encodeURIComponent(String(condition))}`);
467
- }
468
- return;
469
- }
470
- const operatorObj = condition;
471
- if (operatorObj.not) {
472
- this.addFilterParam(params, field, operatorObj.not, true);
473
- return;
474
- }
475
- for (const [op, value] of Object.entries(operatorObj)) {
476
- if (op === "not")
477
- continue;
478
- const operator = op;
479
- if (value === null) {
480
- params.push(`${field}=${negate ? "not." : ""}is.null`);
481
- } else if (operator === "in" && Array.isArray(value)) {
482
- params.push(`${field}=${negate ? "not." : ""}in.${value.join(",")}`);
483
- } else if (operator === "is") {
484
- if (typeof value === "boolean") {
485
- params.push(`${field}=${negate ? "not." : ""}is.${value}`);
486
- } else {
487
- params.push(`${field}=${negate ? "not." : ""}is.null`);
488
- }
489
- } else {
490
- const paramValue = typeof value === "string" ? encodeURIComponent(value) : String(value);
491
- params.push(`${field}=${negate ? "not." : ""}${operator}.${paramValue}`);
492
- }
493
- }
494
- }
495
- // Internal method to execute a query with options
496
- async executeQuery(options) {
497
- const params = this.buildQueryParams(options);
498
- const headers = await this.headers();
499
- return this.handleRequest(
500
- fetch(`${this.baseUrl}/account/${this.projectId}/db/${this.table}${params}`, {
501
- headers
502
- })
503
- );
504
- }
505
- // Public method to start building a query
506
- getAll() {
507
- return new QueryBuilder(this, this.tableSchema);
508
- }
509
- // Get a specific item by ID
510
- async get(id) {
511
- const headers = await this.headers();
512
- return this.handleRequest(
513
- fetch(`${this.baseUrl}/account/${this.projectId}/db/${this.table}/${id}`, {
514
- headers
515
- })
516
- );
517
- }
518
- async create(value) {
519
- const headers = await this.headers();
520
- return this.handleRequest(
521
- fetch(`${this.baseUrl}/account/${this.projectId}/db/${this.table}`, {
522
- method: "POST",
523
- headers,
524
- body: JSON.stringify({ value })
525
- })
526
- );
527
- }
528
- async update(id, value) {
529
- const headers = await this.headers();
530
- return this.handleRequest(
531
- fetch(`${this.baseUrl}/account/${this.projectId}/db/${this.table}/${id}`, {
532
- method: "PATCH",
533
- headers,
534
- body: JSON.stringify({ value })
535
- })
536
- );
537
- }
538
- async replace(id, value) {
539
- const headers = await this.headers();
540
- return this.handleRequest(
541
- fetch(`${this.baseUrl}/account/${this.projectId}/db/${this.table}/${id}`, {
542
- method: "PUT",
543
- headers,
544
- body: JSON.stringify({ value })
545
- })
546
- );
547
- }
548
- async delete(id) {
549
- const token = await this.getToken();
550
- const headers = {
551
- Authorization: `Bearer ${token}`
552
- };
553
- return this.handleRequest(
554
- fetch(`${this.baseUrl}/account/${this.projectId}/db/${this.table}/${id}`, {
555
- method: "DELETE",
556
- headers
557
- })
558
- );
559
- }
560
- };
561
- var BasicDBSDK = class {
562
- projectId;
563
- getToken;
564
- baseUrl;
565
- schema;
566
- tableNames;
567
- constructor(config) {
568
- this.projectId = config.project_id;
569
- if (config.getToken) {
570
- this.getToken = config.getToken;
571
- } else if (config.token) {
572
- this.getToken = async () => config.token;
573
- } else {
574
- throw new Error("Either token or getToken must be provided");
575
- }
576
- this.baseUrl = config.baseUrl || "https://api.basic.tech";
577
- this.schema = config.schema;
578
- this.tableNames = Object.keys(this.schema.tables);
579
- }
580
- // Primary method - table access
581
- table(name) {
582
- if (!this.tableNames.includes(name)) {
583
- throw new Error(`Table '${name}' not found in schema. Available tables: ${this.tableNames.join(", ")}`);
584
- }
585
- return new TableClient(
586
- this.baseUrl,
587
- this.projectId,
588
- "",
589
- // Empty placeholder, will be replaced in headers() method
590
- name,
591
- this.getToken,
592
- this.schema
593
- // Pass the entire schema to the TableClient
594
- );
595
- }
596
- get tables() {
597
- return {};
598
- }
599
- fields(table) {
600
- const tableSchema = this.schema.tables[table];
601
- if (!tableSchema) {
602
- throw new Error(`Table '${table}' not found in schema`);
603
- }
604
- return Object.keys(tableSchema.fields);
605
- }
606
- };
607
-
608
253
  // package.json
609
- var version = "0.7.0-beta.1";
254
+ var version = "0.7.0-beta.3";
610
255
 
611
256
  // src/updater/versionUpdater.ts
612
257
  var VersionUpdater = class {
@@ -749,6 +394,7 @@ var STORAGE_KEYS = {
749
394
  REFRESH_TOKEN: "basic_refresh_token",
750
395
  USER_INFO: "basic_user_info",
751
396
  AUTH_STATE: "basic_auth_state",
397
+ REDIRECT_URI: "basic_redirect_uri",
752
398
  DEBUG: "basic_debug"
753
399
  };
754
400
  function getCookie(name) {
@@ -946,6 +592,10 @@ async function validateAndCheckSchema(schema) {
946
592
 
947
593
  // src/AuthContext.tsx
948
594
  import { jsx, jsxs } from "react/jsx-runtime";
595
+ var DEFAULT_AUTH_CONFIG = {
596
+ scopes: "profile email app:admin",
597
+ server_url: "https://api.basic.tech"
598
+ };
949
599
  var BasicContext = createContext({
950
600
  unicorn: "\u{1F984}",
951
601
  isAuthReady: false,
@@ -959,7 +609,6 @@ var BasicContext = createContext({
959
609
  }),
960
610
  getSignInLink: () => Promise.resolve(""),
961
611
  db: {},
962
- remoteDb: {},
963
612
  dbStatus: "LOADING" /* LOADING */
964
613
  });
965
614
  function BasicProvider({
@@ -967,7 +616,8 @@ function BasicProvider({
967
616
  project_id,
968
617
  schema,
969
618
  debug = false,
970
- storage
619
+ storage,
620
+ auth
971
621
  }) {
972
622
  const [isAuthReady, setIsAuthReady] = useState(false);
973
623
  const [isSignedIn, setIsSignedIn] = useState(false);
@@ -980,8 +630,12 @@ function BasicProvider({
980
630
  const [isOnline, setIsOnline] = useState(navigator.onLine);
981
631
  const [pendingRefresh, setPendingRefresh] = useState(false);
982
632
  const syncRef = useRef(null);
983
- const remoteDbRef = useRef(null);
984
633
  const storageAdapter = storage || new LocalStorageAdapter();
634
+ const authConfig = {
635
+ scopes: auth?.scopes || DEFAULT_AUTH_CONFIG.scopes,
636
+ server_url: auth?.server_url || DEFAULT_AUTH_CONFIG.server_url
637
+ };
638
+ const scopesString = Array.isArray(authConfig.scopes) ? authConfig.scopes.join(" ") : authConfig.scopes;
985
639
  const isDevMode = () => isDevelopment(debug);
986
640
  const cleanOAuthParams = () => cleanOAuthParamsFromUrl();
987
641
  useEffect(() => {
@@ -994,7 +648,7 @@ function BasicProvider({
994
648
  if (token) {
995
649
  const refreshToken = token.refresh_token || localStorage.getItem("basic_refresh_token");
996
650
  if (refreshToken) {
997
- fetchToken(refreshToken).catch((error2) => {
651
+ fetchToken(refreshToken, true).catch((error2) => {
998
652
  log("Retry refresh failed:", error2);
999
653
  });
1000
654
  }
@@ -1076,17 +730,6 @@ function BasicProvider({
1076
730
  }
1077
731
  connectToDb();
1078
732
  }, [isSignedIn, shouldConnect]);
1079
- useEffect(() => {
1080
- if (project_id && schema && token?.access_token && !remoteDbRef.current) {
1081
- log("Initializing Remote DB SDK");
1082
- remoteDbRef.current = new BasicDBSDK({
1083
- project_id,
1084
- schema,
1085
- getToken: () => getToken(),
1086
- baseUrl: "https://api.basic.tech"
1087
- });
1088
- }
1089
- }, [token, project_id, schema]);
1090
733
  useEffect(() => {
1091
734
  const initializeAuth = async () => {
1092
735
  await storageAdapter.set(STORAGE_KEYS.DEBUG, debug ? "true" : "false");
@@ -1117,14 +760,14 @@ function BasicProvider({
1117
760
  }
1118
761
  await storageAdapter.remove(STORAGE_KEYS.AUTH_STATE);
1119
762
  cleanOAuthParams();
1120
- fetchToken(code).catch((error2) => {
763
+ fetchToken(code, false).catch((error2) => {
1121
764
  log("Error fetching token:", error2);
1122
765
  });
1123
766
  } else {
1124
767
  const refreshToken = await storageAdapter.get(STORAGE_KEYS.REFRESH_TOKEN);
1125
768
  if (refreshToken) {
1126
769
  log("Found refresh token in storage, attempting to refresh access token");
1127
- fetchToken(refreshToken).catch((error2) => {
770
+ fetchToken(refreshToken, true).catch((error2) => {
1128
771
  log("Error fetching refresh token:", error2);
1129
772
  });
1130
773
  } else {
@@ -1160,7 +803,7 @@ function BasicProvider({
1160
803
  useEffect(() => {
1161
804
  async function fetchUser(acc_token) {
1162
805
  console.info("fetching user");
1163
- const user2 = await fetch("https://api.basic.tech/auth/userInfo", {
806
+ const user2 = await fetch(`${authConfig.server_url}/auth/userInfo`, {
1164
807
  method: "GET",
1165
808
  headers: {
1166
809
  "Authorization": `Bearer ${acc_token}`
@@ -1193,7 +836,7 @@ function BasicProvider({
1193
836
  if (isExpired) {
1194
837
  log("token is expired - refreshing ...");
1195
838
  try {
1196
- const newToken = await fetchToken(token?.refresh_token || "");
839
+ const newToken = await fetchToken(token?.refresh_token || "", true);
1197
840
  fetchUser(newToken?.access_token || "");
1198
841
  } catch (error2) {
1199
842
  log("Failed to refresh token in checkToken:", error2);
@@ -1224,13 +867,15 @@ function BasicProvider({
1224
867
  if (!redirectUrl || !redirectUrl.startsWith("http://") && !redirectUrl.startsWith("https://")) {
1225
868
  throw new Error("Invalid redirect URI provided");
1226
869
  }
1227
- let baseUrl = "https://api.basic.tech/auth/authorize";
870
+ await storageAdapter.set(STORAGE_KEYS.REDIRECT_URI, redirectUrl);
871
+ log("Stored redirect_uri for token exchange:", redirectUrl);
872
+ let baseUrl = `${authConfig.server_url}/auth/authorize`;
1228
873
  baseUrl += `?client_id=${project_id}`;
1229
874
  baseUrl += `&redirect_uri=${encodeURIComponent(redirectUrl)}`;
1230
875
  baseUrl += `&response_type=code`;
1231
- baseUrl += `&scope=profile`;
876
+ baseUrl += `&scope=${encodeURIComponent(scopesString)}`;
1232
877
  baseUrl += `&state=${randomState}`;
1233
- log("Generated sign-in link successfully");
878
+ log("Generated sign-in link successfully with scopes:", scopesString);
1234
879
  return baseUrl;
1235
880
  } catch (error2) {
1236
881
  log("Error generating sign-in link:", error2);
@@ -1278,7 +923,7 @@ function BasicProvider({
1278
923
  }
1279
924
  await storageAdapter.remove(STORAGE_KEYS.AUTH_STATE);
1280
925
  cleanOAuthParams();
1281
- const token2 = await fetchToken(code);
926
+ const token2 = await fetchToken(code, false);
1282
927
  if (token2) {
1283
928
  log("signinWithCode successful");
1284
929
  return { success: true };
@@ -1303,6 +948,7 @@ function BasicProvider({
1303
948
  await storageAdapter.remove(STORAGE_KEYS.AUTH_STATE);
1304
949
  await storageAdapter.remove(STORAGE_KEYS.REFRESH_TOKEN);
1305
950
  await storageAdapter.remove(STORAGE_KEYS.USER_INFO);
951
+ await storageAdapter.remove(STORAGE_KEYS.REDIRECT_URI);
1306
952
  if (syncRef.current) {
1307
953
  (async () => {
1308
954
  try {
@@ -1323,7 +969,7 @@ function BasicProvider({
1323
969
  if (refreshToken) {
1324
970
  log("No token in memory, attempting to refresh from storage");
1325
971
  try {
1326
- const newToken = await fetchToken(refreshToken);
972
+ const newToken = await fetchToken(refreshToken, true);
1327
973
  if (newToken?.access_token) {
1328
974
  return newToken.access_token;
1329
975
  }
@@ -1350,7 +996,7 @@ function BasicProvider({
1350
996
  const refreshToken = token?.refresh_token || await storageAdapter.get(STORAGE_KEYS.REFRESH_TOKEN);
1351
997
  if (refreshToken) {
1352
998
  try {
1353
- const newToken = await fetchToken(refreshToken);
999
+ const newToken = await fetchToken(refreshToken, true);
1354
1000
  return newToken?.access_token || "";
1355
1001
  } catch (error2) {
1356
1002
  log("Failed to refresh expired token:", error2);
@@ -1366,19 +1012,45 @@ function BasicProvider({
1366
1012
  }
1367
1013
  return token?.access_token || "";
1368
1014
  };
1369
- const fetchToken = async (code) => {
1015
+ const fetchToken = async (codeOrRefreshToken, isRefreshToken = false) => {
1370
1016
  try {
1371
1017
  if (!isOnline) {
1372
1018
  log("Network is offline, marking refresh as pending");
1373
1019
  setPendingRefresh(true);
1374
1020
  throw new Error("Network offline - refresh will be retried when online");
1375
1021
  }
1376
- const token2 = await fetch("https://api.basic.tech/auth/token", {
1022
+ let requestBody;
1023
+ if (isRefreshToken) {
1024
+ requestBody = {
1025
+ grant_type: "refresh_token",
1026
+ refresh_token: codeOrRefreshToken
1027
+ };
1028
+ if (project_id) {
1029
+ requestBody.client_id = project_id;
1030
+ }
1031
+ } else {
1032
+ requestBody = {
1033
+ grant_type: "authorization_code",
1034
+ code: codeOrRefreshToken
1035
+ };
1036
+ const storedRedirectUri = await storageAdapter.get(STORAGE_KEYS.REDIRECT_URI);
1037
+ if (storedRedirectUri) {
1038
+ requestBody.redirect_uri = storedRedirectUri;
1039
+ log("Including redirect_uri in token exchange:", storedRedirectUri);
1040
+ } else {
1041
+ log("Warning: No redirect_uri found in storage for token exchange");
1042
+ }
1043
+ if (project_id) {
1044
+ requestBody.client_id = project_id;
1045
+ }
1046
+ }
1047
+ log("Token exchange request body:", { ...requestBody, refresh_token: isRefreshToken ? "[REDACTED]" : void 0, code: !isRefreshToken ? "[REDACTED]" : void 0 });
1048
+ const token2 = await fetch(`${authConfig.server_url}/auth/token`, {
1377
1049
  method: "POST",
1378
1050
  headers: {
1379
1051
  "Content-Type": "application/json"
1380
1052
  },
1381
- body: JSON.stringify({ code })
1053
+ body: JSON.stringify(requestBody)
1382
1054
  }).then((response) => response.json()).catch((error2) => {
1383
1055
  log("Network error fetching token:", error2);
1384
1056
  if (!isOnline) {
@@ -1395,6 +1067,7 @@ function BasicProvider({
1395
1067
  }
1396
1068
  await storageAdapter.remove(STORAGE_KEYS.REFRESH_TOKEN);
1397
1069
  await storageAdapter.remove(STORAGE_KEYS.USER_INFO);
1070
+ await storageAdapter.remove(STORAGE_KEYS.REDIRECT_URI);
1398
1071
  clearCookie("basic_token");
1399
1072
  clearCookie("basic_access_token");
1400
1073
  setUser({});
@@ -1409,6 +1082,10 @@ function BasicProvider({
1409
1082
  await storageAdapter.set(STORAGE_KEYS.REFRESH_TOKEN, token2.refresh_token);
1410
1083
  log("Updated refresh token in storage");
1411
1084
  }
1085
+ if (!isRefreshToken) {
1086
+ await storageAdapter.remove(STORAGE_KEYS.REDIRECT_URI);
1087
+ log("Cleaned up redirect_uri from storage after successful exchange");
1088
+ }
1412
1089
  setCookie("basic_access_token", token2.access_token, { httpOnly: false });
1413
1090
  log("Updated access token in cookie");
1414
1091
  }
@@ -1418,6 +1095,7 @@ function BasicProvider({
1418
1095
  if (!error2.message.includes("offline") && !error2.message.includes("Network")) {
1419
1096
  await storageAdapter.remove(STORAGE_KEYS.REFRESH_TOKEN);
1420
1097
  await storageAdapter.remove(STORAGE_KEYS.USER_INFO);
1098
+ await storageAdapter.remove(STORAGE_KEYS.REDIRECT_URI);
1421
1099
  clearCookie("basic_token");
1422
1100
  clearCookie("basic_access_token");
1423
1101
  setUser({});
@@ -1444,7 +1122,6 @@ function BasicProvider({
1444
1122
  getToken,
1445
1123
  getSignInLink,
1446
1124
  db: syncRef.current ? syncRef.current : noDb,
1447
- remoteDb: remoteDbRef.current ? remoteDbRef.current : noDb,
1448
1125
  dbStatus
1449
1126
  }, children: [
1450
1127
  error && isDevMode() && /* @__PURE__ */ jsx(ErrorDisplay, { error }),
@@ -1481,7 +1158,6 @@ function useBasic() {
1481
1158
  // src/index.ts
1482
1159
  import { useLiveQuery as useQuery } from "dexie-react-hooks";
1483
1160
  export {
1484
- BasicDBSDK,
1485
1161
  BasicProvider,
1486
1162
  useBasic,
1487
1163
  useQuery