supastash 0.1.4 → 0.1.6

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 (69) hide show
  1. package/README.md +78 -119
  2. package/dist/hooks/supastashData/addPayloadToUI.d.ts.map +1 -1
  3. package/dist/hooks/supastashData/addPayloadToUI.js +1 -0
  4. package/dist/hooks/supastashData/dataState.d.ts +3 -4
  5. package/dist/hooks/supastashData/dataState.d.ts.map +1 -1
  6. package/dist/hooks/supastashData/dataState.js +5 -4
  7. package/dist/hooks/supastashData/eventQueues.d.ts +1 -1
  8. package/dist/hooks/supastashData/eventQueues.d.ts.map +1 -1
  9. package/dist/hooks/supastashData/eventQueues.js +4 -6
  10. package/dist/hooks/supastashData/fetchCalls.d.ts +1 -2
  11. package/dist/hooks/supastashData/fetchCalls.d.ts.map +1 -1
  12. package/dist/hooks/supastashData/fetchCalls.js +3 -8
  13. package/dist/hooks/supastashData/index.d.ts +38 -35
  14. package/dist/hooks/supastashData/index.d.ts.map +1 -1
  15. package/dist/hooks/supastashData/index.js +51 -45
  16. package/dist/hooks/syncEngine/index.d.ts.map +1 -1
  17. package/dist/hooks/syncEngine/index.js +56 -51
  18. package/dist/hooks/syncEngine/pushLocal/index.js +1 -1
  19. package/dist/store/localCache.d.ts +7 -0
  20. package/dist/store/localCache.d.ts.map +1 -0
  21. package/dist/store/localCache.js +1 -0
  22. package/dist/types/query.types.d.ts +6 -1
  23. package/dist/types/realtimeData.types.d.ts +38 -5
  24. package/dist/utils/fetchData/deleteData.d.ts +1 -1
  25. package/dist/utils/fetchData/deleteData.d.ts.map +1 -1
  26. package/dist/utils/fetchData/deleteData.js +3 -4
  27. package/dist/utils/fetchData/fetchLocalData.d.ts +10 -3
  28. package/dist/utils/fetchData/fetchLocalData.d.ts.map +1 -1
  29. package/dist/utils/fetchData/fetchLocalData.js +79 -27
  30. package/dist/utils/fetchData/realTimeCall.d.ts.map +1 -1
  31. package/dist/utils/fetchData/realTimeCall.js +6 -10
  32. package/dist/utils/fetchData/receiveData.d.ts +1 -1
  33. package/dist/utils/fetchData/receiveData.d.ts.map +1 -1
  34. package/dist/utils/fetchData/receiveData.js +9 -9
  35. package/dist/utils/fetchData/snapShot.d.ts +4 -0
  36. package/dist/utils/fetchData/snapShot.d.ts.map +1 -0
  37. package/dist/utils/fetchData/snapShot.js +34 -0
  38. package/dist/utils/query/builder/crud.d.ts +17 -3
  39. package/dist/utils/query/builder/crud.d.ts.map +1 -1
  40. package/dist/utils/query/builder/crud.js +16 -3
  41. package/dist/utils/query/builder/index.d.ts.map +1 -1
  42. package/dist/utils/query/builder/index.js +1 -0
  43. package/dist/utils/query/builder/mainQuery.js +1 -1
  44. package/dist/utils/query/helpers/localDb/getLocalMethod.d.ts +1 -1
  45. package/dist/utils/query/helpers/localDb/getLocalMethod.d.ts.map +1 -1
  46. package/dist/utils/query/helpers/localDb/getLocalMethod.js +2 -2
  47. package/dist/utils/query/helpers/localDb/localQueryBuilder.d.ts +1 -1
  48. package/dist/utils/query/helpers/localDb/localQueryBuilder.d.ts.map +1 -1
  49. package/dist/utils/query/helpers/localDb/localQueryBuilder.js +2 -2
  50. package/dist/utils/query/helpers/mainQueryHelpers.d.ts.map +1 -1
  51. package/dist/utils/query/helpers/mainQueryHelpers.js +8 -1
  52. package/dist/utils/query/localDbQuery/index.d.ts.map +1 -1
  53. package/dist/utils/query/localDbQuery/index.js +2 -2
  54. package/dist/utils/query/localDbQuery/upsert.d.ts +1 -1
  55. package/dist/utils/query/localDbQuery/upsert.d.ts.map +1 -1
  56. package/dist/utils/query/localDbQuery/upsert.js +37 -18
  57. package/dist/utils/query/remoteQuery/supabaseQuery.d.ts +1 -0
  58. package/dist/utils/query/remoteQuery/supabaseQuery.d.ts.map +1 -1
  59. package/dist/utils/query/remoteQuery/supabaseQuery.js +52 -6
  60. package/dist/utils/schema/wipeTables.js +1 -1
  61. package/dist/utils/sync/pullFromRemote/pullData.js +8 -8
  62. package/dist/utils/sync/pullFromRemote/pullDeletedData.js +8 -8
  63. package/dist/utils/sync/pullFromRemote/updateLocalDb.d.ts.map +1 -1
  64. package/dist/utils/sync/pullFromRemote/updateLocalDb.js +5 -2
  65. package/dist/utils/sync/pushLocal/sendUnsyncedToSupabase.js +1 -1
  66. package/dist/utils/sync/refreshTables.d.ts +1 -0
  67. package/dist/utils/sync/refreshTables.d.ts.map +1 -1
  68. package/dist/utils/sync/refreshTables.js +2 -1
  69. package/package.json +5 -2
