lowdata 0.1.0 → 0.2.0

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 (42) hide show
  1. package/README.md +37 -4
  2. package/dist/{client-CqO3Y1J5.d.cts → client-BmsR0Pf6.d.cts} +8 -2
  3. package/dist/{client-BvdWSYIM.d.ts → client-DSKoYUj9.d.ts} +8 -2
  4. package/dist/forms.cjs +29 -11
  5. package/dist/forms.cjs.map +1 -1
  6. package/dist/forms.d.cts +4 -4
  7. package/dist/forms.d.ts +4 -4
  8. package/dist/forms.js +29 -11
  9. package/dist/forms.js.map +1 -1
  10. package/dist/index.cjs +29 -11
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.d.cts +4 -4
  13. package/dist/index.d.ts +4 -4
  14. package/dist/index.js +29 -11
  15. package/dist/index.js.map +1 -1
  16. package/dist/media.cjs +1 -1
  17. package/dist/media.cjs.map +1 -1
  18. package/dist/media.d.cts +2 -2
  19. package/dist/media.d.ts +2 -2
  20. package/dist/media.js +1 -1
  21. package/dist/media.js.map +1 -1
  22. package/dist/network.cjs +29 -11
  23. package/dist/network.cjs.map +1 -1
  24. package/dist/network.d.cts +7 -6
  25. package/dist/network.d.ts +7 -6
  26. package/dist/network.js +29 -11
  27. package/dist/network.js.map +1 -1
  28. package/dist/{progressiveImage-BhY_K8Dj.d.ts → progressiveImage-BOdic4dJ.d.ts} +1 -1
  29. package/dist/{progressiveImage-BWNdewbi.d.cts → progressiveImage-CDpz_rv3.d.cts} +1 -1
  30. package/dist/react.cjs +29 -11
  31. package/dist/react.cjs.map +1 -1
  32. package/dist/react.d.cts +4 -4
  33. package/dist/react.d.ts +4 -4
  34. package/dist/react.js +29 -11
  35. package/dist/react.js.map +1 -1
  36. package/dist/{retry-C3zL9T5Z.d.cts → retry-BnuESos0.d.cts} +1 -1
  37. package/dist/{retry-D6DfKGOi.d.ts → retry-CnvZhHan.d.ts} +1 -1
  38. package/dist/{types-Bn1BAcch.d.ts → types-1ha2HIfv.d.ts} +1 -1
  39. package/dist/{types-CZDYS-fB.d.cts → types-Cbm1nNDO.d.cts} +1 -1
  40. package/dist/{types--FRrBa-i.d.cts → types-D6fjl8Wy.d.cts} +22 -1
  41. package/dist/{types--FRrBa-i.d.ts → types-D6fjl8Wy.d.ts} +22 -1
  42. package/package.json +22 -2
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/network/types.ts","../src/core/events.ts","../src/core/connection.ts","../src/core/id.ts","../src/core/idb.ts","../src/network/errors.ts","../src/network/queue.ts","../src/core/backoff.ts","../src/core/abortAny.ts","../src/core/types.ts","../src/network/retry.ts","../src/core/lock.ts","../src/network/sync.ts","../src/network/client.ts"],"names":["_a"],"mappings":"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","file":"network.js","sourcesContent":["import type { ConnectionMonitorOptions } from '../core/connection.js';\nimport type { RequestPriority, RetryBackoffConfig } from '../core/types.js';\n\nexport type QueueItemStatus = 'pending' | 'sending' | 'failed' | 'done' | 'cancelled';\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n\nexport interface QueueItem {\n id: string;\n url: string;\n method: HttpMethod;\n headers?: Record<string, string>;\n body?: string | Blob | null;\n priority: RequestPriority;\n createdAt: number;\n updatedAt: number;\n attempts: number;\n status: QueueItemStatus;\n nextAttemptAt: number;\n lastError?: string;\n meta?: Record<string, unknown>;\n timeoutMs?: number;\n retry?: Partial<RetryBackoffConfig>;\n idempotencyKey?: string;\n}\n\nexport interface EnqueueOptions {\n priority?: RequestPriority;\n meta?: Record<string, unknown>;\n timeoutMs?: number;\n retry?: Partial<RetryBackoffConfig>;\n idempotencyKey?: string;\n /** Skip the live attempt and go straight to the persistent queue, even if currently online. */\n forceQueue?: boolean;\n}\n\n/** Result returned by `client.fetch()` when a request could not be sent live and was queued instead. */\nexport interface QueuedResult {\n queued: true;\n id: string;\n item: QueueItem;\n}\n\nexport function isQueued(result: Response | QueuedResult): result is QueuedResult {\n return typeof result === 'object' && result !== null && (result as QueuedResult).queued === true;\n}\n\nexport type SyncEvent =\n | { type: 'sync-start'; pending: number }\n | { type: 'item-start'; item: QueueItem }\n | { type: 'item-success'; item: QueueItem }\n | { type: 'item-failed'; item: QueueItem; willRetry: boolean }\n | { type: 'sync-complete'; succeeded: number; failed: number };\n\nexport interface LowdataClientConfig {\n /** Prefixed onto every relative URL passed to `fetch()`/`queue.add()`. */\n baseUrl?: string;\n defaultHeaders?: Record<string, string>;\n retry?: Partial<RetryBackoffConfig>;\n connection?: ConnectionMonitorOptions;\n /** How many queued items to send concurrently during a sync drain. Default 1 (conservative). */\n syncConcurrency?: number;\n /** Reject `queue.add()` for payloads larger than this. Default 5 MB. */\n maxQueueItemSizeBytes?: number;\n /**\n * Decide whether a failed/offline request should be queued for later instead of surfaced as an\n * error. Default: only mutating methods (POST/PUT/PATCH/DELETE) are queued; GET/HEAD are not,\n * since queuing a read rarely makes sense.\n */\n shouldQueueOffline?: (input: { url: string; method: HttpMethod }) => boolean;\n}\n","/** Tiny typed pub-sub. No Node `EventEmitter` dependency, works in any JS runtime. */\nexport class Emitter<T> {\n private listeners = new Set<(value: T) => void>();\n\n subscribe(listener: (value: T) => void): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n emit(value: T): void {\n for (const listener of this.listeners) {\n listener(value);\n }\n }\n\n clear(): void {\n this.listeners.clear();\n }\n\n get size(): number {\n return this.listeners.size;\n }\n}\n","import { Emitter } from './events.js';\nimport type {\n ConnectionInfo,\n ConnectionListener,\n ConnectionQuality,\n Unsubscribe,\n} from './types.js';\n\n/**\n * The Network Information API (`navigator.connection`) is Chromium-only and not part of the\n * standard DOM lib types, hence this local shape instead of a global augmentation.\n */\ninterface NetworkInformationLike {\n effectiveType?: '4g' | '3g' | '2g' | 'slow-2g';\n downlink?: number;\n rtt?: number;\n saveData?: boolean;\n addEventListener?: (type: 'change', listener: () => void) => void;\n removeEventListener?: (type: 'change', listener: () => void) => void;\n}\n\ntype NavigatorWithConnection = Navigator & { connection?: NetworkInformationLike };\n\nexport interface ConnectionMonitorOptions {\n /**\n * Opt-in latency probe URL used to detect 'slow' connections on browsers without the Network\n * Information API (Safari, Firefox). Never probed automatically on a timer — only once on\n * startup and once per reconnect — because every probe costs a little data.\n */\n pingUrl?: string;\n /** Round-trip time above which the ping probe classifies the connection as 'slow'. Default 600ms. */\n slowRttThresholdMs?: number;\n /** downlink (Mbps) below which the Network Information API classifies as 'slow'. Default 0.5. */\n slowDownlinkMbps?: number;\n /** Timeout for the ping probe itself, in ms. Default 5000. */\n pingTimeoutMs?: number;\n}\n\nconst DEFAULT_SLOW_RTT_MS = 600;\nconst DEFAULT_SLOW_DOWNLINK_MBPS = 0.5;\nconst DEFAULT_PING_TIMEOUT_MS = 5000;\n\nfunction hasNavigator(): boolean {\n return typeof navigator !== 'undefined';\n}\n\n/**\n * Tracks connection quality (online / slow / offline) using the best signal available:\n * `navigator.onLine` + online/offline events as the universal baseline, `navigator.connection`\n * where present, and an optional opt-in ping probe as a cross-browser fallback for 'slow'.\n */\nexport class ConnectionMonitor {\n private emitter = new Emitter<ConnectionInfo>();\n private current: ConnectionInfo;\n private probedRttMs: number | undefined;\n private readonly options: Required<\n Pick<ConnectionMonitorOptions, 'slowRttThresholdMs' | 'slowDownlinkMbps' | 'pingTimeoutMs'>\n > &\n Pick<ConnectionMonitorOptions, 'pingUrl'>;\n private disposed = false;\n private onlineHandler?: () => void;\n private offlineHandler?: () => void;\n private connectionChangeHandler?: () => void;\n\n constructor(options: ConnectionMonitorOptions = {}) {\n this.options = {\n pingUrl: options.pingUrl,\n slowRttThresholdMs: options.slowRttThresholdMs ?? DEFAULT_SLOW_RTT_MS,\n slowDownlinkMbps: options.slowDownlinkMbps ?? DEFAULT_SLOW_DOWNLINK_MBPS,\n pingTimeoutMs: options.pingTimeoutMs ?? DEFAULT_PING_TIMEOUT_MS,\n };\n this.current = this.computeInfo();\n\n if (hasNavigator() && typeof window !== 'undefined') {\n this.onlineHandler = () => {\n this.refresh();\n void this.probeNow();\n };\n this.offlineHandler = () => this.refresh();\n window.addEventListener('online', this.onlineHandler);\n window.addEventListener('offline', this.offlineHandler);\n\n const conn = (navigator as NavigatorWithConnection).connection;\n if (conn?.addEventListener) {\n this.connectionChangeHandler = () => this.refresh();\n conn.addEventListener('change', this.connectionChangeHandler);\n }\n }\n\n if (this.options.pingUrl) {\n void this.probeNow();\n }\n }\n\n getStatus(): ConnectionInfo {\n return this.current;\n }\n\n subscribe(listener: ConnectionListener): Unsubscribe {\n return this.emitter.subscribe(listener);\n }\n\n /** Manually re-run the opt-in ping probe (no-op if no `pingUrl` was configured). */\n async probeNow(): Promise<ConnectionInfo> {\n if (!this.options.pingUrl || !hasNavigator() || navigator.onLine === false) {\n return this.current;\n }\n const start = Date.now();\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.options.pingTimeoutMs);\n try {\n await fetch(this.options.pingUrl, {\n method: 'HEAD',\n cache: 'no-store',\n signal: controller.signal,\n });\n this.probedRttMs = Date.now() - start;\n } catch {\n // A failed probe tells us nothing reliable about latency; leave prior measurement as-is.\n } finally {\n clearTimeout(timer);\n }\n return this.refresh();\n }\n\n destroy(): void {\n if (this.disposed) return;\n this.disposed = true;\n if (typeof window !== 'undefined') {\n if (this.onlineHandler) window.removeEventListener('online', this.onlineHandler);\n if (this.offlineHandler) window.removeEventListener('offline', this.offlineHandler);\n }\n if (hasNavigator() && this.connectionChangeHandler) {\n const conn = (navigator as NavigatorWithConnection).connection;\n conn?.removeEventListener?.('change', this.connectionChangeHandler);\n }\n this.emitter.clear();\n }\n\n private refresh(): ConnectionInfo {\n this.current = this.computeInfo();\n this.emitter.emit(this.current);\n return this.current;\n }\n\n private computeInfo(): ConnectionInfo {\n if (!hasNavigator()) {\n // Server/SSR context: assume the best case rather than block anything.\n return { quality: 'online', online: true };\n }\n\n const online = navigator.onLine !== false;\n if (!online) {\n return { quality: 'offline', online: false };\n }\n\n const conn = (navigator as NavigatorWithConnection).connection;\n if (conn) {\n const info: ConnectionInfo = {\n quality: 'online',\n online: true,\n effectiveType: conn.effectiveType,\n downlinkMbps: conn.downlink,\n rttMs: conn.rtt,\n saveData: conn.saveData,\n };\n const isSlow =\n conn.saveData === true ||\n conn.effectiveType === '2g' ||\n conn.effectiveType === 'slow-2g' ||\n (typeof conn.downlink === 'number' && conn.downlink < this.options.slowDownlinkMbps) ||\n (typeof conn.rtt === 'number' && conn.rtt > this.options.slowRttThresholdMs);\n return { ...info, quality: isSlow ? 'slow' : 'online' };\n }\n\n // No Network Information API: fall back to the opt-in ping probe measurement, if any.\n const quality: ConnectionQuality =\n typeof this.probedRttMs === 'number' && this.probedRttMs > this.options.slowRttThresholdMs\n ? 'slow'\n : 'online';\n return {\n quality,\n online: true,\n rttMs: this.probedRttMs,\n };\n }\n}\n\nlet sharedMonitor: ConnectionMonitor | undefined;\n\nfunction getSharedMonitor(): ConnectionMonitor {\n if (!sharedMonitor) sharedMonitor = new ConnectionMonitor();\n return sharedMonitor;\n}\n\n/** Convenience one-shot read of connection quality, without owning a `LowdataClient`. */\nexport function getConnectionQuality(): ConnectionInfo {\n return getSharedMonitor().getStatus();\n}\n\n/** Convenience subscription to connection changes, without owning a `LowdataClient`. */\nexport function onConnectionChange(listener: ConnectionListener): Unsubscribe {\n return getSharedMonitor().subscribe(listener);\n}\n","/** Generate a reasonably unique id. Prefers `crypto.randomUUID`, falls back everywhere else. */\nexport function createId(): string {\n const g = globalThis as { crypto?: Crypto };\n if (g.crypto && typeof g.crypto.randomUUID === 'function') {\n return g.crypto.randomUUID();\n }\n return `ld_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n}\n","/**\n * Minimal promise-based IndexedDB wrapper. Deliberately small and hand-rolled (no `idb`\n * dependency) — lowdata only needs put/get/getAll/delete/clear against a handful of stores.\n */\n\nexport interface IdbIndexSpec {\n name: string;\n keyPath: string;\n unique?: boolean;\n}\n\nexport interface IdbStoreSpec {\n name: string;\n keyPath: string;\n indexes?: IdbIndexSpec[];\n}\n\nexport function isIndexedDbAvailable(): boolean {\n try {\n return typeof indexedDB !== 'undefined' && indexedDB !== null;\n } catch {\n return false;\n }\n}\n\nexport function openDatabase(\n name: string,\n version: number,\n stores: IdbStoreSpec[],\n): Promise<IDBDatabase> {\n if (!isIndexedDbAvailable()) {\n return Promise.reject(new Error('lowdata: IndexedDB is not available in this environment'));\n }\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(name, version);\n\n request.onupgradeneeded = () => {\n const db = request.result;\n for (const store of stores) {\n if (db.objectStoreNames.contains(store.name)) continue;\n const objectStore = db.createObjectStore(store.name, { keyPath: store.keyPath });\n for (const index of store.indexes ?? []) {\n objectStore.createIndex(index.name, index.keyPath, { unique: index.unique ?? false });\n }\n }\n };\n request.onsuccess = () => resolve(request.result);\n request.onerror = () =>\n reject(request.error ?? new Error('lowdata: failed to open IndexedDB database'));\n request.onblocked = () =>\n reject(new Error('lowdata: IndexedDB open blocked by another connection'));\n });\n}\n\nfunction wrapRequest<T>(request: IDBRequest<T>): Promise<T> {\n return new Promise((resolve, reject) => {\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error ?? new Error('lowdata: IndexedDB request failed'));\n });\n}\n\nfunction wrapTransaction(tx: IDBTransaction): Promise<void> {\n return new Promise((resolve, reject) => {\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error ?? new Error('lowdata: IndexedDB transaction failed'));\n tx.onabort = () => reject(tx.error ?? new Error('lowdata: IndexedDB transaction aborted'));\n });\n}\n\nexport async function idbPut<T>(db: IDBDatabase, storeName: string, value: T): Promise<void> {\n const tx = db.transaction(storeName, 'readwrite');\n tx.objectStore(storeName).put(value);\n await wrapTransaction(tx);\n}\n\nexport async function idbGet<T>(\n db: IDBDatabase,\n storeName: string,\n key: IDBValidKey,\n): Promise<T | undefined> {\n const tx = db.transaction(storeName, 'readonly');\n return wrapRequest<T>(tx.objectStore(storeName).get(key) as IDBRequest<T>);\n}\n\nexport async function idbDelete(\n db: IDBDatabase,\n storeName: string,\n key: IDBValidKey,\n): Promise<void> {\n const tx = db.transaction(storeName, 'readwrite');\n tx.objectStore(storeName).delete(key);\n await wrapTransaction(tx);\n}\n\nexport async function idbGetAll<T>(\n db: IDBDatabase,\n storeName: string,\n options?: { indexName?: string; query?: IDBValidKey | IDBKeyRange },\n): Promise<T[]> {\n const tx = db.transaction(storeName, 'readonly');\n const source = options?.indexName\n ? tx.objectStore(storeName).index(options.indexName)\n : tx.objectStore(storeName);\n return wrapRequest<T[]>(source.getAll(options?.query) as IDBRequest<T[]>);\n}\n\nexport async function idbClear(db: IDBDatabase, storeName: string): Promise<void> {\n const tx = db.transaction(storeName, 'readwrite');\n tx.objectStore(storeName).clear();\n await wrapTransaction(tx);\n}\n\nexport async function idbCount(db: IDBDatabase, storeName: string): Promise<number> {\n const tx = db.transaction(storeName, 'readonly');\n return wrapRequest<number>(tx.objectStore(storeName).count());\n}\n\n/** lowdata's shared database schema, opened once per store namespace (see `getSharedDb`). */\nexport const LOWDATA_DB_NAME = 'lowdata';\nexport const LOWDATA_DB_VERSION = 1;\n\nexport const LOWDATA_STORES: IdbStoreSpec[] = [\n {\n name: 'queue',\n keyPath: 'id',\n indexes: [\n { name: 'status', keyPath: 'status' },\n { name: 'priority', keyPath: 'priority' },\n { name: 'nextAttemptAt', keyPath: 'nextAttemptAt' },\n ],\n },\n { name: 'meta', keyPath: 'key' },\n {\n name: 'formDrafts',\n keyPath: 'submissionId',\n indexes: [{ name: 'formId', keyPath: 'formId' }],\n },\n];\n\nlet sharedDbPromise: Promise<IDBDatabase> | undefined;\n\n/** Lazily opens (and memoizes) the single shared lowdata database connection. */\nexport function getSharedDb(): Promise<IDBDatabase> {\n if (!sharedDbPromise) {\n sharedDbPromise = openDatabase(LOWDATA_DB_NAME, LOWDATA_DB_VERSION, LOWDATA_STORES).catch(\n (err) => {\n sharedDbPromise = undefined;\n throw err;\n },\n );\n }\n return sharedDbPromise;\n}\n\n/**\n * Test-only escape hatch to force a fresh connection between test cases. Closes the underlying\n * `IDBDatabase` connection (not just the cached promise) so a subsequent `indexedDB.deleteDatabase`\n * in test teardown completes instead of hanging in a \"blocked\" state waiting for this connection\n * to close.\n */\nexport async function _resetSharedDbForTests(): Promise<void> {\n const previous = sharedDbPromise;\n sharedDbPromise = undefined;\n if (!previous) return;\n try {\n const db = await previous;\n db.close();\n } catch {\n // Previous open attempt failed — nothing to close.\n }\n}\n\n/** Runs an operation against IndexedDB, or an in-memory fallback once IndexedDB has proven unavailable. */\nexport interface DbFallbackAccessor {\n run<T>(fn: (db: IDBDatabase) => Promise<T>, fallback: () => T): Promise<T>;\n isPersistent(): boolean;\n}\n\n/**\n * Shared \"try IndexedDB, permanently fall back to an in-memory implementation on first failure\"\n * policy, used by both the request queue and form draft storage. The fallback exists so importing\n * lowdata never throws in an environment without IndexedDB (SSR, locked-down browsers) — not to\n * promise durability there. Once a `getDb()` call has failed, every subsequent `run()` goes\n * straight to `fallback()` without retrying — an environment without IndexedDB isn't expected to\n * gain it mid-session.\n */\nexport function createDbFallbackAccessor(getDb: () => Promise<IDBDatabase>): DbFallbackAccessor {\n let dbAvailable = true;\n return {\n async run<T>(fn: (db: IDBDatabase) => Promise<T>, fallback: () => T): Promise<T> {\n if (!dbAvailable) return fallback();\n try {\n const db = await getDb();\n return await fn(db);\n } catch {\n dbAvailable = false;\n return fallback();\n }\n },\n isPersistent: () => dbAvailable,\n };\n}\n","import type { LowdataRequestError as LowdataRequestErrorShape } from '../core/types.js';\n\nexport class LowdataRequestError extends Error implements LowdataRequestErrorShape {\n status?: number;\n isNetworkError: boolean;\n isTimeout: boolean;\n attempt: number;\n retryAfterMs?: number;\n\n constructor(\n message: string,\n init: {\n status?: number;\n isNetworkError?: boolean;\n isTimeout?: boolean;\n attempt: number;\n retryAfterMs?: number;\n cause?: unknown;\n },\n ) {\n super(message, init.cause !== undefined ? { cause: init.cause } : undefined);\n this.name = 'LowdataRequestError';\n this.status = init.status;\n this.isNetworkError = init.isNetworkError ?? false;\n this.isTimeout = init.isTimeout ?? false;\n this.attempt = init.attempt;\n this.retryAfterMs = init.retryAfterMs;\n }\n}\n","import {\n createDbFallbackAccessor,\n idbClear,\n idbDelete,\n idbGet,\n idbGetAll,\n idbPut,\n} from '../core/idb.js';\nimport type { QueueItem, QueueItemStatus } from './types.js';\n\nconst STORE = 'queue';\n\nconst PRIORITY_ORDER: Record<QueueItem['priority'], number> = { high: 0, normal: 1, low: 2 };\n\nexport interface QueueListFilter {\n status?: QueueItemStatus;\n}\n\n/**\n * Persistent (IndexedDB-backed) request queue with an automatic in-memory fallback for\n * environments without IndexedDB (SSR, very old/locked-down browsers). The fallback is\n * non-persistent — it exists so importing lowdata never throws, not to promise durability there.\n */\nexport class RequestQueue {\n private memory = new Map<string, QueueItem>();\n private accessor;\n\n constructor(getDb: () => Promise<IDBDatabase>) {\n this.accessor = createDbFallbackAccessor(getDb);\n }\n\n isPersistent(): boolean {\n return this.accessor.isPersistent();\n }\n\n async add(item: QueueItem): Promise<QueueItem> {\n return this.accessor.run(\n async (db) => {\n await idbPut<QueueItem>(db, STORE, item);\n return item;\n },\n () => {\n this.memory.set(item.id, item);\n return item;\n },\n );\n }\n\n async update(item: QueueItem): Promise<void> {\n await this.accessor.run(\n async (db) => {\n await idbPut<QueueItem>(db, STORE, item);\n },\n () => {\n this.memory.set(item.id, item);\n },\n );\n }\n\n async get(id: string): Promise<QueueItem | undefined> {\n return this.accessor.run(\n (db) => idbGet<QueueItem>(db, STORE, id),\n () => this.memory.get(id),\n );\n }\n\n async remove(id: string): Promise<void> {\n await this.accessor.run(\n (db) => idbDelete(db, STORE, id),\n () => {\n this.memory.delete(id);\n },\n );\n }\n\n /** Filtering by status queries the `status` index rather than scanning the whole store. */\n async list(filter?: QueueListFilter): Promise<QueueItem[]> {\n if (filter?.status) {\n const status = filter.status;\n return this.accessor.run(\n (db) => idbGetAll<QueueItem>(db, STORE, { indexName: 'status', query: status }),\n () => Array.from(this.memory.values()).filter((item) => item.status === status),\n );\n }\n return this.accessor.run(\n (db) => idbGetAll<QueueItem>(db, STORE),\n () => Array.from(this.memory.values()),\n );\n }\n\n async clear(): Promise<void> {\n await this.accessor.run(\n (db) => idbClear(db, STORE),\n () => {\n this.memory.clear();\n },\n );\n }\n\n /** Items ready to send now: `pending` and due, sorted by priority then insertion order. */\n async selectEligible(now: number): Promise<QueueItem[]> {\n const pending = await this.list({ status: 'pending' });\n return pending\n .filter((item) => item.nextAttemptAt <= now)\n .sort((a, b) => {\n const byPriority = PRIORITY_ORDER[a.priority] - PRIORITY_ORDER[b.priority];\n return byPriority !== 0 ? byPriority : a.createdAt - b.createdAt;\n });\n }\n\n /** Revive items stuck in `sending` longer than `staleAfterMs` (recovers from a crash mid-send). */\n async sweepStale(staleAfterMs: number, now: number): Promise<QueueItem[]> {\n const sending = await this.list({ status: 'sending' });\n const revived: QueueItem[] = [];\n for (const item of sending) {\n if (now - item.updatedAt > staleAfterMs) {\n const next: QueueItem = { ...item, status: 'pending', updatedAt: now };\n await this.update(next);\n revived.push(next);\n }\n }\n return revived;\n }\n}\n","import type { RetryBackoffConfig } from './types.js';\n\n/**\n * Exponential backoff with jitter.\n *\n * `attempt` is 0-indexed (0 = delay before the first retry, after the initial try failed).\n * Jitter strategies:\n * - 'full': Random(0, exp) — spreads retries the most, best for avoiding a\n * thundering herd when many clients reconnect at once.\n * - 'equal': exp/2 + Random(0, exp/2) — keeps delays closer to the exponential curve while\n * still avoiding perfect synchronization.\n * - 'none': exp — deterministic, useful mainly for tests.\n */\nexport function computeBackoffDelay(attempt: number, config: RetryBackoffConfig): number {\n const safeAttempt = Math.max(0, attempt);\n const exp = Math.min(config.maxDelayMs, config.baseDelayMs * 2 ** safeAttempt);\n\n switch (config.jitter) {\n case 'none':\n return exp;\n case 'equal':\n return exp / 2 + Math.random() * (exp / 2);\n case 'full':\n default:\n return Math.random() * exp;\n }\n}\n","/**\n * Combine multiple AbortSignals into one that aborts as soon as any input signal aborts.\n *\n * Hand-written because the build target (es2019) predates `AbortSignal.any()`, and this keeps\n * lowdata dependency-free rather than reaching for a polyfill.\n */\nexport function combineSignals(signals: Array<AbortSignal | undefined>): {\n signal: AbortSignal;\n dispose: () => void;\n} {\n const controller = new AbortController();\n const active = signals.filter((s): s is AbortSignal => Boolean(s));\n\n const onAbort = (source: AbortSignal) => () => {\n if (!controller.signal.aborted) {\n controller.abort(source.reason);\n }\n };\n\n const cleanups: Array<() => void> = [];\n for (const s of active) {\n if (s.aborted) {\n controller.abort(s.reason);\n break;\n }\n const handler = onAbort(s);\n s.addEventListener('abort', handler, { once: true });\n cleanups.push(() => s.removeEventListener('abort', handler));\n }\n\n return {\n signal: controller.signal,\n dispose: () => {\n for (const cleanup of cleanups) cleanup();\n },\n };\n}\n","/** Coarse connection quality bucket used throughout lowdata. */\nexport type ConnectionQuality = 'online' | 'slow' | 'offline';\n\n/** Snapshot of what lowdata currently knows about the network. */\nexport interface ConnectionInfo {\n quality: ConnectionQuality;\n online: boolean;\n /** Populated only where the Network Information API is available (Chromium browsers). */\n effectiveType?: '4g' | '3g' | '2g' | 'slow-2g';\n downlinkMbps?: number;\n rttMs?: number;\n saveData?: boolean;\n}\n\nexport type ConnectionListener = (info: ConnectionInfo) => void;\n/** Call to stop listening. */\nexport type Unsubscribe = () => void;\n\nexport type RequestPriority = 'high' | 'normal' | 'low';\n\nexport type JitterStrategy = 'full' | 'equal' | 'none';\n\nexport interface RetryBackoffConfig {\n /** Maximum number of retry attempts after the initial try. Default: 8. */\n maxRetries: number;\n /** Base delay in ms used by the exponential backoff formula. Default: 500. */\n baseDelayMs: number;\n /** Upper bound for any single computed delay, in ms. Default: 30_000. */\n maxDelayMs: number;\n /** Jitter strategy applied on top of the exponential delay. Default: 'full'. */\n jitter: JitterStrategy;\n /** Decide whether a failed attempt should be retried. Defaults to `defaultRetryOn`. */\n retryOn?: (error: LowdataRequestError, attempt: number) => boolean;\n}\n\n/** Error thrown/recorded for a failed request attempt, carrying retry-relevant metadata. */\nexport interface LowdataRequestError extends Error {\n status?: number;\n isNetworkError: boolean;\n isTimeout: boolean;\n attempt: number;\n retryAfterMs?: number;\n}\n\nexport const DEFAULT_RETRY_CONFIG: RetryBackoffConfig = {\n maxRetries: 8,\n baseDelayMs: 500,\n maxDelayMs: 30_000,\n jitter: 'full',\n};\n","import { computeBackoffDelay } from '../core/backoff.js';\nimport { combineSignals } from '../core/abortAny.js';\nimport { DEFAULT_RETRY_CONFIG, type RetryBackoffConfig } from '../core/types.js';\nimport { LowdataRequestError } from './errors.js';\n\nconst RETRYABLE_STATUS = new Set([429, 502, 503, 504]);\n\nexport function isRetryableStatus(status: number): boolean {\n return RETRYABLE_STATUS.has(status);\n}\n\n/** Default retry policy: retry network errors, timeouts, and 429/502/503/504; fail fast otherwise. */\nexport function defaultRetryOn(error: LowdataRequestError): boolean {\n if (error.isNetworkError || error.isTimeout) return true;\n return typeof error.status === 'number' && RETRYABLE_STATUS.has(error.status);\n}\n\nexport function parseRetryAfterMs(response: Response): number | undefined {\n const header = response.headers.get('Retry-After');\n if (!header) return undefined;\n const seconds = Number(header);\n if (!Number.isNaN(seconds)) return seconds * 1000;\n const dateMs = Date.parse(header);\n if (!Number.isNaN(dateMs)) return Math.max(0, dateMs - Date.now());\n return undefined;\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(signal.reason ?? new Error('lowdata: aborted'));\n return;\n }\n const timer = setTimeout(resolve, ms);\n signal?.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer);\n reject(signal.reason ?? new Error('lowdata: aborted'));\n },\n { once: true },\n );\n });\n}\n\nexport interface AttemptWithRetryOptions {\n url: string;\n init?: RequestInit;\n retryConfig?: Partial<RetryBackoffConfig>;\n timeoutMs?: number;\n signal?: AbortSignal;\n /** Called after each failed attempt; returning `false` stops retrying immediately (e.g. connection dropped). */\n shouldContinue?: () => boolean;\n}\n\nexport const DEFAULT_TIMEOUT_MS = 15_000;\n\n/**\n * Perform a fetch with automatic retry + exponential backoff + jitter. Resolves with the\n * `Response` as soon as it's non-retryable (2xx..4xx outside the retryable set) — callers still\n * check `response.ok` themselves, matching native `fetch` semantics. Throws `LowdataRequestError`\n * only once retries are exhausted or `shouldContinue()` returns false.\n */\nexport async function attemptWithRetry(options: AttemptWithRetryOptions): Promise<Response> {\n const config: RetryBackoffConfig = { ...DEFAULT_RETRY_CONFIG, ...options.retryConfig };\n const retryOn = config.retryOn ?? defaultRetryOn;\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\n let lastError: LowdataRequestError | undefined;\n\n for (let attempt = 0; attempt <= config.maxRetries; attempt++) {\n const timeoutController = new AbortController();\n const timer = setTimeout(() => timeoutController.abort(), timeoutMs);\n const combined = combineSignals([options.signal, timeoutController.signal]);\n\n try {\n const response = await fetch(options.url, { ...options.init, signal: combined.signal });\n clearTimeout(timer);\n combined.dispose();\n\n if (response.ok || !RETRYABLE_STATUS.has(response.status)) {\n return response;\n }\n\n lastError = new LowdataRequestError(`Request failed with status ${response.status}`, {\n status: response.status,\n attempt,\n retryAfterMs: parseRetryAfterMs(response),\n });\n } catch (cause) {\n clearTimeout(timer);\n combined.dispose();\n\n if (options.signal?.aborted) {\n // Caller explicitly cancelled — never retry, never fall back to queueing.\n throw cause;\n }\n\n const isTimeout = timeoutController.signal.aborted;\n lastError = new LowdataRequestError(\n isTimeout ? 'Request timed out' : 'Network request failed',\n { isNetworkError: !isTimeout, isTimeout, attempt, cause },\n );\n }\n\n const isLastAttempt = attempt === config.maxRetries;\n const continueRetrying = options.shouldContinue ? options.shouldContinue() : true;\n if (isLastAttempt || !continueRetrying || !retryOn(lastError, attempt)) {\n throw lastError;\n }\n\n const delay = lastError.retryAfterMs ?? computeBackoffDelay(attempt, config);\n await sleep(Math.min(delay, config.maxDelayMs), options.signal);\n }\n\n // Unreachable: the loop always returns or throws, but keeps TypeScript's control-flow happy.\n throw lastError ?? new LowdataRequestError('Request failed', { attempt: config.maxRetries });\n}\n","import { idbDelete, idbGet, idbPut } from './idb.js';\n\n/** How long an IndexedDB-fallback lock record is honored before it's considered stale/abandoned. */\nexport const LOCK_STALE_AFTER_MS = 15_000;\n\nexport interface SyncLockHandle {\n release: () => Promise<void>;\n /** Extend a fallback lock's stale-after window during a long-running critical section. No-op for Web Locks. */\n renew: () => Promise<void>;\n}\n\ninterface WebLockLike {\n name: string;\n}\ninterface LockManagerLike {\n request(\n name: string,\n options: { ifAvailable?: boolean },\n callback: (lock: WebLockLike | null) => Promise<void> | void,\n ): Promise<unknown>;\n}\n\nfunction getLockManager(): LockManagerLike | undefined {\n if (typeof navigator === 'undefined') return undefined;\n return (navigator as Navigator & { locks?: LockManagerLike }).locks;\n}\n\n/**\n * Acquire a named exclusive lock via the Web Locks API, non-blocking (`ifAvailable: true`):\n * resolves to `undefined` immediately if another tab already holds it rather than queueing.\n */\nfunction acquireWebLock(locks: LockManagerLike, name: string): Promise<SyncLockHandle | undefined> {\n return new Promise((resolveOuter) => {\n locks\n .request(name, { ifAvailable: true }, (lock) => {\n if (!lock) {\n resolveOuter(undefined);\n return;\n }\n return new Promise<void>((resolveInner) => {\n resolveOuter({\n release: async () => resolveInner(),\n renew: async () => {\n /* held exclusively for the lifetime of the callback; nothing to renew */\n },\n });\n });\n })\n .catch(() => resolveOuter(undefined));\n });\n}\n\ninterface SyncLockRecord {\n key: string;\n ownerId: string;\n expiresAt: number;\n}\n\nasync function acquireIdbLock(\n db: IDBDatabase,\n name: string,\n ownerId: string,\n): Promise<SyncLockHandle | undefined> {\n const key = `syncLock:${name}`;\n const now = Date.now();\n const existing = await idbGet<SyncLockRecord>(db, 'meta', key);\n if (existing && existing.expiresAt > now && existing.ownerId !== ownerId) {\n return undefined;\n }\n await idbPut<SyncLockRecord>(db, 'meta', { key, ownerId, expiresAt: now + LOCK_STALE_AFTER_MS });\n return {\n release: async () => {\n const current = await idbGet<SyncLockRecord>(db, 'meta', key);\n if (current?.ownerId === ownerId) {\n await idbDelete(db, 'meta', key);\n }\n },\n renew: async () => {\n await idbPut<SyncLockRecord>(db, 'meta', {\n key,\n ownerId,\n expiresAt: Date.now() + LOCK_STALE_AFTER_MS,\n });\n },\n };\n}\n\n/**\n * Acquire a cross-tab exclusive lock, preferring the Web Locks API where available (correct by\n * construction, no staleness window) and falling back to an IndexedDB record (stale after\n * `LOCK_STALE_AFTER_MS`) elsewhere. Returns `undefined` if the lock could not be acquired.\n */\nexport async function acquireSyncLock(\n db: IDBDatabase | undefined,\n name: string,\n ownerId: string,\n): Promise<SyncLockHandle | undefined> {\n const locks = getLockManager();\n if (locks) {\n return acquireWebLock(locks, name);\n }\n if (!db) return undefined;\n return acquireIdbLock(db, name, ownerId);\n}\n","import { computeBackoffDelay } from '../core/backoff.js';\nimport { createId } from '../core/id.js';\nimport { acquireSyncLock } from '../core/lock.js';\nimport { DEFAULT_RETRY_CONFIG, type RetryBackoffConfig } from '../core/types.js';\nimport type { ConnectionMonitor } from '../core/connection.js';\nimport { LowdataRequestError } from './errors.js';\nimport {\n DEFAULT_TIMEOUT_MS,\n defaultRetryOn,\n isRetryableStatus,\n parseRetryAfterMs,\n} from './retry.js';\nimport type { RequestQueue } from './queue.js';\nimport type { QueueItem, SyncEvent } from './types.js';\n\n/** Items stuck in `sending` longer than this are assumed crashed and revived to `pending`. */\nconst STALE_SENDING_MS = 60_000;\n/** Safety poll interval — covers reconnects the `online` event misses (e.g. laptop sleep/wake). */\nconst SAFETY_POLL_MS = 30_000;\nconst SYNC_LOCK_NAME = 'lowdata-sync';\n\n/** Sentinel abort reason distinguishing an explicit `queue.cancel()` from a timeout/network drop. */\nconst CANCELLED = Symbol('lowdata-cancelled');\n\nexport interface SyncManagerOptions {\n queue: RequestQueue;\n connection: ConnectionMonitor;\n getDb: () => Promise<IDBDatabase>;\n retryConfig?: Partial<RetryBackoffConfig>;\n /** How many queued items to send concurrently. Default 1 — deliberately conservative on 2G. */\n syncConcurrency?: number;\n onEvent?: (event: SyncEvent) => void;\n}\n\n/**\n * Drives the offline queue: drains eligible items when the connection is up, retries failed\n * ones with backoff across drain cycles (so retries survive reloads), and prevents two open tabs\n * from double-sending the same item via a cross-tab lock.\n */\nexport class SyncManager {\n private readonly ownerId = createId();\n private readonly retryConfig: RetryBackoffConfig;\n private readonly syncConcurrency: number;\n private inFlight = new Map<string, AbortController>();\n private draining = false;\n private disposed = false;\n private unsubscribeConnection: () => void;\n private safetyTimer?: ReturnType<typeof setInterval>;\n\n constructor(private opts: SyncManagerOptions) {\n this.retryConfig = { ...DEFAULT_RETRY_CONFIG, ...opts.retryConfig };\n this.syncConcurrency = Math.max(1, opts.syncConcurrency ?? 1);\n\n this.unsubscribeConnection = this.opts.connection.subscribe((info) => {\n if (info.quality !== 'offline') void this.drain();\n });\n\n if (typeof document !== 'undefined' && typeof setInterval !== 'undefined') {\n this.safetyTimer = setInterval(() => {\n if (document.visibilityState === 'visible') void this.drain();\n }, SAFETY_POLL_MS);\n }\n }\n\n /** Call after enqueueing a new item so a high-priority item is picked up without waiting for the next trigger. */\n notifyEnqueued(): void {\n if (this.opts.connection.getStatus().quality !== 'offline') void this.drain();\n }\n\n cancel(id: string): void {\n this.inFlight.get(id)?.abort(CANCELLED);\n this.inFlight.delete(id);\n }\n\n /**\n * Never throws/rejects — `drain()` is always invoked fire-and-forget (`void this.drain()`) from\n * event listeners, so any failure here (e.g. the shared IndexedDB connection was closed\n * mid-drain) is swallowed rather than surfacing as an unhandled rejection; the next reconnect\n * or safety poll simply tries again.\n */\n async drain(): Promise<void> {\n if (this.draining || this.disposed) return;\n if (this.opts.connection.getStatus().quality === 'offline') return;\n\n // Set synchronously, before any `await`, so two drain() calls issued in the same tick (e.g.\n // two client.fetch() calls both calling notifyEnqueued()) can't both pass the guard above\n // before either sets it — otherwise both could go on to acquire the lock and, on the\n // IndexedDB fallback lock (a non-atomic get-then-put, unlike the atomic Web Locks API), both\n // could believe they hold it and send the same item twice.\n this.draining = true;\n try {\n const db = await this.opts.getDb().catch(() => undefined);\n const lock = await acquireSyncLock(db, SYNC_LOCK_NAME, this.ownerId);\n if (!lock) return; // another tab is already draining, or no lock could be acquired this cycle\n\n let succeeded = 0;\n let failed = 0;\n try {\n await this.opts.queue.sweepStale(STALE_SENDING_MS, Date.now());\n\n const initialEligible = await this.opts.queue.selectEligible(Date.now());\n if (initialEligible.length === 0) return;\n this.opts.onEvent?.({ type: 'sync-start', pending: initialEligible.length });\n\n while (!this.disposed && this.opts.connection.getStatus().quality !== 'offline') {\n const eligible = await this.opts.queue.selectEligible(Date.now());\n if (eligible.length === 0) break;\n\n const batch = eligible.slice(0, this.syncConcurrency);\n const results = await Promise.all(batch.map((item) => this.sendItem(item)));\n succeeded += results.filter(Boolean).length;\n failed += results.filter((ok) => !ok).length;\n }\n\n this.opts.onEvent?.({ type: 'sync-complete', succeeded, failed });\n } finally {\n await lock.release().catch(() => {});\n }\n } catch {\n // swallow — see doc comment above\n } finally {\n this.draining = false;\n }\n }\n\n destroy(): void {\n this.disposed = true;\n this.unsubscribeConnection();\n if (this.safetyTimer) clearInterval(this.safetyTimer);\n for (const controller of this.inFlight.values()) controller.abort(CANCELLED);\n this.inFlight.clear();\n }\n\n private async sendItem(item: QueueItem): Promise<boolean> {\n const controller = new AbortController();\n this.inFlight.set(item.id, controller);\n const timeoutMs = item.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n\n const sendingItem: QueueItem = { ...item, status: 'sending', updatedAt: Date.now() };\n await this.opts.queue.update(sendingItem);\n this.opts.onEvent?.({ type: 'item-start', item: sendingItem });\n\n const retryConfig: RetryBackoffConfig = { ...this.retryConfig, ...item.retry };\n const retryOn = retryConfig.retryOn ?? defaultRetryOn;\n\n let requestError: LowdataRequestError | undefined;\n try {\n const response = await fetch(item.url, {\n method: item.method,\n headers: item.headers,\n body: item.body ?? undefined,\n signal: controller.signal,\n });\n if (response.ok || !isRetryableStatus(response.status)) {\n const doneItem: QueueItem = { ...sendingItem, status: 'done', updatedAt: Date.now() };\n // Terminal and successful — nothing more to do with it, so purge rather than let a\n // long-lived app's queue store grow forever. The event still carries the final item for\n // any subscriber that wants to build its own history.\n await this.opts.queue.remove(doneItem.id);\n this.opts.onEvent?.({ type: 'item-success', item: doneItem });\n return true;\n }\n requestError = new LowdataRequestError(`Request failed with status ${response.status}`, {\n status: response.status,\n attempt: item.attempts,\n retryAfterMs: parseRetryAfterMs(response),\n });\n } catch (cause) {\n if (controller.signal.reason === CANCELLED) {\n const cancelledItem: QueueItem = {\n ...sendingItem,\n status: 'cancelled',\n updatedAt: Date.now(),\n };\n await this.opts.queue.update(cancelledItem);\n this.opts.onEvent?.({ type: 'item-failed', item: cancelledItem, willRetry: false });\n return false;\n }\n const isTimeout = controller.signal.aborted && controller.signal.reason !== CANCELLED;\n requestError = new LowdataRequestError(\n isTimeout ? 'Request timed out' : 'Network request failed',\n { isNetworkError: !isTimeout, isTimeout, attempt: item.attempts, cause },\n );\n } finally {\n clearTimeout(timer);\n this.inFlight.delete(item.id);\n }\n\n const attempts = item.attempts + 1;\n const willRetry = attempts <= retryConfig.maxRetries && retryOn(requestError, item.attempts);\n // Capped the same way the live-retry path (retry.ts) caps it, so a server's Retry-After is\n // honored consistently regardless of whether the request started live or queued from the start.\n const rawDelay = requestError.retryAfterMs ?? computeBackoffDelay(item.attempts, retryConfig);\n const nextAttemptAt = willRetry\n ? Date.now() + Math.min(rawDelay, retryConfig.maxDelayMs)\n : sendingItem.nextAttemptAt;\n const resultItem: QueueItem = {\n ...sendingItem,\n attempts,\n status: willRetry ? 'pending' : 'failed',\n nextAttemptAt,\n lastError: requestError.message,\n updatedAt: Date.now(),\n };\n await this.opts.queue.update(resultItem);\n this.opts.onEvent?.({ type: 'item-failed', item: resultItem, willRetry });\n return false;\n }\n}\n","import { ConnectionMonitor } from '../core/connection.js';\nimport { Emitter } from '../core/events.js';\nimport { createId } from '../core/id.js';\nimport { getSharedDb } from '../core/idb.js';\nimport type { ConnectionInfo, ConnectionListener, Unsubscribe } from '../core/types.js';\nimport { LowdataRequestError } from './errors.js';\nimport { RequestQueue, type QueueListFilter } from './queue.js';\nimport { attemptWithRetry } from './retry.js';\nimport { SyncManager } from './sync.js';\nimport type {\n EnqueueOptions,\n HttpMethod,\n LowdataClientConfig,\n QueueItem,\n QueuedResult,\n SyncEvent,\n} from './types.js';\n\nconst DEFAULT_MAX_QUEUE_ITEM_BYTES = 5 * 1024 * 1024; // 5 MB\nconst MUTATING_METHODS = new Set<HttpMethod>(['POST', 'PUT', 'PATCH', 'DELETE']);\n\nfunction defaultShouldQueueOffline({ method }: { url: string; method: HttpMethod }): boolean {\n return MUTATING_METHODS.has(method);\n}\n\nfunction normalizeHeaders(headers?: HeadersInit): Record<string, string> | undefined {\n if (!headers) return undefined;\n if (headers instanceof Headers) {\n const out: Record<string, string> = {};\n headers.forEach((value, key) => {\n out[key] = value;\n });\n return out;\n }\n if (Array.isArray(headers)) return Object.fromEntries(headers);\n return { ...headers };\n}\n\n/** Only string/Blob bodies can be durably queued; other BodyInit shapes fail loudly, not silently. */\nfunction normalizeQueueableBody(body: string | Blob | null | undefined): string | Blob | null {\n if (body == null) return null;\n if (typeof body === 'string' || body instanceof Blob) return body;\n throw new TypeError(\n 'lowdata: only string or Blob request bodies can be queued for offline delivery. ' +\n 'Serialize your payload (e.g. JSON.stringify) or pass a Blob/File before queuing.',\n );\n}\n\nfunction bodySizeBytes(body: string | Blob | null): number {\n if (body === null) return 0;\n return typeof body === 'string' ? new Blob([body]).size : body.size;\n}\n\nexport class LowdataClient {\n readonly connection: {\n getStatus: () => ConnectionInfo;\n subscribe: (listener: ConnectionListener) => Unsubscribe;\n };\n readonly queue: {\n add: (\n item: Omit<\n QueueItem,\n 'id' | 'createdAt' | 'updatedAt' | 'attempts' | 'status' | 'nextAttemptAt'\n >,\n ) => Promise<QueueItem>;\n cancel: (id: string) => Promise<void>;\n list: (filter?: QueueListFilter) => Promise<QueueItem[]>;\n clear: () => Promise<void>;\n };\n\n private monitor: ConnectionMonitor;\n private requestQueue: RequestQueue;\n private syncManager: SyncManager;\n private syncEmitter = new Emitter<SyncEvent>();\n private destroyed = false;\n\n constructor(private config: LowdataClientConfig = {}) {\n this.monitor = new ConnectionMonitor(config.connection);\n this.requestQueue = new RequestQueue(() => getSharedDb());\n this.syncManager = new SyncManager({\n queue: this.requestQueue,\n connection: this.monitor,\n getDb: () => getSharedDb(),\n retryConfig: config.retry,\n syncConcurrency: config.syncConcurrency,\n onEvent: (event) => this.syncEmitter.emit(event),\n });\n\n this.connection = {\n getStatus: () => this.monitor.getStatus(),\n subscribe: (listener) => this.monitor.subscribe(listener),\n };\n this.queue = {\n add: (item) => this.enqueue(item),\n cancel: (id) => this.cancelQueued(id),\n list: (filter) => this.requestQueue.list(filter),\n clear: () => this.requestQueue.clear(),\n };\n }\n\n onSync(listener: (event: SyncEvent) => void): Unsubscribe {\n return this.syncEmitter.subscribe(listener);\n }\n\n /**\n * Drop-in `fetch()` wrapper: retries transient failures with backoff, and — for mutating\n * requests that still can't get through — falls back to the persistent offline queue instead\n * of losing the request. Returns a `QueuedResult` (check with `isQueued()`) when queued.\n */\n async fetch(\n url: string,\n init: RequestInit & EnqueueOptions = {},\n ): Promise<Response | QueuedResult> {\n if (this.destroyed) throw new Error('lowdata: this client has been destroyed');\n\n const fullUrl = this.resolveUrl(url);\n const method = (init.method ?? 'GET').toUpperCase() as HttpMethod;\n const shouldQueueOffline = this.config.shouldQueueOffline ?? defaultShouldQueueOffline;\n const canQueue = shouldQueueOffline({ url: fullUrl, method });\n const isOffline = this.monitor.getStatus().quality === 'offline';\n\n if ((init.forceQueue || isOffline) && canQueue) {\n return this.enqueueFromInit(fullUrl, method, init);\n }\n if (init.forceQueue || isOffline) {\n // Not queueable (e.g. a GET) and we're offline — surface a clear network error instead of\n // silently attempting (and failing) a doomed fetch.\n throw new LowdataRequestError('Offline and this request is not configured to be queued', {\n isNetworkError: true,\n attempt: 0,\n });\n }\n\n try {\n return await attemptWithRetry({\n url: fullUrl,\n init: {\n ...init,\n headers: { ...this.config.defaultHeaders, ...normalizeHeaders(init.headers) },\n },\n retryConfig: { ...this.config.retry, ...init.retry },\n timeoutMs: init.timeoutMs,\n signal: init.signal ?? undefined,\n shouldContinue: () => this.monitor.getStatus().quality !== 'offline',\n });\n } catch (err) {\n if (init.signal?.aborted) throw err; // explicit cancellation — never silently queue\n if (canQueue) {\n return this.enqueueFromInit(fullUrl, method, init);\n }\n throw err;\n }\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.syncManager.destroy();\n this.monitor.destroy();\n this.syncEmitter.clear();\n }\n\n private resolveUrl(url: string): string {\n if (!this.config.baseUrl || /^[a-z][a-z0-9+.-]*:\\/\\//i.test(url)) return url;\n return `${this.config.baseUrl.replace(/\\/$/, '')}/${url.replace(/^\\//, '')}`;\n }\n\n private maxQueueItemBytes(): number {\n return this.config.maxQueueItemSizeBytes ?? DEFAULT_MAX_QUEUE_ITEM_BYTES;\n }\n\n private assertWithinSizeBudget(body: string | Blob | null): void {\n const size = bodySizeBytes(body);\n const max = this.maxQueueItemBytes();\n if (size > max) {\n throw new RangeError(\n `lowdata: request body (${size} bytes) exceeds maxQueueItemSizeBytes (${max} bytes).`,\n );\n }\n }\n\n /**\n * Shared by `enqueueFromInit` (the `fetch()` fallback path) and `enqueue` (the direct\n * `queue.add()` path) — the only difference between the two call sites is where the fields come\n * from, not how a queue item gets constructed, persisted, and announced to the sync manager.\n */\n private async persistNewQueueItem(\n fields: Omit<\n QueueItem,\n 'id' | 'createdAt' | 'updatedAt' | 'attempts' | 'status' | 'nextAttemptAt'\n >,\n ): Promise<QueueItem> {\n const body = normalizeQueueableBody(fields.body);\n this.assertWithinSizeBudget(body);\n\n const now = Date.now();\n const item: QueueItem = {\n ...fields,\n body,\n id: createId(),\n createdAt: now,\n updatedAt: now,\n attempts: 0,\n status: 'pending',\n nextAttemptAt: now,\n };\n const saved = await this.requestQueue.add(item);\n this.syncManager.notifyEnqueued();\n return saved;\n }\n\n private async enqueueFromInit(\n url: string,\n method: HttpMethod,\n init: RequestInit & EnqueueOptions,\n ): Promise<QueuedResult> {\n const saved = await this.persistNewQueueItem({\n url,\n method,\n headers: { ...this.config.defaultHeaders, ...normalizeHeaders(init.headers) },\n body: init.body as string | Blob | null | undefined,\n priority: init.priority ?? 'normal',\n meta: init.meta,\n timeoutMs: init.timeoutMs,\n retry: init.retry,\n idempotencyKey: init.idempotencyKey,\n });\n return { queued: true, id: saved.id, item: saved };\n }\n\n private async enqueue(\n partial: Omit<\n QueueItem,\n 'id' | 'createdAt' | 'updatedAt' | 'attempts' | 'status' | 'nextAttemptAt'\n >,\n ): Promise<QueueItem> {\n return this.persistNewQueueItem(partial);\n }\n\n private async cancelQueued(id: string): Promise<void> {\n this.syncManager.cancel(id);\n const item = await this.requestQueue.get(id);\n if (item && item.status !== 'done' && item.status !== 'cancelled') {\n await this.requestQueue.update({ ...item, status: 'cancelled', updatedAt: Date.now() });\n }\n }\n}\n\nexport function createLowdataClient(config?: LowdataClientConfig): LowdataClient {\n return new LowdataClient(config);\n}\n"]}
1
+ {"version":3,"sources":["../src/network/types.ts","../src/core/events.ts","../src/core/connection.ts","../src/core/id.ts","../src/core/idb.ts","../src/network/errors.ts","../src/network/queue.ts","../src/core/backoff.ts","../src/core/abortAny.ts","../src/core/types.ts","../src/network/retry.ts","../src/core/lock.ts","../src/network/sync.ts","../src/network/client.ts"],"names":["_a","_b"],"mappings":"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","file":"network.js","sourcesContent":["import type { ConnectionMonitorOptions } from '../core/connection.js';\nimport type { LowdataErrorHandler, RequestPriority, RetryBackoffConfig } from '../core/types.js';\n\nexport type QueueItemStatus = 'pending' | 'sending' | 'failed' | 'done' | 'cancelled';\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n\nexport interface QueueItem {\n id: string;\n url: string;\n method: HttpMethod;\n headers?: Record<string, string>;\n body?: string | Blob | null;\n priority: RequestPriority;\n createdAt: number;\n updatedAt: number;\n attempts: number;\n status: QueueItemStatus;\n nextAttemptAt: number;\n lastError?: string;\n meta?: Record<string, unknown>;\n timeoutMs?: number;\n retry?: Partial<RetryBackoffConfig>;\n idempotencyKey?: string;\n}\n\nexport interface EnqueueOptions {\n priority?: RequestPriority;\n meta?: Record<string, unknown>;\n timeoutMs?: number;\n retry?: Partial<RetryBackoffConfig>;\n idempotencyKey?: string;\n /** Skip the live attempt and go straight to the persistent queue, even if currently online. */\n forceQueue?: boolean;\n}\n\n/** Result returned by `client.fetch()` when a request could not be sent live and was queued instead. */\nexport interface QueuedResult {\n queued: true;\n id: string;\n item: QueueItem;\n}\n\nexport function isQueued(result: Response | QueuedResult): result is QueuedResult {\n return typeof result === 'object' && result !== null && (result as QueuedResult).queued === true;\n}\n\nexport type SyncEvent =\n | { type: 'sync-start'; pending: number }\n | { type: 'item-start'; item: QueueItem }\n | { type: 'item-success'; item: QueueItem }\n | { type: 'item-failed'; item: QueueItem; willRetry: boolean }\n | { type: 'sync-complete'; succeeded: number; failed: number };\n\nexport interface LowdataClientConfig {\n /** Prefixed onto every relative URL passed to `fetch()`/`queue.add()`. */\n baseUrl?: string;\n defaultHeaders?: Record<string, string>;\n retry?: Partial<RetryBackoffConfig>;\n connection?: ConnectionMonitorOptions;\n /** How many queued items to send concurrently during a sync drain. Default 1 (conservative). */\n syncConcurrency?: number;\n /** Reject `queue.add()` for payloads larger than this. Default 5 MB. */\n maxQueueItemSizeBytes?: number;\n /**\n * Decide whether a failed/offline request should be queued for later instead of surfaced as an\n * error. Default: only mutating methods (POST/PUT/PATCH/DELETE) are queued; GET/HEAD are not,\n * since queuing a read rarely makes sense.\n */\n shouldQueueOffline?: (input: { url: string; method: HttpMethod }) => boolean;\n /**\n * Observe otherwise-silent internal failures (a background sync error, a fallback to an\n * in-memory queue/draft store) instead of them only producing a single `console.warn`. Useful\n * for piping into your own logging/monitoring in production.\n */\n onError?: LowdataErrorHandler;\n}\n","/** Tiny typed pub-sub. No Node `EventEmitter` dependency, works in any JS runtime. */\nexport class Emitter<T> {\n private listeners = new Set<(value: T) => void>();\n\n subscribe(listener: (value: T) => void): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n emit(value: T): void {\n for (const listener of this.listeners) {\n listener(value);\n }\n }\n\n clear(): void {\n this.listeners.clear();\n }\n\n get size(): number {\n return this.listeners.size;\n }\n}\n","import { Emitter } from './events.js';\nimport type {\n ConnectionInfo,\n ConnectionListener,\n ConnectionQuality,\n Unsubscribe,\n} from './types.js';\n\n/**\n * The Network Information API (`navigator.connection`) is Chromium-only and not part of the\n * standard DOM lib types, hence this local shape instead of a global augmentation.\n */\ninterface NetworkInformationLike {\n effectiveType?: '4g' | '3g' | '2g' | 'slow-2g';\n downlink?: number;\n rtt?: number;\n saveData?: boolean;\n addEventListener?: (type: 'change', listener: () => void) => void;\n removeEventListener?: (type: 'change', listener: () => void) => void;\n}\n\ntype NavigatorWithConnection = Navigator & { connection?: NetworkInformationLike };\n\nexport interface ConnectionMonitorOptions {\n /**\n * Opt-in latency probe URL used to detect 'slow' connections on browsers without the Network\n * Information API (Safari, Firefox). Never probed automatically on a timer — only once on\n * startup and once per reconnect — because every probe costs a little data.\n */\n pingUrl?: string;\n /** Round-trip time above which the ping probe classifies the connection as 'slow'. Default 600ms. */\n slowRttThresholdMs?: number;\n /** downlink (Mbps) below which the Network Information API classifies as 'slow'. Default 0.5. */\n slowDownlinkMbps?: number;\n /** Timeout for the ping probe itself, in ms. Default 5000. */\n pingTimeoutMs?: number;\n}\n\nconst DEFAULT_SLOW_RTT_MS = 600;\nconst DEFAULT_SLOW_DOWNLINK_MBPS = 0.5;\nconst DEFAULT_PING_TIMEOUT_MS = 5000;\n\nfunction hasNavigator(): boolean {\n return typeof navigator !== 'undefined';\n}\n\n/**\n * Tracks connection quality (online / slow / offline) using the best signal available:\n * `navigator.onLine` + online/offline events as the universal baseline, `navigator.connection`\n * where present, and an optional opt-in ping probe as a cross-browser fallback for 'slow'.\n */\nexport class ConnectionMonitor {\n private emitter = new Emitter<ConnectionInfo>();\n private current: ConnectionInfo;\n private probedRttMs: number | undefined;\n private readonly options: Required<\n Pick<ConnectionMonitorOptions, 'slowRttThresholdMs' | 'slowDownlinkMbps' | 'pingTimeoutMs'>\n > &\n Pick<ConnectionMonitorOptions, 'pingUrl'>;\n private disposed = false;\n private onlineHandler?: () => void;\n private offlineHandler?: () => void;\n private connectionChangeHandler?: () => void;\n\n constructor(options: ConnectionMonitorOptions = {}) {\n this.options = {\n pingUrl: options.pingUrl,\n slowRttThresholdMs: options.slowRttThresholdMs ?? DEFAULT_SLOW_RTT_MS,\n slowDownlinkMbps: options.slowDownlinkMbps ?? DEFAULT_SLOW_DOWNLINK_MBPS,\n pingTimeoutMs: options.pingTimeoutMs ?? DEFAULT_PING_TIMEOUT_MS,\n };\n this.current = this.computeInfo();\n\n if (hasNavigator() && typeof window !== 'undefined') {\n this.onlineHandler = () => {\n this.refresh();\n void this.probeNow();\n };\n this.offlineHandler = () => this.refresh();\n window.addEventListener('online', this.onlineHandler);\n window.addEventListener('offline', this.offlineHandler);\n\n const conn = (navigator as NavigatorWithConnection).connection;\n if (conn?.addEventListener) {\n this.connectionChangeHandler = () => this.refresh();\n conn.addEventListener('change', this.connectionChangeHandler);\n }\n }\n\n if (this.options.pingUrl) {\n void this.probeNow();\n }\n }\n\n getStatus(): ConnectionInfo {\n return this.current;\n }\n\n subscribe(listener: ConnectionListener): Unsubscribe {\n return this.emitter.subscribe(listener);\n }\n\n /** Manually re-run the opt-in ping probe (no-op if no `pingUrl` was configured). */\n async probeNow(): Promise<ConnectionInfo> {\n if (!this.options.pingUrl || !hasNavigator() || navigator.onLine === false) {\n return this.current;\n }\n const start = Date.now();\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.options.pingTimeoutMs);\n try {\n await fetch(this.options.pingUrl, {\n method: 'HEAD',\n cache: 'no-store',\n signal: controller.signal,\n });\n this.probedRttMs = Date.now() - start;\n } catch {\n // A failed probe tells us nothing reliable about latency; leave prior measurement as-is.\n } finally {\n clearTimeout(timer);\n }\n return this.refresh();\n }\n\n destroy(): void {\n if (this.disposed) return;\n this.disposed = true;\n if (typeof window !== 'undefined') {\n if (this.onlineHandler) window.removeEventListener('online', this.onlineHandler);\n if (this.offlineHandler) window.removeEventListener('offline', this.offlineHandler);\n }\n if (hasNavigator() && this.connectionChangeHandler) {\n const conn = (navigator as NavigatorWithConnection).connection;\n conn?.removeEventListener?.('change', this.connectionChangeHandler);\n }\n this.emitter.clear();\n }\n\n private refresh(): ConnectionInfo {\n this.current = this.computeInfo();\n this.emitter.emit(this.current);\n return this.current;\n }\n\n private computeInfo(): ConnectionInfo {\n if (!hasNavigator()) {\n // Server/SSR context: assume the best case rather than block anything.\n return { quality: 'online', online: true };\n }\n\n const online = navigator.onLine !== false;\n if (!online) {\n return { quality: 'offline', online: false };\n }\n\n const conn = (navigator as NavigatorWithConnection).connection;\n if (conn) {\n const info: ConnectionInfo = {\n quality: 'online',\n online: true,\n effectiveType: conn.effectiveType,\n downlinkMbps: conn.downlink,\n rttMs: conn.rtt,\n saveData: conn.saveData,\n };\n const isSlow =\n conn.saveData === true ||\n conn.effectiveType === '2g' ||\n conn.effectiveType === 'slow-2g' ||\n (typeof conn.downlink === 'number' && conn.downlink < this.options.slowDownlinkMbps) ||\n (typeof conn.rtt === 'number' && conn.rtt > this.options.slowRttThresholdMs);\n return { ...info, quality: isSlow ? 'slow' : 'online' };\n }\n\n // No Network Information API: fall back to the opt-in ping probe measurement, if any.\n const quality: ConnectionQuality =\n typeof this.probedRttMs === 'number' && this.probedRttMs > this.options.slowRttThresholdMs\n ? 'slow'\n : 'online';\n return {\n quality,\n online: true,\n rttMs: this.probedRttMs,\n };\n }\n}\n\nlet sharedMonitor: ConnectionMonitor | undefined;\n\nfunction getSharedMonitor(): ConnectionMonitor {\n if (!sharedMonitor) sharedMonitor = new ConnectionMonitor();\n return sharedMonitor;\n}\n\n/** Convenience one-shot read of connection quality, without owning a `LowdataClient`. */\nexport function getConnectionQuality(): ConnectionInfo {\n return getSharedMonitor().getStatus();\n}\n\n/** Convenience subscription to connection changes, without owning a `LowdataClient`. */\nexport function onConnectionChange(listener: ConnectionListener): Unsubscribe {\n return getSharedMonitor().subscribe(listener);\n}\n","/** Generate a reasonably unique id. Prefers `crypto.randomUUID`, falls back everywhere else. */\nexport function createId(): string {\n const g = globalThis as { crypto?: Crypto };\n if (g.crypto && typeof g.crypto.randomUUID === 'function') {\n return g.crypto.randomUUID();\n }\n return `ld_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n}\n","/**\n * Minimal promise-based IndexedDB wrapper. Deliberately small and hand-rolled (no `idb`\n * dependency) — lowdata only needs put/get/getAll/delete/clear against a handful of stores.\n */\nimport type { LowdataErrorHandler } from './types.js';\n\nexport interface IdbIndexSpec {\n name: string;\n keyPath: string;\n unique?: boolean;\n}\n\nexport interface IdbStoreSpec {\n name: string;\n keyPath: string;\n indexes?: IdbIndexSpec[];\n}\n\nexport function isIndexedDbAvailable(): boolean {\n try {\n return typeof indexedDB !== 'undefined' && indexedDB !== null;\n } catch {\n return false;\n }\n}\n\nexport function openDatabase(\n name: string,\n version: number,\n stores: IdbStoreSpec[],\n): Promise<IDBDatabase> {\n if (!isIndexedDbAvailable()) {\n return Promise.reject(new Error('lowdata: IndexedDB is not available in this environment'));\n }\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(name, version);\n\n request.onupgradeneeded = () => {\n const db = request.result;\n for (const store of stores) {\n if (db.objectStoreNames.contains(store.name)) continue;\n const objectStore = db.createObjectStore(store.name, { keyPath: store.keyPath });\n for (const index of store.indexes ?? []) {\n objectStore.createIndex(index.name, index.keyPath, { unique: index.unique ?? false });\n }\n }\n };\n request.onsuccess = () => resolve(request.result);\n request.onerror = () =>\n reject(request.error ?? new Error('lowdata: failed to open IndexedDB database'));\n request.onblocked = () =>\n reject(new Error('lowdata: IndexedDB open blocked by another connection'));\n });\n}\n\nfunction wrapRequest<T>(request: IDBRequest<T>): Promise<T> {\n return new Promise((resolve, reject) => {\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error ?? new Error('lowdata: IndexedDB request failed'));\n });\n}\n\nfunction wrapTransaction(tx: IDBTransaction): Promise<void> {\n return new Promise((resolve, reject) => {\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error ?? new Error('lowdata: IndexedDB transaction failed'));\n tx.onabort = () => reject(tx.error ?? new Error('lowdata: IndexedDB transaction aborted'));\n });\n}\n\nexport async function idbPut<T>(db: IDBDatabase, storeName: string, value: T): Promise<void> {\n const tx = db.transaction(storeName, 'readwrite');\n tx.objectStore(storeName).put(value);\n await wrapTransaction(tx);\n}\n\nexport async function idbGet<T>(\n db: IDBDatabase,\n storeName: string,\n key: IDBValidKey,\n): Promise<T | undefined> {\n const tx = db.transaction(storeName, 'readonly');\n return wrapRequest<T>(tx.objectStore(storeName).get(key) as IDBRequest<T>);\n}\n\nexport async function idbDelete(\n db: IDBDatabase,\n storeName: string,\n key: IDBValidKey,\n): Promise<void> {\n const tx = db.transaction(storeName, 'readwrite');\n tx.objectStore(storeName).delete(key);\n await wrapTransaction(tx);\n}\n\nexport async function idbGetAll<T>(\n db: IDBDatabase,\n storeName: string,\n options?: { indexName?: string; query?: IDBValidKey | IDBKeyRange },\n): Promise<T[]> {\n const tx = db.transaction(storeName, 'readonly');\n const source = options?.indexName\n ? tx.objectStore(storeName).index(options.indexName)\n : tx.objectStore(storeName);\n return wrapRequest<T[]>(source.getAll(options?.query) as IDBRequest<T[]>);\n}\n\nexport async function idbClear(db: IDBDatabase, storeName: string): Promise<void> {\n const tx = db.transaction(storeName, 'readwrite');\n tx.objectStore(storeName).clear();\n await wrapTransaction(tx);\n}\n\nexport async function idbCount(db: IDBDatabase, storeName: string): Promise<number> {\n const tx = db.transaction(storeName, 'readonly');\n return wrapRequest<number>(tx.objectStore(storeName).count());\n}\n\n/** lowdata's shared database schema, opened once per store namespace (see `getSharedDb`). */\nexport const LOWDATA_DB_NAME = 'lowdata';\nexport const LOWDATA_DB_VERSION = 1;\n\nexport const LOWDATA_STORES: IdbStoreSpec[] = [\n {\n name: 'queue',\n keyPath: 'id',\n indexes: [\n { name: 'status', keyPath: 'status' },\n { name: 'priority', keyPath: 'priority' },\n { name: 'nextAttemptAt', keyPath: 'nextAttemptAt' },\n ],\n },\n { name: 'meta', keyPath: 'key' },\n {\n name: 'formDrafts',\n keyPath: 'submissionId',\n indexes: [{ name: 'formId', keyPath: 'formId' }],\n },\n];\n\nlet sharedDbPromise: Promise<IDBDatabase> | undefined;\n\n/** Lazily opens (and memoizes) the single shared lowdata database connection. */\nexport function getSharedDb(): Promise<IDBDatabase> {\n if (!sharedDbPromise) {\n sharedDbPromise = openDatabase(LOWDATA_DB_NAME, LOWDATA_DB_VERSION, LOWDATA_STORES).catch(\n (err) => {\n sharedDbPromise = undefined;\n throw err;\n },\n );\n }\n return sharedDbPromise;\n}\n\n/**\n * Test-only escape hatch to force a fresh connection between test cases. Closes the underlying\n * `IDBDatabase` connection (not just the cached promise) so a subsequent `indexedDB.deleteDatabase`\n * in test teardown completes instead of hanging in a \"blocked\" state waiting for this connection\n * to close.\n */\nexport async function _resetSharedDbForTests(): Promise<void> {\n const previous = sharedDbPromise;\n sharedDbPromise = undefined;\n if (!previous) return;\n try {\n const db = await previous;\n db.close();\n } catch {\n // Previous open attempt failed — nothing to close.\n }\n}\n\n/** Runs an operation against IndexedDB, or an in-memory fallback once IndexedDB has proven unavailable. */\nexport interface DbFallbackAccessor {\n run<T>(fn: (db: IDBDatabase) => Promise<T>, fallback: () => T): Promise<T>;\n isPersistent(): boolean;\n}\n\n/**\n * Shared \"try IndexedDB, fall back to an in-memory implementation\" policy, used by both the\n * request queue and form draft storage. The fallback exists so importing lowdata never throws in\n * an environment without IndexedDB (SSR, locked-down browsers) — not to promise durability there.\n *\n * A `getDb()` failure is structural (IndexedDB genuinely isn't available) and permanently flips to\n * the in-memory fallback for the rest of the session — an environment without IndexedDB isn't\n * expected to gain it mid-session. A failure from `fn(db)` on an already-open database (a\n * transient `QuotaExceededError`, a blocked transaction, another tab's version-change) is *not*\n * treated as \"IndexedDB is unavailable\" — only that one call falls back to memory; persistence\n * keeps being attempted on the next call. Conflating the two used to mean one quota hiccup could\n * silently and permanently disable persistence for an otherwise-healthy session.\n */\nexport function createDbFallbackAccessor(\n getDb: () => Promise<IDBDatabase>,\n onError?: LowdataErrorHandler,\n): DbFallbackAccessor {\n let dbAvailable = true;\n return {\n async run<T>(fn: (db: IDBDatabase) => Promise<T>, fallback: () => T): Promise<T> {\n if (!dbAvailable) return fallback();\n\n let db: IDBDatabase;\n try {\n db = await getDb();\n } catch (error) {\n dbAvailable = false;\n onError?.(error, { scope: 'db-open' });\n return fallback();\n }\n\n try {\n return await fn(db);\n } catch (error) {\n onError?.(error, { scope: 'db-operation' });\n return fallback();\n }\n },\n isPersistent: () => dbAvailable,\n };\n}\n","import type { LowdataRequestError as LowdataRequestErrorShape } from '../core/types.js';\n\nexport class LowdataRequestError extends Error implements LowdataRequestErrorShape {\n status?: number;\n isNetworkError: boolean;\n isTimeout: boolean;\n attempt: number;\n retryAfterMs?: number;\n\n constructor(\n message: string,\n init: {\n status?: number;\n isNetworkError?: boolean;\n isTimeout?: boolean;\n attempt: number;\n retryAfterMs?: number;\n cause?: unknown;\n },\n ) {\n super(message, init.cause !== undefined ? { cause: init.cause } : undefined);\n this.name = 'LowdataRequestError';\n this.status = init.status;\n this.isNetworkError = init.isNetworkError ?? false;\n this.isTimeout = init.isTimeout ?? false;\n this.attempt = init.attempt;\n this.retryAfterMs = init.retryAfterMs;\n }\n}\n","import {\n createDbFallbackAccessor,\n idbClear,\n idbDelete,\n idbGet,\n idbGetAll,\n idbPut,\n} from '../core/idb.js';\nimport type { LowdataErrorHandler } from '../core/types.js';\nimport type { QueueItem, QueueItemStatus } from './types.js';\n\nconst STORE = 'queue';\n\nconst PRIORITY_ORDER: Record<QueueItem['priority'], number> = { high: 0, normal: 1, low: 2 };\n\nexport interface QueueListFilter {\n status?: QueueItemStatus;\n}\n\n/**\n * Persistent (IndexedDB-backed) request queue with an automatic in-memory fallback for\n * environments without IndexedDB (SSR, very old/locked-down browsers). The fallback is\n * non-persistent — it exists so importing lowdata never throws, not to promise durability there.\n */\nexport class RequestQueue {\n private memory = new Map<string, QueueItem>();\n private accessor;\n\n constructor(getDb: () => Promise<IDBDatabase>, onError?: LowdataErrorHandler) {\n this.accessor = createDbFallbackAccessor(getDb, onError);\n }\n\n isPersistent(): boolean {\n return this.accessor.isPersistent();\n }\n\n async add(item: QueueItem): Promise<QueueItem> {\n return this.accessor.run(\n async (db) => {\n await idbPut<QueueItem>(db, STORE, item);\n return item;\n },\n () => {\n this.memory.set(item.id, item);\n return item;\n },\n );\n }\n\n async update(item: QueueItem): Promise<void> {\n await this.accessor.run(\n async (db) => {\n await idbPut<QueueItem>(db, STORE, item);\n },\n () => {\n this.memory.set(item.id, item);\n },\n );\n }\n\n async get(id: string): Promise<QueueItem | undefined> {\n return this.accessor.run(\n (db) => idbGet<QueueItem>(db, STORE, id),\n () => this.memory.get(id),\n );\n }\n\n async remove(id: string): Promise<void> {\n await this.accessor.run(\n (db) => idbDelete(db, STORE, id),\n () => {\n this.memory.delete(id);\n },\n );\n }\n\n /** Filtering by status queries the `status` index rather than scanning the whole store. */\n async list(filter?: QueueListFilter): Promise<QueueItem[]> {\n if (filter?.status) {\n const status = filter.status;\n return this.accessor.run(\n (db) => idbGetAll<QueueItem>(db, STORE, { indexName: 'status', query: status }),\n () => Array.from(this.memory.values()).filter((item) => item.status === status),\n );\n }\n return this.accessor.run(\n (db) => idbGetAll<QueueItem>(db, STORE),\n () => Array.from(this.memory.values()),\n );\n }\n\n async clear(): Promise<void> {\n await this.accessor.run(\n (db) => idbClear(db, STORE),\n () => {\n this.memory.clear();\n },\n );\n }\n\n /** Items ready to send now: `pending` and due, sorted by priority then insertion order. */\n async selectEligible(now: number): Promise<QueueItem[]> {\n const pending = await this.list({ status: 'pending' });\n return pending\n .filter((item) => item.nextAttemptAt <= now)\n .sort((a, b) => {\n const byPriority = PRIORITY_ORDER[a.priority] - PRIORITY_ORDER[b.priority];\n return byPriority !== 0 ? byPriority : a.createdAt - b.createdAt;\n });\n }\n\n /** Revive items stuck in `sending` longer than `staleAfterMs` (recovers from a crash mid-send). */\n async sweepStale(staleAfterMs: number, now: number): Promise<QueueItem[]> {\n const sending = await this.list({ status: 'sending' });\n const revived: QueueItem[] = [];\n for (const item of sending) {\n if (now - item.updatedAt > staleAfterMs) {\n const next: QueueItem = { ...item, status: 'pending', updatedAt: now };\n await this.update(next);\n revived.push(next);\n }\n }\n return revived;\n }\n}\n","import type { RetryBackoffConfig } from './types.js';\n\n/**\n * Exponential backoff with jitter.\n *\n * `attempt` is 0-indexed (0 = delay before the first retry, after the initial try failed).\n * Jitter strategies:\n * - 'full': Random(0, exp) — spreads retries the most, best for avoiding a\n * thundering herd when many clients reconnect at once.\n * - 'equal': exp/2 + Random(0, exp/2) — keeps delays closer to the exponential curve while\n * still avoiding perfect synchronization.\n * - 'none': exp — deterministic, useful mainly for tests.\n */\nexport function computeBackoffDelay(attempt: number, config: RetryBackoffConfig): number {\n const safeAttempt = Math.max(0, attempt);\n const exp = Math.min(config.maxDelayMs, config.baseDelayMs * 2 ** safeAttempt);\n\n switch (config.jitter) {\n case 'none':\n return exp;\n case 'equal':\n return exp / 2 + Math.random() * (exp / 2);\n case 'full':\n default:\n return Math.random() * exp;\n }\n}\n","/**\n * Combine multiple AbortSignals into one that aborts as soon as any input signal aborts.\n *\n * Hand-written because the build target (es2019) predates `AbortSignal.any()`, and this keeps\n * lowdata dependency-free rather than reaching for a polyfill.\n */\nexport function combineSignals(signals: Array<AbortSignal | undefined>): {\n signal: AbortSignal;\n dispose: () => void;\n} {\n const controller = new AbortController();\n const active = signals.filter((s): s is AbortSignal => Boolean(s));\n\n const onAbort = (source: AbortSignal) => () => {\n if (!controller.signal.aborted) {\n controller.abort(source.reason);\n }\n };\n\n const cleanups: Array<() => void> = [];\n for (const s of active) {\n if (s.aborted) {\n controller.abort(s.reason);\n break;\n }\n const handler = onAbort(s);\n s.addEventListener('abort', handler, { once: true });\n cleanups.push(() => s.removeEventListener('abort', handler));\n }\n\n return {\n signal: controller.signal,\n dispose: () => {\n for (const cleanup of cleanups) cleanup();\n },\n };\n}\n","/** Coarse connection quality bucket used throughout lowdata. */\nexport type ConnectionQuality = 'online' | 'slow' | 'offline';\n\n/** Snapshot of what lowdata currently knows about the network. */\nexport interface ConnectionInfo {\n quality: ConnectionQuality;\n online: boolean;\n /** Populated only where the Network Information API is available (Chromium browsers). */\n effectiveType?: '4g' | '3g' | '2g' | 'slow-2g';\n downlinkMbps?: number;\n rttMs?: number;\n saveData?: boolean;\n}\n\nexport type ConnectionListener = (info: ConnectionInfo) => void;\n/** Call to stop listening. */\nexport type Unsubscribe = () => void;\n\nexport type RequestPriority = 'high' | 'normal' | 'low';\n\nexport type JitterStrategy = 'full' | 'equal' | 'none';\n\nexport interface RetryBackoffConfig {\n /** Maximum number of retry attempts after the initial try. Default: 8. */\n maxRetries: number;\n /** Base delay in ms used by the exponential backoff formula. Default: 500. */\n baseDelayMs: number;\n /** Upper bound for any single computed delay, in ms. Default: 30_000. */\n maxDelayMs: number;\n /** Jitter strategy applied on top of the exponential delay. Default: 'full'. */\n jitter: JitterStrategy;\n /** Decide whether a failed attempt should be retried. Defaults to `defaultRetryOn`. */\n retryOn?: (error: LowdataRequestError, attempt: number) => boolean;\n}\n\n/** Error thrown/recorded for a failed request attempt, carrying retry-relevant metadata. */\nexport interface LowdataRequestError extends Error {\n status?: number;\n isNetworkError: boolean;\n isTimeout: boolean;\n attempt: number;\n retryAfterMs?: number;\n}\n\nexport const DEFAULT_RETRY_CONFIG: RetryBackoffConfig = {\n maxRetries: 8,\n baseDelayMs: 500,\n maxDelayMs: 30_000,\n jitter: 'full',\n};\n\n/**\n * Where an internal, otherwise-silent failure originated:\n * - `'db-open'`: IndexedDB itself couldn't be opened (SSR, unsupported/locked-down browser) —\n * persistence is now permanently disabled for this session; lowdata falls back to an\n * in-memory queue/draft store.\n * - `'db-operation'`: a single IndexedDB operation failed (e.g. a transient\n * `QuotaExceededError`, a blocked transaction) — persistence is still available; only that\n * one call fell back to memory.\n * - `'sync'`: the background sync loop hit an error outside of a single queued item's own\n * retry accounting (e.g. it couldn't acquire the shared database or the cross-tab lock).\n */\nexport type LowdataErrorScope = 'db-open' | 'db-operation' | 'sync';\n\n/**\n * Optional escape hatch for otherwise-silent internal failures. lowdata deliberately never lets\n * these throw — a failed background sync or a degraded-to-memory fallback shouldn't crash the\n * host app — but a production app still needs a way to *see* it happened (log it, alert on it),\n * rather than it vanishing into a single `console.warn`.\n */\nexport type LowdataErrorHandler = (error: unknown, context: { scope: LowdataErrorScope }) => void;\n","import { computeBackoffDelay } from '../core/backoff.js';\nimport { combineSignals } from '../core/abortAny.js';\nimport { DEFAULT_RETRY_CONFIG, type RetryBackoffConfig } from '../core/types.js';\nimport { LowdataRequestError } from './errors.js';\n\nconst RETRYABLE_STATUS = new Set([429, 502, 503, 504]);\n\nexport function isRetryableStatus(status: number): boolean {\n return RETRYABLE_STATUS.has(status);\n}\n\n/** Default retry policy: retry network errors, timeouts, and 429/502/503/504; fail fast otherwise. */\nexport function defaultRetryOn(error: LowdataRequestError): boolean {\n if (error.isNetworkError || error.isTimeout) return true;\n return typeof error.status === 'number' && RETRYABLE_STATUS.has(error.status);\n}\n\nexport function parseRetryAfterMs(response: Response): number | undefined {\n const header = response.headers.get('Retry-After');\n if (!header) return undefined;\n const seconds = Number(header);\n if (!Number.isNaN(seconds)) return seconds * 1000;\n const dateMs = Date.parse(header);\n if (!Number.isNaN(dateMs)) return Math.max(0, dateMs - Date.now());\n return undefined;\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(signal.reason ?? new Error('lowdata: aborted'));\n return;\n }\n const timer = setTimeout(resolve, ms);\n signal?.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer);\n reject(signal.reason ?? new Error('lowdata: aborted'));\n },\n { once: true },\n );\n });\n}\n\nexport interface AttemptWithRetryOptions {\n url: string;\n init?: RequestInit;\n retryConfig?: Partial<RetryBackoffConfig>;\n timeoutMs?: number;\n signal?: AbortSignal;\n /** Called after each failed attempt; returning `false` stops retrying immediately (e.g. connection dropped). */\n shouldContinue?: () => boolean;\n}\n\nexport const DEFAULT_TIMEOUT_MS = 15_000;\n\n/**\n * Perform a fetch with automatic retry + exponential backoff + jitter. Resolves with the\n * `Response` as soon as it's non-retryable (2xx..4xx outside the retryable set) — callers still\n * check `response.ok` themselves, matching native `fetch` semantics. Throws `LowdataRequestError`\n * only once retries are exhausted or `shouldContinue()` returns false.\n */\nexport async function attemptWithRetry(options: AttemptWithRetryOptions): Promise<Response> {\n const config: RetryBackoffConfig = { ...DEFAULT_RETRY_CONFIG, ...options.retryConfig };\n const retryOn = config.retryOn ?? defaultRetryOn;\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\n let lastError: LowdataRequestError | undefined;\n\n for (let attempt = 0; attempt <= config.maxRetries; attempt++) {\n const timeoutController = new AbortController();\n const timer = setTimeout(() => timeoutController.abort(), timeoutMs);\n const combined = combineSignals([options.signal, timeoutController.signal]);\n\n try {\n const response = await fetch(options.url, { ...options.init, signal: combined.signal });\n clearTimeout(timer);\n combined.dispose();\n\n if (response.ok || !RETRYABLE_STATUS.has(response.status)) {\n return response;\n }\n\n lastError = new LowdataRequestError(`Request failed with status ${response.status}`, {\n status: response.status,\n attempt,\n retryAfterMs: parseRetryAfterMs(response),\n });\n } catch (cause) {\n clearTimeout(timer);\n combined.dispose();\n\n if (options.signal?.aborted) {\n // Caller explicitly cancelled — never retry, never fall back to queueing.\n throw cause;\n }\n\n const isTimeout = timeoutController.signal.aborted;\n lastError = new LowdataRequestError(\n isTimeout ? 'Request timed out' : 'Network request failed',\n { isNetworkError: !isTimeout, isTimeout, attempt, cause },\n );\n }\n\n const isLastAttempt = attempt === config.maxRetries;\n const continueRetrying = options.shouldContinue ? options.shouldContinue() : true;\n if (isLastAttempt || !continueRetrying || !retryOn(lastError, attempt)) {\n throw lastError;\n }\n\n const delay = lastError.retryAfterMs ?? computeBackoffDelay(attempt, config);\n await sleep(Math.min(delay, config.maxDelayMs), options.signal);\n }\n\n // Unreachable: the loop always returns or throws, but keeps TypeScript's control-flow happy.\n throw lastError ?? new LowdataRequestError('Request failed', { attempt: config.maxRetries });\n}\n","import { idbDelete, idbGet, idbPut } from './idb.js';\n\n/** How long an IndexedDB-fallback lock record is honored before it's considered stale/abandoned. */\nexport const LOCK_STALE_AFTER_MS = 15_000;\n\nexport interface SyncLockHandle {\n release: () => Promise<void>;\n /** Extend a fallback lock's stale-after window during a long-running critical section. No-op for Web Locks. */\n renew: () => Promise<void>;\n}\n\ninterface WebLockLike {\n name: string;\n}\ninterface LockManagerLike {\n request(\n name: string,\n options: { ifAvailable?: boolean },\n callback: (lock: WebLockLike | null) => Promise<void> | void,\n ): Promise<unknown>;\n}\n\nfunction getLockManager(): LockManagerLike | undefined {\n if (typeof navigator === 'undefined') return undefined;\n return (navigator as Navigator & { locks?: LockManagerLike }).locks;\n}\n\n/**\n * Acquire a named exclusive lock via the Web Locks API, non-blocking (`ifAvailable: true`):\n * resolves to `undefined` immediately if another tab already holds it rather than queueing.\n */\nfunction acquireWebLock(locks: LockManagerLike, name: string): Promise<SyncLockHandle | undefined> {\n return new Promise((resolveOuter) => {\n locks\n .request(name, { ifAvailable: true }, (lock) => {\n if (!lock) {\n resolveOuter(undefined);\n return;\n }\n return new Promise<void>((resolveInner) => {\n resolveOuter({\n release: async () => resolveInner(),\n renew: async () => {\n /* held exclusively for the lifetime of the callback; nothing to renew */\n },\n });\n });\n })\n .catch(() => resolveOuter(undefined));\n });\n}\n\ninterface SyncLockRecord {\n key: string;\n ownerId: string;\n expiresAt: number;\n}\n\nasync function acquireIdbLock(\n db: IDBDatabase,\n name: string,\n ownerId: string,\n): Promise<SyncLockHandle | undefined> {\n const key = `syncLock:${name}`;\n const now = Date.now();\n const existing = await idbGet<SyncLockRecord>(db, 'meta', key);\n if (existing && existing.expiresAt > now && existing.ownerId !== ownerId) {\n return undefined;\n }\n await idbPut<SyncLockRecord>(db, 'meta', { key, ownerId, expiresAt: now + LOCK_STALE_AFTER_MS });\n return {\n release: async () => {\n const current = await idbGet<SyncLockRecord>(db, 'meta', key);\n if (current?.ownerId === ownerId) {\n await idbDelete(db, 'meta', key);\n }\n },\n renew: async () => {\n await idbPut<SyncLockRecord>(db, 'meta', {\n key,\n ownerId,\n expiresAt: Date.now() + LOCK_STALE_AFTER_MS,\n });\n },\n };\n}\n\n/**\n * Acquire a cross-tab exclusive lock, preferring the Web Locks API where available (correct by\n * construction, no staleness window) and falling back to an IndexedDB record (stale after\n * `LOCK_STALE_AFTER_MS`) elsewhere. Returns `undefined` if the lock could not be acquired.\n */\nexport async function acquireSyncLock(\n db: IDBDatabase | undefined,\n name: string,\n ownerId: string,\n): Promise<SyncLockHandle | undefined> {\n const locks = getLockManager();\n if (locks) {\n return acquireWebLock(locks, name);\n }\n if (!db) return undefined;\n return acquireIdbLock(db, name, ownerId);\n}\n","import { computeBackoffDelay } from '../core/backoff.js';\nimport { createId } from '../core/id.js';\nimport { acquireSyncLock } from '../core/lock.js';\nimport {\n DEFAULT_RETRY_CONFIG,\n type LowdataErrorHandler,\n type RetryBackoffConfig,\n} from '../core/types.js';\nimport type { ConnectionMonitor } from '../core/connection.js';\nimport { LowdataRequestError } from './errors.js';\nimport {\n DEFAULT_TIMEOUT_MS,\n defaultRetryOn,\n isRetryableStatus,\n parseRetryAfterMs,\n} from './retry.js';\nimport type { RequestQueue } from './queue.js';\nimport type { QueueItem, SyncEvent } from './types.js';\n\n/** Items stuck in `sending` longer than this are assumed crashed and revived to `pending`. */\nconst STALE_SENDING_MS = 60_000;\n/** Safety poll interval — covers reconnects the `online` event misses (e.g. laptop sleep/wake). */\nconst SAFETY_POLL_MS = 30_000;\nconst SYNC_LOCK_NAME = 'lowdata-sync';\n\n/** Sentinel abort reason distinguishing an explicit `queue.cancel()` from a timeout/network drop. */\nconst CANCELLED = Symbol('lowdata-cancelled');\n\nexport interface SyncManagerOptions {\n queue: RequestQueue;\n connection: ConnectionMonitor;\n getDb: () => Promise<IDBDatabase>;\n retryConfig?: Partial<RetryBackoffConfig>;\n /** How many queued items to send concurrently. Default 1 — deliberately conservative on 2G. */\n syncConcurrency?: number;\n onEvent?: (event: SyncEvent) => void;\n onError?: LowdataErrorHandler;\n}\n\n/**\n * Drives the offline queue: drains eligible items when the connection is up, retries failed\n * ones with backoff across drain cycles (so retries survive reloads), and prevents two open tabs\n * from double-sending the same item via a cross-tab lock.\n */\nexport class SyncManager {\n private readonly ownerId = createId();\n private readonly retryConfig: RetryBackoffConfig;\n private readonly syncConcurrency: number;\n private inFlight = new Map<string, AbortController>();\n private draining = false;\n private disposed = false;\n private unsubscribeConnection: () => void;\n private safetyTimer?: ReturnType<typeof setInterval>;\n\n constructor(private opts: SyncManagerOptions) {\n this.retryConfig = { ...DEFAULT_RETRY_CONFIG, ...opts.retryConfig };\n this.syncConcurrency = Math.max(1, opts.syncConcurrency ?? 1);\n\n this.unsubscribeConnection = this.opts.connection.subscribe((info) => {\n if (info.quality !== 'offline') void this.drain();\n });\n\n if (typeof document !== 'undefined' && typeof setInterval !== 'undefined') {\n this.safetyTimer = setInterval(() => {\n if (document.visibilityState === 'visible') void this.drain();\n }, SAFETY_POLL_MS);\n }\n }\n\n /** Call after enqueueing a new item so a high-priority item is picked up without waiting for the next trigger. */\n notifyEnqueued(): void {\n if (this.opts.connection.getStatus().quality !== 'offline') void this.drain();\n }\n\n cancel(id: string): void {\n this.inFlight.get(id)?.abort(CANCELLED);\n this.inFlight.delete(id);\n }\n\n /**\n * Never throws/rejects — `drain()` is always invoked fire-and-forget (`void this.drain()`) from\n * event listeners, so any failure here (e.g. the shared IndexedDB connection was closed\n * mid-drain) is swallowed rather than surfacing as an unhandled rejection; the next reconnect\n * or safety poll simply tries again.\n */\n async drain(): Promise<void> {\n if (this.draining || this.disposed) return;\n if (this.opts.connection.getStatus().quality === 'offline') return;\n\n // Set synchronously, before any `await`, so two drain() calls issued in the same tick (e.g.\n // two client.fetch() calls both calling notifyEnqueued()) can't both pass the guard above\n // before either sets it — otherwise both could go on to acquire the lock and, on the\n // IndexedDB fallback lock (a non-atomic get-then-put, unlike the atomic Web Locks API), both\n // could believe they hold it and send the same item twice.\n this.draining = true;\n try {\n const db = await this.opts.getDb().catch((error) => {\n this.opts.onError?.(error, { scope: 'db-open' });\n return undefined;\n });\n const lock = await acquireSyncLock(db, SYNC_LOCK_NAME, this.ownerId);\n if (!lock) return; // another tab is already draining, or no lock could be acquired this cycle\n\n let succeeded = 0;\n let failed = 0;\n try {\n await this.opts.queue.sweepStale(STALE_SENDING_MS, Date.now());\n\n const initialEligible = await this.opts.queue.selectEligible(Date.now());\n if (initialEligible.length === 0) return;\n this.opts.onEvent?.({ type: 'sync-start', pending: initialEligible.length });\n\n while (!this.disposed && this.opts.connection.getStatus().quality !== 'offline') {\n const eligible = await this.opts.queue.selectEligible(Date.now());\n if (eligible.length === 0) break;\n\n const batch = eligible.slice(0, this.syncConcurrency);\n const results = await Promise.all(batch.map((item) => this.sendItem(item)));\n succeeded += results.filter(Boolean).length;\n failed += results.filter((ok) => !ok).length;\n }\n\n this.opts.onEvent?.({ type: 'sync-complete', succeeded, failed });\n } finally {\n await lock.release().catch(() => {});\n }\n } catch (error) {\n // swallow — see doc comment above — but still make it observable.\n this.opts.onError?.(error, { scope: 'sync' });\n } finally {\n this.draining = false;\n }\n }\n\n destroy(): void {\n this.disposed = true;\n this.unsubscribeConnection();\n if (this.safetyTimer) clearInterval(this.safetyTimer);\n for (const controller of this.inFlight.values()) controller.abort(CANCELLED);\n this.inFlight.clear();\n }\n\n private async sendItem(item: QueueItem): Promise<boolean> {\n const controller = new AbortController();\n this.inFlight.set(item.id, controller);\n const timeoutMs = item.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n\n const sendingItem: QueueItem = { ...item, status: 'sending', updatedAt: Date.now() };\n await this.opts.queue.update(sendingItem);\n this.opts.onEvent?.({ type: 'item-start', item: sendingItem });\n\n const retryConfig: RetryBackoffConfig = { ...this.retryConfig, ...item.retry };\n const retryOn = retryConfig.retryOn ?? defaultRetryOn;\n\n let requestError: LowdataRequestError | undefined;\n try {\n const response = await fetch(item.url, {\n method: item.method,\n headers: item.headers,\n body: item.body ?? undefined,\n signal: controller.signal,\n });\n if (response.ok || !isRetryableStatus(response.status)) {\n const doneItem: QueueItem = { ...sendingItem, status: 'done', updatedAt: Date.now() };\n // Terminal and successful — nothing more to do with it, so purge rather than let a\n // long-lived app's queue store grow forever. The event still carries the final item for\n // any subscriber that wants to build its own history.\n await this.opts.queue.remove(doneItem.id);\n this.opts.onEvent?.({ type: 'item-success', item: doneItem });\n return true;\n }\n requestError = new LowdataRequestError(`Request failed with status ${response.status}`, {\n status: response.status,\n attempt: item.attempts,\n retryAfterMs: parseRetryAfterMs(response),\n });\n } catch (cause) {\n if (controller.signal.reason === CANCELLED) {\n const cancelledItem: QueueItem = {\n ...sendingItem,\n status: 'cancelled',\n updatedAt: Date.now(),\n };\n await this.opts.queue.update(cancelledItem);\n this.opts.onEvent?.({ type: 'item-failed', item: cancelledItem, willRetry: false });\n return false;\n }\n const isTimeout = controller.signal.aborted && controller.signal.reason !== CANCELLED;\n requestError = new LowdataRequestError(\n isTimeout ? 'Request timed out' : 'Network request failed',\n { isNetworkError: !isTimeout, isTimeout, attempt: item.attempts, cause },\n );\n } finally {\n clearTimeout(timer);\n this.inFlight.delete(item.id);\n }\n\n const attempts = item.attempts + 1;\n const willRetry = attempts <= retryConfig.maxRetries && retryOn(requestError, item.attempts);\n // Capped the same way the live-retry path (retry.ts) caps it, so a server's Retry-After is\n // honored consistently regardless of whether the request started live or queued from the start.\n const rawDelay = requestError.retryAfterMs ?? computeBackoffDelay(item.attempts, retryConfig);\n const nextAttemptAt = willRetry\n ? Date.now() + Math.min(rawDelay, retryConfig.maxDelayMs)\n : sendingItem.nextAttemptAt;\n const resultItem: QueueItem = {\n ...sendingItem,\n attempts,\n status: willRetry ? 'pending' : 'failed',\n nextAttemptAt,\n lastError: requestError.message,\n updatedAt: Date.now(),\n };\n await this.opts.queue.update(resultItem);\n this.opts.onEvent?.({ type: 'item-failed', item: resultItem, willRetry });\n return false;\n }\n}\n","import { ConnectionMonitor } from '../core/connection.js';\nimport { Emitter } from '../core/events.js';\nimport { createId } from '../core/id.js';\nimport { getSharedDb } from '../core/idb.js';\nimport type {\n ConnectionInfo,\n ConnectionListener,\n LowdataErrorHandler,\n Unsubscribe,\n} from '../core/types.js';\nimport { LowdataRequestError } from './errors.js';\nimport { RequestQueue, type QueueListFilter } from './queue.js';\nimport { attemptWithRetry } from './retry.js';\nimport { SyncManager } from './sync.js';\nimport type {\n EnqueueOptions,\n HttpMethod,\n LowdataClientConfig,\n QueueItem,\n QueuedResult,\n SyncEvent,\n} from './types.js';\n\nconst DEFAULT_MAX_QUEUE_ITEM_BYTES = 5 * 1024 * 1024; // 5 MB\nconst MUTATING_METHODS = new Set<HttpMethod>(['POST', 'PUT', 'PATCH', 'DELETE']);\n\nfunction defaultShouldQueueOffline({ method }: { url: string; method: HttpMethod }): boolean {\n return MUTATING_METHODS.has(method);\n}\n\nconst defaultOnError: LowdataErrorHandler = (error, { scope }) => {\n console.warn(`lowdata: internal error (${scope})`, error);\n};\n\nfunction normalizeHeaders(headers?: HeadersInit): Record<string, string> | undefined {\n if (!headers) return undefined;\n if (headers instanceof Headers) {\n const out: Record<string, string> = {};\n headers.forEach((value, key) => {\n out[key] = value;\n });\n return out;\n }\n if (Array.isArray(headers)) return Object.fromEntries(headers);\n return { ...headers };\n}\n\n/** Only string/Blob bodies can be durably queued; other BodyInit shapes fail loudly, not silently. */\nfunction normalizeQueueableBody(body: string | Blob | null | undefined): string | Blob | null {\n if (body == null) return null;\n if (typeof body === 'string' || body instanceof Blob) return body;\n throw new TypeError(\n 'lowdata: only string or Blob request bodies can be queued for offline delivery. ' +\n 'Serialize your payload (e.g. JSON.stringify) or pass a Blob/File before queuing.',\n );\n}\n\nfunction bodySizeBytes(body: string | Blob | null): number {\n if (body === null) return 0;\n return typeof body === 'string' ? new Blob([body]).size : body.size;\n}\n\nexport class LowdataClient {\n readonly connection: {\n getStatus: () => ConnectionInfo;\n subscribe: (listener: ConnectionListener) => Unsubscribe;\n };\n readonly queue: {\n add: (\n item: Omit<\n QueueItem,\n 'id' | 'createdAt' | 'updatedAt' | 'attempts' | 'status' | 'nextAttemptAt'\n >,\n ) => Promise<QueueItem>;\n cancel: (id: string) => Promise<void>;\n list: (filter?: QueueListFilter) => Promise<QueueItem[]>;\n clear: () => Promise<void>;\n };\n\n private monitor: ConnectionMonitor;\n private requestQueue: RequestQueue;\n private syncManager: SyncManager;\n private syncEmitter = new Emitter<SyncEvent>();\n private destroyed = false;\n\n constructor(private config: LowdataClientConfig = {}) {\n const onError = config.onError ?? defaultOnError;\n this.monitor = new ConnectionMonitor(config.connection);\n this.requestQueue = new RequestQueue(() => getSharedDb(), onError);\n this.syncManager = new SyncManager({\n queue: this.requestQueue,\n connection: this.monitor,\n getDb: () => getSharedDb(),\n retryConfig: config.retry,\n syncConcurrency: config.syncConcurrency,\n onEvent: (event) => this.syncEmitter.emit(event),\n onError,\n });\n\n this.connection = {\n getStatus: () => this.monitor.getStatus(),\n subscribe: (listener) => this.monitor.subscribe(listener),\n };\n this.queue = {\n add: (item) => this.enqueue(item),\n cancel: (id) => this.cancelQueued(id),\n list: (filter) => this.requestQueue.list(filter),\n clear: () => this.requestQueue.clear(),\n };\n }\n\n onSync(listener: (event: SyncEvent) => void): Unsubscribe {\n return this.syncEmitter.subscribe(listener);\n }\n\n /**\n * Drop-in `fetch()` wrapper: retries transient failures with backoff, and — for mutating\n * requests that still can't get through — falls back to the persistent offline queue instead\n * of losing the request. Returns a `QueuedResult` (check with `isQueued()`) when queued.\n */\n async fetch(\n url: string,\n init: RequestInit & EnqueueOptions = {},\n ): Promise<Response | QueuedResult> {\n if (this.destroyed) throw new Error('lowdata: this client has been destroyed');\n\n const fullUrl = this.resolveUrl(url);\n const method = (init.method ?? 'GET').toUpperCase() as HttpMethod;\n const shouldQueueOffline = this.config.shouldQueueOffline ?? defaultShouldQueueOffline;\n const canQueue = shouldQueueOffline({ url: fullUrl, method });\n const isOffline = this.monitor.getStatus().quality === 'offline';\n\n if ((init.forceQueue || isOffline) && canQueue) {\n return this.enqueueFromInit(fullUrl, method, init);\n }\n if (init.forceQueue || isOffline) {\n // Not queueable (e.g. a GET) and we're offline — surface a clear network error instead of\n // silently attempting (and failing) a doomed fetch.\n throw new LowdataRequestError('Offline and this request is not configured to be queued', {\n isNetworkError: true,\n attempt: 0,\n });\n }\n\n try {\n return await attemptWithRetry({\n url: fullUrl,\n init: {\n ...init,\n headers: { ...this.config.defaultHeaders, ...normalizeHeaders(init.headers) },\n },\n retryConfig: { ...this.config.retry, ...init.retry },\n timeoutMs: init.timeoutMs,\n signal: init.signal ?? undefined,\n shouldContinue: () => this.monitor.getStatus().quality !== 'offline',\n });\n } catch (err) {\n if (init.signal?.aborted) throw err; // explicit cancellation — never silently queue\n if (canQueue) {\n return this.enqueueFromInit(fullUrl, method, init);\n }\n throw err;\n }\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.syncManager.destroy();\n this.monitor.destroy();\n this.syncEmitter.clear();\n }\n\n private resolveUrl(url: string): string {\n if (!this.config.baseUrl || /^[a-z][a-z0-9+.-]*:\\/\\//i.test(url)) return url;\n return `${this.config.baseUrl.replace(/\\/$/, '')}/${url.replace(/^\\//, '')}`;\n }\n\n private maxQueueItemBytes(): number {\n return this.config.maxQueueItemSizeBytes ?? DEFAULT_MAX_QUEUE_ITEM_BYTES;\n }\n\n private assertWithinSizeBudget(body: string | Blob | null): void {\n const size = bodySizeBytes(body);\n const max = this.maxQueueItemBytes();\n if (size > max) {\n throw new RangeError(\n `lowdata: request body (${size} bytes) exceeds maxQueueItemSizeBytes (${max} bytes).`,\n );\n }\n }\n\n /**\n * Shared by `enqueueFromInit` (the `fetch()` fallback path) and `enqueue` (the direct\n * `queue.add()` path) — the only difference between the two call sites is where the fields come\n * from, not how a queue item gets constructed, persisted, and announced to the sync manager.\n */\n private async persistNewQueueItem(\n fields: Omit<\n QueueItem,\n 'id' | 'createdAt' | 'updatedAt' | 'attempts' | 'status' | 'nextAttemptAt'\n >,\n ): Promise<QueueItem> {\n const body = normalizeQueueableBody(fields.body);\n this.assertWithinSizeBudget(body);\n\n const now = Date.now();\n const item: QueueItem = {\n ...fields,\n body,\n id: createId(),\n createdAt: now,\n updatedAt: now,\n attempts: 0,\n status: 'pending',\n nextAttemptAt: now,\n };\n const saved = await this.requestQueue.add(item);\n this.syncManager.notifyEnqueued();\n return saved;\n }\n\n private async enqueueFromInit(\n url: string,\n method: HttpMethod,\n init: RequestInit & EnqueueOptions,\n ): Promise<QueuedResult> {\n const saved = await this.persistNewQueueItem({\n url,\n method,\n headers: { ...this.config.defaultHeaders, ...normalizeHeaders(init.headers) },\n body: init.body as string | Blob | null | undefined,\n priority: init.priority ?? 'normal',\n meta: init.meta,\n timeoutMs: init.timeoutMs,\n retry: init.retry,\n idempotencyKey: init.idempotencyKey,\n });\n return { queued: true, id: saved.id, item: saved };\n }\n\n private async enqueue(\n partial: Omit<\n QueueItem,\n 'id' | 'createdAt' | 'updatedAt' | 'attempts' | 'status' | 'nextAttemptAt'\n >,\n ): Promise<QueueItem> {\n return this.persistNewQueueItem(partial);\n }\n\n private async cancelQueued(id: string): Promise<void> {\n this.syncManager.cancel(id);\n const item = await this.requestQueue.get(id);\n if (item && item.status !== 'done' && item.status !== 'cancelled') {\n await this.requestQueue.update({ ...item, status: 'cancelled', updatedAt: Date.now() });\n }\n }\n}\n\nexport function createLowdataClient(config?: LowdataClientConfig): LowdataClient {\n return new LowdataClient(config);\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { U as Unsubscribe } from './types--FRrBa-i.js';
1
+ import { U as Unsubscribe } from './types-D6fjl8Wy.js';
2
2
 
3
3
  interface ProgressiveImageState {
4
4
  src: string;
@@ -1,4 +1,4 @@
1
- import { U as Unsubscribe } from './types--FRrBa-i.cjs';
1
+ import { U as Unsubscribe } from './types-D6fjl8Wy.cjs';
2
2
 
3
3
  interface ProgressiveImageState {
4
4
  src: string;
package/dist/react.cjs CHANGED
@@ -281,16 +281,23 @@ function getSharedDb() {
281
281
  }
282
282
  return sharedDbPromise;
283
283
  }
284
- function createDbFallbackAccessor(getDb) {
284
+ function createDbFallbackAccessor(getDb, onError) {
285
285
  let dbAvailable = true;
286
286
  return {
287
287
  async run(fn, fallback) {
288
288
  if (!dbAvailable) return fallback();
289
+ let db;
289
290
  try {
290
- const db = await getDb();
291
- return await fn(db);
292
- } catch {
291
+ db = await getDb();
292
+ } catch (error) {
293
293
  dbAvailable = false;
294
+ onError == null ? void 0 : onError(error, { scope: "db-open" });
295
+ return fallback();
296
+ }
297
+ try {
298
+ return await fn(db);
299
+ } catch (error) {
300
+ onError == null ? void 0 : onError(error, { scope: "db-operation" });
294
301
  return fallback();
295
302
  }
296
303
  },
@@ -316,9 +323,9 @@ var LowdataRequestError = class extends Error {
316
323
  var STORE = "queue";
317
324
  var PRIORITY_ORDER = { high: 0, normal: 1, low: 2 };
318
325
  var RequestQueue = class {
319
- constructor(getDb) {
326
+ constructor(getDb, onError) {
320
327
  this.memory = /* @__PURE__ */ new Map();
321
- this.accessor = createDbFallbackAccessor(getDb);
328
+ this.accessor = createDbFallbackAccessor(getDb, onError);
322
329
  }
323
330
  isPersistent() {
324
331
  return this.accessor.isPersistent();
@@ -633,12 +640,16 @@ var SyncManager = class {
633
640
  * or safety poll simply tries again.
634
641
  */
635
642
  async drain() {
636
- var _a, _b, _c, _d;
643
+ var _a, _b, _c, _d, _e, _f;
637
644
  if (this.draining || this.disposed) return;
638
645
  if (this.opts.connection.getStatus().quality === "offline") return;
639
646
  this.draining = true;
640
647
  try {
641
- const db = await this.opts.getDb().catch(() => void 0);
648
+ const db = await this.opts.getDb().catch((error) => {
649
+ var _a2, _b2;
650
+ (_b2 = (_a2 = this.opts).onError) == null ? void 0 : _b2.call(_a2, error, { scope: "db-open" });
651
+ return void 0;
652
+ });
642
653
  const lock = await acquireSyncLock(db, SYNC_LOCK_NAME, this.ownerId);
643
654
  if (!lock) return;
644
655
  let succeeded = 0;
@@ -661,7 +672,8 @@ var SyncManager = class {
661
672
  await lock.release().catch(() => {
662
673
  });
663
674
  }
664
- } catch {
675
+ } catch (error) {
676
+ (_f = (_e = this.opts).onError) == null ? void 0 : _f.call(_e, error, { scope: "sync" });
665
677
  } finally {
666
678
  this.draining = false;
667
679
  }
@@ -747,6 +759,9 @@ var MUTATING_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"
747
759
  function defaultShouldQueueOffline({ method }) {
748
760
  return MUTATING_METHODS.has(method);
749
761
  }
762
+ var defaultOnError = (error, { scope }) => {
763
+ console.warn(`lowdata: internal error (${scope})`, error);
764
+ };
750
765
  function normalizeHeaders(headers) {
751
766
  if (!headers) return void 0;
752
767
  if (headers instanceof Headers) {
@@ -775,15 +790,18 @@ var LowdataClient = class {
775
790
  this.config = config;
776
791
  this.syncEmitter = new Emitter();
777
792
  this.destroyed = false;
793
+ var _a;
794
+ const onError = (_a = config.onError) != null ? _a : defaultOnError;
778
795
  this.monitor = new ConnectionMonitor(config.connection);
779
- this.requestQueue = new RequestQueue(() => getSharedDb());
796
+ this.requestQueue = new RequestQueue(() => getSharedDb(), onError);
780
797
  this.syncManager = new SyncManager({
781
798
  queue: this.requestQueue,
782
799
  connection: this.monitor,
783
800
  getDb: () => getSharedDb(),
784
801
  retryConfig: config.retry,
785
802
  syncConcurrency: config.syncConcurrency,
786
- onEvent: (event) => this.syncEmitter.emit(event)
803
+ onEvent: (event) => this.syncEmitter.emit(event),
804
+ onError
787
805
  });
788
806
  this.connection = {
789
807
  getStatus: () => this.monitor.getStatus(),