supastash 0.1.9 → 0.1.11

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 (54) hide show
  1. package/README.md +20 -16
  2. package/dist/hooks/supastashData/fetchCalls.d.ts.map +1 -1
  3. package/dist/hooks/supastashData/fetchCalls.js +2 -1
  4. package/dist/hooks/supastashData/realtimeSubscription.d.ts.map +1 -1
  5. package/dist/hooks/supastashData/realtimeSubscription.js +2 -1
  6. package/dist/hooks/supastashLogic.d.ts.map +1 -1
  7. package/dist/hooks/supastashLogic.js +4 -3
  8. package/dist/utils/fetchData/deleteData.d.ts.map +1 -1
  9. package/dist/utils/fetchData/deleteData.js +2 -1
  10. package/dist/utils/fetchData/fetchLocalData.d.ts.map +1 -1
  11. package/dist/utils/fetchData/fetchLocalData.js +4 -4
  12. package/dist/utils/fetchData/initialFetch.d.ts.map +1 -1
  13. package/dist/utils/fetchData/initialFetch.js +2 -1
  14. package/dist/utils/fetchData/realTimeCall.d.ts.map +1 -1
  15. package/dist/utils/fetchData/realTimeCall.js +2 -1
  16. package/dist/utils/fetchData/realTimeManager.js +2 -2
  17. package/dist/utils/fetchData/receiveData.js +2 -2
  18. package/dist/utils/logs.d.ts +7 -0
  19. package/dist/utils/logs.d.ts.map +1 -1
  20. package/dist/utils/logs.js +19 -0
  21. package/dist/utils/query/builder/mainQuery.d.ts.map +1 -1
  22. package/dist/utils/query/builder/mainQuery.js +2 -1
  23. package/dist/utils/query/helpers/mainQueryHelpers.js +4 -4
  24. package/dist/utils/query/localDbQuery/delete.d.ts.map +1 -1
  25. package/dist/utils/query/localDbQuery/delete.js +3 -2
  26. package/dist/utils/query/localDbQuery/insert.d.ts.map +1 -1
  27. package/dist/utils/query/localDbQuery/insert.js +2 -1
  28. package/dist/utils/query/localDbQuery/select.d.ts.map +1 -1
  29. package/dist/utils/query/localDbQuery/select.js +2 -1
  30. package/dist/utils/query/localDbQuery/update.d.ts.map +1 -1
  31. package/dist/utils/query/localDbQuery/update.js +3 -2
  32. package/dist/utils/query/localDbQuery/upsert.d.ts.map +1 -1
  33. package/dist/utils/query/localDbQuery/upsert.js +3 -2
  34. package/dist/utils/schema/createSyncStatus.d.ts.map +1 -1
  35. package/dist/utils/schema/createSyncStatus.js +5 -0
  36. package/dist/utils/sync/pullFromRemote/getLastCreatedInfo.d.ts +13 -0
  37. package/dist/utils/sync/pullFromRemote/getLastCreatedInfo.d.ts.map +1 -0
  38. package/dist/utils/sync/pullFromRemote/getLastCreatedInfo.js +34 -0
  39. package/dist/utils/sync/pullFromRemote/getLastDeletedInfo.d.ts.map +1 -1
  40. package/dist/utils/sync/pullFromRemote/getLastDeletedInfo.js +6 -1
  41. package/dist/utils/sync/pullFromRemote/getLastPulledInfo.d.ts.map +1 -1
  42. package/dist/utils/sync/pullFromRemote/getLastPulledInfo.js +6 -1
  43. package/dist/utils/sync/pullFromRemote/pullData.d.ts.map +1 -1
  44. package/dist/utils/sync/pullFromRemote/pullData.js +46 -15
  45. package/dist/utils/sync/pullFromRemote/updateLocalDb.d.ts.map +1 -1
  46. package/dist/utils/sync/pullFromRemote/updateLocalDb.js +16 -17
  47. package/dist/utils/sync/pushLocal/sendUnsyncedToSupabase.d.ts.map +1 -1
  48. package/dist/utils/sync/pushLocal/sendUnsyncedToSupabase.js +2 -1
  49. package/dist/utils/sync/pushLocal/uploadChunk.js +2 -2
  50. package/dist/utils/syncStatus.d.ts.map +1 -1
  51. package/dist/utils/syncStatus.js +2 -0
  52. package/dist/utils/syncUpdate.d.ts.map +1 -1
  53. package/dist/utils/syncUpdate.js +2 -1
  54. package/package.json +1 -1
