featuredrop 1.4.0 → 2.1.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.
- package/README.md +287 -760
- package/dist/adapters.cjs +1757 -0
- package/dist/adapters.cjs.map +1 -0
- package/dist/adapters.d.cts +744 -0
- package/dist/adapters.d.ts +744 -0
- package/dist/adapters.js +1745 -0
- package/dist/adapters.js.map +1 -0
- package/dist/admin.cjs +148 -32
- package/dist/admin.cjs.map +1 -1
- package/dist/admin.d.cts +14 -3
- package/dist/admin.d.ts +14 -3
- package/dist/admin.js +148 -32
- package/dist/admin.js.map +1 -1
- package/dist/bridges.cjs +111 -13
- package/dist/bridges.cjs.map +1 -1
- package/dist/bridges.d.cts +12 -5
- package/dist/bridges.d.ts +12 -5
- package/dist/bridges.js +111 -13
- package/dist/bridges.js.map +1 -1
- package/dist/ci.cjs +34 -0
- package/dist/ci.cjs.map +1 -1
- package/dist/ci.d.cts +5 -1
- package/dist/ci.d.ts +5 -1
- package/dist/ci.js +34 -1
- package/dist/ci.js.map +1 -1
- package/dist/cms.cjs +835 -0
- package/dist/cms.cjs.map +1 -0
- package/dist/cms.d.cts +236 -0
- package/dist/cms.d.ts +236 -0
- package/dist/cms.js +829 -0
- package/dist/cms.js.map +1 -0
- package/dist/flags.cjs +27 -7
- package/dist/flags.cjs.map +1 -1
- package/dist/flags.d.cts +14 -0
- package/dist/flags.d.ts +14 -0
- package/dist/flags.js +27 -7
- package/dist/flags.js.map +1 -1
- package/dist/index.cjs +52 -4481
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1340
- package/dist/index.d.ts +1 -1340
- package/dist/index.js +53 -4388
- package/dist/index.js.map +1 -1
- package/dist/markdown.cjs +257 -0
- package/dist/markdown.cjs.map +1 -0
- package/dist/markdown.d.cts +9 -0
- package/dist/markdown.d.ts +9 -0
- package/dist/markdown.js +234 -0
- package/dist/markdown.js.map +1 -0
- package/dist/renderer.cjs +503 -0
- package/dist/renderer.cjs.map +1 -0
- package/dist/renderer.d.cts +250 -0
- package/dist/renderer.d.ts +250 -0
- package/dist/renderer.js +501 -0
- package/dist/renderer.js.map +1 -0
- package/dist/rss.cjs +291 -0
- package/dist/rss.cjs.map +1 -0
- package/dist/rss.d.cts +158 -0
- package/dist/rss.d.ts +158 -0
- package/dist/rss.js +268 -0
- package/dist/rss.js.map +1 -0
- package/package.json +72 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/adapters/local-storage.ts","../src/adapters/indexeddb.ts","../src/adapters/memory.ts","../src/adapters/remote.ts","../src/adapters/postgres.ts","../src/adapters/redis.ts","../src/adapters/hybrid.ts","../src/adapters/mysql.ts","../src/adapters/mongo.ts","../src/adapters/sqlite.ts","../src/adapters/supabase.ts"],"names":["DISMISSED_SUFFIX","normalizeDismissedIds","normalizeWatermark","normalizeLastSeen","parseDismissedIds"],"mappings":"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","file":"adapters.cjs","sourcesContent":["import type { StorageAdapter } from \"../types\";\n\nexport interface LocalStorageAdapterOptions {\n /** Key prefix for localStorage entries. Default: \"featuredrop\" */\n prefix?: string;\n /** Server-side watermark (ISO string). Typically from user profile. */\n watermark?: string | null;\n /** Callback when dismissAll is called. Use for server-side watermark updates. */\n onDismissAll?: (now: Date) => Promise<void>;\n}\n\nconst DISMISSED_SUFFIX = \":dismissed\";\n\n/**\n * localStorage-based storage adapter.\n *\n * Architecture:\n * - **Watermark** comes from the server (passed at construction time)\n * - **Per-feature dismissals** are stored in localStorage (zero server writes)\n * - **dismissAll()** optionally calls a server callback, then clears localStorage\n *\n * Gracefully handles SSR environments where `window`/`localStorage` is unavailable.\n */\nexport class LocalStorageAdapter implements StorageAdapter {\n private readonly prefix: string;\n private readonly watermarkValue: string | null;\n private readonly onDismissAllCallback?: (now: Date) => Promise<void>;\n private readonly dismissedKey: string;\n\n constructor(options: LocalStorageAdapterOptions = {}) {\n this.prefix = options.prefix ?? \"featuredrop\";\n this.watermarkValue = options.watermark ?? null;\n this.onDismissAllCallback = options.onDismissAll;\n this.dismissedKey = `${this.prefix}${DISMISSED_SUFFIX}`;\n }\n\n getWatermark(): string | null {\n return this.watermarkValue;\n }\n\n getDismissedIds(): ReadonlySet<string> {\n try {\n if (typeof window === \"undefined\") return new Set();\n const raw = localStorage.getItem(this.dismissedKey);\n if (!raw) return new Set();\n const parsed: unknown = JSON.parse(raw);\n if (Array.isArray(parsed)) return new Set(parsed as string[]);\n return new Set();\n } catch {\n return new Set();\n }\n }\n\n dismiss(id: string): void {\n try {\n if (typeof window === \"undefined\") return;\n const raw = localStorage.getItem(this.dismissedKey);\n const existing: string[] = raw ? (JSON.parse(raw) as string[]) : [];\n if (!existing.includes(id)) {\n existing.push(id);\n localStorage.setItem(this.dismissedKey, JSON.stringify(existing));\n }\n } catch {\n // localStorage unavailable — silent fail\n }\n }\n\n async dismissAll(now: Date): Promise<void> {\n try {\n if (typeof window !== \"undefined\") {\n localStorage.removeItem(this.dismissedKey);\n }\n } catch {\n // localStorage unavailable — silent fail\n }\n\n if (this.onDismissAllCallback) {\n await this.onDismissAllCallback(now);\n }\n }\n}\n","import type { StorageAdapter } from \"../types\";\n\nexport interface IndexedDBAdapterOptions {\n prefix?: string;\n watermark?: string | null;\n dbName?: string;\n storeName?: string;\n onDismissAll?: (now: Date) => Promise<void>;\n /** Optional remote state fetch for offline-first sync reconciliation. */\n onSyncState?: () => Promise<{ watermark?: string | null; dismissedIds?: string[] }>;\n /** Optional remote flush for queued single-dismiss operations. */\n onFlushDismissBatch?: (ids: string[]) => Promise<void>;\n /** Optional remote flush for queued dismiss-all operations. */\n onFlushDismissAll?: (watermark: string) => Promise<void>;\n /** Delay before queued operations are flushed. Default: 500ms. */\n flushDebounceMs?: number;\n /** Attach online/visibility listeners to trigger sync+flush. Default: true in browser. */\n autoSyncOnOnline?: boolean;\n}\n\ninterface PersistedState {\n watermark: string | null;\n dismissed: string[];\n queue?: PersistedQueueOperation[];\n}\n\ntype PersistedQueueOperation =\n | { type: \"dismiss\"; id: string }\n | { type: \"dismissAll\"; watermark: string };\n\ninterface SyncStatePayload {\n watermark?: string | null;\n dismissedIds?: string[];\n}\n\nconst DISMISSED_SUFFIX = \":dismissed\";\nconst WATERMARK_SUFFIX = \":watermark\";\nconst QUEUE_SUFFIX = \":queue\";\n\nfunction canUseLocalStorage(): boolean {\n return typeof window !== \"undefined\" && typeof window.localStorage !== \"undefined\";\n}\n\nfunction readLocalStorageState(prefix: string): PersistedState {\n if (!canUseLocalStorage()) {\n return { watermark: null, dismissed: [], queue: [] };\n }\n try {\n const dismissedRaw = localStorage.getItem(`${prefix}${DISMISSED_SUFFIX}`);\n const watermarkRaw = localStorage.getItem(`${prefix}${WATERMARK_SUFFIX}`);\n const queueRaw = localStorage.getItem(`${prefix}${QUEUE_SUFFIX}`);\n const dismissedParsed = dismissedRaw ? JSON.parse(dismissedRaw) as unknown : [];\n const queueParsed = queueRaw ? JSON.parse(queueRaw) as unknown : [];\n return {\n watermark: typeof watermarkRaw === \"string\" ? watermarkRaw : null,\n dismissed: Array.isArray(dismissedParsed)\n ? dismissedParsed.filter((value): value is string => typeof value === \"string\")\n : [],\n queue: normalizeQueue(queueParsed),\n };\n } catch {\n return { watermark: null, dismissed: [], queue: [] };\n }\n}\n\nfunction writeLocalStorageState(prefix: string, state: PersistedState): void {\n if (!canUseLocalStorage()) return;\n try {\n localStorage.setItem(`${prefix}${DISMISSED_SUFFIX}`, JSON.stringify(state.dismissed));\n if (state.watermark) {\n localStorage.setItem(`${prefix}${WATERMARK_SUFFIX}`, state.watermark);\n } else {\n localStorage.removeItem(`${prefix}${WATERMARK_SUFFIX}`);\n }\n if (state.queue && state.queue.length > 0) {\n localStorage.setItem(`${prefix}${QUEUE_SUFFIX}`, JSON.stringify(state.queue));\n } else {\n localStorage.removeItem(`${prefix}${QUEUE_SUFFIX}`);\n }\n } catch {\n // ignore storage write errors\n }\n}\n\nfunction getIndexedDBFactory(): IDBFactory | null {\n if (typeof globalThis === \"undefined\") return null;\n const candidate = globalThis.indexedDB as IDBFactory | undefined;\n return candidate ?? null;\n}\n\nfunction normalizeQueue(value: unknown): PersistedQueueOperation[] {\n if (!Array.isArray(value)) return [];\n const queue: PersistedQueueOperation[] = [];\n for (const item of value) {\n if (!item || typeof item !== \"object\") continue;\n const candidate = item as Record<string, unknown>;\n if (candidate.type === \"dismiss\" && typeof candidate.id === \"string\") {\n queue.push({ type: \"dismiss\", id: candidate.id });\n continue;\n }\n if (candidate.type === \"dismissAll\" && typeof candidate.watermark === \"string\") {\n queue.push({ type: \"dismissAll\", watermark: candidate.watermark });\n continue;\n }\n }\n return queue;\n}\n\nfunction normalizeDismissedIds(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.filter((entry): entry is string => typeof entry === \"string\");\n}\n\nfunction parseIso(value: string | null | undefined): number {\n if (!value) return Number.NaN;\n return new Date(value).getTime();\n}\n\nfunction resolveLatestWatermark(a: string | null, b: string | null): string | null {\n if (!a) return b ?? null;\n if (!b) return a;\n const aTs = parseIso(a);\n const bTs = parseIso(b);\n if (!Number.isFinite(aTs)) return b;\n if (!Number.isFinite(bTs)) return a;\n return aTs >= bTs ? a : b;\n}\n\nexport class IndexedDBAdapter implements StorageAdapter {\n private readonly prefix: string;\n private readonly dbName: string;\n private readonly storeName: string;\n private readonly onDismissAllCallback?: (now: Date) => Promise<void>;\n private readonly onSyncStateCallback?: () => Promise<SyncStatePayload>;\n private readonly onFlushDismissBatchCallback?: (ids: string[]) => Promise<void>;\n private readonly onFlushDismissAllCallback?: (watermark: string) => Promise<void>;\n private readonly flushDebounceMs: number;\n private readonly autoSyncOnOnline: boolean;\n private watermark: string | null;\n private dismissed: Set<string>;\n private queue: PersistedQueueOperation[];\n private readonly hydratePromise: Promise<void>;\n private flushTimer: ReturnType<typeof setTimeout> | null = null;\n private flushing = false;\n private readonly boundOnlineHandler: (() => void) | null;\n private readonly boundVisibilityHandler: (() => void) | null;\n\n constructor(options: IndexedDBAdapterOptions = {}) {\n this.prefix = options.prefix ?? \"featuredrop\";\n this.dbName = options.dbName ?? \"featuredrop\";\n this.storeName = options.storeName ?? \"state\";\n this.onDismissAllCallback = options.onDismissAll;\n this.onSyncStateCallback = options.onSyncState;\n this.onFlushDismissBatchCallback = options.onFlushDismissBatch;\n this.onFlushDismissAllCallback = options.onFlushDismissAll;\n this.flushDebounceMs = options.flushDebounceMs ?? 500;\n this.autoSyncOnOnline = options.autoSyncOnOnline ?? true;\n\n const localState = readLocalStorageState(this.prefix);\n this.watermark = options.watermark ?? localState.watermark;\n this.dismissed = new Set(localState.dismissed);\n this.queue = localState.queue ?? [];\n this.hydratePromise = this.hydrateFromIndexedDB();\n\n const canAttachListeners = this.autoSyncOnOnline && typeof window !== \"undefined\";\n if (canAttachListeners) {\n this.boundOnlineHandler = () => {\n void this.syncFromRemote();\n };\n this.boundVisibilityHandler = () => {\n if (document.visibilityState === \"visible\") {\n void this.syncFromRemote();\n }\n };\n window.addEventListener(\"online\", this.boundOnlineHandler);\n document.addEventListener(\"visibilitychange\", this.boundVisibilityHandler);\n } else {\n this.boundOnlineHandler = null;\n this.boundVisibilityHandler = null;\n }\n }\n\n getWatermark(): string | null {\n return this.watermark;\n }\n\n getDismissedIds(): ReadonlySet<string> {\n return this.dismissed;\n }\n\n dismiss(id: string): void {\n if (!id || this.dismissed.has(id)) return;\n this.dismissed = new Set(this.dismissed).add(id);\n this.queue.push({ type: \"dismiss\", id });\n this.persist();\n this.scheduleFlush();\n }\n\n async dismissAll(now: Date): Promise<void> {\n this.watermark = now.toISOString();\n this.dismissed = new Set();\n this.queue = [{ type: \"dismissAll\", watermark: this.watermark }];\n this.persist();\n this.scheduleFlush();\n await this.onDismissAllCallback?.(now);\n }\n\n /** Flush queued dismiss operations to optional remote callbacks. */\n async flushQueue(): Promise<void> {\n if (this.flushing || this.queue.length === 0) return;\n if (!this.onFlushDismissBatchCallback && !this.onFlushDismissAllCallback) return;\n\n this.flushing = true;\n try {\n const operations = [...this.queue];\n const lastDismissAll = this.getLastDismissAll(operations);\n const dismissIds = this.collectDismissBatch(operations, !!lastDismissAll);\n const hasDismissAll = !!lastDismissAll;\n const needsDismissBatch = dismissIds.length > 0;\n\n // If caller only provided one remote callback, keep unsupported operations queued.\n if (hasDismissAll && !this.onFlushDismissAllCallback) return;\n if (needsDismissBatch && !this.onFlushDismissBatchCallback) return;\n\n if (lastDismissAll && this.onFlushDismissAllCallback) {\n await this.onFlushDismissAllCallback(lastDismissAll.watermark);\n }\n\n if (dismissIds.length > 0 && this.onFlushDismissBatchCallback) {\n await this.onFlushDismissBatchCallback(dismissIds);\n }\n\n // Clear all operations that were part of this flush snapshot.\n if (this.queue.length <= operations.length) {\n this.queue = [];\n } else {\n this.queue = this.queue.slice(operations.length);\n }\n this.persist();\n } catch {\n // Keep queue for retry after network recovery.\n } finally {\n this.flushing = false;\n }\n }\n\n /** Merge local state with optional remote source, then flush queued writes. */\n async syncFromRemote(): Promise<void> {\n await this.hydratePromise.catch(() => undefined);\n if (this.onSyncStateCallback) {\n try {\n const remote = await this.onSyncStateCallback();\n const mergedDismissed = new Set<string>(this.dismissed);\n for (const id of normalizeDismissedIds(remote.dismissedIds)) {\n mergedDismissed.add(id);\n }\n this.dismissed = mergedDismissed;\n this.watermark = resolveLatestWatermark(this.watermark, remote.watermark ?? null);\n this.persist();\n } catch {\n // Keep local state if remote sync fails.\n }\n }\n await this.flushQueue();\n }\n\n /** Cleanup optional browser listeners. */\n destroy(): void {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n if (this.boundOnlineHandler && typeof window !== \"undefined\") {\n window.removeEventListener(\"online\", this.boundOnlineHandler);\n }\n if (this.boundVisibilityHandler && typeof document !== \"undefined\") {\n document.removeEventListener(\"visibilitychange\", this.boundVisibilityHandler);\n }\n }\n\n private persist(): void {\n const snapshot = {\n watermark: this.watermark,\n dismissed: Array.from(this.dismissed),\n queue: this.queue,\n };\n writeLocalStorageState(this.prefix, snapshot);\n void this.writeIndexedDBState(snapshot);\n }\n\n private async hydrateFromIndexedDB(): Promise<void> {\n const state = await this.readIndexedDBState();\n if (!state) return;\n this.watermark = state.watermark;\n this.dismissed = new Set(state.dismissed);\n this.queue = state.queue ?? [];\n writeLocalStorageState(this.prefix, state);\n }\n\n private async readIndexedDBState(): Promise<PersistedState | null> {\n const db = await this.openDb();\n if (!db) return null;\n\n return new Promise((resolve) => {\n const tx = db.transaction(this.storeName, \"readonly\");\n const store = tx.objectStore(this.storeName);\n const request = store.get(this.prefix);\n request.onsuccess = () => {\n const value = request.result as PersistedState | undefined;\n if (!value) {\n resolve(null);\n return;\n }\n resolve({\n watermark: typeof value.watermark === \"string\" ? value.watermark : null,\n dismissed: normalizeDismissedIds(value.dismissed),\n queue: normalizeQueue(value.queue),\n });\n };\n request.onerror = () => resolve(null);\n });\n }\n\n private async writeIndexedDBState(state: PersistedState): Promise<void> {\n await this.hydratePromise.catch(() => undefined);\n const db = await this.openDb();\n if (!db) return;\n\n await new Promise<void>((resolve) => {\n const tx = db.transaction(this.storeName, \"readwrite\");\n const store = tx.objectStore(this.storeName);\n store.put(state, this.prefix);\n tx.oncomplete = () => resolve();\n tx.onerror = () => resolve();\n tx.onabort = () => resolve();\n });\n }\n\n private async openDb(): Promise<IDBDatabase | null> {\n const factory = getIndexedDBFactory();\n if (!factory) return null;\n\n return new Promise((resolve) => {\n const request = factory.open(this.dbName, 1);\n request.onerror = () => resolve(null);\n request.onupgradeneeded = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains(this.storeName)) {\n db.createObjectStore(this.storeName);\n }\n };\n request.onsuccess = () => resolve(request.result);\n });\n }\n\n private scheduleFlush(): void {\n if (this.flushTimer) return;\n this.flushTimer = setTimeout(() => {\n this.flushTimer = null;\n void this.flushQueue();\n }, this.flushDebounceMs);\n }\n\n private getLastDismissAll(operations: PersistedQueueOperation[]): { watermark: string } | null {\n for (let index = operations.length - 1; index >= 0; index--) {\n const operation = operations[index];\n if (operation.type === \"dismissAll\") {\n return { watermark: operation.watermark };\n }\n }\n return null;\n }\n\n private collectDismissBatch(\n operations: PersistedQueueOperation[],\n skipBeforeDismissAll: boolean,\n ): string[] {\n const startIndex = skipBeforeDismissAll\n ? operations.reduce(\n (lastIndex, operation, index) =>\n operation.type === \"dismissAll\" ? index : lastIndex,\n -1,\n )\n : -1;\n const batch = new Set<string>();\n for (let index = startIndex + 1; index < operations.length; index++) {\n const operation = operations[index];\n if (operation.type === \"dismiss\") {\n batch.add(operation.id);\n }\n }\n return Array.from(batch);\n }\n}\n","import type { StorageAdapter } from \"../types\";\n\n/**\n * In-memory storage adapter.\n *\n * Useful for:\n * - Testing (no side effects)\n * - Server-side rendering (no `window`/`localStorage`)\n * - Environments without persistent storage\n */\nexport class MemoryAdapter implements StorageAdapter {\n private watermark: string | null;\n private dismissed: Set<string>;\n\n constructor(options: { watermark?: string | null } = {}) {\n this.watermark = options.watermark ?? null;\n this.dismissed = new Set();\n }\n\n getWatermark(): string | null {\n return this.watermark;\n }\n\n getDismissedIds(): ReadonlySet<string> {\n return this.dismissed;\n }\n\n dismiss(id: string): void {\n this.dismissed.add(id);\n }\n\n async dismissAll(now: Date): Promise<void> {\n this.watermark = now.toISOString();\n this.dismissed.clear();\n }\n}\n","import type { FeatureManifest, StorageAdapter } from \"../types\";\n\nexport interface RemoteAdapterOptions {\n /** Base URL for the feature API (e.g. https://api.example.com/api/features) */\n url: string;\n /** Optional headers applied to all requests */\n headers?: Record<string, string>;\n /** Polling interval in ms for stale-while-revalidate (default: 5 minutes) */\n fetchInterval?: number;\n /** Data format, currently supports 'rest' (default) */\n format?: \"rest\";\n /** Optional user identifier to pass to state endpoint */\n userId?: string;\n /** Number of retries after the initial request (default: 3) */\n retryAttempts?: number;\n /** Base backoff delay used between retries (default: 250ms) */\n retryBaseDelayMs?: number;\n /** Consecutive failed operations before opening the circuit (default: 5) */\n circuitBreakerThreshold?: number;\n /** Cooldown period while the circuit is open (default: 60s) */\n circuitBreakerCooldownMs?: number;\n /** Optional sleep function override for test environments */\n sleep?: (delayMs: number) => Promise<void>;\n /** Optional timestamp function override for test environments */\n now?: () => number;\n /** Request timeout in milliseconds (default: 10s). */\n requestTimeoutMs?: number;\n /** HTTP statuses that should be retried (default: 408,429,500,502,503,504). */\n retryOnStatuses?: number[];\n /** Debounce window for batching dismiss calls (default: 150ms). */\n dismissBatchWindowMs?: number;\n /** Max ids sent in a single dismiss-batch request (default: 100). */\n maxDismissBatchSize?: number;\n /** Disable `/dismiss-batch` endpoint usage and always send single dismiss requests. */\n disableDismissBatch?: boolean;\n /** Flush/sync pending state when browser regains connectivity (default: false). */\n syncOnOnline?: boolean;\n /** Flush/sync pending state when tab becomes visible again (default: false). */\n syncOnVisibilityChange?: boolean;\n /** Optional periodic state sync interval in ms (default: disabled). */\n syncIntervalMs?: number;\n /** Optional error hook for diagnostics/telemetry. */\n onError?: (error: unknown, context: { operation: string; attempt: number }) => void;\n}\n\ninterface RemoteStateResponse {\n watermark?: string | null;\n dismissedIds?: string[];\n}\n\nclass RemoteHttpError extends Error {\n readonly status: number;\n\n constructor(message: string, status: number) {\n super(message);\n this.name = \"RemoteHttpError\";\n this.status = status;\n }\n}\n\nfunction assertFetch(): typeof fetch {\n if (typeof fetch === \"undefined\") {\n throw new Error(\"RemoteAdapter requires global fetch (Node 18+ or polyfill)\");\n }\n return fetch;\n}\n\nexport class RemoteAdapter implements StorageAdapter {\n private readonly baseUrl: string;\n private readonly headers: Record<string, string>;\n private readonly fetchInterval: number;\n private readonly userId?: string;\n private dismissedIds: Set<string> = new Set();\n private watermark: string | null = null;\n private lastManifest: FeatureManifest | null = null;\n private lastFetchTs = 0;\n private readonly retryAttempts: number;\n private readonly retryBaseDelayMs: number;\n private readonly circuitBreakerThreshold: number;\n private readonly circuitBreakerCooldownMs: number;\n private readonly sleep: (delayMs: number) => Promise<void>;\n private readonly now: () => number;\n private readonly requestTimeoutMs: number;\n private readonly retryOnStatuses: Set<number>;\n private readonly dismissBatchWindowMs: number;\n private readonly maxDismissBatchSize: number;\n private readonly disableDismissBatch: boolean;\n private readonly syncOnOnline: boolean;\n private readonly syncOnVisibilityChange: boolean;\n private readonly syncIntervalMs: number;\n private readonly onError?: (error: unknown, context: { operation: string; attempt: number }) => void;\n private consecutiveFailures = 0;\n private circuitOpenUntil = 0;\n private manifestInFlight: Promise<FeatureManifest> | null = null;\n private stateSyncInFlight: Promise<void> | null = null;\n private dismissFlushInFlight: Promise<void> | null = null;\n private dismissFlushTimer: ReturnType<typeof setTimeout> | null = null;\n private syncTimer: ReturnType<typeof setInterval> | null = null;\n private pendingDismissIds = new Set<string>();\n private supportsDismissBatch = true;\n private readonly boundOnlineHandler: (() => void) | null = null;\n private readonly boundVisibilityHandler: (() => void) | null = null;\n\n constructor(options: RemoteAdapterOptions) {\n this.baseUrl = options.url.replace(/\\/$/, \"\");\n this.headers = options.headers ?? {};\n this.fetchInterval = options.fetchInterval ?? 5 * 60 * 1000;\n this.userId = options.userId;\n this.retryAttempts = options.retryAttempts ?? 3;\n this.retryBaseDelayMs = options.retryBaseDelayMs ?? 250;\n this.circuitBreakerThreshold = options.circuitBreakerThreshold ?? 5;\n this.circuitBreakerCooldownMs = options.circuitBreakerCooldownMs ?? 60_000;\n this.sleep = options.sleep ?? ((delayMs: number) => new Promise((resolve) => setTimeout(resolve, delayMs)));\n this.now = options.now ?? (() => Date.now());\n this.requestTimeoutMs = options.requestTimeoutMs ?? 10_000;\n this.retryOnStatuses = new Set(options.retryOnStatuses ?? [408, 429, 500, 502, 503, 504]);\n this.dismissBatchWindowMs = options.dismissBatchWindowMs ?? 150;\n this.maxDismissBatchSize = Math.max(1, options.maxDismissBatchSize ?? 100);\n this.disableDismissBatch = options.disableDismissBatch ?? false;\n this.syncOnOnline = options.syncOnOnline ?? false;\n this.syncOnVisibilityChange = options.syncOnVisibilityChange ?? false;\n this.syncIntervalMs = Math.max(0, options.syncIntervalMs ?? 0);\n this.onError = options.onError;\n\n if (typeof window !== \"undefined\" && this.syncOnOnline) {\n this.boundOnlineHandler = () => {\n void this.runRecoverySync();\n };\n window.addEventListener(\"online\", this.boundOnlineHandler);\n }\n\n if (typeof document !== \"undefined\" && this.syncOnVisibilityChange) {\n this.boundVisibilityHandler = () => {\n if (document.visibilityState === \"visible\") {\n void this.runRecoverySync();\n }\n };\n document.addEventListener(\"visibilitychange\", this.boundVisibilityHandler);\n }\n\n if (this.syncIntervalMs > 0) {\n this.syncTimer = setInterval(() => {\n void this.syncState();\n }, this.syncIntervalMs);\n }\n }\n\n /** Fetch manifest with stale-while-revalidate */\n async fetchManifest(force = false): Promise<FeatureManifest> {\n const now = this.now();\n if (!force && this.lastManifest && now - this.lastFetchTs < this.fetchInterval) {\n return this.lastManifest;\n }\n if (this.manifestInFlight) return this.manifestInFlight;\n\n const task = (async () => {\n try {\n const json = await this.withRetry(\"fetchManifest\", async () =>\n this.requestJson<FeatureManifest>(\"\", {\n method: \"GET\",\n headers: this.headers,\n }),\n );\n this.lastManifest = json;\n this.lastFetchTs = now;\n return json;\n } catch {\n // Graceful fallback: stale cache if available, empty manifest otherwise.\n return this.lastManifest ?? [];\n }\n })();\n this.manifestInFlight = task.finally(() => {\n this.manifestInFlight = null;\n });\n return this.manifestInFlight;\n }\n\n /** Fetch state (watermark + dismissed IDs) */\n async syncState(): Promise<void> {\n if (this.stateSyncInFlight) return this.stateSyncInFlight;\n const task = (async () => {\n try {\n const query = this.userId ? `?userId=${encodeURIComponent(this.userId)}` : \"\";\n const json = await this.withRetry(\"syncState\", async () =>\n this.requestJson<RemoteStateResponse>(`/state${query}`, {\n method: \"GET\",\n headers: this.headers,\n }),\n );\n\n if (json.watermark !== undefined) this.watermark = json.watermark;\n if (Array.isArray(json.dismissedIds)) this.dismissedIds = new Set(json.dismissedIds);\n } catch {\n // Best effort sync — failures should not crash host apps.\n }\n })();\n this.stateSyncInFlight = task.finally(() => {\n this.stateSyncInFlight = null;\n });\n return this.stateSyncInFlight;\n }\n\n getWatermark(): string | null {\n return this.watermark;\n }\n\n getDismissedIds(): ReadonlySet<string> {\n return this.dismissedIds;\n }\n\n dismiss(id: string): void {\n if (!id) return;\n this.dismissedIds.add(id);\n this.pendingDismissIds.add(id);\n this.scheduleDismissFlush();\n }\n\n async dismissAll(now: Date): Promise<void> {\n await this.flushPendingDismisses().catch(() => {\n // keep local state responsive even when flush fails\n });\n this.watermark = now.toISOString();\n this.dismissedIds.clear();\n await this.flushDismissAll(now).catch(() => {});\n }\n\n /** Cleanup timers/listeners and flush any queued dismiss operations. */\n async destroy(): Promise<void> {\n if (this.dismissFlushTimer) {\n clearTimeout(this.dismissFlushTimer);\n this.dismissFlushTimer = null;\n }\n if (this.syncTimer) {\n clearInterval(this.syncTimer);\n this.syncTimer = null;\n }\n if (this.boundOnlineHandler && typeof window !== \"undefined\") {\n window.removeEventListener(\"online\", this.boundOnlineHandler);\n }\n if (this.boundVisibilityHandler && typeof document !== \"undefined\") {\n document.removeEventListener(\"visibilitychange\", this.boundVisibilityHandler);\n }\n await this.flushPendingDismisses().catch(() => {\n // suppress teardown errors and keep local state intact\n });\n }\n\n /** Returns current adapter health; false while circuit breaker is open. */\n async isHealthy(): Promise<boolean> {\n if (this.isCircuitOpen()) return false;\n try {\n await this.withRetry(\"isHealthy\", async () =>\n this.requestVoid(\"\", {\n method: \"GET\",\n headers: this.headers,\n }),\n );\n return true;\n } catch {\n return false;\n }\n }\n\n private async flushDismiss(id: string): Promise<void> {\n await this.withRetry(\"dismiss\", async () =>\n this.requestVoid(\"/dismiss\", {\n method: \"POST\",\n jsonBody: { featureId: id },\n }),\n );\n }\n\n private async flushDismissAll(now: Date): Promise<void> {\n await this.withRetry(\"dismissAll\", async () =>\n this.requestVoid(\"/dismiss-all\", {\n method: \"POST\",\n jsonBody: { watermark: now.toISOString() },\n }),\n );\n }\n\n private isCircuitOpen(): boolean {\n return this.now() < this.circuitOpenUntil;\n }\n\n private markFailure(): void {\n this.consecutiveFailures += 1;\n if (this.consecutiveFailures >= this.circuitBreakerThreshold) {\n this.circuitOpenUntil = this.now() + this.circuitBreakerCooldownMs;\n }\n }\n\n private markSuccess(): void {\n this.consecutiveFailures = 0;\n this.circuitOpenUntil = 0;\n }\n\n /** Force-flush queued dismiss IDs immediately. */\n async flushPendingDismisses(): Promise<void> {\n if (this.dismissFlushTimer) {\n clearTimeout(this.dismissFlushTimer);\n this.dismissFlushTimer = null;\n }\n if (this.dismissFlushInFlight) return this.dismissFlushInFlight;\n const task = this.flushPendingDismissesInternal();\n this.dismissFlushInFlight = task.finally(() => {\n this.dismissFlushInFlight = null;\n });\n return this.dismissFlushInFlight;\n }\n\n private async flushPendingDismissesInternal(): Promise<void> {\n if (this.pendingDismissIds.size === 0) return;\n const ids = Array.from(this.pendingDismissIds);\n this.pendingDismissIds.clear();\n try {\n await this.flushDismissBatch(ids);\n } catch {\n for (const id of ids) this.pendingDismissIds.add(id);\n throw new Error(\"RemoteAdapter dismiss flush failed\");\n }\n }\n\n private async flushDismissBatch(ids: string[]): Promise<void> {\n for (let index = 0; index < ids.length; index += this.maxDismissBatchSize) {\n const chunk = ids.slice(index, index + this.maxDismissBatchSize);\n if (chunk.length === 1 || this.disableDismissBatch || !this.supportsDismissBatch) {\n await this.flushDismiss(chunk[0]);\n continue;\n }\n\n try {\n await this.withRetry(\"dismissBatch\", async () =>\n this.requestVoid(\"/dismiss-batch\", {\n method: \"POST\",\n jsonBody: { featureIds: chunk },\n }),\n );\n } catch (error: unknown) {\n const status = error instanceof RemoteHttpError ? error.status : undefined;\n // Auto-fallback when backend doesn't support batch endpoint.\n if (status === 404 || status === 405 || status === 501) {\n this.supportsDismissBatch = false;\n for (const id of chunk) {\n await this.flushDismiss(id);\n }\n continue;\n }\n throw error;\n }\n }\n }\n\n private scheduleDismissFlush(): void {\n if (this.dismissFlushTimer) return;\n this.dismissFlushTimer = setTimeout(() => {\n this.dismissFlushTimer = null;\n void this.flushPendingDismisses().catch(() => {\n // keep local-only behavior on network failure and try again later.\n this.scheduleDismissFlush();\n });\n }, this.dismissBatchWindowMs);\n }\n\n private async runRecoverySync(): Promise<void> {\n await this.flushPendingDismisses().catch(() => {\n // queue remains intact for next recovery attempt\n });\n await this.syncState();\n }\n\n private async requestJson<T>(\n path: string,\n init: {\n method: \"GET\" | \"POST\";\n headers?: Record<string, string>;\n jsonBody?: unknown;\n },\n ): Promise<T> {\n const response = await this.request(path, init);\n return (await response.json()) as T;\n }\n\n private async requestVoid(\n path: string,\n init: {\n method: \"GET\" | \"POST\";\n headers?: Record<string, string>;\n jsonBody?: unknown;\n },\n ): Promise<void> {\n await this.request(path, init);\n }\n\n private async request(\n path: string,\n init: {\n method: \"GET\" | \"POST\";\n headers?: Record<string, string>;\n jsonBody?: unknown;\n },\n ): Promise<Response> {\n const fetchImpl = assertFetch();\n const controller = new AbortController();\n const timeoutId =\n this.requestTimeoutMs > 0\n ? setTimeout(() => {\n controller.abort();\n }, this.requestTimeoutMs)\n : null;\n\n try {\n const res = await fetchImpl(`${this.baseUrl}${path}`, {\n method: init.method,\n headers: {\n ...(init.jsonBody ? { \"Content-Type\": \"application/json\" } : {}),\n ...this.headers,\n ...(init.headers ?? {}),\n },\n body: init.jsonBody === undefined ? undefined : JSON.stringify(init.jsonBody),\n signal: controller.signal,\n });\n if (!res.ok) {\n throw new RemoteHttpError(\n `RemoteAdapter request failed (${res.status}) for ${path || \"/\"}`,\n res.status,\n );\n }\n return res;\n } catch (error: unknown) {\n const name =\n error instanceof DOMException\n ? error.name\n : error && typeof error === \"object\" && \"name\" in error\n ? String((error as { name?: unknown }).name)\n : \"\";\n if (name === \"AbortError\") {\n throw new Error(`RemoteAdapter request timed out after ${this.requestTimeoutMs}ms`);\n }\n throw error;\n } finally {\n if (timeoutId) clearTimeout(timeoutId);\n }\n }\n\n private shouldRetry(error: unknown): boolean {\n if (error instanceof RemoteHttpError) {\n return this.retryOnStatuses.has(error.status);\n }\n const message = error instanceof Error ? error.message : \"\";\n if (message.includes(\"circuit breaker is open\")) return false;\n return true;\n }\n\n private async withRetry<T>(operationName: string, operation: () => Promise<T>): Promise<T> {\n if (this.isCircuitOpen()) {\n throw new Error(\"RemoteAdapter circuit breaker is open\");\n }\n\n let lastError: unknown = new Error(\"RemoteAdapter request failed\");\n for (let attempt = 0; attempt <= this.retryAttempts; attempt++) {\n try {\n const result = await operation();\n this.markSuccess();\n return result;\n } catch (error: unknown) {\n lastError = error;\n this.onError?.(error, { operation: operationName, attempt });\n if (attempt >= this.retryAttempts || !this.shouldRetry(error)) break;\n const delayMs = this.retryBaseDelayMs * 2 ** attempt;\n await this.sleep(delayMs);\n }\n }\n\n this.markFailure();\n throw lastError instanceof Error ? lastError : new Error(\"RemoteAdapter request failed\");\n }\n}\n","import type { DismissalState, ServerStorageAdapter } from \"../types\";\n\ninterface QueryResultRow {\n watermark?: string | null;\n dismissed_ids?: string[] | null;\n dismissedIds?: string[] | null;\n last_seen?: string | null;\n lastSeen?: string | null;\n}\n\nexport interface PostgresQueryResult<T = QueryResultRow> {\n rows: T[];\n rowCount?: number | null;\n}\n\nexport type PostgresQueryFn = <T = QueryResultRow>(\n sql: string,\n params?: unknown[],\n) => Promise<PostgresQueryResult<T>>;\n\nexport interface PostgresAdapterOptions {\n userId: string;\n query: PostgresQueryFn;\n tableName?: string;\n autoMigrate?: boolean;\n}\n\nfunction normalizeDismissedIds(row: QueryResultRow | undefined): string[] {\n if (!row) return [];\n const ids = row.dismissed_ids ?? row.dismissedIds;\n if (!Array.isArray(ids)) return [];\n return ids.filter((id): id is string => typeof id === \"string\");\n}\n\nfunction normalizeWatermark(row: QueryResultRow | undefined): string | null {\n if (!row) return null;\n return row.watermark ?? null;\n}\n\nfunction normalizeLastSeen(row: QueryResultRow | undefined): string {\n if (!row) return new Date(0).toISOString();\n return row.last_seen ?? row.lastSeen ?? new Date(0).toISOString();\n}\n\n/**\n * Postgres-backed storage adapter.\n *\n * This adapter is dependency-free by design and accepts a user-provided\n * query function, allowing integration with pg, drizzle, prisma, etc.\n */\nexport class PostgresAdapter implements ServerStorageAdapter {\n readonly userId: string;\n\n private readonly query: PostgresQueryFn;\n private readonly tableName: string;\n private readonly autoMigrate: boolean;\n private watermark: string | null = null;\n private dismissedIds = new Set<string>();\n private initialized = false;\n\n constructor(options: PostgresAdapterOptions) {\n if (!options.userId) {\n throw new Error(\"PostgresAdapter: userId is required\");\n }\n this.userId = options.userId;\n this.query = options.query;\n this.tableName = options.tableName ?? \"featuredrop_state\";\n this.autoMigrate = options.autoMigrate ?? true;\n }\n\n getWatermark(): string | null {\n return this.watermark;\n }\n\n getDismissedIds(): ReadonlySet<string> {\n return this.dismissedIds;\n }\n\n dismiss(id: string): void {\n this.dismissedIds.add(id);\n void this.dismissBatch([id]);\n }\n\n async dismissAll(now: Date): Promise<void> {\n this.watermark = now.toISOString();\n this.dismissedIds.clear();\n await this.ensureReady();\n await this.query(\n `INSERT INTO ${this.tableName} (user_id, watermark, dismissed_ids, last_seen, created_at, updated_at)\n VALUES ($1, $2, '{}', NOW(), NOW(), NOW())\n ON CONFLICT (user_id)\n DO UPDATE SET watermark = EXCLUDED.watermark, dismissed_ids = '{}', last_seen = NOW(), updated_at = NOW()`,\n [this.userId, this.watermark],\n );\n }\n\n async sync(): Promise<void> {\n await this.ensureReady();\n const result = await this.query<QueryResultRow>(\n `SELECT watermark, dismissed_ids, last_seen\n FROM ${this.tableName}\n WHERE user_id = $1`,\n [this.userId],\n );\n const row = result.rows[0];\n this.watermark = normalizeWatermark(row);\n this.dismissedIds = new Set(normalizeDismissedIds(row));\n }\n\n async dismissBatch(ids: string[]): Promise<void> {\n if (ids.length === 0) return;\n await this.ensureReady();\n const uniqueIds = Array.from(new Set(ids));\n await this.query(\n `INSERT INTO ${this.tableName} (user_id, watermark, dismissed_ids, last_seen, created_at, updated_at)\n VALUES ($1, NULL, $2::text[], NOW(), NOW(), NOW())\n ON CONFLICT (user_id)\n DO UPDATE SET\n dismissed_ids = (\n SELECT ARRAY(\n SELECT DISTINCT x FROM UNNEST(\n COALESCE(${this.tableName}.dismissed_ids, '{}') || EXCLUDED.dismissed_ids\n ) AS x\n )\n ),\n last_seen = NOW(),\n updated_at = NOW()`,\n [this.userId, uniqueIds],\n );\n }\n\n async resetUser(userId: string): Promise<void> {\n await this.ensureReady();\n await this.query(\n `DELETE FROM ${this.tableName} WHERE user_id = $1`,\n [userId],\n );\n if (userId === this.userId) {\n this.watermark = null;\n this.dismissedIds.clear();\n }\n }\n\n async getBulkState(userIds: string[]): Promise<Map<string, DismissalState>> {\n await this.ensureReady();\n if (userIds.length === 0) return new Map();\n\n const result = await this.query<QueryResultRow & { user_id: string }>(\n `SELECT user_id, watermark, dismissed_ids, last_seen\n FROM ${this.tableName}\n WHERE user_id = ANY($1::text[])`,\n [userIds],\n );\n\n const out = new Map<string, DismissalState>();\n for (const row of result.rows) {\n out.set(row.user_id, {\n watermark: normalizeWatermark(row),\n dismissedIds: normalizeDismissedIds(row),\n lastSeen: normalizeLastSeen(row),\n deviceCount: 1,\n });\n }\n return out;\n }\n\n async isHealthy(): Promise<boolean> {\n try {\n await this.query(\"SELECT 1\");\n return true;\n } catch {\n return false;\n }\n }\n\n async destroy(): Promise<void> {\n // No-op by default. Caller owns the pool/connection lifecycle.\n }\n\n private async ensureReady(): Promise<void> {\n if (this.initialized) return;\n if (this.autoMigrate) {\n await this.query(\n `CREATE TABLE IF NOT EXISTS ${this.tableName} (\n user_id TEXT PRIMARY KEY,\n watermark TIMESTAMPTZ,\n dismissed_ids TEXT[] DEFAULT '{}',\n last_seen TIMESTAMPTZ DEFAULT NOW(),\n created_at TIMESTAMPTZ DEFAULT NOW(),\n updated_at TIMESTAMPTZ DEFAULT NOW()\n )`,\n );\n await this.query(\n `CREATE INDEX IF NOT EXISTS idx_${this.tableName}_last_seen ON ${this.tableName}(last_seen)`,\n );\n }\n this.initialized = true;\n }\n}\n","import type { DismissalState, ServerStorageAdapter } from \"../types\";\n\nexport interface RedisLikePipeline {\n set(key: string, value: string): RedisLikePipeline;\n del(key: string): RedisLikePipeline;\n sadd(key: string, ...members: string[]): RedisLikePipeline;\n exec(): Promise<unknown>;\n}\n\nexport interface RedisLikeClient {\n get(key: string): Promise<string | null>;\n set(key: string, value: string): Promise<unknown>;\n del(key: string): Promise<unknown>;\n smembers(key: string): Promise<string[]>;\n sadd(key: string, ...members: string[]): Promise<unknown>;\n ping(): Promise<string>;\n multi(): RedisLikePipeline;\n quit?(): Promise<unknown>;\n disconnect?(): void;\n}\n\nexport interface RedisAdapterOptions {\n userId: string;\n client: RedisLikeClient;\n keyPrefix?: string;\n}\n\n/**\n * Redis-backed storage adapter.\n * Uses simple key + set structures to keep operations predictable.\n */\nexport class RedisAdapter implements ServerStorageAdapter {\n readonly userId: string;\n\n private readonly client: RedisLikeClient;\n private readonly keyPrefix: string;\n private watermark: string | null = null;\n private dismissedIds = new Set<string>();\n\n constructor(options: RedisAdapterOptions) {\n if (!options.userId) {\n throw new Error(\"RedisAdapter: userId is required\");\n }\n this.userId = options.userId;\n this.client = options.client;\n this.keyPrefix = options.keyPrefix ?? \"fd:\";\n }\n\n getWatermark(): string | null {\n return this.watermark;\n }\n\n getDismissedIds(): ReadonlySet<string> {\n return this.dismissedIds;\n }\n\n dismiss(id: string): void {\n this.dismissedIds.add(id);\n void this.client.sadd(this.dismissedKey(this.userId), id);\n void this.client.set(this.lastSeenKey(this.userId), new Date().toISOString());\n }\n\n async dismissAll(now: Date): Promise<void> {\n this.watermark = now.toISOString();\n this.dismissedIds.clear();\n await this.client\n .multi()\n .set(this.watermarkKey(this.userId), this.watermark)\n .del(this.dismissedKey(this.userId))\n .set(this.lastSeenKey(this.userId), now.toISOString())\n .exec();\n }\n\n async sync(): Promise<void> {\n const [watermark, dismissedIds] = await Promise.all([\n this.client.get(this.watermarkKey(this.userId)),\n this.client.smembers(this.dismissedKey(this.userId)),\n ]);\n this.watermark = watermark;\n this.dismissedIds = new Set(dismissedIds);\n }\n\n async dismissBatch(ids: string[]): Promise<void> {\n const uniqueIds = Array.from(new Set(ids));\n if (uniqueIds.length === 0) return;\n this.dismissedIds = new Set([...this.dismissedIds, ...uniqueIds]);\n await this.client.sadd(this.dismissedKey(this.userId), ...uniqueIds);\n await this.client.set(this.lastSeenKey(this.userId), new Date().toISOString());\n }\n\n async resetUser(userId: string): Promise<void> {\n await this.client\n .multi()\n .del(this.watermarkKey(userId))\n .del(this.dismissedKey(userId))\n .del(this.lastSeenKey(userId))\n .exec();\n if (userId === this.userId) {\n this.watermark = null;\n this.dismissedIds.clear();\n }\n }\n\n async getBulkState(userIds: string[]): Promise<Map<string, DismissalState>> {\n const map = new Map<string, DismissalState>();\n await Promise.all(\n userIds.map(async (userId) => {\n const [watermark, dismissedIds, lastSeen] = await Promise.all([\n this.client.get(this.watermarkKey(userId)),\n this.client.smembers(this.dismissedKey(userId)),\n this.client.get(this.lastSeenKey(userId)),\n ]);\n map.set(userId, {\n watermark,\n dismissedIds,\n lastSeen: lastSeen ?? new Date(0).toISOString(),\n deviceCount: 1,\n });\n }),\n );\n return map;\n }\n\n async isHealthy(): Promise<boolean> {\n try {\n const response = await this.client.ping();\n return response.toUpperCase() === \"PONG\";\n } catch {\n return false;\n }\n }\n\n async destroy(): Promise<void> {\n if (this.client.quit) {\n await this.client.quit();\n return;\n }\n this.client.disconnect?.();\n }\n\n private watermarkKey(userId: string): string {\n return `${this.keyPrefix}${userId}:watermark`;\n }\n\n private dismissedKey(userId: string): string {\n return `${this.keyPrefix}${userId}:dismissed`;\n }\n\n private lastSeenKey(userId: string): string {\n return `${this.keyPrefix}${userId}:last_seen`;\n }\n}\n","import type { DismissalState, ServerStorageAdapter, StorageAdapter } from \"../types\";\n\nexport interface HybridAdapterOptions {\n local: StorageAdapter;\n remote: ServerStorageAdapter;\n /** If true, sync from remote before writes. Default false */\n syncBeforeWrite?: boolean;\n /** Batch window for queued dismiss writes. Default: 500ms */\n dismissBatchWindowMs?: number;\n /** Optional periodic sync interval in ms. Default: disabled (0) */\n syncIntervalMs?: number;\n /** Sync on browser visibility return. Default: true */\n syncOnVisibilityChange?: boolean;\n /** Sync on browser online event. Default: true */\n syncOnOnline?: boolean;\n}\n\n/**\n * Hybrid adapter that combines local immediacy with remote persistence.\n */\nexport class HybridAdapter implements ServerStorageAdapter {\n readonly userId: string;\n\n private readonly local: StorageAdapter;\n private readonly remote: ServerStorageAdapter;\n private readonly syncBeforeWrite: boolean;\n private readonly dismissBatchWindowMs: number;\n private readonly syncIntervalMs: number;\n private readonly syncOnVisibilityChange: boolean;\n private readonly syncOnOnline: boolean;\n private pendingDismissIds = new Set<string>();\n private dismissTimer: ReturnType<typeof setTimeout> | null = null;\n private syncTimer: ReturnType<typeof setInterval> | null = null;\n private flushInFlight: Promise<void> | null = null;\n private syncInFlight: Promise<void> | null = null;\n private readonly boundVisibilityHandler: (() => void) | null;\n private readonly boundOnlineHandler: (() => void) | null;\n\n constructor(options: HybridAdapterOptions) {\n this.local = options.local;\n this.remote = options.remote;\n this.userId = options.remote.userId;\n this.syncBeforeWrite = options.syncBeforeWrite ?? false;\n this.dismissBatchWindowMs = options.dismissBatchWindowMs ?? 500;\n this.syncIntervalMs = options.syncIntervalMs ?? 0;\n this.syncOnVisibilityChange = options.syncOnVisibilityChange ?? true;\n this.syncOnOnline = options.syncOnOnline ?? true;\n\n if (typeof window !== \"undefined\" && this.syncOnOnline) {\n this.boundOnlineHandler = () => {\n void this.sync();\n };\n window.addEventListener(\"online\", this.boundOnlineHandler);\n } else {\n this.boundOnlineHandler = null;\n }\n\n if (typeof document !== \"undefined\" && this.syncOnVisibilityChange) {\n this.boundVisibilityHandler = () => {\n if (document.visibilityState === \"visible\") {\n void this.sync();\n }\n };\n document.addEventListener(\"visibilitychange\", this.boundVisibilityHandler);\n } else {\n this.boundVisibilityHandler = null;\n }\n\n if (this.syncIntervalMs > 0) {\n this.syncTimer = setInterval(() => {\n void this.sync();\n }, this.syncIntervalMs);\n }\n }\n\n getWatermark(): string | null {\n return this.local.getWatermark() ?? this.remote.getWatermark();\n }\n\n getDismissedIds(): ReadonlySet<string> {\n const merged = new Set<string>();\n for (const id of this.local.getDismissedIds()) merged.add(id);\n for (const id of this.remote.getDismissedIds()) merged.add(id);\n return merged;\n }\n\n dismiss(id: string): void {\n this.local.dismiss(id);\n this.pendingDismissIds.add(id);\n this.scheduleDismissFlush();\n }\n\n async dismissAll(now: Date): Promise<void> {\n await this.flushPendingDismisses();\n this.pendingDismissIds.clear();\n await Promise.all([\n this.local.dismissAll(now),\n this.remote.dismissAll(now),\n ]);\n }\n\n async sync(): Promise<void> {\n if (this.syncInFlight) return this.syncInFlight;\n const syncTask = (async () => {\n await this.remote.sync();\n // Drain any queued dismisses after connectivity/state reconciliation.\n await this.flushPendingDismissesInternal(true);\n })();\n const inFlight = syncTask.finally(() => {\n if (this.syncInFlight === inFlight) this.syncInFlight = null;\n });\n this.syncInFlight = inFlight;\n return inFlight;\n }\n\n async dismissBatch(ids: string[]): Promise<void> {\n if (this.syncBeforeWrite) {\n await this.remote.sync();\n }\n for (const id of ids) {\n this.local.dismiss(id);\n }\n await this.remote.dismissBatch(ids);\n }\n\n async resetUser(userId: string): Promise<void> {\n await this.remote.resetUser(userId);\n if (userId === this.userId) {\n await this.local.dismissAll(new Date(0));\n }\n }\n\n async getBulkState(userIds: string[]): Promise<Map<string, DismissalState>> {\n return this.remote.getBulkState(userIds);\n }\n\n async isHealthy(): Promise<boolean> {\n return this.remote.isHealthy();\n }\n\n async destroy(): Promise<void> {\n if (this.dismissTimer) {\n clearTimeout(this.dismissTimer);\n this.dismissTimer = null;\n }\n if (this.syncTimer) {\n clearInterval(this.syncTimer);\n this.syncTimer = null;\n }\n if (this.boundOnlineHandler && typeof window !== \"undefined\") {\n window.removeEventListener(\"online\", this.boundOnlineHandler);\n }\n if (this.boundVisibilityHandler && typeof document !== \"undefined\") {\n document.removeEventListener(\"visibilitychange\", this.boundVisibilityHandler);\n }\n await this.flushPendingDismisses();\n await this.remote.destroy();\n }\n\n /** Manually flush queued dismiss operations to the remote adapter. */\n async flushPendingDismisses(): Promise<void> {\n if (this.flushInFlight) return this.flushInFlight;\n const flushTask = this.flushPendingDismissesInternal(false);\n const inFlight = flushTask.finally(() => {\n if (this.flushInFlight === inFlight) this.flushInFlight = null;\n });\n this.flushInFlight = inFlight;\n return inFlight;\n }\n\n private async flushPendingDismissesInternal(skipSyncBeforeWrite: boolean): Promise<void> {\n // Keep draining until no queued ids remain. This handles new dismisses added while flushing.\n while (this.pendingDismissIds.size > 0) {\n const ids = Array.from(this.pendingDismissIds);\n this.pendingDismissIds.clear();\n try {\n if (this.syncBeforeWrite && !skipSyncBeforeWrite) {\n await this.remote.sync();\n }\n await this.remote.dismissBatch(ids);\n } catch {\n // Put failed ids back into queue for retry.\n for (const id of ids) this.pendingDismissIds.add(id);\n return;\n }\n }\n }\n\n private scheduleDismissFlush(): void {\n if (this.dismissTimer) return;\n this.dismissTimer = setTimeout(() => {\n this.dismissTimer = null;\n void this.flushPendingDismisses();\n }, this.dismissBatchWindowMs);\n }\n}\n","import type { DismissalState, ServerStorageAdapter } from \"../types\";\n\ninterface MySQLRow {\n user_id?: string;\n watermark?: string | null;\n dismissed_ids?: string[] | string | null;\n dismissedIds?: string[] | string | null;\n last_seen?: string | null;\n lastSeen?: string | null;\n}\n\nexport interface MySQLQueryResult<T = MySQLRow> {\n rows: T[];\n}\n\nexport type MySQLQueryFn = <T = MySQLRow>(\n sql: string,\n params?: unknown[],\n) => Promise<MySQLQueryResult<T>>;\n\nexport interface MySQLAdapterOptions {\n userId: string;\n query: MySQLQueryFn;\n tableName?: string;\n autoMigrate?: boolean;\n}\n\nfunction parseDismissedIds(value: unknown): string[] {\n if (Array.isArray(value)) {\n return value.filter((item): item is string => typeof item === \"string\");\n }\n if (typeof value === \"string\" && value.trim()) {\n try {\n const parsed = JSON.parse(value) as unknown;\n if (Array.isArray(parsed)) {\n return parsed.filter((item): item is string => typeof item === \"string\");\n }\n } catch {\n return [];\n }\n }\n return [];\n}\n\nfunction normalizeDismissedIds(row: MySQLRow | undefined): string[] {\n if (!row) return [];\n return parseDismissedIds(row.dismissed_ids ?? row.dismissedIds);\n}\n\nfunction normalizeWatermark(row: MySQLRow | undefined): string | null {\n if (!row) return null;\n return row.watermark ?? null;\n}\n\nfunction normalizeLastSeen(row: MySQLRow | undefined): string {\n if (!row) return new Date(0).toISOString();\n return row.last_seen ?? row.lastSeen ?? new Date(0).toISOString();\n}\n\nexport class MySQLAdapter implements ServerStorageAdapter {\n readonly userId: string;\n\n private readonly query: MySQLQueryFn;\n private readonly tableName: string;\n private readonly autoMigrate: boolean;\n private watermark: string | null = null;\n private dismissedIds = new Set<string>();\n private initialized = false;\n\n constructor(options: MySQLAdapterOptions) {\n if (!options.userId) {\n throw new Error(\"MySQLAdapter: userId is required\");\n }\n this.userId = options.userId;\n this.query = options.query;\n this.tableName = options.tableName ?? \"featuredrop_state\";\n this.autoMigrate = options.autoMigrate ?? true;\n }\n\n getWatermark(): string | null {\n return this.watermark;\n }\n\n getDismissedIds(): ReadonlySet<string> {\n return this.dismissedIds;\n }\n\n dismiss(id: string): void {\n this.dismissedIds.add(id);\n void this.dismissBatch([id]);\n }\n\n async dismissAll(now: Date): Promise<void> {\n this.watermark = now.toISOString();\n this.dismissedIds.clear();\n await this.ensureReady();\n await this.query(\n `INSERT INTO ${this.tableName} (user_id, watermark, dismissed_ids, last_seen, created_at, updated_at)\n VALUES (?, ?, ?, NOW(3), NOW(3), NOW(3))\n ON DUPLICATE KEY UPDATE watermark = VALUES(watermark), dismissed_ids = VALUES(dismissed_ids), last_seen = NOW(3), updated_at = NOW(3)`,\n [this.userId, this.watermark, JSON.stringify([])],\n );\n }\n\n async sync(): Promise<void> {\n await this.ensureReady();\n const result = await this.query<MySQLRow>(\n `SELECT watermark, dismissed_ids, last_seen FROM ${this.tableName} WHERE user_id = ? LIMIT 1`,\n [this.userId],\n );\n const row = result.rows[0];\n this.watermark = normalizeWatermark(row);\n this.dismissedIds = new Set(normalizeDismissedIds(row));\n }\n\n async dismissBatch(ids: string[]): Promise<void> {\n const uniqueIds = Array.from(new Set(ids));\n if (uniqueIds.length === 0) return;\n await this.ensureReady();\n\n const merged = new Set<string>([\n ...Array.from(this.dismissedIds),\n ...uniqueIds,\n ]);\n const mergedArray = Array.from(merged);\n this.dismissedIds = merged;\n\n await this.query(\n `INSERT INTO ${this.tableName} (user_id, watermark, dismissed_ids, last_seen, created_at, updated_at)\n VALUES (?, ?, ?, NOW(3), NOW(3), NOW(3))\n ON DUPLICATE KEY UPDATE dismissed_ids = VALUES(dismissed_ids), last_seen = NOW(3), updated_at = NOW(3)`,\n [this.userId, this.watermark, JSON.stringify(mergedArray)],\n );\n }\n\n async resetUser(userId: string): Promise<void> {\n await this.ensureReady();\n await this.query(`DELETE FROM ${this.tableName} WHERE user_id = ?`, [userId]);\n if (userId === this.userId) {\n this.watermark = null;\n this.dismissedIds.clear();\n }\n }\n\n async getBulkState(userIds: string[]): Promise<Map<string, DismissalState>> {\n await this.ensureReady();\n if (userIds.length === 0) return new Map();\n const placeholders = userIds.map(() => \"?\").join(\", \");\n const result = await this.query<MySQLRow & { user_id: string }>(\n `SELECT user_id, watermark, dismissed_ids, last_seen\n FROM ${this.tableName}\n WHERE user_id IN (${placeholders})`,\n userIds,\n );\n const out = new Map<string, DismissalState>();\n for (const row of result.rows) {\n out.set(row.user_id, {\n watermark: normalizeWatermark(row),\n dismissedIds: normalizeDismissedIds(row),\n lastSeen: normalizeLastSeen(row),\n deviceCount: 1,\n });\n }\n return out;\n }\n\n async isHealthy(): Promise<boolean> {\n try {\n await this.query(\"SELECT 1\");\n return true;\n } catch {\n return false;\n }\n }\n\n async destroy(): Promise<void> {\n // No-op by default. Caller owns the client/pool lifecycle.\n }\n\n private async ensureReady(): Promise<void> {\n if (this.initialized) return;\n if (this.autoMigrate) {\n await this.query(\n `CREATE TABLE IF NOT EXISTS ${this.tableName} (\n user_id VARCHAR(255) PRIMARY KEY,\n watermark DATETIME(3) NULL,\n dismissed_ids JSON NOT NULL,\n last_seen DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),\n created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),\n updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)\n )`,\n );\n await this.query(\n `CREATE INDEX idx_${this.tableName}_last_seen ON ${this.tableName}(last_seen)`,\n );\n }\n this.initialized = true;\n }\n}\n","import type { DismissalState, ServerStorageAdapter } from \"../types\";\n\ninterface MongoStateDoc {\n userId: string;\n watermark?: string | null;\n dismissedIds?: string[];\n lastSeen?: string;\n}\n\ninterface MongoFindCursor<T> {\n toArray: () => Promise<T[]>;\n}\n\nexport interface MongoLikeCollection {\n findOne: (filter: Record<string, unknown>) => Promise<MongoStateDoc | null>;\n updateOne: (\n filter: Record<string, unknown>,\n update: Record<string, unknown>,\n options?: Record<string, unknown>,\n ) => Promise<unknown>;\n deleteOne: (filter: Record<string, unknown>) => Promise<unknown>;\n find?: (filter: Record<string, unknown>) => MongoFindCursor<MongoStateDoc>;\n}\n\nexport interface MongoAdapterOptions {\n userId: string;\n collection: MongoLikeCollection;\n}\n\nfunction normalizeDismissedIds(ids: unknown): string[] {\n if (!Array.isArray(ids)) return [];\n return ids.filter((id): id is string => typeof id === \"string\");\n}\n\nfunction normalizeLastSeen(value: unknown): string {\n return typeof value === \"string\" && value ? value : new Date(0).toISOString();\n}\n\nexport class MongoAdapter implements ServerStorageAdapter {\n readonly userId: string;\n\n private readonly collection: MongoLikeCollection;\n private watermark: string | null = null;\n private dismissedIds = new Set<string>();\n\n constructor(options: MongoAdapterOptions) {\n if (!options.userId) {\n throw new Error(\"MongoAdapter: userId is required\");\n }\n this.userId = options.userId;\n this.collection = options.collection;\n }\n\n getWatermark(): string | null {\n return this.watermark;\n }\n\n getDismissedIds(): ReadonlySet<string> {\n return this.dismissedIds;\n }\n\n dismiss(id: string): void {\n this.dismissedIds.add(id);\n void this.collection.updateOne(\n { userId: this.userId },\n {\n $addToSet: { dismissedIds: id },\n $set: { lastSeen: new Date().toISOString() },\n },\n { upsert: true },\n );\n }\n\n async dismissAll(now: Date): Promise<void> {\n this.watermark = now.toISOString();\n this.dismissedIds.clear();\n await this.collection.updateOne(\n { userId: this.userId },\n {\n $set: {\n userId: this.userId,\n watermark: this.watermark,\n dismissedIds: [],\n lastSeen: this.watermark,\n },\n },\n { upsert: true },\n );\n }\n\n async sync(): Promise<void> {\n const doc = await this.collection.findOne({ userId: this.userId });\n this.watermark = doc?.watermark ?? null;\n this.dismissedIds = new Set(normalizeDismissedIds(doc?.dismissedIds));\n }\n\n async dismissBatch(ids: string[]): Promise<void> {\n const unique = Array.from(new Set(ids));\n if (unique.length === 0) return;\n this.dismissedIds = new Set([...this.dismissedIds, ...unique]);\n await this.collection.updateOne(\n { userId: this.userId },\n {\n $addToSet: { dismissedIds: { $each: unique } },\n $set: { lastSeen: new Date().toISOString() },\n },\n { upsert: true },\n );\n }\n\n async resetUser(userId: string): Promise<void> {\n await this.collection.deleteOne({ userId });\n if (userId === this.userId) {\n this.watermark = null;\n this.dismissedIds.clear();\n }\n }\n\n async getBulkState(userIds: string[]): Promise<Map<string, DismissalState>> {\n const out = new Map<string, DismissalState>();\n if (userIds.length === 0) return out;\n\n if (this.collection.find) {\n const rows = await this.collection.find({ userId: { $in: userIds } }).toArray();\n for (const row of rows) {\n out.set(row.userId, {\n watermark: row.watermark ?? null,\n dismissedIds: normalizeDismissedIds(row.dismissedIds),\n lastSeen: normalizeLastSeen(row.lastSeen),\n deviceCount: 1,\n });\n }\n return out;\n }\n\n await Promise.all(\n userIds.map(async (userId) => {\n const row = await this.collection.findOne({ userId });\n if (!row) return;\n out.set(userId, {\n watermark: row.watermark ?? null,\n dismissedIds: normalizeDismissedIds(row.dismissedIds),\n lastSeen: normalizeLastSeen(row.lastSeen),\n deviceCount: 1,\n });\n }),\n );\n return out;\n }\n\n async isHealthy(): Promise<boolean> {\n try {\n await this.collection.findOne({});\n return true;\n } catch {\n return false;\n }\n }\n\n async destroy(): Promise<void> {\n // No-op by default. Caller owns the Mongo client lifecycle.\n }\n}\n","import type { DismissalState, ServerStorageAdapter } from \"../types\";\n\ninterface SQLiteRow {\n user_id?: string;\n watermark?: string | null;\n dismissed_ids?: string[] | string | null;\n dismissedIds?: string[] | string | null;\n last_seen?: string | null;\n lastSeen?: string | null;\n}\n\nexport interface SQLiteQueryResult<T = SQLiteRow> {\n rows: T[];\n}\n\nexport type SQLiteQueryFn = <T = SQLiteRow>(\n sql: string,\n params?: unknown[],\n) => Promise<SQLiteQueryResult<T>>;\n\nexport interface SQLiteAdapterOptions {\n userId: string;\n query: SQLiteQueryFn;\n tableName?: string;\n autoMigrate?: boolean;\n}\n\nfunction parseDismissedIds(value: unknown): string[] {\n if (Array.isArray(value)) {\n return value.filter((item): item is string => typeof item === \"string\");\n }\n if (typeof value === \"string\" && value.trim()) {\n try {\n const parsed = JSON.parse(value) as unknown;\n if (Array.isArray(parsed)) {\n return parsed.filter((item): item is string => typeof item === \"string\");\n }\n } catch {\n return [];\n }\n }\n return [];\n}\n\nfunction normalizeDismissedIds(row: SQLiteRow | undefined): string[] {\n if (!row) return [];\n return parseDismissedIds(row.dismissed_ids ?? row.dismissedIds);\n}\n\nfunction normalizeWatermark(row: SQLiteRow | undefined): string | null {\n if (!row) return null;\n return row.watermark ?? null;\n}\n\nfunction normalizeLastSeen(row: SQLiteRow | undefined): string {\n if (!row) return new Date(0).toISOString();\n return row.last_seen ?? row.lastSeen ?? new Date(0).toISOString();\n}\n\nexport class SQLiteAdapter implements ServerStorageAdapter {\n readonly userId: string;\n\n private readonly query: SQLiteQueryFn;\n private readonly tableName: string;\n private readonly autoMigrate: boolean;\n private watermark: string | null = null;\n private dismissedIds = new Set<string>();\n private initialized = false;\n\n constructor(options: SQLiteAdapterOptions) {\n if (!options.userId) {\n throw new Error(\"SQLiteAdapter: userId is required\");\n }\n this.userId = options.userId;\n this.query = options.query;\n this.tableName = options.tableName ?? \"featuredrop_state\";\n this.autoMigrate = options.autoMigrate ?? true;\n }\n\n getWatermark(): string | null {\n return this.watermark;\n }\n\n getDismissedIds(): ReadonlySet<string> {\n return this.dismissedIds;\n }\n\n dismiss(id: string): void {\n this.dismissedIds.add(id);\n void this.dismissBatch([id]);\n }\n\n async dismissAll(now: Date): Promise<void> {\n this.watermark = now.toISOString();\n this.dismissedIds.clear();\n await this.ensureReady();\n await this.query(\n `INSERT INTO ${this.tableName} (user_id, watermark, dismissed_ids, last_seen, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?)\n ON CONFLICT(user_id)\n DO UPDATE SET watermark = excluded.watermark, dismissed_ids = excluded.dismissed_ids, last_seen = excluded.last_seen, updated_at = excluded.updated_at`,\n [this.userId, this.watermark, JSON.stringify([]), this.watermark, this.watermark, this.watermark],\n );\n }\n\n async sync(): Promise<void> {\n await this.ensureReady();\n const result = await this.query<SQLiteRow>(\n `SELECT watermark, dismissed_ids, last_seen FROM ${this.tableName} WHERE user_id = ? LIMIT 1`,\n [this.userId],\n );\n const row = result.rows[0];\n this.watermark = normalizeWatermark(row);\n this.dismissedIds = new Set(normalizeDismissedIds(row));\n }\n\n async dismissBatch(ids: string[]): Promise<void> {\n const uniqueIds = Array.from(new Set(ids));\n if (uniqueIds.length === 0) return;\n await this.ensureReady();\n\n const merged = new Set<string>([\n ...Array.from(this.dismissedIds),\n ...uniqueIds,\n ]);\n const mergedArray = Array.from(merged);\n this.dismissedIds = merged;\n const nowIso = new Date().toISOString();\n\n await this.query(\n `INSERT INTO ${this.tableName} (user_id, watermark, dismissed_ids, last_seen, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?)\n ON CONFLICT(user_id)\n DO UPDATE SET dismissed_ids = excluded.dismissed_ids, last_seen = excluded.last_seen, updated_at = excluded.updated_at`,\n [this.userId, this.watermark, JSON.stringify(mergedArray), nowIso, nowIso, nowIso],\n );\n }\n\n async resetUser(userId: string): Promise<void> {\n await this.ensureReady();\n await this.query(`DELETE FROM ${this.tableName} WHERE user_id = ?`, [userId]);\n if (userId === this.userId) {\n this.watermark = null;\n this.dismissedIds.clear();\n }\n }\n\n async getBulkState(userIds: string[]): Promise<Map<string, DismissalState>> {\n await this.ensureReady();\n if (userIds.length === 0) return new Map();\n const placeholders = userIds.map(() => \"?\").join(\", \");\n const result = await this.query<SQLiteRow & { user_id: string }>(\n `SELECT user_id, watermark, dismissed_ids, last_seen\n FROM ${this.tableName}\n WHERE user_id IN (${placeholders})`,\n userIds,\n );\n const out = new Map<string, DismissalState>();\n for (const row of result.rows) {\n out.set(row.user_id, {\n watermark: normalizeWatermark(row),\n dismissedIds: normalizeDismissedIds(row),\n lastSeen: normalizeLastSeen(row),\n deviceCount: 1,\n });\n }\n return out;\n }\n\n async isHealthy(): Promise<boolean> {\n try {\n await this.query(\"SELECT 1\");\n return true;\n } catch {\n return false;\n }\n }\n\n async destroy(): Promise<void> {\n // No-op by default. Caller owns db lifecycle.\n }\n\n private async ensureReady(): Promise<void> {\n if (this.initialized) return;\n if (this.autoMigrate) {\n await this.query(\n `CREATE TABLE IF NOT EXISTS ${this.tableName} (\n user_id TEXT PRIMARY KEY,\n watermark TEXT,\n dismissed_ids TEXT NOT NULL,\n last_seen TEXT NOT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n )`,\n );\n await this.query(\n `CREATE INDEX IF NOT EXISTS idx_${this.tableName}_last_seen ON ${this.tableName}(last_seen)`,\n );\n }\n this.initialized = true;\n }\n}\n","import type { DismissalState, ServerStorageAdapter } from \"../types\";\n\ninterface SupabaseErrorLike {\n message?: string;\n}\n\ninterface SupabaseMaybeSingleResult<T> {\n data: T | null;\n error: SupabaseErrorLike | null;\n}\n\ninterface SupabaseMutationResult {\n error: SupabaseErrorLike | null;\n}\n\ninterface SupabaseSelectQuery<T> {\n eq: (column: string, value: unknown) => SupabaseSelectQuery<T>;\n maybeSingle: () => Promise<SupabaseMaybeSingleResult<T>>;\n}\n\ninterface SupabaseMutationQuery {\n eq: (column: string, value: unknown) => Promise<SupabaseMutationResult>;\n}\n\ninterface SupabaseTableClient<T> {\n select: (columns: string) => SupabaseSelectQuery<T>;\n upsert: (value: Record<string, unknown>) => Promise<SupabaseMutationResult>;\n update: (value: Record<string, unknown>) => SupabaseMutationQuery;\n delete: () => SupabaseMutationQuery;\n}\n\nexport interface SupabaseRealtimeChannelLike {\n on: (\n event: \"postgres_changes\",\n filter: Record<string, unknown>,\n callback: () => void,\n ) => SupabaseRealtimeChannelLike;\n subscribe: (callback?: (status: string) => void) => SupabaseRealtimeChannelLike;\n}\n\nexport interface SupabaseClientLike {\n from: <T = SupabaseStateRow>(table: string) => SupabaseTableClient<T>;\n channel?: (name: string) => SupabaseRealtimeChannelLike;\n removeChannel?: (channel: SupabaseRealtimeChannelLike) => void | Promise<void>;\n}\n\ninterface SupabaseStateRow {\n [key: string]: unknown;\n user_id: string;\n watermark?: string | null;\n dismissed_ids?: string[] | null;\n last_seen?: string | null;\n}\n\nexport interface SupabaseAdapterOptions {\n userId: string;\n client: SupabaseClientLike;\n tableName?: string;\n realtime?: boolean;\n}\n\nfunction normalizeDismissedIds(row: SupabaseStateRow | null): string[] {\n if (!row || !Array.isArray(row.dismissed_ids)) return [];\n return row.dismissed_ids.filter((id): id is string => typeof id === \"string\");\n}\n\nfunction normalizeWatermark(row: SupabaseStateRow | null): string | null {\n if (!row) return null;\n return row.watermark ?? null;\n}\n\nfunction normalizeLastSeen(row: SupabaseStateRow | null): string {\n if (!row) return new Date(0).toISOString();\n return row.last_seen ?? new Date(0).toISOString();\n}\n\nfunction throwOnError(error: SupabaseErrorLike | null): void {\n if (!error) return;\n throw new Error(`SupabaseAdapter: ${error.message ?? \"unknown error\"}`);\n}\n\nexport class SupabaseAdapter implements ServerStorageAdapter {\n readonly userId: string;\n\n private readonly client: SupabaseClientLike;\n private readonly tableName: string;\n private readonly realtime: boolean;\n private watermark: string | null = null;\n private dismissedIds = new Set<string>();\n private realtimeChannel: SupabaseRealtimeChannelLike | null = null;\n private syncing = false;\n\n constructor(options: SupabaseAdapterOptions) {\n if (!options.userId) {\n throw new Error(\"SupabaseAdapter: userId is required\");\n }\n this.userId = options.userId;\n this.client = options.client;\n this.tableName = options.tableName ?? \"featuredrop_state\";\n this.realtime = options.realtime ?? false;\n\n if (this.realtime && this.client.channel) {\n this.setupRealtime();\n }\n }\n\n getWatermark(): string | null {\n return this.watermark;\n }\n\n getDismissedIds(): ReadonlySet<string> {\n return this.dismissedIds;\n }\n\n dismiss(id: string): void {\n this.dismissedIds.add(id);\n void this.dismissBatch([id]);\n }\n\n async dismissAll(now: Date): Promise<void> {\n this.watermark = now.toISOString();\n this.dismissedIds.clear();\n await this.upsertState({\n watermark: this.watermark,\n dismissed_ids: [],\n last_seen: this.watermark,\n });\n }\n\n async sync(): Promise<void> {\n if (this.syncing) return;\n this.syncing = true;\n try {\n const row = await this.fetchState(this.userId);\n this.watermark = normalizeWatermark(row);\n this.dismissedIds = new Set(normalizeDismissedIds(row));\n } finally {\n this.syncing = false;\n }\n }\n\n async dismissBatch(ids: string[]): Promise<void> {\n const uniqueIds = Array.from(new Set(ids));\n if (uniqueIds.length === 0) return;\n\n const merged = new Set<string>([\n ...Array.from(this.dismissedIds),\n ...uniqueIds,\n ]);\n this.dismissedIds = merged;\n\n await this.upsertState({\n watermark: this.watermark,\n dismissed_ids: Array.from(merged),\n last_seen: new Date().toISOString(),\n });\n }\n\n async resetUser(userId: string): Promise<void> {\n const result = await this.client\n .from(this.tableName)\n .delete()\n .eq(\"user_id\", userId);\n throwOnError(result.error);\n if (userId === this.userId) {\n this.watermark = null;\n this.dismissedIds.clear();\n }\n }\n\n async getBulkState(userIds: string[]): Promise<Map<string, DismissalState>> {\n const out = new Map<string, DismissalState>();\n if (userIds.length === 0) return out;\n\n await Promise.all(\n userIds.map(async (userId) => {\n const row = await this.fetchState(userId);\n if (!row) return;\n out.set(userId, {\n watermark: normalizeWatermark(row),\n dismissedIds: normalizeDismissedIds(row),\n lastSeen: normalizeLastSeen(row),\n deviceCount: 1,\n });\n }),\n );\n return out;\n }\n\n async isHealthy(): Promise<boolean> {\n try {\n await this.client\n .from(this.tableName)\n .select(\"user_id\")\n .eq(\"user_id\", this.userId)\n .maybeSingle();\n return true;\n } catch {\n return false;\n }\n }\n\n async destroy(): Promise<void> {\n if (this.realtimeChannel && this.client.removeChannel) {\n await this.client.removeChannel(this.realtimeChannel);\n }\n this.realtimeChannel = null;\n }\n\n private async fetchState(userId: string): Promise<SupabaseStateRow | null> {\n const result = await this.client\n .from<SupabaseStateRow>(this.tableName)\n .select(\"user_id, watermark, dismissed_ids, last_seen\")\n .eq(\"user_id\", userId)\n .maybeSingle();\n throwOnError(result.error);\n return result.data;\n }\n\n private async upsertState(state: {\n watermark: string | null;\n dismissed_ids: string[];\n last_seen: string;\n }): Promise<void> {\n const payload: SupabaseStateRow = {\n user_id: this.userId,\n watermark: state.watermark,\n dismissed_ids: state.dismissed_ids,\n last_seen: state.last_seen,\n };\n const result = await this.client.from(this.tableName).upsert(payload as Record<string, unknown>);\n throwOnError(result.error);\n }\n\n private setupRealtime(): void {\n const channelFactory = this.client.channel;\n if (!channelFactory) return;\n this.realtimeChannel = channelFactory(`featuredrop:${this.tableName}:${this.userId}`)\n .on(\n \"postgres_changes\",\n {\n event: \"*\",\n schema: \"public\",\n table: this.tableName,\n filter: `user_id=eq.${this.userId}`,\n },\n () => {\n void this.sync();\n },\n )\n .subscribe();\n }\n}\n"]}
|