package/README.md CHANGED
@@ -1,27 +1,25 @@
1
1
  # Supastash
2
2
 
3
- **Offline-First Sync Engine for Supabase + React Native.**
3
+ **Offline-First Sync Engine for Supabase + React Native**
4
4
 
5
- > Reliable offline-first syncing for Supabase + React Native using local SQLite. Plug in your adapter and get syncing no boilerplate.
5
+ > Sync local SQLite data with Supabase in real-time even when your app is offline. Built for React Native, no boilerplate required.
6
6
 
7
- Supastash makes it effortless to build offline-capable mobile apps using **SQLite for local-first storage** and **Supabase for cloud sync**. Designed for React Native, Supastash handles syncing, conflict resolution, realtime updates, and local querying so you can focus on features, not infrastructure.
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.
8
8
 
9
9
  ---
10
10
 
11
- ### 📚 Documentation
12
-
13
- Read the [Docs](https://0xzekea.github.io/supastash/)
11
+ ## 📚 **[Read the Full Docs »](https://0xzekea.github.io/supastash/)**
14
12
 
15
13
  ---
16
14
 
17
- ## 🚀 Features
15
+ ## Features
18
16
 
19
- - 🔁 **Two-way sync** with Supabase
20
- - 💾 **Local-first querying** with React Native SQLite
21
- - ⚡ **Realtime updates** using Supabase channels
22
- - 🔌 **Pluggable SQLite adapters** (`expo-sqlite`, `react-native-nitro-sqlite`, `react-native-sqlite-storage`)
23
- - **Built-in deduplication**, conflict resolution, and background retries
24
- - 🧠 Designed to support **event batching**, **job staging**, and fine-grained sync control
17
+ - 🔁 Two-way sync with Supabase
18
+ - 💾 Local-first querying via SQLite
19
+ - ⚡ Realtime updates (INSERT, UPDATE, DELETE)
20
+ - 🔌 Works with any SQLite adapter (`expo-sqlite`, `rn-nitro`, `sqlite-storage`)
21
+ - 🧠 Handles conflict resolution, batching, retries
22
+ - 🧩 Supports filtering, job staging, and advanced sync control
25
23
 
26
24
  ---
27
25
 
@@ -29,31 +27,34 @@ Read the [Docs](https://0xzekea.github.io/supastash/)
29
27
 
30
28
  ```bash
31
29
  npm install supastash
32
- # or
33
- yarn add supastash
34
30
  ```
35
31
 
36
- ### 📎 Peer Dependencies (You MUST install these)
32
+ ### Required Peer Dependencies
37
33
 
38
34
  ```bash
39
- npm install @supabase/supabase-js
40
- @react-native-community/netinfo
41
- react
42
- react-native
35
+ npm install @supabase/supabase-js \
36
+ @react-native-community/netinfo \
37
+ react react-native
38
+ ```
39
+
40
+ ### Choose one SQLite adapter:
43
41
 
44
- # Choose one SQLite adapter:
42
+ ```bash
43
+ # Expo
45
44
  npm install expo-sqlite
46
- # OR React Native Nitro
45
+
46
+ # React Native Nitro (faster)
47
47
  npm install react-native-nitro-sqlite
48
- # OR React Native SQLite Storage
48
+
49
+ # Or classic storage
49
50
  npm install react-native-sqlite-storage
50
51
  ```
51
52
 
52
- > `sqliteClientType` must match your adapter: "expo", "rn-nitro", or "rn-storage"
53
+ > Match with: `"sqliteClientType": "expo"`, `"rn-nitro"`, or `"rn-storage"`
53
54
 
54
55
  ---
55
56
 
56
- ## ⚙️ Setup
57
+ ## ⚙️ Quick Setup
57
58
 
58
59
  ```ts
59
60
  // lib/supastash.ts
@@ -66,6 +67,7 @@ configureSupastash({
66
67
  dbName: "supastash_db",
67
68
  sqliteClient: { openDatabaseAsync },
68
69
  sqliteClientType: "expo",
70
+
69
71
  onSchemaInit: () => {
70
72
  defineLocalSchema(
71
73
  "users",
@@ -73,60 +75,48 @@ configureSupastash({
73
75
  id: "TEXT PRIMARY KEY",
74
76
  name: "TEXT",
75
77
  email: "TEXT",
76
- created_at: "TIMESTAMP DEFAULT CURRENT_TIMESTAMP",
77
- updated_at: "TIMESTAMP DEFAULT CURRENT_TIMESTAMP",
78
+ created_at: "TIMESTAMP",
79
+ updated_at: "TIMESTAMP",
78
80
  },
79
81
  true
80
82
  );
81
83
  },
84
+
82
85
  debugMode: true,
83
86
  syncEngine: {
84
87
  push: true,
85
- pull: false, // ⚠️ Pull sync is disabled by default.
88
+ pull: false, // enable if using RLS
86
89
  },
87
90
  });
88
91
  ```
89
92
 
90
- Then initialize early:
93
+ Then in your root layout:
91
94
 
92
95
  ```ts
93
- // _layout.tsx or App.tsx
96
+ // App.tsx or _layout.tsx
94
97
  import "@/lib/supastash";
95
98
 
96
- export default function RootLayout() {
99
+ export default function App() {
97
100
  return <Stack />;
98
101
  }
99
102
  ```
100
103
 
101
104
  ---
102
105
 
103
- ## 🚨 Key Notes
104
-
105
- > ⚠️ **Important:** All timestamp fields (`created_at`, `updated_at`) used for syncing **must be `timestamptz`** in Supabase. This avoids timezone mismatch issues and ensures reliable sync.
106
+ ## 🚨 Important Notes
106
107
 
107
- - Supabase tables **must** include:
108
-
109
- - `id`, `created_at`, `updated_at`, `deleted_at`
110
- - Avoid null primary keys
111
-
112
- - To enable schema reflection, create this Supabase RPC:
108
+ - Timestamp fields (`created_at`, `updated_at`, `deleted_at`) **must be `timestamptz`** in Supabase
109
+ - Every synced table must have a valid `id`
110
+ - Create this SQL function in Supabase to allow schema reflection:
113
111
 
114
112
  ```sql
115
113
  create or replace function get_table_schema(table_name text)
116
- returns table(
117
- column_name text,
118
- data_type text,
119
- is_nullable text
120
- )
114
+ returns table(column_name text, data_type text, is_nullable text)
121
115
  security definer
122
116
  as $$
123
- select
124
- column_name,
125
- data_type,
126
- is_nullable
117
+ select column_name, data_type, is_nullable
127
118
  from information_schema.columns
128
- where table_schema = 'public'
129
- and table_name = $1;
119
+ where table_schema = 'public' and table_name = $1;
130
120
  $$ language sql;
131
121
 
132
122
  grant execute on function get_table_schema(text) to anon, authenticated;
@@ -134,130 +124,99 @@ grant execute on function get_table_schema(text) to anon, authenticated;
134
124
 
135
125
  ---
136
126
 
137
- ## 🧪 Basic Usage
138
-
139
- ### `useSupatashData` hook
127
+ ## 🧪 Example: `useSupatashData`
140
128
 
141
- ```ts
129
+ ```tsx
142
130
  import { useSupatashData } from "supastash";
143
131
 
144
- type Order = {
145
- id: string;
146
- user_id: string;
147
- deleted_at: string | null;
148
- updated_at: string;
149
- created_at: string;
150
- };
132
+ const { data, dataMap } = useSupatashData("orders");
133
+ ```
151
134
 
152
- const { data: orders, dataMap: ordersMap } = useSupatashData<Order>("orders");
135
+ Filtered by user:
153
136
 
154
- // Filtered
137
+ ```tsx
155
138
  const { userId } = useAuth();
156
- const { data: userOrders } = useSupatashData<Order>("orders", {
139
+ const { data: userOrders } = useSupatashData("orders", {
157
140
  filter: { column: "user_id", operator: "eq", value: userId },
158
141
  shouldFetch: !!userId,
159
142
  });
160
143
  ```
161
144
 
162
- ### `useSupatash`
145
+ Ensure sync engine is ready:
163
146
 
164
- ```ts
147
+ ```tsx
165
148
  import { useSupatash } from "supastash";
166
149
 
167
150
  const { dbReady } = useSupatash();
168
151
  if (!dbReady) return null;
169
- return <Stack />;
170
152
  ```
171
153
 
172
154
  ---
173
155
 
174
- ## 📘 API Overview
175
-
176
- ### `configureSupastash(config)`
177
-
178
- Initialize sync system.
179
-
180
- ### `useSupatashData(table, options)`
156
+ ## 🔧 API Overview
181
157
 
182
- Access data with local cache, syncing, filtering, etc.
183
-
184
- Returns:
185
-
186
- ```ts
187
- {
188
- data: R[];
189
- dataMap: Map<string, R>;
190
- trigger: () => void;
191
- cancel: () => void;
192
- }
193
- ```
194
-
195
- ### `refreshTable(table: string)` / `refreshAllTables()`
196
-
197
- Force-refresh any or all table data.
158
+ - [`configureSupastash()`](https://0xzekea.github.io/supastash/docs/configuration)) setup + schema
159
+ - [`useSupatashData()`](https://0xzekea.github.io/supastash/docs/data-access)) – read/write synced local data
198
160
 
199
161
  ---
200
162
 
201
- ## 🔄 Sync Internals
163
+ ## 🔄 How Sync Works
202
164
 
203
- - Safe writes with `created_at`, `updated_at`, `deleted_at`
204
- - Retries with **exponential backoff**
205
- - Batched inserts, updates, deletes
206
- - Real-time changes are applied directly to local cache
165
+ - Tracks changes with `created_at`, `updated_at`, `deleted_at`
166
+ - Retries failed syncs with exponential backoff
167
+ - Batches realtime + manual changes efficiently
168
+ - Keeps local cache as the main source of truth
207
169
 
208
170
  ---
209
171
 
210
- ### Sync Modes (per-query control)
211
-
212
- You can control how each query syncs:
213
-
214
- - `localOnly`: Use only local data
215
- - `remoteOnly`: Fetch directly from Supabase
216
- - `localFirst` _(default)_: Read/write locally, then sync to Supabase
217
- - `remoteFirst`: Write to Supabase first, then update local
172
+ ## 🧩 Sync Modes (via query builder)
218
173
 
219
- Use `.syncMode("...")` or `{ viewRemoteResult: true }` in `.run()` to control behavior.
174
+ ```ts
175
+ supastash
176
+ .from("orders")
177
+ .select("*")
178
+ .syncMode("remoteOnly") // or localOnly, localFirst, remoteFirst
179
+ .run();
180
+ ```
220
181
 
221
182
  ---
222
183
 
223
- ## 📁 Project Structure
184
+ ## 🗂 Example Project Structure
224
185
 
225
186
  ```
226
187
  src/
227
- ├─ core/ # Supabase + sync logic
228
- ├─ hooks/ # Main React hooks
188
+ ├─ core/ # Config
189
+ ├─ hooks/ # Custom hooks
229
190
  ├─ types/ # Type definitions
230
- ├─ utils/ # Helper utilities
191
+ ├─ utils/ # Helpers
231
192
  ```
232
193
 
233
194
  ---
234
195
 
235
- ## 🔧 Testing
196
+ ## 🧪 Testing & Dev
236
197
 
237
198
  ```bash
199
+ # Run tests
238
200
  yarn test
239
- ```
240
201
 
241
- Uses `vitest` for unit testing.
202
+ # Start local dev build
203
+ yarn dev
204
+ ```
242
205
 
243
206
  ---
244
207
 
245
208
  ## 🤝 Contributing
246
209
 
247
- ```bash
248
- yarn dev
249
- ```
250
-
251
- Open a PR with tests and typed signatures. PRs welcome.
210
+ PRs welcome! Please include tests and type signatures.
252
211
 
253
212
  ---
254
213
 
255
214
  ## 📜 License
256
215
 
257
- MIT License © Ezekiel Akpan
216
+ MIT © Ezekiel Akpan
258
217
 
259
218
  ---
260
219
 
261
220
  ## 💬 Questions?
262
221
 
263
- Open an issue or reach out on [X @0xZekeA](https://x.com/0xZekeA)
222
+ Open an issue or reach out on [X (Twitter) @0xZekeA](https://x.com/0xZekeA)
@@ -1 +1 @@
1
- {"version":3,"file":"addPayloadToUI.d.ts","sourceRoot":"","sources":["../../../src/hooks/supastashData/addPayloadToUI.ts"],"names":[],"mappings":"AAoBA,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,GAAG,GAAG,GAAG,EAAE,EACpB,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,EAC9D,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,EACxD,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,QAoBrD"}
1
+ {"version":3,"file":"addPayloadToUI.d.ts","sourceRoot":"","sources":["../../../src/hooks/supastashData/addPayloadToUI.ts"],"names":[],"mappings":"AAsBA,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,GAAG,GAAG,GAAG,EAAE,EACpB,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,EAC9D,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,EACxD,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,QAoBrD"}
@@ -1,3 +1,4 @@
1
+ // Deprecated
1
2
  const versionMap = new Map();
2
3
  function getNewVersion(table, setter) {
3
4
  if (versionMap.get(table)) {
@@ -1,8 +1,7 @@
1
- declare function useDataState<R = any>(table: string): {
1
+ declare function useDataState<R, T>(table: string): {
2
2
  dataMap: Map<string, R>;
3
- setDataMap: import("react").Dispatch<import("react").SetStateAction<Map<string, R>>>;
4
- version: string;
5
- setVersion: import("react").Dispatch<import("react").SetStateAction<string>>;
3
+ data: Array<R>;
4
+ groupedBy?: { [K in keyof T]: Map<T[K], Array<R>>; };
6
5
  };
7
6
  export default useDataState;
8
7
  //# sourceMappingURL=dataState.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dataState.d.ts","sourceRoot":"","sources":["../../../src/hooks/supastashData/dataState.ts"],"names":[],"mappings":"AAEA,iBAAS,YAAY,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,MAAM;;;;;EAI3C;AAED,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"dataState.d.ts","sourceRoot":"","sources":["../../../src/hooks/supastashData/dataState.ts"],"names":[],"mappings":"AAGA,iBAAS,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,GAQ4B;IACjE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACxB,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IACf,SAAS,CAAC,EAAE,GACT,CAAC,IAAI,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GACpC,CAAC;CACH,CACF;AAED,eAAe,YAAY,CAAC"}
@@ -1,7 +1,8 @@
1
- import { useState } from "react";
1
+ import { useCallback, useSyncExternalStore } from "react";
2
+ import { getSnapshot, subscribe } from "../../utils/fetchData/snapShot";
2
3
  function useDataState(table) {
3
- const [version, setVersion] = useState(`${table}-${Date.now()}`);
4
- const [dataMap, setDataMap] = useState(new Map());
5
- return { dataMap, setDataMap, version, setVersion };
4
+ const stableSubscribe = useCallback((cb) => subscribe(table, cb), [table]);
5
+ const getStableSnapshot = useCallback(() => getSnapshot(table), [table]);
6
+ return useSyncExternalStore(stableSubscribe, getStableSnapshot);
6
7
  }
7
8
  export default useDataState;
@@ -1,5 +1,5 @@
1
1
  import { PayloadData } from "../../types/query.types";
2
2
  import { RealtimeOptions } from "../../types/realtimeData.types";
3
- declare function useEventQueues(table: string, setDataMap: React.Dispatch<React.SetStateAction<Map<string, any>>>, setVersion: React.Dispatch<React.SetStateAction<string>>, options: RealtimeOptions, flushIntervalMs: number): (eventType: string, data: PayloadData) => void;
3
+ declare function useEventQueues<R>(table: string, options: RealtimeOptions<R>, flushIntervalMs: number): (eventType: string, data: PayloadData) => void;
4
4
  export default useEventQueues;
5
5
  //# sourceMappingURL=eventQueues.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"eventQueues.d.ts","sourceRoot":"","sources":["../../../src/hooks/supastashData/eventQueues.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAKjE,iBAAS,cAAc,CACrB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,EAClE,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,EACxD,OAAO,EAAE,eAAe,EACxB,eAAe,EAAE,MAAM,eA6CU,MAAM,QAAQ,WAAW,UAgB3D;AAED,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"eventQueues.d.ts","sourceRoot":"","sources":["../../../src/hooks/supastashData/eventQueues.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAKjE,iBAAS,cAAc,CAAC,CAAC,EACvB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,EAC3B,eAAe,EAAE,MAAM,eA8CU,MAAM,QAAQ,WAAW,UAgB3D;AAED,eAAe,cAAc,CAAC"}
@@ -2,7 +2,7 @@ import { useRef } from "react";
2
2
  import { deleteData } from "../../utils/fetchData/deleteData";
3
3
  import { receiveData } from "../../utils/fetchData/receiveData";
4
4
  import useDataState from "./dataState";
5
- function useEventQueues(table, setDataMap, setVersion, options, flushIntervalMs) {
5
+ function useEventQueues(table, options, flushIntervalMs) {
6
6
  const { dataMap } = useDataState(table);
7
7
  const insertQueue = useRef([]);
8
8
  const updateQueue = useRef([]);
@@ -11,15 +11,13 @@ function useEventQueues(table, setDataMap, setVersion, options, flushIntervalMs)
11
11
  const flush = () => {
12
12
  if (options.shouldFetch) {
13
13
  insertQueue.current.forEach((item) => {
14
- receiveData(item, table, setDataMap, setVersion, options.shouldFetch);
15
- options.onInsertAndUpdate?.(item) || options.onInsert?.(item);
14
+ receiveData(item, table, options.shouldFetch, options.onInsertAndUpdate || options.onInsert);
16
15
  });
17
16
  updateQueue.current.forEach((item) => {
18
- receiveData(item, table, setDataMap, setVersion, options.shouldFetch);
19
- options.onInsertAndUpdate?.(item) || options.onUpdate?.(item);
17
+ receiveData(item, table, options.shouldFetch, options.onInsertAndUpdate || options.onInsert);
20
18
  });
21
19
  deleteQueue.current.forEach((item) => {
22
- deleteData(item, table, setDataMap, setVersion, dataMap, options.shouldFetch);
20
+ deleteData(item, table, options.shouldFetch);
23
21
  options.onDelete?.(item);
24
22
  });
25
23
  insertQueue.current = [];
@@ -1,9 +1,8 @@
1
1
  import { RealtimeOptions } from "../../types/realtimeData.types";
2
- export declare function fetchCalls(table: string, setDataMap: React.Dispatch<React.SetStateAction<Map<string, any>>>, setVersion: React.Dispatch<React.SetStateAction<string>>, options: RealtimeOptions, initialized: React.RefObject<boolean>): {
2
+ export declare function fetchCalls<R>(table: string, options: RealtimeOptions<R>, initialized: React.RefObject<boolean>): {
3
3
  triggerRefresh: () => Promise<void>;
4
4
  trigger: () => void;
5
5
  cancel: () => void;
6
6
  initialFetchAndSync: () => Promise<void>;
7
- pushToUI: (payload: any | any[], operation: "insert" | "update" | "delete" | "upsert") => Promise<void>;
8
7
  };
9
8
  //# sourceMappingURL=fetchCalls.d.ts.map
@@ -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;AASjE,wBAAgB,UAAU,CACxB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,EAClE,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,EACxD,OAAO,EAAE,eAAe,EACxB,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC;;;;;wBA2E1B,GAAG,GAAG,GAAG,EAAE,aACT,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ;EAYvD"}
1
+ {"version":3,"file":"fetchCalls.d.ts","sourceRoot":"","sources":["../../../src/hooks/supastashData/fetchCalls.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAQjE,wBAAgB,UAAU,CAAC,CAAC,EAC1B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,EAC3B,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC;;;;;EAkFtC"}
@@ -4,11 +4,10 @@ import { tableFilters } from "../../store/tableFilters";
4
4
  import { fetchLocalData } from "../../utils/fetchData/fetchLocalData";
5
5
  import { initialFetch } from "../../utils/fetchData/initialFetch";
6
6
  import log from "../../utils/logs";
7
- import { addPayloadToUI } from "./addPayloadToUI";
8
7
  const timesFetched = new Map();
9
8
  let lastFetched = new Map();
10
- export function fetchCalls(table, setDataMap, setVersion, options, initialized) {
11
- const { shouldFetch = true, limit, filter, onPushToRemote, onInsertAndUpdate, useFilterWhileSyncing = true, } = options;
9
+ export function fetchCalls(table, options, initialized) {
10
+ const { shouldFetch = true, limit, filter, onPushToRemote, onInsertAndUpdate, useFilterWhileSyncing = true, extraMapKeys, daylength, } = options;
12
11
  const cancelled = useRef(false);
13
12
  useEffect(() => {
14
13
  if (filter && useFilterWhileSyncing && !tableFilters.get(table)) {
@@ -29,7 +28,7 @@ export function fetchCalls(table, setDataMap, setVersion, options, initialized)
29
28
  }, []);
30
29
  const fetch = async () => {
31
30
  if (!cancelled.current) {
32
- await fetchLocalData(table, setDataMap, setVersion, shouldFetch, limit);
31
+ await fetchLocalData(table, shouldFetch, limit, extraMapKeys, daylength);
33
32
  }
34
33
  };
35
34
  const trigger = () => {
@@ -63,14 +62,10 @@ export function fetchCalls(table, setDataMap, setVersion, options, initialized)
63
62
  console.error(`[Supastash] Error on initial fetch for ${table}`, error);
64
63
  }
65
64
  };
66
- const pushToUI = async (payload, operation) => {
67
- addPayloadToUI(table, payload, setDataMap, setVersion, operation);
68
- };
69
65
  return {
70
66
  triggerRefresh,
71
67
  trigger,
72
68
  cancel,
73
69
  initialFetchAndSync,
74
- pushToUI,
75
70
  };
76
71
  }
@@ -1,53 +1,56 @@
1
1
  import { RealtimeOptions, SupastashDataResult } from "../../types/realtimeData.types";
2
2
  /**
3
3
  * @description
4
- * React hook to sync and subscribe to local-first data from a Supabase table.
4
+ * React hook to sync and subscribe to local-first data from a Supabase table using Supastash.
5
5
  *
6
- * - Fetches initial data from a local SQLite table using Supastash.
7
- * - Subscribes to Supabase `postgres_changes` for INSERT, UPDATE, DELETE events.
8
- * - Batches updates and applies them to local state at controlled intervals.
9
- * - Supports optional callbacks for reacting to specific event types.
10
- * - Lazy loading and manual triggers are supported for better control in UI flows.
6
+ * This hook:
7
+ * - Fetches initial data from local SQLite (offline-first).
8
+ * - Optionally subscribes to Supabase `postgres_changes` for realtime updates.
9
+ * - Batches and flushes changes into state at a controlled interval.
10
+ * - Supports lazy loading, manual triggers, and event callbacks.
11
11
  *
12
12
  * @example
13
13
  * const authenticated = !!session?.user;
14
- *
15
14
  * const { data, dataMap, trigger, cancel } = useSupastashData("users", {
16
- * filter: {
17
- * column: "user_id",
18
- * operator: "eq",
19
- * value: 1,
20
- * },
21
- * shouldFetch: authenticated, // Only fetch if allowed
15
+ * shouldFetch: authenticated,
16
+ * filter: { column: "user_id", operator: "eq", value: 1 },
22
17
  * flushIntervalMs: 200,
23
18
  * onInsert: (user) => console.log("User added:", user),
24
- * lazy: true, // Don't fetch or subscribe until trigger() is called
19
+ * lazy: true,
25
20
  * });
26
21
  *
27
22
  * useEffect(() => {
28
- * trigger(); // Manually start loading
23
+ * trigger(); // manually start sync
29
24
  * }, []);
30
25
  *
31
- * @param table - The name of the table to subscribe to (must match the local table name).
32
- * @param options.shouldFetch - If true, loads data from the local DB on mount. Defaults to true.
33
- * @param options.filter - Optional structured filter for realtime subscription.
34
- * @param options.flushIntervalMs - Interval in ms to flush batched changes into state. Defaults to 100ms.
35
- * @param options.lazy - If true, disables auto-fetch. Use `trigger()` to manually start.
36
- * @param options.onInsert - Optional callback triggered on INSERT events.
37
- * @param options.onUpdate - Optional callback triggered on UPDATE events.
38
- * @param options.onDelete - Optional callback triggered on DELETE events.
39
- * @param options.realtime - If true, subscribes to realtime changes. Defaults to true.
40
- * @param options.onInsertAndUpdate - Optional callback triggered on INSERT and UPDATE events.
41
- * @param options.onPushToRemote - Optional callback triggered on INSERT and UPDATE events.
42
- * @param options.onDelete - Optional callback triggered on DELETE events.
43
- * @param options.limit - Optional limit for the number of records to fetch initially. Defaults to 200.
44
- * @param options.useFilterWhileSyncing - If true, uses the filter while syncing. Defaults to true.
45
- *
46
- * @returns
47
- * - `data`: Array of local data, memoized by version.
48
- * - `dataMap`: Map of data keyed by ID.
49
- * - `trigger`: Starts fetch and subscription (used with `lazy: true`).
50
- * - `cancel`: Cancels a pending fetch or blocks lazy init.
26
+ * @param table - The table name (must match local SQLite table).
27
+ * @param options - Configuration object:
28
+ *
29
+ * ### Fetch Options:
30
+ * @param options.shouldFetch - If `false`, prevents initial fetch. Defaults to `true`.
31
+ * @param options.lazy - If `true`, disables auto-fetch. Call `trigger()` manually.
32
+ * @param options.limit - Max number of records to load from local DB. Defaults to `200`.
33
+ * @param options.useFilterWhileSyncing - If `true`, applies filter while syncing. Defaults to `true`.
34
+ * @param options.extraMapKey - Field to additionally group data by (`groupedBy`).
35
+ *
36
+ * ### Realtime Options:
37
+ * @param options.realtime - If `true`, subscribes to Supabase realtime. Defaults to `true`.
38
+ * @param options.filter - Structured filter (column, operator, value) for realtime subscription.
39
+ * @param options.flushIntervalMs - How often (ms) to apply batched changes to UI. Defaults to `100`.
40
+ *
41
+ * ### Event Callbacks:
42
+ * @param options.onInsert - Triggered on INSERT event.
43
+ * @param options.onUpdate - Triggered on UPDATE event.
44
+ * @param options.onDelete - Triggered on DELETE event.
45
+ * @param options.onInsertAndUpdate - Triggered on both INSERT and UPDATE.
46
+ * @param options.onPushToRemote - Called when a record is pushed to Supabase.
47
+ *
48
+ * @returns Object with:
49
+ * - `data`: Array of records.
50
+ * - `dataMap`: Map of records keyed by ID.
51
+ * - `groupedBy`: Optional maps grouped by fields (like `chat_id`).
52
+ * - `trigger()`: Manually start sync (used with lazy).
53
+ * - `cancel()`: Cancel a pending or lazy fetch.
51
54
  */
52
55
  export declare function useSupastashData<R = any>(table: string, options?: RealtimeOptions): SupastashDataResult<R>;
53
56
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/supastashData/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,eAAe,EACf,mBAAmB,EACpB,MAAM,gCAAgC,CAAC;AAWxC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,GAAG,GAAG,EACtC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,eAAoB,GAC5B,mBAAmB,CAAC,CAAC,CAAC,CAwDxB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/supastashData/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,eAAe,EACf,mBAAmB,EACpB,MAAM,gCAAgC,CAAC;AAWxC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,GAAG,GAAG,EACtC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,eAAoB,GAC5B,mBAAmB,CAAC,CAAC,CAAC,CA2ExB"}