@pol-studios/powersync 1.0.25 → 1.0.32

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 (118) hide show
  1. package/README.md +0 -1
  2. package/dist/{CacheSettingsManager-uz-kbnRH.d.ts → CacheSettingsManager-0H_7thHW.d.ts} +21 -3
  3. package/dist/attachments/index.d.ts +30 -30
  4. package/dist/attachments/index.js +13 -4
  5. package/dist/{background-sync-ChCXW-EV.d.ts → background-sync-BujnI3IR.d.ts} +1 -1
  6. package/dist/{chunk-55DKCJV4.js → chunk-2RDWLXJW.js} +408 -78
  7. package/dist/chunk-2RDWLXJW.js.map +1 -0
  8. package/dist/{chunk-P4HZA6ZT.js → chunk-4665ZSE5.js} +2 -2
  9. package/dist/chunk-4665ZSE5.js.map +1 -0
  10. package/dist/{chunk-XOY2CJ67.js → chunk-4F5B5CZ7.js} +3 -3
  11. package/dist/chunk-5WRI5ZAA.js +31 -0
  12. package/dist/{chunk-BGBQYQV3.js → chunk-65A3SYJZ.js} +193 -299
  13. package/dist/chunk-65A3SYJZ.js.map +1 -0
  14. package/dist/chunk-6SZ64KCZ.js +755 -0
  15. package/dist/chunk-6SZ64KCZ.js.map +1 -0
  16. package/dist/{chunk-YSTEESEG.js → chunk-74TBHWJ4.js} +122 -11
  17. package/dist/chunk-74TBHWJ4.js.map +1 -0
  18. package/dist/chunk-ANXWYQEJ.js +1 -0
  19. package/dist/chunk-ANXWYQEJ.js.map +1 -0
  20. package/dist/{chunk-CAB26E6F.js → chunk-C4J4MLER.js} +29 -24
  21. package/dist/chunk-C4J4MLER.js.map +1 -0
  22. package/dist/{chunk-C5ODS3XH.js → chunk-EOW7JK7Q.js} +9 -16
  23. package/dist/chunk-EOW7JK7Q.js.map +1 -0
  24. package/dist/chunk-HRAVPIAZ.js +220 -0
  25. package/dist/chunk-HRAVPIAZ.js.map +1 -0
  26. package/dist/{chunk-XAEII4ZX.js → chunk-NUGQOTEM.js} +32 -4
  27. package/dist/chunk-NUGQOTEM.js.map +1 -0
  28. package/dist/chunk-OGUFUZSY.js +5415 -0
  29. package/dist/chunk-OGUFUZSY.js.map +1 -0
  30. package/dist/{chunk-VB737IVN.js → chunk-P4D6BQ4X.js} +328 -706
  31. package/dist/chunk-P4D6BQ4X.js.map +1 -0
  32. package/dist/{chunk-CACKC6XG.js → chunk-PGEDE6IM.js} +136 -89
  33. package/dist/chunk-PGEDE6IM.js.map +1 -0
  34. package/dist/{chunk-A4IBBWGO.js → chunk-RALHHPTU.js} +1 -1
  35. package/dist/chunk-RIDSPLE5.js +42 -0
  36. package/dist/chunk-RIDSPLE5.js.map +1 -0
  37. package/dist/{chunk-Z6VOBGTU.js → chunk-UOMHWUHV.js} +2 -12
  38. package/dist/chunk-UOMHWUHV.js.map +1 -0
  39. package/dist/{chunk-WGHNIAF7.js → chunk-YONQYTVH.js} +2 -2
  40. package/dist/chunk-ZAN22NGL.js +13 -0
  41. package/dist/chunk-ZAN22NGL.js.map +1 -0
  42. package/dist/config/index.d.ts +200 -0
  43. package/dist/config/index.js +23 -0
  44. package/dist/config/index.js.map +1 -0
  45. package/dist/connector/index.d.ts +23 -5
  46. package/dist/connector/index.js +4 -2
  47. package/dist/core/index.d.ts +2 -2
  48. package/dist/core/index.js +1 -0
  49. package/dist/error/index.js +1 -0
  50. package/dist/generator/index.js +2 -0
  51. package/dist/generator/index.js.map +1 -1
  52. package/dist/index.d.ts +19 -16
  53. package/dist/index.js +88 -46
  54. package/dist/index.native.d.ts +18 -14
  55. package/dist/index.native.js +93 -44
  56. package/dist/index.web.d.ts +17 -14
  57. package/dist/index.web.js +88 -46
  58. package/dist/maintenance/index.d.ts +2 -2
  59. package/dist/maintenance/index.js +3 -2
  60. package/dist/platform/index.d.ts +1 -1
  61. package/dist/platform/index.js +2 -0
  62. package/dist/platform/index.js.map +1 -1
  63. package/dist/platform/index.native.d.ts +1 -1
  64. package/dist/platform/index.native.js +1 -0
  65. package/dist/platform/index.web.d.ts +1 -1
  66. package/dist/platform/index.web.js +1 -0
  67. package/dist/pol-attachment-queue-DqBvLAEY.d.ts +255 -0
  68. package/dist/provider/index.d.ts +319 -124
  69. package/dist/provider/index.js +21 -16
  70. package/dist/provider/index.native.d.ts +108 -0
  71. package/dist/provider/index.native.js +121 -0
  72. package/dist/provider/index.native.js.map +1 -0
  73. package/dist/provider/index.web.d.ts +16 -0
  74. package/dist/provider/index.web.js +112 -0
  75. package/dist/provider/index.web.js.map +1 -0
  76. package/dist/react/index.d.ts +16 -65
  77. package/dist/react/index.js +2 -9
  78. package/dist/storage/index.d.ts +5 -4
  79. package/dist/storage/index.js +12 -9
  80. package/dist/storage/index.native.d.ts +5 -4
  81. package/dist/storage/index.native.js +8 -5
  82. package/dist/storage/index.web.d.ts +5 -4
  83. package/dist/storage/index.web.js +11 -8
  84. package/dist/storage/upload/index.d.ts +4 -3
  85. package/dist/storage/upload/index.js +4 -2
  86. package/dist/storage/upload/index.native.d.ts +4 -3
  87. package/dist/storage/upload/index.native.js +4 -2
  88. package/dist/storage/upload/index.web.d.ts +2 -1
  89. package/dist/storage/upload/index.web.js +4 -2
  90. package/dist/{supabase-connector-D2oIl2t8.d.ts → supabase-connector-HMxBA9Kg.d.ts} +23 -25
  91. package/dist/sync/index.d.ts +183 -11
  92. package/dist/sync/index.js +13 -3
  93. package/dist/{types-CyvBaAl8.d.ts → types-6QHGELuY.d.ts} +4 -1
  94. package/dist/{types-CDqWh56B.d.ts → types-B9MptP7E.d.ts} +13 -1
  95. package/dist/types-BhAEsJj-.d.ts +330 -0
  96. package/dist/{types-D0WcHrq6.d.ts → types-CGMibJKD.d.ts} +8 -0
  97. package/dist/{types-DiBvmGEi.d.ts → types-DqJnP50o.d.ts} +22 -24
  98. package/dist/{pol-attachment-queue-BE2HU3Us.d.ts → types-JCEhw2Lf.d.ts} +139 -346
  99. package/package.json +18 -4
  100. package/dist/chunk-24RDMMCL.js +0 -44
  101. package/dist/chunk-24RDMMCL.js.map +0 -1
  102. package/dist/chunk-55DKCJV4.js.map +0 -1
  103. package/dist/chunk-654ERHA7.js +0 -1
  104. package/dist/chunk-BGBQYQV3.js.map +0 -1
  105. package/dist/chunk-C5ODS3XH.js.map +0 -1
  106. package/dist/chunk-CAB26E6F.js.map +0 -1
  107. package/dist/chunk-CACKC6XG.js.map +0 -1
  108. package/dist/chunk-P4HZA6ZT.js.map +0 -1
  109. package/dist/chunk-TIFL2KWE.js +0 -358
  110. package/dist/chunk-TIFL2KWE.js.map +0 -1
  111. package/dist/chunk-VB737IVN.js.map +0 -1
  112. package/dist/chunk-XAEII4ZX.js.map +0 -1
  113. package/dist/chunk-YSTEESEG.js.map +0 -1
  114. package/dist/chunk-Z6VOBGTU.js.map +0 -1
  115. /package/dist/{chunk-XOY2CJ67.js.map → chunk-4F5B5CZ7.js.map} +0 -0
  116. /package/dist/{chunk-654ERHA7.js.map → chunk-5WRI5ZAA.js.map} +0 -0
  117. /package/dist/{chunk-A4IBBWGO.js.map → chunk-RALHHPTU.js.map} +0 -0
  118. /package/dist/{chunk-WGHNIAF7.js.map → chunk-YONQYTVH.js.map} +0 -0