package/README.md CHANGED
@@ -1,10 +1,12 @@
1
1
  # Supastash
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/supastash.svg)](https://www.npmjs.com/package/supastash)
4
+
3
5
  **Offline-First Sync Engine for Supabase + React Native**
4
6
 
5
- > Sync local SQLite data with Supabase in real-time — even when your app is offline. Built for React Native, no boilerplate required.
7
+ > Sync between SQLite and Supabase in real-time — even when your app is offline. Built for React Native, no boilerplate required.
6
8
 
7
- Supastash gives your app **instant offline access**, **two-way syncing**, and **real-time updates** — all while letting you work with local data as the source of truth.
9
+ Supastash gives your app **instant offline access**, **two-way sync**, and **real-time updates** — with local database as the source of truth.
8
10
 
9
11
  ---
10
12
 
@@ -56,6 +58,8 @@ npm install react-native-sqlite-storage
56
58
 
57
59
  ## ⚙️ Quick Setup
58
60
 
61
+ Initialize once, use anywhere
62
+
59
63
  ```ts
60
64
  // lib/supastash.ts
61
65
  import { configureSupastash, defineLocalSchema } from "supastash";
@@ -85,7 +89,11 @@ configureSupastash({
85
89
  debugMode: true,
86
90
  syncEngine: {
87
91
  push: true,
88
- pull: false, // enable if using RLS
92
+ pull: false, // enable if using RLS and want to pull filtered data
93
+ },
94
+ excludeTables: {
95
+ push: ["daily_reminders"],
96
+ pull: ["daily_reminders"],
89
97
  },
90
98
  });
91
99
  ```
@@ -95,8 +103,13 @@ Then in your root layout:
95
103
  ```ts
96
104
  // App.tsx or _layout.tsx
97
105
  import "@/lib/supastash";
106
+ import { useSupatash } from "supastash";
98
107
 
99
108
  export default function App() {
109
+ const { dbReady } = useSupatash();
110
+
111
+ if (!dbReady) return null;
112
+
100
113
  return <Stack />;
101
114
  }
102
115
  ```
@@ -106,7 +119,7 @@ export default function App() {
106
119
  ## 🚨 Important Notes
107
120
 
108
121
  - Timestamp fields (`created_at`, `updated_at`, `deleted_at`) **must be `timestamptz`** in Supabase
109
- - Every synced table must have a valid `id`
122
+ - Every synced table must have a valid `id` column
110
123
  - Create this SQL function in Supabase to allow schema reflection:
111
124
 
112
125
  ```sql
@@ -142,15 +155,6 @@ const { data: userOrders } = useSupatashData("orders", {
142
155
  });
143
156
  ```
144
157
 
145
- Ensure sync engine is ready:
146
-
147
- ```tsx
148
- import { useSupatash } from "supastash";
149
-
150
- const { dbReady } = useSupatash();
151
- if (!dbReady) return null;
152
- ```
153
-
154
158
  ---
155
159
 
156
160
  ## 🔧 API Overview
@@ -172,10 +176,10 @@ if (!dbReady) return null;
172
176
  ## 🧩 Sync Modes (via query builder)
173
177
 
174
178
  ```ts
175
- supastash
179
+ await supastash
176
180
  .from("orders")
177
- .select("*")
178
- .syncMode("remoteOnly") // or localOnly, localFirst, remoteFirst
181
+ .update({ status: "Dropped-off" })
182
+ .syncMode("localFirst") // or localOnly, remoteOnly, remoteFirst
179
183
  .run();
180
184
  ```
181
185
 
@@ -1 +1 @@
1
- {"version":3,"file":"fetchCalls.d.ts","sourceRoot":"","sources":["../../../src/hooks/supastashData/fetchCalls.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAIjE,wBAAgB,UAAU,CAAC,CAAC,EAC1B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,EAC3B,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC;;;;;EAsEtC"}
1
+ {"version":3,"file":"fetchCalls.d.ts","sourceRoot":"","sources":["../../../src/hooks/supastashData/fetchCalls.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAKjE,wBAAgB,UAAU,CAAC,CAAC,EAC1B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,EAC3B,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC;;;;;EAsEtC"}
@@ -3,6 +3,7 @@ import { syncCalls } from "../../store/syncCalls";
3
3
  import { tableFilters } from "../../store/tableFilters";
4
4
  import { fetchLocalData } from "../../utils/fetchData/fetchLocalData";
5
5
  import { initialFetch } from "../../utils/fetchData/initialFetch";
6
+ import { logError } from "../../utils/logs";
6
7
  export function fetchCalls(table, options, initialized) {
7
8
  const { shouldFetch = true, limit, filter, onPushToRemote, onInsertAndUpdate, useFilterWhileSyncing = true, extraMapKeys, daylength, } = options;
8
9
  const cancelled = useRef(false);
@@ -49,7 +50,7 @@ export function fetchCalls(table, options, initialized) {
49
50
  await fetch();
50
51
  }
51
52
  catch (error) {
52
- console.error(`[Supastash] Error on initial fetch for ${table}`, error);
53
+ logError(`[Supastash] Error on initial fetch for ${table}`, error);
53
54
  }
54
55
  };
55
56
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"realtimeSubscription.d.ts","sourceRoot":"","sources":["../../../src/hooks/supastashData/realtimeSubscription.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EACL,eAAe,EACf,cAAc,EACf,MAAM,gCAAgC,CAAC;AAOxC,iBAAS,uBAAuB,CAC9B,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,IAAI,EAC5D,OAAO,EAAE,eAAe,EACxB,WAAW,EAAE,OAAO,EACpB,QAAQ,EAAE,OAAO,kBAyGlB;AAED,eAAe,uBAAuB,CAAC"}
1
+ {"version":3,"file":"realtimeSubscription.d.ts","sourceRoot":"","sources":["../../../src/hooks/supastashData/realtimeSubscription.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EACL,eAAe,EACf,cAAc,EACf,MAAM,gCAAgC,CAAC;AAQxC,iBAAS,uBAAuB,CAC9B,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,IAAI,EAC5D,OAAO,EAAE,eAAe,EACxB,WAAW,EAAE,OAAO,EACpB,QAAQ,EAAE,OAAO,kBAyGlB;AAED,eAAe,uBAAuB,CAAC"}
@@ -4,6 +4,7 @@ import { useCallback, useEffect, useRef } from "react";
4
4
  import { getSupastashConfig } from "../../core/config";
5
5
  import { buildFilterString } from "../../utils/fetchData/buildFilter";
6
6
  import { RealtimeManager } from "../../utils/fetchData/realTimeManager";
7
+ import { logError } from "../../utils/logs";
7
8
  import { supabaseClientErr } from "../../utils/supabaseClientErr";
8
9
  const generateHookId = () => `hook_${Date.now()}_${Math.random().toString(36)}`;
9
10
  function useRealtimeSubscription(table, queueHandler, options, initialized, realtime) {
@@ -58,7 +59,7 @@ function useRealtimeSubscription(table, queueHandler, options, initialized, real
58
59
  }, [table, hookId, options.filter]);
59
60
  useEffect(() => {
60
61
  if (!supabase) {
61
- console.error("[Supastash] No supabase client found", supabaseClientErr);
62
+ logError("[Supastash] No supabase client found", supabaseClientErr);
62
63
  return;
63
64
  }
64
65
  const filterString = options.filter
@@ -1 +1 @@
1
- {"version":3,"file":"supastashLogic.d.ts","sourceRoot":"","sources":["../../src/hooks/supastashLogic.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAOrE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,IAAI,mBAAmB,CA4DlD"}
1
+ {"version":3,"file":"supastashLogic.d.ts","sourceRoot":"","sources":["../../src/hooks/supastashLogic.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAQrE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,IAAI,mBAAmB,CA6DlD"}
@@ -2,6 +2,7 @@ import { useEffect, useRef, useState } from "react";
2
2
  import { getSupastashConfig } from "../core/config";
3
3
  import { supastashDbErrorMsg } from "../db/dbErrorMsg";
4
4
  import { useSyncEngine } from "../hooks/syncEngine";
5
+ import { logError } from "../utils/logs";
5
6
  import { createDeletedStatusTable, createSyncStatusTable, } from "../utils/schema/createSyncStatus";
6
7
  import { supabaseClientErr } from "../utils/supabaseClientErr";
7
8
  /**
@@ -25,7 +26,7 @@ export function useSupastash() {
25
26
  const initialized = useRef(false);
26
27
  const config = getSupastashConfig();
27
28
  if (!config.sqliteClient || !config.sqliteClientType) {
28
- console.error(`
29
+ logError(`
29
30
  [Supastash] ${supastashDbErrorMsg}`);
30
31
  return {
31
32
  dbReady: false,
@@ -34,7 +35,7 @@ export function useSupastash() {
34
35
  };
35
36
  }
36
37
  if (!config.supabaseClient) {
37
- console.error(`[Supastash] Add a supabase client to config ${supabaseClientErr}`);
38
+ logError(`[Supastash] Add a supabase client to config ${supabaseClientErr}`);
38
39
  return {
39
40
  dbReady: false,
40
41
  startSync: () => { },
@@ -57,7 +58,7 @@ export function useSupastash() {
57
58
  setDbReady(true);
58
59
  }
59
60
  catch (error) {
60
- console.error(`[Supastash] Error initializing: ${error}`);
61
+ logError(`[Supastash] Error initializing: ${error}`);
61
62
  }
62
63
  }
63
64
  init();
@@ -1 +1 @@
1
- {"version":3,"file":"deleteData.d.ts","sourceRoot":"","sources":["../../../src/utils/fetchData/deleteData.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAMtD,wBAAsB,UAAU,CAC9B,OAAO,EAAE,WAAW,EACpB,KAAK,EAAE,MAAM,EACb,WAAW,GAAE,OAAc,iBAqB5B"}
1
+ {"version":3,"file":"deleteData.d.ts","sourceRoot":"","sources":["../../../src/utils/fetchData/deleteData.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAOtD,wBAAsB,UAAU,CAC9B,OAAO,EAAE,WAAW,EACpB,KAAK,EAAE,MAAM,EACb,WAAW,GAAE,OAAc,iBAqB5B"}
@@ -1,5 +1,6 @@
1
1
  import { permanentlyDeleteData } from "../../utils/query/localDbQuery/delete";
2
2
  import { checkIfTableExist } from "../../utils/tableValidator";
3
+ import { logError } from "../logs";
3
4
  import { refreshScreen } from "../refreshScreenCalls";
4
5
  import { createTable } from "./createTable";
5
6
  export async function deleteData(payload, table, shouldFetch = true) {
@@ -19,6 +20,6 @@ export async function deleteData(payload, table, shouldFetch = true) {
19
20
  refreshScreen(table);
20
21
  }
21
22
  catch (error) {
22
- console.error("[Supastash] Error receiving data:", error);
23
+ logError("[Supastash] Error receiving data:", error);
23
24
  }
24
25
  }
@@ -1 +1 @@
1
- {"version":3,"file":"fetchLocalData.d.ts","sourceRoot":"","sources":["../../../src/utils/fetchData/fetchLocalData.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AA0DtD;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,CAAC,EACpC,KAAK,EAAE,MAAM,EACb,WAAW,GAAE,OAAc,EAC3B,KAAK,GAAE,MAAY,EACnB,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EAC1B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC;IACT,IAAI,EAAE,WAAW,EAAE,CAAC;IACpB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAClC,SAAS,EAAE;SACR,CAAC,IAAI,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;KAC9C,CAAC;CACH,GAAG,IAAI,CAAC,CAgFR"}
1
+ {"version":3,"file":"fetchLocalData.d.ts","sourceRoot":"","sources":["../../../src/utils/fetchData/fetchLocalData.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AA0DtD;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,CAAC,EACpC,KAAK,EAAE,MAAM,EACb,WAAW,GAAE,OAAc,EAC3B,KAAK,GAAE,MAAY,EACnB,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EAC1B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC;IACT,IAAI,EAAE,WAAW,EAAE,CAAC;IACpB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAClC,SAAS,EAAE;SACR,CAAC,IAAI,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;KAC9C,CAAC;CACH,GAAG,IAAI,CAAC,CA6ER"}
@@ -1,6 +1,6 @@
1
1
  import { getSupastashDb } from "../../db/dbInitializer";
2
2
  import { localCache } from "../../store/localCache";
3
- import log from "../logs";
3
+ import log, { logError, logWarn } from "../logs";
4
4
  import { notifySubscribers } from "./snapShot";
5
5
  const fetchingPromises = new Map();
6
6
  const versionMap = new Map();
@@ -27,7 +27,7 @@ function getNewVersion(table) {
27
27
  clearTimeout(debounceMap.get(table));
28
28
  const timeout = setTimeout(() => {
29
29
  if (queue.length > 10) {
30
- console.warn(`[Supastash] Table "${table}" is noisy: ${queue.length} events in ${timeoutMs}ms`);
30
+ logWarn(`[Supastash] Table "${table}" is noisy: ${queue.length} events in ${timeoutMs}ms`);
31
31
  }
32
32
  versionMap.delete(table);
33
33
  notifySubscribers(table);
@@ -75,7 +75,7 @@ export async function fetchLocalData(table, shouldFetch = true, limit = 200, ext
75
75
  if (extraMapKeys?.length) {
76
76
  for (const key of extraMapKeys) {
77
77
  if (item[key] == null) {
78
- console.warn(`[Supastash] Item ${item.id} has no ${String(key)} field`);
78
+ logWarn(`[Supastash] Item ${item.id} has no ${String(key)} field`);
79
79
  continue;
80
80
  }
81
81
  const groupVal = item[key];
@@ -96,7 +96,7 @@ export async function fetchLocalData(table, shouldFetch = true, limit = 200, ext
96
96
  return { data, dataMap, groupedBy };
97
97
  }
98
98
  catch (error) {
99
- console.error(`[Supastash] Error fetching local data for ${table}:`, error);
99
+ logError(`[Supastash] Error fetching local data for ${table}:`, error);
100
100
  return null;
101
101
  }
102
102
  })();
@@ -1 +1 @@
1
- {"version":3,"file":"initialFetch.d.ts","sourceRoot":"","sources":["../../../src/utils/fetchData/initialFetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAOhE,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,cAAc,EACvB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,EAC/C,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,iBAatD"}
1
+ {"version":3,"file":"initialFetch.d.ts","sourceRoot":"","sources":["../../../src/utils/fetchData/initialFetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAQhE,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,cAAc,EACvB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,EAC/C,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,iBAatD"}
@@ -1,3 +1,4 @@
1
+ import { logError } from "../logs";
1
2
  import { updateLocalDb } from "../sync/pullFromRemote/updateLocalDb";
2
3
  import { pushLocalDataToRemote } from "../sync/pushLocal/sendUnsyncedToSupabase";
3
4
  import { createTable } from "./createTable";
@@ -12,7 +13,7 @@ export async function initialFetch(table, filter, onReceiveData, onPushToRemote)
12
13
  await pushLocalDataToRemote(table, onPushToRemote);
13
14
  }
14
15
  catch (error) {
15
- console.error(`[Supastash] Error on initial fetch for ${table}`, error);
16
+ logError(`[Supastash] Error on initial fetch for ${table}`, error);
16
17
  }
17
18
  finally {
18
19
  isInSync.delete(table);
@@ -1 +1 @@
1
- {"version":3,"file":"realTimeCall.d.ts","sourceRoot":"","sources":["../../../src/utils/fetchData/realTimeCall.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAMjE,QAAA,MAAM,eAAe,GACnB,OAAO,MAAM,EACb,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,IAAI,EAC5D,SAAS,eAAe,EACxB,aAAa,OAAO,EACpB,UAAU,OAAO,SA0ClB,CAAC;AAEF,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"realTimeCall.d.ts","sourceRoot":"","sources":["../../../src/utils/fetchData/realTimeCall.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAOjE,QAAA,MAAM,eAAe,GACnB,OAAO,MAAM,EACb,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,IAAI,EAC5D,SAAS,eAAe,EACxB,aAAa,OAAO,EACpB,UAAU,OAAO,SA0ClB,CAAC;AAEF,eAAe,eAAe,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { useEffect, useMemo } from "react";
2
2
  import { getSupastashConfig } from "../../core/config";
3
+ import { logError } from "../logs";
3
4
  import { supabaseClientErr } from "../supabaseClientErr";
4
5
  import { buildFilterString } from "./buildFilter";
5
6
  const hasRegistered = new Map();
@@ -15,7 +16,7 @@ const useRealtimeData = (table, queueHandler, options, initialized, realtime) =>
15
16
  return;
16
17
  const supabase = getSupastashConfig().supabaseClient;
17
18
  if (!supabase) {
18
- console.error("[Supastash] No supabase client found", supabaseClientErr);
19
+ logError("[Supastash] No supabase client found", supabaseClientErr);
19
20
  return;
20
21
  }
21
22
  hasRegistered.set(subKey, true);
@@ -1,6 +1,6 @@
1
1
  // DEPRECATED: Use useRealtimeData instead
2
2
  import { getSupastashConfig } from "../../core/config";
3
- import log from "../logs";
3
+ import log, { logError } from "../logs";
4
4
  import { supabaseClientErr } from "../supabaseClientErr";
5
5
  class SupastashRealtimeManager {
6
6
  constructor() {
@@ -29,7 +29,7 @@ class SupastashRealtimeManager {
29
29
  async createConnection() {
30
30
  const supabase = getSupastashConfig().supabaseClient;
31
31
  if (!supabase) {
32
- console.error("[Supastash] No supabase client found", supabaseClientErr);
32
+ logError("[Supastash] No supabase client found", supabaseClientErr);
33
33
  return null;
34
34
  }
35
35
  if (this.connection) {
@@ -1,7 +1,7 @@
1
1
  import { getSupastashDb } from "../../db/dbInitializer";
2
2
  import { upsertData } from "../../utils/sync/pullFromRemote/updateLocalDb";
3
3
  import { checkIfTableExist } from "../../utils/tableValidator";
4
- import log from "../logs";
4
+ import log, { logError } from "../logs";
5
5
  import { refreshScreen } from "../refreshScreenCalls";
6
6
  import { createTable } from "./createTable";
7
7
  const DEFAULT_DATE = "1970-01-01T00:00:00Z";
@@ -34,6 +34,6 @@ export async function receiveData(payload, table, shouldFetch = true, upsertCall
34
34
  refreshScreen(table);
35
35
  }
36
36
  catch (error) {
37
- console.error("[Supastash] Error receiving data:", error);
37
+ logError("[Supastash] Error receiving data:", error);
38
38
  }
39
39
  }
@@ -4,4 +4,11 @@
4
4
  */
5
5
  declare const log: (...args: any[]) => void;
6
6
  export default log;
7
+ /**
8
+ * Logs an error to the console if debug mode is enabled
9
+ * @param args - The arguments to log
10
+ */
11
+ declare const logError: (...args: any[]) => void;
12
+ declare const logWarn: (...args: any[]) => void;
13
+ export { log, logError, logWarn };
7
14
  //# sourceMappingURL=logs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/utils/logs.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,QAAA,MAAM,GAAG,GAAI,GAAG,MAAM,GAAG,EAAE,SAM1B,CAAC;AAEF,eAAe,GAAG,CAAC"}
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/utils/logs.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,QAAA,MAAM,GAAG,GAAI,GAAG,MAAM,GAAG,EAAE,SAM1B,CAAC;AAEF,eAAe,GAAG,CAAC;AAEnB;;;GAGG;AACH,QAAA,MAAM,QAAQ,GAAI,GAAG,MAAM,GAAG,EAAE,SAK/B,CAAC;AAEF,QAAA,MAAM,OAAO,GAAI,GAAG,MAAM,GAAG,EAAE,SAK9B,CAAC;AAEF,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC"}
@@ -13,3 +13,22 @@ const log = (...args) => {
13
13
  }
14
14
  };
15
15
  export default log;
16
+ /**
17
+ * Logs an error to the console if debug mode is enabled
18
+ * @param args - The arguments to log
19
+ */
20
+ const logError = (...args) => {
21
+ if (!DEBUG_MODE)
22
+ return;
23
+ if (typeof console !== "undefined" && console.error) {
24
+ Function.prototype.apply.call(console.error, console, args);
25
+ }
26
+ };
27
+ const logWarn = (...args) => {
28
+ if (!DEBUG_MODE)
29
+ return;
30
+ if (typeof console !== "undefined" && console.warn) {
31
+ Function.prototype.apply.call(console.warn, console, args);
32
+ }
33
+ };
34
+ export { log, logError, logWarn };
@@ -1 +1 @@
1
- {"version":3,"file":"mainQuery.d.ts","sourceRoot":"","sources":["../../../../src/utils/query/builder/mainQuery.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EAGX,cAAc,EACd,oBAAoB,EACrB,MAAM,4BAA4B,CAAC;AAUpC;;;;GAIG;AACH,wBAAsB,OAAO,CAC3B,CAAC,SAAS,WAAW,EACrB,CAAC,SAAS,OAAO,EACjB,CAAC,SAAS,OAAO,EACjB,CAAC,EACD,CAAC,EAED,KAAK,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG;IAAE,gBAAgB,EAAE,CAAC,CAAA;CAAE,GACvD,OAAO,CAAC,oBAAoB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CA2E3C"}
1
+ {"version":3,"file":"mainQuery.d.ts","sourceRoot":"","sources":["../../../../src/utils/query/builder/mainQuery.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EAGX,cAAc,EACd,oBAAoB,EACrB,MAAM,4BAA4B,CAAC;AAWpC;;;;GAIG;AACH,wBAAsB,OAAO,CAC3B,CAAC,SAAS,WAAW,EACrB,CAAC,SAAS,OAAO,EACjB,CAAC,SAAS,OAAO,EACjB,CAAC,EACD,CAAC,EAED,KAAK,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG;IAAE,gBAAgB,EAAE,CAAC,CAAA;CAAE,GACvD,OAAO,CAAC,oBAAoB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CA2E3C"}
@@ -1,3 +1,4 @@
1
+ import { logError } from "../../logs";
1
2
  import { refreshScreen } from "../../refreshScreenCalls";
2
3
  import { assignInsertIds, getCommonError, runSyncStrategy, validatePayloadForSingleInsert, } from "../helpers/mainQueryHelpers";
3
4
  import { validateQuery } from "../helpers/queryValidator";
@@ -41,7 +42,7 @@ export async function queryDb(state) {
41
42
  });
42
43
  }
43
44
  catch (error) {
44
- console.error(`[Supastash] ${error instanceof Error ? error.message : String(error)}`);
45
+ logError(`[Supastash] ${error instanceof Error ? error.message : String(error)}`);
45
46
  if (state.viewRemoteResult) {
46
47
  return Promise.resolve({
47
48
  remote: null,
@@ -1,5 +1,5 @@
1
1
  import { isOnline } from "../../../utils/connection";
2
- import log from "../../../utils/logs";
2
+ import log, { logError } from "../../../utils/logs";
3
3
  import { generateUUIDv4 } from "../../genUUID";
4
4
  import { queryLocalDb } from "../localDbQuery";
5
5
  import { querySupabase } from "../remoteQuery/supabaseQuery";
@@ -68,7 +68,7 @@ async function runBatchedRemoteQuery() {
68
68
  const state = stateCache.shift();
69
69
  if (calledOfflineRetries.get(state.id) &&
70
70
  calledOfflineRetries.get(state.id) >= MAX_OFFLINE_RETRIES) {
71
- console.error(`[Supastash] Failed to send remote batch query:\n` +
71
+ logError(`[Supastash] Failed to send remote batch query:\n` +
72
72
  ` Table: ${state.table}\n` +
73
73
  ` Method: ${state.method}\n` +
74
74
  ` Retries: ${MAX_OFFLINE_RETRIES}\n` +
@@ -108,7 +108,7 @@ async function runBatchedRemoteQuery() {
108
108
  continue;
109
109
  }
110
110
  else {
111
- console.error(`[Supastash] Remote sync failed on ${state.table} with ${state.method} after ${retryCount + 1} tries: ${error.message}`);
111
+ logError(`[Supastash] Remote sync failed on ${state.table} with ${state.method} after ${retryCount + 1} tries: ${error.message}`);
112
112
  }
113
113
  }
114
114
  }
@@ -124,7 +124,7 @@ function addToCache(state) {
124
124
  clearTimeout(batchTimer);
125
125
  batchTimer = setTimeout(() => {
126
126
  runBatchedRemoteQuery();
127
- }, 1500);
127
+ }, 200);
128
128
  }
129
129
  export async function runSyncStrategy(state) {
130
130
  const { type } = state;
@@ -1 +1 @@
1
- {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../../src/utils/query/localDbQuery/delete.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,QAAQ,EACT,MAAM,4BAA4B,CAAC;AAIpC;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,CAAC,GAAG,GAAG,EACtC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI,EAC7B,QAAQ,CAAC,EAAE,QAAQ,GAClB,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CA+BlC;AAED;;;;;GAKG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,GAAG,GAAG,EACjD,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI,GAC5B,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAkBlC"}
1
+ {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../../src/utils/query/localDbQuery/delete.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,QAAQ,EACT,MAAM,4BAA4B,CAAC;AAKpC;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,CAAC,GAAG,GAAG,EACtC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI,EAC7B,QAAQ,CAAC,EAAE,QAAQ,GAClB,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CA+BlC;AAED;;;;;GAKG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,GAAG,GAAG,EACjD,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI,GAC5B,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAkBlC"}
@@ -1,4 +1,5 @@
1
1
  import { getSupastashDb } from "../../../db/dbInitializer";
2
+ import { logError } from "../../logs";
2
3
  import { assertTableExists } from "../../tableValidator";
3
4
  import { buildWhereClause } from "../helpers/remoteDb/queryFilterBuilder";
4
5
  /**
@@ -21,7 +22,7 @@ export async function deleteData(table, filters, syncMode) {
21
22
  return { error: null, data: itemsToBeDeleted };
22
23
  }
23
24
  catch (error) {
24
- console.error(`[Supastash] ${error}`);
25
+ logError(`[Supastash] ${error}`);
25
26
  return {
26
27
  error: {
27
28
  message: error instanceof Error ? error.message : String(error),
@@ -44,7 +45,7 @@ export async function permanentlyDeleteData(table, filters) {
44
45
  return { error: null };
45
46
  }
46
47
  catch (error) {
47
- console.error(`[Supastash] ${error}`);
48
+ logError(`[Supastash] ${error}`);
48
49
  return {
49
50
  error: {
50
51
  message: error instanceof Error ? error.message : String(error),
@@ -1 +1 @@
1
- {"version":3,"file":"insert.d.ts","sourceRoot":"","sources":["../../../../src/utils/query/localDbQuery/insert.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,iBAAiB,EACjB,aAAa,EACb,QAAQ,EACT,MAAM,4BAA4B,CAAC;AAKpC;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,EAAE,CAAC,EACtD,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,CAAC,EAAE,GAAG,IAAI,EACnB,QAAQ,CAAC,EAAE,QAAQ,EACnB,QAAQ,CAAC,EAAE,CAAC,GACX,OAAO,CAAC,CAAC,SAAS,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,CA6EnE"}
1
+ {"version":3,"file":"insert.d.ts","sourceRoot":"","sources":["../../../../src/utils/query/localDbQuery/insert.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,iBAAiB,EACjB,aAAa,EACb,QAAQ,EACT,MAAM,4BAA4B,CAAC;AAMpC;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,EAAE,CAAC,EACtD,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,CAAC,EAAE,GAAG,IAAI,EACnB,QAAQ,CAAC,EAAE,QAAQ,EACnB,QAAQ,CAAC,EAAE,CAAC,GACX,OAAO,CAAC,CAAC,SAAS,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,CA6EnE"}
@@ -1,4 +1,5 @@
1
1
  import { getSupastashDb } from "../../../db/dbInitializer";
2
+ import { logError } from "../../logs";
2
3
  import { getSafeValue } from "../../serializer";
3
4
  import { parseStringifiedFields } from "../../sync/pushLocal/parseFields";
4
5
  import { assertTableExists } from "../../tableValidator";
@@ -54,7 +55,7 @@ export async function insertData(table, payload, syncMode, isSingle) {
54
55
  };
55
56
  }
56
57
  catch (error) {
57
- console.error(`[Supastash] ${error}`);
58
+ logError(`[Supastash] ${error}`);
58
59
  return {
59
60
  error: {
60
61
  message: error instanceof Error ? error.message : String(error),
@@ -1 +1 @@
1
- {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../../src/utils/query/localDbQuery/select.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,aAAa,EACd,MAAM,4BAA4B,CAAC;AAKpC;;;;;;;;;GASG;AACH,wBAAsB,UAAU,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,EAAE,CAAC,EACtD,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI,EAC7B,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,QAAQ,EAAE,CAAC,GACV,OAAO,CAAC,CAAC,SAAS,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAoCnE"}
1
+ {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../../src/utils/query/localDbQuery/select.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,aAAa,EACd,MAAM,4BAA4B,CAAC;AAMpC;;;;;;;;;GASG;AACH,wBAAsB,UAAU,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,EAAE,CAAC,EACtD,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI,EAC7B,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,QAAQ,EAAE,CAAC,GACV,OAAO,CAAC,CAAC,SAAS,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAoCnE"}
@@ -1,4 +1,5 @@
1
1
  import { getSupastashDb } from "../../../db/dbInitializer";
2
+ import { logError } from "../../logs";
2
3
  import { parseStringifiedFields } from "../../sync/pushLocal/parseFields";
3
4
  import { assertTableExists } from "../../tableValidator";
4
5
  import { buildWhereClause } from "../helpers/remoteDb/queryFilterBuilder";
@@ -33,7 +34,7 @@ export async function selectData(table, select, filters, limit, isSingle) {
33
34
  return { data, error: null };
34
35
  }
35
36
  catch (error) {
36
- console.error(`[Supastash] ${error}`);
37
+ logError(`[Supastash] ${error}`);
37
38
  return {
38
39
  error: {
39
40
  message: error instanceof Error ? error.message : String(error),
@@ -1 +1 @@
1
- {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../../src/utils/query/localDbQuery/update.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,WAAW,EAEX,iBAAiB,EACjB,aAAa,EACb,QAAQ,EACT,MAAM,4BAA4B,CAAC;AAQpC;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,EAAE,CAAC,EACtD,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,CAAC,GAAG,IAAI,EACjB,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI,EAC7B,QAAQ,CAAC,EAAE,QAAQ,EACnB,QAAQ,CAAC,EAAE,CAAC,EACZ,iBAAiB,CAAC,EAAE,OAAO,GAC1B,OAAO,CAAC,CAAC,SAAS,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,CA+EnE"}
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../../src/utils/query/localDbQuery/update.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,WAAW,EAEX,iBAAiB,EACjB,aAAa,EACb,QAAQ,EACT,MAAM,4BAA4B,CAAC;AASpC;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,EAAE,CAAC,EACtD,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,CAAC,GAAG,IAAI,EACjB,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI,EAC7B,QAAQ,CAAC,EAAE,QAAQ,EACnB,QAAQ,CAAC,EAAE,CAAC,EACZ,iBAAiB,CAAC,EAAE,OAAO,GAC1B,OAAO,CAAC,CAAC,SAAS,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,CA+EnE"}
@@ -1,6 +1,7 @@
1
1
  import { getSupastashConfig } from "../../../core/config";
2
2
  import { getSupastashDb } from "../../../db/dbInitializer";
3
3
  import { parseStringifiedFields } from "../../../utils/sync/pushLocal/parseFields";
4
+ import { logError, logWarn } from "../../logs";
4
5
  import { getSafeValue } from "../../serializer";
5
6
  import { assertTableExists } from "../../tableValidator";
6
7
  import { buildWhereClause } from "../helpers/remoteDb/queryFilterBuilder";
@@ -31,7 +32,7 @@ export async function updateData(table, payload, filters, syncMode, isSingle, pr
31
32
  if (!preserveTimestamp || payload.updated_at === undefined) {
32
33
  if (!warned.has(table) && !getSupastashConfig().debugMode && __DEV__) {
33
34
  warned.add(table);
34
- console.warn(`[Supastash] updated_at not provided for update call on ${table} – defaulting to ${timeStamp}`);
35
+ logWarn(`[Supastash] updated_at not provided for update call on ${table} – defaulting to ${timeStamp}`);
35
36
  }
36
37
  const userUpdatedAt = payload.updated_at;
37
38
  newPayload.updated_at =
@@ -66,7 +67,7 @@ export async function updateData(table, payload, filters, syncMode, isSingle, pr
66
67
  };
67
68
  }
68
69
  catch (error) {
69
- console.error(`[Supastash] ${error}`);
70
+ logError(`[Supastash] ${error}`);
70
71
  return {
71
72
  error: {
72
73
  message: error instanceof Error ? error.message : String(error),
@@ -1 +1 @@
1
- {"version":3,"file":"upsert.d.ts","sourceRoot":"","sources":["../../../../src/utils/query/localDbQuery/upsert.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,iBAAiB,EACjB,aAAa,EACb,QAAQ,EACT,MAAM,4BAA4B,CAAC;AAQpC;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,EAAE,CAAC,EACtD,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,EACvB,QAAQ,CAAC,EAAE,QAAQ,EACnB,QAAQ,CAAC,EAAE,CAAC,EACZ,cAAc,GAAE,MAAM,EAAW,EACjC,iBAAiB,CAAC,EAAE,OAAO,GAC1B,OAAO,CAAC,CAAC,SAAS,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,CA4HnE"}
1
+ {"version":3,"file":"upsert.d.ts","sourceRoot":"","sources":["../../../../src/utils/query/localDbQuery/upsert.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,iBAAiB,EACjB,aAAa,EACb,QAAQ,EACT,MAAM,4BAA4B,CAAC;AASpC;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,EAAE,CAAC,EACtD,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,EACvB,QAAQ,CAAC,EAAE,QAAQ,EACnB,QAAQ,CAAC,EAAE,CAAC,EACZ,cAAc,GAAE,MAAM,EAAW,EACjC,iBAAiB,CAAC,EAAE,OAAO,GAC1B,OAAO,CAAC,CAAC,SAAS,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,CA4HnE"}
@@ -1,6 +1,7 @@
1
1
  import { getSupastashConfig } from "../../../core/config";
2
2
  import { getSupastashDb } from "../../../db/dbInitializer";
3
3
  import { generateUUIDv4 } from "../../../utils/genUUID";
4
+ import { logError, logWarn } from "../../logs";
4
5
  import { getSafeValue } from "../../serializer";
5
6
  import { parseStringifiedFields } from "../../sync/pushLocal/parseFields";
6
7
  import { assertTableExists } from "../../tableValidator";
@@ -48,7 +49,7 @@ export async function upsertData(table, payload, syncMode, isSingle, onConflictK
48
49
  !getSupastashConfig().debugMode &&
49
50
  __DEV__) {
50
51
  warned.add(table);
51
- console.warn(`[Supastash] updated_at not provided for upsert call on ${table} – defaulting to ${timeStamp}`);
52
+ logWarn(`[Supastash] updated_at not provided for upsert call on ${table} – defaulting to ${timeStamp}`);
52
53
  }
53
54
  const userUpdatedAt = item.updated_at;
54
55
  newPayload.updated_at =
@@ -90,7 +91,7 @@ export async function upsertData(table, payload, syncMode, isSingle, onConflictK
90
91
  };
91
92
  }
92
93
  catch (error) {
93
- console.error(`[Supastash] ${error}`);
94
+ logError(`[Supastash] ${error}`);
94
95
  return {
95
96
  error: {
96
97
  message: error instanceof Error ? error.message : String(error),
@@ -1 +1 @@
1
- {"version":3,"file":"createSyncStatus.d.ts","sourceRoot":"","sources":["../../../src/utils/schema/createSyncStatus.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAsB,qBAAqB,kBAS1C;AAED;;GAEG;AACH,wBAAsB,wBAAwB,kBAS7C"}
1
+ {"version":3,"file":"createSyncStatus.d.ts","sourceRoot":"","sources":["../../../src/utils/schema/createSyncStatus.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAsB,qBAAqB,kBAe1C;AAED;;GAEG;AACH,wBAAsB,wBAAwB,kBAS7C"}
@@ -7,8 +7,13 @@ export async function createSyncStatusTable() {
7
7
  const sql = `CREATE TABLE IF NOT EXISTS supastash_sync_status (
8
8
  table_name TEXT NOT NULL,
9
9
  last_synced_at TEXT NOT NULL
10
+ );`;
11
+ const sql2 = `CREATE TABLE IF NOT EXISTS supastash_last_created (
12
+ table_name TEXT NOT NULL,
13
+ last_created_at TEXT NOT NULL
10
14
  );`;
11
15
  await db.execAsync(sql);
16
+ await db.execAsync(sql2);
12
17
  }
13
18
  /**
14
19
  * Creates the supastash_deleted_status table if it doesn't exist
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Gets the last synced timestamp for a given table
3
+ * @param table - The table to get the last created timestamp for
4
+ * @returns The last synced timestamp
5
+ */
6
+ export declare function getLastCreatedInfo(table: string): Promise<string>;
7
+ /**
8
+ * Updates the last synced timestamp for a given table
9
+ * @param table - The table to update the last created timestamp for
10
+ * @param lastCreatedAt - The last created timestamp
11
+ */
12
+ export declare function updateLastCreatedInfo(table: string, lastCreatedAt: string): Promise<void>;
13
+ //# sourceMappingURL=getLastCreatedInfo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getLastCreatedInfo.d.ts","sourceRoot":"","sources":["../../../../src/utils/sync/pullFromRemote/getLastCreatedInfo.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA6BvE;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,iBAQtB"}
@@ -0,0 +1,34 @@
1
+ import { getSupastashDb } from "../../../db/dbInitializer";
2
+ import { logWarn } from "../../logs";
3
+ const DEFAULT_LAST_CREATED_AT = "2000-01-01T00:00:00Z";
4
+ const LAST_CREATED_TABLE = "supastash_last_created";
5
+ /**
6
+ * Gets the last synced timestamp for a given table
7
+ * @param table - The table to get the last created timestamp for
8
+ * @returns The last synced timestamp
9
+ */
10
+ export async function getLastCreatedInfo(table) {
11
+ const db = await getSupastashDb();
12
+ // Add table name to supastash_last_created if it doesn't exist
13
+ await db.runAsync(`INSERT OR IGNORE INTO supastash_last_created (table_name, last_created_at) VALUES (?, ?)`, [table, DEFAULT_LAST_CREATED_AT]);
14
+ // Get the latest sync timestamp for this table
15
+ const result = await db.getFirstAsync(`SELECT last_created_at FROM ${LAST_CREATED_TABLE} WHERE table_name = ?`, [table]);
16
+ const original = result?.last_created_at || DEFAULT_LAST_CREATED_AT;
17
+ const timestamp = Date.parse(original);
18
+ if (isNaN(timestamp)) {
19
+ logWarn(`[Supastash] Invalid date string found on created_at column for ${table}: ${original}`);
20
+ return original;
21
+ }
22
+ const lastSyncedAt = new Date(timestamp + 1);
23
+ const lastSyncedAtISOString = lastSyncedAt.toISOString();
24
+ return lastSyncedAtISOString;
25
+ }
26
+ /**
27
+ * Updates the last synced timestamp for a given table
28
+ * @param table - The table to update the last created timestamp for
29
+ * @param lastCreatedAt - The last created timestamp
30
+ */
31
+ export async function updateLastCreatedInfo(table, lastCreatedAt) {
32
+ const db = await getSupastashDb();
33
+ await db.runAsync(`UPDATE ${LAST_CREATED_TABLE} SET last_created_at = ? WHERE table_name = ?`, [lastCreatedAt, table]);
34
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"getLastDeletedInfo.d.ts","sourceRoot":"","sources":["../../../../src/utils/sync/pullFromRemote/getLastDeletedInfo.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAuBvE;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,iBAQtB"}
1
+ {"version":3,"file":"getLastDeletedInfo.d.ts","sourceRoot":"","sources":["../../../../src/utils/sync/pullFromRemote/getLastDeletedInfo.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA6BvE;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,iBAQtB"}
@@ -1,5 +1,6 @@
1
1
  import { getSupastashDb } from "../../../db/dbInitializer";
2
- const DEFAULT_LAST_DELETED_AT = "2024-01-01T00:00:00Z";
2
+ import { logWarn } from "../../logs";
3
+ const DEFAULT_LAST_DELETED_AT = "2000-01-01T00:00:00Z";
3
4
  const DELETED_STATUS_TABLE = "supastash_deleted_status";
4
5
  /**
5
6
  * Gets the last deleted timestamp for a given table
@@ -14,6 +15,10 @@ export async function getLastDeletedInfo(table) {
14
15
  const result = await db.getFirstAsync(`SELECT last_deleted_at FROM ${DELETED_STATUS_TABLE} WHERE table_name = ?`, [table]);
15
16
  const original = result?.last_deleted_at || DEFAULT_LAST_DELETED_AT;
16
17
  const timestamp = Date.parse(original);
18
+ if (isNaN(timestamp)) {
19
+ logWarn(`[Supastash] Invalid date string found on deleted_at column for ${table}: ${original}`);
20
+ return original;
21
+ }
17
22
  const lastDeletedAt = new Date(timestamp + 1);
18
23
  const lastDeletedAtISOString = lastDeletedAt.toISOString();
19
24
  return lastDeletedAtISOString;
@@ -1 +1 @@
1
- {"version":3,"file":"getLastPulledInfo.d.ts","sourceRoot":"","sources":["../../../../src/utils/sync/pullFromRemote/getLastPulledInfo.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAuBtE;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,iBAQrB"}
1
+ {"version":3,"file":"getLastPulledInfo.d.ts","sourceRoot":"","sources":["../../../../src/utils/sync/pullFromRemote/getLastPulledInfo.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA6BtE;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,iBAQrB"}
@@ -1,5 +1,6 @@
1
1
  import { getSupastashDb } from "../../../db/dbInitializer";
2
- const DEFAULT_LAST_PULLED_AT = "2024-01-01T00:00:00Z";
2
+ import { logWarn } from "../../logs";
3
+ const DEFAULT_LAST_PULLED_AT = "2000-01-01T00:00:00Z";
3
4
  const SYNC_STATUS_TABLE = "supastash_sync_status";
4
5
  /**
5
6
  * Gets the last synced timestamp for a given table
@@ -14,6 +15,10 @@ export async function getLastPulledInfo(table) {
14
15
  const result = await db.getFirstAsync(`SELECT last_synced_at FROM ${SYNC_STATUS_TABLE} WHERE table_name = ?`, [table]);
15
16
  const original = result?.last_synced_at || DEFAULT_LAST_PULLED_AT;
16
17
  const timestamp = Date.parse(original);
18
+ if (isNaN(timestamp)) {
19
+ logWarn(`[Supastash] Invalid date string found on updated_at column for ${table}: ${original}`);
20
+ return original;
21
+ }
17
22
  const lastSyncedAt = new Date(timestamp + 1);
18
23
  const lastSyncedAtISOString = lastSyncedAt.toISOString();
19
24
  return lastSyncedAtISOString;
@@ -1 +1 @@
1
- {"version":3,"file":"pullData.d.ts","sourceRoot":"","sources":["../../../../src/utils/sync/pullFromRemote/pullData.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAoBnE;;;;GAIG;AACH,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,cAAc,GACtB,OAAO,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,CAsE/B"}
1
+ {"version":3,"file":"pullData.d.ts","sourceRoot":"","sources":["../../../../src/utils/sync/pullFromRemote/pullData.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AA2BnE;;;;GAIG;AACH,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,cAAc,GACtB,OAAO,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,CAmF/B"}
@@ -1,6 +1,7 @@
1
1
  import { getSupastashConfig } from "../../../core/config";
2
2
  import log from "../../logs";
3
3
  import { supabaseClientErr } from "../../supabaseClientErr";
4
+ import { getLastCreatedInfo, updateLastCreatedInfo, } from "./getLastCreatedInfo";
4
5
  import { getLastPulledInfo, updateLastPulledInfo } from "./getLastPulledInfo";
5
6
  const validOperators = new Set([
6
7
  "eq",
@@ -14,8 +15,10 @@ const validOperators = new Set([
14
15
  "is",
15
16
  "in",
16
17
  ]);
17
- let timesPulled = 0;
18
- let lastPulled = 0;
18
+ const DEFAULT_MAX_PULL_ATTEMPTS = 150;
19
+ let timesPulled = new Map();
20
+ let lastPulled = new Map();
21
+ const RANDOM_OLD_DATE = "2000-01-01T00:00:00Z";
19
22
  /**
20
23
  * Pulls data from the remote database for a given table
21
24
  * @param table - The table to pull data from
@@ -23,13 +26,14 @@ let lastPulled = 0;
23
26
  */
24
27
  export async function pullData(table, filter) {
25
28
  const lastSyncedAt = await getLastPulledInfo(table);
29
+ const lastCreatedAt = await getLastCreatedInfo(table);
26
30
  const supabase = getSupastashConfig().supabaseClient;
27
31
  if (!supabase)
28
32
  throw new Error(`No supabase client found: ${supabaseClientErr}`);
29
33
  let filteredQuery = supabase
30
34
  .from(table)
31
35
  .select("*")
32
- .gt("updated_at", lastSyncedAt)
36
+ .or(`created_at.gte.${lastCreatedAt},updated_at.gte.${lastSyncedAt}`)
33
37
  .is("deleted_at", null)
34
38
  .order("updated_at", { ascending: false, nullsFirst: false });
35
39
  if (filter &&
@@ -39,33 +43,60 @@ export async function pullData(table, filter) {
39
43
  !filter.value)) {
40
44
  throw new Error(`Invalid filter: ${JSON.stringify(filter)} for table ${table}`);
41
45
  }
46
+ const isValidValue = filter &&
47
+ (filter.operator === "is" ||
48
+ filter.operator === "in" ||
49
+ typeof filter.value !== "undefined");
42
50
  if (filter?.operator &&
43
51
  validOperators.has(filter.operator) &&
44
52
  filter.column &&
45
- filter.value) {
53
+ isValidValue) {
46
54
  filteredQuery = filteredQuery[filter.operator](filter.column, filter.value);
47
55
  }
48
- // Fetch records updated after the last sync
56
+ // Fetch records where created_at >= lastCreatedAt OR updated_at >= lastSyncedAt
49
57
  const { data, error } = await filteredQuery;
50
58
  if (error) {
51
59
  log(`[Supastash] Error fetching from ${table}:`, error.message);
52
60
  return null;
53
61
  }
54
62
  if (!data || data.length === 0) {
55
- timesPulled++;
56
- if (timesPulled >= 150) {
57
- const timeSinceLastPull = Date.now() - lastPulled;
58
- lastPulled = Date.now();
59
- log(`[Supastash] No updates for ${table} at ${lastSyncedAt} (times pulled: ${timesPulled}) in the last ${timeSinceLastPull}ms`);
60
- timesPulled = 0;
63
+ timesPulled.set(table, (timesPulled.get(table) || 0) + 1);
64
+ if ((timesPulled.get(table) || 0) >= DEFAULT_MAX_PULL_ATTEMPTS) {
65
+ const timeSinceLastPull = Date.now() - (lastPulled.get(table) || 0);
66
+ lastPulled.set(table, Date.now());
67
+ log(`[Supastash] No updates for ${table} at ${lastSyncedAt} (times pulled: ${timesPulled.get(table)}) in the last ${timeSinceLastPull}ms`);
68
+ timesPulled.set(table, 0);
61
69
  }
62
70
  return null;
63
71
  }
64
72
  log(`Received ${data.length} updates for ${table}`);
65
- // Update the supastash_sync_status table with the latest timestamp
66
- const latest = data.find((r) => r.updated_at)?.updated_at;
67
- if (latest) {
68
- await updateLastPulledInfo(table, latest);
73
+ // Update the sync status tables with the latest timestamps
74
+ const { createdMaxDate, updatedMaxDate } = getMaxDate(data);
75
+ if (updatedMaxDate) {
76
+ await updateLastPulledInfo(table, updatedMaxDate);
77
+ }
78
+ if (createdMaxDate) {
79
+ await updateLastCreatedInfo(table, createdMaxDate);
69
80
  }
70
81
  return data;
71
82
  }
83
+ function getMaxDate(data) {
84
+ let createdMaxDate = RANDOM_OLD_DATE;
85
+ let updatedMaxDate = RANDOM_OLD_DATE;
86
+ const createdColumn = "created_at";
87
+ const updatedColumn = "updated_at";
88
+ for (const item of data) {
89
+ const createdValue = item[createdColumn];
90
+ const updatedValue = item[updatedColumn];
91
+ if (typeof createdValue === "string" && !isNaN(Date.parse(createdValue))) {
92
+ createdMaxDate = new Date(Math.max(new Date(createdMaxDate).getTime(), new Date(createdValue).getTime())).toISOString();
93
+ }
94
+ if (typeof updatedValue === "string" && !isNaN(Date.parse(updatedValue))) {
95
+ updatedMaxDate = new Date(Math.max(new Date(updatedMaxDate).getTime(), new Date(updatedValue).getTime())).toISOString();
96
+ }
97
+ }
98
+ return {
99
+ createdMaxDate: createdMaxDate === RANDOM_OLD_DATE ? null : createdMaxDate,
100
+ updatedMaxDate: updatedMaxDate === RANDOM_OLD_DATE ? null : updatedMaxDate,
101
+ };
102
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"updateLocalDb.d.ts","sourceRoot":"","sources":["../../../../src/utils/sync/pullFromRemote/updateLocalDb.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAanE;;;GAGG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,cAAc,EACxB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,iBAgDhD;AAID;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,GAAG,EACX,SAAS,CAAC,EAAE,OAAO,iBAkEpB"}
1
+ {"version":3,"file":"updateLocalDb.d.ts","sourceRoot":"","sources":["../../../../src/utils/sync/pullFromRemote/updateLocalDb.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAanE;;;GAGG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,cAAc,EACxB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,iBA+ChD;AAID;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,GAAG,EACX,SAAS,CAAC,EAAE,OAAO,iBAiEpB"}
@@ -2,7 +2,7 @@ import { getSupastashConfig } from "../../../core/config";
2
2
  import { getSupastashDb } from "../../../db/dbInitializer";
3
3
  import { isOnline } from "../../connection";
4
4
  import { getTableSchema } from "../../getTableSchema";
5
- import log from "../../logs";
5
+ import log, { logError, logWarn } from "../../logs";
6
6
  import { refreshScreen } from "../../refreshScreenCalls";
7
7
  import { updateLocalSyncedAt } from "../../syncUpdate";
8
8
  import { pullData } from "./pullData";
@@ -24,18 +24,18 @@ export async function updateLocalDb(table, filters, onReceiveData) {
24
24
  const db = await getSupastashDb();
25
25
  const deletedData = await pullDeletedData(table, filters);
26
26
  const data = await pullData(table, filters);
27
- const dataToUpdate = data?.filter((d) => !deletedData?.deletedDataMap.has(d.id));
28
- const changes = !!deletedData || !!dataToUpdate;
27
+ const refreshNeeded = !!deletedData?.records.length || !!data?.length;
29
28
  // Delete records that are no longer in the remote data
30
- if (deletedData) {
29
+ if (deletedData && deletedData.records.length > 0) {
31
30
  for (const record of deletedData.records) {
32
31
  await db.runAsync(`DELETE FROM ${table} WHERE id = ?`, [record.id]);
33
32
  }
34
- refreshScreen(table);
35
33
  }
36
34
  // Update local database with remote changes
37
- if (dataToUpdate) {
38
- for (const record of dataToUpdate) {
35
+ if (data && data.length > 0) {
36
+ for (const record of data) {
37
+ if (deletedData?.deletedDataMap.has(record.id))
38
+ continue;
39
39
  const { doesExist, newer } = await checkIfRecordExistsAndIsNewer(table, record);
40
40
  if (newer) {
41
41
  if (onReceiveData) {
@@ -47,11 +47,13 @@ export async function updateLocalDb(table, filters, onReceiveData) {
47
47
  }
48
48
  }
49
49
  }
50
- if (changes)
50
+ if (refreshNeeded)
51
51
  refreshScreen(table);
52
52
  }
53
53
  catch (error) {
54
- console.error(`[Supastash] Error updating local db for ${table}`, error);
54
+ if (__DEV__) {
55
+ logError(`[Supastash] Error updating local db for ${table}`, error);
56
+ }
55
57
  }
56
58
  finally {
57
59
  isInSync.delete(table);
@@ -83,20 +85,17 @@ export async function upsertData(table, record, doesExist) {
83
85
  const unknownKeys = Object.keys(record).filter((key) => !columns.includes(key));
84
86
  if (unknownKeys.length > 0 && !warned.get(table)) {
85
87
  warned.set(table, true);
86
- console.warn(`⚠️ [Supastash] ${table} record contains keys not in local schema: ${unknownKeys.join(", ")}. Data will still be stored`);
88
+ logWarn(`⚠️ [Supastash] ${table} record contains keys not in local schema: ${unknownKeys.join(", ")}. Data will still be stored`);
87
89
  }
88
90
  }
89
91
  // Prep for upsert
90
92
  const keys = columns;
91
93
  const placeholders = keys.map(() => "?").join(", ");
92
- const updateParts = keys
93
- .filter((key) => key !== "id")
94
- .map((key) => `${key} = ?`);
94
+ const updateColumns = keys.filter((key) => key !== "id");
95
+ const updateParts = updateColumns.map((key) => `${key} = ?`);
95
96
  const updatePlaceholders = updateParts.join(", ");
96
97
  const values = keys.map((key) => recordToSave[key]);
97
- const updateValues = keys
98
- .filter((key) => key !== "id")
99
- .map((key) => recordToSave[key]);
98
+ const updateValues = updateColumns.map((key) => recordToSave[key]);
100
99
  if (itemExists) {
101
100
  // Update existing record
102
101
  await db.runAsync(`UPDATE ${table} SET ${updatePlaceholders} WHERE id = ?`, [...updateValues, record.id]);
@@ -108,7 +107,7 @@ export async function upsertData(table, record, doesExist) {
108
107
  await updateLocalSyncedAt(table, record.id);
109
108
  }
110
109
  catch (error) {
111
- console.error(`[Supastash] Error upserting data for ${table}`, error);
110
+ logError(`[Supastash] Error upserting data for ${table}`, error);
112
111
  }
113
112
  }
114
113
  async function checkIfRecordExistsAndIsNewer(table, item) {
@@ -1 +1 @@
1
- {"version":3,"file":"sendUnsyncedToSupabase.d.ts","sourceRoot":"","sources":["../../../../src/utils/sync/pushLocal/sendUnsyncedToSupabase.ts"],"names":[],"mappings":"AAQA;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,MAAM,EACb,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,EACrD,MAAM,CAAC,EAAE,MAAM,EAAE,iBAsClB"}
1
+ {"version":3,"file":"sendUnsyncedToSupabase.d.ts","sourceRoot":"","sources":["../../../../src/utils/sync/pushLocal/sendUnsyncedToSupabase.ts"],"names":[],"mappings":"AASA;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,MAAM,EACb,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,EACrD,MAAM,CAAC,EAAE,MAAM,EAAE,iBAsClB"}
@@ -1,4 +1,5 @@
1
1
  import { isOnline } from "../../connection";
2
+ import { logError } from "../../logs";
2
3
  import { refreshScreen } from "../../refreshScreenCalls";
3
4
  import { deleteData } from "./deleteChunks";
4
5
  import { getAllDeletedData, getAllUnsyncedData } from "./getAllUnsyncedData";
@@ -35,7 +36,7 @@ export async function pushLocalDataToRemote(table, onPushToRemote, noSync) {
35
36
  }
36
37
  }
37
38
  catch (error) {
38
- console.error(`[Supastash] Error pushing local data to remote for ${table}`, error);
39
+ logError(`[Supastash] Error pushing local data to remote for ${table}`, error);
39
40
  }
40
41
  finally {
41
42
  isInSync.delete(table);
@@ -1,5 +1,5 @@
1
1
  import { getSupastashConfig } from "../../../core/config";
2
- import log from "../../logs";
2
+ import log, { logError } from "../../logs";
3
3
  import { supabaseClientErr } from "../../supabaseClientErr";
4
4
  import { updateLocalSyncedAt } from "../../syncUpdate";
5
5
  import { parseStringifiedFields } from "./parseFields";
@@ -77,7 +77,7 @@ async function uploadChunk(table, chunk, onPushToRemote) {
77
77
  if (onPushToRemote) {
78
78
  const result = await onPushToRemote(toUpsert);
79
79
  if (typeof result !== "boolean") {
80
- console.error(`[Supastash] Invalid return type from "onPushToRemote" callback on table ${table}.\n
80
+ logError(`[Supastash] Invalid return type from "onPushToRemote" callback on table ${table}.\n
81
81
  Expected boolean but received ${typeof result}.\n
82
82
  Skipping this chunk.
83
83
  Check the "onPushToRemote" callback in the "useSupastashData" hook for table ${table}.
@@ -1 +1 @@
1
- {"version":3,"file":"syncStatus.d.ts","sourceRoot":"","sources":["../../src/utils/syncStatus.ts"],"names":[],"mappings":"AASA;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,iBAKxD;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,kBAIzC;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;IAChE,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,IAAI,CAAC,CAUR;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,iBAM5E;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,iBAM1D;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,kBAI3C;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;IAClE,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,IAAI,CAAC,CAUR;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,iBAOtB"}
1
+ {"version":3,"file":"syncStatus.d.ts","sourceRoot":"","sources":["../../src/utils/syncStatus.ts"],"names":[],"mappings":"AAUA;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,iBAKxD;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,kBAKzC;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;IAChE,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,IAAI,CAAC,CAUR;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,iBAM5E;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,iBAM1D;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,kBAI3C;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;IAClE,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,IAAI,CAAC,CAUR;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,iBAOtB"}
@@ -2,6 +2,7 @@ import { getSupastashDb } from "../db/dbInitializer";
2
2
  import { createDeletedStatusTable, createSyncStatusTable, } from "./schema/createSyncStatus";
3
3
  const SYNC_STATUS_TABLE = "supastash_sync_status";
4
4
  const DELETED_STATUS_TABLE = "supastash_deleted_status";
5
+ const LAST_CREATED_TABLE = "supastash_last_created";
5
6
  /**
6
7
  * Clears the sync log for a given table
7
8
  * @param tableName - The name of the table to clear the sync status for
@@ -22,6 +23,7 @@ export async function clearLocalSyncLog(tableName) {
22
23
  export async function clearAllLocalSyncLog() {
23
24
  const db = await getSupastashDb();
24
25
  await db.runAsync(`DROP TABLE IF EXISTS ${SYNC_STATUS_TABLE}`);
26
+ await db.runAsync(`DROP TABLE IF EXISTS ${LAST_CREATED_TABLE}`);
25
27
  await createSyncStatusTable();
26
28
  }
27
29
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"syncUpdate.d.ts","sourceRoot":"","sources":["../../src/utils/syncUpdate.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,iBAYtE"}
1
+ {"version":3,"file":"syncUpdate.d.ts","sourceRoot":"","sources":["../../src/utils/syncUpdate.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,iBAYtE"}
@@ -1,4 +1,5 @@
1
1
  import { getSupastashDb } from "../db/dbInitializer";
2
+ import { logError } from "./logs";
2
3
  /**
3
4
  * Updates synced_at from null to a timeStamp
4
5
  * @param tableName - The name of the table to update
@@ -14,6 +15,6 @@ export async function updateLocalSyncedAt(tableName, id) {
14
15
  ]);
15
16
  }
16
17
  catch (error) {
17
- console.error(error);
18
+ logError(error);
18
19
  }
19
20
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "supastash",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",