@pol-studios/db 1.0.19 → 1.0.22
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/DataLayerContext-ZmLPYR_s.d.ts +825 -0
- package/dist/EntityPermissions-DwFt4tUd.d.ts +35 -0
- package/dist/FilterConfig-Bt2Ek74z.d.ts +99 -0
- package/dist/UserMetadataContext-B8gVWGMl.d.ts +35 -0
- package/dist/UserMetadataContext-DntmpK41.d.ts +33 -0
- package/dist/auth/context.d.ts +48 -0
- package/dist/auth/context.js +2 -2
- package/dist/auth/guards.d.ts +180 -0
- package/dist/auth/hooks.d.ts +312 -0
- package/dist/auth/hooks.js +3 -3
- package/dist/auth/index.d.ts +11 -0
- package/dist/auth/index.js +3 -3
- package/dist/{chunk-2T6WTCP4.js → chunk-3EVWXMUV.js} +54 -155
- package/dist/chunk-3EVWXMUV.js.map +1 -0
- package/dist/{chunk-YERWPV6B.js → chunk-3FHAKRDV.js} +145 -19
- package/dist/{chunk-YERWPV6B.js.map → chunk-3FHAKRDV.js.map} +1 -1
- package/dist/{chunk-X3HZLNBV.js → chunk-FKRACEHV.js} +2 -962
- package/dist/chunk-FKRACEHV.js.map +1 -0
- package/dist/{chunk-N26IEHZT.js → chunk-FZF26ZRB.js} +18 -2
- package/dist/{chunk-N26IEHZT.js.map → chunk-FZF26ZRB.js.map} +1 -1
- package/dist/chunk-HTJ2FQW5.js +963 -0
- package/dist/chunk-HTJ2FQW5.js.map +1 -0
- package/dist/{chunk-R5B2XMN5.js → chunk-I4BDZDHX.js} +1614 -2141
- package/dist/chunk-I4BDZDHX.js.map +1 -0
- package/dist/{chunk-36DVUMQD.js → chunk-LPC64MD4.js} +2 -2
- package/dist/{chunk-72WV3ALS.js → chunk-OUUQSI3Y.js} +2 -2
- package/dist/{chunk-RMRYGICS.js → chunk-WP6TIVPH.js} +4 -4
- package/dist/client/index.d.ts +16 -0
- package/dist/core/index.d.ts +568 -0
- package/dist/database.types-ChFCG-4M.d.ts +8604 -0
- package/dist/executor-CB4KHyYG.d.ts +507 -0
- package/dist/gen/index.d.ts +1099 -0
- package/dist/hooks/index.d.ts +119 -0
- package/dist/hooks/index.js +1 -1
- package/dist/index-2YySlz7X.d.ts +433 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +14 -95
- package/dist/index.native.d.ts +775 -0
- package/dist/index.native.js +17 -96
- package/dist/index.web.d.ts +438 -0
- package/dist/index.web.js +585 -46
- package/dist/index.web.js.map +1 -1
- package/dist/mutation/index.d.ts +58 -0
- package/dist/parser/index.d.ts +366 -0
- package/dist/powersync-bridge/index.d.ts +284 -0
- package/dist/powersync-bridge/index.js +1 -1
- package/dist/query/index.d.ts +723 -0
- package/dist/query/index.js +10 -8
- package/dist/realtime/index.d.ts +44 -0
- package/dist/select-query-parser-BwyHum1L.d.ts +352 -0
- package/dist/setupAuthContext-Kv-THH-h.d.ts +61 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types-CYr9JiUE.d.ts +62 -0
- package/dist/useBatchUpsert-9OYjibLh.d.ts +24 -0
- package/dist/useDbCount-s-aR9YeV.d.ts +1082 -0
- package/dist/useDbQuery-C-TL8jY1.d.ts +19 -0
- package/dist/useReceiptAI-6HkRpRml.d.ts +58 -0
- package/dist/useResolveFeedback-DTGcHpCs.d.ts +882 -0
- package/dist/useSupabase-DvWVuHHE.d.ts +28 -0
- package/dist/with-auth/index.d.ts +704 -0
- package/dist/with-auth/index.js +4 -4
- package/package.json +50 -1
- package/dist/chunk-2T6WTCP4.js.map +0 -1
- package/dist/chunk-R5B2XMN5.js.map +0 -1
- package/dist/chunk-X3HZLNBV.js.map +0 -1
- /package/dist/{chunk-36DVUMQD.js.map → chunk-LPC64MD4.js.map} +0 -0
- /package/dist/{chunk-72WV3ALS.js.map → chunk-OUUQSI3Y.js.map} +0 -0
- /package/dist/{chunk-RMRYGICS.js.map → chunk-WP6TIVPH.js.map} +0 -0
|
@@ -0,0 +1,1082 @@
|
|
|
1
|
+
import { p as DataLayerContextValue, q as DataLayerCoreContextValue, r as DataLayerStatusContextValue } from './DataLayerContext-ZmLPYR_s.js';
|
|
2
|
+
import { Dispatch, SetStateAction } from 'react';
|
|
3
|
+
import { QueryOptions, WhereClause } from './core/index.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* V3 Data Layer Hooks
|
|
7
|
+
*
|
|
8
|
+
* Provides access to the V3 data layer context for components.
|
|
9
|
+
* This module provides three hooks for different use cases:
|
|
10
|
+
*
|
|
11
|
+
* - useDataLayerCore(): Stable values only (registry, adapters, clients)
|
|
12
|
+
* Use in query/mutation hooks to avoid re-renders on status changes.
|
|
13
|
+
*
|
|
14
|
+
* - useDataLayerStatus(): Dynamic values only (status, syncStatus, syncControl)
|
|
15
|
+
* Use for UI components that display sync status, online indicator, etc.
|
|
16
|
+
*
|
|
17
|
+
* - useDataLayer(): Combined access (backward compatible)
|
|
18
|
+
* Use when you need both core and status values.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Hook to access ONLY the stable core values (registry, adapters, clients)
|
|
23
|
+
*
|
|
24
|
+
* PERFORMANCE BENEFIT: Components using this hook will NOT re-render when
|
|
25
|
+
* network status or sync status changes. Use this in query/mutation hooks.
|
|
26
|
+
*
|
|
27
|
+
* Provides access to:
|
|
28
|
+
* - registry: Adapter registry for getting table adapters
|
|
29
|
+
* - getAdapter: Function to get adapter for a specific table
|
|
30
|
+
* - powerSync: PowerSync database instance (null when not available)
|
|
31
|
+
* - supabase: Supabase client (always available)
|
|
32
|
+
* - queryClient: React Query client
|
|
33
|
+
* - schema: Database schema
|
|
34
|
+
*
|
|
35
|
+
* @throws Error if used outside of DataLayerProvider
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* const { getAdapter, supabase } = useDataLayerCore();
|
|
39
|
+
* const adapter = getAdapter("Task");
|
|
40
|
+
* // This component won't re-render on sync status changes
|
|
41
|
+
*/
|
|
42
|
+
declare function useDataLayerCore(): DataLayerCoreContextValue;
|
|
43
|
+
/**
|
|
44
|
+
* Hook to access ONLY the dynamic status values
|
|
45
|
+
*
|
|
46
|
+
* PERFORMANCE BENEFIT: Only components that actually need status information
|
|
47
|
+
* will re-render when status changes. Use for UI components that display
|
|
48
|
+
* sync status, online indicator, pending uploads count, etc.
|
|
49
|
+
*
|
|
50
|
+
* Provides access to:
|
|
51
|
+
* - status: Current initialization and connection status
|
|
52
|
+
* - syncStatus: Sync status for PowerSync
|
|
53
|
+
* - syncControl: Sync controls for PowerSync
|
|
54
|
+
*
|
|
55
|
+
* @throws Error if used outside of DataLayerProvider
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* const { status, syncStatus } = useDataLayerStatus();
|
|
59
|
+
*
|
|
60
|
+
* return (
|
|
61
|
+
* <StatusBar
|
|
62
|
+
* isOnline={status.isOnline}
|
|
63
|
+
* pendingUploads={syncStatus.pendingUploads}
|
|
64
|
+
* />
|
|
65
|
+
* );
|
|
66
|
+
*/
|
|
67
|
+
declare function useDataLayerStatus(): DataLayerStatusContextValue;
|
|
68
|
+
/**
|
|
69
|
+
* Hook to access the V3 data layer context (combined core + status)
|
|
70
|
+
*
|
|
71
|
+
* NOTE: Consider using useDataLayerCore() or useDataLayerStatus() instead
|
|
72
|
+
* for better render performance. This hook re-renders on ALL status changes.
|
|
73
|
+
*
|
|
74
|
+
* Provides access to:
|
|
75
|
+
* - registry: Adapter registry for getting table adapters
|
|
76
|
+
* - getAdapter: Function to get adapter for a specific table
|
|
77
|
+
* - powerSync: PowerSync database instance (null when not available)
|
|
78
|
+
* - supabase: Supabase client (always available)
|
|
79
|
+
* - queryClient: React Query client
|
|
80
|
+
* - schema: Database schema
|
|
81
|
+
* - status: Current initialization and connection status
|
|
82
|
+
* - syncStatus: Sync status for PowerSync
|
|
83
|
+
* - syncControl: Sync controls for PowerSync
|
|
84
|
+
*
|
|
85
|
+
* @throws Error if used outside of DataLayerProvider
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* const { getAdapter, status } = useDataLayer();
|
|
89
|
+
*
|
|
90
|
+
* if (status.isInitialized) {
|
|
91
|
+
* const adapter = getAdapter("Task");
|
|
92
|
+
* // Use adapter...
|
|
93
|
+
* }
|
|
94
|
+
*/
|
|
95
|
+
declare function useDataLayer(): DataLayerContextValue;
|
|
96
|
+
/**
|
|
97
|
+
* Hook to safely access data layer context (returns null if not in provider)
|
|
98
|
+
*
|
|
99
|
+
* Use this when you need to check if the data layer is available
|
|
100
|
+
* without throwing an error. Useful for conditional rendering or
|
|
101
|
+
* components that may be rendered outside the provider context.
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* const dataLayer = useDataLayerOptional();
|
|
105
|
+
*
|
|
106
|
+
* if (dataLayer) {
|
|
107
|
+
* // Safe to use data layer
|
|
108
|
+
* } else {
|
|
109
|
+
* // Render fallback UI
|
|
110
|
+
* }
|
|
111
|
+
*/
|
|
112
|
+
declare function useDataLayerOptional(): DataLayerContextValue | null;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* V3 useDbQuery Hook
|
|
116
|
+
*
|
|
117
|
+
* React hook for querying multiple records from a table.
|
|
118
|
+
* Works identically whether PowerSync or Supabase is the backend.
|
|
119
|
+
* Uses React Query for state management and caching.
|
|
120
|
+
*
|
|
121
|
+
* Types are automatically inferred from table names when you augment
|
|
122
|
+
* the DatabaseTypes interface with your app's Database type.
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* // In your app's types/db.d.ts:
|
|
126
|
+
* declare module "@pol-studios/db" {
|
|
127
|
+
* interface DatabaseTypes {
|
|
128
|
+
* database: import("@/database.types").Database;
|
|
129
|
+
* }
|
|
130
|
+
* }
|
|
131
|
+
*
|
|
132
|
+
* // Then usage auto-infers types:
|
|
133
|
+
* const { data } = useDbQuery("EquipmentFixtureUnit", { ... });
|
|
134
|
+
* // data is typed as Tables<"EquipmentFixtureUnit">[]
|
|
135
|
+
*/
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Augment this interface in your app to enable automatic type inference.
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* // In types/db.d.ts
|
|
142
|
+
* declare module "@pol-studios/db" {
|
|
143
|
+
* interface DatabaseTypes {
|
|
144
|
+
* database: import("@/database.types").Database;
|
|
145
|
+
* }
|
|
146
|
+
* }
|
|
147
|
+
*/
|
|
148
|
+
interface DatabaseTypes$1 {
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* The configured Database type, or a generic fallback
|
|
152
|
+
*/
|
|
153
|
+
type ConfiguredDatabase$1 = DatabaseTypes$1 extends {
|
|
154
|
+
database: infer DB;
|
|
155
|
+
} ? DB : GenericSchema$1;
|
|
156
|
+
/**
|
|
157
|
+
* Generic schema structure for fallback
|
|
158
|
+
*/
|
|
159
|
+
type GenericSchema$1 = {
|
|
160
|
+
public: {
|
|
161
|
+
Tables: Record<string, {
|
|
162
|
+
Row: Record<string, unknown>;
|
|
163
|
+
}>;
|
|
164
|
+
Views: Record<string, {
|
|
165
|
+
Row: Record<string, unknown>;
|
|
166
|
+
}>;
|
|
167
|
+
};
|
|
168
|
+
[schema: string]: {
|
|
169
|
+
Tables: Record<string, {
|
|
170
|
+
Row: Record<string, unknown>;
|
|
171
|
+
}>;
|
|
172
|
+
Views?: Record<string, {
|
|
173
|
+
Row: Record<string, unknown>;
|
|
174
|
+
}>;
|
|
175
|
+
};
|
|
176
|
+
};
|
|
177
|
+
/**
|
|
178
|
+
* Default schema from Database (usually "public")
|
|
179
|
+
*/
|
|
180
|
+
type DefaultSchema$1 = ConfiguredDatabase$1 extends {
|
|
181
|
+
public: infer S;
|
|
182
|
+
} ? S : never;
|
|
183
|
+
/**
|
|
184
|
+
* Extract all valid table names from the default schema
|
|
185
|
+
*/
|
|
186
|
+
type PublicTableNames$1 = DefaultSchema$1 extends {
|
|
187
|
+
Tables: infer T;
|
|
188
|
+
} ? keyof T & string : string;
|
|
189
|
+
/**
|
|
190
|
+
* Extract all valid schema names
|
|
191
|
+
*/
|
|
192
|
+
type SchemaNames$1 = keyof ConfiguredDatabase$1 & string;
|
|
193
|
+
/**
|
|
194
|
+
* Extract table names for a specific schema
|
|
195
|
+
*/
|
|
196
|
+
type SchemaTableNames$1<S extends string> = ConfiguredDatabase$1 extends {
|
|
197
|
+
[K in S]: {
|
|
198
|
+
Tables: infer T;
|
|
199
|
+
};
|
|
200
|
+
} ? keyof T & string : string;
|
|
201
|
+
/**
|
|
202
|
+
* Build dot notation strings for all schema.table combinations
|
|
203
|
+
*/
|
|
204
|
+
type SchemaDotTable$1 = {
|
|
205
|
+
[S in SchemaNames$1]: S extends "public" ? never : `${S}.${SchemaTableNames$1<S>}`;
|
|
206
|
+
}[SchemaNames$1];
|
|
207
|
+
/**
|
|
208
|
+
* Table identifier - provides autocomplete for valid table names
|
|
209
|
+
*
|
|
210
|
+
* Supports:
|
|
211
|
+
* - "TableName" - public schema tables
|
|
212
|
+
* - "schema.TableName" - dot notation for other schemas
|
|
213
|
+
* - { schema, table } - object format for other schemas
|
|
214
|
+
*/
|
|
215
|
+
type TableIdentifier$1 = PublicTableNames$1 | SchemaDotTable$1 | {
|
|
216
|
+
[S in Exclude<SchemaNames$1, "public">]: {
|
|
217
|
+
schema: S;
|
|
218
|
+
table: SchemaTableNames$1<S>;
|
|
219
|
+
};
|
|
220
|
+
}[Exclude<SchemaNames$1, "public">];
|
|
221
|
+
/**
|
|
222
|
+
* Resolve row type from a table identifier
|
|
223
|
+
*
|
|
224
|
+
* Supports:
|
|
225
|
+
* - "TableName" → public schema
|
|
226
|
+
* - "schema.TableName" → specified schema (dot notation)
|
|
227
|
+
* - { schema: "schema", table: "TableName" } → specified schema (object)
|
|
228
|
+
*/
|
|
229
|
+
type ResolveRowType$1<T extends TableIdentifier$1> = T extends string ? T extends `${infer Schema}.${infer Table}` ? ConfiguredDatabase$1 extends {
|
|
230
|
+
[K in Schema]: {
|
|
231
|
+
Tables: {
|
|
232
|
+
[K2 in Table]: {
|
|
233
|
+
Row: infer R;
|
|
234
|
+
};
|
|
235
|
+
};
|
|
236
|
+
};
|
|
237
|
+
} ? R : Record<string, unknown> : DefaultSchema$1 extends {
|
|
238
|
+
Tables: {
|
|
239
|
+
[K in T]: {
|
|
240
|
+
Row: infer R;
|
|
241
|
+
};
|
|
242
|
+
};
|
|
243
|
+
} ? R : DefaultSchema$1 extends {
|
|
244
|
+
Views: {
|
|
245
|
+
[K in T]: {
|
|
246
|
+
Row: infer R;
|
|
247
|
+
};
|
|
248
|
+
};
|
|
249
|
+
} ? R : Record<string, unknown> : T extends {
|
|
250
|
+
schema: infer S;
|
|
251
|
+
table: infer TN;
|
|
252
|
+
} ? S extends string ? TN extends string ? ConfiguredDatabase$1 extends {
|
|
253
|
+
[K in S]: {
|
|
254
|
+
Tables: {
|
|
255
|
+
[K2 in TN]: {
|
|
256
|
+
Row: infer R;
|
|
257
|
+
};
|
|
258
|
+
};
|
|
259
|
+
};
|
|
260
|
+
} ? R : Record<string, unknown> : Record<string, unknown> : Record<string, unknown> : Record<string, unknown>;
|
|
261
|
+
/**
|
|
262
|
+
* Options for useDbQuery hook
|
|
263
|
+
*/
|
|
264
|
+
interface UseDbQueryOptions extends Omit<QueryOptions, "enabled"> {
|
|
265
|
+
/** Whether the query is enabled (default: true) */
|
|
266
|
+
enabled?: boolean;
|
|
267
|
+
/**
|
|
268
|
+
* React Query stale time in ms
|
|
269
|
+
* Default depends on backend:
|
|
270
|
+
* - PowerSync (offline): 0 - always refetch from SQLite (disk is fast)
|
|
271
|
+
* - Supabase (online): 30000 - use normal caching
|
|
272
|
+
*/
|
|
273
|
+
staleTime?: number;
|
|
274
|
+
/** React Query gcTime (cache time) in ms (default: 300000 - 5 minutes) */
|
|
275
|
+
gcTime?: number;
|
|
276
|
+
/** Whether to refetch on window focus (default: true) */
|
|
277
|
+
refetchOnWindowFocus?: boolean;
|
|
278
|
+
/**
|
|
279
|
+
* Whether to refetch on mount
|
|
280
|
+
* Default depends on backend:
|
|
281
|
+
* - PowerSync (offline): "always" - always query SQLite
|
|
282
|
+
* - Supabase (online): true - refetch if stale
|
|
283
|
+
*/
|
|
284
|
+
refetchOnMount?: boolean | "always";
|
|
285
|
+
/** Whether to enable real-time subscriptions (if adapter supports) */
|
|
286
|
+
realtime?: boolean;
|
|
287
|
+
/** If true, returns single item instead of array (for compatibility with V2) */
|
|
288
|
+
single?: boolean;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Result from useDbQuery hook
|
|
292
|
+
*/
|
|
293
|
+
interface UseDbQueryResult<T> {
|
|
294
|
+
/** Query data */
|
|
295
|
+
data: T[] | undefined;
|
|
296
|
+
/** Whether query is loading (initial load) */
|
|
297
|
+
isLoading: boolean;
|
|
298
|
+
/** Whether query is in pending state */
|
|
299
|
+
isPending: boolean;
|
|
300
|
+
/** Whether query is currently fetching (including refetch) */
|
|
301
|
+
isFetching: boolean;
|
|
302
|
+
/** Whether query is currently refetching (alias for isFetching for V2 compatibility) */
|
|
303
|
+
isRefetching: boolean;
|
|
304
|
+
/** Whether query completed successfully */
|
|
305
|
+
isSuccess: boolean;
|
|
306
|
+
/** Whether query errored */
|
|
307
|
+
isError: boolean;
|
|
308
|
+
/** Query error if any */
|
|
309
|
+
error: Error | null;
|
|
310
|
+
/** Refetch the query */
|
|
311
|
+
refetch: () => Promise<void>;
|
|
312
|
+
/** Total count (if pagination is used) */
|
|
313
|
+
count?: number;
|
|
314
|
+
/** Whether data is stale */
|
|
315
|
+
isStale: boolean;
|
|
316
|
+
/** Timestamp of last data update */
|
|
317
|
+
dataUpdatedAt: number | null;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Hook for querying multiple records from a table
|
|
321
|
+
*
|
|
322
|
+
* This hook provides a unified interface for querying data that works
|
|
323
|
+
* identically whether the backend is PowerSync (offline-first) or
|
|
324
|
+
* Supabase (online-only). It uses React Query for caching and state management.
|
|
325
|
+
*
|
|
326
|
+
* Features:
|
|
327
|
+
* - Automatic type inference from table names (when DatabaseTypes is augmented)
|
|
328
|
+
* - Automatic backend selection based on DataLayerProvider configuration
|
|
329
|
+
* - React Query integration for caching, deduplication, and background updates
|
|
330
|
+
* - Optional real-time subscriptions (when adapter supports it)
|
|
331
|
+
* - Pagination support with count
|
|
332
|
+
*
|
|
333
|
+
* @param table - Table name (string) or { schema, table } object
|
|
334
|
+
* @param options - Query options (select, where, orderBy, limit, offset, etc.)
|
|
335
|
+
* @returns Query result with data, loading states, error, and refetch function
|
|
336
|
+
*
|
|
337
|
+
* @example
|
|
338
|
+
* // Basic query - types auto-inferred from table name
|
|
339
|
+
* const { data } = useDbQuery("EquipmentFixtureUnit");
|
|
340
|
+
* // data is typed as Tables<"EquipmentFixtureUnit">[]
|
|
341
|
+
*
|
|
342
|
+
* @example
|
|
343
|
+
* // Query from non-public schema
|
|
344
|
+
* const { data } = useDbQuery({ schema: "core", table: "Profile" });
|
|
345
|
+
* // data is typed as Tables<{ schema: "core" }, "Profile">[]
|
|
346
|
+
*
|
|
347
|
+
* @example
|
|
348
|
+
* // Query with filters and sorting
|
|
349
|
+
* const { data } = useDbQuery("Task", {
|
|
350
|
+
* select: "*, Project(*)",
|
|
351
|
+
* where: { status: "active" },
|
|
352
|
+
* orderBy: [{ field: "createdAt", direction: "desc" }],
|
|
353
|
+
* limit: 10,
|
|
354
|
+
* });
|
|
355
|
+
*/
|
|
356
|
+
/**
|
|
357
|
+
* Main hook signature with auto-inferred types from table identifiers
|
|
358
|
+
*/
|
|
359
|
+
declare function useDbQuery<T extends TableIdentifier$1>(table: T, options?: UseDbQueryOptions): UseDbQueryResult<ResolveRowType$1<T>>;
|
|
360
|
+
/**
|
|
361
|
+
* Overload for explicit type parameter when table name is a string literal
|
|
362
|
+
*/
|
|
363
|
+
declare function useDbQuery<T>(table: string, options?: UseDbQueryOptions): UseDbQueryResult<T>;
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* V3 useDbQueryById Hook
|
|
367
|
+
*
|
|
368
|
+
* React hook for querying a single record by ID from a table.
|
|
369
|
+
* Works identically whether PowerSync or Supabase is the backend.
|
|
370
|
+
* Uses React Query for state management and caching.
|
|
371
|
+
*/
|
|
372
|
+
/**
|
|
373
|
+
* Options for useDbQueryById hook
|
|
374
|
+
*/
|
|
375
|
+
interface UseDbQueryByIdOptions {
|
|
376
|
+
/** Columns to select (Supabase-style select string) */
|
|
377
|
+
select?: string;
|
|
378
|
+
/** Whether the query is enabled (default: true if id is provided) */
|
|
379
|
+
enabled?: boolean;
|
|
380
|
+
/** React Query stale time in ms (default: 30000) */
|
|
381
|
+
staleTime?: number;
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Result from useDbQueryById hook
|
|
385
|
+
*/
|
|
386
|
+
interface UseDbQueryByIdResult<T> {
|
|
387
|
+
/** Query data (undefined while loading, null if not found) */
|
|
388
|
+
data: T | null | undefined;
|
|
389
|
+
/** Whether query is loading (initial load) */
|
|
390
|
+
isLoading: boolean;
|
|
391
|
+
/** Whether query is in pending state */
|
|
392
|
+
isPending: boolean;
|
|
393
|
+
/** Whether query is currently fetching (including refetch) */
|
|
394
|
+
isFetching: boolean;
|
|
395
|
+
/** Query error if any */
|
|
396
|
+
error: Error | null;
|
|
397
|
+
/** Refetch the query */
|
|
398
|
+
refetch: () => Promise<void>;
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Hook for querying a single record by ID
|
|
402
|
+
*
|
|
403
|
+
* This hook provides a unified interface for fetching a single record that works
|
|
404
|
+
* identically whether the backend is PowerSync (offline-first) or
|
|
405
|
+
* Supabase (online-only). It uses React Query for caching and state management.
|
|
406
|
+
*
|
|
407
|
+
* Features:
|
|
408
|
+
* - Automatic backend selection based on DataLayerProvider configuration
|
|
409
|
+
* - React Query integration for caching, deduplication, and background updates
|
|
410
|
+
* - Automatic disabling when ID is null/undefined
|
|
411
|
+
* - Fallback to query with where clause if adapter doesn't support queryById
|
|
412
|
+
* - Type-safe with generic type parameter
|
|
413
|
+
*
|
|
414
|
+
* @param table - The table name to query
|
|
415
|
+
* @param id - The record ID (query is disabled if null/undefined)
|
|
416
|
+
* @param options - Query options (select, enabled, staleTime)
|
|
417
|
+
* @returns Query result with data, loading states, error, and refetch function
|
|
418
|
+
*
|
|
419
|
+
* @example
|
|
420
|
+
* // Basic query by ID
|
|
421
|
+
* const { data, isLoading, error } = useDbQueryById<Task>("Task", taskId);
|
|
422
|
+
*
|
|
423
|
+
* @example
|
|
424
|
+
* // Query with relations
|
|
425
|
+
* const { data, isLoading, error } = useDbQueryById<Task>("Task", taskId, {
|
|
426
|
+
* select: "*, Project(*), AssignedUser:User(*)",
|
|
427
|
+
* });
|
|
428
|
+
*
|
|
429
|
+
* @example
|
|
430
|
+
* // Conditional query based on other state
|
|
431
|
+
* const { data } = useDbQueryById<Project>("Project", selectedProjectId, {
|
|
432
|
+
* enabled: hasPermission && !!selectedProjectId,
|
|
433
|
+
* });
|
|
434
|
+
*
|
|
435
|
+
* @example
|
|
436
|
+
* // With custom stale time
|
|
437
|
+
* const { data } = useDbQueryById<User>("User", userId, {
|
|
438
|
+
* staleTime: 60000, // 1 minute
|
|
439
|
+
* });
|
|
440
|
+
*/
|
|
441
|
+
declare function useDbQueryById<T = Record<string, unknown>>(table: string, id: string | number | null | undefined, options?: UseDbQueryByIdOptions): UseDbQueryByIdResult<T>;
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* V3 useAdvanceQuery Hook
|
|
445
|
+
*
|
|
446
|
+
* Hybrid query hook that combines PowerSync (local SQLite) with edge function filtering.
|
|
447
|
+
* - When NO filters active: Uses PowerSync for fast local queries that stay in sync
|
|
448
|
+
* - When filters active: Uses edge function for complex filtering
|
|
449
|
+
*
|
|
450
|
+
* This provides the best of both worlds:
|
|
451
|
+
* - Fast, reactive local queries via PowerSync
|
|
452
|
+
* - Complex filtering, natural language queries, and aggregations via edge function
|
|
453
|
+
*
|
|
454
|
+
* @example
|
|
455
|
+
* const [result, filters, setFilters] = useAdvanceQuery<Equipment[]>(
|
|
456
|
+
* "EquipmentFixtureUnit",
|
|
457
|
+
* {
|
|
458
|
+
* select: "*, EquipmentFixtureUnitControl(*)",
|
|
459
|
+
* where: { projectDatabaseId: 123 },
|
|
460
|
+
* orderBy: [{ field: "unitNumber", direction: "asc" }],
|
|
461
|
+
* filterKey: "equipment-filters",
|
|
462
|
+
* }
|
|
463
|
+
* );
|
|
464
|
+
*/
|
|
465
|
+
|
|
466
|
+
type FilterOperator = "=" | ">" | ">=" | "<" | "<=" | "contains" | "ilike" | "is" | "in" | "ai_search";
|
|
467
|
+
interface Filter {
|
|
468
|
+
id: string;
|
|
469
|
+
field: string;
|
|
470
|
+
op: FilterOperator;
|
|
471
|
+
value: string | number | string[] | number[] | boolean | null;
|
|
472
|
+
not?: boolean;
|
|
473
|
+
similarity?: number;
|
|
474
|
+
where?: string;
|
|
475
|
+
display?: string;
|
|
476
|
+
}
|
|
477
|
+
interface FilterGroup {
|
|
478
|
+
id: string;
|
|
479
|
+
op: "AND" | "OR";
|
|
480
|
+
filters: Array<Filter | FilterGroup>;
|
|
481
|
+
not?: boolean;
|
|
482
|
+
}
|
|
483
|
+
interface Pagination {
|
|
484
|
+
offset?: number;
|
|
485
|
+
limit?: number;
|
|
486
|
+
}
|
|
487
|
+
interface Sort {
|
|
488
|
+
field: string;
|
|
489
|
+
direction: "asc" | "desc";
|
|
490
|
+
}
|
|
491
|
+
interface QueryState extends FilterGroup {
|
|
492
|
+
pagination?: Pagination;
|
|
493
|
+
sort?: Sort[];
|
|
494
|
+
distinctOn?: string[];
|
|
495
|
+
naturalLanguageQuery?: string;
|
|
496
|
+
isReady: boolean;
|
|
497
|
+
}
|
|
498
|
+
interface ClarificationQuestion {
|
|
499
|
+
question: string;
|
|
500
|
+
suggestions: Array<{
|
|
501
|
+
interpretation: string;
|
|
502
|
+
field_path: string;
|
|
503
|
+
example: string;
|
|
504
|
+
confidence: number;
|
|
505
|
+
}>;
|
|
506
|
+
}
|
|
507
|
+
interface UseAdvanceQueryOptions extends Omit<UseDbQueryOptions, "realtime"> {
|
|
508
|
+
/** Key for persisting filter state (required for filter state persistence) */
|
|
509
|
+
filterKey: string;
|
|
510
|
+
/** Initial filter state */
|
|
511
|
+
initialFilters?: QueryState;
|
|
512
|
+
/** Timeout for edge function requests in ms (default: 15000) */
|
|
513
|
+
timeout?: number;
|
|
514
|
+
/** Count mode: "exact" | "estimated" | "" (default: "exact") */
|
|
515
|
+
count?: "exact" | "estimated" | "";
|
|
516
|
+
/**
|
|
517
|
+
* Whether to enable real-time subscriptions
|
|
518
|
+
* - PowerSync path: Uses watch() for reactive updates (default: true when PowerSync)
|
|
519
|
+
* - Edge function path: Uses Supabase realtime to invalidate query on changes
|
|
520
|
+
*/
|
|
521
|
+
realtime?: boolean;
|
|
522
|
+
}
|
|
523
|
+
interface UseAdvanceQueryResult<T> {
|
|
524
|
+
data: T[] | undefined;
|
|
525
|
+
isLoading: boolean;
|
|
526
|
+
isPending: boolean;
|
|
527
|
+
isFetching: boolean;
|
|
528
|
+
isRefetching: boolean;
|
|
529
|
+
isSuccess: boolean;
|
|
530
|
+
isError: boolean;
|
|
531
|
+
error: Error | null;
|
|
532
|
+
refetch: () => Promise<void>;
|
|
533
|
+
count?: number;
|
|
534
|
+
clarification?: ClarificationQuestion;
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* Hybrid advance query hook
|
|
538
|
+
*
|
|
539
|
+
* Uses PowerSync (local SQLite) when no filters are active for fast, reactive queries.
|
|
540
|
+
* Falls back to edge function when filters are active for complex filtering.
|
|
541
|
+
*/
|
|
542
|
+
declare function useAdvanceQuery<T extends TableIdentifier$1>(table: T, options: UseAdvanceQueryOptions): [
|
|
543
|
+
UseAdvanceQueryResult<ResolveRowType$1<T>>,
|
|
544
|
+
QueryState,
|
|
545
|
+
Dispatch<SetStateAction<QueryState>>
|
|
546
|
+
];
|
|
547
|
+
declare function useAdvanceQuery<T>(table: string, options: UseAdvanceQueryOptions): [
|
|
548
|
+
UseAdvanceQueryResult<T>,
|
|
549
|
+
QueryState,
|
|
550
|
+
Dispatch<SetStateAction<QueryState>>
|
|
551
|
+
];
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* V3 useDbInsert Hook
|
|
555
|
+
*
|
|
556
|
+
* React hook for inserting records into a table using the V3 adapter pattern.
|
|
557
|
+
* Integrates with React Query for mutation management and cache invalidation.
|
|
558
|
+
*/
|
|
559
|
+
/**
|
|
560
|
+
* Options for useDbInsert hook
|
|
561
|
+
*/
|
|
562
|
+
interface UseDbInsertOptions<T> {
|
|
563
|
+
/** Callback when insert succeeds */
|
|
564
|
+
onSuccess?: (data: T) => void;
|
|
565
|
+
/** Callback when insert fails */
|
|
566
|
+
onError?: (error: Error) => void;
|
|
567
|
+
/** Tables to invalidate after successful insert */
|
|
568
|
+
invalidateTables?: string[];
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Result from useDbInsert hook
|
|
572
|
+
*/
|
|
573
|
+
interface UseDbInsertResult<T> {
|
|
574
|
+
/** Trigger insert (fire and forget) */
|
|
575
|
+
mutate: (data: Partial<T>) => void;
|
|
576
|
+
/** Trigger insert and await result */
|
|
577
|
+
mutateAsync: (data: Partial<T>) => Promise<T>;
|
|
578
|
+
/** Whether mutation is in progress */
|
|
579
|
+
isPending: boolean;
|
|
580
|
+
/** Mutation error if any */
|
|
581
|
+
error: Error | null;
|
|
582
|
+
/** Reset mutation state */
|
|
583
|
+
reset: () => void;
|
|
584
|
+
/** Last successful data */
|
|
585
|
+
data: T | undefined;
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* Hook for inserting records into a table
|
|
589
|
+
*
|
|
590
|
+
* Uses the V3 adapter pattern to route inserts to the appropriate backend
|
|
591
|
+
* (PowerSync, Supabase, or Cached) based on table configuration.
|
|
592
|
+
*
|
|
593
|
+
* @param table - The table name to insert into
|
|
594
|
+
* @param options - Optional configuration for callbacks and cache invalidation
|
|
595
|
+
* @returns Mutation result with mutate/mutateAsync functions
|
|
596
|
+
*
|
|
597
|
+
* @example
|
|
598
|
+
* ```typescript
|
|
599
|
+
* const { mutateAsync, isPending } = useDbInsert<Task>("Task");
|
|
600
|
+
* const newTask = await mutateAsync({ title: "New Task", status: "pending" });
|
|
601
|
+
* ```
|
|
602
|
+
*
|
|
603
|
+
* @example
|
|
604
|
+
* ```typescript
|
|
605
|
+
* // With options
|
|
606
|
+
* const { mutate } = useDbInsert<Project>("Project", {
|
|
607
|
+
* onSuccess: (data) => console.log("Created:", data),
|
|
608
|
+
* onError: (error) => console.error("Failed:", error),
|
|
609
|
+
* invalidateTables: ["Project", "ProjectSummary"],
|
|
610
|
+
* });
|
|
611
|
+
* ```
|
|
612
|
+
*/
|
|
613
|
+
declare function useDbInsert<T = Record<string, unknown>>(table: string, options?: UseDbInsertOptions<T>): UseDbInsertResult<T>;
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* V3 useDbUpdate Hook
|
|
617
|
+
*
|
|
618
|
+
* React hook for updating records in a table using the V3 adapter pattern.
|
|
619
|
+
* Integrates with React Query for mutation management, cache invalidation,
|
|
620
|
+
* and optional optimistic updates.
|
|
621
|
+
*/
|
|
622
|
+
/**
|
|
623
|
+
* Options for useDbUpdate hook
|
|
624
|
+
*/
|
|
625
|
+
interface UseDbUpdateOptions<T> {
|
|
626
|
+
/** Callback when update succeeds */
|
|
627
|
+
onSuccess?: (data: T) => void;
|
|
628
|
+
/** Callback when update fails */
|
|
629
|
+
onError?: (error: Error) => void;
|
|
630
|
+
/** Tables to invalidate after successful update */
|
|
631
|
+
invalidateTables?: string[];
|
|
632
|
+
/** Enable optimistic updates */
|
|
633
|
+
optimistic?: boolean;
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* Result from useDbUpdate hook
|
|
637
|
+
*/
|
|
638
|
+
interface UseDbUpdateResult<T> {
|
|
639
|
+
/** Trigger update (fire and forget) */
|
|
640
|
+
mutate: (params: {
|
|
641
|
+
id: string;
|
|
642
|
+
data: Partial<T>;
|
|
643
|
+
}) => void;
|
|
644
|
+
/** Trigger update and await result */
|
|
645
|
+
mutateAsync: (params: {
|
|
646
|
+
id: string;
|
|
647
|
+
data: Partial<T>;
|
|
648
|
+
}) => Promise<T>;
|
|
649
|
+
/** Whether mutation is in progress */
|
|
650
|
+
isPending: boolean;
|
|
651
|
+
/** Mutation error if any */
|
|
652
|
+
error: Error | null;
|
|
653
|
+
/** Reset mutation state */
|
|
654
|
+
reset: () => void;
|
|
655
|
+
/** Last successful data */
|
|
656
|
+
data: T | undefined;
|
|
657
|
+
}
|
|
658
|
+
/**
|
|
659
|
+
* Hook for updating records in a table
|
|
660
|
+
*
|
|
661
|
+
* Uses the V3 adapter pattern to route updates to the appropriate backend
|
|
662
|
+
* (PowerSync, Supabase, or Cached) based on table configuration.
|
|
663
|
+
*
|
|
664
|
+
* @param table - The table name to update records in
|
|
665
|
+
* @param options - Optional configuration for callbacks, cache invalidation, and optimistic updates
|
|
666
|
+
* @returns Mutation result with mutate/mutateAsync functions
|
|
667
|
+
*
|
|
668
|
+
* @example
|
|
669
|
+
* ```typescript
|
|
670
|
+
* const { mutateAsync, isPending } = useDbUpdate<Task>("Task");
|
|
671
|
+
* const updated = await mutateAsync({ id: taskId, data: { status: "completed" } });
|
|
672
|
+
* ```
|
|
673
|
+
*
|
|
674
|
+
* @example
|
|
675
|
+
* ```typescript
|
|
676
|
+
* // With optimistic updates
|
|
677
|
+
* const { mutate } = useDbUpdate<Project>("Project", {
|
|
678
|
+
* optimistic: true,
|
|
679
|
+
* onSuccess: (data) => console.log("Updated:", data),
|
|
680
|
+
* onError: (error) => console.error("Failed:", error),
|
|
681
|
+
* });
|
|
682
|
+
* ```
|
|
683
|
+
*/
|
|
684
|
+
declare function useDbUpdate<T = Record<string, unknown>>(table: string, options?: UseDbUpdateOptions<T>): UseDbUpdateResult<T>;
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* V3 useDbUpsert Hook
|
|
688
|
+
*
|
|
689
|
+
* React hook for upserting (insert or update) records in a table using the V3 adapter pattern.
|
|
690
|
+
* Integrates with React Query for mutation management and cache invalidation.
|
|
691
|
+
*/
|
|
692
|
+
/**
|
|
693
|
+
* Options for useDbUpsert hook
|
|
694
|
+
*/
|
|
695
|
+
interface UseDbUpsertOptions<T> {
|
|
696
|
+
/** Callback when upsert succeeds */
|
|
697
|
+
onSuccess?: (data: T) => void;
|
|
698
|
+
/** Callback when upsert fails */
|
|
699
|
+
onError?: (error: Error) => void;
|
|
700
|
+
/** Tables to invalidate after successful upsert */
|
|
701
|
+
invalidateTables?: string[];
|
|
702
|
+
}
|
|
703
|
+
/**
|
|
704
|
+
* Result from useDbUpsert hook
|
|
705
|
+
*/
|
|
706
|
+
interface UseDbUpsertResult<T> {
|
|
707
|
+
/** Trigger upsert (fire and forget) */
|
|
708
|
+
mutate: (data: Partial<T>) => void;
|
|
709
|
+
/** Trigger upsert and await result */
|
|
710
|
+
mutateAsync: (data: Partial<T>) => Promise<T>;
|
|
711
|
+
/** Whether mutation is in progress */
|
|
712
|
+
isPending: boolean;
|
|
713
|
+
/** Mutation error if any */
|
|
714
|
+
error: Error | null;
|
|
715
|
+
/** Reset mutation state */
|
|
716
|
+
reset: () => void;
|
|
717
|
+
/** Last successful data */
|
|
718
|
+
data: T | undefined;
|
|
719
|
+
}
|
|
720
|
+
/**
|
|
721
|
+
* Hook for upserting (insert or update) records in a table
|
|
722
|
+
*
|
|
723
|
+
* Uses the V3 adapter pattern to route upserts to the appropriate backend
|
|
724
|
+
* (PowerSync, Supabase, or Cached) based on table configuration.
|
|
725
|
+
*
|
|
726
|
+
* If the record has an ID and exists, it will be updated.
|
|
727
|
+
* Otherwise, a new record will be inserted.
|
|
728
|
+
*
|
|
729
|
+
* @param table - The table name to upsert into
|
|
730
|
+
* @param options - Optional configuration for callbacks and cache invalidation
|
|
731
|
+
* @returns Mutation result with mutate/mutateAsync functions
|
|
732
|
+
*
|
|
733
|
+
* @example
|
|
734
|
+
* ```typescript
|
|
735
|
+
* const { mutateAsync, isPending } = useDbUpsert<Task>("Task");
|
|
736
|
+
* const task = await mutateAsync({ id: existingId, title: "Updated Title" });
|
|
737
|
+
* ```
|
|
738
|
+
*
|
|
739
|
+
* @example
|
|
740
|
+
* ```typescript
|
|
741
|
+
* // Insert if no ID, update if ID exists
|
|
742
|
+
* const { mutate } = useDbUpsert<Setting>("Setting", {
|
|
743
|
+
* onSuccess: (data) => console.log("Upserted:", data),
|
|
744
|
+
* invalidateTables: ["Setting", "UserPreferences"],
|
|
745
|
+
* });
|
|
746
|
+
*
|
|
747
|
+
* // This will insert (no id)
|
|
748
|
+
* mutate({ key: "theme", value: "dark" });
|
|
749
|
+
*
|
|
750
|
+
* // This will update (has id)
|
|
751
|
+
* mutate({ id: "setting-123", key: "theme", value: "light" });
|
|
752
|
+
* ```
|
|
753
|
+
*/
|
|
754
|
+
declare function useDbUpsert<T = Record<string, unknown>>(table: string, options?: UseDbUpsertOptions<T>): UseDbUpsertResult<T>;
|
|
755
|
+
|
|
756
|
+
/**
|
|
757
|
+
* V3 useDbDelete Hook
|
|
758
|
+
*
|
|
759
|
+
* React hook for deleting records from a table using the V3 adapter pattern.
|
|
760
|
+
* Integrates with React Query for mutation management, cache invalidation,
|
|
761
|
+
* and optional optimistic deletes.
|
|
762
|
+
*/
|
|
763
|
+
/**
|
|
764
|
+
* Options for useDbDelete hook
|
|
765
|
+
*/
|
|
766
|
+
interface UseDbDeleteOptions {
|
|
767
|
+
/** Callback when delete succeeds */
|
|
768
|
+
onSuccess?: () => void;
|
|
769
|
+
/** Callback when delete fails */
|
|
770
|
+
onError?: (error: Error) => void;
|
|
771
|
+
/** Tables to invalidate after successful delete */
|
|
772
|
+
invalidateTables?: string[];
|
|
773
|
+
/** Enable optimistic delete */
|
|
774
|
+
optimistic?: boolean;
|
|
775
|
+
}
|
|
776
|
+
/**
|
|
777
|
+
* Result from useDbDelete hook
|
|
778
|
+
*/
|
|
779
|
+
interface UseDbDeleteResult {
|
|
780
|
+
/** Trigger delete (fire and forget) */
|
|
781
|
+
mutate: (id: string) => void;
|
|
782
|
+
/** Trigger delete and await completion */
|
|
783
|
+
mutateAsync: (id: string) => Promise<void>;
|
|
784
|
+
/** Whether mutation is in progress */
|
|
785
|
+
isPending: boolean;
|
|
786
|
+
/** Mutation error if any */
|
|
787
|
+
error: Error | null;
|
|
788
|
+
/** Reset mutation state */
|
|
789
|
+
reset: () => void;
|
|
790
|
+
}
|
|
791
|
+
/**
|
|
792
|
+
* Hook for deleting records from a table
|
|
793
|
+
*
|
|
794
|
+
* Uses the V3 adapter pattern to route deletes to the appropriate backend
|
|
795
|
+
* (PowerSync, Supabase, or Cached) based on table configuration.
|
|
796
|
+
*
|
|
797
|
+
* @param table - The table name to delete from
|
|
798
|
+
* @param options - Optional configuration for callbacks, cache invalidation, and optimistic deletes
|
|
799
|
+
* @returns Mutation result with mutate/mutateAsync functions
|
|
800
|
+
*
|
|
801
|
+
* @example
|
|
802
|
+
* ```typescript
|
|
803
|
+
* const { mutateAsync, isPending } = useDbDelete("Task");
|
|
804
|
+
* await mutateAsync(taskId);
|
|
805
|
+
* ```
|
|
806
|
+
*
|
|
807
|
+
* @example
|
|
808
|
+
* ```typescript
|
|
809
|
+
* // With optimistic delete for instant UI feedback
|
|
810
|
+
* const { mutate } = useDbDelete("Comment", {
|
|
811
|
+
* optimistic: true,
|
|
812
|
+
* onSuccess: () => console.log("Deleted successfully"),
|
|
813
|
+
* onError: (error) => console.error("Delete failed:", error),
|
|
814
|
+
* invalidateTables: ["Comment", "Post"],
|
|
815
|
+
* });
|
|
816
|
+
*
|
|
817
|
+
* // Immediately removes from UI, rolls back on failure
|
|
818
|
+
* mutate(commentId);
|
|
819
|
+
* ```
|
|
820
|
+
*/
|
|
821
|
+
declare function useDbDelete(table: string, options?: UseDbDeleteOptions): UseDbDeleteResult;
|
|
822
|
+
|
|
823
|
+
/**
|
|
824
|
+
* V3 useDbInfiniteQuery Hook
|
|
825
|
+
*
|
|
826
|
+
* React hook for querying records with infinite scroll pagination.
|
|
827
|
+
* Works identically whether PowerSync or Supabase is the backend.
|
|
828
|
+
* Uses React Query's useInfiniteQuery for state management and caching.
|
|
829
|
+
*
|
|
830
|
+
* Types are automatically inferred from table names when you augment
|
|
831
|
+
* the DatabaseTypes interface with your app's Database type.
|
|
832
|
+
*
|
|
833
|
+
* @example
|
|
834
|
+
* // In your app's types/db.d.ts:
|
|
835
|
+
* declare module "@pol-studios/db" {
|
|
836
|
+
* interface DatabaseTypes {
|
|
837
|
+
* database: import("@/database.types").Database;
|
|
838
|
+
* }
|
|
839
|
+
* }
|
|
840
|
+
*
|
|
841
|
+
* // Then usage auto-infers types:
|
|
842
|
+
* const { data, fetchNextPage, hasNextPage } = useDbInfiniteQuery("EquipmentFixtureUnit", {
|
|
843
|
+
* pageSize: 20,
|
|
844
|
+
* orderBy: [{ field: "createdAt", direction: "desc" }],
|
|
845
|
+
* });
|
|
846
|
+
*/
|
|
847
|
+
|
|
848
|
+
/**
|
|
849
|
+
* Augment this interface in your app to enable automatic type inference.
|
|
850
|
+
*/
|
|
851
|
+
interface DatabaseTypes {
|
|
852
|
+
}
|
|
853
|
+
/**
|
|
854
|
+
* The configured Database type, or a generic fallback
|
|
855
|
+
*/
|
|
856
|
+
type ConfiguredDatabase = DatabaseTypes extends {
|
|
857
|
+
database: infer DB;
|
|
858
|
+
} ? DB : GenericSchema;
|
|
859
|
+
/**
|
|
860
|
+
* Generic schema structure for fallback
|
|
861
|
+
*/
|
|
862
|
+
type GenericSchema = {
|
|
863
|
+
public: {
|
|
864
|
+
Tables: Record<string, {
|
|
865
|
+
Row: Record<string, unknown>;
|
|
866
|
+
}>;
|
|
867
|
+
Views: Record<string, {
|
|
868
|
+
Row: Record<string, unknown>;
|
|
869
|
+
}>;
|
|
870
|
+
};
|
|
871
|
+
[schema: string]: {
|
|
872
|
+
Tables: Record<string, {
|
|
873
|
+
Row: Record<string, unknown>;
|
|
874
|
+
}>;
|
|
875
|
+
Views?: Record<string, {
|
|
876
|
+
Row: Record<string, unknown>;
|
|
877
|
+
}>;
|
|
878
|
+
};
|
|
879
|
+
};
|
|
880
|
+
/**
|
|
881
|
+
* Default schema from Database (usually "public")
|
|
882
|
+
*/
|
|
883
|
+
type DefaultSchema = ConfiguredDatabase extends {
|
|
884
|
+
public: infer S;
|
|
885
|
+
} ? S : never;
|
|
886
|
+
/**
|
|
887
|
+
* Extract all valid table names from the default schema
|
|
888
|
+
*/
|
|
889
|
+
type PublicTableNames = DefaultSchema extends {
|
|
890
|
+
Tables: infer T;
|
|
891
|
+
} ? keyof T & string : string;
|
|
892
|
+
/**
|
|
893
|
+
* Extract all valid schema names
|
|
894
|
+
*/
|
|
895
|
+
type SchemaNames = keyof ConfiguredDatabase & string;
|
|
896
|
+
/**
|
|
897
|
+
* Extract table names for a specific schema
|
|
898
|
+
*/
|
|
899
|
+
type SchemaTableNames<S extends string> = ConfiguredDatabase extends {
|
|
900
|
+
[K in S]: {
|
|
901
|
+
Tables: infer T;
|
|
902
|
+
};
|
|
903
|
+
} ? keyof T & string : string;
|
|
904
|
+
/**
|
|
905
|
+
* Build dot notation strings for all schema.table combinations
|
|
906
|
+
*/
|
|
907
|
+
type SchemaDotTable = {
|
|
908
|
+
[S in SchemaNames]: S extends "public" ? never : `${S}.${SchemaTableNames<S>}`;
|
|
909
|
+
}[SchemaNames];
|
|
910
|
+
/**
|
|
911
|
+
* Table identifier - provides autocomplete for valid table names
|
|
912
|
+
*/
|
|
913
|
+
type TableIdentifier = PublicTableNames | SchemaDotTable | {
|
|
914
|
+
[S in Exclude<SchemaNames, "public">]: {
|
|
915
|
+
schema: S;
|
|
916
|
+
table: SchemaTableNames<S>;
|
|
917
|
+
};
|
|
918
|
+
}[Exclude<SchemaNames, "public">];
|
|
919
|
+
/**
|
|
920
|
+
* Resolve row type from a table identifier
|
|
921
|
+
*/
|
|
922
|
+
type ResolveRowType<T extends TableIdentifier> = T extends string ? T extends `${infer Schema}.${infer Table}` ? ConfiguredDatabase extends {
|
|
923
|
+
[K in Schema]: {
|
|
924
|
+
Tables: {
|
|
925
|
+
[K2 in Table]: {
|
|
926
|
+
Row: infer R;
|
|
927
|
+
};
|
|
928
|
+
};
|
|
929
|
+
};
|
|
930
|
+
} ? R : Record<string, unknown> : DefaultSchema extends {
|
|
931
|
+
Tables: {
|
|
932
|
+
[K in T]: {
|
|
933
|
+
Row: infer R;
|
|
934
|
+
};
|
|
935
|
+
};
|
|
936
|
+
} ? R : DefaultSchema extends {
|
|
937
|
+
Views: {
|
|
938
|
+
[K in T]: {
|
|
939
|
+
Row: infer R;
|
|
940
|
+
};
|
|
941
|
+
};
|
|
942
|
+
} ? R : Record<string, unknown> : T extends {
|
|
943
|
+
schema: infer S;
|
|
944
|
+
table: infer TN;
|
|
945
|
+
} ? S extends string ? TN extends string ? ConfiguredDatabase extends {
|
|
946
|
+
[K in S]: {
|
|
947
|
+
Tables: {
|
|
948
|
+
[K2 in TN]: {
|
|
949
|
+
Row: infer R;
|
|
950
|
+
};
|
|
951
|
+
};
|
|
952
|
+
};
|
|
953
|
+
} ? R : Record<string, unknown> : Record<string, unknown> : Record<string, unknown> : Record<string, unknown>;
|
|
954
|
+
/**
|
|
955
|
+
* Options for useDbInfiniteQuery hook
|
|
956
|
+
*/
|
|
957
|
+
interface UseDbInfiniteQueryOptions extends Omit<QueryOptions, "limit" | "offset" | "enabled"> {
|
|
958
|
+
/** Whether the query is enabled (default: true) */
|
|
959
|
+
enabled?: boolean;
|
|
960
|
+
/** React Query stale time in ms (default: 30000) */
|
|
961
|
+
staleTime?: number;
|
|
962
|
+
/** Whether to refetch on window focus (default: true) */
|
|
963
|
+
refetchOnWindowFocus?: boolean;
|
|
964
|
+
/** Number of items per page (default: 50) */
|
|
965
|
+
pageSize?: number;
|
|
966
|
+
/** Text to search for */
|
|
967
|
+
searchText?: string;
|
|
968
|
+
/** Fields to search in when searchText is provided */
|
|
969
|
+
searchFields?: string[];
|
|
970
|
+
}
|
|
971
|
+
/**
|
|
972
|
+
* Result from useDbInfiniteQuery hook
|
|
973
|
+
*/
|
|
974
|
+
interface UseDbInfiniteQueryResult<T> {
|
|
975
|
+
/** Flattened array of all loaded data */
|
|
976
|
+
data: T[] | undefined;
|
|
977
|
+
/** Whether query is loading (initial load) */
|
|
978
|
+
isLoading: boolean;
|
|
979
|
+
/** Whether query is in pending state */
|
|
980
|
+
isPending: boolean;
|
|
981
|
+
/** Whether query is currently fetching (including refetch) */
|
|
982
|
+
isFetching: boolean;
|
|
983
|
+
/** Query error if any */
|
|
984
|
+
error: Error | null;
|
|
985
|
+
/** Function to fetch the next page */
|
|
986
|
+
fetchNextPage: () => Promise<void>;
|
|
987
|
+
/** Whether there are more pages to load */
|
|
988
|
+
hasNextPage: boolean;
|
|
989
|
+
/** Whether currently fetching the next page */
|
|
990
|
+
isFetchingNextPage: boolean;
|
|
991
|
+
/** Total count of items (if available) */
|
|
992
|
+
count?: number;
|
|
993
|
+
/** Refetch all pages */
|
|
994
|
+
refetch: () => Promise<void>;
|
|
995
|
+
}
|
|
996
|
+
/**
|
|
997
|
+
* Hook for querying records with infinite scroll pagination
|
|
998
|
+
*
|
|
999
|
+
* @param table - Table name (string) or { schema, table } object
|
|
1000
|
+
* @param options - Query options (select, where, orderBy, pageSize, searchText, etc.)
|
|
1001
|
+
* @returns Query result with data, loading states, pagination controls, and refetch function
|
|
1002
|
+
*
|
|
1003
|
+
* @example
|
|
1004
|
+
* // Basic infinite query - types auto-inferred from table name
|
|
1005
|
+
* const { data, fetchNextPage, hasNextPage } = useDbInfiniteQuery("EquipmentFixtureUnit");
|
|
1006
|
+
*
|
|
1007
|
+
* @example
|
|
1008
|
+
* // With search and pagination
|
|
1009
|
+
* const { data, fetchNextPage, hasNextPage, isFetchingNextPage } = useDbInfiniteQuery("Task", {
|
|
1010
|
+
* pageSize: 20,
|
|
1011
|
+
* searchText: searchQuery,
|
|
1012
|
+
* searchFields: ["name", "description"],
|
|
1013
|
+
* orderBy: [{ field: "createdAt", direction: "desc" }],
|
|
1014
|
+
* });
|
|
1015
|
+
*
|
|
1016
|
+
* @example
|
|
1017
|
+
* // In a FlatList or similar
|
|
1018
|
+
* <FlatList
|
|
1019
|
+
* data={data}
|
|
1020
|
+
* onEndReached={() => hasNextPage && fetchNextPage()}
|
|
1021
|
+
* ListFooterComponent={isFetchingNextPage ? <Spinner /> : null}
|
|
1022
|
+
* />
|
|
1023
|
+
*/
|
|
1024
|
+
declare function useDbInfiniteQuery<T extends TableIdentifier>(table: T, options?: UseDbInfiniteQueryOptions): UseDbInfiniteQueryResult<ResolveRowType<T>>;
|
|
1025
|
+
/**
|
|
1026
|
+
* Overload for explicit type parameter (backwards compatibility)
|
|
1027
|
+
*/
|
|
1028
|
+
declare function useDbInfiniteQuery<T>(table: string, options?: UseDbInfiniteQueryOptions): UseDbInfiniteQueryResult<T>;
|
|
1029
|
+
|
|
1030
|
+
/**
|
|
1031
|
+
* V3 useDbCount Hook
|
|
1032
|
+
*
|
|
1033
|
+
* React hook for counting records in a table.
|
|
1034
|
+
* Works with the data layer using either PowerSync or Supabase backend.
|
|
1035
|
+
*/
|
|
1036
|
+
|
|
1037
|
+
/**
|
|
1038
|
+
* Options for useDbCount hook
|
|
1039
|
+
*/
|
|
1040
|
+
interface UseDbCountOptions {
|
|
1041
|
+
/** Filter conditions */
|
|
1042
|
+
where?: WhereClause;
|
|
1043
|
+
/** Whether the query is enabled (default: true) */
|
|
1044
|
+
enabled?: boolean;
|
|
1045
|
+
/** React Query stale time in ms (default: 30000) */
|
|
1046
|
+
staleTime?: number;
|
|
1047
|
+
}
|
|
1048
|
+
/**
|
|
1049
|
+
* Result from useDbCount hook
|
|
1050
|
+
*/
|
|
1051
|
+
interface UseDbCountResult {
|
|
1052
|
+
/** The count value */
|
|
1053
|
+
count: number | undefined;
|
|
1054
|
+
/** Whether query is loading */
|
|
1055
|
+
isLoading: boolean;
|
|
1056
|
+
/** Whether query is fetching */
|
|
1057
|
+
isFetching: boolean;
|
|
1058
|
+
/** Query error if any */
|
|
1059
|
+
error: Error | null;
|
|
1060
|
+
/** Refetch the count */
|
|
1061
|
+
refetch: () => Promise<void>;
|
|
1062
|
+
}
|
|
1063
|
+
/**
|
|
1064
|
+
* Hook for counting records in a table
|
|
1065
|
+
*
|
|
1066
|
+
* @param table - The table name to count
|
|
1067
|
+
* @param options - Count options (where filter, enabled)
|
|
1068
|
+
* @returns Count result with loading states
|
|
1069
|
+
*
|
|
1070
|
+
* @example
|
|
1071
|
+
* // Simple count
|
|
1072
|
+
* const { count, isLoading } = useDbCount("EquipmentFixtureUnit");
|
|
1073
|
+
*
|
|
1074
|
+
* @example
|
|
1075
|
+
* // Count with filter
|
|
1076
|
+
* const { count } = useDbCount("EquipmentFixtureUnit", {
|
|
1077
|
+
* where: { projectDatabaseId: 123 },
|
|
1078
|
+
* });
|
|
1079
|
+
*/
|
|
1080
|
+
declare function useDbCount(table: string, options?: UseDbCountOptions): UseDbCountResult;
|
|
1081
|
+
|
|
1082
|
+
export { type Sort as A, type UseDbInsertOptions as B, type ClarificationQuestion as C, type DatabaseTypes$1 as D, type UseDbInsertResult as E, type Filter as F, type UseDbUpdateOptions as G, type UseDbUpdateResult as H, type UseDbUpsertOptions as I, type UseDbUpsertResult as J, type UseDbDeleteOptions as K, type UseDbDeleteResult as L, type PublicTableNames$1 as P, type QueryState as Q, type ResolveRowType$1 as R, type SchemaNames$1 as S, type TableIdentifier$1 as T, type UseAdvanceQueryOptions as U, useDataLayer as a, useDataLayerCore as b, useDataLayerStatus as c, useDbCount as d, useDbDelete as e, useDbInfiniteQuery as f, useDbInsert as g, useDbQuery as h, useDbQueryById as i, useDbUpdate as j, useDbUpsert as k, type SchemaTableNames$1 as l, type UseAdvanceQueryResult as m, type UseDbCountOptions as n, type UseDbCountResult as o, type UseDbInfiniteQueryOptions as p, type UseDbInfiniteQueryResult as q, type UseDbQueryOptions as r, type UseDbQueryResult as s, useDataLayerOptional as t, useAdvanceQuery as u, type UseDbQueryByIdOptions as v, type UseDbQueryByIdResult as w, type FilterGroup as x, type FilterOperator as y, type Pagination as z };
|