@@ -1,17 +1,19 @@
1
1
  import { SupabaseClient } from '@supabase/supabase-js';
2
2
  import { QueryClient } from '@tanstack/react-query';
3
- import { A as AbstractPowerSyncDatabase, a as SyncStatus, C as CrudEntry, S as SyncMode, F as FailedTransaction, h as CompletedTransaction, b as ConnectionHealth, e as SyncMetrics, D as DownloadProgress, E as EntitySyncState, f as SyncError } from '../types-CDqWh56B.js';
3
+ import { A as AbstractPowerSyncDatabase, a as SyncStatus, C as CrudEntry, S as SyncMode, F as FailedTransaction, h as CompletedTransaction, b as ConnectionHealth, e as SyncMetrics, D as DownloadProgress, E as EntitySyncState, f as SyncError, U as UploadBlockReason } from '../types-B9MptP7E.js';
4
4
  import { PlatformAdapter } from '../platform/index.js';
5
- import { a as ConnectorConfig, i as ConflictBus } from '../types-DiBvmGEi.js';
6
- import { f as AttachmentConfig, P as PolAttachmentQueue, A as AttachmentSourceConfig, F as AttachmentRecord, C as CompressionConfig, j as DownloadConfig } from '../pol-attachment-queue-BE2HU3Us.js';
7
- import { S as SupabaseConnector } from '../supabase-connector-D2oIl2t8.js';
5
+ import { a as ConnectorConfig, i as ConflictBus, h as UploadErrorMiddleware } from '../types-DqJnP50o.js';
6
+ import { d as AttachmentConfig, c as AttachmentSourceConfig, z as AttachmentRecord, f as CompressionConfig, i as DownloadConfig } from '../types-JCEhw2Lf.js';
7
+ import { P as PolAttachmentQueue } from '../pol-attachment-queue-DqBvLAEY.js';
8
+ import { S as SupabaseConnector } from '../supabase-connector-HMxBA9Kg.js';
8
9
  import * as react from 'react';
