@pol-studios/powersync 1.0.6 → 1.0.7

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/dist/CacheSettingsManager-1exbOC6S.d.ts +261 -0
  2. package/dist/attachments/index.d.ts +65 -355
  3. package/dist/attachments/index.js +24 -6
  4. package/dist/{types-Cd7RhNqf.d.ts → background-sync-ChCXW-EV.d.ts} +53 -2
  5. package/dist/chunk-4C3RY5SU.js +204 -0
  6. package/dist/chunk-4C3RY5SU.js.map +1 -0
  7. package/dist/{chunk-3AYXHQ4W.js → chunk-53WH2JJV.js} +111 -47
  8. package/dist/chunk-53WH2JJV.js.map +1 -0
  9. package/dist/chunk-A4IBBWGO.js +377 -0
  10. package/dist/chunk-A4IBBWGO.js.map +1 -0
  11. package/dist/chunk-BREGB4WL.js +1768 -0
  12. package/dist/chunk-BREGB4WL.js.map +1 -0
  13. package/dist/{chunk-EJ23MXPQ.js → chunk-CGL33PL4.js} +3 -1
  14. package/dist/chunk-CGL33PL4.js.map +1 -0
  15. package/dist/chunk-DGUM43GV.js +11 -0
  16. package/dist/chunk-DHYUBVP7.js +131 -0
  17. package/dist/chunk-DHYUBVP7.js.map +1 -0
  18. package/dist/chunk-FV2HXEIY.js +124 -0
  19. package/dist/chunk-FV2HXEIY.js.map +1 -0
  20. package/dist/chunk-GKF7TOMT.js +1 -0
  21. package/dist/{chunk-R4YFWQ3Q.js → chunk-H772V6XQ.js} +304 -51
  22. package/dist/chunk-H772V6XQ.js.map +1 -0
  23. package/dist/{chunk-62J2DPKX.js → chunk-HFOFLW5F.js} +396 -412
  24. package/dist/chunk-HFOFLW5F.js.map +1 -0
  25. package/dist/chunk-KGSFAE5B.js +1 -0
  26. package/dist/chunk-LNL64IJZ.js +1 -0
  27. package/dist/chunk-MKD2VCX3.js +32 -0
  28. package/dist/chunk-MKD2VCX3.js.map +1 -0
  29. package/dist/{chunk-7EMDVIZX.js → chunk-N75DEF5J.js} +19 -1
  30. package/dist/chunk-N75DEF5J.js.map +1 -0
  31. package/dist/chunk-P6WOZO7H.js +49 -0
  32. package/dist/chunk-P6WOZO7H.js.map +1 -0
  33. package/dist/chunk-TGBT5XBE.js +1 -0
  34. package/dist/chunk-TGBT5XBE.js.map +1 -0
  35. package/dist/chunk-UEYRTLKE.js +72 -0
  36. package/dist/chunk-UEYRTLKE.js.map +1 -0
  37. package/dist/chunk-WGHNIAF7.js +329 -0
  38. package/dist/chunk-WGHNIAF7.js.map +1 -0
  39. package/dist/chunk-WQ5MPAVC.js +449 -0
  40. package/dist/chunk-WQ5MPAVC.js.map +1 -0
  41. package/dist/{chunk-FPTDATY5.js → chunk-XQAJM2MW.js} +22 -11
  42. package/dist/chunk-XQAJM2MW.js.map +1 -0
  43. package/dist/chunk-YSTEESEG.js +676 -0
  44. package/dist/chunk-YSTEESEG.js.map +1 -0
  45. package/dist/chunk-ZEOKPWUC.js +1165 -0
  46. package/dist/chunk-ZEOKPWUC.js.map +1 -0
  47. package/dist/connector/index.d.ts +182 -3
  48. package/dist/connector/index.js +12 -4
  49. package/dist/core/index.d.ts +5 -3
  50. package/dist/core/index.js +5 -2
  51. package/dist/error/index.d.ts +54 -0
  52. package/dist/error/index.js +8 -0
  53. package/dist/error/index.js.map +1 -0
  54. package/dist/index.d.ts +100 -12
  55. package/dist/index.js +148 -38
  56. package/dist/index.native.d.ts +20 -10
  57. package/dist/index.native.js +148 -39
  58. package/dist/index.web.d.ts +20 -10
  59. package/dist/index.web.js +149 -39
  60. package/dist/maintenance/index.d.ts +118 -0
  61. package/dist/maintenance/index.js +17 -0
  62. package/dist/maintenance/index.js.map +1 -0
  63. package/dist/platform/index.d.ts +16 -1
  64. package/dist/platform/index.js +2 -0
  65. package/dist/platform/index.js.map +1 -1
  66. package/dist/platform/index.native.d.ts +2 -2
  67. package/dist/platform/index.native.js +2 -1
  68. package/dist/platform/index.web.d.ts +1 -1
  69. package/dist/platform/index.web.js +2 -1
  70. package/dist/pol-attachment-queue-C7YNXXhK.d.ts +676 -0
  71. package/dist/provider/index.d.ts +447 -21
  72. package/dist/provider/index.js +33 -13
  73. package/dist/storage/index.d.ts +6 -0
  74. package/dist/storage/index.js +28 -0
  75. package/dist/storage/index.js.map +1 -0
  76. package/dist/storage/index.native.d.ts +6 -0
  77. package/dist/storage/index.native.js +26 -0
  78. package/dist/storage/index.native.js.map +1 -0
  79. package/dist/storage/index.web.d.ts +6 -0
  80. package/dist/storage/index.web.js +26 -0
  81. package/dist/storage/index.web.js.map +1 -0
  82. package/dist/storage/upload/index.d.ts +55 -0
  83. package/dist/storage/upload/index.js +15 -0
  84. package/dist/storage/upload/index.js.map +1 -0
  85. package/dist/storage/upload/index.native.d.ts +57 -0
  86. package/dist/storage/upload/index.native.js +14 -0
  87. package/dist/storage/upload/index.native.js.map +1 -0
  88. package/dist/storage/upload/index.web.d.ts +5 -0
  89. package/dist/storage/upload/index.web.js +14 -0
  90. package/dist/storage/upload/index.web.js.map +1 -0
  91. package/dist/{index-l3iL9Jte.d.ts → supabase-connector-qLm-WHkM.d.ts} +90 -25
  92. package/dist/sync/index.d.ts +288 -23
  93. package/dist/sync/index.js +22 -10
  94. package/dist/types-BVacP54t.d.ts +52 -0
  95. package/dist/types-Bgvx7-E8.d.ts +187 -0
  96. package/dist/{types-afHtE1U_.d.ts → types-CDqWh56B.d.ts} +2 -0
  97. package/package.json +72 -2
  98. package/dist/chunk-32OLICZO.js +0 -1
  99. package/dist/chunk-3AYXHQ4W.js.map +0 -1
  100. package/dist/chunk-5FIMA26D.js +0 -1
  101. package/dist/chunk-62J2DPKX.js.map +0 -1
  102. package/dist/chunk-7EMDVIZX.js.map +0 -1
  103. package/dist/chunk-EJ23MXPQ.js.map +0 -1
  104. package/dist/chunk-FPTDATY5.js.map +0 -1
  105. package/dist/chunk-KCDG2MNP.js +0 -1431
  106. package/dist/chunk-KCDG2MNP.js.map +0 -1
  107. package/dist/chunk-OLHGI472.js +0 -1
  108. package/dist/chunk-PAFBKNL3.js +0 -99
  109. package/dist/chunk-PAFBKNL3.js.map +0 -1
  110. package/dist/chunk-R4YFWQ3Q.js.map +0 -1
  111. package/dist/chunk-V6LJ6MR2.js +0 -740
  112. package/dist/chunk-V6LJ6MR2.js.map +0 -1
  113. package/dist/chunk-VJCL2SWD.js +0 -1
  114. package/dist/failed-upload-store-C0cLxxPz.d.ts +0 -33
  115. /package/dist/{chunk-32OLICZO.js.map → chunk-DGUM43GV.js.map} +0 -0
  116. /package/dist/{chunk-5FIMA26D.js.map → chunk-GKF7TOMT.js.map} +0 -0
  117. /package/dist/{chunk-OLHGI472.js.map → chunk-KGSFAE5B.js.map} +0 -0
  118. /package/dist/{chunk-VJCL2SWD.js.map → chunk-LNL64IJZ.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/provider/PowerSyncProvider.tsx","../src/conflicts/conflict-bus.ts","../src/provider/OfflineDataProvider.tsx","../src/provider/ProviderBridge.tsx"],"sourcesContent":["/**\n * PowerSyncProvider Component for @pol-studios/powersync\n *\n * Main provider component that initializes and manages the PowerSync database,\n * connector, attachment queue, and all monitoring services.\n */\n\nimport React, { useEffect, useState, useRef, useMemo, useCallback } from 'react';\nimport type { Session } from '@supabase/supabase-js';\nimport type { AbstractPowerSyncDatabase, SyncStatus, ConnectionHealth, SyncMetrics, CrudEntry, FailedTransaction, CompletedTransaction, SyncMode } from '../core/types';\nimport { SupabaseConnector } from '../connector/supabase-connector';\nimport { extractEntityIds, extractTableNames, createSyncError } from '../core/errors';\nimport { PolAttachmentQueue, createPolAttachmentQueue } from '../attachments/pol-attachment-queue';\nimport { SyncStatusTracker } from '../sync/status-tracker';\nimport { MetricsCollector } from '../sync/metrics-collector';\nimport { HealthMonitor } from '../sync/health-monitor';\nimport { ConflictBus } from '../conflicts/conflict-bus';\nimport { PowerSyncContext, SyncStatusContext, ConnectionHealthContext, SyncMetricsContext, AttachmentQueueContext, ConnectionStatusContext, SyncActivityContext, PendingMutationsContext, FailedTransactionsContext, CompletedTransactionsContext, SyncModeContext } from './context';\nimport type { PowerSyncProviderProps, PowerSyncContextValue, SyncStatusContextValue, ConnectionHealthContextValue, SyncMetricsContextValue, ConnectionStatusContextValue, SyncActivityContextValue, PendingMutationsContextValue, FailedTransactionsContextValue, CompletedTransactionsContextValue, SyncModeContextValue } from './types';\nimport { DEFAULT_SYNC_STATUS, DEFAULT_CONNECTION_HEALTH, DEFAULT_SYNC_METRICS } from './types';\n\n/**\n * PowerSyncProvider initializes and manages the PowerSync database and related services.\n *\n * Features:\n * - Initializes PowerSync database using platform adapter\n * - Creates and manages SupabaseConnector\n * - Connects/disconnects based on auth state\n * - Tracks sync status and connection health\n * - Optionally initializes AttachmentQueue\n * - Provides all contexts to children\n * - Handles cleanup on unmount\n *\n * @example\n * ```tsx\n * import { PowerSyncProvider, usePowerSync, useSyncStatus } from '@pol-studios/powersync';\n *\n * function App() {\n * return (\n * <PowerSyncProvider\n * config={{\n * platform: createNativePlatformAdapter(logger),\n * schema: AppSchema,\n * powerSyncUrl: 'https://your-powersync.com',\n * supabaseClient: supabase,\n * }}\n * onReady={() => console.log('PowerSync ready!')}\n * onError={(err) => console.error('PowerSync error:', err)}\n * >\n * <MainApp />\n * </PowerSyncProvider>\n * );\n * }\n * ```\n */\nexport function PowerSyncProvider<TSchema = unknown>({\n config,\n children,\n onReady,\n onError,\n onSyncStatusChange\n}: PowerSyncProviderProps<TSchema>): React.ReactElement {\n const {\n platform,\n schema,\n powerSyncUrl,\n supabaseClient,\n dbFilename = 'powersync.db',\n connector: connectorConfig,\n attachments: attachmentConfig,\n sync: syncConfig\n } = config;\n const logger = platform.logger;\n\n // Merge sync config with defaults\n const mergedSyncConfig = {\n autoConnect: syncConfig?.autoConnect ?? true,\n syncInterval: syncConfig?.syncInterval ?? 0,\n enableHealthMonitoring: syncConfig?.enableHealthMonitoring ?? true,\n enableMetrics: syncConfig?.enableMetrics ?? true\n };\n\n // ─── State ─────────────────────────────────────────────────────────────────\n\n const [db, setDb] = useState<AbstractPowerSyncDatabase | null>(null);\n const [connector, setConnector] = useState<SupabaseConnector | null>(null);\n const [attachmentQueue, setAttachmentQueue] = useState<PolAttachmentQueue | null>(null);\n const [isReady, setIsReady] = useState(false);\n const [isInitializing, setIsInitializing] = useState(true);\n // Track whether the attachment queue has finished initializing\n // True if: (1) attachments not configured, or (2) queue successfully initialized\n const [attachmentQueueReady, setAttachmentQueueReady] = useState(!attachmentConfig);\n const [error, setError] = useState<Error | null>(null);\n const [session, setSession] = useState<Session | null>(null);\n\n // Conflict bus - created once and stable for the lifetime of the provider\n const conflictBusRef = useRef<ConflictBus | null>(null);\n if (!conflictBusRef.current) {\n conflictBusRef.current = new ConflictBus();\n }\n const conflictBus = conflictBusRef.current;\n\n // Sync status state\n const [syncStatus, setSyncStatus] = useState<SyncStatus>(DEFAULT_SYNC_STATUS);\n const [pendingMutations, setPendingMutations] = useState<CrudEntry[]>([]);\n // Combined sync mode state to ensure atomic updates and prevent React batching issues\n const [syncModeState, setSyncModeState] = useState<{\n loaded: boolean;\n mode: SyncMode;\n }>({\n loaded: false,\n mode: 'push-pull'\n });\n const [lastSyncedAt, setLastSyncedAt] = useState<Date | null>(null);\n const [connectionError, setConnectionError] = useState<Error | null>(null);\n const [failedTransactions, setFailedTransactions] = useState<FailedTransaction[]>([]);\n const [completedTransactions, setCompletedTransactions] = useState<CompletedTransaction[]>([]);\n // Track \"new\" completed transactions (since last notification display) for toast/banner notifications\n const [newCompletedTransactions, setNewCompletedTransactions] = useState<CompletedTransaction[]>([]);\n\n // Health and metrics state\n const [connectionHealth, setConnectionHealth] = useState<ConnectionHealth>(DEFAULT_CONNECTION_HEALTH);\n const [syncMetrics, setSyncMetrics] = useState<SyncMetrics>(DEFAULT_SYNC_METRICS);\n\n // Auto-offline state: tracks whether offline mode was set automatically due to network loss\n // When true, sync will auto-resume when network returns\n // When false (user manually chose offline), sync won't auto-resume\n const [isAutoOffline, setIsAutoOffline] = useState(false);\n\n // Network reachability state: tracks whether network is currently reachable\n // This is used as a gate to block uploads even when syncMode is 'push-pull'\n const [networkReachable, setNetworkReachable] = useState(true);\n\n // ─── Refs ──────────────────────────────────────────────────────────────────\n\n const statusTrackerRef = useRef<SyncStatusTracker | null>(null);\n const metricsCollectorRef = useRef<MetricsCollector | null>(null);\n const healthMonitorRef = useRef<HealthMonitor | null>(null);\n const attachmentQueueRef = useRef<PolAttachmentQueue | null>(null);\n const listenerUnsubscribeRef = useRef<(() => void) | null>(null);\n const wasSyncingRef = useRef(false);\n const wasUploadingRef = useRef(false);\n const initializingRef = useRef(false);\n // Track when database is being/has been closed to prevent operations on closed db\n const dbClosedRef = useRef(false);\n // Store connector to clean up on recreation\n const connectorRef = useRef<SupabaseConnector | null>(null);\n // Track cleanup promise to prevent re-initialization during cleanup\n const cleanupPromiseRef = useRef<Promise<void> | null>(null);\n const isCleaningUpRef = useRef(false);\n // Track previous network state for auto-offline detection\n const prevNetworkConnectedRef = useRef<boolean | null>(null);\n // Track if auto-offline handling is initialized (to avoid setting offline on initial false network check)\n const autoOfflineInitializedRef = useRef(false);\n // Refs to avoid stale closures in network listener when checking auto-offline conditions\n const isAutoOfflineRef = useRef(false);\n const syncModeRef = useRef<SyncMode>('push-pull');\n // Ref for removePendingMutation to avoid stale closures in connector callback\n const removePendingMutationRef = useRef<(id: string) => void>(() => {});\n\n // Callback refs - prevents unnecessary effect re-runs when parent passes inline functions\n const onSyncStatusChangeRef = useRef(onSyncStatusChange);\n const onReadyRef = useRef(onReady);\n const onErrorRef = useRef(onError);\n\n // Keep callback refs updated\n useEffect(() => {\n onSyncStatusChangeRef.current = onSyncStatusChange;\n }, [onSyncStatusChange]);\n useEffect(() => {\n onReadyRef.current = onReady;\n }, [onReady]);\n useEffect(() => {\n onErrorRef.current = onError;\n }, [onError]);\n\n // Keep auto-offline and sync mode refs updated to avoid stale closures in network listener\n useEffect(() => {\n isAutoOfflineRef.current = isAutoOffline;\n syncModeRef.current = syncModeState.mode;\n }, [isAutoOffline, syncModeState.mode]);\n\n // ─── Initialize Monitoring Services ────────────────────────────────────────\n\n useEffect(() => {\n // Create status tracker\n const statusTracker = new SyncStatusTracker(platform.storage, logger, {\n onStatusChange: status => {\n setSyncStatus(status);\n setLastSyncedAt(status.lastSyncedAt);\n onSyncStatusChangeRef.current?.(status);\n }\n });\n statusTrackerRef.current = statusTracker;\n\n // Create metrics collector\n const metricsCollector = new MetricsCollector(platform.storage, logger, {\n onMetricsChange: setSyncMetrics\n });\n metricsCollectorRef.current = metricsCollector;\n\n // Create health monitor\n const healthMonitor = new HealthMonitor(logger, {\n onHealthChange: setConnectionHealth\n });\n healthMonitorRef.current = healthMonitor;\n\n // Initialize async with timeout fallback\n const initPromise = Promise.all([statusTracker.init(), metricsCollector.init()]);\n const timeoutPromise = new Promise<[void, void]>(resolve => {\n setTimeout(() => {\n logger.warn('[PowerSyncProvider] Sync mode state load timed out, using default (push-pull)');\n resolve([undefined, undefined]);\n }, 5000); // 5 second timeout\n });\n Promise.race([initPromise, timeoutPromise]).then(() => {\n const loadedMode = statusTracker.getSyncMode();\n const loadedIsAutoOffline = statusTracker.getIsAutoOffline();\n logger.info('[PowerSyncProvider] Sync mode state loaded:', {\n mode: loadedMode,\n isAutoOffline: loadedIsAutoOffline\n });\n // Use single state update to ensure atomic change and prevent React batching issues\n setSyncModeState({\n loaded: true,\n mode: loadedMode\n });\n // Load persisted auto-offline flag so auto-restore works after app restart\n setIsAutoOffline(loadedIsAutoOffline);\n // Load initial completed transactions from storage\n setCompletedTransactions(statusTracker.getCompletedTransactions());\n // newCompletedTransactions starts empty since lastNotificationTime is Date.now() on init\n setNewCompletedTransactions(statusTracker.getNewCompletedTransactions());\n // Load initial failed transactions from storage\n setFailedTransactions(statusTracker.getFailedTransactions());\n });\n\n // Cleanup\n return () => {\n statusTracker.dispose();\n metricsCollector.dispose();\n healthMonitor.dispose();\n };\n }, [platform, logger]);\n\n // ─── Auth State Listener ───────────────────────────────────────────────────\n\n useEffect(() => {\n logger.debug('[PowerSyncProvider] Setting up auth listener');\n\n // Get initial session\n supabaseClient.auth.getSession().then(({\n data: {\n session: initialSession\n }\n }) => {\n logger.debug('[PowerSyncProvider] Initial session:', !!initialSession);\n setSession(initialSession);\n });\n\n // Listen for auth changes\n const {\n data: {\n subscription\n }\n } = supabaseClient.auth.onAuthStateChange((_event, newSession) => {\n logger.debug('[PowerSyncProvider] Auth state changed, hasSession:', !!newSession);\n setSession(newSession);\n });\n return () => {\n subscription.unsubscribe();\n };\n }, [supabaseClient, logger]);\n\n // ─── Database Initialization ───────────────────────────────────────────────\n\n useEffect(() => {\n // Guard against StrictMode double-mounting\n // The ref persists across the quick unmount/remount cycle\n if (initializingRef.current) {\n logger.debug('[PowerSyncProvider] Already initializing, skipping...');\n return;\n }\n initializingRef.current = true;\n\n // Use a controller object to track cancellation\n const controller = {\n cancelled: false\n };\n const initDatabase = async () => {\n try {\n // Wait for any pending cleanup to complete before initializing\n // This prevents \"database is locked\" errors during StrictMode double-mount\n if (cleanupPromiseRef.current) {\n logger.debug('[PowerSyncProvider] Waiting for cleanup to complete...');\n await cleanupPromiseRef.current;\n if (controller.cancelled) {\n initializingRef.current = false;\n return;\n }\n logger.debug('[PowerSyncProvider] Cleanup complete, proceeding with init');\n }\n\n // Reset cleanup state for fresh initialization\n dbClosedRef.current = false;\n logger.info('[PowerSyncProvider] Initializing database...');\n\n // Create database using platform adapter (includes init())\n const database = await platform.createDatabase({\n dbFilename,\n schema\n });\n\n // Check if cancelled during async operation\n if (controller.cancelled) {\n logger.debug('[PowerSyncProvider] Init cancelled, closing database...');\n await database.close();\n initializingRef.current = false;\n return;\n }\n logger.info('[PowerSyncProvider] Database initialized');\n setDb(database);\n setIsReady(true);\n setIsInitializing(false);\n\n // Set database on health monitor\n healthMonitorRef.current?.setDatabase(database);\n\n // Start health monitoring if enabled\n if (mergedSyncConfig.enableHealthMonitoring) {\n healthMonitorRef.current?.start();\n }\n onReadyRef.current?.();\n } catch (err) {\n const initError = err instanceof Error ? err : new Error(String(err));\n logger.error('[PowerSyncProvider] Initialization failed:', initError);\n\n // Only update state if not cancelled\n if (!controller.cancelled) {\n setError(initError);\n setIsInitializing(false);\n onErrorRef.current?.(initError);\n }\n\n // Reset ref on error so retry is possible\n initializingRef.current = false;\n }\n };\n initDatabase();\n return () => {\n // Mark as cancelled - the async operation will check this\n controller.cancelled = true;\n // Reset initializingRef so StrictMode double-mount can reinitialize\n initializingRef.current = false;\n };\n }, [platform, dbFilename, schema, logger, mergedSyncConfig.enableHealthMonitoring]);\n\n // ─── Connect to PowerSync ──────────────────────────────────────────────────\n\n useEffect(() => {\n // Console.log fallback for critical diagnostic point (always visible regardless of logger level)\n if (__DEV__) {\n console.log('[PowerSyncProvider] Connect effect triggered:', {\n hasDb: !!db,\n hasSession: !!session,\n autoConnect: mergedSyncConfig.autoConnect,\n syncModeState\n });\n }\n\n // Use info level for critical connect path so it always appears\n logger.info('[PowerSyncProvider] Connect effect - db:', !!db, 'session:', !!session, 'autoConnect:', mergedSyncConfig.autoConnect, 'syncModeLoaded:', syncModeState.loaded, 'syncMode:', syncModeState.mode);\n\n // Individual checks with logging for each early return condition\n if (!db) {\n logger.debug('[PowerSyncProvider] Connect effect - waiting for db');\n return;\n }\n if (!session) {\n logger.debug('[PowerSyncProvider] Connect effect - no session');\n return;\n }\n if (!mergedSyncConfig.autoConnect) {\n logger.debug('[PowerSyncProvider] Connect effect - autoConnect disabled');\n return;\n }\n\n // Wait for sync mode state to be loaded before deciding\n if (!syncModeState.loaded) {\n logger.info('[PowerSyncProvider] Waiting for sync mode state to load...');\n return;\n }\n\n // Skip connect if offline mode\n if (syncModeState.mode === 'offline') {\n logger.debug('[PowerSyncProvider] Skipping connect - offline mode');\n return;\n }\n\n // Create abort controller to handle sync mode changes during connect\n // This prevents race conditions when mode changes while connection is in progress\n const abortController = new AbortController();\n const connectPowerSync = async () => {\n try {\n // Check if aborted before starting work\n if (abortController.signal.aborted) {\n logger.debug('[PowerSyncProvider] Connect aborted before start');\n return;\n }\n setConnectionError(null);\n\n // Destroy previous connector to clean up listeners and mark as destroyed\n // This sets isDestroyed flag on the old connector to prevent active uploads\n // from continuing with stale connector state\n if (connectorRef.current) {\n connectorRef.current.destroy();\n connectorRef.current = null;\n }\n\n // Check if aborted after destroying previous connector\n if (abortController.signal.aborted) {\n logger.debug('[PowerSyncProvider] Connect aborted after connector cleanup');\n return;\n }\n\n // Create connector with failure callbacks\n const statusTracker_0 = statusTrackerRef.current;\n const newConnector = new SupabaseConnector({\n supabaseClient,\n powerSyncUrl,\n schemaRouter: connectorConfig?.schemaRouter,\n crudHandler: connectorConfig?.crudHandler,\n retryConfig: connectorConfig?.retryConfig,\n logger,\n // Conflict detection - enabled by default\n conflictDetection: {\n enabled: true\n },\n conflictBus,\n // Check if uploads should be performed based on sync mode\n shouldUpload: () => statusTrackerRef.current?.shouldUpload() ?? true,\n // Clear failures when transaction succeeds\n onTransactionSuccess: entries => {\n if (!statusTracker_0) return;\n const entityIds = extractEntityIds(entries);\n entityIds.forEach(id => {\n // Find and clear failures affecting this entity\n const failures = statusTracker_0.getFailuresForEntity(id);\n failures.forEach(f => statusTracker_0.clearFailure(f.id));\n });\n // Update local state\n setFailedTransactions(statusTracker_0.getFailedTransactions());\n },\n // Record failures when transaction fails\n onTransactionFailure: (entries_0, error_0, classified) => {\n if (!statusTracker_0) return;\n statusTracker_0.recordTransactionFailure(entries_0, createSyncError(classified, error_0.message), classified.isPermanent, extractEntityIds(entries_0), extractTableNames(entries_0));\n // Update local state\n setFailedTransactions(statusTracker_0.getFailedTransactions());\n },\n // Record completed transactions\n onTransactionComplete: entries_1 => {\n if (!statusTracker_0) return;\n statusTracker_0.recordTransactionComplete(entries_1);\n // Update local state\n setCompletedTransactions(statusTracker_0.getCompletedTransactions());\n setNewCompletedTransactions(statusTracker_0.getNewCompletedTransactions());\n }\n });\n\n // Check if aborted after creating connector but before using it\n if (abortController.signal.aborted) {\n logger.debug('[PowerSyncProvider] Connect aborted after connector creation, destroying new connector');\n newConnector.destroy();\n return;\n }\n setConnector(newConnector);\n connectorRef.current = newConnector;\n\n // Check if already connected\n if (db.connected) {\n logger.debug('[PowerSyncProvider] Already connected, reconnecting...');\n await db.disconnect();\n }\n\n // Check if aborted after disconnect\n if (abortController.signal.aborted) {\n logger.debug('[PowerSyncProvider] Connect aborted after disconnect');\n return;\n }\n logger.info('[PowerSyncProvider] Connecting to PowerSync...');\n await db.connect(newConnector);\n\n // Check if aborted after connect - if so, don't update state\n if (abortController.signal.aborted) {\n logger.debug('[PowerSyncProvider] Connect aborted after connection established');\n return;\n }\n\n // Verify actual connection status\n if (db.connected) {\n logger.info('[PowerSyncProvider] Connected successfully');\n // Reset reconnect attempts on successful connection\n healthMonitorRef.current?.resetReconnectAttempts();\n } else {\n logger.warn('[PowerSyncProvider] Connection initiated but streaming not established - check PowerSync URL');\n }\n } catch (err_0) {\n // Ignore errors if aborted\n if (abortController.signal.aborted) {\n logger.debug('[PowerSyncProvider] Connect error ignored due to abort');\n return;\n }\n const connectError = err_0 instanceof Error ? err_0 : new Error(String(err_0));\n logger.error('[PowerSyncProvider] Connection failed:', connectError);\n setConnectionError(connectError);\n healthMonitorRef.current?.recordReconnectAttempt();\n }\n };\n connectPowerSync();\n\n // Cleanup: abort any in-progress connection when effect re-runs or unmounts\n return () => {\n abortController.abort();\n };\n }, [db, session, powerSyncUrl, supabaseClient, connectorConfig, conflictBus, mergedSyncConfig.autoConnect, syncModeState, logger]);\n\n // ─── Status Listener ───────────────────────────────────────────────────────\n\n useEffect(() => {\n if (!db) return;\n\n // Set initial status\n const initialStatus = db.currentStatus;\n if (initialStatus) {\n statusTrackerRef.current?.handleStatusChange(initialStatus);\n }\n\n // Register listener\n const unsubscribe = db.registerListener({\n statusChanged: status_0 => {\n statusTrackerRef.current?.handleStatusChange(status_0 as Record<string, unknown>);\n\n // Track sync timing for metrics\n const dataFlow = (status_0 as Record<string, unknown>).dataFlowStatus as Record<string, boolean> | undefined;\n const isDownloading = dataFlow?.downloading ?? false;\n const isUploading = dataFlow?.uploading ?? false;\n const progress = (status_0 as Record<string, unknown>).downloadProgress as Record<string, number> | undefined;\n\n // Log download state changes\n if (isDownloading && !wasSyncingRef.current) {\n logger.info('[PowerSyncProvider] Downloading from server...');\n metricsCollectorRef.current?.markSyncStart();\n }\n if (!isDownloading && wasSyncingRef.current) {\n const duration = metricsCollectorRef.current?.markSyncEnd();\n logger.info('[PowerSyncProvider] Download complete', duration ? `(${duration}ms)` : '');\n if (duration !== null && duration !== undefined) {\n metricsCollectorRef.current?.recordSync({\n durationMs: duration,\n success: true,\n operationsDownloaded: progress?.totalOperations ?? 0\n });\n }\n }\n\n // Log upload state changes\n if (isUploading && !wasUploadingRef.current) {\n logger.info('[PowerSyncProvider] Uploading local changes...');\n }\n if (!isUploading && wasUploadingRef.current) {\n logger.info('[PowerSyncProvider] Upload complete');\n }\n wasSyncingRef.current = isDownloading;\n wasUploadingRef.current = isUploading;\n }\n });\n listenerUnsubscribeRef.current = unsubscribe;\n return () => {\n unsubscribe();\n listenerUnsubscribeRef.current = null;\n };\n }, [db]);\n\n // ─── Pending Mutations Management ─────────────────────────────────────────\n // hydratePendingMutations: Called once on startup to recover unsynced mutations\n // addPendingMutation: Called by mutation hooks after writes\n // removePendingMutation: Called when transactions complete sync\n\n const hydratePendingMutations = useCallback(async () => {\n if (!db || dbClosedRef.current) {\n return;\n }\n try {\n // Read ALL pending mutations (no limit) for full hydration on startup\n const rows = await db.getAll<{\n id: string;\n tx_id: number | null;\n data: string;\n }>('SELECT id, tx_id, data FROM ps_crud ORDER BY id ASC');\n const mutations: CrudEntry[] = rows.map((row): CrudEntry | null => {\n try {\n const parsed = JSON.parse(row.data);\n\n // Extract timestamp from _metadata if available\n let createdAt = new Date(); // fallback\n if (parsed.data?._metadata) {\n try {\n const metadata = typeof parsed.data._metadata === 'string' ? JSON.parse(parsed.data._metadata) : parsed.data._metadata;\n if (metadata?.createdAt) {\n createdAt = new Date(metadata.createdAt);\n }\n } catch {\n // Use fallback if metadata parsing fails\n }\n }\n return {\n id: parsed.data?.id ?? parsed.id ?? row.id,\n clientId: parseInt(row.id, 10) || 0,\n op: parsed.op ?? 'PUT',\n table: parsed.type ?? 'unknown',\n opData: parsed.data,\n transactionId: row.tx_id ?? undefined,\n createdAt\n };\n } catch {\n return null;\n }\n }).filter((e): e is CrudEntry => e !== null);\n if (!dbClosedRef.current) {\n statusTrackerRef.current?.updatePendingMutations(mutations);\n setPendingMutations(mutations);\n }\n } catch {\n // Ignore errors during shutdown\n }\n }, [db]);\n\n // Add a single mutation (called by hooks after successful writes)\n const addPendingMutation = useCallback((entry: CrudEntry) => {\n const entryWithTimestamp = {\n ...entry,\n createdAt: entry.createdAt ?? new Date()\n };\n setPendingMutations(prev => {\n const newMutations = [...prev, entryWithTimestamp];\n statusTrackerRef.current?.updatePendingMutations(newMutations);\n return newMutations;\n });\n }, []);\n\n // Remove a mutation when synced (called from onTransactionComplete)\n const removePendingMutation = useCallback((id_0: string) => {\n setPendingMutations(prev_0 => {\n const newMutations_0 = prev_0.filter(m => m.id !== id_0);\n statusTrackerRef.current?.updatePendingMutations(newMutations_0);\n return newMutations_0;\n });\n }, []);\n\n // Keep ref updated for connector callback\n useEffect(() => {\n removePendingMutationRef.current = removePendingMutation;\n }, [removePendingMutation]);\n\n // ─── Hydrate Pending Mutations on Startup ─────────────────────────────────\n // Only called once when db becomes available to recover unsynced mutations from previous session\n\n useEffect(() => {\n if (!db) return;\n\n // Reset closed flag when db becomes available (fixes race condition with cleanup effect)\n dbClosedRef.current = false;\n\n // Hydrate pending mutations from ps_crud (once on startup only)\n hydratePendingMutations();\n\n // No listener for statusChanged - mutations are now added directly by hooks\n }, [db, hydratePendingMutations]);\n\n // ─── Attachment Queue Initialization ───────────────────────────────────────\n\n useEffect(() => {\n if (!db || !attachmentConfig || attachmentQueueRef.current) {\n return;\n }\n\n // Cancellation controller to prevent setting state after unmount/re-render\n const controller_0 = {\n cancelled: false\n };\n const initAttachmentQueue = async () => {\n try {\n logger.info('[PowerSyncProvider] Initializing attachment queue...');\n\n // Create PolAttachmentQueue (extends AbstractAttachmentQueue from @powersync/attachments)\n const queue = createPolAttachmentQueue(db as any,\n // PowerSync DB instance\n platform, attachmentConfig);\n await queue.init();\n\n // Check if cancelled during async init\n if (controller_0.cancelled) {\n queue.dispose();\n return;\n }\n attachmentQueueRef.current = queue;\n setAttachmentQueue(queue);\n setAttachmentQueueReady(true);\n logger.info('[PowerSyncProvider] Attachment queue initialized successfully');\n } catch (err_1) {\n // Only update state if not cancelled\n if (!controller_0.cancelled) {\n logger.error('[PowerSyncProvider] Attachment queue initialization failed:', err_1);\n // Even on failure, mark as \"ready\" so consumers aren't stuck waiting forever\n // They will see attachmentQueue as null and can handle accordingly\n setAttachmentQueueReady(true);\n }\n }\n };\n initAttachmentQueue();\n return () => {\n controller_0.cancelled = true;\n attachmentQueueRef.current?.dispose();\n attachmentQueueRef.current = null;\n // Reset to false on cleanup - the effect will set the correct initial value on re-run\n setAttachmentQueueReady(false);\n };\n }, [db, attachmentConfig, platform, logger]);\n\n // ─── Cleanup ─────────────────────────────────────────────────────────────────\n\n useEffect(() => {\n // Only run cleanup on unmount\n return () => {\n // Prevent multiple concurrent cleanups\n if (isCleaningUpRef.current) {\n logger.debug('[PowerSyncProvider] Cleanup already in progress, skipping...');\n return;\n }\n logger.info('[PowerSyncProvider] Cleaning up...');\n isCleaningUpRef.current = true;\n\n // Mark database as closed FIRST to prevent any pending operations\n dbClosedRef.current = true;\n\n // Destroy connector to clean up event listeners\n connectorRef.current?.destroy();\n connectorRef.current = null;\n listenerUnsubscribeRef.current?.();\n attachmentQueueRef.current?.dispose();\n healthMonitorRef.current?.stop();\n conflictBusRef.current?.destroy();\n if (db) {\n // Track cleanup promise so initialization can wait for it\n cleanupPromiseRef.current = (async () => {\n try {\n await db.disconnect();\n await db.close();\n logger.debug('[PowerSyncProvider] Database cleanup completed');\n } catch (err_2) {\n // Only log if it's not a \"database already closed\" error\n const errorMessage = err_2 instanceof Error ? err_2.message : String(err_2);\n if (!errorMessage.includes('not open') && !errorMessage.includes('closed')) {\n logger.warn('[PowerSyncProvider] Error during cleanup:', err_2);\n }\n } finally {\n isCleaningUpRef.current = false;\n cleanupPromiseRef.current = null;\n }\n })();\n } else {\n isCleaningUpRef.current = false;\n }\n };\n }, [db, logger]);\n\n // ─── Auto-Offline Network Listener ─────────────────────────────────────────\n // Automatically switch to offline mode when network is lost,\n // and auto-resume when network returns (unless user manually chose offline)\n\n useEffect(() => {\n // Skip if not ready or sync mode not loaded yet\n if (!isReady || !syncModeState.loaded) return;\n const handleNetworkChange = async (isConnected: boolean) => {\n const wasConnected = prevNetworkConnectedRef.current;\n prevNetworkConnectedRef.current = isConnected;\n\n // Update network reachability gate on the status tracker\n // This instantly blocks/allows uploads without changing sync mode\n const tracker = statusTrackerRef.current;\n if (tracker) {\n tracker.setNetworkReachable(isConnected);\n }\n // Also update React state for UI components\n setNetworkReachable(isConnected);\n\n // Initialize on first call - don't auto-offline on startup\n if (!autoOfflineInitializedRef.current) {\n autoOfflineInitializedRef.current = true;\n logger.debug('[PowerSyncProvider] Auto-offline initialized, network:', isConnected);\n return;\n }\n\n // Network lost: auto-enter offline mode\n if (wasConnected === true && !isConnected) {\n logger.info('[PowerSyncProvider] Network lost - auto-entering offline mode');\n const tracker_0 = statusTrackerRef.current;\n if (tracker_0) {\n // Persist auto-offline flag so it survives app restart\n await tracker_0.setIsAutoOffline(true);\n setIsAutoOffline(true);\n await tracker_0.setSyncMode('offline');\n setSyncModeState({\n loaded: true,\n mode: 'offline'\n });\n }\n return;\n }\n\n // Network restored: auto-resume sync (only if we auto-set offline, not user-set)\n if (wasConnected === false && isConnected) {\n // Only auto-resume if we auto-set offline mode (use refs to avoid stale closures)\n if (isAutoOfflineRef.current && syncModeRef.current === 'offline') {\n logger.info('[PowerSyncProvider] Network restored - auto-resuming sync');\n const tracker_1 = statusTrackerRef.current;\n if (tracker_1) {\n // Clear persisted auto-offline flag\n await tracker_1.setIsAutoOffline(false);\n setIsAutoOffline(false);\n await tracker_1.setSyncMode('push-pull');\n setSyncModeState({\n loaded: true,\n mode: 'push-pull'\n });\n\n // Reconnect if we have a connector and db\n if (db && connector && !db.connected) {\n try {\n await db.connect(connector);\n logger.info('[PowerSyncProvider] Reconnected after network restore');\n } catch (err_3) {\n logger.warn('[PowerSyncProvider] Failed to reconnect after network restore:', err_3);\n }\n }\n }\n } else {\n logger.debug('[PowerSyncProvider] Network restored but not auto-resuming (manual offline or different mode)');\n }\n }\n };\n\n // Subscribe to network changes\n const unsubscribe_0 = platform.network.addConnectionListener(handleNetworkChange);\n\n // Get initial network state\n platform.network.isConnected().then(connected => {\n prevNetworkConnectedRef.current = connected;\n autoOfflineInitializedRef.current = true;\n // Set initial network reachability\n const tracker_2 = statusTrackerRef.current;\n if (tracker_2) {\n tracker_2.setNetworkReachable(connected);\n }\n setNetworkReachable(connected);\n\n // Edge case: On app restart with isAutoOffline=true and syncMode='offline',\n // network listener initializes with network already available.\n // No transition (false→true) happens, so auto-resume path never triggers.\n // Check immediately if we should auto-resume.\n if (connected && isAutoOfflineRef.current && syncModeRef.current === 'offline') {\n logger.info('[PowerSyncProvider] Network available on startup with auto-offline active, auto-resuming from offline');\n if (tracker_2) {\n tracker_2.setIsAutoOffline(false);\n setIsAutoOffline(false);\n tracker_2.setSyncMode('push-pull');\n setSyncModeState({\n loaded: true,\n mode: 'push-pull'\n });\n\n // Reconnect if we have a connector and db\n if (db && connector && !db.connected) {\n db.connect(connector).then(() => {\n logger.info('[PowerSyncProvider] Reconnected after auto-resume on startup');\n }).catch(err_4 => {\n logger.warn('[PowerSyncProvider] Failed to reconnect after auto-resume on startup:', err_4);\n });\n }\n }\n }\n logger.debug('[PowerSyncProvider] Auto-offline ready, initial network:', connected);\n });\n return () => {\n unsubscribe_0();\n };\n }, [isReady, syncModeState.loaded, syncModeState.mode, isAutoOffline, db, connector, platform, logger]);\n\n // ─── Clear Failure Functions ────────────────────────────────────────────────\n\n const clearFailure = useCallback((failureId: string) => {\n const tracker_3 = statusTrackerRef.current;\n if (!tracker_3) {\n logger.warn('[PowerSyncProvider] Cannot clear failure - tracker not initialized');\n return;\n }\n tracker_3.clearFailure(failureId);\n setFailedTransactions(tracker_3.getFailedTransactions());\n }, [logger]);\n const clearAllFailures = useCallback(() => {\n const tracker_4 = statusTrackerRef.current;\n if (!tracker_4) {\n logger.warn('[PowerSyncProvider] Cannot clear failures - tracker not initialized');\n return;\n }\n tracker_4.clearAllFailures();\n setFailedTransactions(tracker_4.getFailedTransactions());\n }, [logger]);\n const clearCompletedHistory = useCallback(() => {\n const tracker_5 = statusTrackerRef.current;\n if (!tracker_5) {\n logger.warn('[PowerSyncProvider] Cannot clear completed history - tracker not initialized');\n return;\n }\n tracker_5.clearCompletedHistory();\n setCompletedTransactions(tracker_5.getCompletedTransactions());\n setNewCompletedTransactions(tracker_5.getNewCompletedTransactions());\n }, [logger]);\n const clearCompletedItem = useCallback((completedId: string) => {\n const tracker_6 = statusTrackerRef.current;\n if (!tracker_6) {\n logger.warn('[PowerSyncProvider] Cannot clear completed item - tracker not initialized');\n return;\n }\n tracker_6.clearCompletedItem(completedId);\n setCompletedTransactions(tracker_6.getCompletedTransactions());\n setNewCompletedTransactions(tracker_6.getNewCompletedTransactions());\n }, [logger]);\n const markNotificationsAsSeen = useCallback(() => {\n const tracker_7 = statusTrackerRef.current;\n if (!tracker_7) {\n logger.warn('[PowerSyncProvider] Cannot mark notifications as seen - tracker not initialized');\n return;\n }\n tracker_7.markNotificationsAsSeen();\n setNewCompletedTransactions(tracker_7.getNewCompletedTransactions());\n }, [logger]);\n const setSyncMode = useCallback(async (mode: SyncMode) => {\n const tracker_8 = statusTrackerRef.current;\n if (!tracker_8) {\n logger.warn('[PowerSyncProvider] Cannot set sync mode - tracker not initialized');\n return;\n }\n // Clear auto-offline flag when user manually sets sync mode\n // This ensures manual offline choice won't be auto-resumed\n // Persist the change so it survives app restart\n await tracker_8.setIsAutoOffline(false);\n setIsAutoOffline(false);\n await tracker_8.setSyncMode(mode);\n setSyncModeState({\n loaded: true,\n mode\n });\n }, [logger]);\n const setForceNextUpload = useCallback((force: boolean) => {\n const tracker_9 = statusTrackerRef.current;\n if (!tracker_9) {\n logger.warn('[PowerSyncProvider] Cannot set force upload - tracker not initialized');\n return;\n }\n tracker_9.setForceNextUpload(force);\n }, [logger]);\n\n // Internal function for auto-offline mode changes (sets isAutoOffline flag)\n const setAutoOfflineMode = useCallback(async (mode_0: SyncMode, isAuto: boolean) => {\n const tracker_10 = statusTrackerRef.current;\n if (!tracker_10) {\n logger.warn('[PowerSyncProvider] Cannot set sync mode - tracker not initialized');\n return;\n }\n // Persist the auto-offline flag so it survives app restart\n await tracker_10.setIsAutoOffline(isAuto);\n setIsAutoOffline(isAuto);\n await tracker_10.setSyncMode(mode_0);\n setSyncModeState({\n loaded: true,\n mode: mode_0\n });\n }, [logger]);\n\n // ─── Discard Mutation Functions ────────────────────────────────────────────\n\n const discardPendingMutation = useCallback(async (clientId: number) => {\n if (!db || !connector) {\n logger.warn('[PowerSync] Cannot discard - not initialized');\n return;\n }\n if (syncStatus.uploading) {\n throw new Error('Cannot discard while upload is in progress');\n }\n logger.info('[PowerSync] Discarding pending mutation:', clientId);\n\n // Disconnect to ensure no active transaction\n await db.disconnect();\n try {\n await db.execute('DELETE FROM ps_crud WHERE id = ?', [clientId]);\n logger.info('[PowerSync] Mutation discarded successfully');\n } finally {\n // Use connectorRef.current to avoid stale connector in finally block\n const currentConnector = connectorRef.current;\n if (currentConnector && db) {\n try {\n await db.connect(currentConnector);\n } catch (reconnectError) {\n logger.error('[PowerSync] Failed to reconnect after discard:', reconnectError);\n // Surface the error - don't silently fail\n throw reconnectError;\n }\n }\n }\n }, [db, connector, syncStatus.uploading, logger]);\n const discardAllPendingMutations = useCallback(async () => {\n if (!db || !connector) {\n logger.warn('[PowerSync] Cannot discard all - not initialized');\n return;\n }\n if (syncStatus.uploading) {\n throw new Error('Cannot discard while upload is in progress');\n }\n logger.info('[PowerSync] Discarding all pending mutations');\n await db.disconnect();\n try {\n await db.execute('DELETE FROM ps_crud');\n logger.info('[PowerSync] All mutations discarded successfully');\n } finally {\n // Use connectorRef.current to avoid stale connector in finally block\n const currentConnector = connectorRef.current;\n if (currentConnector && db) {\n try {\n await db.connect(currentConnector);\n } catch (reconnectError) {\n logger.error('[PowerSync] Failed to reconnect after discard:', reconnectError);\n // Surface the error - don't silently fail\n throw reconnectError;\n }\n }\n }\n }, [db, connector, syncStatus.uploading, logger]);\n\n // ─── Retry Control Functions ──────────────────────────────────────────────\n\n const pauseAutoRetry = useCallback(() => {\n if (!connector) {\n logger.warn('[PowerSyncProvider] Cannot pause auto-retry - connector not initialized');\n return;\n }\n connector.pauseAutoRetry();\n }, [connector, logger]);\n const resumeAutoRetry = useCallback(() => {\n if (!connector) {\n logger.warn('[PowerSyncProvider] Cannot resume auto-retry - connector not initialized');\n return;\n }\n connector.resumeAutoRetry();\n }, [connector, logger]);\n const retryFailure = useCallback(async (failureId_0: string) => {\n const tracker_11 = statusTrackerRef.current;\n if (!tracker_11) return;\n\n // Get the failure first (before removing) to preserve the error info\n const failures_0 = tracker_11.getFailedTransactions();\n const failure = failures_0.find(f_0 => f_0.id === failureId_0);\n if (!failure) {\n logger.warn('[PowerSyncProvider] Failure not found:', failureId_0);\n return;\n }\n\n // Remove from tracking (entries stay in ps_crud for retry)\n const entries_2 = tracker_11.takeFailureForRetry(failureId_0);\n if (!entries_2 || entries_2.length === 0) return;\n\n // Update local state\n setFailedTransactions(tracker_11.getFailedTransactions());\n\n // Trigger a sync to pick up pending items\n if (!db || !connector) {\n logger.warn('[PowerSyncProvider] Cannot retry - not initialized');\n // Re-record the failure since we can't sync\n tracker_11.recordTransactionFailure(failure.entries, failure.error, failure.isPermanent, failure.affectedEntityIds, failure.affectedTables, {\n retryCount: failure.retryCount,\n firstFailedAt: failure.firstFailedAt\n });\n setFailedTransactions(tracker_11.getFailedTransactions());\n return;\n }\n try {\n // Disconnect and reconnect to force a fresh sync\n if (db.connected) {\n await db.disconnect();\n }\n await db.connect(connector);\n logger.info('[PowerSyncProvider] Retry triggered for failure:', failureId_0);\n } catch (err_5) {\n logger.error('[PowerSyncProvider] Retry failed, re-recording failure:', err_5);\n // Re-record the failure so user can try again\n tracker_11.recordTransactionFailure(failure.entries, failure.error, failure.isPermanent, failure.affectedEntityIds, failure.affectedTables, {\n retryCount: failure.retryCount,\n firstFailedAt: failure.firstFailedAt\n });\n setFailedTransactions(tracker_11.getFailedTransactions());\n }\n }, [db, connector, logger]);\n\n // ─── Context Values ────────────────────────────────────────────────────────\n\n const powerSyncContextValue = useMemo<PowerSyncContextValue<TSchema>>(() => ({\n db,\n connector,\n attachmentQueue,\n isReady,\n isInitializing,\n attachmentQueueReady,\n error,\n schema,\n platform,\n conflictBus\n }), [db, connector, attachmentQueue, isReady, isInitializing, attachmentQueueReady, error, schema, platform, conflictBus]);\n const syncStatusContextValue = useMemo<SyncStatusContextValue>(() => ({\n status: syncStatus,\n pendingMutations,\n pendingCount: pendingMutations.length,\n // Expose uploading/downloading directly from syncStatus for reliable activity detection\n isUploading: syncStatus.uploading,\n isDownloading: syncStatus.downloading,\n isPaused: syncModeState.mode === 'offline',\n syncMode: syncModeState.mode,\n lastSyncedAt,\n // Connection error for consumers to display\n connectionError,\n // Failed transaction fields\n failedTransactions,\n hasUploadErrors: failedTransactions.length > 0,\n permanentErrorCount: failedTransactions.filter(f_1 => f_1.isPermanent).length,\n // Clear failure functions\n clearFailure,\n clearAllFailures,\n // Completed transaction fields\n completedTransactions,\n clearCompletedHistory,\n // Sync mode control functions\n setSyncMode,\n setForceNextUpload,\n // Discard mutation functions\n discardPendingMutation,\n discardAllPendingMutations,\n // Retry control functions\n pauseAutoRetry,\n resumeAutoRetry\n }), [syncStatus, pendingMutations, syncModeState.mode, lastSyncedAt, connectionError, failedTransactions, clearFailure, clearAllFailures, completedTransactions, clearCompletedHistory, setSyncMode, setForceNextUpload, discardPendingMutation, discardAllPendingMutations, pauseAutoRetry, resumeAutoRetry]);\n const connectionHealthContextValue = useMemo<ConnectionHealthContextValue>(() => ({\n health: connectionHealth\n }), [connectionHealth]);\n const syncMetricsContextValue = useMemo<SyncMetricsContextValue>(() => ({\n metrics: syncMetrics\n }), [syncMetrics]);\n\n // ─── Split Context Values (Performance Optimization) ────────────────────────\n // Each context is memoized independently so changes to one don't trigger\n // re-renders in components subscribed to others.\n\n // Connection status - rarely changes (on connect/disconnect)\n const connectionStatusValue = useMemo<ConnectionStatusContextValue>(() => ({\n connected: syncStatus.connected,\n connecting: syncStatus.connecting,\n hasSynced: syncStatus.hasSynced,\n lastSyncedAt,\n connectionError\n }), [syncStatus.connected, syncStatus.connecting, syncStatus.hasSynced, lastSyncedAt, connectionError]);\n\n // Sync activity - changes during active sync\n const syncActivityValue = useMemo<SyncActivityContextValue>(() => ({\n uploading: syncStatus.uploading,\n downloading: syncStatus.downloading,\n downloadProgress: syncStatus.downloadProgress\n }), [syncStatus.uploading, syncStatus.downloading, syncStatus.downloadProgress]);\n\n // Pending mutations - changes on local writes\n const pendingMutationsValue = useMemo<PendingMutationsContextValue>(() => ({\n pendingMutations,\n pendingCount: pendingMutations.length,\n discardPendingMutation,\n discardAllPendingMutations,\n addPendingMutation,\n removePendingMutation\n }), [pendingMutations, discardPendingMutation, discardAllPendingMutations, addPendingMutation, removePendingMutation]);\n\n // Failed transactions - changes on failures\n const failedTransactionsValue = useMemo<FailedTransactionsContextValue>(() => ({\n failedTransactions,\n hasUploadErrors: failedTransactions.length > 0,\n permanentErrorCount: failedTransactions.filter(f_2 => f_2.isPermanent).length,\n clearFailure,\n clearAllFailures,\n pauseAutoRetry,\n resumeAutoRetry,\n retryFailure\n }), [failedTransactions, clearFailure, clearAllFailures, pauseAutoRetry, resumeAutoRetry, retryFailure]);\n\n // Completed transactions - changes on successful syncs\n const completedTransactionsValue = useMemo<CompletedTransactionsContextValue>(() => ({\n completedTransactions,\n clearCompletedHistory,\n clearCompletedItem,\n newCompletedTransactions,\n markNotificationsAsSeen\n }), [completedTransactions, clearCompletedHistory, clearCompletedItem, newCompletedTransactions, markNotificationsAsSeen]);\n\n // Sync mode - rarely changes (user action or auto-offline)\n const syncModeValue = useMemo<SyncModeContextValue>(() => ({\n syncMode: syncModeState.mode,\n isPaused: syncModeState.mode === 'offline',\n isAutoOffline,\n networkReachable,\n setSyncMode,\n setForceNextUpload\n }), [syncModeState.mode, isAutoOffline, networkReachable, setSyncMode, setForceNextUpload]);\n\n // ─── Render ────────────────────────────────────────────────────────────────\n\n return <PowerSyncContext.Provider value={powerSyncContextValue as PowerSyncContextValue}>\n <ConnectionStatusContext.Provider value={connectionStatusValue}>\n <SyncActivityContext.Provider value={syncActivityValue}>\n <PendingMutationsContext.Provider value={pendingMutationsValue}>\n <FailedTransactionsContext.Provider value={failedTransactionsValue}>\n <CompletedTransactionsContext.Provider value={completedTransactionsValue}>\n <SyncModeContext.Provider value={syncModeValue}>\n <SyncStatusContext.Provider value={syncStatusContextValue}>\n <ConnectionHealthContext.Provider value={connectionHealthContextValue}>\n <SyncMetricsContext.Provider value={syncMetricsContextValue}>\n <AttachmentQueueContext.Provider value={attachmentQueue}>\n {children}\n </AttachmentQueueContext.Provider>\n </SyncMetricsContext.Provider>\n </ConnectionHealthContext.Provider>\n </SyncStatusContext.Provider>\n </SyncModeContext.Provider>\n </CompletedTransactionsContext.Provider>\n </FailedTransactionsContext.Provider>\n </PendingMutationsContext.Provider>\n </SyncActivityContext.Provider>\n </ConnectionStatusContext.Provider>\n </PowerSyncContext.Provider>;\n}","import type { ConflictCheckResult, ConflictResolution } from './types';\nexport type ConflictListener = (conflict: ConflictCheckResult) => void;\nexport type ResolutionListener = (table: string, recordId: string, resolution: ConflictResolution) => void;\n\n/**\n * Event bus for decoupling conflict detection from UI resolution.\n *\n * Flow:\n * 1. Connector detects conflict -> calls bus.emitConflict()\n * 2. ConflictContext subscribes via bus.onConflict() -> shows UI\n * 3. User resolves -> ConflictContext calls bus.emitResolution()\n * 4. Connector subscribes via bus.onResolution() -> triggers re-upload\n */\nexport class ConflictBus {\n private static MAX_PENDING = 100;\n private conflictListeners = new Set<ConflictListener>();\n private resolutionListeners = new Set<ResolutionListener>();\n private pendingConflicts: ConflictCheckResult[] = [];\n\n /**\n * Subscribe to conflict detection events.\n * Flushes any pending conflicts to ALL listeners (including the new one).\n * @returns Unsubscribe function\n */\n onConflict(listener: ConflictListener): () => void {\n this.conflictListeners.add(listener);\n\n // Flush pending conflicts to ALL listeners, not just the new one\n if (this.pendingConflicts.length > 0) {\n const pending = [...this.pendingConflicts];\n this.pendingConflicts = [];\n for (const conflict of pending) {\n this.conflictListeners.forEach(l => l(conflict));\n }\n }\n return () => this.conflictListeners.delete(listener);\n }\n\n /**\n * Subscribe to resolution events.\n * @returns Unsubscribe function\n */\n onResolution(listener: ResolutionListener): () => void {\n this.resolutionListeners.add(listener);\n return () => this.resolutionListeners.delete(listener);\n }\n\n /**\n * Emit a conflict detection event (called by connector).\n * If no listeners are subscribed, queues the conflict for later delivery.\n */\n emitConflict(conflict: ConflictCheckResult): void {\n if (this.conflictListeners.size === 0) {\n console.warn('[ConflictBus] No listeners - queueing conflict');\n if (this.pendingConflicts.length >= ConflictBus.MAX_PENDING) {\n console.warn('[ConflictBus] Pending queue full, dropping oldest conflict');\n this.pendingConflicts.shift();\n }\n this.pendingConflicts.push(conflict);\n return;\n }\n this.conflictListeners.forEach(listener => listener(conflict));\n }\n\n /**\n * Emit a resolution event (called by UI/ConflictContext).\n */\n emitResolution(table: string, recordId: string, resolution: ConflictResolution): void {\n this.resolutionListeners.forEach(listener => listener(table, recordId, resolution));\n }\n\n /**\n * Clear all listeners and pending conflicts (for cleanup).\n */\n destroy(): void {\n this.conflictListeners.clear();\n this.resolutionListeners.clear();\n this.pendingConflicts = [];\n }\n\n /**\n * Get the number of pending conflicts (useful for debugging/testing).\n */\n get pendingCount(): number {\n return this.pendingConflicts.length;\n }\n}","import { c as _c } from \"react/compiler-runtime\";\n/**\n * OfflineDataProvider Component for @pol-studios/powersync\n *\n * Batteries-included offline data provider that combines:\n * - PowerSyncProvider for offline-first data sync\n * - DataLayerProvider integration from @pol-studios/db\n * - ConflictProvider for conflict resolution UI\n * - StorageQueueProvider for attachment queue access\n * - Background sync system setup\n * - Error recovery UI with retry capability\n * - Online-only mode fallback (no PowerSync URL)\n *\n * This is the recommended entry point for apps using offline-first data.\n *\n * @example\n * ```tsx\n * <OfflineDataProvider\n * config={{\n * schema: AppSchema,\n * supabaseClient: supabase,\n * queryClient: queryClient,\n * powerSyncUrl: env.powerSyncUrl,\n * attachments: {\n * bucket: 'my-bucket',\n * sourceTable: 'MediaContent',\n * idColumn: 'storagePath',\n * },\n * }}\n * dataLayer={{ config: dataLayerConfig }}\n * renderInitError={(error, retry) => <MyErrorUI error={error} onRetry={retry} />}\n * >\n * <App />\n * </OfflineDataProvider>\n * ```\n */\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { View, Text, StyleSheet, Pressable } from 'react-native';\nimport type { CrudEntry, AbstractPowerSyncDatabase } from '../core/types';\nimport type { OfflineDataProviderProps, PowerSyncSyncStatusSnapshot } from './OfflineDataProvider.types';\nimport type { BackgroundSyncSystem } from '../sync/background-sync';\n\n/**\n * SyncControl interface matching @pol-studios/db DataLayerProvider expectations.\n * This is defined locally to avoid circular dependencies.\n */\ninterface DataLayerSyncControl {\n triggerSync: () => Promise<void>;\n startLiveSync: () => Promise<void>;\n stopLiveSync: () => void;\n setScope: (scopeName: string, values: string[]) => Promise<void>;\n retryFailedUploads?: () => Promise<void>;\n clearFailedUploads?: () => void;\n failedUploads?: unknown[];\n pauseAutoRetry: () => void;\n resumeAutoRetry: () => void;\n isAutoRetryPaused: boolean;\n addPendingMutation: (entry: {\n id: string;\n table: string;\n op: string;\n opData?: unknown;\n createdAt?: Date;\n }) => void;\n removePendingMutation: (id: string) => void;\n}\nimport { PowerSyncProvider } from './PowerSyncProvider';\nimport { PowerSyncErrorBoundary } from '../error';\nimport { SupabaseStorageAdapter } from '../storage';\nimport { createNativePlatformAdapter } from '../platform/index.native';\nimport type { LoggerAdapter, PlatformAdapter } from '../platform/types';\nimport { ProviderBridge } from './ProviderBridge';\n\n// ─── Default Logger ───────────────────────────────────────────────────────────\n\n/**\n * Default console logger for when no platform is provided.\n */\nconst defaultLogger: LoggerAdapter = {\n debug: (...args) => console.debug('[OfflineData]', ...args),\n info: (...args) => console.info('[OfflineData]', ...args),\n warn: (...args) => console.warn('[OfflineData]', ...args),\n error: (...args) => console.error('[OfflineData]', ...args)\n};\n\n// ─── Error Recovery UI Styles ─────────────────────────────────────────────────\n\nconst errorStyles = StyleSheet.create({\n container: {\n flex: 1,\n justifyContent: 'center',\n alignItems: 'center',\n backgroundColor: '#f5f5f5',\n padding: 20\n },\n content: {\n backgroundColor: 'white',\n borderRadius: 12,\n padding: 24,\n maxWidth: 400,\n width: '100%',\n shadowColor: '#000',\n shadowOffset: {\n width: 0,\n height: 2\n },\n shadowOpacity: 0.1,\n shadowRadius: 8,\n elevation: 4\n },\n title: {\n fontSize: 20,\n fontWeight: '600',\n color: '#1a1a1a',\n marginBottom: 12,\n textAlign: 'center'\n },\n message: {\n fontSize: 14,\n color: '#666',\n marginBottom: 16,\n textAlign: 'center',\n lineHeight: 20\n },\n errorDetail: {\n fontSize: 12,\n color: '#999',\n marginBottom: 20,\n textAlign: 'center',\n fontFamily: 'monospace'\n },\n retryButton: {\n backgroundColor: '#007AFF',\n borderRadius: 8,\n paddingVertical: 12,\n paddingHorizontal: 24,\n alignItems: 'center'\n },\n retryButtonText: {\n color: 'white',\n fontSize: 16,\n fontWeight: '600'\n }\n});\n\n// ─── Default Error Recovery UI ───────────────────────────────────────────────\n\n/**\n * Default error recovery UI shown when initialization fails.\n */\nfunction DefaultErrorRecoveryUI(t0) {\n const $ = _c(10);\n const {\n error,\n onRetry\n } = t0;\n let t1;\n let t2;\n if ($[0] === Symbol.for(\"react.memo_cache_sentinel\")) {\n t1 = <Text style={errorStyles.title}>Database Error</Text>;\n t2 = <Text style={errorStyles.message}>The local database encountered an error. This can happen if the app was interrupted during startup.</Text>;\n $[0] = t1;\n $[1] = t2;\n } else {\n t1 = $[0];\n t2 = $[1];\n }\n let t3;\n if ($[2] !== error.message) {\n t3 = <Text style={errorStyles.errorDetail}>{error.message}</Text>;\n $[2] = error.message;\n $[3] = t3;\n } else {\n t3 = $[3];\n }\n let t4;\n if ($[4] === Symbol.for(\"react.memo_cache_sentinel\")) {\n t4 = <Text style={errorStyles.retryButtonText}>Retry</Text>;\n $[4] = t4;\n } else {\n t4 = $[4];\n }\n let t5;\n if ($[5] !== onRetry) {\n t5 = <Pressable style={errorStyles.retryButton} onPress={onRetry}>{t4}</Pressable>;\n $[5] = onRetry;\n $[6] = t5;\n } else {\n t5 = $[6];\n }\n let t6;\n if ($[7] !== t3 || $[8] !== t5) {\n t6 = <View style={errorStyles.container}><View style={errorStyles.content}>{t1}{t2}{t3}{t5}</View></View>;\n $[7] = t3;\n $[8] = t5;\n $[9] = t6;\n } else {\n t6 = $[9];\n }\n return t6;\n}\n\n// ─── Main Provider Component ──────────────────────────────────────────────────\n\n/**\n * Batteries-included offline data provider.\n *\n * Combines PowerSyncProvider with error boundary, DataLayerProvider integration,\n * and sensible defaults for a complete offline-first data solution.\n *\n * Key features:\n * - Automatic PowerSync setup and initialization\n * - Integration with @pol-studios/db DataLayerProvider\n * - ConflictProvider and StorageQueueProvider wiring\n * - Background sync system support\n * - Error recovery UI with retry capability\n * - Online-only mode fallback when no PowerSync URL is provided\n *\n * @example\n * ```tsx\n * // Basic usage\n * <OfflineDataProvider\n * config={{\n * schema: AppSchema,\n * supabaseClient: supabase,\n * queryClient: queryClient,\n * powerSyncUrl: process.env.EXPO_PUBLIC_POWERSYNC_URL,\n * }}\n * >\n * <App />\n * </OfflineDataProvider>\n *\n * // With DataLayer integration\n * <OfflineDataProvider\n * config={{ ... }}\n * dataLayer={{ config: dataLayerConfig }}\n * >\n * <App />\n * </OfflineDataProvider>\n *\n * // With custom error UI\n * <OfflineDataProvider\n * config={{ ... }}\n * renderInitError={(error, retry) => <MyErrorUI error={error} onRetry={retry} />}\n * >\n * <App />\n * </OfflineDataProvider>\n * ```\n */\nexport function OfflineDataProvider(t0) {\n const $ = _c(109);\n const {\n config,\n children,\n dataLayer,\n backgroundSync,\n skipConflictProvider: t1,\n skipStorageQueueProvider: t2,\n storageAdapter: customStorageAdapter,\n uploadHandler: customUploadHandler,\n renderInitError,\n renderError,\n onReady,\n onError,\n onSyncStatusChange,\n onBackgroundSyncSystemReady: onBackgroundSyncSystemReadyProp\n } = t0;\n const skipConflictProvider = t1 === undefined ? false : t1;\n const skipStorageQueueProvider = t2 === undefined ? false : t2;\n const {\n schema,\n supabaseClient,\n queryClient,\n powerSyncUrl,\n dbFilename: t3,\n attachments,\n platform: customPlatform,\n connector: connectorConfig,\n sync: syncConfig\n } = config;\n const dbFilename = t3 === undefined ? \"powersync.db\" : t3;\n const [initError, setInitError] = useState(null);\n const [retryKey, setRetryKey] = useState(0);\n const [powerSyncInstance, setPowerSyncInstance] = useState(null);\n const [powerSyncSyncStatus, setPowerSyncSyncStatus] = useState(undefined);\n const addPendingMutationRef = useRef(null);\n const removePendingMutationRef = useRef(null);\n const backgroundSyncSystemRef = useRef(null);\n let t4;\n if ($[0] !== customPlatform) {\n t4 = customPlatform ?? createNativePlatformAdapter(defaultLogger);\n $[0] = customPlatform;\n $[1] = t4;\n } else {\n t4 = $[1];\n }\n const platform = t4;\n let t5;\n bb0: {\n if (customStorageAdapter) {\n t5 = customStorageAdapter;\n break bb0;\n }\n if (!attachments) {\n t5 = undefined;\n break bb0;\n }\n let t6;\n if ($[2] !== attachments.bucket || $[3] !== platform.fileSystem || $[4] !== supabaseClient) {\n t6 = new SupabaseStorageAdapter({\n client: supabaseClient,\n bucketConfig: {\n defaultBucket: attachments.bucket\n }\n }, platform.fileSystem);\n $[2] = attachments.bucket;\n $[3] = platform.fileSystem;\n $[4] = supabaseClient;\n $[5] = t6;\n } else {\n t6 = $[5];\n }\n t5 = t6;\n }\n const storageAdapter = t5;\n let t10;\n let t11;\n let t6;\n let t7;\n let t8;\n let t9;\n if ($[6] !== platform.logger) {\n t6 = async () => {\n platform.logger.warn(\"Sync not available: Use useSyncControl from PowerSync context\");\n };\n t7 = async () => {\n platform.logger.warn(\"Live sync not available: Use useSyncControl from PowerSync context\");\n };\n t8 = () => {\n platform.logger.warn(\"Live sync not available: Use useSyncControl from PowerSync context\");\n };\n t9 = async () => {\n platform.logger.warn(\"Scope control not available: Use useSyncControl from PowerSync context\");\n };\n t10 = async () => {\n platform.logger.warn(\"Retry not available: Use useSyncControl from PowerSync context\");\n };\n t11 = () => {\n platform.logger.warn(\"Clear failed uploads not available: Use useSyncControl from PowerSync context\");\n };\n $[6] = platform.logger;\n $[7] = t10;\n $[8] = t11;\n $[9] = t6;\n $[10] = t7;\n $[11] = t8;\n $[12] = t9;\n } else {\n t10 = $[7];\n t11 = $[8];\n t6 = $[9];\n t7 = $[10];\n t8 = $[11];\n t9 = $[12];\n }\n let t12;\n if ($[13] === Symbol.for(\"react.memo_cache_sentinel\")) {\n t12 = [];\n $[13] = t12;\n } else {\n t12 = $[13];\n }\n let t13;\n let t14;\n if ($[14] !== platform.logger) {\n t13 = () => {\n platform.logger.warn(\"Pause auto-retry not available: Use useSyncControl from PowerSync context\");\n };\n t14 = () => {\n platform.logger.warn(\"Resume auto-retry not available: Use useSyncControl from PowerSync context\");\n };\n $[14] = platform.logger;\n $[15] = t13;\n $[16] = t14;\n } else {\n t13 = $[15];\n t14 = $[16];\n }\n let t15;\n let t16;\n if ($[17] === Symbol.for(\"react.memo_cache_sentinel\")) {\n t15 = entry => {\n if (addPendingMutationRef.current) {\n addPendingMutationRef.current(entry as CrudEntry);\n }\n };\n t16 = id => {\n if (removePendingMutationRef.current) {\n removePendingMutationRef.current(id);\n }\n };\n $[17] = t15;\n $[18] = t16;\n } else {\n t15 = $[17];\n t16 = $[18];\n }\n let t17;\n if ($[19] !== t10 || $[20] !== t11 || $[21] !== t13 || $[22] !== t14 || $[23] !== t6 || $[24] !== t7 || $[25] !== t8 || $[26] !== t9) {\n t17 = {\n triggerSync: t6,\n startLiveSync: t7,\n stopLiveSync: t8,\n setScope: t9,\n retryFailedUploads: t10,\n clearFailedUploads: t11,\n failedUploads: t12,\n pauseAutoRetry: t13,\n resumeAutoRetry: t14,\n isAutoRetryPaused: false,\n addPendingMutation: t15,\n removePendingMutation: t16\n };\n $[19] = t10;\n $[20] = t11;\n $[21] = t13;\n $[22] = t14;\n $[23] = t6;\n $[24] = t7;\n $[25] = t8;\n $[26] = t9;\n $[27] = t17;\n } else {\n t17 = $[27];\n }\n const syncControl = t17;\n let t18;\n bb1: {\n if (!attachments) {\n t18 = undefined;\n break bb1;\n }\n let t19;\n if ($[28] !== attachments.idColumn || $[29] !== attachments.orderByColumn || $[30] !== attachments.projectFilter || $[31] !== attachments.sourceTable) {\n t19 = {\n table: attachments.sourceTable,\n idColumn: attachments.idColumn,\n orderByColumn: attachments.orderByColumn,\n projectFilter: attachments.projectFilter\n };\n $[28] = attachments.idColumn;\n $[29] = attachments.orderByColumn;\n $[30] = attachments.projectFilter;\n $[31] = attachments.sourceTable;\n $[32] = t19;\n } else {\n t19 = $[32];\n }\n let t20;\n if ($[33] !== platform.logger) {\n t20 = async (attachment, error) => {\n platform.logger.warn(`[AttachmentQueue] Download failed for ${attachment.filename}:`, error);\n return {\n retry: true\n };\n };\n $[33] = platform.logger;\n $[34] = t20;\n } else {\n t20 = $[34];\n }\n let t21;\n if ($[35] !== customUploadHandler) {\n t21 = customUploadHandler ? {\n handler: customUploadHandler,\n config: {\n concurrency: 3,\n timeoutMs: 120000,\n baseRetryDelayMs: 5000,\n maxRetryDelayMs: 3600000,\n staleDaysThreshold: 7\n }\n } : undefined;\n $[35] = customUploadHandler;\n $[36] = t21;\n } else {\n t21 = $[36];\n }\n let t22;\n if ($[37] !== storageAdapter || $[38] !== t19 || $[39] !== t20 || $[40] !== t21) {\n t22 = {\n source: t19,\n remoteStorage: storageAdapter,\n attachmentTableName: \"photo_attachments\",\n performInitialSync: true,\n onDownloadError: t20,\n upload: t21\n };\n $[37] = storageAdapter;\n $[38] = t19;\n $[39] = t20;\n $[40] = t21;\n $[41] = t22;\n } else {\n t22 = $[41];\n }\n t18 = t22;\n }\n const attachmentConfig = t18;\n const t19 = powerSyncUrl ?? \"\";\n const t20 = syncConfig?.autoConnect ?? true;\n const t21 = syncConfig?.enableHealthMonitoring ?? true;\n const t22 = syncConfig?.enableMetrics ?? true;\n let t23;\n if ($[42] !== t20 || $[43] !== t21 || $[44] !== t22) {\n t23 = {\n autoConnect: t20,\n enableHealthMonitoring: t21,\n enableMetrics: t22\n };\n $[42] = t20;\n $[43] = t21;\n $[44] = t22;\n $[45] = t23;\n } else {\n t23 = $[45];\n }\n let t24;\n if ($[46] !== attachmentConfig || $[47] !== connectorConfig || $[48] !== dbFilename || $[49] !== platform || $[50] !== queryClient || $[51] !== schema || $[52] !== supabaseClient || $[53] !== t19 || $[54] !== t23) {\n t24 = {\n platform,\n schema,\n powerSyncUrl: t19,\n supabaseClient,\n queryClient,\n dbFilename,\n connector: connectorConfig,\n attachments: attachmentConfig,\n sync: t23\n };\n $[46] = attachmentConfig;\n $[47] = connectorConfig;\n $[48] = dbFilename;\n $[49] = platform;\n $[50] = queryClient;\n $[51] = schema;\n $[52] = supabaseClient;\n $[53] = t19;\n $[54] = t23;\n $[55] = t24;\n } else {\n t24 = $[55];\n }\n const powerSyncConfig = t24;\n let t25;\n if ($[56] !== onError || $[57] !== platform.logger) {\n t25 = err => {\n platform.logger.error(\"PowerSync error:\", err);\n const errorMessage = err.message ?? \"\";\n if (errorMessage.includes(\"not open\") || errorMessage.includes(\"closed\") || errorMessage.includes(\"failed to open\") || errorMessage.includes(\"initialization failed\")) {\n setInitError(err);\n }\n onError?.(err);\n };\n $[56] = onError;\n $[57] = platform.logger;\n $[58] = t25;\n } else {\n t25 = $[58];\n }\n const handlePowerSyncError = t25;\n let t26;\n if ($[59] !== platform.logger) {\n t26 = () => {\n platform.logger.info(\"Retrying PowerSync initialization...\");\n setInitError(null);\n setRetryKey(_temp);\n };\n $[59] = platform.logger;\n $[60] = t26;\n } else {\n t26 = $[60];\n }\n const handleRetry = t26;\n let t27;\n if ($[61] !== backgroundSync?.callbacks || $[62] !== onBackgroundSyncSystemReadyProp || $[63] !== platform.logger) {\n t27 = system => {\n backgroundSyncSystemRef.current = system;\n backgroundSync?.callbacks?.onSyncStart?.();\n onBackgroundSyncSystemReadyProp?.(system);\n platform.logger.info(\"[Background Sync] System ready\");\n };\n $[61] = backgroundSync?.callbacks;\n $[62] = onBackgroundSyncSystemReadyProp;\n $[63] = platform.logger;\n $[64] = t27;\n } else {\n t27 = $[64];\n }\n backgroundSync?.callbacks;\n const handleBackgroundSyncSystemReady = t27;\n let t28;\n if ($[65] !== renderError || $[66] !== renderInitError) {\n t28 = (error_0, retry) => {\n const customRenderer = renderInitError ?? renderError;\n if (customRenderer) {\n return customRenderer(error_0, retry);\n }\n return <DefaultErrorRecoveryUI error={error_0} onRetry={retry} />;\n };\n $[65] = renderError;\n $[66] = renderInitError;\n $[67] = t28;\n } else {\n t28 = $[67];\n }\n const errorFallback = t28;\n let t29;\n if ($[68] !== powerSyncSyncStatus || $[69] !== powerSyncUrl) {\n t29 = !powerSyncUrl ? {\n hasSynced: true,\n connected: true,\n connecting: false,\n isOnline: true\n } : powerSyncSyncStatus;\n $[68] = powerSyncSyncStatus;\n $[69] = powerSyncUrl;\n $[70] = t29;\n } else {\n t29 = $[70];\n }\n const effectiveSyncStatus = t29;\n let t30;\n let t31;\n if ($[71] !== effectiveSyncStatus || $[72] !== onSyncStatusChange) {\n t30 = () => {\n if (effectiveSyncStatus) {\n onSyncStatusChange?.(effectiveSyncStatus);\n }\n };\n t31 = [effectiveSyncStatus, onSyncStatusChange];\n $[71] = effectiveSyncStatus;\n $[72] = onSyncStatusChange;\n $[73] = t30;\n $[74] = t31;\n } else {\n t30 = $[73];\n t31 = $[74];\n }\n useEffect(t30, t31);\n let t32;\n let t33;\n if ($[75] !== backgroundSync || $[76] !== children || $[77] !== dataLayer || $[78] !== effectiveSyncStatus || $[79] !== errorFallback || $[80] !== handleBackgroundSyncSystemReady || $[81] !== handlePowerSyncError || $[82] !== handleRetry || $[83] !== initError || $[84] !== onError || $[85] !== onReady || $[86] !== platform.logger || $[87] !== powerSyncConfig || $[88] !== powerSyncInstance || $[89] !== powerSyncUrl || $[90] !== queryClient || $[91] !== renderError || $[92] !== renderInitError || $[93] !== retryKey || $[94] !== skipConflictProvider || $[95] !== skipStorageQueueProvider || $[96] !== supabaseClient || $[97] !== syncControl) {\n t33 = Symbol.for(\"react.early_return_sentinel\");\n bb2: {\n const renderContent = () => {\n if (!powerSyncUrl) {\n return <>{children}</>;\n }\n if (initError) {\n const customRenderer_0 = renderInitError ?? renderError;\n if (customRenderer_0) {\n return <>{customRenderer_0(initError, handleRetry)}</>;\n }\n return <DefaultErrorRecoveryUI error={initError} onRetry={handleRetry} />;\n }\n return <PowerSyncErrorBoundary fallback={errorFallback} onError={handlePowerSyncError}><PowerSyncProvider key={retryKey} config={powerSyncConfig as any} onReady={() => {\n platform.logger.info(\"PowerSync initialized and ready\");\n setInitError(null);\n onReady?.();\n }} onError={handlePowerSyncError}><ProviderBridge skipConflictProvider={skipConflictProvider} skipStorageQueueProvider={skipStorageQueueProvider} backgroundSync={backgroundSync} onBackgroundSyncSystemReady={handleBackgroundSyncSystemReady} onDbReady={(db, syncStatus) => {\n setPowerSyncInstance(db);\n setPowerSyncSyncStatus(syncStatus);\n }} onSyncStatusChange={syncStatus_0 => {\n setPowerSyncSyncStatus(syncStatus_0);\n }} onAddPendingMutationReady={add => {\n addPendingMutationRef.current = add;\n }} onRemovePendingMutationReady={remove => {\n removePendingMutationRef.current = remove;\n }}>{children}</ProviderBridge></PowerSyncProvider></PowerSyncErrorBoundary>;\n };\n let t34;\n if ($[100] !== dataLayer.config || $[101] !== effectiveSyncStatus || $[102] !== onError || $[103] !== platform.logger || $[104] !== powerSyncInstance || $[105] !== queryClient || $[106] !== supabaseClient || $[107] !== syncControl) {\n t34 = content => {\n const {\n DataLayerProvider\n } = require(\"@pol-studios/db\");\n return <DataLayerProvider config={dataLayer.config} powerSyncInstance={powerSyncInstance} supabaseClient={supabaseClient} queryClient={queryClient} powerSyncSyncStatus={effectiveSyncStatus} syncControl={syncControl} onInitialized={() => {\n platform.logger.info(\"Data layer initialized\");\n }} onError={err_0 => {\n platform.logger.error(\"Data layer error:\", err_0);\n onError?.(err_0);\n }}>{content}</DataLayerProvider>;\n };\n $[100] = dataLayer.config;\n $[101] = effectiveSyncStatus;\n $[102] = onError;\n $[103] = platform.logger;\n $[104] = powerSyncInstance;\n $[105] = queryClient;\n $[106] = supabaseClient;\n $[107] = syncControl;\n $[108] = t34;\n } else {\n t34 = $[108];\n }\n const renderWithDataLayer = t34;\n if (dataLayer && !dataLayer.skip) {\n t33 = renderWithDataLayer(renderContent());\n break bb2;\n }\n t32 = renderContent();\n }\n $[75] = backgroundSync;\n $[76] = children;\n $[77] = dataLayer;\n $[78] = effectiveSyncStatus;\n $[79] = errorFallback;\n $[80] = handleBackgroundSyncSystemReady;\n $[81] = handlePowerSyncError;\n $[82] = handleRetry;\n $[83] = initError;\n $[84] = onError;\n $[85] = onReady;\n $[86] = platform.logger;\n $[87] = powerSyncConfig;\n $[88] = powerSyncInstance;\n $[89] = powerSyncUrl;\n $[90] = queryClient;\n $[91] = renderError;\n $[92] = renderInitError;\n $[93] = retryKey;\n $[94] = skipConflictProvider;\n $[95] = skipStorageQueueProvider;\n $[96] = supabaseClient;\n $[97] = syncControl;\n $[98] = t32;\n $[99] = t33;\n } else {\n t32 = $[98];\n t33 = $[99];\n }\n if (t33 !== Symbol.for(\"react.early_return_sentinel\")) {\n return t33;\n }\n return t32;\n}\nfunction _temp(prev) {\n return prev + 1;\n}\nexport default OfflineDataProvider;","/**\n * ProviderBridge Component for @pol-studios/powersync\n *\n * Internal bridge component that connects PowerSync context to external providers:\n * - DataLayerProvider from @pol-studios/db\n * - ConflictProvider from @pol-studios/db\n * - StorageQueueProvider from @pol-studios/db\n *\n * This component is used internally by OfflineDataProvider and should not be\n * exported directly. It handles the complex wiring between packages.\n */\n\nimport React, { ReactNode, useCallback, useEffect, useMemo, useRef } from 'react';\nimport { PowerSyncContext, AbstractPowerSyncDatabase } from '@powersync/react-native';\nimport type { CrudEntry } from '../core/types';\nimport type { ProviderBridgeProps, PowerSyncSyncStatusSnapshot, BackgroundSyncStatus } from './OfflineDataProvider.types';\nimport type { BackgroundSyncSystem } from '../sync/background-sync';\nimport { usePowerSync, useSyncStatus, useOnlineStatus, usePendingMutationsContext } from './hooks';\n\n/**\n * ProviderBridge connects the PowerSync package context to external providers\n * like ConflictProvider and StorageQueueProvider from @pol-studios/db.\n *\n * This component:\n * 1. Signals the parent when the db is ready (onDbReady)\n * 2. Reports sync status changes (onSyncStatusChange)\n * 3. Exposes pending mutation functions to parent (for DataLayerProvider)\n * 4. Sets up background sync system when enabled\n * 5. Wraps children with ConflictProvider and StorageQueueProvider\n * 6. Exposes PowerSync db via native PowerSyncContext for SDK hooks\n *\n * IMPORTANT: DataLayerProvider is rendered OUTSIDE this component (in OfflineDataProvider)\n * so it always exists in the React tree even before PowerSync is ready.\n * This prevents \"useDataLayer must be used within a DataLayerProvider\" errors\n * when routes mount before the db is initialized.\n *\n * CRITICAL: The conflictBus is created internally by PowerSyncProvider and\n * passed to the connector. We MUST use the same bus instance from context\n * for ConflictProvider, otherwise conflicts detected by the connector won't\n * reach the UI components subscribed via ConflictProvider.\n */\nexport function ProviderBridge({\n children,\n skipConflictProvider = false,\n skipStorageQueueProvider = false,\n backgroundSync,\n onBackgroundSyncSystemReady,\n onDbReady,\n onSyncStatusChange,\n onAddPendingMutationReady,\n onRemovePendingMutationReady\n}: ProviderBridgeProps): React.ReactElement | null {\n const {\n db,\n attachmentQueue,\n isReady,\n attachmentQueueReady,\n conflictBus,\n platform\n } = usePowerSync();\n const {\n status: syncStatus\n } = useSyncStatus();\n const {\n addPendingMutation,\n removePendingMutation\n } = usePendingMutationsContext();\n // Get online status from PowerSync's platform adapter (uses NetInfo on React Native)\n // This is the single source of truth for network connectivity\n const isOnline = useOnlineStatus();\n\n // Refs to track callbacks and readiness so effects don't need them as deps\n const onDbReadyRef = useRef(onDbReady);\n const onSyncStatusChangeRef = useRef(onSyncStatusChange);\n useEffect(() => {\n onDbReadyRef.current = onDbReady;\n }, [onDbReady]);\n useEffect(() => {\n onSyncStatusChangeRef.current = onSyncStatusChange;\n }, [onSyncStatusChange]);\n\n // Track whether we've already signalled readiness to avoid calling onDbReady multiple times\n const hasSignalledReady = useRef(false);\n\n // Signal parent with pending mutation functions once ready\n // These are CRITICAL for SyncTrackingAdapter to work correctly\n useEffect(() => {\n if (!isReady) return;\n platform.logger.debug('[ProviderBridge] Passing pending mutation functions to parent');\n onAddPendingMutationReady(addPendingMutation);\n onRemovePendingMutationReady(removePendingMutation);\n }, [isReady, addPendingMutation, removePendingMutation, onAddPendingMutationReady, onRemovePendingMutationReady, platform]);\n\n // Signal parent with db instance once ready\n useEffect(() => {\n if (!isReady || !db) return;\n const snapshot: PowerSyncSyncStatusSnapshot = {\n hasSynced: syncStatus.hasSynced,\n connected: syncStatus.connected,\n connecting: syncStatus.connecting,\n isOnline\n };\n if (!hasSignalledReady.current) {\n hasSignalledReady.current = true;\n onDbReadyRef.current(db, snapshot);\n } else {\n onSyncStatusChangeRef.current(snapshot);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isReady, db, syncStatus.hasSynced, syncStatus.connected, syncStatus.connecting, isOnline]);\n\n // Set up background sync system when db is ready and background sync is enabled\n useEffect(() => {\n if (!isReady || !db || !backgroundSync?.enabled) return;\n\n // Create BackgroundSyncSystem adapter for background sync\n const backgroundSystem: BackgroundSyncSystem = {\n init: async () => {\n // Already initialized via normal flow\n if (!db.connected) {\n // Note: db.connect() requires a connector, but in background mode\n // the db should already be initialized from the foreground session\n platform.logger.info('[Background Sync] DB not connected, waiting for connection...');\n }\n },\n disconnect: async () => {\n await db.disconnect();\n },\n isConnected: () => db.connected,\n getDatabase: () => db,\n onStatusChange: (callback: (status: BackgroundSyncStatus) => void) => {\n return db.registerListener({\n statusChanged: (status: {\n lastSyncedAt?: Date | null;\n dataFlowStatus?: {\n downloading?: boolean;\n uploading?: boolean;\n };\n }) => {\n callback({\n lastSyncedAt: status.lastSyncedAt ?? null,\n downloading: status.dataFlowStatus?.downloading ?? false,\n uploading: status.dataFlowStatus?.uploading ?? false\n });\n }\n });\n }\n };\n\n // Signal parent that background sync system is ready\n onBackgroundSyncSystemReady?.(backgroundSystem);\n\n // Cleanup: signal parent that system is no longer available on unmount\n return () => {\n onBackgroundSyncSystemReady?.(null as unknown as BackgroundSyncSystem);\n };\n }, [isReady, db, backgroundSync?.enabled, onBackgroundSyncSystemReady, platform]);\n\n // Don't render until PowerSync is ready\n if (!isReady) {\n return null; // Or a loading spinner - DataLayerProvider is still mounted above\n }\n\n // Build the provider tree based on skip flags\n let content: ReactNode = children;\n\n // Wrap with StorageQueueProvider if not skipped\n if (!skipStorageQueueProvider) {\n // Dynamically import to avoid hard dependency\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const {\n StorageQueueProvider\n } = require('@pol-studios/db');\n content = <StorageQueueProvider attachmentQueue={attachmentQueue} isReady={attachmentQueueReady}>\n {content}\n </StorageQueueProvider>;\n }\n\n // Wrap with ConflictProvider if not skipped\n if (!skipConflictProvider) {\n // Dynamically import to avoid hard dependency\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const {\n ConflictProvider\n } = require('@pol-studios/db');\n content = <ConflictProvider conflictBus={conflictBus}>\n {content}\n </ConflictProvider>;\n }\n\n // Wrap with native PowerSyncContext for SDK hooks to work\n // Note: Using 'as any' because our AbstractPowerSyncDatabase is a subset interface,\n // but the SDK's PowerSyncContext expects the full @powersync/common type\n if (db) {\n return (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n <PowerSyncContext.Provider value={db as any}>\n {content}\n </PowerSyncContext.Provider>\n );\n }\n return <>{content}</>;\n}\nexport default ProviderBridge;"],"mappings":"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","names":["useEffect","useRef","useState","useEffect","useRef","PowerSyncContext","jsx","useRef","useEffect","PowerSyncContext","Fragment","jsx","useState","useRef","t6","t19","t20","t21","t22","useEffect"]}
@@ -5,6 +5,7 @@ var STORAGE_KEY_PAUSED = `${STORAGE_KEY_PREFIX}-paused`;
5
5
  var STORAGE_KEY_METRICS = `${STORAGE_KEY_PREFIX}-metrics`;
6
6
  var STORAGE_KEY_ATTACHMENT_SETTINGS = `${STORAGE_KEY_PREFIX}-attachment-settings`;
7
7
  var STORAGE_KEY_SYNC_MODE = `${STORAGE_KEY_PREFIX}-sync-mode`;
8
+ var STORAGE_KEY_AUTO_OFFLINE = `${STORAGE_KEY_PREFIX}-auto-offline`;
8
9
  var DEFAULT_SYNC_MODE = "push-pull";
9
10
  var HEALTH_CHECK_INTERVAL_MS = 3e4;
10
11
  var HEALTH_CHECK_TIMEOUT_MS = 5e3;
@@ -37,6 +38,7 @@ export {
37
38
  STORAGE_KEY_METRICS,
38
39
  STORAGE_KEY_ATTACHMENT_SETTINGS,
39
40
  STORAGE_KEY_SYNC_MODE,
41
+ STORAGE_KEY_AUTO_OFFLINE,
40
42
  DEFAULT_SYNC_MODE,
41
43
  HEALTH_CHECK_INTERVAL_MS,
42
44
  HEALTH_CHECK_TIMEOUT_MS,
@@ -62,4 +64,4 @@ export {
62
64
  DEFAULT_RETRY_MAX_DELAY_MS,
63
65
  DEFAULT_RETRY_BACKOFF_MULTIPLIER
64
66
  };
65
- //# sourceMappingURL=chunk-EJ23MXPQ.js.map
67
+ //# sourceMappingURL=chunk-CGL33PL4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/constants.ts"],"sourcesContent":["/**\n * Constants for @pol-studios/powersync\n *\n * This module contains all configurable constants with sensible defaults.\n * These can be overridden via configuration.\n */\n\n// ─── Storage Keys ────────────────────────────────────────────────────────────\n\n/** Storage key prefix for all PowerSync-related keys */\nexport const STORAGE_KEY_PREFIX = '@pol-studios/powersync';\n\n/** Storage key for PowerSync enabled state */\nexport const STORAGE_KEY_ENABLED = `${STORAGE_KEY_PREFIX}-enabled`;\n\n/** Storage key for PowerSync paused state */\nexport const STORAGE_KEY_PAUSED = `${STORAGE_KEY_PREFIX}-paused`;\n\n/** Storage key for persisted sync metrics */\nexport const STORAGE_KEY_METRICS = `${STORAGE_KEY_PREFIX}-metrics`;\n\n/** Storage key for attachment queue settings */\nexport const STORAGE_KEY_ATTACHMENT_SETTINGS = `${STORAGE_KEY_PREFIX}-attachment-settings`;\n\n/** Storage key for sync mode */\nexport const STORAGE_KEY_SYNC_MODE = `${STORAGE_KEY_PREFIX}-sync-mode`;\n\n/** Storage key for auto-offline flag (tracks if offline was set automatically vs manually) */\nexport const STORAGE_KEY_AUTO_OFFLINE = `${STORAGE_KEY_PREFIX}-auto-offline`;\n\n/** Default sync mode */\nexport const DEFAULT_SYNC_MODE = 'push-pull' as const;\n\n// ─── Health Check Configuration ──────────────────────────────────────────────\n\n/** Interval between health checks in milliseconds */\nexport const HEALTH_CHECK_INTERVAL_MS = 30_000; // 30 seconds\n\n/** Timeout for individual health check queries */\nexport const HEALTH_CHECK_TIMEOUT_MS = 5_000; // 5 seconds\n\n/** Latency threshold above which connection is considered degraded */\nexport const LATENCY_DEGRADED_THRESHOLD_MS = 1_000; // 1 second\n\n/** Number of consecutive failures before marking as disconnected */\nexport const MAX_CONSECUTIVE_FAILURES = 2;\n\n// ─── Storage Quota Thresholds ────────────────────────────────────────────────\n\n/** Warning threshold for device free space (default: 100MB) */\nexport const STORAGE_WARNING_THRESHOLD = 100 * 1024 * 1024; // 100 MB\n\n/** Critical threshold for device free space (default: 50MB) */\nexport const STORAGE_CRITICAL_THRESHOLD = 50 * 1024 * 1024; // 50 MB\n\n// ─── Attachment Queue Configuration ──────────────────────────────────────────\n\n/** Default maximum cache size for attachments */\nexport const DEFAULT_ATTACHMENT_CACHE_SIZE = 5 * 1024 * 1024 * 1024; // 5 GB\n\n/** Default number of concurrent attachment downloads */\nexport const DEFAULT_ATTACHMENT_CONCURRENCY = 50;\n\n/** Delay between retry passes for attachment downloads */\nexport const ATTACHMENT_RETRY_DELAY_MS = 5_000; // 5 seconds\n\n/** Timeout for individual attachment downloads */\nexport const ATTACHMENT_DOWNLOAD_TIMEOUT_MS = 60_000; // 60 seconds\n\n/** Default image compression quality (0.0 to 1.0) */\nexport const DEFAULT_COMPRESSION_QUALITY = 0.7; // 70%\n\n/** Maximum image width before resizing */\nexport const COMPRESSION_MAX_WIDTH = 2048;\n\n/** Skip compression for files smaller than this */\nexport const COMPRESSION_SKIP_SIZE_BYTES = 100_000; // 100 KB\n\n/** Skip compression if already smaller than this */\nexport const COMPRESSION_TARGET_SIZE_BYTES = 300_000; // 300 KB\n\n/** Stop downloads at this percentage of cache limit to leave headroom */\nexport const DOWNLOAD_STOP_THRESHOLD = 0.95; // 95%\n\n/** Trigger eviction at this percentage of cache limit */\nexport const EVICTION_TRIGGER_THRESHOLD = 1.0; // 100%\n\n// ─── Sync Configuration ──────────────────────────────────────────────────────\n\n/** Default sync interval for periodic sync mode */\nexport const DEFAULT_SYNC_INTERVAL_MS = 5 * 60 * 1000; // 5 minutes\n\n/** Debounce time for status notifications */\nexport const STATUS_NOTIFY_THROTTLE_MS = 500;\n\n/** Cache TTL for stats queries */\nexport const STATS_CACHE_TTL_MS = 500;\n\n// ─── Retry Configuration ─────────────────────────────────────────────────────\n\n/** Default maximum retry attempts */\nexport const DEFAULT_MAX_RETRY_ATTEMPTS = 3;\n\n/** Default base delay for retry backoff */\nexport const DEFAULT_RETRY_BASE_DELAY_MS = 1_000; // 1 second\n\n/** Default maximum delay between retries */\nexport const DEFAULT_RETRY_MAX_DELAY_MS = 30_000; // 30 seconds\n\n/** Default backoff multiplier */\nexport const DEFAULT_RETRY_BACKOFF_MULTIPLIER = 2;"],"mappings":";AAUO,IAAM,qBAAqB;AAG3B,IAAM,sBAAsB,GAAG,kBAAkB;AAGjD,IAAM,qBAAqB,GAAG,kBAAkB;AAGhD,IAAM,sBAAsB,GAAG,kBAAkB;AAGjD,IAAM,kCAAkC,GAAG,kBAAkB;AAG7D,IAAM,wBAAwB,GAAG,kBAAkB;AAGnD,IAAM,2BAA2B,GAAG,kBAAkB;AAGtD,IAAM,oBAAoB;AAK1B,IAAM,2BAA2B;AAGjC,IAAM,0BAA0B;AAGhC,IAAM,gCAAgC;AAGtC,IAAM,2BAA2B;AAKjC,IAAM,4BAA4B,MAAM,OAAO;AAG/C,IAAM,6BAA6B,KAAK,OAAO;AAK/C,IAAM,gCAAgC,IAAI,OAAO,OAAO;AAGxD,IAAM,iCAAiC;AAGvC,IAAM,4BAA4B;AAGlC,IAAM,iCAAiC;AAGvC,IAAM,8BAA8B;AAGpC,IAAM,wBAAwB;AAG9B,IAAM,8BAA8B;AAGpC,IAAM,gCAAgC;AAGtC,IAAM,0BAA0B;AAGhC,IAAM,6BAA6B;AAKnC,IAAM,2BAA2B,IAAI,KAAK;AAG1C,IAAM,4BAA4B;AAGlC,IAAM,qBAAqB;AAK3B,IAAM,6BAA6B;AAGnC,IAAM,8BAA8B;AAGpC,IAAM,6BAA6B;AAGnC,IAAM,mCAAmC;","names":[]}
@@ -0,0 +1,11 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ export {
9
+ __require
10
+ };
11
+ //# sourceMappingURL=chunk-DGUM43GV.js.map
@@ -0,0 +1,131 @@
1
+ import {
2
+ DEFAULT_UPLOAD_NOTIFICATION,
3
+ resolveBucketFromConfig
4
+ } from "./chunk-MKD2VCX3.js";
5
+
6
+ // src/storage/upload/SupabaseUploadHandler.native.ts
7
+ import { Platform } from "react-native";
8
+ var Upload = null;
9
+ async function loadUploadModule() {
10
+ if (!Upload) {
11
+ const module = await import("react-native-background-upload");
12
+ Upload = module.default;
13
+ }
14
+ return Upload;
15
+ }
16
+ var SupabaseUploadHandler = class {
17
+ supabase;
18
+ bucketConfig;
19
+ notificationConfig;
20
+ constructor(options, notificationConfig) {
21
+ this.supabase = options.supabaseClient;
22
+ this.bucketConfig = options.bucketConfig;
23
+ this.notificationConfig = {
24
+ ...DEFAULT_UPLOAD_NOTIFICATION,
25
+ ...notificationConfig
26
+ };
27
+ }
28
+ /**
29
+ * Upload a file to Supabase Storage using react-native-background-upload.
30
+ * Supports iOS background uploads and AbortSignal for cancellation.
31
+ */
32
+ async uploadFile(storagePath, localFileUri, mediaType, signal) {
33
+ if (signal?.aborted) {
34
+ throw new DOMException("Operation aborted", "AbortError");
35
+ }
36
+ const bucket = this.resolveBucket(storagePath);
37
+ const {
38
+ data,
39
+ error
40
+ } = await this.supabase.storage.from(bucket).createSignedUploadUrl(storagePath);
41
+ if (error || !data?.signedUrl) {
42
+ throw new Error(error?.message || "Failed to create signed upload URL");
43
+ }
44
+ if (signal?.aborted) {
45
+ throw new DOMException("Operation aborted", "AbortError");
46
+ }
47
+ const UploadModule = await loadUploadModule();
48
+ return new Promise((resolve, reject) => {
49
+ const uploadId = `upload_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
50
+ let isSettled = false;
51
+ const completedSub = UploadModule.addListener("completed", uploadId, (eventData) => {
52
+ if (isSettled) return;
53
+ isSettled = true;
54
+ cleanup();
55
+ if (eventData.responseCode >= 200 && eventData.responseCode < 300) {
56
+ resolve();
57
+ } else {
58
+ reject(new Error(`Upload failed with status ${eventData.responseCode}`));
59
+ }
60
+ });
61
+ const errorSub = UploadModule.addListener("error", uploadId, (eventData) => {
62
+ if (isSettled) return;
63
+ isSettled = true;
64
+ cleanup();
65
+ reject(new Error(eventData.error));
66
+ });
67
+ const cancelledSub = UploadModule.addListener("cancelled", uploadId, () => {
68
+ if (isSettled) return;
69
+ isSettled = true;
70
+ cleanup();
71
+ reject(new DOMException("Operation aborted", "AbortError"));
72
+ });
73
+ const cleanup = () => {
74
+ completedSub.remove();
75
+ errorSub.remove();
76
+ cancelledSub.remove();
77
+ if (signal) {
78
+ signal.removeEventListener("abort", abortHandler);
79
+ }
80
+ };
81
+ const abortHandler = () => {
82
+ if (isSettled) return;
83
+ UploadModule.cancelUpload(uploadId).catch(() => {
84
+ });
85
+ };
86
+ if (signal) {
87
+ signal.addEventListener("abort", abortHandler, {
88
+ once: true
89
+ });
90
+ }
91
+ const isAndroid = Platform.OS === "android";
92
+ UploadModule.startUpload({
93
+ url: data.signedUrl,
94
+ path: localFileUri,
95
+ method: "PUT",
96
+ type: "raw",
97
+ customUploadId: uploadId,
98
+ headers: {
99
+ "Content-Type": mediaType
100
+ },
101
+ // Android notification settings
102
+ ...isAndroid && {
103
+ notification: this.notificationConfig
104
+ }
105
+ }).catch((err) => {
106
+ if (isSettled) return;
107
+ isSettled = true;
108
+ cleanup();
109
+ reject(err);
110
+ });
111
+ });
112
+ }
113
+ /**
114
+ * Resolve the storage bucket for a given path.
115
+ */
116
+ resolveBucket(storagePath) {
117
+ return resolveBucketFromConfig(this.bucketConfig, storagePath);
118
+ }
119
+ };
120
+ function createSupabaseUploadHandler(supabaseClient, bucketConfig, notificationConfig) {
121
+ return new SupabaseUploadHandler({
122
+ supabaseClient,
123
+ bucketConfig
124
+ }, notificationConfig);
125
+ }
126
+
127
+ export {
128
+ SupabaseUploadHandler,
129
+ createSupabaseUploadHandler
130
+ };
131
+ //# sourceMappingURL=chunk-DHYUBVP7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/storage/upload/SupabaseUploadHandler.native.ts"],"sourcesContent":["/**\n * Supabase Upload Handler for React Native\n *\n * Implements UploadHandler interface using react-native-background-upload\n * for iOS background upload capability.\n */\n\nimport { Platform } from 'react-native';\nimport type { StorageUploadHandler, BucketConfig } from '../types';\nimport { resolveBucketFromConfig } from '../types';\nimport type { SupabaseUploadHandlerOptions, UploadNotificationConfig } from './types';\nimport { DEFAULT_UPLOAD_NOTIFICATION } from './types';\n\n// Lazy-loaded module reference\nlet Upload: typeof import('react-native-background-upload').default | null = null;\n\n/**\n * Load react-native-background-upload lazily.\n * This prevents the module from being bundled on web.\n */\nasync function loadUploadModule(): Promise<typeof import('react-native-background-upload').default> {\n if (!Upload) {\n const module = await import('react-native-background-upload');\n Upload = module.default;\n }\n return Upload;\n}\n\n/**\n * React Native upload handler using react-native-background-upload.\n *\n * Features:\n * - iOS background upload support\n * - AbortSignal cancellation support\n * - Android notification support\n * - Signed URL-based uploads\n *\n * @example\n * ```typescript\n * const handler = createSupabaseUploadHandler(supabaseClient, {\n * defaultBucket: 'attachments',\n * bucketMap: new Map([['avatars/', 'user-avatars']]),\n * });\n *\n * await handler.uploadFile(\n * 'photos/image.jpg',\n * 'file:///path/to/image.jpg',\n * 'image/jpeg'\n * );\n * ```\n */\nexport class SupabaseUploadHandler implements StorageUploadHandler {\n private supabase: any;\n private bucketConfig: BucketConfig;\n private notificationConfig: UploadNotificationConfig;\n constructor(options: SupabaseUploadHandlerOptions, notificationConfig?: Partial<UploadNotificationConfig>) {\n this.supabase = options.supabaseClient;\n this.bucketConfig = options.bucketConfig;\n this.notificationConfig = {\n ...DEFAULT_UPLOAD_NOTIFICATION,\n ...notificationConfig\n };\n }\n\n /**\n * Upload a file to Supabase Storage using react-native-background-upload.\n * Supports iOS background uploads and AbortSignal for cancellation.\n */\n async uploadFile(storagePath: string, localFileUri: string, mediaType: string, signal?: AbortSignal): Promise<void> {\n // Check if already aborted\n if (signal?.aborted) {\n throw new DOMException('Operation aborted', 'AbortError');\n }\n const bucket = this.resolveBucket(storagePath);\n\n // 1. Get signed upload URL from Supabase\n const {\n data,\n error\n } = await this.supabase.storage.from(bucket).createSignedUploadUrl(storagePath);\n if (error || !data?.signedUrl) {\n throw new Error(error?.message || 'Failed to create signed upload URL');\n }\n\n // Check abort after async operation\n if (signal?.aborted) {\n throw new DOMException('Operation aborted', 'AbortError');\n }\n\n // Load the upload module\n const UploadModule = await loadUploadModule();\n\n // 2. Upload using react-native-background-upload\n return new Promise((resolve, reject) => {\n const uploadId = `upload_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n let isSettled = false;\n\n // Setup listeners before starting\n const completedSub = UploadModule.addListener('completed', uploadId, (eventData: {\n responseCode: number;\n }) => {\n if (isSettled) return;\n isSettled = true;\n cleanup();\n if (eventData.responseCode >= 200 && eventData.responseCode < 300) {\n resolve();\n } else {\n reject(new Error(`Upload failed with status ${eventData.responseCode}`));\n }\n });\n const errorSub = UploadModule.addListener('error', uploadId, (eventData: {\n error: string;\n }) => {\n if (isSettled) return;\n isSettled = true;\n cleanup();\n reject(new Error(eventData.error));\n });\n const cancelledSub = UploadModule.addListener('cancelled', uploadId, () => {\n if (isSettled) return;\n isSettled = true;\n cleanup();\n reject(new DOMException('Operation aborted', 'AbortError'));\n });\n const cleanup = () => {\n completedSub.remove();\n errorSub.remove();\n cancelledSub.remove();\n if (signal) {\n signal.removeEventListener('abort', abortHandler);\n }\n };\n\n // Register abort handler to cancel the upload\n const abortHandler = () => {\n if (isSettled) return;\n UploadModule.cancelUpload(uploadId).catch(() => {\n // Ignore errors when cancelling - the upload may have already completed\n });\n };\n if (signal) {\n signal.addEventListener('abort', abortHandler, {\n once: true\n });\n }\n\n // Determine platform for notification settings\n const isAndroid = Platform.OS === 'android';\n\n // Start the upload\n UploadModule.startUpload({\n url: data.signedUrl,\n path: localFileUri,\n method: 'PUT',\n type: 'raw',\n customUploadId: uploadId,\n headers: {\n 'Content-Type': mediaType\n },\n // Android notification settings\n ...(isAndroid && {\n notification: this.notificationConfig\n })\n }).catch((err: Error) => {\n if (isSettled) return;\n isSettled = true;\n cleanup();\n reject(err);\n });\n });\n }\n\n /**\n * Resolve the storage bucket for a given path.\n */\n resolveBucket(storagePath: string): string {\n return resolveBucketFromConfig(this.bucketConfig, storagePath);\n }\n}\n\n/**\n * Factory function for creating a SupabaseUploadHandler.\n */\nexport function createSupabaseUploadHandler(supabaseClient: any, bucketConfig: BucketConfig, notificationConfig?: Partial<UploadNotificationConfig>): SupabaseUploadHandler {\n return new SupabaseUploadHandler({\n supabaseClient,\n bucketConfig\n }, notificationConfig);\n}"],"mappings":"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","names":[]}
@@ -0,0 +1,124 @@
1
+ // src/utils/retry.ts
2
+ var AbortError = class extends Error {
3
+ constructor(message = "Operation aborted") {
4
+ super(message);
5
+ this.name = "AbortError";
6
+ }
7
+ };
8
+ var RetryExhaustedError = class extends Error {
9
+ /** The last error that caused the final retry to fail */
10
+ cause;
11
+ /** Total number of attempts made */
12
+ attempts;
13
+ constructor(cause, attempts) {
14
+ super(`Retry exhausted after ${attempts} attempt(s): ${cause.message}`);
15
+ this.name = "RetryExhaustedError";
16
+ this.cause = cause;
17
+ this.attempts = attempts;
18
+ }
19
+ };
20
+ function calculateBackoffDelay(attempt, config) {
21
+ const {
22
+ baseDelayMs,
23
+ maxDelayMs,
24
+ backoffMultiplier
25
+ } = config;
26
+ const safeAttempt = Math.max(0, attempt);
27
+ const exponentialDelay = baseDelayMs * Math.pow(backoffMultiplier, safeAttempt);
28
+ return Math.min(exponentialDelay, maxDelayMs);
29
+ }
30
+ function addJitter(delay) {
31
+ const jitterFactor = 0.9 + Math.random() * 0.2;
32
+ return Math.round(delay * jitterFactor);
33
+ }
34
+ function sleep(ms, signal) {
35
+ return new Promise((resolve, reject) => {
36
+ if (signal?.aborted) {
37
+ reject(new AbortError());
38
+ return;
39
+ }
40
+ if (ms <= 0) {
41
+ resolve();
42
+ return;
43
+ }
44
+ let timeoutId;
45
+ const handleAbort = () => {
46
+ if (timeoutId !== void 0) {
47
+ clearTimeout(timeoutId);
48
+ }
49
+ reject(new AbortError());
50
+ };
51
+ if (signal) {
52
+ signal.addEventListener("abort", handleAbort, {
53
+ once: true
54
+ });
55
+ }
56
+ timeoutId = setTimeout(() => {
57
+ if (signal) {
58
+ signal.removeEventListener("abort", handleAbort);
59
+ }
60
+ resolve();
61
+ }, ms);
62
+ });
63
+ }
64
+ var DEFAULT_BACKOFF_CONFIG = {
65
+ maxRetries: 3,
66
+ baseDelayMs: 1e3,
67
+ maxDelayMs: 3e4,
68
+ backoffMultiplier: 2
69
+ };
70
+ async function withExponentialBackoff(fn, config, options) {
71
+ const {
72
+ maxRetries,
73
+ baseDelayMs,
74
+ maxDelayMs,
75
+ backoffMultiplier
76
+ } = config;
77
+ const {
78
+ signal,
79
+ onRetry
80
+ } = options ?? {};
81
+ if (signal?.aborted) {
82
+ throw new AbortError();
83
+ }
84
+ const safeMaxRetries = Math.max(0, Math.floor(maxRetries));
85
+ const totalAttempts = safeMaxRetries + 1;
86
+ let lastError;
87
+ for (let attempt = 0; attempt < totalAttempts; attempt++) {
88
+ if (signal?.aborted) {
89
+ throw new AbortError();
90
+ }
91
+ try {
92
+ return await fn();
93
+ } catch (error) {
94
+ lastError = error instanceof Error ? error : new Error(String(error));
95
+ const isLastAttempt = attempt === totalAttempts - 1;
96
+ if (isLastAttempt) {
97
+ break;
98
+ }
99
+ if (signal?.aborted) {
100
+ throw new AbortError();
101
+ }
102
+ const baseDelay = calculateBackoffDelay(attempt, {
103
+ baseDelayMs,
104
+ maxDelayMs,
105
+ backoffMultiplier
106
+ });
107
+ const delayWithJitter = addJitter(baseDelay);
108
+ onRetry?.(attempt + 1, delayWithJitter, lastError);
109
+ await sleep(delayWithJitter, signal);
110
+ }
111
+ }
112
+ throw new RetryExhaustedError(lastError, totalAttempts);
113
+ }
114
+
115
+ export {
116
+ AbortError,
117
+ RetryExhaustedError,
118
+ calculateBackoffDelay,
119
+ addJitter,
120
+ sleep,
121
+ DEFAULT_BACKOFF_CONFIG,
122
+ withExponentialBackoff
123
+ };
124
+ //# sourceMappingURL=chunk-FV2HXEIY.js.map