@pol-studios/powersync 1.0.24 → 1.0.30

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 (53) hide show
  1. package/README.md +0 -1
  2. package/dist/attachments/index.d.ts +1 -1
  3. package/dist/{background-sync-ChCXW-EV.d.ts → background-sync-CVR3PkFi.d.ts} +1 -1
  4. package/dist/{chunk-BGBQYQV3.js → chunk-BC2SRII2.js} +180 -299
  5. package/dist/chunk-BC2SRII2.js.map +1 -0
  6. package/dist/{chunk-YSTEESEG.js → chunk-C2ACBYBZ.js} +208 -11
  7. package/dist/chunk-C2ACBYBZ.js.map +1 -0
  8. package/dist/{chunk-24RDMMCL.js → chunk-FNYQFILT.js} +1 -1
  9. package/dist/chunk-FNYQFILT.js.map +1 -0
  10. package/dist/{chunk-YVX3A36I.js → chunk-JCGOZVWL.js} +406 -331
  11. package/dist/chunk-JCGOZVWL.js.map +1 -0
  12. package/dist/{chunk-WGHNIAF7.js → chunk-QREWE3NR.js} +2 -2
  13. package/dist/{chunk-TIFL2KWE.js → chunk-RBPWEOIV.js} +3 -3
  14. package/dist/{chunk-55DKCJV4.js → chunk-RE5HWLCB.js} +124 -13
  15. package/dist/chunk-RE5HWLCB.js.map +1 -0
  16. package/dist/connector/index.d.ts +4 -4
  17. package/dist/connector/index.js +1 -2
  18. package/dist/core/index.d.ts +2 -2
  19. package/dist/generator/cli.js +6 -1
  20. package/dist/generator/index.d.ts +1 -0
  21. package/dist/generator/index.js +9 -1
  22. package/dist/generator/index.js.map +1 -1
  23. package/dist/index.d.ts +7 -7
  24. package/dist/index.js +27 -17
  25. package/dist/index.native.d.ts +5 -5
  26. package/dist/index.native.js +27 -17
  27. package/dist/index.web.d.ts +5 -5
  28. package/dist/index.web.js +27 -17
  29. package/dist/maintenance/index.d.ts +2 -2
  30. package/dist/maintenance/index.js +2 -2
  31. package/dist/platform/index.d.ts +1 -1
  32. package/dist/platform/index.native.d.ts +1 -1
  33. package/dist/platform/index.web.d.ts +1 -1
  34. package/dist/provider/index.d.ts +188 -28
  35. package/dist/provider/index.js +17 -7
  36. package/dist/react/index.d.ts +2 -2
  37. package/dist/react/index.js +3 -3
  38. package/dist/storage/index.d.ts +1 -1
  39. package/dist/storage/index.native.d.ts +1 -1
  40. package/dist/storage/index.web.d.ts +1 -1
  41. package/dist/{supabase-connector-D2oIl2t8.d.ts → supabase-connector-C4YpH_l3.d.ts} +23 -25
  42. package/dist/sync/index.d.ts +42 -5
  43. package/dist/sync/index.js +2 -2
  44. package/dist/{types-DiBvmGEi.d.ts → types-CpM2_LhU.d.ts} +17 -24
  45. package/dist/{types-CDqWh56B.d.ts → types-Dv1uf0LZ.d.ts} +16 -1
  46. package/package.json +2 -2
  47. package/dist/chunk-24RDMMCL.js.map +0 -1
  48. package/dist/chunk-55DKCJV4.js.map +0 -1
  49. package/dist/chunk-BGBQYQV3.js.map +0 -1
  50. package/dist/chunk-YSTEESEG.js.map +0 -1
  51. package/dist/chunk-YVX3A36I.js.map +0 -1
  52. /package/dist/{chunk-WGHNIAF7.js.map → chunk-QREWE3NR.js.map} +0 -0
  53. /package/dist/{chunk-TIFL2KWE.js.map → chunk-RBPWEOIV.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/provider/context.ts","../src/provider/hooks.ts"],"sourcesContent":["/**\n * React Contexts for @pol-studios/powersync\n *\n * This module creates the React contexts used by the PowerSyncProvider.\n */\n\nimport { createContext } from 'react';\nimport type { PowerSyncContextValue, SyncStatusContextValue, ConnectionHealthContextValue, SyncMetricsContextValue, ConnectionStatusContextValue, SyncActivityContextValue, PendingMutationsContextValue, FailedTransactionsContextValue, CompletedTransactionsContextValue, SyncModeContextValue } from './types';\nimport type { PolAttachmentQueue } from '../attachments/pol-attachment-queue';\n\n// ─── Main PowerSync Context ──────────────────────────────────────────────────\n\n/**\n * Main context for PowerSync database instance and related state.\n *\n * Provides access to:\n * - PowerSync database instance\n * - SupabaseConnector instance\n * - AttachmentQueue instance (if configured)\n * - Initialization state\n *\n * @example\n * ```typescript\n * const { db, isReady, error } = useContext(PowerSyncContext);\n * ```\n */\nexport const PowerSyncContext = createContext<PowerSyncContextValue | null>(null);\nPowerSyncContext.displayName = 'PowerSyncContext';\n\n// ─── Sync Status Context ─────────────────────────────────────────────────────\n\n/**\n * Context for sync status updates.\n *\n * Provides access to:\n * - Current sync status (connected, syncing, etc.)\n * - Pending mutations count\n * - Paused state\n * - Last synced timestamp\n *\n * @example\n * ```typescript\n * const { status, pendingCount, isPaused } = useContext(SyncStatusContext);\n * ```\n */\nexport const SyncStatusContext = createContext<SyncStatusContextValue | null>(null);\nSyncStatusContext.displayName = 'SyncStatusContext';\n\n// ─── Split Contexts (Performance Optimization) ───────────────────────────────\n// These focused contexts allow components to subscribe to only the data they need.\n\n/**\n * Context for connection status only.\n * Subscribe to this instead of SyncStatusContext when you only need connection state.\n */\nexport const ConnectionStatusContext = createContext<ConnectionStatusContextValue | null>(null);\nConnectionStatusContext.displayName = 'ConnectionStatusContext';\n\n/**\n * Context for sync activity (uploading/downloading).\n * Subscribe to this instead of SyncStatusContext when you only need sync progress.\n */\nexport const SyncActivityContext = createContext<SyncActivityContextValue | null>(null);\nSyncActivityContext.displayName = 'SyncActivityContext';\n\n/**\n * Context for pending mutations.\n * Subscribe to this instead of SyncStatusContext when you only need pending upload info.\n */\nexport const PendingMutationsContext = createContext<PendingMutationsContextValue | null>(null);\nPendingMutationsContext.displayName = 'PendingMutationsContext';\n\n/**\n * Context for failed transactions.\n * Subscribe to this instead of SyncStatusContext when you only need error info.\n */\nexport const FailedTransactionsContext = createContext<FailedTransactionsContextValue | null>(null);\nFailedTransactionsContext.displayName = 'FailedTransactionsContext';\n\n/**\n * Context for completed transactions.\n * Subscribe to this instead of SyncStatusContext when you only need sync history.\n */\nexport const CompletedTransactionsContext = createContext<CompletedTransactionsContextValue | null>(null);\nCompletedTransactionsContext.displayName = 'CompletedTransactionsContext';\n\n/**\n * Context for sync mode control.\n * Subscribe to this instead of SyncStatusContext when you only need sync mode.\n */\nexport const SyncModeContext = createContext<SyncModeContextValue | null>(null);\nSyncModeContext.displayName = 'SyncModeContext';\n\n// ─── Connection Health Context ───────────────────────────────────────────────\n\n/**\n * Context for connection health monitoring.\n *\n * Provides access to:\n * - Health status (healthy, degraded, disconnected)\n * - Latency measurements\n * - Health check timestamps\n * - Failure counts\n *\n * @example\n * ```typescript\n * const { health } = useContext(ConnectionHealthContext);\n * if (health.status === 'degraded') {\n * showWarning('Connection is slow');\n * }\n * ```\n */\nexport const ConnectionHealthContext = createContext<ConnectionHealthContextValue | null>(null);\nConnectionHealthContext.displayName = 'ConnectionHealthContext';\n\n// ─── Sync Metrics Context ────────────────────────────────────────────────────\n\n/**\n * Context for sync metrics and statistics.\n *\n * Provides access to:\n * - Sync operation counts\n * - Sync durations\n * - Data transfer amounts\n * - Error tracking\n *\n * @example\n * ```typescript\n * const { metrics } = useContext(SyncMetricsContext);\n * console.log(`Total syncs: ${metrics.totalSyncs}`);\n * ```\n */\nexport const SyncMetricsContext = createContext<SyncMetricsContextValue | null>(null);\nSyncMetricsContext.displayName = 'SyncMetricsContext';\n\n// ─── Attachment Queue Context ────────────────────────────────────────────────\n\n/**\n * Context for the attachment queue (if configured).\n *\n * Provides direct access to the AttachmentQueue instance for:\n * - Checking attachment sync stats\n * - Pausing/resuming downloads\n * - Getting local URIs for attachments\n *\n * @example\n * ```typescript\n * const attachmentQueue = useContext(AttachmentQueueContext);\n * if (attachmentQueue) {\n * const stats = await attachmentQueue.getStats();\n * console.log(`Downloaded: ${stats.syncedCount}/${stats.totalExpected}`);\n * }\n * ```\n */\nexport const AttachmentQueueContext = createContext<PolAttachmentQueue | null>(null);\nAttachmentQueueContext.displayName = 'AttachmentQueueContext';","import { c as _c } from \"react/compiler-runtime\";\n/**\n * React Hooks for @pol-studios/powersync\n *\n * This module provides React hooks for accessing PowerSync functionality\n * within the provider's context.\n */\n\nimport { useContext, useCallback, useMemo, useRef, useState, useEffect } from 'react';\nimport type { AbstractPowerSyncDatabase, SyncStatus, ConnectionHealth, SyncMetrics, CrudEntry, EntitySyncState, FailedTransaction, CompletedTransaction, SyncError, UploadBlockReason } from '../core/types';\nimport type { PlatformAdapter } from '../platform/types';\nimport type { PowerSyncContextValue, SyncStatusContextValue, ConnectionHealthContextValue, SyncMetricsContextValue, ConnectionStatusContextValue, SyncActivityContextValue, PendingMutationsContextValue, FailedTransactionsContextValue, CompletedTransactionsContextValue, SyncModeContextValue } from './types';\nimport type { SyncScope, SyncControlActions } from '../sync/types';\nimport type { PolAttachmentQueue } from '../attachments/pol-attachment-queue';\nimport type { SupabaseConnector } from '../connector/supabase-connector';\nimport { PowerSyncContext, SyncStatusContext, ConnectionHealthContext, SyncMetricsContext, AttachmentQueueContext, ConnectionStatusContext, SyncActivityContext, PendingMutationsContext, FailedTransactionsContext, CompletedTransactionsContext, SyncModeContext } from './context';\nimport type { SyncMode } from '../core/types';\n// Note: STORAGE_KEY_PAUSED and STORAGE_KEY_SYNC_MODE are handled by the status tracker\n\n// Track warned call sites to avoid console spam during re-renders.\n// Intentionally module-scoped: This is a dev-only debugging feature that tracks\n// which call sites have already been warned about using deprecated hooks.\n// The Set persists across React lifecycles by design to prevent duplicate warnings.\nconst warnedSyncStatusCallSites = __DEV__ ? new Set<string>() : null;\n\n// Duration to show 'synced' state after entity finishes syncing\nconst SYNCED_DISPLAY_DURATION_MS = 3000;\n\n// ─── Main Hook ───────────────────────────────────────────────────────────────\n\n/**\n * Hook to access the PowerSync database and related services.\n *\n * @returns PowerSync context value with database, connector, and state\n * @throws Error if used outside of PowerSyncProvider\n *\n * @example\n * ```typescript\n * function MyComponent() {\n * const { db, isReady, error } = usePowerSync();\n *\n * if (!isReady) return <LoadingSpinner />;\n * if (error) return <Error message={error.message} />;\n *\n * // Use db for queries\n * const users = await db.getAll('SELECT * FROM users');\n * }\n * ```\n */\nexport function usePowerSync() {\n const context = useContext(PowerSyncContext);\n if (!context) {\n throw new Error(\"usePowerSync must be used within a PowerSyncProvider\");\n }\n return context as PowerSyncContextValue<TSchema>;\n}\n\n// ─── Sync Status Hook ────────────────────────────────────────────────────────\n\n/**\n * @deprecated This hook causes re-renders on any status change.\n * Use focused hooks instead:\n *\n * | Old (useSyncStatus) | New hook |\n * |--------------------------------|-----------------------------|\n * | connected, hasSynced | useConnectionStatus() |\n * | uploading, downloading | useSyncActivityContext() |\n * | pendingCount, pendingMutations | usePendingMutationsContext()|\n * | failedTransactions | useFailedTransactions() |\n * | syncMode, setSyncMode | useSyncMode() |\n * | triggerSync, pause, resume | useSyncControl() |\n *\n * @returns Sync status with connection state, pending uploads, and progress\n * @throws Error if used outside of PowerSyncProvider\n *\n * @example\n * ```typescript\n * function SyncIndicator() {\n * const { status, pendingCount, isPaused } = useSyncStatus();\n *\n * if (status.downloading) {\n * const { current, target, percentage } = status.downloadProgress ?? {};\n * return <Progress value={percentage} label={`${current}/${target}`} />;\n * }\n *\n * if (pendingCount > 0) {\n * return <Badge>{pendingCount} pending uploads</Badge>;\n * }\n *\n * return <Text>Synced</Text>;\n * }\n * ```\n */\nexport function useSyncStatus() {\n if (__DEV__ && warnedSyncStatusCallSites) {\n const stack = new Error().stack?.split(\"\\n\")[2] ?? \"unknown\";\n if (!warnedSyncStatusCallSites.has(stack)) {\n warnedSyncStatusCallSites.add(stack);\n console.warn(\"[useSyncStatus] Deprecated: This hook causes re-renders on any status change. Use focused hooks: useConnectionStatus, useSyncActivityContext, usePendingMutationsContext, etc. See migration guide in JSDoc.\");\n }\n }\n const context = useContext(SyncStatusContext);\n if (!context) {\n throw new Error(\"useSyncStatus must be used within a PowerSyncProvider\");\n }\n return context;\n}\n\n// ─── Focused Context Hooks (Performance Optimization) ────────────────────────\n// These hooks subscribe to only specific data, preventing unnecessary re-renders.\n\n/**\n * Hook to access connection status only.\n * Use this instead of useSyncStatus when you only need connection state.\n *\n * @returns Connection status with connected, connecting, hasSynced states\n * @throws Error if used outside of PowerSyncProvider\n *\n * @example\n * ```typescript\n * function ConnectionBadge() {\n * const { connected, connecting } = useConnectionStatus();\n *\n * if (connecting) return <Badge>Connecting...</Badge>;\n * return <Badge color={connected ? 'green' : 'red'}>{connected ? 'Online' : 'Offline'}</Badge>;\n * }\n * ```\n */\nexport function useConnectionStatus() {\n const context = useContext(ConnectionStatusContext);\n if (!context) {\n throw new Error(\"useConnectionStatus must be used within a PowerSyncProvider\");\n }\n return context;\n}\n\n/**\n * Hook to access sync activity (uploading/downloading).\n * Use this instead of useSyncStatus when you only need sync progress.\n *\n * @returns Sync activity with uploading, downloading, and downloadProgress\n * @throws Error if used outside of PowerSyncProvider\n *\n * @example\n * ```typescript\n * function SyncProgressBar() {\n * const { downloading, downloadProgress } = useSyncActivityContext();\n *\n * if (!downloading) return null;\n * return <ProgressBar value={downloadProgress?.percentage ?? 0} />;\n * }\n * ```\n */\nexport function useSyncActivityContext() {\n const context = useContext(SyncActivityContext);\n if (!context) {\n throw new Error(\"useSyncActivityContext must be used within a PowerSyncProvider\");\n }\n return context;\n}\n\n/**\n * Hook to access pending mutations.\n * Use this instead of useSyncStatus when you only need pending upload info.\n *\n * @returns Pending mutations with count and discard functions\n * @throws Error if used outside of PowerSyncProvider\n *\n * @example\n * ```typescript\n * function PendingChangesIndicator() {\n * const { pendingCount } = usePendingMutationsContext();\n *\n * if (pendingCount === 0) return null;\n * return <Badge>{pendingCount} pending</Badge>;\n * }\n * ```\n */\nexport function usePendingMutationsContext() {\n const context = useContext(PendingMutationsContext);\n if (!context) {\n throw new Error(\"usePendingMutationsContext must be used within a PowerSyncProvider\");\n }\n return context;\n}\n\n/**\n * Hook to access failed transactions.\n * Use this instead of useSyncStatus when you only need error info.\n *\n * @returns Failed transactions with error counts and clear/retry functions\n * @throws Error if used outside of PowerSyncProvider\n *\n * @example\n * ```typescript\n * function SyncErrorBanner() {\n * const { hasUploadErrors, permanentErrorCount, retryFailure, failedTransactions } = useFailedTransactionsContext();\n *\n * if (!hasUploadErrors) return null;\n * return (\n * <Banner onRetry={() => failedTransactions.forEach(f => retryFailure(f.id))}>\n * {permanentErrorCount} changes failed to sync\n * </Banner>\n * );\n * }\n * ```\n */\nexport function useFailedTransactionsContext() {\n const context = useContext(FailedTransactionsContext);\n if (!context) {\n throw new Error(\"useFailedTransactionsContext must be used within a PowerSyncProvider\");\n }\n return context;\n}\n\n/**\n * Hook to access completed transactions history.\n * Use this instead of useSyncStatus when you only need sync history.\n *\n * @returns Completed transactions with clear function\n * @throws Error if used outside of PowerSyncProvider\n *\n * @example\n * ```typescript\n * function RecentSyncs() {\n * const { completedTransactions, clearCompletedHistory } = useCompletedTransactionsContext();\n *\n * return (\n * <View>\n * {completedTransactions.map(t => (\n * <Text key={t.id}>Synced {t.affectedEntityIds.length} items</Text>\n * ))}\n * <Button onPress={clearCompletedHistory}>Clear</Button>\n * </View>\n * );\n * }\n * ```\n */\nexport function useCompletedTransactionsContext() {\n const context = useContext(CompletedTransactionsContext);\n if (!context) {\n throw new Error(\"useCompletedTransactionsContext must be used within a PowerSyncProvider\");\n }\n return context;\n}\n\n/**\n * Hook to access sync mode control.\n * Use this instead of useSyncStatus when you only need sync mode.\n *\n * @returns Sync mode with isPaused state and control functions\n * @throws Error if used outside of PowerSyncProvider\n *\n * @example\n * ```typescript\n * function SyncModeToggle() {\n * const { syncMode, isPaused, setSyncMode } = useSyncModeContext();\n *\n * return (\n * <Toggle\n * value={!isPaused}\n * onValueChange={(on) => setSyncMode(on ? 'push-pull' : 'offline')}\n * label={isPaused ? 'Offline' : syncMode}\n * />\n * );\n * }\n * ```\n */\nexport function useSyncModeContext() {\n const context = useContext(SyncModeContext);\n if (!context) {\n throw new Error(\"useSyncModeContext must be used within a PowerSyncProvider\");\n }\n return context;\n}\n\n// ─── Sync Control Hook ───────────────────────────────────────────────────────\n\n/**\n * Hook to control sync operations.\n *\n * @returns Actions for triggering, pausing, and resuming sync\n *\n * @example\n * ```typescript\n * function SyncControls() {\n * const { triggerSync, syncNow, pause, resume, disconnect, setSyncMode } = useSyncControl();\n * const { isPaused, syncMode } = useSyncStatus();\n *\n * return (\n * <View>\n * <Button onPress={syncNow}>Sync Now</Button>\n * {isPaused ? (\n * <Button onPress={resume}>Resume</Button>\n * ) : (\n * <Button onPress={pause}>Pause</Button>\n * )}\n * </View>\n * );\n * }\n * ```\n */\nexport function useSyncControl() {\n const $ = _c(35);\n const {\n db,\n connector,\n platform\n } = usePowerSync();\n const {\n setSyncMode: setContextSyncMode,\n setForceNextUpload\n } = useSyncModeContext();\n const scopeRef = useRef(null);\n let t0;\n if ($[0] !== connector || $[1] !== db || $[2] !== platform || $[3] !== setContextSyncMode) {\n t0 = async mode => {\n await setContextSyncMode(mode);\n if (mode === \"offline\") {\n if (db?.connected) {\n platform.logger.info(\"[useSyncControl] Mode changed to offline - disconnecting\");\n await db.disconnect();\n }\n } else {\n if (db && connector && !db.connected) {\n platform.logger.info(\"[useSyncControl] Mode changed to\", mode, \"- reconnecting\");\n await db.connect(connector);\n }\n }\n };\n $[0] = connector;\n $[1] = db;\n $[2] = platform;\n $[3] = setContextSyncMode;\n $[4] = t0;\n } else {\n t0 = $[4];\n }\n const setSyncMode = t0;\n let t1;\n if ($[5] !== connector || $[6] !== db || $[7] !== platform || $[8] !== setForceNextUpload) {\n t1 = async () => {\n if (!db || !connector) {\n platform.logger.warn(\"[useSyncControl] Cannot sync - database not initialized\");\n return;\n }\n setForceNextUpload(true);\n platform.logger.info(\"[useSyncControl] Sync Now triggered - forcing full sync\");\n if (db.connected) {\n await db.disconnect();\n }\n await db.connect(connector);\n platform.logger.info(\"[useSyncControl] Connected, sync should start automatically\");\n };\n $[5] = connector;\n $[6] = db;\n $[7] = platform;\n $[8] = setForceNextUpload;\n $[9] = t1;\n } else {\n t1 = $[9];\n }\n const syncNow = t1;\n let t2;\n if ($[10] !== connector || $[11] !== db || $[12] !== platform || $[13] !== setContextSyncMode) {\n t2 = async () => {\n if (!db || !connector) {\n platform.logger.warn(\"[useSyncControl] Cannot trigger sync - not initialized\");\n return;\n }\n await setContextSyncMode(\"push-pull\");\n if (db.connected) {\n platform.logger.info(\"[useSyncControl] Disconnecting to force fresh sync...\");\n await db.disconnect();\n }\n platform.logger.info(\"[useSyncControl] Connecting...\");\n await db.connect(connector);\n platform.logger.info(\"[useSyncControl] Connected, sync should start automatically\");\n };\n $[10] = connector;\n $[11] = db;\n $[12] = platform;\n $[13] = setContextSyncMode;\n $[14] = t2;\n } else {\n t2 = $[14];\n }\n const triggerSync = t2;\n let t3;\n if ($[15] !== platform || $[16] !== setSyncMode) {\n t3 = async () => {\n await setSyncMode(\"offline\");\n platform.logger.info(\"[useSyncControl] Sync paused\");\n };\n $[15] = platform;\n $[16] = setSyncMode;\n $[17] = t3;\n } else {\n t3 = $[17];\n }\n const pause = t3;\n let t4;\n if ($[18] !== platform || $[19] !== setSyncMode) {\n t4 = async () => {\n await setSyncMode(\"push-pull\");\n platform.logger.info(\"[useSyncControl] Sync resumed\");\n };\n $[18] = platform;\n $[19] = setSyncMode;\n $[20] = t4;\n } else {\n t4 = $[20];\n }\n const resume = t4;\n let t5;\n if ($[21] !== db || $[22] !== platform) {\n t5 = async () => {\n if (!db) {\n platform.logger.warn(\"[useSyncControl] Cannot disconnect - not initialized\");\n return;\n }\n platform.logger.info(\"[useSyncControl] Disconnecting...\");\n await db.disconnect();\n platform.logger.info(\"[useSyncControl] Disconnected\");\n };\n $[21] = db;\n $[22] = platform;\n $[23] = t5;\n } else {\n t5 = $[23];\n }\n const disconnect = t5;\n let t6;\n if ($[24] !== connector || $[25] !== platform) {\n t6 = scope => {\n scopeRef.current = scope;\n if (connector && scope) {\n connector.setActiveProjectIds(scope.ids);\n platform.logger.info(\"[useSyncControl] Scope set:\", scope);\n }\n };\n $[24] = connector;\n $[25] = platform;\n $[26] = t6;\n } else {\n t6 = $[26];\n }\n const setScope = t6;\n let t7;\n if ($[27] !== disconnect || $[28] !== pause || $[29] !== resume || $[30] !== setScope || $[31] !== setSyncMode || $[32] !== syncNow || $[33] !== triggerSync) {\n t7 = {\n triggerSync,\n syncNow,\n pause,\n resume,\n disconnect,\n setScope,\n setSyncMode\n };\n $[27] = disconnect;\n $[28] = pause;\n $[29] = resume;\n $[30] = setScope;\n $[31] = setSyncMode;\n $[32] = syncNow;\n $[33] = triggerSync;\n $[34] = t7;\n } else {\n t7 = $[34];\n }\n return t7;\n}\n\n// ─── Sync Mode Hook ──────────────────────────────────────────────────────────\n\n/**\n * Hook to get and set the current sync mode.\n *\n * @returns Object with current mode, setter, and capability flags\n *\n * @example\n * ```typescript\n * function SyncModeSelector() {\n * const { mode, setMode, canUpload, canDownload } = useSyncMode();\n *\n * return (\n * <View>\n * <Text>Current mode: {mode}</Text>\n * <Text>Can upload: {canUpload ? 'Yes' : 'No'}</Text>\n * <Button onPress={() => setMode('pull-only')}>Download Only</Button>\n * </View>\n * );\n * }\n * ```\n */\nexport function useSyncMode() {\n const $ = _c(6);\n const {\n syncMode,\n setSyncMode,\n networkReachable\n } = useSyncModeContext();\n const t0 = networkReachable && syncMode === \"push-pull\";\n const t1 = syncMode !== \"offline\";\n let t2;\n if ($[0] !== networkReachable || $[1] !== setSyncMode || $[2] !== syncMode || $[3] !== t0 || $[4] !== t1) {\n t2 = {\n mode: syncMode,\n setMode: setSyncMode,\n canUpload: t0,\n canDownload: t1,\n networkReachable\n };\n $[0] = networkReachable;\n $[1] = setSyncMode;\n $[2] = syncMode;\n $[3] = t0;\n $[4] = t1;\n $[5] = t2;\n } else {\n t2 = $[5];\n }\n return t2;\n}\n\n// ─── Upload Retry Hook ────────────────────────────────────────────────────────\n\n/**\n * Hook to access upload retry state for exponential backoff handling.\n *\n * When an upload fails, the provider disconnects and waits with exponential backoff\n * before reconnecting. After 7 failed attempts (256s backoff), it stays disconnected\n * and lets the user decide.\n *\n * @returns Upload retry state and control functions\n * @throws Error if used outside of PowerSyncProvider\n *\n * @example\n * ```typescript\n * function UploadRetryBanner() {\n * const {\n * isWaiting,\n * nextRetryAt,\n * maxRetriesReached,\n * retryCount,\n * manualRetry,\n * discardAndReconnect,\n * } = useUploadRetry();\n *\n * if (maxRetriesReached) {\n * return (\n * <View>\n * <Text>Upload failed after {retryCount} attempts</Text>\n * <Button onPress={manualRetry}>Try Again</Button>\n * <Button onPress={discardAndReconnect}>Discard Changes</Button>\n * </View>\n * );\n * }\n *\n * if (isWaiting && nextRetryAt) {\n * return (\n * <View>\n * <Text>Retrying in {Math.ceil((nextRetryAt.getTime() - Date.now()) / 1000)}s</Text>\n * </View>\n * );\n * }\n *\n * return null;\n * }\n * ```\n */\nexport function useUploadRetry() {\n const $ = _c(7);\n const context = useSyncModeContext();\n let t0;\n if ($[0] !== context.discardFailedEntryAndReconnect || $[1] !== context.isWaitingForUploadRetry || $[2] !== context.manualUploadRetry || $[3] !== context.maxUploadRetriesReached || $[4] !== context.nextUploadRetryAt || $[5] !== context.uploadRetryCount) {\n t0 = {\n isWaiting: context.isWaitingForUploadRetry,\n nextRetryAt: context.nextUploadRetryAt,\n maxRetriesReached: context.maxUploadRetriesReached,\n retryCount: context.uploadRetryCount,\n manualRetry: context.manualUploadRetry,\n discardEntryAndReconnect: context.discardFailedEntryAndReconnect\n };\n $[0] = context.discardFailedEntryAndReconnect;\n $[1] = context.isWaitingForUploadRetry;\n $[2] = context.manualUploadRetry;\n $[3] = context.maxUploadRetriesReached;\n $[4] = context.nextUploadRetryAt;\n $[5] = context.uploadRetryCount;\n $[6] = t0;\n } else {\n t0 = $[6];\n }\n return t0;\n}\n\n// ─── Connection Health Hook ──────────────────────────────────────────────────\n\n/**\n * Hook to access connection health status.\n *\n * @returns Current connection health with latency and failure tracking\n * @throws Error if used outside of PowerSyncProvider\n *\n * @example\n * ```typescript\n * function ConnectionIndicator() {\n * const health = useConnectionHealth();\n *\n * const statusColor = {\n * healthy: 'green',\n * degraded: 'yellow',\n * disconnected: 'red',\n * }[health.status];\n *\n * return (\n * <View>\n * <StatusDot color={statusColor} />\n * {health.latency && <Text>{health.latency}ms</Text>}\n * </View>\n * );\n * }\n * ```\n */\nexport function useConnectionHealth() {\n const context = useContext(ConnectionHealthContext);\n if (!context) {\n throw new Error(\"useConnectionHealth must be used within a PowerSyncProvider\");\n }\n return context.health;\n}\n\n// ─── Sync Metrics Hook ───────────────────────────────────────────────────────\n\n/**\n * Hook to access sync metrics.\n *\n * @returns Sync metrics including success rates, timing, and data transfer\n * @throws Error if used outside of PowerSyncProvider\n *\n * @example\n * ```typescript\n * function SyncStats() {\n * const metrics = useSyncMetrics();\n *\n * const successRate = metrics.totalSyncs > 0\n * ? (metrics.successfulSyncs / metrics.totalSyncs * 100).toFixed(1)\n * : 100;\n *\n * return (\n * <View>\n * <Text>Total syncs: {metrics.totalSyncs}</Text>\n * <Text>Success rate: {successRate}%</Text>\n * <Text>Avg duration: {metrics.averageSyncDuration ?? 'N/A'}ms</Text>\n * </View>\n * );\n * }\n * ```\n */\nexport function useSyncMetrics() {\n const context = useContext(SyncMetricsContext);\n if (!context) {\n throw new Error(\"useSyncMetrics must be used within a PowerSyncProvider\");\n }\n return context.metrics;\n}\n\n// ─── Attachment Queue Hook ───────────────────────────────────────────────────\n\n/**\n * Hook to access the attachment queue (if configured).\n *\n * @returns AttachmentQueue instance or null if not configured\n *\n * @example\n * ```typescript\n * function PhotoStats() {\n * const attachmentQueue = useAttachmentQueue();\n * const [stats, setStats] = useState(null);\n *\n * useEffect(() => {\n * if (!attachmentQueue) return;\n *\n * return attachmentQueue.onProgress((newStats) => {\n * setStats(newStats);\n * });\n * }, [attachmentQueue]);\n *\n * if (!stats) return null;\n *\n * return (\n * <View>\n * <Text>Photos: {stats.syncedCount}/{stats.totalExpected}</Text>\n * <Text>Cache used: {formatBytes(stats.syncedSize)}</Text>\n * </View>\n * );\n * }\n * ```\n */\nexport function useAttachmentQueue() {\n return useContext(AttachmentQueueContext);\n}\n\n// ─── Attachment Queue Ready Hook ─────────────────────────────────────────────\n\n/**\n * Hook to check if the attachment queue has finished initializing.\n *\n * This is useful when you need to wait for the attachment queue to be ready\n * before performing upload operations. The attachment queue initializes\n * asynchronously after the database is ready, so there's a brief period\n * where `isReady` is true but `attachmentQueueReady` is false.\n *\n * @returns Whether the attachment queue is ready (true if initialized or if attachments not configured)\n *\n * @example\n * ```typescript\n * function UploadButton() {\n * const attachmentQueue = useAttachmentQueue();\n * const attachmentQueueReady = useAttachmentQueueReady();\n *\n * if (!attachmentQueueReady) {\n * return <Button disabled>Initializing...</Button>;\n * }\n *\n * if (!attachmentQueue) {\n * return <Text>Uploads not configured</Text>;\n * }\n *\n * return <Button onPress={handleUpload}>Upload</Button>;\n * }\n * ```\n */\nexport function useAttachmentQueueReady() {\n const {\n attachmentQueueReady\n } = usePowerSync();\n return attachmentQueueReady;\n}\n\n// ─── Database Query Hook ─────────────────────────────────────────────────────\n\n/**\n * Hook to get the PowerSync database instance.\n * Throws if not ready.\n *\n * @returns The PowerSync database instance\n * @throws Error if not initialized or used outside of PowerSyncProvider\n *\n * @example\n * ```typescript\n * function UserList() {\n * const db = useDatabase();\n * const [users, setUsers] = useState([]);\n *\n * useEffect(() => {\n * db.getAll('SELECT * FROM users').then(setUsers);\n * }, [db]);\n *\n * return <FlatList data={users} />;\n * }\n * ```\n */\nexport function useDatabase() {\n const {\n db,\n isReady,\n error\n } = usePowerSync();\n if (error) {\n throw error;\n }\n if (!isReady || !db) {\n throw new Error(\"PowerSync database is not ready\");\n }\n return db;\n}\n\n// ─── Platform Adapter Hook ───────────────────────────────────────────────────\n\n/**\n * Hook to access the platform adapter.\n *\n * @returns The platform adapter instance\n *\n * @example\n * ```typescript\n * function FileViewer({ filePath }) {\n * const { platform } = usePowerSync();\n *\n * const handleOpen = async () => {\n * const content = await platform.fileSystem.readFile(filePath);\n * // Process content...\n * };\n *\n * return <Button onPress={handleOpen}>Open File</Button>;\n * }\n * ```\n */\nexport function usePlatform() {\n const {\n platform\n } = usePowerSync();\n return platform;\n}\n\n// ─── Online Status Hook ──────────────────────────────────────────────────────\n\n/**\n * Hook to track online/offline status using the platform's network adapter.\n *\n * @returns Whether the device is currently connected to the internet\n *\n * @example\n * ```typescript\n * function OfflineBanner() {\n * const isOnline = useOnlineStatus();\n *\n * if (isOnline) return null;\n *\n * return <Banner type=\"warning\">You are offline</Banner>;\n * }\n * ```\n */\nexport function useOnlineStatus() {\n const $ = _c(4);\n const {\n platform\n } = usePowerSync();\n const [isOnline, setIsOnline] = useState(true);\n let t0;\n if ($[0] !== platform.network) {\n t0 = () => {\n platform.network.isConnected().then(setIsOnline);\n const unsubscribe = platform.network.addConnectionListener(setIsOnline);\n return unsubscribe;\n };\n $[0] = platform.network;\n $[1] = t0;\n } else {\n t0 = $[1];\n }\n let t1;\n if ($[2] !== platform) {\n t1 = [platform];\n $[2] = platform;\n $[3] = t1;\n } else {\n t1 = $[3];\n }\n useEffect(t0, t1);\n return isOnline;\n}\n\n// ─── Pending Mutations Hook ──────────────────────────────────────────────────\n\n/**\n * Hook to get pending mutations that need to be uploaded.\n *\n * @returns Array of pending CRUD entries and count\n *\n * @example\n * ```typescript\n * function PendingChanges() {\n * const { mutations, count } = usePendingMutations();\n *\n * if (count === 0) return null;\n *\n * return (\n * <View>\n * <Text>{count} changes pending upload</Text>\n * <FlatList\n * data={mutations}\n * renderItem={({ item }) => (\n * <Text>{item.op} on {item.table}</Text>\n * )}\n * />\n * </View>\n * );\n * }\n * ```\n */\nexport function usePendingMutations() {\n const $ = _c(3);\n const {\n pendingMutations,\n pendingCount\n } = usePendingMutationsContext();\n let t0;\n if ($[0] !== pendingCount || $[1] !== pendingMutations) {\n t0 = {\n mutations: pendingMutations,\n count: pendingCount\n };\n $[0] = pendingCount;\n $[1] = pendingMutations;\n $[2] = t0;\n } else {\n t0 = $[2];\n }\n return t0;\n}\n\n// ─── Is Syncing Hook ─────────────────────────────────────────────────────────\n\n/**\n * Hook to check if sync is currently active.\n *\n * @returns Whether sync is currently in progress (uploading or downloading)\n *\n * @example\n * ```typescript\n * function SyncButton() {\n * const isSyncing = useIsSyncing();\n * const { triggerSync } = useSyncControl();\n *\n * return (\n * <Button\n * onPress={triggerSync}\n * disabled={isSyncing}\n * >\n * {isSyncing ? 'Syncing...' : 'Sync Now'}\n * </Button>\n * );\n * }\n * ```\n */\nexport function useIsSyncing() {\n const {\n uploading,\n downloading\n } = useSyncActivityContext();\n return uploading || downloading;\n}\n\n// ─── Download Progress Hook ──────────────────────────────────────────────────\n\n/**\n * Hook to get download progress during sync.\n *\n * @returns Download progress or null if not downloading\n *\n * @example\n * ```typescript\n * function DownloadProgress() {\n * const progress = useDownloadProgress();\n *\n * if (!progress) return null;\n *\n * return (\n * <ProgressBar\n * value={progress.percentage}\n * label={`${progress.current}/${progress.target} operations`}\n * />\n * );\n * }\n * ```\n */\nexport function useDownloadProgress() {\n const {\n downloadProgress\n } = useSyncActivityContext();\n return downloadProgress;\n}\n\n// ─── Entity Sync Status Hook ─────────────────────────────────────────────────\n\n/**\n * Return type for useEntitySyncStatus hook.\n */\nexport interface EntitySyncStatusResult {\n /** Current sync state for this entity */\n state: EntitySyncState;\n /** Error details if state is 'error' */\n error: SyncError | null;\n /** Number of pending operations for this entity */\n pendingOperations: number;\n /** The failed transaction if any */\n failedTransaction: FailedTransaction | null;\n /** Dismiss the failure (remove from tracking) */\n dismiss: () => void;\n}\n\n/**\n * Hook to get sync status for a specific entity.\n *\n * Combines local mutation state (from pending mutations) with\n * failure state to provide a unified status for UI.\n *\n * @param entityId - The entity ID to check status for\n * @returns Unified sync state and actions\n *\n * @example\n * ```typescript\n * function EquipmentHeader({ unitId }) {\n * const { state, error, dismiss } = useEntitySyncStatus(unitId);\n *\n * const borderColor = {\n * idle: 'transparent',\n * saving: 'orange',\n * syncing: 'amber',\n * synced: 'green',\n * error: 'red',\n * }[state];\n * }\n * ```\n */\nexport function useEntitySyncStatus(entityId: string | undefined): EntitySyncStatusResult {\n // Use focused context hooks instead of deprecated useSyncStatus\n const {\n pendingMutations\n } = usePendingMutationsContext();\n const {\n failedTransactions,\n clearFailure\n } = useFailedTransactionsContext();\n const [, forceUpdate] = useState(0);\n\n // Track recently synced entities with timestamps using a ref (avoids module-level mutable state)\n const recentlySyncedRef = useRef<Map<string, number>>(new Map());\n\n // Find if entity is in pending mutations\n // Check both entry.id (PowerSync's internal CRUD entry ID) and entry.opData?.id (the actual record ID)\n const entityPendingMutations = useMemo(() => {\n if (!entityId) return [];\n return pendingMutations.filter(entry => entry.id === entityId || String(entry.opData?.id) === entityId);\n }, [entityId, pendingMutations]);\n\n // Find if entity has a failed transaction\n const failedTransaction = useMemo(() => {\n if (!entityId) return null;\n return failedTransactions.find(ft => ft.affectedEntityIds.includes(entityId)) ?? null;\n }, [entityId, failedTransactions]);\n\n // Track transition from syncing to synced\n const wasSyncingRef = useRef(false);\n const isCurrentlySyncing = entityPendingMutations.length > 0;\n\n // When entity transitions from syncing to not syncing (and no error),\n // mark it as recently synced\n useEffect(() => {\n if (!entityId) return;\n if (wasSyncingRef.current && !isCurrentlySyncing && !failedTransaction) {\n recentlySyncedRef.current.set(entityId, Date.now());\n\n // Schedule cleanup after the display duration\n const timer = setTimeout(() => {\n const syncedAt = recentlySyncedRef.current.get(entityId);\n if (syncedAt && Date.now() - syncedAt >= SYNCED_DISPLAY_DURATION_MS) {\n recentlySyncedRef.current.delete(entityId);\n forceUpdate(n => n + 1);\n }\n }, SYNCED_DISPLAY_DURATION_MS);\n return () => {\n clearTimeout(timer);\n recentlySyncedRef.current.delete(entityId);\n };\n }\n wasSyncingRef.current = isCurrentlySyncing;\n }, [entityId, isCurrentlySyncing, failedTransaction]);\n\n // Determine current state\n const state = useMemo((): EntitySyncState => {\n if (!entityId) return 'idle';\n\n // Check for ANY failure (highest priority)\n // Both permanent and transient failures should show error state\n // The UI can use failedTransaction.isPermanent to distinguish if needed\n if (failedTransaction) {\n return 'error';\n }\n\n // Check if currently syncing\n if (entityPendingMutations.length > 0) {\n return 'syncing';\n }\n\n // Check if recently synced\n const syncedAt_0 = recentlySyncedRef.current.get(entityId);\n if (syncedAt_0 && Date.now() - syncedAt_0 < SYNCED_DISPLAY_DURATION_MS) {\n return 'synced';\n }\n return 'idle';\n }, [entityId, failedTransaction, entityPendingMutations.length]);\n\n // Get error from failed transaction\n const error = failedTransaction?.error ?? null;\n\n // Dismiss function - clears the failure from tracking\n const dismiss = useCallback(() => {\n if (failedTransaction) {\n clearFailure(failedTransaction.id);\n }\n }, [failedTransaction, clearFailure]);\n return {\n state,\n error,\n pendingOperations: entityPendingMutations.length,\n failedTransaction,\n dismiss\n };\n}\n\n// ─── Upload Status Hook ──────────────────────────────────────────────────────\n\n/**\n * Return type for useUploadStatus hook.\n */\nexport interface UploadStatusResult {\n /** Number of operations waiting to upload */\n pendingCount: number;\n /** Number of failed transactions */\n failedCount: number;\n /** Number of permanent failures needing user action */\n permanentFailureCount: number;\n /** Whether there are any errors */\n hasErrors: boolean;\n /** Whether there are permanent errors needing attention */\n hasPermanentErrors: boolean;\n /** All failed transactions */\n failedTransactions: FailedTransaction[];\n /** Trigger sync retry (reconnect) */\n retryAll: () => Promise<void>;\n /** Dismiss a specific failure by its ID */\n dismissFailure: (failureId: string) => void;\n}\n\n/**\n * Hook to get overall upload status across all entities.\n *\n * @returns Upload status with counts and actions\n *\n * @example\n * ```typescript\n * function SyncStatusBar() {\n * const { pendingCount, failedCount, hasPermanentErrors, retryAll } = useUploadStatus();\n *\n * if (hasPermanentErrors) {\n * return <Banner onRetry={retryAll}>\n * {failedCount} changes failed to sync\n * </Banner>;\n * }\n * }\n * ```\n */\nexport function useUploadStatus() {\n const $ = _c(12);\n const {\n pendingCount\n } = usePendingMutationsContext();\n const {\n failedTransactions,\n hasUploadErrors,\n permanentErrorCount,\n clearFailure\n } = useFailedTransactionsContext();\n const {\n triggerSync\n } = useSyncControl();\n let t0;\n if ($[0] !== triggerSync) {\n t0 = async () => {\n await triggerSync();\n };\n $[0] = triggerSync;\n $[1] = t0;\n } else {\n t0 = $[1];\n }\n const retryAll = t0;\n let t1;\n if ($[2] !== clearFailure) {\n t1 = failureId => {\n clearFailure(failureId);\n };\n $[2] = clearFailure;\n $[3] = t1;\n } else {\n t1 = $[3];\n }\n const dismissFailure = t1;\n const t2 = permanentErrorCount > 0;\n let t3;\n if ($[4] !== dismissFailure || $[5] !== failedTransactions || $[6] !== hasUploadErrors || $[7] !== pendingCount || $[8] !== permanentErrorCount || $[9] !== retryAll || $[10] !== t2) {\n t3 = {\n pendingCount,\n failedCount: failedTransactions.length,\n permanentFailureCount: permanentErrorCount,\n hasErrors: hasUploadErrors,\n hasPermanentErrors: t2,\n failedTransactions,\n retryAll,\n dismissFailure\n };\n $[4] = dismissFailure;\n $[5] = failedTransactions;\n $[6] = hasUploadErrors;\n $[7] = pendingCount;\n $[8] = permanentErrorCount;\n $[9] = retryAll;\n $[10] = t2;\n $[11] = t3;\n } else {\n t3 = $[11];\n }\n return t3;\n}\n\n// ─── Sync Activity Hook ──────────────────────────────────────────────────────\n\n/**\n * Return type for useSyncActivity hook.\n */\nexport interface SyncActivityResult {\n /** Pending CRUD entries waiting to be synced */\n pending: CrudEntry[];\n /** Failed transactions that need attention */\n failed: FailedTransaction[];\n /** Recently completed transactions */\n completed: CompletedTransaction[];\n /** New completed transactions since last notification display (for toasts/banners) */\n newCompleted: CompletedTransaction[];\n /** Counts summary */\n counts: {\n pending: number;\n failed: number;\n completed: number;\n newCompleted: number;\n };\n /** Whether there is any sync activity to show (pending or failed) */\n hasActivity: boolean;\n /** Retry all failed transactions */\n retryAll: () => Promise<void>;\n /** Retry a specific failed transaction */\n retryFailure: (failureId: string) => Promise<void>;\n /** Dismiss a specific failure */\n dismissFailure: (failureId: string) => void;\n /** Clear all completed transactions from the list */\n clearCompleted: () => void;\n /** Clear a specific completed transaction from the list */\n clearCompletedItem: (completedId: string) => void;\n /** Mark notifications as seen (for auto-dismiss functionality) */\n markNotificationsAsSeen: () => void;\n}\n\n/**\n * Hook to get comprehensive sync activity including pending, failed, and completed transactions.\n *\n * Uses the provider's completed transaction tracking via the status tracker.\n *\n * @returns Sync activity with all transaction states and actions\n *\n * @example\n * ```typescript\n * function SyncActivityBanner() {\n * const { pending, failed, completed, counts, hasActivity, retryAll, clearCompleted } = useSyncActivity();\n *\n * if (!hasActivity && completed.length === 0) return null;\n *\n * return (\n * <View>\n * <Text>{counts.pending} syncing, {counts.failed} failed</Text>\n * {failed.length > 0 && <Button onPress={retryAll}>Retry All</Button>}\n * </View>\n * );\n * }\n * ```\n */\nexport function useSyncActivity() {\n const $ = _c(24);\n const {\n pendingMutations\n } = usePendingMutationsContext();\n const {\n failedTransactions,\n clearFailure,\n retryFailure\n } = useFailedTransactionsContext();\n const {\n completedTransactions,\n clearCompletedHistory,\n clearCompletedItem,\n newCompletedTransactions,\n markNotificationsAsSeen\n } = useCompletedTransactionsContext();\n const {\n uploading: isUploading,\n downloading: isDownloading\n } = useSyncActivityContext();\n const {\n triggerSync\n } = useSyncControl();\n let t0;\n if ($[0] !== triggerSync) {\n t0 = async () => {\n await triggerSync();\n };\n $[0] = triggerSync;\n $[1] = t0;\n } else {\n t0 = $[1];\n }\n const retryAll = t0;\n let t1;\n if ($[2] !== clearFailure) {\n t1 = failureId => {\n clearFailure(failureId);\n };\n $[2] = clearFailure;\n $[3] = t1;\n } else {\n t1 = $[3];\n }\n const dismissFailure = t1;\n let t2;\n if ($[4] !== clearCompletedHistory) {\n t2 = () => {\n clearCompletedHistory();\n };\n $[4] = clearCompletedHistory;\n $[5] = t2;\n } else {\n t2 = $[5];\n }\n const clearCompleted = t2;\n let t3;\n if ($[6] !== completedTransactions.length || $[7] !== failedTransactions.length || $[8] !== newCompletedTransactions.length || $[9] !== pendingMutations.length) {\n t3 = {\n pending: pendingMutations.length,\n failed: failedTransactions.length,\n completed: completedTransactions.length,\n newCompleted: newCompletedTransactions.length\n };\n $[6] = completedTransactions.length;\n $[7] = failedTransactions.length;\n $[8] = newCompletedTransactions.length;\n $[9] = pendingMutations.length;\n $[10] = t3;\n } else {\n t3 = $[10];\n }\n const counts = t3;\n const hasActivity = isUploading || isDownloading || failedTransactions.length > 0;\n let t4;\n if ($[11] !== clearCompleted || $[12] !== clearCompletedItem || $[13] !== completedTransactions || $[14] !== counts || $[15] !== dismissFailure || $[16] !== failedTransactions || $[17] !== hasActivity || $[18] !== markNotificationsAsSeen || $[19] !== newCompletedTransactions || $[20] !== pendingMutations || $[21] !== retryAll || $[22] !== retryFailure) {\n t4 = {\n pending: pendingMutations,\n failed: failedTransactions,\n completed: completedTransactions,\n newCompleted: newCompletedTransactions,\n counts,\n hasActivity,\n retryAll,\n retryFailure,\n dismissFailure,\n clearCompleted,\n clearCompletedItem,\n markNotificationsAsSeen\n };\n $[11] = clearCompleted;\n $[12] = clearCompletedItem;\n $[13] = completedTransactions;\n $[14] = counts;\n $[15] = dismissFailure;\n $[16] = failedTransactions;\n $[17] = hasActivity;\n $[18] = markNotificationsAsSeen;\n $[19] = newCompletedTransactions;\n $[20] = pendingMutations;\n $[21] = retryAll;\n $[22] = retryFailure;\n $[23] = t4;\n } else {\n t4 = $[23];\n }\n return t4;\n}\n\n// ============================================================================\n// Renamed Hooks (cleaner API)\n// ============================================================================\n\n// Note: useSyncActivity and usePendingMutations already exist as higher-level hooks\n// with different return types (lines 707 and 1049). The focused context hooks\n// (useSyncActivityContext, usePendingMutationsContext) retain the \"Context\" suffix\n// to distinguish them from the convenience hooks.\n\n/**\n * Get failed transactions state and retry/dismiss functions.\n * Alias for useFailedTransactionsContext.\n */\nexport const useFailedTransactions = useFailedTransactionsContext;\n\n/**\n * Get completed transactions state and clear function.\n * Alias for useCompletedTransactionsContext.\n */\nexport const useCompletedTransactions = useCompletedTransactionsContext;\n\n// ─── Upload Blocked Reason Hook ──────────────────────────────────────────────\n\n/**\n * Return type for useUploadBlockedReason hook.\n */\nexport interface UploadBlockedReasonResult {\n /** Whether uploads are currently blocked */\n isBlocked: boolean;\n /** The reason uploads are blocked */\n reason: UploadBlockReason;\n /** Human-readable description of why uploads are blocked */\n description: string | null;\n /** Whether an upload is actively in progress */\n isUploading: boolean;\n}\n\n/**\n * User-friendly descriptions for upload block reasons.\n */\nconst BLOCK_REASON_DESCRIPTIONS: Record<UploadBlockReason, string | null> = {\n offline_mode: 'Offline mode enabled',\n pull_only_mode: 'Download-only mode enabled',\n network_unreachable: 'No internet connection',\n auto_offline: 'Went offline due to network loss',\n disconnected: 'Not connected to sync service',\n connecting: 'Connecting to sync service...',\n uploading: 'Upload in progress',\n none: null\n};\n\n/**\n * Hook to get why uploads are blocked.\n * Derives block reason from existing sync mode, network, and connection state.\n *\n * @returns Upload blocked status with reason and description\n *\n * @example\n * ```typescript\n * function UploadBlockedBanner() {\n * const { isBlocked, reason, description } = useUploadBlockedReason();\n *\n * if (!isBlocked) return null;\n *\n * return <Banner>{description}</Banner>;\n * }\n * ```\n */\nexport function useUploadBlockedReason() {\n const $ = _c(5);\n const {\n syncMode,\n isAutoOffline,\n networkReachable\n } = useSyncModeContext();\n const {\n uploading\n } = useSyncActivityContext();\n const {\n connected,\n connecting\n } = useConnectionStatus();\n let reason = \"none\";\n if (syncMode === \"offline\") {\n reason = isAutoOffline ? \"auto_offline\" : \"offline_mode\";\n } else {\n if (syncMode === \"pull-only\") {\n reason = \"pull_only_mode\";\n } else {\n if (!networkReachable) {\n reason = \"network_unreachable\";\n } else {\n if (!connected && !connecting) {\n reason = \"disconnected\";\n } else {\n if (connecting) {\n reason = \"connecting\";\n } else {\n if (uploading) {\n reason = \"uploading\";\n }\n }\n }\n }\n }\n }\n const isBlocked = reason !== \"none\" && reason !== \"uploading\";\n const description = BLOCK_REASON_DESCRIPTIONS[reason];\n let t0;\n if ($[0] !== description || $[1] !== isBlocked || $[2] !== reason || $[3] !== uploading) {\n t0 = {\n isBlocked,\n reason,\n description,\n isUploading: uploading\n };\n $[0] = description;\n $[1] = isBlocked;\n $[2] = reason;\n $[3] = uploading;\n $[4] = t0;\n } else {\n t0 = $[4];\n }\n return t0;\n}\n\n// ─── Retry Countdown Hook ────────────────────────────────────────────────────\n\n/**\n * Return type for useRetryCountdown hook.\n */\nexport interface RetryCountdownResult {\n /** The soonest next retry time from all failed transactions */\n nextRetryAt: Date | null;\n /** Milliseconds until the next retry (0 if already past) */\n timeUntilRetryMs: number;\n /** Formatted countdown string (e.g., \"5s\", \"1m 30s\", \"2m\") or null if no retry scheduled */\n formattedCountdown: string | null;\n}\n\n/**\n * Format milliseconds into a human-readable countdown string.\n */\nfunction formatCountdown(ms: number): string {\n if (ms <= 0) return '0s';\n const totalSeconds = Math.ceil(ms / 1000);\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n if (minutes === 0) {\n return `${seconds}s`;\n } else if (seconds === 0) {\n return `${minutes}m`;\n } else {\n return `${minutes}m ${seconds}s`;\n }\n}\n\n/**\n * Hook for retry countdown display.\n * Returns the soonest nextRetryAt from all failed transactions.\n * Re-renders every second when countdown is active.\n *\n * @returns Retry countdown information\n *\n * @example\n * ```typescript\n * function RetryTimer() {\n * const { nextRetryAt, formattedCountdown } = useRetryCountdown();\n *\n * if (!nextRetryAt) return null;\n *\n * return <Text>Retrying in {formattedCountdown}</Text>;\n * }\n * ```\n */\nexport function useRetryCountdown() {\n const $ = _c(13);\n const {\n failedTransactions\n } = useFailedTransactionsContext();\n const [now, setNow] = useState(_temp);\n let earliest = null;\n if ($[0] !== earliest || $[1] !== failedTransactions) {\n for (const ft of failedTransactions) {\n if (ft.nextRetryAt) {\n if (!earliest || ft.nextRetryAt < earliest) {\n earliest = ft.nextRetryAt;\n }\n }\n }\n $[0] = earliest;\n $[1] = failedTransactions;\n $[2] = earliest;\n } else {\n earliest = $[2];\n }\n const soonestRetry = earliest;\n let t0;\n bb0: {\n if (!soonestRetry) {\n t0 = 0;\n break bb0;\n }\n t0 = Math.max(0, soonestRetry.getTime() - now);\n }\n const timeUntilRetryMs = t0;\n let t1;\n let t2;\n if ($[3] !== soonestRetry) {\n t1 = () => {\n if (!soonestRetry) {\n return;\n }\n let isMounted = true;\n const tick = () => {\n if (isMounted) {\n setNow(Date.now());\n }\n };\n tick();\n const interval = setInterval(tick, 1000);\n return () => {\n isMounted = false;\n clearInterval(interval);\n };\n };\n t2 = [soonestRetry];\n $[3] = soonestRetry;\n $[4] = t1;\n $[5] = t2;\n } else {\n t1 = $[4];\n t2 = $[5];\n }\n useEffect(t1, t2);\n let t3;\n if ($[6] !== soonestRetry || $[7] !== timeUntilRetryMs) {\n t3 = soonestRetry ? formatCountdown(timeUntilRetryMs) : null;\n $[6] = soonestRetry;\n $[7] = timeUntilRetryMs;\n $[8] = t3;\n } else {\n t3 = $[8];\n }\n let t4;\n if ($[9] !== soonestRetry || $[10] !== t3 || $[11] !== timeUntilRetryMs) {\n t4 = {\n nextRetryAt: soonestRetry,\n timeUntilRetryMs,\n formattedCountdown: t3\n };\n $[9] = soonestRetry;\n $[10] = t3;\n $[11] = timeUntilRetryMs;\n $[12] = t4;\n } else {\n t4 = $[12];\n }\n return t4;\n}\nfunction _temp() {\n return Date.now();\n}"],"mappings":";AAMA,SAAS,qBAAqB;AAoBvB,IAAM,mBAAmB,cAA4C,IAAI;AAChF,iBAAiB,cAAc;AAkBxB,IAAM,oBAAoB,cAA6C,IAAI;AAClF,kBAAkB,cAAc;AASzB,IAAM,0BAA0B,cAAmD,IAAI;AAC9F,wBAAwB,cAAc;AAM/B,IAAM,sBAAsB,cAA+C,IAAI;AACtF,oBAAoB,cAAc;AAM3B,IAAM,0BAA0B,cAAmD,IAAI;AAC9F,wBAAwB,cAAc;AAM/B,IAAM,4BAA4B,cAAqD,IAAI;AAClG,0BAA0B,cAAc;AAMjC,IAAM,+BAA+B,cAAwD,IAAI;AACxG,6BAA6B,cAAc;AAMpC,IAAM,kBAAkB,cAA2C,IAAI;AAC9E,gBAAgB,cAAc;AAqBvB,IAAM,0BAA0B,cAAmD,IAAI;AAC9F,wBAAwB,cAAc;AAmB/B,IAAM,qBAAqB,cAA8C,IAAI;AACpF,mBAAmB,cAAc;AAqB1B,IAAM,yBAAyB,cAAyC,IAAI;AACnF,uBAAuB,cAAc;;;AC3JrC,SAAS,KAAK,UAAU;AAQxB,SAAS,YAAY,aAAa,SAAS,QAAQ,UAAU,iBAAiB;AAe9E,IAAM,4BAA4B,UAAU,oBAAI,IAAY,IAAI;AAGhE,IAAM,6BAA6B;AAuB5B,SAAS,eAAe;AAC7B,QAAM,UAAU,WAAW,gBAAgB;AAC3C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,sDAAsD;AAAA,EACxE;AACA,SAAO;AACT;AAsCO,SAAS,gBAAgB;AAC9B,MAAI,WAAW,2BAA2B;AACxC,UAAM,QAAQ,IAAI,MAAM,EAAE,OAAO,MAAM,IAAI,EAAE,CAAC,KAAK;AACnD,QAAI,CAAC,0BAA0B,IAAI,KAAK,GAAG;AACzC,gCAA0B,IAAI,KAAK;AACnC,cAAQ,KAAK,8MAA8M;AAAA,IAC7N;AAAA,EACF;AACA,QAAM,UAAU,WAAW,iBAAiB;AAC5C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,uDAAuD;AAAA,EACzE;AACA,SAAO;AACT;AAsBO,SAAS,sBAAsB;AACpC,QAAM,UAAU,WAAW,uBAAuB;AAClD,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,6DAA6D;AAAA,EAC/E;AACA,SAAO;AACT;AAmBO,SAAS,yBAAyB;AACvC,QAAM,UAAU,WAAW,mBAAmB;AAC9C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,gEAAgE;AAAA,EAClF;AACA,SAAO;AACT;AAmBO,SAAS,6BAA6B;AAC3C,QAAM,UAAU,WAAW,uBAAuB;AAClD,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,oEAAoE;AAAA,EACtF;AACA,SAAO;AACT;AAuBO,SAAS,+BAA+B;AAC7C,QAAM,UAAU,WAAW,yBAAyB;AACpD,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,sEAAsE;AAAA,EACxF;AACA,SAAO;AACT;AAyBO,SAAS,kCAAkC;AAChD,QAAM,UAAU,WAAW,4BAA4B;AACvD,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,yEAAyE;AAAA,EAC3F;AACA,SAAO;AACT;AAwBO,SAAS,qBAAqB;AACnC,QAAM,UAAU,WAAW,eAAe;AAC1C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,4DAA4D;AAAA,EAC9E;AACA,SAAO;AACT;AA4BO,SAAS,iBAAiB;AAC/B,QAAM,IAAI,GAAG,EAAE;AACf,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,aAAa;AACjB,QAAM;AAAA,IACJ,aAAa;AAAA,IACb;AAAA,EACF,IAAI,mBAAmB;AACvB,QAAM,WAAW,OAAO,IAAI;AAC5B,MAAI;AACJ,MAAI,EAAE,CAAC,MAAM,aAAa,EAAE,CAAC,MAAM,MAAM,EAAE,CAAC,MAAM,YAAY,EAAE,CAAC,MAAM,oBAAoB;AACzF,SAAK,OAAM,SAAQ;AACjB,YAAM,mBAAmB,IAAI;AAC7B,UAAI,SAAS,WAAW;AACtB,YAAI,IAAI,WAAW;AACjB,mBAAS,OAAO,KAAK,0DAA0D;AAC/E,gBAAM,GAAG,WAAW;AAAA,QACtB;AAAA,MACF,OAAO;AACL,YAAI,MAAM,aAAa,CAAC,GAAG,WAAW;AACpC,mBAAS,OAAO,KAAK,oCAAoC,MAAM,gBAAgB;AAC/E,gBAAM,GAAG,QAAQ,SAAS;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AACA,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AAAA,EACT,OAAO;AACL,SAAK,EAAE,CAAC;AAAA,EACV;AACA,QAAM,cAAc;AACpB,MAAI;AACJ,MAAI,EAAE,CAAC,MAAM,aAAa,EAAE,CAAC,MAAM,MAAM,EAAE,CAAC,MAAM,YAAY,EAAE,CAAC,MAAM,oBAAoB;AACzF,SAAK,YAAY;AACf,UAAI,CAAC,MAAM,CAAC,WAAW;AACrB,iBAAS,OAAO,KAAK,yDAAyD;AAC9E;AAAA,MACF;AACA,yBAAmB,IAAI;AACvB,eAAS,OAAO,KAAK,yDAAyD;AAC9E,UAAI,GAAG,WAAW;AAChB,cAAM,GAAG,WAAW;AAAA,MACtB;AACA,YAAM,GAAG,QAAQ,SAAS;AAC1B,eAAS,OAAO,KAAK,6DAA6D;AAAA,IACpF;AACA,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AAAA,EACT,OAAO;AACL,SAAK,EAAE,CAAC;AAAA,EACV;AACA,QAAM,UAAU;AAChB,MAAI;AACJ,MAAI,EAAE,EAAE,MAAM,aAAa,EAAE,EAAE,MAAM,MAAM,EAAE,EAAE,MAAM,YAAY,EAAE,EAAE,MAAM,oBAAoB;AAC7F,SAAK,YAAY;AACf,UAAI,CAAC,MAAM,CAAC,WAAW;AACrB,iBAAS,OAAO,KAAK,wDAAwD;AAC7E;AAAA,MACF;AACA,YAAM,mBAAmB,WAAW;AACpC,UAAI,GAAG,WAAW;AAChB,iBAAS,OAAO,KAAK,uDAAuD;AAC5E,cAAM,GAAG,WAAW;AAAA,MACtB;AACA,eAAS,OAAO,KAAK,gCAAgC;AACrD,YAAM,GAAG,QAAQ,SAAS;AAC1B,eAAS,OAAO,KAAK,6DAA6D;AAAA,IACpF;AACA,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AAAA,EACV,OAAO;AACL,SAAK,EAAE,EAAE;AAAA,EACX;AACA,QAAM,cAAc;AACpB,MAAI;AACJ,MAAI,EAAE,EAAE,MAAM,YAAY,EAAE,EAAE,MAAM,aAAa;AAC/C,SAAK,YAAY;AACf,YAAM,YAAY,SAAS;AAC3B,eAAS,OAAO,KAAK,8BAA8B;AAAA,IACrD;AACA,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AAAA,EACV,OAAO;AACL,SAAK,EAAE,EAAE;AAAA,EACX;AACA,QAAM,QAAQ;AACd,MAAI;AACJ,MAAI,EAAE,EAAE,MAAM,YAAY,EAAE,EAAE,MAAM,aAAa;AAC/C,SAAK,YAAY;AACf,YAAM,YAAY,WAAW;AAC7B,eAAS,OAAO,KAAK,+BAA+B;AAAA,IACtD;AACA,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AAAA,EACV,OAAO;AACL,SAAK,EAAE,EAAE;AAAA,EACX;AACA,QAAM,SAAS;AACf,MAAI;AACJ,MAAI,EAAE,EAAE,MAAM,MAAM,EAAE,EAAE,MAAM,UAAU;AACtC,SAAK,YAAY;AACf,UAAI,CAAC,IAAI;AACP,iBAAS,OAAO,KAAK,sDAAsD;AAC3E;AAAA,MACF;AACA,eAAS,OAAO,KAAK,mCAAmC;AACxD,YAAM,GAAG,WAAW;AACpB,eAAS,OAAO,KAAK,+BAA+B;AAAA,IACtD;AACA,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AAAA,EACV,OAAO;AACL,SAAK,EAAE,EAAE;AAAA,EACX;AACA,QAAM,aAAa;AACnB,MAAI;AACJ,MAAI,EAAE,EAAE,MAAM,aAAa,EAAE,EAAE,MAAM,UAAU;AAC7C,SAAK,WAAS;AACZ,eAAS,UAAU;AACnB,UAAI,aAAa,OAAO;AACtB,kBAAU,oBAAoB,MAAM,GAAG;AACvC,iBAAS,OAAO,KAAK,+BAA+B,KAAK;AAAA,MAC3D;AAAA,IACF;AACA,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AAAA,EACV,OAAO;AACL,SAAK,EAAE,EAAE;AAAA,EACX;AACA,QAAM,WAAW;AACjB,MAAI;AACJ,MAAI,EAAE,EAAE,MAAM,cAAc,EAAE,EAAE,MAAM,SAAS,EAAE,EAAE,MAAM,UAAU,EAAE,EAAE,MAAM,YAAY,EAAE,EAAE,MAAM,eAAe,EAAE,EAAE,MAAM,WAAW,EAAE,EAAE,MAAM,aAAa;AAC5J,SAAK;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AAAA,EACV,OAAO;AACL,SAAK,EAAE,EAAE;AAAA,EACX;AACA,SAAO;AACT;AAwBO,SAAS,cAAc;AAC5B,QAAM,IAAI,GAAG,CAAC;AACd,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,mBAAmB;AACvB,QAAM,KAAK,oBAAoB,aAAa;AAC5C,QAAM,KAAK,aAAa;AACxB,MAAI;AACJ,MAAI,EAAE,CAAC,MAAM,oBAAoB,EAAE,CAAC,MAAM,eAAe,EAAE,CAAC,MAAM,YAAY,EAAE,CAAC,MAAM,MAAM,EAAE,CAAC,MAAM,IAAI;AACxG,SAAK;AAAA,MACH,MAAM;AAAA,MACN,SAAS;AAAA,MACT,WAAW;AAAA,MACX,aAAa;AAAA,MACb;AAAA,IACF;AACA,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AAAA,EACT,OAAO;AACL,SAAK,EAAE,CAAC;AAAA,EACV;AACA,SAAO;AACT;AAgDO,SAAS,iBAAiB;AAC/B,QAAM,IAAI,GAAG,CAAC;AACd,QAAM,UAAU,mBAAmB;AACnC,MAAI;AACJ,MAAI,EAAE,CAAC,MAAM,QAAQ,kCAAkC,EAAE,CAAC,MAAM,QAAQ,2BAA2B,EAAE,CAAC,MAAM,QAAQ,qBAAqB,EAAE,CAAC,MAAM,QAAQ,2BAA2B,EAAE,CAAC,MAAM,QAAQ,qBAAqB,EAAE,CAAC,MAAM,QAAQ,kBAAkB;AAC5P,SAAK;AAAA,MACH,WAAW,QAAQ;AAAA,MACnB,aAAa,QAAQ;AAAA,MACrB,mBAAmB,QAAQ;AAAA,MAC3B,YAAY,QAAQ;AAAA,MACpB,aAAa,QAAQ;AAAA,MACrB,0BAA0B,QAAQ;AAAA,IACpC;AACA,MAAE,CAAC,IAAI,QAAQ;AACf,MAAE,CAAC,IAAI,QAAQ;AACf,MAAE,CAAC,IAAI,QAAQ;AACf,MAAE,CAAC,IAAI,QAAQ;AACf,MAAE,CAAC,IAAI,QAAQ;AACf,MAAE,CAAC,IAAI,QAAQ;AACf,MAAE,CAAC,IAAI;AAAA,EACT,OAAO;AACL,SAAK,EAAE,CAAC;AAAA,EACV;AACA,SAAO;AACT;AA8BO,SAAS,sBAAsB;AACpC,QAAM,UAAU,WAAW,uBAAuB;AAClD,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,6DAA6D;AAAA,EAC/E;AACA,SAAO,QAAQ;AACjB;AA6BO,SAAS,iBAAiB;AAC/B,QAAM,UAAU,WAAW,kBAAkB;AAC7C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,wDAAwD;AAAA,EAC1E;AACA,SAAO,QAAQ;AACjB;AAkCO,SAAS,qBAAqB;AACnC,SAAO,WAAW,sBAAsB;AAC1C;AAgCO,SAAS,0BAA0B;AACxC,QAAM;AAAA,IACJ;AAAA,EACF,IAAI,aAAa;AACjB,SAAO;AACT;AAyBO,SAAS,cAAc;AAC5B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,aAAa;AACjB,MAAI,OAAO;AACT,UAAM;AAAA,EACR;AACA,MAAI,CAAC,WAAW,CAAC,IAAI;AACnB,UAAM,IAAI,MAAM,iCAAiC;AAAA,EACnD;AACA,SAAO;AACT;AAuBO,SAAS,cAAc;AAC5B,QAAM;AAAA,IACJ;AAAA,EACF,IAAI,aAAa;AACjB,SAAO;AACT;AAoBO,SAAS,kBAAkB;AAChC,QAAM,IAAI,GAAG,CAAC;AACd,QAAM;AAAA,IACJ;AAAA,EACF,IAAI,aAAa;AACjB,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,IAAI;AAC7C,MAAI;AACJ,MAAI,EAAE,CAAC,MAAM,SAAS,SAAS;AAC7B,SAAK,MAAM;AACT,eAAS,QAAQ,YAAY,EAAE,KAAK,WAAW;AAC/C,YAAM,cAAc,SAAS,QAAQ,sBAAsB,WAAW;AACtE,aAAO;AAAA,IACT;AACA,MAAE,CAAC,IAAI,SAAS;AAChB,MAAE,CAAC,IAAI;AAAA,EACT,OAAO;AACL,SAAK,EAAE,CAAC;AAAA,EACV;AACA,MAAI;AACJ,MAAI,EAAE,CAAC,MAAM,UAAU;AACrB,SAAK,CAAC,QAAQ;AACd,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AAAA,EACT,OAAO;AACL,SAAK,EAAE,CAAC;AAAA,EACV;AACA,YAAU,IAAI,EAAE;AAChB,SAAO;AACT;AA8BO,SAAS,sBAAsB;AACpC,QAAM,IAAI,GAAG,CAAC;AACd,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,EACF,IAAI,2BAA2B;AAC/B,MAAI;AACJ,MAAI,EAAE,CAAC,MAAM,gBAAgB,EAAE,CAAC,MAAM,kBAAkB;AACtD,SAAK;AAAA,MACH,WAAW;AAAA,MACX,OAAO;AAAA,IACT;AACA,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AAAA,EACT,OAAO;AACL,SAAK,EAAE,CAAC;AAAA,EACV;AACA,SAAO;AACT;AA0BO,SAAS,eAAe;AAC7B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,EACF,IAAI,uBAAuB;AAC3B,SAAO,aAAa;AACtB;AAyBO,SAAS,sBAAsB;AACpC,QAAM;AAAA,IACJ;AAAA,EACF,IAAI,uBAAuB;AAC3B,SAAO;AACT;AA4CO,SAAS,oBAAoB,UAAsD;AAExF,QAAM;AAAA,IACJ;AAAA,EACF,IAAI,2BAA2B;AAC/B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,EACF,IAAI,6BAA6B;AACjC,QAAM,CAAC,EAAE,WAAW,IAAI,SAAS,CAAC;AAGlC,QAAM,oBAAoB,OAA4B,oBAAI,IAAI,CAAC;AAI/D,QAAM,yBAAyB,QAAQ,MAAM;AAC3C,QAAI,CAAC,SAAU,QAAO,CAAC;AACvB,WAAO,iBAAiB,OAAO,WAAS,MAAM,OAAO,YAAY,OAAO,MAAM,QAAQ,EAAE,MAAM,QAAQ;AAAA,EACxG,GAAG,CAAC,UAAU,gBAAgB,CAAC;AAG/B,QAAM,oBAAoB,QAAQ,MAAM;AACtC,QAAI,CAAC,SAAU,QAAO;AACtB,WAAO,mBAAmB,KAAK,QAAM,GAAG,kBAAkB,SAAS,QAAQ,CAAC,KAAK;AAAA,EACnF,GAAG,CAAC,UAAU,kBAAkB,CAAC;AAGjC,QAAM,gBAAgB,OAAO,KAAK;AAClC,QAAM,qBAAqB,uBAAuB,SAAS;AAI3D,YAAU,MAAM;AACd,QAAI,CAAC,SAAU;AACf,QAAI,cAAc,WAAW,CAAC,sBAAsB,CAAC,mBAAmB;AACtE,wBAAkB,QAAQ,IAAI,UAAU,KAAK,IAAI,CAAC;AAGlD,YAAM,QAAQ,WAAW,MAAM;AAC7B,cAAM,WAAW,kBAAkB,QAAQ,IAAI,QAAQ;AACvD,YAAI,YAAY,KAAK,IAAI,IAAI,YAAY,4BAA4B;AACnE,4BAAkB,QAAQ,OAAO,QAAQ;AACzC,sBAAY,OAAK,IAAI,CAAC;AAAA,QACxB;AAAA,MACF,GAAG,0BAA0B;AAC7B,aAAO,MAAM;AACX,qBAAa,KAAK;AAClB,0BAAkB,QAAQ,OAAO,QAAQ;AAAA,MAC3C;AAAA,IACF;AACA,kBAAc,UAAU;AAAA,EAC1B,GAAG,CAAC,UAAU,oBAAoB,iBAAiB,CAAC;AAGpD,QAAM,QAAQ,QAAQ,MAAuB;AAC3C,QAAI,CAAC,SAAU,QAAO;AAKtB,QAAI,mBAAmB;AACrB,aAAO;AAAA,IACT;AAGA,QAAI,uBAAuB,SAAS,GAAG;AACrC,aAAO;AAAA,IACT;AAGA,UAAM,aAAa,kBAAkB,QAAQ,IAAI,QAAQ;AACzD,QAAI,cAAc,KAAK,IAAI,IAAI,aAAa,4BAA4B;AACtE,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,GAAG,CAAC,UAAU,mBAAmB,uBAAuB,MAAM,CAAC;AAG/D,QAAM,QAAQ,mBAAmB,SAAS;AAG1C,QAAM,UAAU,YAAY,MAAM;AAChC,QAAI,mBAAmB;AACrB,mBAAa,kBAAkB,EAAE;AAAA,IACnC;AAAA,EACF,GAAG,CAAC,mBAAmB,YAAY,CAAC;AACpC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,mBAAmB,uBAAuB;AAAA,IAC1C;AAAA,IACA;AAAA,EACF;AACF;AA4CO,SAAS,kBAAkB;AAChC,QAAM,IAAI,GAAG,EAAE;AACf,QAAM;AAAA,IACJ;AAAA,EACF,IAAI,2BAA2B;AAC/B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,6BAA6B;AACjC,QAAM;AAAA,IACJ;AAAA,EACF,IAAI,eAAe;AACnB,MAAI;AACJ,MAAI,EAAE,CAAC,MAAM,aAAa;AACxB,SAAK,YAAY;AACf,YAAM,YAAY;AAAA,IACpB;AACA,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AAAA,EACT,OAAO;AACL,SAAK,EAAE,CAAC;AAAA,EACV;AACA,QAAM,WAAW;AACjB,MAAI;AACJ,MAAI,EAAE,CAAC,MAAM,cAAc;AACzB,SAAK,eAAa;AAChB,mBAAa,SAAS;AAAA,IACxB;AACA,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AAAA,EACT,OAAO;AACL,SAAK,EAAE,CAAC;AAAA,EACV;AACA,QAAM,iBAAiB;AACvB,QAAM,KAAK,sBAAsB;AACjC,MAAI;AACJ,MAAI,EAAE,CAAC,MAAM,kBAAkB,EAAE,CAAC,MAAM,sBAAsB,EAAE,CAAC,MAAM,mBAAmB,EAAE,CAAC,MAAM,gBAAgB,EAAE,CAAC,MAAM,uBAAuB,EAAE,CAAC,MAAM,YAAY,EAAE,EAAE,MAAM,IAAI;AACpL,SAAK;AAAA,MACH;AAAA,MACA,aAAa,mBAAmB;AAAA,MAChC,uBAAuB;AAAA,MACvB,WAAW;AAAA,MACX,oBAAoB;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AAAA,EACV,OAAO;AACL,SAAK,EAAE,EAAE;AAAA,EACX;AACA,SAAO;AACT;AA8DO,SAAS,kBAAkB;AAChC,QAAM,IAAI,GAAG,EAAE;AACf,QAAM;AAAA,IACJ;AAAA,EACF,IAAI,2BAA2B;AAC/B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,6BAA6B;AACjC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,gCAAgC;AACpC,QAAM;AAAA,IACJ,WAAW;AAAA,IACX,aAAa;AAAA,EACf,IAAI,uBAAuB;AAC3B,QAAM;AAAA,IACJ;AAAA,EACF,IAAI,eAAe;AACnB,MAAI;AACJ,MAAI,EAAE,CAAC,MAAM,aAAa;AACxB,SAAK,YAAY;AACf,YAAM,YAAY;AAAA,IACpB;AACA,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AAAA,EACT,OAAO;AACL,SAAK,EAAE,CAAC;AAAA,EACV;AACA,QAAM,WAAW;AACjB,MAAI;AACJ,MAAI,EAAE,CAAC,MAAM,cAAc;AACzB,SAAK,eAAa;AAChB,mBAAa,SAAS;AAAA,IACxB;AACA,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AAAA,EACT,OAAO;AACL,SAAK,EAAE,CAAC;AAAA,EACV;AACA,QAAM,iBAAiB;AACvB,MAAI;AACJ,MAAI,EAAE,CAAC,MAAM,uBAAuB;AAClC,SAAK,MAAM;AACT,4BAAsB;AAAA,IACxB;AACA,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AAAA,EACT,OAAO;AACL,SAAK,EAAE,CAAC;AAAA,EACV;AACA,QAAM,iBAAiB;AACvB,MAAI;AACJ,MAAI,EAAE,CAAC,MAAM,sBAAsB,UAAU,EAAE,CAAC,MAAM,mBAAmB,UAAU,EAAE,CAAC,MAAM,yBAAyB,UAAU,EAAE,CAAC,MAAM,iBAAiB,QAAQ;AAC/J,SAAK;AAAA,MACH,SAAS,iBAAiB;AAAA,MAC1B,QAAQ,mBAAmB;AAAA,MAC3B,WAAW,sBAAsB;AAAA,MACjC,cAAc,yBAAyB;AAAA,IACzC;AACA,MAAE,CAAC,IAAI,sBAAsB;AAC7B,MAAE,CAAC,IAAI,mBAAmB;AAC1B,MAAE,CAAC,IAAI,yBAAyB;AAChC,MAAE,CAAC,IAAI,iBAAiB;AACxB,MAAE,EAAE,IAAI;AAAA,EACV,OAAO;AACL,SAAK,EAAE,EAAE;AAAA,EACX;AACA,QAAM,SAAS;AACf,QAAM,cAAc,eAAe,iBAAiB,mBAAmB,SAAS;AAChF,MAAI;AACJ,MAAI,EAAE,EAAE,MAAM,kBAAkB,EAAE,EAAE,MAAM,sBAAsB,EAAE,EAAE,MAAM,yBAAyB,EAAE,EAAE,MAAM,UAAU,EAAE,EAAE,MAAM,kBAAkB,EAAE,EAAE,MAAM,sBAAsB,EAAE,EAAE,MAAM,eAAe,EAAE,EAAE,MAAM,2BAA2B,EAAE,EAAE,MAAM,4BAA4B,EAAE,EAAE,MAAM,oBAAoB,EAAE,EAAE,MAAM,YAAY,EAAE,EAAE,MAAM,cAAc;AACjW,SAAK;AAAA,MACH,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,cAAc;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AAAA,EACV,OAAO;AACL,SAAK,EAAE,EAAE;AAAA,EACX;AACA,SAAO;AACT;AAeO,IAAM,wBAAwB;AAM9B,IAAM,2BAA2B;AAqBxC,IAAM,4BAAsE;AAAA,EAC1E,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,qBAAqB;AAAA,EACrB,cAAc;AAAA,EACd,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,MAAM;AACR;AAmBO,SAAS,yBAAyB;AACvC,QAAM,IAAI,GAAG,CAAC;AACd,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,mBAAmB;AACvB,QAAM;AAAA,IACJ;AAAA,EACF,IAAI,uBAAuB;AAC3B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,EACF,IAAI,oBAAoB;AACxB,MAAI,SAAS;AACb,MAAI,aAAa,WAAW;AAC1B,aAAS,gBAAgB,iBAAiB;AAAA,EAC5C,OAAO;AACL,QAAI,aAAa,aAAa;AAC5B,eAAS;AAAA,IACX,OAAO;AACL,UAAI,CAAC,kBAAkB;AACrB,iBAAS;AAAA,MACX,OAAO;AACL,YAAI,CAAC,aAAa,CAAC,YAAY;AAC7B,mBAAS;AAAA,QACX,OAAO;AACL,cAAI,YAAY;AACd,qBAAS;AAAA,UACX,OAAO;AACL,gBAAI,WAAW;AACb,uBAAS;AAAA,YACX;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,QAAM,YAAY,WAAW,UAAU,WAAW;AAClD,QAAM,cAAc,0BAA0B,MAAM;AACpD,MAAI;AACJ,MAAI,EAAE,CAAC,MAAM,eAAe,EAAE,CAAC,MAAM,aAAa,EAAE,CAAC,MAAM,UAAU,EAAE,CAAC,MAAM,WAAW;AACvF,SAAK;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,MACA,aAAa;AAAA,IACf;AACA,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AAAA,EACT,OAAO;AACL,SAAK,EAAE,CAAC;AAAA,EACV;AACA,SAAO;AACT;AAmBA,SAAS,gBAAgB,IAAoB;AAC3C,MAAI,MAAM,EAAG,QAAO;AACpB,QAAM,eAAe,KAAK,KAAK,KAAK,GAAI;AACxC,QAAM,UAAU,KAAK,MAAM,eAAe,EAAE;AAC5C,QAAM,UAAU,eAAe;AAC/B,MAAI,YAAY,GAAG;AACjB,WAAO,GAAG,OAAO;AAAA,EACnB,WAAW,YAAY,GAAG;AACxB,WAAO,GAAG,OAAO;AAAA,EACnB,OAAO;AACL,WAAO,GAAG,OAAO,KAAK,OAAO;AAAA,EAC/B;AACF;AAoBO,SAAS,oBAAoB;AAClC,QAAM,IAAI,GAAG,EAAE;AACf,QAAM;AAAA,IACJ;AAAA,EACF,IAAI,6BAA6B;AACjC,QAAM,CAAC,KAAK,MAAM,IAAI,SAAS,KAAK;AACpC,MAAI,WAAW;AACf,MAAI,EAAE,CAAC,MAAM,YAAY,EAAE,CAAC,MAAM,oBAAoB;AACpD,eAAW,MAAM,oBAAoB;AACnC,UAAI,GAAG,aAAa;AAClB,YAAI,CAAC,YAAY,GAAG,cAAc,UAAU;AAC1C,qBAAW,GAAG;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AACA,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AAAA,EACT,OAAO;AACL,eAAW,EAAE,CAAC;AAAA,EAChB;AACA,QAAM,eAAe;AACrB,MAAI;AACJ,OAAK;AACH,QAAI,CAAC,cAAc;AACjB,WAAK;AACL,YAAM;AAAA,IACR;AACA,SAAK,KAAK,IAAI,GAAG,aAAa,QAAQ,IAAI,GAAG;AAAA,EAC/C;AACA,QAAM,mBAAmB;AACzB,MAAI;AACJ,MAAI;AACJ,MAAI,EAAE,CAAC,MAAM,cAAc;AACzB,SAAK,MAAM;AACT,UAAI,CAAC,cAAc;AACjB;AAAA,MACF;AACA,UAAI,YAAY;AAChB,YAAM,OAAO,MAAM;AACjB,YAAI,WAAW;AACb,iBAAO,KAAK,IAAI,CAAC;AAAA,QACnB;AAAA,MACF;AACA,WAAK;AACL,YAAM,WAAW,YAAY,MAAM,GAAI;AACvC,aAAO,MAAM;AACX,oBAAY;AACZ,sBAAc,QAAQ;AAAA,MACxB;AAAA,IACF;AACA,SAAK,CAAC,YAAY;AAClB,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AAAA,EACT,OAAO;AACL,SAAK,EAAE,CAAC;AACR,SAAK,EAAE,CAAC;AAAA,EACV;AACA,YAAU,IAAI,EAAE;AAChB,MAAI;AACJ,MAAI,EAAE,CAAC,MAAM,gBAAgB,EAAE,CAAC,MAAM,kBAAkB;AACtD,SAAK,eAAe,gBAAgB,gBAAgB,IAAI;AACxD,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AACP,MAAE,CAAC,IAAI;AAAA,EACT,OAAO;AACL,SAAK,EAAE,CAAC;AAAA,EACV;AACA,MAAI;AACJ,MAAI,EAAE,CAAC,MAAM,gBAAgB,EAAE,EAAE,MAAM,MAAM,EAAE,EAAE,MAAM,kBAAkB;AACvE,SAAK;AAAA,MACH,aAAa;AAAA,MACb;AAAA,MACA,oBAAoB;AAAA,IACtB;AACA,MAAE,CAAC,IAAI;AACP,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AACR,MAAE,EAAE,IAAI;AAAA,EACV,OAAO;AACL,SAAK,EAAE,EAAE;AAAA,EACX;AACA,SAAO;AACT;AACA,SAAS,QAAQ;AACf,SAAO,KAAK,IAAI;AAClB;","names":[]}
@@ -41,4 +41,4 @@ export {
41
41
  DEFAULT_SYNC_METRICS,
42
42
  DEFAULT_SYNC_CONFIG
43
43
  };
44
- //# sourceMappingURL=chunk-24RDMMCL.js.map
44
+ //# sourceMappingURL=chunk-FNYQFILT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/provider/types.ts"],"sourcesContent":["/**\n * Provider Types for @pol-studios/powersync\n *\n * Defines configuration and context interfaces for the PowerSyncProvider.\n */\n\nimport type { SupabaseClient } from '@supabase/supabase-js';\nimport type { QueryClient } from '@tanstack/react-query';\nimport type { AbstractPowerSyncDatabase, SyncStatus, ConnectionHealth, SyncMetrics, CrudEntry, FailedTransaction, CompletedTransaction, SyncMode, DownloadProgress } from '../core/types';\nimport type { PlatformAdapter } from '../platform/types';\nimport type { ConnectorConfig } from '../connector/types';\nimport type { AttachmentConfig } from '../attachments/types';\nimport type { PolAttachmentQueue } from '../attachments/pol-attachment-queue';\nimport type { SupabaseConnector } from '../connector/supabase-connector';\nimport type { ConflictBus } from '../conflicts/conflict-bus';\n\n// ─── Provider Configuration ──────────────────────────────────────────────────\n\n/**\n * Main configuration for PowerSyncProvider.\n *\n * @template TSchema - The PowerSync schema type\n *\n * @example\n * ```typescript\n * const config: PowerSyncConfig<AppSchema> = {\n * platform: createNativePlatformAdapter(logger),\n * schema: AppSchema,\n * powerSyncUrl: 'https://your-powersync-instance.com',\n * supabaseClient: supabase,\n * dbFilename: 'myapp.db',\n * sync: {\n * autoConnect: true,\n * },\n * };\n * ```\n */\nexport interface PowerSyncConfig<TSchema = unknown> {\n /**\n * Platform adapter for platform-specific operations.\n * Use createNativePlatformAdapter() for React Native or createWebPlatformAdapter() for Web.\n */\n platform: PlatformAdapter;\n\n /**\n * PowerSync schema definition.\n * This defines the tables and their structure for the local database.\n */\n schema: TSchema;\n\n /**\n * PowerSync service URL.\n * @example \"https://your-instance.powersync.journeyapps.com\"\n */\n powerSyncUrl: string;\n\n /**\n * Supabase client instance.\n * Used for authentication and as the backend for CRUD uploads.\n */\n supabaseClient: SupabaseClient;\n\n /**\n * Optional: TanStack Query client for cache invalidation.\n * If provided, will invalidate queries when sync completes.\n */\n queryClient?: QueryClient;\n\n /**\n * Optional: Database filename.\n * @default \"powersync.db\"\n */\n dbFilename?: string;\n\n /**\n * Optional: Connector configuration for custom CRUD handling.\n */\n connector?: ConnectorConfig;\n\n /**\n * Optional: Attachment queue configuration for offline file caching.\n *\n * @example\n * ```typescript\n * attachments: {\n * source: { table: 'photos', idColumn: 'storage_path' },\n * remoteStorage: supabaseStorageAdapter,\n * }\n * ```\n */\n attachments?: AttachmentConfig;\n\n /**\n * Optional: Sync behavior configuration.\n */\n sync?: SyncConfig;\n}\n\n/**\n * Sync behavior configuration.\n */\nexport interface SyncConfig {\n /**\n * Automatically connect when the provider mounts and there's an authenticated session.\n * @default true\n */\n autoConnect?: boolean;\n\n /**\n * Sync interval for periodic sync checks (in milliseconds).\n * Set to 0 to disable periodic sync.\n * @default 0 (disabled)\n */\n syncInterval?: number;\n\n /**\n * Enable health monitoring.\n * @default true\n */\n enableHealthMonitoring?: boolean;\n\n /**\n * Enable metrics collection.\n * @default true\n */\n enableMetrics?: boolean;\n}\n\n// ─── Context Types ───────────────────────────────────────────────────────────\n\n/**\n * Value provided by the main PowerSyncContext.\n *\n * @template TSchema - The PowerSync schema type\n */\nexport interface PowerSyncContextValue<TSchema = unknown> {\n /**\n * The PowerSync database instance.\n * Will be null if not initialized or if initialization failed.\n */\n db: AbstractPowerSyncDatabase | null;\n\n /**\n * The Supabase connector instance.\n * Will be null if not initialized.\n */\n connector: SupabaseConnector | null;\n\n /**\n * The attachment queue instance.\n * Will be null if attachments are not configured or not initialized.\n */\n attachmentQueue: PolAttachmentQueue | null;\n\n /**\n * Whether the PowerSync database is ready for use.\n */\n isReady: boolean;\n\n /**\n * Whether the provider is currently initializing.\n */\n isInitializing: boolean;\n\n /**\n * Whether the attachment queue is ready for use.\n * This is separate from isReady because the attachment queue initializes\n * asynchronously after the database is ready.\n *\n * States:\n * - `false`: Attachment queue is still initializing\n * - `true` with `attachmentQueue !== null`: Ready and available\n * - `true` with `attachmentQueue === null`: Either attachments not configured, OR initialization failed\n */\n attachmentQueueReady: boolean;\n\n /**\n * Error that occurred during initialization, if any.\n */\n error: Error | null;\n\n /**\n * The schema used for this database.\n */\n schema: TSchema;\n\n /**\n * The platform adapter instance.\n */\n platform: PlatformAdapter;\n\n /**\n * The conflict bus for subscribing to conflict events.\n * Use this to wire up conflict UI components.\n */\n conflictBus: ConflictBus;\n}\n\n/**\n * Value provided by SyncStatusContext.\n */\nexport interface SyncStatusContextValue {\n /**\n * Current sync status.\n */\n status: SyncStatus;\n\n /**\n * Pending mutations waiting to be uploaded.\n */\n pendingMutations: CrudEntry[];\n\n /**\n * Number of pending mutations.\n */\n pendingCount: number;\n\n /**\n * Whether data is currently being uploaded to the server.\n * This is the authoritative source for upload activity.\n */\n isUploading: boolean;\n\n /**\n * Whether data is currently being downloaded from the server.\n * This is the authoritative source for download activity.\n */\n isDownloading: boolean;\n\n /**\n * Whether sync is currently paused (offline mode).\n */\n isPaused: boolean;\n\n /**\n * Current sync mode: 'push-pull' (full sync), 'pull-only' (download only), or 'offline' (no sync).\n */\n syncMode: SyncMode;\n\n /**\n * Timestamp of the last successful sync.\n */\n lastSyncedAt: Date | null;\n\n /**\n * Error that occurred during connection, if any.\n */\n connectionError: Error | null;\n\n /**\n * Failed transactions that need attention.\n */\n failedTransactions: FailedTransaction[];\n\n /**\n * Whether there are any upload errors.\n */\n hasUploadErrors: boolean;\n\n /**\n * Count of permanent errors that need user action.\n */\n permanentErrorCount: number;\n\n /**\n * Clear a specific failure by its ID.\n */\n clearFailure: (failureId: string) => void;\n\n /**\n * Completed transactions history.\n */\n completedTransactions: CompletedTransaction[];\n\n /**\n * Clear the completed transaction history.\n */\n clearCompletedHistory: () => void;\n\n /**\n * Set the sync mode.\n * @param mode - The sync mode to set\n */\n setSyncMode: (mode: SyncMode) => Promise<void>;\n\n /**\n * Set the force next upload flag.\n * When true, the next sync cycle will upload regardless of sync mode.\n */\n setForceNextUpload: (force: boolean) => void;\n\n /**\n * Discard a specific pending mutation by its client ID.\n * Uses safe disconnect/reconnect pattern to avoid transaction conflicts.\n * @throws Error if upload is in progress\n */\n discardPendingMutation: (clientId: number) => Promise<void>;\n\n // ─── Upload Retry State ─────────────────────────────────────────────────────\n /**\n * Whether we're currently waiting for a retry after upload failure.\n */\n isWaitingForUploadRetry: boolean;\n /**\n * When the next retry will occur (null if not waiting).\n */\n nextUploadRetryAt: Date | null;\n /**\n * Whether the maximum retry attempts have been reached.\n */\n maxUploadRetriesReached: boolean;\n /**\n * Current retry attempt count.\n */\n uploadRetryCount: number;\n /**\n * Force a manual retry after max retries reached.\n */\n manualUploadRetry: () => Promise<void>;\n /**\n * Discard a specific failed entry by its ps_crud ID and reconnect.\n * Use this when a single entry is causing upload failures.\n * @param entryId - The ps_crud entry ID (clientId) to discard\n */\n discardFailedEntryAndReconnect: (entryId: number) => Promise<void>;\n}\n\n// ─── Split Context Types (Performance Optimization) ─────────────────────────\n// These focused contexts allow components to subscribe to only the data they need,\n// preventing re-renders when unrelated data changes.\n\n/**\n * Connection state - changes rarely (on connect/disconnect).\n * Use this for components that only need to display connection status.\n */\nexport interface ConnectionStatusContextValue {\n /** Whether connected to the PowerSync service */\n connected: boolean;\n /** Whether currently attempting to connect */\n connecting: boolean;\n /** Whether initial sync has completed */\n hasSynced: boolean;\n /** Timestamp of last successful sync */\n lastSyncedAt: Date | null;\n /** Error that occurred during connection, if any */\n connectionError: Error | null;\n}\n\n/**\n * Sync activity - changes during active sync.\n * Use this for components that display sync progress.\n */\nexport interface SyncActivityContextValue {\n /** Whether data is currently being uploaded to the server */\n uploading: boolean;\n /** Whether data is currently being downloaded from the server */\n downloading: boolean;\n /** Download progress details */\n downloadProgress: DownloadProgress | null;\n}\n\n/**\n * Pending mutations - changes on local writes.\n * Use this for components that display pending upload count or list.\n */\nexport interface PendingMutationsContextValue {\n /** Pending mutations waiting to be uploaded */\n pendingMutations: CrudEntry[];\n /** Number of pending mutations */\n pendingCount: number;\n /** Discard a specific pending mutation by its client ID */\n discardPendingMutation: (clientId: number) => Promise<void>;\n /**\n * Add a pending mutation to the list.\n * Called by mutation hooks (useDbInsert, useDbUpdate, useDbDelete, useDbUpsert)\n * after a successful write. Includes createdAt timestamp for display.\n */\n addPendingMutation: (entry: CrudEntry) => void;\n /**\n * Remove a pending mutation by its entity ID.\n * Called when a transaction completes sync.\n */\n removePendingMutation: (id: string) => void;\n}\n\n/**\n * Failed transactions - changes on failures.\n * Use this for components that display sync errors.\n */\nexport interface FailedTransactionsContextValue {\n /** Failed transactions that need attention */\n failedTransactions: FailedTransaction[];\n /** Whether there are any upload errors */\n hasUploadErrors: boolean;\n /** Count of permanent errors that need user action */\n permanentErrorCount: number;\n /** Clear a specific failure by its ID */\n clearFailure: (failureId: string) => void;\n /**\n * Retry a specific failed transaction.\n *\n * This removes the failure from tracking and triggers a sync.\n * The actual CRUD entries remain in PowerSync's queue - this just\n * clears our error tracking so the sync can retry them.\n *\n * If the sync fails to start, the failure is re-recorded.\n */\n retryFailure: (failureId: string) => Promise<void>;\n}\n\n/**\n * Completed transactions - changes on successful syncs.\n * Use this for components that display sync history.\n */\nexport interface CompletedTransactionsContextValue {\n /** Recently completed transactions */\n completedTransactions: CompletedTransaction[];\n /** Clear the completed transaction history */\n clearCompletedHistory: () => void;\n /** Clear a specific completed transaction by ID */\n clearCompletedItem: (completedId: string) => void;\n /**\n * Completed transactions that occurred AFTER the last notification display.\n * Use this for toast/banner notifications to avoid showing stale historical counts.\n */\n newCompletedTransactions: CompletedTransaction[];\n /**\n * Mark notifications as seen (updates the lastNotificationTime).\n * Call this when a sync notification is displayed or auto-dismissed.\n */\n markNotificationsAsSeen: () => void;\n}\n\n/**\n * Sync mode control - changes rarely (user action).\n * Use this for components that display/control sync mode.\n */\nexport interface SyncModeContextValue {\n /** Current sync mode */\n syncMode: SyncMode;\n /** Whether sync is currently paused (offline mode) */\n isPaused: boolean;\n /**\n * Whether offline mode was automatically set 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 */\n isAutoOffline: boolean;\n /**\n * Whether the network is currently reachable.\n * This is used as a gate to block uploads even when syncMode is 'push-pull'.\n */\n networkReachable: boolean;\n /** Set the sync mode (manual - won't auto-resume) */\n setSyncMode: (mode: SyncMode) => Promise<void>;\n /** Set the force next upload flag */\n setForceNextUpload: (force: boolean) => void;\n\n // ─── Upload Retry State ─────────────────────────────────────────────────────\n /**\n * Whether we're currently waiting for a retry after upload failure.\n * When true, PowerSync is disconnected and waiting for the backoff timer.\n */\n isWaitingForUploadRetry: boolean;\n /**\n * When the next retry will occur (null if not waiting).\n * Use this to display a countdown to the user.\n */\n nextUploadRetryAt: Date | null;\n /**\n * Whether the maximum retry attempts have been reached.\n * When true, the system won't automatically retry - user must intervene.\n */\n maxUploadRetriesReached: boolean;\n /**\n * Current retry attempt count (0 when no retries have occurred).\n */\n uploadRetryCount: number;\n /**\n * Force a manual retry after max retries reached.\n * Resets retry state and attempts to reconnect.\n */\n manualUploadRetry: () => Promise<void>;\n /**\n * Discard a specific failed entry by its ps_crud ID and reconnect.\n * Use this when a single entry is causing upload failures.\n * @param entryId - The ps_crud entry ID (clientId) to discard\n */\n discardFailedEntryAndReconnect: (entryId: number) => Promise<void>;\n}\n\n/**\n * Value provided by ConnectionHealthContext.\n */\nexport interface ConnectionHealthContextValue {\n /**\n * Current connection health status.\n */\n health: ConnectionHealth;\n}\n\n/**\n * Value provided by SyncMetricsContext.\n */\nexport interface SyncMetricsContextValue {\n /**\n * Current sync metrics.\n */\n metrics: SyncMetrics;\n}\n\n// ─── Provider Props ──────────────────────────────────────────────────────────\n\n/**\n * Props for the PowerSyncProvider component.\n *\n * @template TSchema - The PowerSync schema type\n */\nexport interface PowerSyncProviderProps<TSchema = unknown> {\n /**\n * PowerSync configuration.\n */\n config: PowerSyncConfig<TSchema>;\n\n /**\n * Child components to render.\n */\n children: React.ReactNode;\n\n /**\n * Called when the database is initialized and ready.\n */\n onReady?: () => void;\n\n /**\n * Called when an error occurs during initialization.\n */\n onError?: (error: Error) => void;\n\n /**\n * Called when sync status changes.\n */\n onSyncStatusChange?: (status: SyncStatus) => void;\n}\n\n// ─── Default Values ──────────────────────────────────────────────────────────\n\n/**\n * Default sync status.\n */\nexport const DEFAULT_SYNC_STATUS: SyncStatus = {\n connected: false,\n connecting: false,\n hasSynced: false,\n lastSyncedAt: null,\n uploading: false,\n downloading: false,\n downloadProgress: null,\n failedTransactions: [],\n hasUploadErrors: false,\n permanentErrorCount: 0\n};\n\n/**\n * Default connection health.\n */\nexport const DEFAULT_CONNECTION_HEALTH: ConnectionHealth = {\n status: 'disconnected',\n latency: null,\n lastHealthCheck: null,\n consecutiveFailures: 0,\n reconnectAttempts: 0\n};\n\n/**\n * Default sync metrics.\n */\nexport const DEFAULT_SYNC_METRICS: SyncMetrics = {\n totalSyncs: 0,\n successfulSyncs: 0,\n failedSyncs: 0,\n lastSyncDuration: null,\n averageSyncDuration: null,\n totalDataDownloaded: 0,\n totalDataUploaded: 0,\n lastError: null\n};\n\n/**\n * Default sync configuration.\n */\nexport const DEFAULT_SYNC_CONFIG: Required<SyncConfig> = {\n autoConnect: true,\n syncInterval: 0,\n enableHealthMonitoring: true,\n enableMetrics: true\n};"],"mappings":";AAsiBO,IAAM,sBAAkC;AAAA,EAC7C,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,cAAc;AAAA,EACd,WAAW;AAAA,EACX,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,oBAAoB,CAAC;AAAA,EACrB,iBAAiB;AAAA,EACjB,qBAAqB;AACvB;AAKO,IAAM,4BAA8C;AAAA,EACzD,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,iBAAiB;AAAA,EACjB,qBAAqB;AAAA,EACrB,mBAAmB;AACrB;AAKO,IAAM,uBAAoC;AAAA,EAC/C,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,WAAW;AACb;AAKO,IAAM,sBAA4C;AAAA,EACvD,aAAa;AAAA,EACb,cAAc;AAAA,EACd,wBAAwB;AAAA,EACxB,eAAe;AACjB;","names":[]}