9
10
  import react__default, { ReactNode } from 'react';
10
11
  import { Schema } from '@powersync/react-native';
11
- import { a as StorageBackend } from '../types-D0WcHrq6.js';
12
- import { h as BackgroundSyncSystem, c as SyncControlActions } from '../background-sync-ChCXW-EV.js';
13
- import '@powersync/attachments';
12
+ import { a as StorageBackend } from '../types-CGMibJKD.js';
13
+ import { h as BackgroundSyncSystem, c as SyncControlActions } from '../background-sync-BujnI3IR.js';
14
+ import { a as ProcessedPolConfig } from '../types-BhAEsJj-.js';
14
15
  import '@powersync/common';
16
+ import '@powersync/attachments';
15
17
 
16
18
  /**
17
19
  * Provider Types for @pol-studios/powersync
@@ -79,8 +81,12 @@ interface PowerSyncConfig<TSchema = unknown> {
79
81
  * @example
80
82
  * ```typescript
81
83
  * attachments: {
82
- * source: { table: 'photos', idColumn: 'storage_path' },
83
- * remoteStorage: supabaseStorageAdapter,
84
+ * source: { type: 'supabase-bucket', bucket: 'photos' },
85
+ * watchPaths: (db, supabase, onUpdate) => {
86
+ * db.watch('SELECT storage_path FROM photos', [], {
87
+ * onResult: (r) => onUpdate(r.rows._array.map(x => x.storage_path)),
88
+ * });
89
+ * },
84
90
  * }
85
91
  * ```
86
92
  */
@@ -116,6 +122,26 @@ interface SyncConfig {
116
122
  */
117
123
  enableMetrics?: boolean;
118
124
  }
125
+ /**
126
+ * Options for resetSync operation.
127
+ */
128
+ interface ResetSyncOptions {
129
+ /**
130
+ * Clear downloaded attachments (photos, documents).
131
+ * @default true
132
+ */
133
+ clearAttachments?: boolean;
134
+ /**
135
+ * Clear React Query cache.
136
+ * @default true
137
+ */
138
+ clearQueryCache?: boolean;
139
+ /**
140
+ * Timeout for cache operations in milliseconds.
141
+ * @default 30000
142
+ */
143
+ timeout?: number;
144
+ }
119
145
  /**
120
146
  * Value provided by the main PowerSyncContext.
121
147
  *
@@ -173,6 +199,23 @@ interface PowerSyncContextValue<TSchema = unknown> {
173
199
  * Use this to wire up conflict UI components.
174
200
  */
175
201
  conflictBus: ConflictBus;
202
+ /**
203
+ * Reset sync data by disconnecting and clearing synced data.
204
+ * Optionally clears React Query cache and attachment cache.
205
+ *
206
+ * @param options - Reset options
207
+ * @example
208
+ * ```typescript
209
+ * const { resetSync } = usePowerSync();
210
+ *
211
+ * await resetSync({
212
+ * clearAttachments: true, // Clear downloaded photos/documents
213
+ * clearQueryCache: true, // Clear React Query cache
214
+ * timeout: 30000, // Timeout for cache operations
215
+ * });
216
+ * ```
217
+ */
218
+ resetSync: (options?: ResetSyncOptions) => Promise<void>;
176
219
  }
177
220
  /**
178
221
  * Value provided by SyncStatusContext.
@@ -232,10 +275,6 @@ interface SyncStatusContextValue {
232
275
  * Clear a specific failure by its ID.
233
276
  */
234
277
  clearFailure: (failureId: string) => void;
235
- /**
236
- * Clear all failures.
237
- */
238
- clearAllFailures: () => void;
239
278
  /**
240
279
  * Completed transactions history.
241
280
  */
@@ -261,20 +300,31 @@ interface SyncStatusContextValue {
261
300
  */
262
301
  discardPendingMutation: (clientId: number) => Promise<void>;
263
302
  /**
264
- * Discard all pending mutations.
265
- * Uses safe disconnect/reconnect pattern to avoid transaction conflicts.
266
- * @throws Error if upload is in progress
303
+ * Whether we're currently waiting for a retry after upload failure.
304
+ */
305
+ isWaitingForUploadRetry: boolean;
306
+ /**
307
+ * When the next retry will occur (null if not waiting).
267
308
  */
268
- discardAllPendingMutations: () => Promise<void>;
309
+ nextUploadRetryAt: Date | null;
269
310
  /**
270
- * Pause automatic retry of failed uploads.
271
- * Useful when user is actively resolving conflicts.
311
+ * Whether the maximum retry attempts have been reached.
272
312
  */
273
- pauseAutoRetry: () => void;
313
+ maxUploadRetriesReached: boolean;
274
314
  /**
275
- * Resume automatic retry of failed uploads.
315
+ * Current retry attempt count.
276
316
  */
277
- resumeAutoRetry: () => void;
317
+ uploadRetryCount: number;
318
+ /**
319
+ * Force a manual retry after max retries reached.
320
+ */
321
+ manualUploadRetry: () => Promise<void>;
322
+ /**
323
+ * Discard a specific failed entry by its ps_crud ID and reconnect.
324
+ * Use this when a single entry is causing upload failures.
325
+ * @param entryId - The ps_crud entry ID (clientId) to discard
326
+ */
327
+ discardFailedEntryAndReconnect: (entryId: number) => Promise<void>;
278
328
  }
