@pol-studios/powersync 1.0.6 → 1.0.10
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/README.md +933 -0
- package/dist/CacheSettingsManager-uz-kbnRH.d.ts +461 -0
- package/dist/attachments/index.d.ts +745 -332
- package/dist/attachments/index.js +152 -6
- package/dist/{types-Cd7RhNqf.d.ts → background-sync-ChCXW-EV.d.ts} +53 -2
- package/dist/chunk-24RDMMCL.js +44 -0
- package/dist/chunk-24RDMMCL.js.map +1 -0
- package/dist/chunk-4TXTAEF2.js +2060 -0
- package/dist/chunk-4TXTAEF2.js.map +1 -0
- package/dist/chunk-63PXSPIN.js +358 -0
- package/dist/chunk-63PXSPIN.js.map +1 -0
- package/dist/chunk-654ERHA7.js +1 -0
- package/dist/chunk-A4IBBWGO.js +377 -0
- package/dist/chunk-A4IBBWGO.js.map +1 -0
- package/dist/chunk-BRXQNASY.js +1720 -0
- package/dist/chunk-BRXQNASY.js.map +1 -0
- package/dist/chunk-CAB26E6F.js +142 -0
- package/dist/chunk-CAB26E6F.js.map +1 -0
- package/dist/{chunk-EJ23MXPQ.js → chunk-CGL33PL4.js} +3 -1
- package/dist/chunk-CGL33PL4.js.map +1 -0
- package/dist/{chunk-R4YFWQ3Q.js → chunk-CUCAYK7Z.js} +309 -92
- package/dist/chunk-CUCAYK7Z.js.map +1 -0
- package/dist/chunk-FV2HXEIY.js +124 -0
- package/dist/chunk-FV2HXEIY.js.map +1 -0
- package/dist/chunk-HWSNV45P.js +279 -0
- package/dist/chunk-HWSNV45P.js.map +1 -0
- package/dist/{chunk-62J2DPKX.js → chunk-KN2IZERF.js} +530 -413
- package/dist/chunk-KN2IZERF.js.map +1 -0
- package/dist/{chunk-7EMDVIZX.js → chunk-N75DEF5J.js} +19 -1
- package/dist/chunk-N75DEF5J.js.map +1 -0
- package/dist/chunk-P4HZA6ZT.js +83 -0
- package/dist/chunk-P4HZA6ZT.js.map +1 -0
- package/dist/chunk-P6WOZO7H.js +49 -0
- package/dist/chunk-P6WOZO7H.js.map +1 -0
- package/dist/chunk-T4AO7JIG.js +1 -0
- package/dist/chunk-TGBT5XBE.js +1 -0
- package/dist/{chunk-FPTDATY5.js → chunk-VACPAAQZ.js} +54 -12
- package/dist/chunk-VACPAAQZ.js.map +1 -0
- package/dist/chunk-WGHNIAF7.js +329 -0
- package/dist/chunk-WGHNIAF7.js.map +1 -0
- package/dist/{chunk-3AYXHQ4W.js → chunk-WN5ZJ3E2.js} +108 -47
- package/dist/chunk-WN5ZJ3E2.js.map +1 -0
- package/dist/chunk-XAEII4ZX.js +456 -0
- package/dist/chunk-XAEII4ZX.js.map +1 -0
- package/dist/chunk-XOY2CJ67.js +289 -0
- package/dist/chunk-XOY2CJ67.js.map +1 -0
- package/dist/chunk-YHTZ7VMV.js +1 -0
- package/dist/chunk-YSTEESEG.js +676 -0
- package/dist/chunk-YSTEESEG.js.map +1 -0
- package/dist/chunk-Z6VOBGTU.js +32 -0
- package/dist/chunk-Z6VOBGTU.js.map +1 -0
- package/dist/chunk-ZM4ENYMF.js +230 -0
- package/dist/chunk-ZM4ENYMF.js.map +1 -0
- package/dist/connector/index.d.ts +236 -4
- package/dist/connector/index.js +15 -4
- package/dist/core/index.d.ts +16 -3
- package/dist/core/index.js +6 -2
- package/dist/error/index.d.ts +54 -0
- package/dist/error/index.js +7 -0
- package/dist/error/index.js.map +1 -0
- package/dist/index.d.ts +102 -12
- package/dist/index.js +309 -37
- package/dist/index.native.d.ts +22 -10
- package/dist/index.native.js +309 -38
- package/dist/index.web.d.ts +22 -10
- package/dist/index.web.js +310 -38
- package/dist/maintenance/index.d.ts +118 -0
- package/dist/maintenance/index.js +16 -0
- package/dist/maintenance/index.js.map +1 -0
- package/dist/platform/index.d.ts +16 -1
- package/dist/platform/index.js.map +1 -1
- package/dist/platform/index.native.d.ts +2 -2
- package/dist/platform/index.native.js +1 -1
- package/dist/platform/index.web.d.ts +1 -1
- package/dist/platform/index.web.js +1 -1
- package/dist/pol-attachment-queue-BVAIueoP.d.ts +817 -0
- package/dist/provider/index.d.ts +451 -21
- package/dist/provider/index.js +32 -13
- package/dist/react/index.d.ts +372 -0
- package/dist/react/index.js +25 -0
- package/dist/react/index.js.map +1 -0
- package/dist/storage/index.d.ts +6 -0
- package/dist/storage/index.js +42 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/index.native.d.ts +6 -0
- package/dist/storage/index.native.js +40 -0
- package/dist/storage/index.native.js.map +1 -0
- package/dist/storage/index.web.d.ts +6 -0
- package/dist/storage/index.web.js +40 -0
- package/dist/storage/index.web.js.map +1 -0
- package/dist/storage/upload/index.d.ts +54 -0
- package/dist/storage/upload/index.js +15 -0
- package/dist/storage/upload/index.js.map +1 -0
- package/dist/storage/upload/index.native.d.ts +56 -0
- package/dist/storage/upload/index.native.js +15 -0
- package/dist/storage/upload/index.native.js.map +1 -0
- package/dist/storage/upload/index.web.d.ts +2 -0
- package/dist/storage/upload/index.web.js +14 -0
- package/dist/storage/upload/index.web.js.map +1 -0
- package/dist/supabase-connector-T9vHq_3i.d.ts +202 -0
- package/dist/sync/index.d.ts +288 -23
- package/dist/sync/index.js +22 -10
- package/dist/{index-l3iL9Jte.d.ts → types-B212hgfA.d.ts} +101 -158
- package/dist/{types-afHtE1U_.d.ts → types-CDqWh56B.d.ts} +2 -0
- package/dist/types-CyvBaAl8.d.ts +60 -0
- package/dist/types-D0WcHrq6.d.ts +234 -0
- package/package.json +89 -5
- package/dist/chunk-32OLICZO.js +0 -1
- package/dist/chunk-3AYXHQ4W.js.map +0 -1
- package/dist/chunk-5FIMA26D.js +0 -1
- package/dist/chunk-62J2DPKX.js.map +0 -1
- package/dist/chunk-7EMDVIZX.js.map +0 -1
- package/dist/chunk-EJ23MXPQ.js.map +0 -1
- package/dist/chunk-FPTDATY5.js.map +0 -1
- package/dist/chunk-KCDG2MNP.js +0 -1431
- package/dist/chunk-KCDG2MNP.js.map +0 -1
- package/dist/chunk-OLHGI472.js +0 -1
- package/dist/chunk-PAFBKNL3.js +0 -99
- package/dist/chunk-PAFBKNL3.js.map +0 -1
- package/dist/chunk-R4YFWQ3Q.js.map +0 -1
- package/dist/chunk-V6LJ6MR2.js +0 -740
- package/dist/chunk-V6LJ6MR2.js.map +0 -1
- package/dist/chunk-VJCL2SWD.js +0 -1
- package/dist/failed-upload-store-C0cLxxPz.d.ts +0 -33
- /package/dist/{chunk-32OLICZO.js.map → chunk-654ERHA7.js.map} +0 -0
- /package/dist/{chunk-5FIMA26D.js.map → chunk-T4AO7JIG.js.map} +0 -0
- /package/dist/{chunk-OLHGI472.js.map → chunk-TGBT5XBE.js.map} +0 -0
- /package/dist/{chunk-VJCL2SWD.js.map → chunk-YHTZ7VMV.js.map} +0 -0
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { SupabaseClient } from '@supabase/supabase-js';
|
|
2
|
-
import { C as CrudEntry, i as ClassifiedError
|
|
2
|
+
import { C as CrudEntry, i as ClassifiedError } from './types-CDqWh56B.js';
|
|
3
3
|
import { LoggerAdapter } from './platform/index.js';
|
|
4
|
-
import { F as FailedUpload } from './failed-upload-store-C0cLxxPz.js';
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* Conflict Types for @pol-studios/powersync
|
|
@@ -86,10 +85,13 @@ type ResolutionListener = (table: string, recordId: string, resolution: Conflict
|
|
|
86
85
|
* 4. Connector subscribes via bus.onResolution() -> triggers re-upload
|
|
87
86
|
*/
|
|
88
87
|
declare class ConflictBus {
|
|
88
|
+
private static MAX_PENDING;
|
|
89
89
|
private conflictListeners;
|
|
90
90
|
private resolutionListeners;
|
|
91
|
+
private pendingConflicts;
|
|
91
92
|
/**
|
|
92
93
|
* Subscribe to conflict detection events.
|
|
94
|
+
* Flushes any pending conflicts to ALL listeners (including the new one).
|
|
93
95
|
* @returns Unsubscribe function
|
|
94
96
|
*/
|
|
95
97
|
onConflict(listener: ConflictListener): () => void;
|
|
@@ -100,6 +102,7 @@ declare class ConflictBus {
|
|
|
100
102
|
onResolution(listener: ResolutionListener): () => void;
|
|
101
103
|
/**
|
|
102
104
|
* Emit a conflict detection event (called by connector).
|
|
105
|
+
* If no listeners are subscribed, queues the conflict for later delivery.
|
|
103
106
|
*/
|
|
104
107
|
emitConflict(conflict: ConflictCheckResult): void;
|
|
105
108
|
/**
|
|
@@ -107,9 +110,13 @@ declare class ConflictBus {
|
|
|
107
110
|
*/
|
|
108
111
|
emitResolution(table: string, recordId: string, resolution: ConflictResolution): void;
|
|
109
112
|
/**
|
|
110
|
-
* Clear all listeners (for cleanup).
|
|
113
|
+
* Clear all listeners and pending conflicts (for cleanup).
|
|
111
114
|
*/
|
|
112
115
|
destroy(): void;
|
|
116
|
+
/**
|
|
117
|
+
* Get the number of pending conflicts (useful for debugging/testing).
|
|
118
|
+
*/
|
|
119
|
+
get pendingCount(): number;
|
|
113
120
|
}
|
|
114
121
|
|
|
115
122
|
/**
|
|
@@ -118,6 +125,37 @@ declare class ConflictBus {
|
|
|
118
125
|
* Defines interfaces for PowerSync backend connectors.
|
|
119
126
|
*/
|
|
120
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Circuit breaker configuration for the connector.
|
|
130
|
+
* Prevents cascading failures by stopping requests when service is down.
|
|
131
|
+
*/
|
|
132
|
+
interface ConnectorCircuitBreakerConfig {
|
|
133
|
+
/**
|
|
134
|
+
* Enable circuit breaker pattern.
|
|
135
|
+
* @default false
|
|
136
|
+
*/
|
|
137
|
+
enabled: boolean;
|
|
138
|
+
/**
|
|
139
|
+
* Number of failures required to trip the circuit.
|
|
140
|
+
* @default 5
|
|
141
|
+
*/
|
|
142
|
+
failureThreshold?: number;
|
|
143
|
+
/**
|
|
144
|
+
* Time window in ms for counting failures.
|
|
145
|
+
* @default 60000 (60 seconds)
|
|
146
|
+
*/
|
|
147
|
+
failureWindowMs?: number;
|
|
148
|
+
/**
|
|
149
|
+
* Initial delay before transitioning from OPEN to HALF_OPEN.
|
|
150
|
+
* @default 1000 (1 second)
|
|
151
|
+
*/
|
|
152
|
+
initialRecoveryDelayMs?: number;
|
|
153
|
+
/**
|
|
154
|
+
* Maximum delay for exponential backoff.
|
|
155
|
+
* @default 32000 (32 seconds)
|
|
156
|
+
*/
|
|
157
|
+
maxRecoveryDelayMs?: number;
|
|
158
|
+
}
|
|
121
159
|
/**
|
|
122
160
|
* Options for creating a SupabaseConnector
|
|
123
161
|
*/
|
|
@@ -168,6 +206,13 @@ interface SupabaseConnectorOptions {
|
|
|
168
206
|
* @default DEFAULT_RETRY_CONFIG
|
|
169
207
|
*/
|
|
170
208
|
retryConfig?: Partial<RetryConfig>;
|
|
209
|
+
/**
|
|
210
|
+
* Optional: Configuration for circuit breaker pattern.
|
|
211
|
+
* When enabled, prevents cascading failures by stopping requests when
|
|
212
|
+
* the service is experiencing high failure rates.
|
|
213
|
+
* @default { enabled: false }
|
|
214
|
+
*/
|
|
215
|
+
circuitBreaker?: ConnectorCircuitBreakerConfig;
|
|
171
216
|
}
|
|
172
217
|
/**
|
|
173
218
|
* Configuration passed to PowerSyncProvider for connector setup
|
|
@@ -279,182 +324,80 @@ interface RetryStrategyConfig {
|
|
|
279
324
|
interface RetryConfig {
|
|
280
325
|
/** Retry config for transient errors (network, server 5xx) */
|
|
281
326
|
transient: RetryStrategyConfig;
|
|
282
|
-
/** Retry config for permanent errors (
|
|
327
|
+
/** Retry config for permanent errors (validation, constraints) */
|
|
283
328
|
permanent: RetryStrategyConfig;
|
|
329
|
+
/** Retry config for RLS/permission errors (42501, row-level security violations) */
|
|
330
|
+
rls: RetryStrategyConfig;
|
|
284
331
|
}
|
|
285
332
|
/**
|
|
286
333
|
* Default retry configuration
|
|
334
|
+
*
|
|
335
|
+
* Uses fast exponential backoff for transient errors (network issues):
|
|
336
|
+
* - Transient: 1s → 2s → 4s
|
|
337
|
+
*
|
|
338
|
+
* RLS/permission errors (42501, row-level security violations) use extended delays
|
|
339
|
+
* because parent data may need time to sync before child records can be inserted.
|
|
340
|
+
* - RLS: 30s → 60s → 120s → 120s → 120s (5 retries over ~7.5 minutes)
|
|
341
|
+
*
|
|
342
|
+
* Other permanent errors (validation, constraints) get NO retries
|
|
343
|
+
* because they will never succeed - fail fast and surface to user.
|
|
344
|
+
* PowerSync's native retry mechanism will re-attempt on next sync cycle.
|
|
287
345
|
*/
|
|
288
346
|
declare const DEFAULT_RETRY_CONFIG: RetryConfig;
|
|
289
|
-
|
|
290
347
|
/**
|
|
291
|
-
*
|
|
292
|
-
*
|
|
293
|
-
* A generic, configurable connector that handles:
|
|
294
|
-
* - Authentication with Supabase JWT tokens
|
|
295
|
-
* - Uploading local changes back to Supabase
|
|
296
|
-
* - Schema routing for multi-schema databases
|
|
297
|
-
* - Custom CRUD handling for complex operations
|
|
298
|
-
* - Version-based conflict detection (when enabled)
|
|
348
|
+
* Session representation for authentication.
|
|
349
|
+
* Used by AuthProvider to communicate auth state.
|
|
299
350
|
*/
|
|
300
|
-
|
|
351
|
+
interface Session {
|
|
352
|
+
/** Access token for API requests */
|
|
353
|
+
accessToken: string;
|
|
354
|
+
/** When the token expires (optional) */
|
|
355
|
+
expiresAt?: Date;
|
|
356
|
+
/** User information (optional) */
|
|
357
|
+
user?: {
|
|
358
|
+
id: string;
|
|
359
|
+
};
|
|
360
|
+
}
|
|
301
361
|
/**
|
|
302
|
-
*
|
|
303
|
-
*
|
|
304
|
-
* This connector handles authentication and CRUD uploads to Supabase.
|
|
305
|
-
* It supports configurable schema routing and custom CRUD handlers
|
|
306
|
-
* for complex use cases.
|
|
362
|
+
* Authentication provider interface.
|
|
363
|
+
* Abstracts auth for the connector - works with any auth backend.
|
|
307
364
|
*
|
|
308
|
-
* @example
|
|
365
|
+
* @example
|
|
309
366
|
* ```typescript
|
|
310
|
-
*
|
|
311
|
-
*
|
|
312
|
-
* powerSyncUrl: 'https://your-powersync-instance.com',
|
|
313
|
-
* });
|
|
314
|
-
* ```
|
|
367
|
+
* // Using built-in Supabase adapter
|
|
368
|
+
* const auth = createSupabaseAuth(supabaseClient);
|
|
315
369
|
*
|
|
316
|
-
*
|
|
317
|
-
*
|
|
318
|
-
*
|
|
319
|
-
*
|
|
320
|
-
*
|
|
321
|
-
*
|
|
322
|
-
* if (['Profile', 'Comment', 'CommentSection'].includes(table)) {
|
|
323
|
-
* return 'core';
|
|
324
|
-
* }
|
|
325
|
-
* return 'public';
|
|
370
|
+
* // Custom implementation
|
|
371
|
+
* const auth: AuthProvider = {
|
|
372
|
+
* getSession: async () => ({ accessToken: myToken }),
|
|
373
|
+
* refreshSession: async () => {
|
|
374
|
+
* const newToken = await myAuthService.refresh();
|
|
375
|
+
* return { accessToken: newToken };
|
|
326
376
|
* },
|
|
327
|
-
*
|
|
328
|
-
*
|
|
329
|
-
*
|
|
330
|
-
* @example With custom CRUD handler
|
|
331
|
-
* ```typescript
|
|
332
|
-
* const connector = new SupabaseConnector({
|
|
333
|
-
* supabaseClient: supabase,
|
|
334
|
-
* powerSyncUrl: 'https://your-powersync-instance.com',
|
|
335
|
-
* crudHandler: {
|
|
336
|
-
* async handlePut(entry, supabase, schema) {
|
|
337
|
-
* // Custom handling for specific tables
|
|
338
|
-
* if (entry.table === 'SpecialTable') {
|
|
339
|
-
* await myCustomUpsert(entry);
|
|
340
|
-
* return true; // Handled
|
|
341
|
-
* }
|
|
342
|
-
* return false; // Use default
|
|
343
|
-
* },
|
|
377
|
+
* onAuthStateChange: (cb) => {
|
|
378
|
+
* return myAuthService.subscribe(cb);
|
|
344
379
|
* },
|
|
345
|
-
* }
|
|
380
|
+
* };
|
|
346
381
|
* ```
|
|
347
382
|
*/
|
|
348
|
-
|
|
349
|
-
private readonly supabase;
|
|
350
|
-
private readonly powerSyncUrl;
|
|
351
|
-
private readonly schemaRouter;
|
|
352
|
-
private readonly crudHandler?;
|
|
353
|
-
private readonly logger?;
|
|
354
|
-
private readonly onTransactionSuccess?;
|
|
355
|
-
private readonly onTransactionFailure?;
|
|
356
|
-
private readonly onTransactionComplete?;
|
|
357
|
-
private readonly shouldUploadFn?;
|
|
358
|
-
private readonly conflictDetection?;
|
|
359
|
-
private readonly conflictHandler?;
|
|
360
|
-
private readonly conflictBus?;
|
|
361
|
-
private versionColumnCache;
|
|
362
|
-
private activeProjectIds;
|
|
363
|
-
private resolvedConflicts;
|
|
364
|
-
private unsubscribeResolution?;
|
|
365
|
-
private retryConfig;
|
|
366
|
-
private autoRetryPaused;
|
|
367
|
-
constructor(options: SupabaseConnectorOptions);
|
|
383
|
+
interface AuthProvider {
|
|
368
384
|
/**
|
|
369
|
-
*
|
|
370
|
-
*
|
|
385
|
+
* Get the current session.
|
|
386
|
+
* @returns Current session or null if not authenticated
|
|
371
387
|
*/
|
|
372
|
-
|
|
388
|
+
getSession(): Promise<Session | null>;
|
|
373
389
|
/**
|
|
374
|
-
*
|
|
375
|
-
*
|
|
390
|
+
* Refresh the current session.
|
|
391
|
+
* @throws Error if refresh fails (e.g., refresh token expired)
|
|
392
|
+
* @returns New session with fresh access token
|
|
376
393
|
*/
|
|
377
|
-
|
|
394
|
+
refreshSession(): Promise<Session>;
|
|
378
395
|
/**
|
|
379
|
-
*
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
/**
|
|
383
|
-
* Manually retry all failed uploads that are ready for retry.
|
|
384
|
-
* This processes entries from the failed upload store.
|
|
385
|
-
*/
|
|
386
|
-
retryFailedUploads(): Promise<void>;
|
|
387
|
-
/**
|
|
388
|
-
* Clear all failed uploads from the store.
|
|
389
|
-
* Use with caution - this discards all pending retries.
|
|
390
|
-
*/
|
|
391
|
-
clearFailedUploads(): void;
|
|
392
|
-
/**
|
|
393
|
-
* Get all failed uploads from the store.
|
|
394
|
-
*/
|
|
395
|
-
getFailedUploads(): FailedUpload[];
|
|
396
|
-
/**
|
|
397
|
-
* Process a single CRUD entry with exponential backoff retry.
|
|
398
|
-
*
|
|
399
|
-
* @param entry - The CRUD entry to process
|
|
400
|
-
* @throws Error if all retries exhausted (for critical failures)
|
|
401
|
-
*/
|
|
402
|
-
private processWithRetry;
|
|
403
|
-
/**
|
|
404
|
-
* Set the active project IDs for scoped sync.
|
|
405
|
-
* Call this when user selects/opens projects.
|
|
406
|
-
*/
|
|
407
|
-
setActiveProjectIds(projectIds: string[]): void;
|
|
408
|
-
/**
|
|
409
|
-
* Get the current active project IDs.
|
|
410
|
-
*/
|
|
411
|
-
getActiveProjectIds(): string[];
|
|
412
|
-
/**
|
|
413
|
-
* Get credentials for PowerSync connection.
|
|
414
|
-
* Uses Supabase session token.
|
|
415
|
-
*
|
|
416
|
-
* Note: Token refresh is handled by Supabase's startAutoRefresh() which must be
|
|
417
|
-
* called on app initialization. getSession() returns the auto-refreshed token.
|
|
418
|
-
*/
|
|
419
|
-
fetchCredentials(): Promise<PowerSyncCredentials>;
|
|
420
|
-
/**
|
|
421
|
-
* Upload local changes to Supabase.
|
|
422
|
-
* Called automatically by PowerSync when there are pending uploads.
|
|
423
|
-
*
|
|
424
|
-
* When conflict detection is enabled:
|
|
425
|
-
* 1. Checks if table has _version column (cached)
|
|
426
|
-
* 2. If yes, compares local vs server version
|
|
427
|
-
* 3. On version mismatch, queries AuditLog for field conflicts
|
|
428
|
-
* 4. If conflicts found, calls handler or publishes to conflict bus
|
|
429
|
-
* 5. Applies resolution or skips entry based on handler response
|
|
430
|
-
*/
|
|
431
|
-
uploadData(database: AbstractPowerSyncDatabase): Promise<void>;
|
|
432
|
-
/**
|
|
433
|
-
* Process a transaction without conflict detection.
|
|
434
|
-
* Used when conflict detection is disabled.
|
|
435
|
-
*/
|
|
436
|
-
private processTransaction;
|
|
437
|
-
/**
|
|
438
|
-
* Check if a table has a _version column (cached).
|
|
439
|
-
*/
|
|
440
|
-
private checkVersionColumn;
|
|
441
|
-
/**
|
|
442
|
-
* Filter opData to only include specified fields.
|
|
443
|
-
* Used for partial sync resolution.
|
|
444
|
-
*/
|
|
445
|
-
private filterFields;
|
|
446
|
-
/**
|
|
447
|
-
* Process a single CRUD operation.
|
|
448
|
-
*
|
|
449
|
-
* UUID-native tables (public schema, post-migration) use `id` as the UUID column.
|
|
450
|
-
* Core schema tables (Profile, Comment, CommentSection) still use a separate `uuid` column.
|
|
451
|
-
*/
|
|
452
|
-
/**
|
|
453
|
-
* Process a single CRUD operation.
|
|
454
|
-
*
|
|
455
|
-
* All synced tables use `id` as their UUID primary key column.
|
|
396
|
+
* Subscribe to auth state changes.
|
|
397
|
+
* @param cb - Callback fired when auth state changes
|
|
398
|
+
* @returns Unsubscribe function
|
|
456
399
|
*/
|
|
457
|
-
|
|
400
|
+
onAuthStateChange(cb: (session: Session | null) => void): () => void;
|
|
458
401
|
}
|
|
459
402
|
|
|
460
|
-
export { type
|
|
403
|
+
export { type AuthProvider as A, type ConnectorCircuitBreakerConfig as C, DEFAULT_RETRY_CONFIG as D, type FieldConflict as F, type PowerSyncCredentials as P, type RetryStrategyConfig as R, type SupabaseConnectorOptions as S, type ConnectorConfig as a, type SchemaRouter as b, type CrudHandler as c, defaultSchemaRouter as d, type RetryConfig as e, type Session as f, ConflictBus as g, type ConflictCheckResult as h, type ConflictResolution as i, type ConflictHandler as j, type ConflictDetectionConfig as k, type ConflictListener as l, type ResolutionListener as m };
|
|
@@ -39,6 +39,8 @@ interface CrudEntry {
|
|
|
39
39
|
opData?: Record<string, unknown>;
|
|
40
40
|
/** Transaction ID for grouping operations */
|
|
41
41
|
transactionId?: number;
|
|
42
|
+
/** When this mutation was created (for display purposes) */
|
|
43
|
+
createdAt?: Date;
|
|
42
44
|
}
|
|
43
45
|
/**
|
|
44
46
|
* Download progress information during sync
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Upload Handler Types for @pol-studios/powersync
|
|
3
|
+
*
|
|
4
|
+
* Defines types for platform-specific upload handlers.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Bucket configuration for multi-bucket routing.
|
|
8
|
+
*/
|
|
9
|
+
interface BucketConfig {
|
|
10
|
+
/** Default bucket for storage operations */
|
|
11
|
+
defaultBucket: string;
|
|
12
|
+
/** Map of path prefixes to bucket names */
|
|
13
|
+
bucketMap?: Map<string, string>;
|
|
14
|
+
/** Custom bucket resolver function */
|
|
15
|
+
resolver?: (storagePath: string) => string | undefined;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Options for creating a SupabaseUploadHandler.
|
|
19
|
+
*/
|
|
20
|
+
interface SupabaseUploadHandlerOptions {
|
|
21
|
+
/** Supabase client instance */
|
|
22
|
+
supabaseClient: any;
|
|
23
|
+
/** Bucket configuration for multi-bucket routing */
|
|
24
|
+
bucketConfig: BucketConfig;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Event handlers for upload progress tracking.
|
|
28
|
+
*/
|
|
29
|
+
interface UploadEventHandlers {
|
|
30
|
+
/** Called with progress updates during upload */
|
|
31
|
+
onProgress?: (progress: {
|
|
32
|
+
loaded: number;
|
|
33
|
+
total: number;
|
|
34
|
+
}) => void;
|
|
35
|
+
/** Called when upload completes successfully */
|
|
36
|
+
onComplete?: () => void;
|
|
37
|
+
/** Called when upload fails */
|
|
38
|
+
onError?: (error: Error) => void;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Configuration for native upload notifications (Android).
|
|
42
|
+
*/
|
|
43
|
+
interface UploadNotificationConfig {
|
|
44
|
+
/** Whether to show upload notifications */
|
|
45
|
+
enabled: boolean;
|
|
46
|
+
/** Whether to auto-clear notification on completion */
|
|
47
|
+
autoClear: boolean;
|
|
48
|
+
/** Title shown during upload progress */
|
|
49
|
+
onProgressTitle: string;
|
|
50
|
+
/** Title shown when upload completes */
|
|
51
|
+
onCompleteTitle: string;
|
|
52
|
+
/** Title shown when upload fails */
|
|
53
|
+
onErrorTitle: string;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Default notification configuration for Android uploads.
|
|
57
|
+
*/
|
|
58
|
+
declare const DEFAULT_UPLOAD_NOTIFICATION: UploadNotificationConfig;
|
|
59
|
+
|
|
60
|
+
export { type BucketConfig as B, DEFAULT_UPLOAD_NOTIFICATION as D, type SupabaseUploadHandlerOptions as S, type UploadEventHandlers as U, type UploadNotificationConfig as a };
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { FileSystemAdapter, LoggerAdapter } from './platform/index.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Unified Storage Types for @pol-studios/powersync
|
|
5
|
+
*
|
|
6
|
+
* Single storage interface for all Supabase storage operations.
|
|
7
|
+
* Consolidates the previous 6 fragmented interfaces into one:
|
|
8
|
+
* - AttachmentStorageAdapter (attachments/types.ts)
|
|
9
|
+
* - RemoteStorageAdapter (storage/types.ts - removed)
|
|
10
|
+
* - StorageAdapter (@powersync/attachments)
|
|
11
|
+
* - PowerSyncStorageAdapter (storage/types.ts - removed)
|
|
12
|
+
* - StorageUploadHandler (storage/types.ts - removed)
|
|
13
|
+
* - UploadHandler (attachments/types.ts)
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Unified storage interface for Supabase storage operations.
|
|
17
|
+
* Handles both upload and download for attachments.
|
|
18
|
+
*
|
|
19
|
+
* This is the ONLY storage interface consumers need to implement.
|
|
20
|
+
* It replaces all previous storage adapter interfaces.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* const storage: SupabaseStorage = {
|
|
25
|
+
* async download(path) {
|
|
26
|
+
* const { data } = await supabase.storage
|
|
27
|
+
* .from('attachments')
|
|
28
|
+
* .createSignedUrl(path, 60);
|
|
29
|
+
* // Download to temp file and return URI
|
|
30
|
+
* return tempFileUri;
|
|
31
|
+
* },
|
|
32
|
+
*
|
|
33
|
+
* async upload(path, localUri, mediaType) {
|
|
34
|
+
* const file = await readFile(localUri);
|
|
35
|
+
* await supabase.storage
|
|
36
|
+
* .from('attachments')
|
|
37
|
+
* .upload(path, file, { contentType: mediaType });
|
|
38
|
+
* },
|
|
39
|
+
* };
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
interface SupabaseStorage {
|
|
43
|
+
/**
|
|
44
|
+
* Download a file and return the local file:// URI.
|
|
45
|
+
*
|
|
46
|
+
* @param path - Remote storage path
|
|
47
|
+
* @returns Local file:// URI pointing to the downloaded file
|
|
48
|
+
*/
|
|
49
|
+
download(path: string): Promise<string>;
|
|
50
|
+
/**
|
|
51
|
+
* Upload a local file to remote storage.
|
|
52
|
+
*
|
|
53
|
+
* @param path - Remote storage path
|
|
54
|
+
* @param localUri - Local file:// URI to upload from
|
|
55
|
+
* @param mediaType - MIME type of the file
|
|
56
|
+
* @param signal - Optional AbortSignal for cancellation
|
|
57
|
+
*/
|
|
58
|
+
upload(path: string, localUri: string, mediaType: string, signal?: AbortSignal): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Delete a file from remote storage.
|
|
61
|
+
* Optional - not all implementations need deletion.
|
|
62
|
+
*
|
|
63
|
+
* @param path - Remote storage path to delete
|
|
64
|
+
*/
|
|
65
|
+
delete?(path: string): Promise<void>;
|
|
66
|
+
/**
|
|
67
|
+
* Resolve which bucket a path belongs to.
|
|
68
|
+
* Optional - useful for multi-bucket configurations.
|
|
69
|
+
*
|
|
70
|
+
* @param path - Remote storage path
|
|
71
|
+
* @returns The bucket name
|
|
72
|
+
*/
|
|
73
|
+
resolveBucket?(path: string): string;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Download result discriminated union.
|
|
77
|
+
* Native platforms return file URIs, web returns blobs.
|
|
78
|
+
*/
|
|
79
|
+
type DownloadResult = {
|
|
80
|
+
type: 'file';
|
|
81
|
+
uri: string;
|
|
82
|
+
} | {
|
|
83
|
+
type: 'blob';
|
|
84
|
+
data: Blob;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Storage backend returned by createSupabaseStorage factory.
|
|
88
|
+
* This is a more flexible interface that returns discriminated unions
|
|
89
|
+
* to handle both native (file URI) and web (blob) download results.
|
|
90
|
+
*
|
|
91
|
+
* For simpler use cases, use SupabaseStorage interface directly.
|
|
92
|
+
*/
|
|
93
|
+
interface StorageBackend {
|
|
94
|
+
/** Download a file, returns discriminated union based on platform */
|
|
95
|
+
download(path: string): Promise<DownloadResult>;
|
|
96
|
+
/** Upload a local file to remote storage */
|
|
97
|
+
upload(path: string, localUri: string, contentType: string, options?: StorageUploadOptions): Promise<void>;
|
|
98
|
+
/** Delete a file from remote storage */
|
|
99
|
+
delete(path: string): Promise<void>;
|
|
100
|
+
/** Resolve which bucket a path belongs to */
|
|
101
|
+
resolveBucket(path: string): string;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Progress information for upload operations.
|
|
105
|
+
*/
|
|
106
|
+
interface UploadProgress {
|
|
107
|
+
/** Bytes uploaded so far */
|
|
108
|
+
loaded: number;
|
|
109
|
+
/** Total bytes to upload */
|
|
110
|
+
total: number;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Options for upload operations.
|
|
114
|
+
*/
|
|
115
|
+
interface StorageUploadOptions {
|
|
116
|
+
/** AbortSignal for cancellation support */
|
|
117
|
+
signal?: AbortSignal;
|
|
118
|
+
/** Progress callback */
|
|
119
|
+
onProgress?: (progress: UploadProgress) => void;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Options for creating a Supabase storage backend.
|
|
124
|
+
*/
|
|
125
|
+
interface SupabaseStorageOptions {
|
|
126
|
+
/** Supabase client instance */
|
|
127
|
+
client: SupabaseClient;
|
|
128
|
+
/** Default storage bucket */
|
|
129
|
+
defaultBucket: string;
|
|
130
|
+
/**
|
|
131
|
+
* Map of path prefixes to bucket names.
|
|
132
|
+
* Checked in iteration order (use Map to preserve order).
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```typescript
|
|
136
|
+
* bucketMap: new Map([
|
|
137
|
+
* ['avatars/', 'user-avatars'],
|
|
138
|
+
* ['docs/', 'documents'],
|
|
139
|
+
* ])
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
bucketMap?: Map<string, string>;
|
|
143
|
+
/**
|
|
144
|
+
* Custom bucket resolver function.
|
|
145
|
+
* Takes precedence over bucketMap.
|
|
146
|
+
* Return undefined to fall through to bucketMap/defaultBucket.
|
|
147
|
+
*/
|
|
148
|
+
bucketResolver?: (storagePath: string) => string | undefined;
|
|
149
|
+
/**
|
|
150
|
+
* Signed URL expiry in seconds.
|
|
151
|
+
* @default 60 (short-lived for security)
|
|
152
|
+
*/
|
|
153
|
+
signedUrlExpiry?: number;
|
|
154
|
+
/**
|
|
155
|
+
* File system adapter for native file operations.
|
|
156
|
+
* Required for native platforms to enable file-based downloads.
|
|
157
|
+
*/
|
|
158
|
+
fileSystem?: FileSystemAdapter;
|
|
159
|
+
/**
|
|
160
|
+
* Optional logger for diagnostic messages.
|
|
161
|
+
*/
|
|
162
|
+
logger?: LoggerAdapter;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Transform options for Supabase image transformation.
|
|
166
|
+
* See: https://supabase.com/docs/guides/storage/serving/image-transformations
|
|
167
|
+
*/
|
|
168
|
+
interface SupabaseTransformOptions {
|
|
169
|
+
width?: number;
|
|
170
|
+
height?: number;
|
|
171
|
+
resize?: 'cover' | 'contain' | 'fill';
|
|
172
|
+
format?: 'origin' | 'avif' | 'webp';
|
|
173
|
+
quality?: number;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Minimal Supabase client interface for storage operations.
|
|
177
|
+
* Using a minimal interface to avoid version conflicts with @supabase/supabase-js.
|
|
178
|
+
*/
|
|
179
|
+
interface SupabaseClient {
|
|
180
|
+
storage: {
|
|
181
|
+
from(bucket: string): {
|
|
182
|
+
createSignedUrl(path: string, expiresIn: number, options?: {
|
|
183
|
+
download?: string | boolean;
|
|
184
|
+
transform?: SupabaseTransformOptions;
|
|
185
|
+
}): Promise<{
|
|
186
|
+
data: {
|
|
187
|
+
signedUrl: string;
|
|
188
|
+
} | null;
|
|
189
|
+
error: Error | null;
|
|
190
|
+
}>;
|
|
191
|
+
upload(path: string, file: Blob | ArrayBuffer | FormData, options?: {
|
|
192
|
+
contentType?: string;
|
|
193
|
+
upsert?: boolean;
|
|
194
|
+
}): Promise<{
|
|
195
|
+
data: {
|
|
196
|
+
path: string;
|
|
197
|
+
} | null;
|
|
198
|
+
error: Error | null;
|
|
199
|
+
}>;
|
|
200
|
+
remove(paths: string[]): Promise<{
|
|
201
|
+
data: {
|
|
202
|
+
name: string;
|
|
203
|
+
}[] | null;
|
|
204
|
+
error: Error | null;
|
|
205
|
+
}>;
|
|
206
|
+
list(path?: string, options?: {
|
|
207
|
+
search?: string;
|
|
208
|
+
limit?: number;
|
|
209
|
+
}): Promise<{
|
|
210
|
+
data: {
|
|
211
|
+
name: string;
|
|
212
|
+
}[] | null;
|
|
213
|
+
error: Error | null;
|
|
214
|
+
}>;
|
|
215
|
+
};
|
|
216
|
+
};
|
|
217
|
+
auth: {
|
|
218
|
+
refreshSession(): Promise<{
|
|
219
|
+
data: unknown;
|
|
220
|
+
error: Error | null;
|
|
221
|
+
}>;
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Resolve bucket from storage path using SupabaseStorageOptions.
|
|
226
|
+
*
|
|
227
|
+
* Resolution order:
|
|
228
|
+
* 1. Custom bucketResolver (if provided and returns a value)
|
|
229
|
+
* 2. bucketMap prefix matching (if provided)
|
|
230
|
+
* 3. defaultBucket
|
|
231
|
+
*/
|
|
232
|
+
declare function resolveBucket(options: Pick<SupabaseStorageOptions, 'defaultBucket' | 'bucketMap' | 'bucketResolver'>, storagePath: string): string;
|
|
233
|
+
|
|
234
|
+
export { type DownloadResult as D, type SupabaseStorage as S, type UploadProgress as U, type StorageBackend as a, type StorageUploadOptions as b, type SupabaseStorageOptions as c, type SupabaseClient as d, type SupabaseTransformOptions as e, resolveBucket as r };
|