279
329
  /**
280
330
  * Connection state - changes rarely (on connect/disconnect).
@@ -315,8 +365,6 @@ interface PendingMutationsContextValue {
315
365
  pendingCount: number;
316
366
  /** Discard a specific pending mutation by its client ID */
317
367
  discardPendingMutation: (clientId: number) => Promise<void>;
318
- /** Discard all pending mutations */
319
- discardAllPendingMutations: () => Promise<void>;
320
368
  /**
321
369
  * Add a pending mutation to the list.
322
370
  * Called by mutation hooks (useDbInsert, useDbUpdate, useDbDelete, useDbUpsert)
@@ -342,12 +390,6 @@ interface FailedTransactionsContextValue {
342
390
  permanentErrorCount: number;
343
391
  /** Clear a specific failure by its ID */
344
392
  clearFailure: (failureId: string) => void;
345
- /** Clear all failures */
346
- clearAllFailures: () => void;
347
- /** Pause automatic retry of failed uploads */
348
- pauseAutoRetry: () => void;
349
- /** Resume automatic retry of failed uploads */
350
- resumeAutoRetry: () => void;
351
393
  /**
352
394
  * Retry a specific failed transaction.
353
395
  *
@@ -405,6 +447,36 @@ interface SyncModeContextValue {
405
447
  setSyncMode: (mode: SyncMode) => Promise<void>;
406
448
  /** Set the force next upload flag */
407
449
  setForceNextUpload: (force: boolean) => void;
450
+ /**
451
+ * Whether we're currently waiting for a retry after upload failure.
452
+ * When true, PowerSync is disconnected and waiting for the backoff timer.
453
+ */
454
+ isWaitingForUploadRetry: boolean;
455
+ /**
456
+ * When the next retry will occur (null if not waiting).
457
+ * Use this to display a countdown to the user.
458
+ */
459
+ nextUploadRetryAt: Date | null;
460
+ /**
461
+ * Whether the maximum retry attempts have been reached.
462
+ * When true, the system won't automatically retry - user must intervene.
463
+ */
464
+ maxUploadRetriesReached: boolean;
465
+ /**
466
+ * Current retry attempt count (0 when no retries have occurred).
467
+ */
468
+ uploadRetryCount: number;
469
+ /**
470
+ * Force a manual retry after max retries reached.
471
+ * Resets retry state and attempts to reconnect.
472
+ */
473
+ manualUploadRetry: () => Promise<void>;
474
+ /**
475
+ * Discard a specific failed entry by its ps_crud ID and reconnect.
476
+ * Use this when a single entry is causing upload failures.
477
+ * @param entryId - The ps_crud entry ID (clientId) to discard
478
+ */
479
+ discardFailedEntryAndReconnect: (entryId: number) => Promise<void>;
408
480
  }
409
481
  /**
410
482
  * Value provided by ConnectionHealthContext.
@@ -693,7 +765,26 @@ interface PowerSyncSyncStatusSnapshot {
693
765
  }
694
766
  /**
695
767
  * Attachment configuration for OfflineDataProvider.
696
- * Uses the new 2-callback API (watchIds, skipDownload).
768
+ *
769
+ * @example
770
+ * ```typescript
771
+ * attachments: {
772
+ * source: { type: 'supabase-bucket', bucket: 'photos', signed: true },
773
+ * watchPaths: (db, supabase, onUpdate) => {
774
+ * const abort = new AbortController();
775
+ * db.watch(
776
+ * // Filter directly in the query - only emit paths you want to download
777
+ * `SELECT storagePath FROM photos
778
+ * WHERE storagePath IS NOT NULL
779
+ * AND storagePath NOT LIKE '%.mp4'`,
780
+ * [],
781
+ * { onResult: (r) => onUpdate(r.rows._array.map(x => x.storagePath)) },
782
+ * { signal: abort.signal }
783
+ * );
784
+ * return () => abort.abort();
785
+ * },
786
+ * }
787
+ * ```
697
788
  */
698
789
  interface OfflineDataAttachmentConfig extends AttachmentSourceConfig {
699
790
  /** Optional: callback when upload completes */
@@ -739,6 +830,8 @@ interface OfflineDataProviderConfig {
739
830
  conflictDetection?: {
740
831
  enabled: boolean;
741
832
  };
833
+ /** Upload error middleware chain for classifying and handling upload errors */
834
+ uploadErrorMiddleware?: UploadErrorMiddleware[];
742
835
  };
743
836
  /** Sync behavior configuration */
744
837
  sync?: {
@@ -754,8 +847,45 @@ interface OfflineDataProviderConfig {
754
847
  * Props for OfflineDataProvider
755
848
  */
756
849
  interface OfflineDataProviderProps {
757
- /** Provider configuration */
758
- config: OfflineDataProviderConfig;
850
+ /**
851
+ * Provider configuration (legacy).
852
+ * Use either `config` OR `polConfig`, not both.
853
+ */
854
+ config?: OfflineDataProviderConfig;
855
+ /**
856
+ * Unified configuration from `definePolConfig`.
857
+ * This is the recommended way to configure OfflineDataProvider.
858
+ *
859
+ * When using polConfig, you must also provide:
860
+ * - `supabaseClient`
861
+ * - `queryClient`
862
+ *
863
+ * @example
864
+ * ```tsx
865
+ * import { definePolConfig } from '@pol-studios/powersync/config';
866
+ *
867
+ * const polConfig = definePolConfig({ ... });
868
+ *
869
+ * <OfflineDataProvider
870
+ * polConfig={polConfig}
871
+ * supabaseClient={supabase}
872
+ * queryClient={queryClient}
873
+ * >
874
+ * <App />
875
+ * </OfflineDataProvider>
876
+ * ```
877
+ */
878
+ polConfig?: ProcessedPolConfig;
879
+ /**
880
+ * Supabase client instance.
881
+ * Required when using `polConfig`.
882
+ */
883
+ supabaseClient?: SupabaseClient;
884
+ /**
885
+ * React Query client.
886
+ * Required when using `polConfig`.
887
+ */
888
+ queryClient?: QueryClient;
759
889
  children: ReactNode;
760
890
  /**
761
891
  * DataLayer configuration for @pol-studios/db integration.
@@ -774,6 +904,37 @@ interface OfflineDataProviderProps {
774
904
  skipStorageQueueProvider?: boolean;
775
905
  /** Custom storage backend (overrides built-in Supabase adapter) */
776
906
  storageBackend?: StorageBackend;
907
+ /**
908
+ * Custom platform adapter (optional).
909
+ * Use this to provide custom logging or filesystem implementations.
910
+ * If not provided, a default native platform adapter is created.
911
+ */
912
+ platform?: PlatformAdapter;
913
+ /**
914
+ * Attachment callback overrides at React level.
915
+ * These override the callbacks defined in polConfig.attachments,
916
+ * allowing you to use React hooks or access component context.
917
+ *
918
+ * @example
919
+ * ```tsx
920
+ * const watchPaths = useCallback((db, supabase, onUpdate) => {
921
+ * db.watch(
922
+ * `SELECT storagePath FROM photos
923
+ * WHERE storagePath IS NOT NULL
924
+ * AND mediaType NOT LIKE 'video/%'`,
925
+ * [],
926
+ * { onResult: (r) => onUpdate(r.rows._array.map(x => x.storagePath)) }
927
+ * );
928
+ * return () => {};
929
+ * }, []);
930
+ *
931
+ * <OfflineDataProvider
932
+ * polConfig={polConfig}
933
+ * attachments={{ watchPaths }}
934
+ * >
935
+ * ```
936
+ */
937
+ attachments?: Partial<Pick<OfflineDataAttachmentConfig, 'watchPaths'>>;
777
938
  /** Custom error UI for initialization errors */
778
939
  renderInitError?: (error: Error, retry: () => void) => ReactNode;
779
940
  /** Custom error UI (alias for renderInitError) */
@@ -810,94 +971,6 @@ interface ProviderBridgeProps {
810
971
  onRemovePendingMutationReady: (remove: (id: string) => void) => void;
811
972
  }
812
973
 
813
- /**
814
- * OfflineDataProvider Component for @pol-studios/powersync
815
- *
816
- * Batteries-included offline data provider that combines:
817
- * - PowerSyncProvider for offline-first data sync
818
- * - DataLayerProvider integration from @pol-studios/db
819
- * - ConflictProvider for conflict resolution UI
820
- * - StorageQueueProvider for attachment queue access
821
- * - Background sync system setup
822
- * - Error recovery UI with retry capability
823
- * - Online-only mode fallback (no PowerSync URL)
824
- *
825
- * @example
826
- * ```tsx
827
- * <OfflineDataProvider
828
- * config={{
829
- * schema: AppSchema,
830
- * supabaseClient: supabase,
831
- * queryClient: queryClient,
832
- * powerSyncUrl: env.powerSyncUrl,
833
- * attachments: {
834
- * bucket: 'my-bucket',
835
- * watchIds: (db, onUpdate) => {
836
- * db.watch('SELECT storagePath as id FROM photos', [], {
837
- * onResult: (r) => onUpdate(r.rows._array.map(x => x.id)),
838
- * });
839
- * },
840
- * skipDownload: async ({ ids }) => {
841
- * // Return IDs to skip downloading (e.g., videos)
842
- * return ids.filter(id => id.endsWith('.mp4'));
843
- * },
844
- * },
845
- * }}
846
- * dataLayer={{ config: dataLayerConfig }}
847
- * renderInitError={(error, retry) => <MyErrorUI error={error} onRetry={retry} />}
848
- * >
849
- * <App />
850
- * </OfflineDataProvider>
851
- * ```
852
- */
853
-
854
- /**
855
- * Batteries-included offline data provider.
856
- *
857
- * Combines PowerSyncProvider with error boundary, DataLayerProvider integration,
858
- * and sensible defaults for a complete offline-first data solution.
859
- *
860
- * Key features:
861
- * - Automatic PowerSync setup and initialization
862
- * - Integration with @pol-studios/db DataLayerProvider
863
- * - ConflictProvider and StorageQueueProvider wiring
864
- * - Background sync system support
865
- * - Error recovery UI with retry capability
866
- * - Online-only mode fallback when no PowerSync URL is provided
867
- *
868
- * @example
869
- * ```tsx
870
- * // Basic usage
871
- * <OfflineDataProvider
872
- * config={{
873
- * schema: AppSchema,
874
- * supabaseClient: supabase,
875
- * queryClient: queryClient,
876
- * powerSyncUrl: process.env.EXPO_PUBLIC_POWERSYNC_URL,
877
- * }}
878
- * >
879
- * <App />
880
- * </OfflineDataProvider>
881
- *
882
- * // With DataLayer integration
883
- * <OfflineDataProvider
884
- * config={{ ... }}
885
- * dataLayer={{ config: dataLayerConfig }}
886
- * >
887
- * <App />
888
- * </OfflineDataProvider>
889
- *
890
- * // With custom error UI
891
- * <OfflineDataProvider
892
- * config={{ ... }}
893
- * renderInitError={(error, retry) => <MyErrorUI error={error} onRetry={retry} />}
894
- * >
895
- * <App />
896
- * </OfflineDataProvider>
897
- * ```
898
- */
899
- declare function OfflineDataProvider({ config, children, dataLayer, backgroundSync, skipConflictProvider, skipStorageQueueProvider, storageBackend, renderInitError, renderError, onReady, onError, onSyncStatusChange, onBackgroundSyncSystemReady: onBackgroundSyncSystemReadyProp, }: OfflineDataProviderProps): react__default.ReactElement;
900
-
901
974
  /**
902
975
  * ProviderBridge Component for @pol-studios/powersync
903
976
  *
@@ -1164,6 +1237,58 @@ declare function useSyncMode(): {
1164
1237
  canDownload: boolean;
1165
1238
  networkReachable: boolean;
1166
1239
  };
1240
+ /**
1241
+ * Hook to access upload retry state for exponential backoff handling.
1242
+ *
1243
+ * When an upload fails, the provider disconnects and waits with exponential backoff
1244
+ * before reconnecting. After 7 failed attempts (256s backoff), it stays disconnected
1245
+ * and lets the user decide.
1246
+ *
1247
+ * @returns Upload retry state and control functions
1248
+ * @throws Error if used outside of PowerSyncProvider
1249
+ *
1250
+ * @example
1251
+ * ```typescript
1252
+ * function UploadRetryBanner() {
1253
+ * const {
1254
+ * isWaiting,
1255
+ * nextRetryAt,
1256
+ * maxRetriesReached,
1257
+ * retryCount,
1258
+ * manualRetry,
1259
+ * discardAndReconnect,
1260
+ * } = useUploadRetry();
1261
+ *
1262
+ * if (maxRetriesReached) {
1263
+ * return (
1264
+ * <View>
1265
+ * <Text>Upload failed after {retryCount} attempts</Text>
1266
+ * <Button onPress={manualRetry}>Try Again</Button>
1267
+ * <Button onPress={discardAndReconnect}>Discard Changes</Button>
1268
+ * </View>
1269
+ * );
1270
+ * }
1271
+ *
1272
+ * if (isWaiting && nextRetryAt) {
1273
+ * return (
1274
+ * <View>
1275
+ * <Text>Retrying in {Math.ceil((nextRetryAt.getTime() - Date.now()) / 1000)}s</Text>
1276
+ * </View>
1277
+ * );
1278
+ * }
1279
+ *
1280
+ * return null;
1281
+ * }
1282
+ * ```
1283
+ */
1284
+ declare function useUploadRetry(): {
1285
+ isWaiting: boolean;
1286
+ nextRetryAt: Date | null;
1287
+ maxRetriesReached: boolean;
1288
+ retryCount: number;
1289
+ manualRetry: () => Promise<void>;
1290
+ discardEntryAndReconnect: (entryId: number) => Promise<void>;
1291
+ };
1167
1292
  /**
1168
1293
  * Hook to access connection health status.
1169
1294
  *
@@ -1469,8 +1594,8 @@ interface UploadStatusResult {
1469
1594
  failedTransactions: FailedTransaction[];
1470
1595
  /** Trigger sync retry (reconnect) */
1471
1596
  retryAll: () => Promise<void>;
1472
- /** Dismiss all failures */
1473
- dismissAll: () => void;
1597
+ /** Dismiss a specific failure by its ID */
1598
+ dismissFailure: (failureId: string) => void;
1474
1599
  }
1475
1600
  /**
1476
1601
  * Hook to get overall upload status across all entities.
@@ -1559,5 +1684,75 @@ declare const useFailedTransactions: typeof useFailedTransactionsContext;
1559
1684
  * Alias for useCompletedTransactionsContext.
1560
1685
  */
1561
1686
  declare const useCompletedTransactions: typeof useCompletedTransactionsContext;
1687
+ /**
1688
+ * Return type for useUploadBlockedReason hook.
1689
+ */
1690
+ interface UploadBlockedReasonResult {
1691
+ /** Whether uploads are currently blocked */
1692
+ isBlocked: boolean;
1693
+ /** The reason uploads are blocked */
1694
+ reason: UploadBlockReason;
1695
+ /** Human-readable description of why uploads are blocked */
1696
+ description: string | null;
1697
+ /** Whether an upload is actively in progress */
1698
+ isUploading: boolean;
1699
+ }
1700
+ /**
1701
+ * Hook to get why uploads are blocked.
1702
+ * Derives block reason from existing sync mode, network, and connection state.
1703
+ *
1704
+ * @returns Upload blocked status with reason and description
1705
+ *
1706
+ * @example
1707
+ * ```typescript
1708
+ * function UploadBlockedBanner() {
1709
+ * const { isBlocked, reason, description } = useUploadBlockedReason();
1710
+ *
1711
+ * if (!isBlocked) return null;
1712
+ *
1713
+ * return <Banner>{description}</Banner>;
1714
+ * }
1715
+ * ```
1716
+ */
1717
+ declare function useUploadBlockedReason(): UploadBlockedReasonResult;
1718
+ /**
1719
+ * Return type for useRetryCountdown hook.
1720
+ */
1721
+ interface RetryCountdownResult {
1722
+ /** The soonest next retry time from all failed transactions */
1723
+ nextRetryAt: Date | null;
1724
+ /** Milliseconds until the next retry (0 if already past) */
1725
+ timeUntilRetryMs: number;
1726
+ /** Formatted countdown string (e.g., "5s", "1m 30s", "2m") or null if no retry scheduled */
1727
+ formattedCountdown: string | null;
1728
+ }
1729
+ /**
1730
+ * Hook for retry countdown display.
1731
+ *
1732
+ * @deprecated The nextRetryAt and backoffMs fields have been removed from FailedTransaction.
1733
+ * PowerSync SDK now controls retry timing internally. This hook is retained for backward
1734
+ * compatibility but will always return null values.
1735
+ *
1736
+ * @returns Retry countdown information (always returns null values)
1737
+ */
1738
+ declare function useRetryCountdown(): RetryCountdownResult;
1739
+
1740
+ /**
1741
+ * Provider Constants for @pol-studios/powersync
1742
+ *
1743
+ * Exports constants used in the provider that may need to be accessed by UI components.
1744
+ */
1745
+ /**
1746
+ * Maximum number of upload retry attempts before stopping automatic retries.
1747
+ * After this many attempts, the user must manually retry or discard the failed entries.
1748
+ *
1749
+ * Backoff delays: 4s, 8s, 16s, 32s, 64s, 128s, 256s (total: ~8.5 minutes)
1750
+ */
1751
+ declare const UPLOAD_MAX_RETRIES = 7;
1752
+ /**
1753
+ * Backoff delays in seconds for each retry attempt.
1754
+ * Uses exponential backoff: 4s, 8s, 16s, 32s, 64s, 128s, 256s
1755
+ */
1756
+ declare const UPLOAD_BACKOFF_DELAYS: readonly [4, 8, 16, 32, 64, 128, 256];
1562
1757
 
1563
- export { AttachmentQueueContext, type BackgroundSyncCallbacks, type BackgroundSyncConfig, type BackgroundSyncStatus, CompletedTransactionsContext, type CompletedTransactionsContextValue, ConnectionHealthContext, type ConnectionHealthContextValue, ConnectionStatusContext, type ConnectionStatusContextValue, DEFAULT_CONNECTION_HEALTH, DEFAULT_SYNC_CONFIG, DEFAULT_SYNC_METRICS, DEFAULT_SYNC_STATUS, type DataLayerConfig, type DataLayerIntegration, type EntitySyncStatusResult, FailedTransactionsContext, type FailedTransactionsContextValue, type OfflineDataAttachmentConfig, OfflineDataProvider, type OfflineDataProviderConfig, type OfflineDataProviderProps, PendingMutationsContext, type PendingMutationsContextValue, type PowerSyncConfig, PowerSyncContext, type PowerSyncContextValue, PowerSyncProvider, type PowerSyncProviderProps, type PowerSyncSyncStatusSnapshot, ProviderBridge, type ProviderBridgeProps, SyncActivityContext, type SyncActivityContextValue, type SyncActivityResult, type SyncConfig, SyncMetricsContext, type SyncMetricsContextValue, SyncModeContext, type SyncModeContextValue, SyncStatusContext, type SyncStatusContextValue, type UploadStatusResult, useAttachmentQueue, useAttachmentQueueReady, useCompletedTransactions, useCompletedTransactionsContext, useConnectionHealth, useConnectionStatus, useDatabase, useDownloadProgress, useEntitySyncStatus, useFailedTransactions, useFailedTransactionsContext, useIsSyncing, useOnlineStatus, usePendingMutations, usePendingMutationsContext, usePlatform, usePowerSync, useSyncActivity, useSyncActivityContext, useSyncControl, useSyncMetrics, useSyncMode, useSyncModeContext, useSyncStatus, useUploadStatus };
1758
+ export { AttachmentQueueContext, type BackgroundSyncCallbacks, type BackgroundSyncConfig, type BackgroundSyncStatus, CompletedTransactionsContext, type CompletedTransactionsContextValue, ConnectionHealthContext, type ConnectionHealthContextValue, ConnectionStatusContext, type ConnectionStatusContextValue, DEFAULT_CONNECTION_HEALTH, DEFAULT_SYNC_CONFIG, DEFAULT_SYNC_METRICS, DEFAULT_SYNC_STATUS, type DataLayerConfig, type DataLayerIntegration, type EntitySyncStatusResult, FailedTransactionsContext, type FailedTransactionsContextValue, type OfflineDataAttachmentConfig, type OfflineDataProviderConfig, type OfflineDataProviderProps, PendingMutationsContext, type PendingMutationsContextValue, type PowerSyncConfig, PowerSyncContext, type PowerSyncContextValue, PowerSyncProvider, type PowerSyncProviderProps, type PowerSyncSyncStatusSnapshot, ProviderBridge, type ProviderBridgeProps, type ResetSyncOptions, type RetryCountdownResult, SyncActivityContext, type SyncActivityContextValue, type SyncActivityResult, type SyncConfig, SyncMetricsContext, type SyncMetricsContextValue, SyncModeContext, type SyncModeContextValue, SyncStatusContext, type SyncStatusContextValue, UPLOAD_BACKOFF_DELAYS, UPLOAD_MAX_RETRIES, type UploadBlockedReasonResult, type UploadStatusResult, useAttachmentQueue, useAttachmentQueueReady, useCompletedTransactions, useCompletedTransactionsContext, useConnectionHealth, useConnectionStatus, useDatabase, useDownloadProgress, useEntitySyncStatus, useFailedTransactions, useFailedTransactionsContext, useIsSyncing, useOnlineStatus, usePendingMutations, usePendingMutationsContext, usePlatform, usePowerSync, useRetryCountdown, useSyncActivity, useSyncActivityContext, useSyncControl, useSyncMetrics, useSyncMode, useSyncModeContext, useSyncStatus, useUploadBlockedReason, useUploadRetry, useUploadStatus };
@@ -1,18 +1,17 @@
1
1
  import {
2
- OfflineDataProvider,
3
2
  PowerSyncProvider,
4
- ProviderBridge
5
- } from "../chunk-VB737IVN.js";
6
- import "../chunk-YHTZ7VMV.js";
7
- import "../chunk-P6WOZO7H.js";
8
- import "../chunk-CACKC6XG.js";
9
- import "../chunk-55DKCJV4.js";
3
+ ProviderBridge,
4
+ UPLOAD_BACKOFF_DELAYS,
5
+ UPLOAD_MAX_RETRIES
6
+ } from "../chunk-P4D6BQ4X.js";
7
+ import "../chunk-PGEDE6IM.js";
10
8
  import {
11
9
  DEFAULT_CONNECTION_HEALTH,
12
10
  DEFAULT_SYNC_CONFIG,
13
11
  DEFAULT_SYNC_METRICS,
14
12
  DEFAULT_SYNC_STATUS
15
- } from "../chunk-24RDMMCL.js";
13
+ } from "../chunk-2RDWLXJW.js";
14
+ import "../chunk-OGUFUZSY.js";
16
15
  import {
17
16
  AttachmentQueueContext,
18
17
  CompletedTransactionsContext,
@@ -42,6 +41,7 @@ import {
42
41
  usePendingMutationsContext,
43
42
  usePlatform,
44
43
  usePowerSync,
44
+ useRetryCountdown,
45
45
  useSyncActivity,
46
46
  useSyncActivityContext,
47
47
  useSyncControl,
@@ -49,16 +49,17 @@ import {
49
49
  useSyncMode,
50
50
  useSyncModeContext,
51
51
  useSyncStatus,
52
+ useUploadBlockedReason,
53
+ useUploadRetry,
52
54
  useUploadStatus
53
- } from "../chunk-YSTEESEG.js";
54
- import "../chunk-CAB26E6F.js";
55
- import "../chunk-XAEII4ZX.js";
56
- import "../chunk-Z6VOBGTU.js";
57
- import "../chunk-CGL33PL4.js";
58
- import "../chunk-WN5ZJ3E2.js";
59
- import "../chunk-BGBQYQV3.js";
55
+ } from "../chunk-74TBHWJ4.js";
56
+ import "../chunk-NUGQOTEM.js";
57
+ import "../chunk-UOMHWUHV.js";
60
58
  import "../chunk-FV2HXEIY.js";
59
+ import "../chunk-CGL33PL4.js";
60
+ import "../chunk-65A3SYJZ.js";
61
61
  import "../chunk-I2AYMY5O.js";
62
+ import "../chunk-5WRI5ZAA.js";
62
63
  export {
63
64
  AttachmentQueueContext,
64
65
  CompletedTransactionsContext,
@@ -69,7 +70,6 @@ export {
69
70
  DEFAULT_SYNC_METRICS,
70
71
  DEFAULT_SYNC_STATUS,
71
72
  FailedTransactionsContext,
72
- OfflineDataProvider,
73
73
  PendingMutationsContext,
74
74
  PowerSyncContext,
75
75
  PowerSyncProvider,
@@ -78,6 +78,8 @@ export {
78
78
  SyncMetricsContext,
79
79
  SyncModeContext,
80
80
  SyncStatusContext,
81
+ UPLOAD_BACKOFF_DELAYS,
82
+ UPLOAD_MAX_RETRIES,
81
83
  useAttachmentQueue,
82
84
  useAttachmentQueueReady,
83
85
  useCompletedTransactions,
@@ -95,6 +97,7 @@ export {
95
97
  usePendingMutationsContext,
96
98
  usePlatform,
97
99
  usePowerSync,
100
+ useRetryCountdown,
98
101
  useSyncActivity,
99
102
  useSyncActivityContext,
100
103
  useSyncControl,
@@ -102,6 +105,8 @@ export {
102
105
  useSyncMode,
103
106
  useSyncModeContext,
104
107
  useSyncStatus,
108
+ useUploadBlockedReason,
109
+ useUploadRetry,
105
110
  useUploadStatus
106
111
  };
107
112
  //# sourceMappingURL=index.js.map