@marktiderman/genesis-chat 0.2.0 → 0.2.1

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 (77) hide show
  1. package/README.md +82 -7
  2. package/dist/{chunk-5D5A7I4Q.js → chunk-A4YJX7KT.js} +130 -16
  3. package/dist/chunk-A4YJX7KT.js.map +1 -0
  4. package/dist/chunk-AZS3HNLM.js +30 -0
  5. package/dist/chunk-AZS3HNLM.js.map +1 -0
  6. package/dist/{chunk-7S6HYNWW.js → chunk-GBJ3YI4E.js} +72 -5
  7. package/dist/chunk-GBJ3YI4E.js.map +1 -0
  8. package/dist/{chunk-PZTOY2LY.js → chunk-JU2FAPBI.js} +46 -13
  9. package/dist/chunk-JU2FAPBI.js.map +1 -0
  10. package/dist/{client-DMa2j7kz.d.ts → client-DUIG1hum.d.ts} +36 -1
  11. package/dist/index.d.ts +4 -4
  12. package/dist/index.js +2 -2
  13. package/dist/native.d.ts +36 -7
  14. package/dist/native.js +239 -116
  15. package/dist/native.js.map +1 -1
  16. package/dist/{outbox-B0y3phE0.d.ts → outbox-B9NAWQ58.d.ts} +74 -6
  17. package/dist/push.d.ts +2 -2
  18. package/dist/react.d.ts +48 -21
  19. package/dist/react.js +3 -3
  20. package/dist/server.d.ts +43 -2
  21. package/dist/server.js +115 -15
  22. package/dist/server.js.map +1 -1
  23. package/dist/{thread-DWXHKPdw.d.ts → thread-oPra7pkW.d.ts} +1 -1
  24. package/dist/web.d.ts +31 -11
  25. package/dist/web.js +97 -48
  26. package/dist/web.js.map +1 -1
  27. package/migrations/0003_genesis_chat_search_threads.sql +85 -0
  28. package/migrations/tests/0002_genesis_chat_coaching.test.sql +7 -3
  29. package/migrations/tests/0003_genesis_chat_search_threads.test.sql +50 -0
  30. package/package.json +7 -3
  31. package/src/__tests__/coaching-core.test.ts +3 -1
  32. package/src/__tests__/coaching-react.test.tsx +73 -2
  33. package/src/__tests__/coaching-web.test.tsx +78 -6
  34. package/src/__tests__/fake-xhr.ts +54 -0
  35. package/src/__tests__/outbox-hosted.test.ts +269 -0
  36. package/src/__tests__/review-279.test.ts +41 -0
  37. package/src/__tests__/review-fixes-web.test.tsx +13 -10
  38. package/src/__tests__/server-fake-video.test.ts +81 -0
  39. package/src/__tests__/server-fakes.ts +7 -1
  40. package/src/__tests__/server-safety.test.ts +17 -4
  41. package/src/__tests__/web.test.tsx +16 -0
  42. package/src/core/client.ts +28 -2
  43. package/src/core/outbox.ts +222 -16
  44. package/src/core/transfer.ts +71 -0
  45. package/src/core/types.ts +17 -0
  46. package/src/index.ts +1 -0
  47. package/src/native/__tests__/emoji.test.tsx +16 -0
  48. package/src/native/__tests__/organise-screens.test.tsx +80 -0
  49. package/src/native/__tests__/video-media.test.tsx +81 -4
  50. package/src/native/attachment-cards.tsx +22 -6
  51. package/src/native/inbox-screen.tsx +12 -6
  52. package/src/native/index.ts +2 -2
  53. package/src/native/message-actions-sheet.tsx +10 -5
  54. package/src/native/message-bubble.tsx +3 -11
  55. package/src/native/modules.ts +2 -0
  56. package/src/native/schedule-sheet.tsx +23 -9
  57. package/src/native/search-screen.tsx +26 -5
  58. package/src/native/thread-screen.tsx +30 -3
  59. package/src/native/topics.tsx +70 -15
  60. package/src/native/video-player.tsx +46 -6
  61. package/src/native/video-recorder.tsx +6 -3
  62. package/src/native/voice-player.tsx +18 -0
  63. package/src/react/index.tsx +103 -19
  64. package/src/react/previews.ts +51 -0
  65. package/src/server/fake-video.ts +171 -0
  66. package/src/server/index.ts +1 -0
  67. package/src/web/attachments.tsx +6 -6
  68. package/src/web/bubble.tsx +22 -0
  69. package/src/web/inbox.tsx +7 -6
  70. package/src/web/memory-client.ts +11 -3
  71. package/src/web/panel.tsx +2 -2
  72. package/src/web/schedule.tsx +14 -2
  73. package/src/web/thread.tsx +36 -8
  74. package/src/web/video.tsx +28 -34
  75. package/dist/chunk-5D5A7I4Q.js.map +0 -1
  76. package/dist/chunk-7S6HYNWW.js.map +0 -1
  77. package/dist/chunk-PZTOY2LY.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/thread.ts","../src/core/outbox.ts"],"names":[],"mappings":"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","file":"chunk-5D5A7I4Q.js","sourcesContent":["/**\n * @feat:chat\n * Pure thread logic, the same on every platform: merging the server's messages\n * with ones still on their way, grouping a run of messages from one sender,\n * day dividers, the unread line, reactions by emoji, and the typing line.\n */\nimport type { ChatActivity, ChatMessage, PendingMessage } from \"./types\";\n\nexport type ThreadItem =\n | { type: \"message\"; message: ChatMessage; pending?: undefined }\n | { type: \"pending\"; pending: PendingMessage; message?: undefined };\n\n/**\n * The server's messages (by seq), then what is still sending, oldest first. A\n * pending message the server already has (same clientId) is dropped, so a send\n * that landed never shows twice.\n */\nexport function mergeThread(server: ChatMessage[], pending: PendingMessage[]): ThreadItem[] {\n const byId = new Map<string, ChatMessage>();\n for (const m of server) byId.set(m.id, m);\n const sorted = [...byId.values()].sort((a, b) => a.seq - b.seq);\n const landed = new Set(sorted.map((m) => m.clientId));\n const waiting = pending\n .filter((p) => !landed.has(p.clientId))\n .sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n return [\n ...sorted.map((message) => ({ type: \"message\" as const, message })),\n ...waiting.map((p) => ({ type: \"pending\" as const, pending: p })),\n ];\n}\n\n/** Adds or replaces messages in a page, keeping it sorted and free of duplicates. */\nexport function upsertMessages(existing: ChatMessage[], incoming: ChatMessage[]): ChatMessage[] {\n const byId = new Map(existing.map((m) => [m.id, m]));\n for (const m of incoming) byId.set(m.id, m);\n return [...byId.values()].sort((a, b) => a.seq - b.seq);\n}\n\nexport function itemSender(item: ThreadItem): string | null {\n return item.type === \"message\" ? item.message.senderId : item.pending.senderId;\n}\n\nexport function itemTime(item: ThreadItem): string {\n return item.type === \"message\" ? item.message.createdAt : item.pending.createdAt;\n}\n\n/** Runs of one sender within five minutes share a header (name, avatar). */\nexport function startsGroup(items: ThreadItem[], index: number, gapMs = 5 * 60_000): boolean {\n if (index === 0) return true;\n const prev = items[index - 1]!;\n const cur = items[index]!;\n if (cur.type === \"message\" && cur.message.kind === \"system\") return true;\n if (prev.type === \"message\" && prev.message.kind === \"system\") return true;\n if (itemSender(prev) !== itemSender(cur)) return true;\n return Date.parse(itemTime(cur)) - Date.parse(itemTime(prev)) > gapMs || !sameDay(itemTime(prev), itemTime(cur));\n}\n\nexport function sameDay(a: string, b: string): boolean {\n const x = new Date(a);\n const y = new Date(b);\n return x.getFullYear() === y.getFullYear() && x.getMonth() === y.getMonth() && x.getDate() === y.getDate();\n}\n\n/** A day divider goes before this item. */\nexport function startsDay(items: ThreadItem[], index: number): boolean {\n return index === 0 || !sameDay(itemTime(items[index - 1]!), itemTime(items[index]!));\n}\n\n/** \"Today\", \"Yesterday\", \"Monday\", or \"12 Mar 2026\". */\nexport function dayLabel(iso: string, now = new Date(), locale?: string): string {\n const d = new Date(iso);\n const startOf = (x: Date) => new Date(x.getFullYear(), x.getMonth(), x.getDate()).getTime();\n const days = Math.round((startOf(now) - startOf(d)) / 86_400_000);\n if (days === 0) return \"Today\";\n if (days === 1) return \"Yesterday\";\n if (days > 1 && days < 7) return d.toLocaleDateString(locale, { weekday: \"long\" });\n return d.toLocaleDateString(locale, { day: \"numeric\", month: \"short\", year: d.getFullYear() === now.getFullYear() ? undefined : \"numeric\" });\n}\n\n/** The first message after what you had read, from someone else: where \"New\" goes. */\nexport function firstUnreadId(messages: ChatMessage[], lastReadSeq: number, me: string): string | null {\n return messages.find((m) => m.seq > lastReadSeq && m.senderId !== me && !m.deletedAt)?.id ?? null;\n}\n\nexport interface ReactionSummary {\n emoji: string;\n count: number;\n mine: boolean;\n userIds: string[];\n}\n\n/** Reactions by emoji, most first, then in first-used order. */\nexport function summarizeReactions(message: ChatMessage, me: string): ReactionSummary[] {\n const order: string[] = [];\n const by = new Map<string, string[]>();\n for (const r of message.reactions) {\n if (!by.has(r.emoji)) {\n by.set(r.emoji, []);\n order.push(r.emoji);\n }\n by.get(r.emoji)!.push(r.userId);\n }\n return order\n .map((emoji) => ({ emoji, count: by.get(emoji)!.length, mine: by.get(emoji)!.includes(me), userIds: by.get(emoji)! }))\n .sort((a, b) => b.count - a.count || order.indexOf(a.emoji) - order.indexOf(b.emoji));\n}\n\n/** Who is doing what now: activity older than six seconds has stopped. */\nexport function currentActivity(activity: ChatActivity[], now = Date.now(), staleMs = 6000): ChatActivity[] {\n const latest = new Map<string, ChatActivity>();\n for (const a of activity) {\n if (now - a.at > staleMs) continue;\n const prev = latest.get(a.userId);\n if (!prev || prev.at < a.at) latest.set(a.userId, a);\n }\n return [...latest.values()];\n}\n\n/** \"Sam is typing…\", \"Sam and Lee are typing…\", \"Sam is recording a voice message…\". */\nexport function activityLine(activity: ChatActivity[], nameOf: (userId: string) => string): string | null {\n if (activity.length === 0) return null;\n const recording = activity.find((a) => a.activity !== \"typing\");\n if (recording) {\n return `${nameOf(recording.userId)} is recording ${recording.activity === \"recording-video\" ? \"a video\" : \"a voice message\"}…`;\n }\n const names = activity.map((a) => nameOf(a.userId));\n if (names.length === 1) return `${names[0]} is typing…`;\n if (names.length === 2) return `${names[0]} and ${names[1]} are typing…`;\n return \"Several people are typing…\";\n}\n\n/** Sends activity at most once every `everyMs`. */\nexport function throttle(fn: () => void, everyMs = 3000): () => void {\n let last = 0;\n return () => {\n const now = Date.now();\n if (now - last >= everyMs) {\n last = now;\n fn();\n }\n };\n}\n\n/** The ids @mentioned in markdown written as `@[Name](user:<uuid>)`. */\nexport function parseMentions(body: string): string[] {\n const ids = new Set<string>();\n for (const m of body.matchAll(/@\\[[^\\]]{1,80}\\]\\(user:([0-9a-f-]{36})\\)/gi)) ids.add(m[1]!.toLowerCase());\n return [...ids];\n}\n\n/** A one-line preview: text, or what was attached. */\nexport function previewText(body: string, attachment: string | null | undefined, deleted = false): string {\n if (deleted) return \"Message deleted\";\n const text = body.replace(/@\\[([^\\]]+)\\]\\(user:[0-9a-f-]{36}\\)/gi, \"@$1\").replace(/[*_`#>~]/g, \"\").trim();\n if (text) return text.length > 140 ? `${text.slice(0, 139)}…` : text;\n switch (attachment) {\n case \"image\":\n return \"Photo\";\n case \"voice\":\n return \"Voice message\";\n case \"video\":\n return \"Video\";\n case \"file\":\n return \"File\";\n case null:\n case undefined:\n return \"\";\n default:\n return \"Attachment\";\n }\n}\n","/**\n * @feat:chat\n * The send queue: a message shows at once as pending, its files upload, then it\n * is sent with the clientId made when it was written, so a retry (after a lost\n * connection, a closed app) never posts twice. Messages to one conversation go\n * in the order they were written: the first that can't go (a lost file, a refusal)\n * holds back the ones after it. A refusal (not allowed, bad data) is `permanent`\n * and only sent again by hand. `clear()` (sign-out) stops sends in flight: none\n * posts, or saves anything, afterwards. Storage is the platform's (memory by default;\n * localStorage on web, MMKV or SQLite on native), behind OutboxStore.\n */\nimport type { ChatClient } from \"./client\";\nimport { ChatError } from \"./client\";\nimport { attachmentKindFor, randomId } from \"./media\";\nimport type { AttachmentInput, ChatMessage, PendingFile, PendingMessage, SendInput } from \"./types\";\n\n/** A file still on the device, uploaded when its message is sent. */\nexport interface LocalFile {\n /** The bytes, or (native) a file URI the platform reads in `readFile`. */\n data: Blob | ArrayBuffer | string;\n name: string;\n contentType: string;\n /** A preview to show while it uploads (an object URL, a file URI). The outbox owns it from here: see `releasePreview`. */\n previewUrl?: string;\n /** Known up front: a voice note's duration and waveform, a photo's size. */\n meta?: Partial<Omit<AttachmentInput, \"path\" | \"kind\">> & { kind?: AttachmentInput[\"kind\"] };\n}\n\nexport interface QueuedMessage extends Omit<PendingMessage, \"files\"> {\n files: LocalFile[];\n /** What each file is, kept with the saved copy (PendingMessage.files). */\n pendingFiles?: PendingFile[];\n /** Files lost on a relaunch (bytes that weren't persisted). */\n lostFiles?: number;\n attempts: number;\n}\n\nfunction describe(f: LocalFile): PendingFile {\n return { name: f.name, contentType: f.contentType, kind: f.meta?.kind ?? attachmentKindFor(f.contentType), meta: f.meta };\n}\n\nexport interface OutboxStore {\n load(): Promise<QueuedMessage[]>;\n save(queue: QueuedMessage[]): Promise<void>;\n}\n\nexport const memoryOutboxStore = (): OutboxStore => {\n let saved: QueuedMessage[] = [];\n return { load: async () => saved, save: async (q) => void (saved = q) };\n};\n\nexport interface OutboxOptions {\n client: ChatClient;\n userId: string;\n store?: OutboxStore;\n /** Reads a native file URI into bytes for upload. */\n readFile?: (uri: string) => Promise<Blob | ArrayBuffer>;\n /** Upload hook, e.g. resumable uploads on native. Defaults to client.upload. `signal` aborts when the message is discarded or the outbox cleared. */\n upload?: (conversationId: string, file: LocalFile, opts?: { signal?: AbortSignal }) => Promise<string>;\n /** Called with every change, for the UI. */\n onChange?: (queue: QueuedMessage[]) => void;\n /** Called when a message lands. */\n onSent?: (message: ChatMessage, clientId: string) => void;\n /** Makes client ids. Default: a random UUID (works where crypto.randomUUID is missing). */\n newId?: () => string;\n /**\n * Keeps a file held as bytes (a pasted image, a recording) between launches: write it\n * somewhere and return a URI `readFile` can read (native: the app's cache directory).\n * Without it, such a file isn't saved, and after a relaunch its message asks for it again.\n */\n persistFile?: (file: LocalFile) => Promise<string>;\n /**\n * Lets go of a file's `previewUrl` once its message has landed, been discarded or cleared.\n * Default: revokes `blob:` object URLs (the web's), and leaves everything else alone.\n */\n releasePreview?: (url: string) => void;\n}\n\n/** Revokes a `blob:` object URL; anything else (a native file URI) is left alone. */\nexport function releaseObjectUrl(url: string) {\n if (!url.startsWith(\"blob:\") || typeof URL === \"undefined\" || typeof URL.revokeObjectURL !== \"function\") return;\n try {\n URL.revokeObjectURL(url);\n } catch {\n // Already gone, or a runtime without object URLs.\n }\n}\n\n\nexport function createOutbox(opts: OutboxOptions) {\n const store = opts.store ?? memoryOutboxStore();\n let queue: QueuedMessage[] = [];\n // Bumped by clear(): work begun under an older generation stops at its next await.\n let generation = 0;\n const running = new Map<string, number>(); // conversationId -> the generation running it\n const aborts = new Map<string, AbortController>(); // clientId -> its uploads' controller\n const uploaded = new Map<string, string>(); // clientId:index -> path\n\n const release = opts.releasePreview ?? releaseObjectUrl;\n const releasePreviews = (q: QueuedMessage) => {\n for (const url of new Set([...Object.values(q.previews ?? {}), ...q.files.map((f) => f.previewUrl)])) {\n if (typeof url === \"string\" && url) release(url);\n }\n };\n\n const newId = opts.newId ?? randomId;\n\n // Saved copies: a file held as bytes is kept only as a URI (persistFile) or marked lost.\n // `files` holds the files still here, in slot order; `pendingFiles` holds every slot.\n const saveable = (q: QueuedMessage): QueuedMessage => {\n const slots = q.pendingFiles?.length ? q.pendingFiles : q.files.map(describe);\n const here = [...q.files];\n const files: LocalFile[] = [];\n const pendingFiles = slots.map((slot) => {\n if (slot.lost) return slot;\n const f = here.shift();\n if (f && typeof f.data === \"string\") {\n files.push(f);\n return { ...slot, lost: false };\n }\n return { ...slot, lost: true };\n });\n return { ...q, files, pendingFiles };\n };\n\n const emit = () => {\n opts.onChange?.([...queue]);\n void store.save(queue.map(saveable));\n };\n\n /** Swaps a byte file for a saved URI, so it survives a relaunch. */\n async function persist(q: QueuedMessage) {\n if (!opts.persistFile) return;\n for (let i = 0; i < q.files.length; i++) {\n const f = q.files[i]!;\n if (typeof f.data === \"string\") continue;\n try {\n q.files[i] = { ...f, data: await opts.persistFile(f) };\n } catch {\n // Kept in memory only; a relaunch asks for it again.\n }\n }\n }\n\n /**\n * One load for the outbox's life, which every method awaits. What was saved is merged into\n * the live queue (a send made while the load was in flight stays), deduped by clientId.\n */\n let loading: Promise<void> | null = null;\n function ensureLoaded(): Promise<void> {\n loading ??= (async () => {\n const gen = generation;\n let saved: QueuedMessage[] = [];\n try {\n saved = (await store.load()) ?? [];\n } catch {\n saved = [];\n }\n // Cleared (signed out) while it loaded: what was saved belonged to that session.\n if (gen !== generation) return;\n // A file held as bytes that wasn't persisted doesn't survive a relaunch: its message waits,\n // failed, for the file to be attached again (never sent without it) or discarded.\n const live = new Set(queue.map((q) => q.clientId));\n const restored: QueuedMessage[] = saved\n .filter((q) => !live.has(q.clientId))\n .map((q) => {\n const lost = (q.pendingFiles ?? []).filter((f) => f.lost).length;\n return {\n ...q,\n status: q.status === \"sending\" || lost > 0 ? \"failed\" : q.status,\n error: lost > 0 ? \"Attach the file again to send\" : (q.error ?? \"Not sent\"),\n files: q.files ?? [],\n attempts: q.attempts ?? 0,\n lostFiles: lost,\n };\n });\n if (restored.length) {\n queue = [...restored, ...queue];\n opts.onChange?.([...queue]);\n }\n })();\n return loading;\n }\n\n async function uploadFile(conversationId: string, file: LocalFile, signal?: AbortSignal): Promise<string> {\n if (opts.upload) return opts.upload(conversationId, file, { signal });\n const data = typeof file.data === \"string\" ? await (opts.readFile ?? notReadable)(file.data) : file.data;\n return opts.client.upload(conversationId, opts.userId, data, { name: file.name, contentType: file.contentType });\n }\n\n async function run(conversationId: string) {\n const gen = generation;\n if (running.get(conversationId) === gen) return;\n running.set(conversationId, gen);\n // Cleared (signed out) or discarded while we waited: stop, sending and saving nothing.\n const stale = (q: QueuedMessage) => gen !== generation || !queue.includes(q);\n try {\n for (;;) {\n if (gen !== generation) return;\n // In the order written: the first message still here decides. One that failed (a lost\n // file, a refusal, no connection) holds back the ones after it until it is retried.\n const next = queue.find((q) => q.input.conversationId === conversationId);\n if (!next || next.status !== \"sending\") break;\n if ((next.lostFiles ?? 0) > 0) {\n next.status = \"failed\";\n next.error = \"Attach the file again to send\";\n emit();\n break;\n }\n const controller = typeof AbortController !== \"undefined\" ? new AbortController() : null;\n if (controller) aborts.set(next.clientId, controller);\n try {\n const attachments: AttachmentInput[] = [...(next.input.attachments ?? [])];\n for (let i = 0; i < next.files.length; i++) {\n const file = next.files[i]!;\n const key = `${next.clientId}:${i}`;\n let path = uploaded.get(key);\n if (!path) {\n path = await uploadFile(conversationId, file, controller?.signal);\n if (stale(next)) return;\n uploaded.set(key, path);\n }\n attachments.push({\n ...file.meta,\n kind: file.meta?.kind ?? attachmentKindFor(file.contentType),\n path,\n name: file.meta?.name ?? file.name,\n mime: file.contentType,\n });\n }\n if (stale(next)) return;\n const message = await opts.client.send({ ...next.input, attachments });\n // Posted, but the person signed out meanwhile: the next session must not hear of it.\n if (gen !== generation) return;\n queue = queue.filter((q) => q.clientId !== next.clientId);\n for (let i = 0; i < next.files.length; i++) uploaded.delete(`${next.clientId}:${i}`);\n emit();\n opts.onSent?.(message, next.clientId);\n // The bubble now draws the stored copy: the local preview can go.\n releasePreviews(next);\n } catch (e) {\n if (stale(next)) return;\n const err = e instanceof ChatError ? e : new ChatError(e instanceof Error ? e.message : String(e), undefined, \"send\");\n next.attempts += 1;\n next.status = \"failed\";\n next.permanent = err.permanent;\n next.error = err.forbidden ? \"You can't post here\" : err.transient ? \"Not sent. Check your connection.\" : err.message;\n emit();\n // Later messages to this conversation wait behind a failed one, so order holds.\n break;\n } finally {\n if (controller && aborts.get(next.clientId) === controller) aborts.delete(next.clientId);\n }\n }\n } finally {\n if (running.get(conversationId) === gen) running.delete(conversationId);\n }\n }\n\n /** Can this failed message go without the person's help (retryAll, coming back online)? */\n const canAutoRetry = (x: QueuedMessage) =>\n !x.permanent && !(x.lostFiles ?? 0) && x.files.every((f) => typeof f.data !== \"string\" || Boolean(opts.readFile || opts.upload));\n\n return {\n /** Queues a message; it shows at once and sends in order. Returns its clientId. */\n async send(input: Omit<SendInput, \"clientId\"> & { clientId?: string }, files: LocalFile[] = []): Promise<string> {\n await ensureLoaded();\n const gen = generation;\n const clientId = input.clientId ?? newId();\n const previews: Record<number, string> = {};\n files.forEach((f, i) => {\n if (f.previewUrl) previews[i] = f.previewUrl;\n });\n const queued: QueuedMessage = {\n clientId,\n input: { ...input, clientId },\n senderId: opts.userId,\n createdAt: new Date().toISOString(),\n status: \"sending\",\n previews,\n files: [...files],\n pendingFiles: files.map(describe),\n attempts: 0,\n };\n queue.push(queued);\n opts.onChange?.([...queue]);\n await persist(queued);\n // Cleared or discarded while its files were saved: it goes nowhere.\n if (gen !== generation || !queue.includes(queued)) return clientId;\n emit();\n void run(input.conversationId);\n return clientId;\n },\n\n async retry(clientId: string) {\n await ensureLoaded();\n const q = queue.find((x) => x.clientId === clientId);\n if (!q) return;\n // Retrying one retries everything failed in that conversation, in order, refusals too\n // (a person asked), up to one still waiting for a file.\n for (const x of queue) {\n if (x.input.conversationId !== q.input.conversationId || x.status !== \"failed\") continue;\n if ((x.lostFiles ?? 0) > 0) break;\n x.status = \"sending\";\n x.permanent = false;\n }\n emit();\n void run(q.input.conversationId);\n },\n\n /**\n * Gives a message the files it lost on a relaunch and sends it. `files` fill the lost\n * slots in order (`PendingMessage.files[i].lost`); the files that were kept stay. Pass\n * one per lost slot; with fewer, the message keeps waiting for the rest.\n */\n async reattach(clientId: string, files: LocalFile[]) {\n await ensureLoaded();\n const q = queue.find((x) => x.clientId === clientId);\n if (!q) return;\n const slots = q.pendingFiles ?? [];\n const kept = [...q.files];\n const given = [...files];\n const merged: LocalFile[] = [];\n const described: PendingFile[] = [];\n for (const slot of slots) {\n if (slot.lost) {\n const f = given.shift();\n if (f) {\n merged.push(f);\n described.push(describe(f));\n } else {\n described.push(slot);\n }\n } else {\n const f = kept.shift();\n if (f) {\n merged.push(f);\n described.push(slot);\n }\n }\n }\n // A message saved before slots were recorded: the given files are all of them.\n if (slots.length === 0) {\n merged.push(...given);\n described.push(...given.map(describe));\n }\n q.files = merged;\n q.pendingFiles = described;\n q.lostFiles = described.filter((d) => d.lost).length;\n if (q.lostFiles > 0) {\n emit();\n return;\n }\n const gen = generation;\n await persist(q);\n if (gen !== generation || !queue.includes(q)) return;\n q.status = \"sending\";\n emit();\n void run(q.input.conversationId);\n },\n\n /**\n * Retries failed messages (after the connection comes back), in order per conversation,\n * stopping at the first that can't go on its own: one waiting for a lost file, or one the\n * server refused (`permanent`, retried only by hand). The ones after it keep waiting.\n */\n async retryAll() {\n await ensureLoaded();\n const conversations = new Set<string>();\n const held = new Set<string>();\n for (const x of queue) {\n const c = x.input.conversationId;\n if (held.has(c) || x.status !== \"failed\") continue;\n if (!canAutoRetry(x)) {\n held.add(c);\n continue;\n }\n x.status = \"sending\";\n conversations.add(c);\n }\n emit();\n for (const c of conversations) void run(c);\n },\n\n /** Forgets every queued message, here and in the store (call it on sign-out). */\n async clear() {\n // At once, before any await: a send in flight stops at its next step and posts nothing.\n generation += 1;\n for (const c of aborts.values()) c.abort();\n aborts.clear();\n running.clear();\n const gone = queue;\n queue = [];\n uploaded.clear();\n gone.forEach(releasePreviews);\n opts.onChange?.([]);\n await ensureLoaded();\n await store.save([]);\n },\n\n async discard(clientId: string) {\n await ensureLoaded();\n const gone = queue.find((q) => q.clientId === clientId);\n queue = queue.filter((q) => q.clientId !== clientId);\n aborts.get(clientId)?.abort();\n aborts.delete(clientId);\n if (gone) releasePreviews(gone);\n emit();\n },\n\n pending(conversationId?: string): PendingMessage[] {\n return queue\n .filter((q) => !conversationId || q.input.conversationId === conversationId)\n .map((q) => ({ ...q, files: q.pendingFiles }));\n },\n\n /** A new client id, made the way this outbox makes them. */\n newId,\n\n load: ensureLoaded,\n };\n}\n\nexport type Outbox = ReturnType<typeof createOutbox>;\n\nasync function notReadable(): Promise<never> {\n // This device's set-up (no readFile), not a refusal: a relaunch that can read it sends it.\n throw new ChatError(\"This file can't be read on this device\", \"GSFILE\", \"upload\");\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/availability.ts","../src/core/media.ts","../src/core/client.ts"],"names":["rows"],"mappings":"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","file":"chunk-7S6HYNWW.js","sourcesContent":["/**\n * @feat:chat\n * Availability, the same on every platform: is someone inside their working hours (read in\n * their own time zone), are they away, and the one line a thread shows about it (\"Mark\n * replies Mon–Fri, 9–5 (Eastern)\", \"Away until Monday: Back Monday\"). Pure: `now` is passed\n * in, and time zones come from Intl.\n */\nimport type { ChatAvailability, Weekday, WorkingHours } from \"./types\";\n\nexport const WEEKDAYS: readonly Weekday[] = [\"mon\", \"tue\", \"wed\", \"thu\", \"fri\", \"sat\", \"sun\"];\n\nconst SHORT: Record<Weekday, string> = { mon: \"Mon\", tue: \"Tue\", wed: \"Wed\", thu: \"Thu\", fri: \"Fri\", sat: \"Sat\", sun: \"Sun\" };\n\n/** \"09:30\" → 570; a bad value (anything but such a string) → null. \"24:00\" is allowed as the end of a day. */\nexport function minutesOf(hhmm: unknown): number | null {\n if (typeof hhmm !== \"string\") return null;\n const m = /^(\\d{1,2}):(\\d{2})$/.exec(hhmm.trim());\n if (!m) return null;\n const h = Number(m[1]);\n const min = Number(m[2]);\n if (h > 24 || min > 59 || (h === 24 && min > 0)) return null;\n return h * 60 + min;\n}\n\n/** At most this many ranges a day, as the database allows. */\nexport const MAX_RANGES_PER_DAY = 4;\n\n/**\n * Working hours as they may safely be read: only mon..sun, each an array of `[\"HH:MM\", \"HH:MM\"]`\n * string pairs (at most four a day); every other day, range or value is dropped. Null when\n * nothing is left. Hours come from other people, so they are never trusted as typed.\n */\nexport function normalizeHours(raw: unknown): WorkingHours | null {\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) return null;\n const src = raw as Record<string, unknown>;\n const out: WorkingHours = {};\n let any = false;\n for (const day of WEEKDAYS) {\n if (!Object.prototype.hasOwnProperty.call(src, day)) continue;\n const ranges = src[day];\n if (!Array.isArray(ranges)) continue;\n const kept: [string, string][] = [];\n for (const r of ranges) {\n if (!Array.isArray(r) || r.length !== 2) continue;\n const [from, to] = r as unknown[];\n if (typeof from !== \"string\" || typeof to !== \"string\" || minutesOf(from) == null || minutesOf(to) == null) continue;\n kept.push([from, to]);\n if (kept.length >= MAX_RANGES_PER_DAY) break;\n }\n if (kept.length) {\n out[day] = kept;\n any = true;\n }\n }\n return any ? out : null;\n}\n\n/** The weekday and minute of the day at `now` in `timeZone` (the device's zone when null or unknown). */\nexport function localClock(now: Date, timeZone?: string | null): { day: Weekday; minutes: number } {\n let parts: Intl.DateTimeFormatPart[];\n try {\n parts = new Intl.DateTimeFormat(\"en-US\", {\n timeZone: timeZone || undefined,\n weekday: \"short\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n hourCycle: \"h23\",\n }).formatToParts(now);\n } catch {\n parts = new Intl.DateTimeFormat(\"en-US\", { weekday: \"short\", hour: \"2-digit\", minute: \"2-digit\", hourCycle: \"h23\" }).formatToParts(now);\n }\n const get = (t: string) => parts.find((p) => p.type === t)?.value ?? \"\";\n const day = get(\"weekday\").slice(0, 3).toLowerCase() as Weekday;\n const hour = Number(get(\"hour\")) % 24;\n return { day: WEEKDAYS.includes(day) ? day : \"mon\", minutes: hour * 60 + Number(get(\"minute\")) };\n}\n\n/**\n * Is `now` inside these working hours, read in `timeZone`? No hours set means always.\n * A range whose end is at or before its start runs overnight into the next day\n * (`fri: [[\"22:00\",\"02:00\"]]` covers Friday 22:00 to Saturday 02:00).\n */\nexport function isWithinWorkingHours(raw: WorkingHours | null | undefined, timeZone: string | null | undefined, now: Date = new Date()): boolean {\n const hours = normalizeHours(raw);\n if (!hours) return true;\n const { day, minutes } = localClock(now, timeZone);\n const yesterday = WEEKDAYS[(WEEKDAYS.indexOf(day) + 6) % 7]!;\n for (const [from, to] of hours[day] ?? []) {\n const a = minutesOf(from);\n const b = minutesOf(to);\n if (a == null || b == null) continue;\n if (b > a ? minutes >= a && minutes < b : minutes >= a) return true;\n }\n for (const [from, to] of hours[yesterday] ?? []) {\n const a = minutesOf(from);\n const b = minutesOf(to);\n if (a == null || b == null) continue;\n if (b <= a && minutes < b) return true;\n }\n return false;\n}\n\n/** Away now: an away message with no end date, or an end date still ahead. */\nexport function isAway(a: Pick<ChatAvailability, \"awayMessage\" | \"awayUntil\"> | null | undefined, now: Date = new Date()): boolean {\n if (!a) return false;\n if (a.awayUntil) return Date.parse(a.awayUntil) > now.getTime();\n return Boolean(a.awayMessage?.trim());\n}\n\n/** \"9\", \"9:30\", \"5\" (12-hour, no am/pm: the range reads \"9–5\"). */\nfunction clock(hhmm: string): string {\n const total = minutesOf(hhmm) ?? 0;\n const h = Math.floor(total / 60) % 24;\n const m = total % 60;\n const h12 = h % 12 === 0 ? 12 : h % 12;\n return m ? `${h12}:${String(m).padStart(2, \"0\")}` : String(h12);\n}\n\n/** \"Mon–Fri, 9–5\", \"Mon–Thu, 9–5; Fri, 9–1\". Days with the same hours are grouped. Empty when none. */\nexport function hoursSummary(raw: WorkingHours | null | undefined): string {\n const hours = normalizeHours(raw);\n if (!hours) return \"\";\n const key = (d: Weekday) => (hours[d] ?? []).map(([a, b]) => `${clock(a)}–${clock(b)}`).join(\", \");\n const runs: { from: Weekday; to: Weekday; text: string }[] = [];\n for (const d of WEEKDAYS) {\n const text = key(d);\n if (!text) continue;\n const last = runs[runs.length - 1];\n if (last && last.text === text && WEEKDAYS.indexOf(last.to) === WEEKDAYS.indexOf(d) - 1) last.to = d;\n else runs.push({ from: d, to: d, text });\n }\n return runs\n .map((r) => {\n const days = r.from === r.to ? SHORT[r.from] : WEEKDAYS.indexOf(r.to) - WEEKDAYS.indexOf(r.from) === 1 ? `${SHORT[r.from]}, ${SHORT[r.to]}` : `${SHORT[r.from]}–${SHORT[r.to]}`;\n return `${days}, ${r.text}`;\n })\n .join(\"; \");\n}\n\n/** \"Eastern\" for America/New_York (the zone's generic name, less \" Time\"); the city when Intl has no name. */\nexport function timeZoneLabel(timeZone: string | null | undefined, locale = \"en-US\"): string {\n if (!timeZone) return \"\";\n try {\n const name = new Intl.DateTimeFormat(locale, { timeZone, timeZoneName: \"longGeneric\" })\n .formatToParts(new Date())\n .find((p) => p.type === \"timeZoneName\")?.value;\n if (name && !/^GMT|^UTC/.test(name)) return name.replace(/ Time$/, \"\");\n } catch {\n // an unknown zone: fall through\n }\n return (timeZone.split(\"/\").pop() ?? timeZone).replace(/_/g, \" \");\n}\n\n/** \"3:00 PM\" today, \"Monday\" within the week, else \"12 Mar\". */\nexport function untilLabel(iso: string, now: Date = new Date(), locale?: string, timeZone?: string | null): string {\n const d = new Date(iso);\n if (!Number.isFinite(d.getTime())) return \"later\";\n try {\n return untilIn(d, now, locale, timeZone || undefined);\n } catch {\n // An unknown zone or locale: the device's.\n return untilIn(d, now, undefined, undefined);\n }\n}\n\nfunction untilIn(d: Date, now: Date, locale: string | undefined, tz: string | undefined): string {\n const dayKey = (x: Date) => new Intl.DateTimeFormat(\"en-CA\", { timeZone: tz, year: \"numeric\", month: \"2-digit\", day: \"2-digit\" }).format(x);\n if (dayKey(d) === dayKey(now)) return d.toLocaleTimeString(locale, { hour: \"numeric\", minute: \"2-digit\", timeZone: tz });\n const days = (d.getTime() - now.getTime()) / 86_400_000;\n if (days < 7) return d.toLocaleDateString(locale, { weekday: \"long\", timeZone: tz });\n return d.toLocaleDateString(locale, { day: \"numeric\", month: \"short\", timeZone: tz });\n}\n\nexport interface AwayLineOptions {\n now?: Date;\n locale?: string;\n /** Show the hours line even inside working hours (a profile, not a banner). */\n always?: boolean;\n}\n\n/**\n * The line a thread shows about someone, or null when they are around:\n * - away with a date: \"Away until Monday: Back Monday\" (the away message after the colon);\n * - away with no date: \"Mark is away: On a retreat\";\n * - outside working hours: \"Mark replies Mon–Fri, 9–5 (Eastern)\".\n */\nexport function awayLine(a: ChatAvailability | null | undefined, name: string, opts: AwayLineOptions = {}): string | null {\n if (!a) return null;\n const now = opts.now ?? new Date();\n const message = a.awayMessage?.trim();\n if (isAway(a, now)) {\n if (a.awayUntil) return `Away until ${untilLabel(a.awayUntil, now, opts.locale, a.timeZone)}${message ? `: ${message}` : \"\"}`;\n return `${name} is away${message ? `: ${message}` : \"\"}`;\n }\n const summary = hoursSummary(a.hours);\n if (!summary) return null;\n if (!opts.always && isWithinWorkingHours(a.hours, a.timeZone, now)) return null;\n const zone = timeZoneLabel(a.timeZone, opts.locale);\n return `${name} replies ${summary}${zone ? ` (${zone})` : \"\"}`;\n}\n\n/** \"Sam\", \"Sam and Lee\", \"Sam, Lee and 3 others\": at most two names. */\nexport function namesLine(names: string[]): string {\n if (names.length <= 1) return names[0] ?? \"\";\n if (names.length === 2) return `${names[0]} and ${names[1]}`;\n const rest = names.length - 2;\n return `${names[0]}, ${names[1]} and ${rest === 1 ? \"1 other\" : `${rest} others`}`;\n}\n\n/**\n * The line for several people (a group's members): one person's full `awayLine`, or for more\n * \"Sam and Lee are away\", \"Sam, Lee and 2 others are outside their hours\", or \"… are away or\n * outside their hours\" when it's a mix. Null when everyone is around.\n */\nexport function awaySummary(people: { availability: ChatAvailability | null | undefined; name: string }[], opts: AwayLineOptions = {}): string | null {\n const now = opts.now ?? new Date();\n const out = people.filter((p) => awayLine(p.availability, p.name, { ...opts, now, always: false }) !== null);\n if (out.length === 0) return null;\n if (out.length === 1) return awayLine(out[0]!.availability, out[0]!.name, { ...opts, now, always: false });\n const away = out.filter((p) => isAway(p.availability, now)).length;\n const what = away === out.length ? \"away\" : away === 0 ? \"outside their hours\" : \"away or outside their hours\";\n return `${namesLine(out.map((p) => p.name))} are ${what}`;\n}\n","/**\n * @feat:chat\n * Media rules shared by every platform: which files may be sent (the same list\n * migration 0001 checks), what kind an upload becomes, the default limits, and\n * the waveform a voice note carries so its bubble draws before the audio loads.\n */\nimport type { AttachmentKind } from \"./types\";\n\n/**\n * A random UUID (v4): `crypto.randomUUID` where the platform has it (some React Native\n * runtimes don't), else `crypto.getRandomValues`, else Math.random as a last resort. Ids\n * only need to be unique per sender: the server checks (sender, client_id).\n */\nexport function randomId(): string {\n const c = (globalThis as { crypto?: { randomUUID?: () => string; getRandomValues?: (a: Uint8Array) => Uint8Array } }).crypto;\n if (c?.randomUUID) return c.randomUUID();\n const b = new Uint8Array(16);\n if (c?.getRandomValues) c.getRandomValues(b);\n else for (let i = 0; i < 16; i++) b[i] = Math.floor(Math.random() * 256);\n b[6] = (b[6]! & 0x0f) | 0x40;\n b[8] = (b[8]! & 0x3f) | 0x80;\n const h = [...b].map((x) => x.toString(16).padStart(2, \"0\")).join(\"\");\n return `${h.slice(0, 8)}-${h.slice(8, 12)}-${h.slice(12, 16)}-${h.slice(16, 20)}-${h.slice(20)}`;\n}\n\n/** Mirrors genesis_chat.allowed_extension. Never SVG or HTML, which a browser runs as a page. */\nexport const ALLOWED_EXTENSIONS = [\n \"png\", \"jpg\", \"jpeg\", \"webp\", \"gif\", \"heic\", \"heif\",\n \"m4a\", \"aac\", \"mp3\", \"ogg\", \"oga\", \"opus\", \"weba\", \"webm\",\n \"mp4\", \"mov\", \"pdf\", \"txt\", \"csv\", \"docx\", \"xlsx\", \"pptx\",\n] as const;\n\nconst MIME_EXTENSIONS: Record<string, string> = {\n \"image/png\": \"png\",\n \"image/jpeg\": \"jpg\",\n \"image/webp\": \"webp\",\n \"image/gif\": \"gif\",\n \"image/heic\": \"heic\",\n \"image/heif\": \"heif\",\n \"audio/mp4\": \"m4a\",\n \"audio/x-m4a\": \"m4a\",\n \"audio/aac\": \"aac\",\n \"audio/mpeg\": \"mp3\",\n \"audio/ogg\": \"ogg\",\n \"audio/webm\": \"webm\",\n \"video/mp4\": \"mp4\",\n \"video/quicktime\": \"mov\",\n \"video/webm\": \"webm\",\n \"application/pdf\": \"pdf\",\n \"text/plain\": \"txt\",\n \"text/csv\": \"csv\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\": \"docx\",\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\": \"xlsx\",\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\": \"pptx\",\n};\n\n/** The extension a file is stored under: from its content type, else its name. */\nexport function fileExtension(name: string, contentType?: string): string {\n const base = (contentType ?? \"\").split(\";\")[0]!.trim().toLowerCase();\n const fromType = MIME_EXTENSIONS[base];\n if (fromType) return fromType;\n const dot = name.lastIndexOf(\".\");\n return dot >= 0 ? name.slice(dot + 1).toLowerCase() : \"\";\n}\n\nexport function isAllowedExtension(ext: string): boolean {\n return (ALLOWED_EXTENSIONS as readonly string[]).includes(ext.toLowerCase());\n}\n\n/** What an upload becomes in a message. */\nexport function attachmentKindFor(contentType: string, opts: { recordedVoice?: boolean } = {}): AttachmentKind {\n const t = contentType.toLowerCase();\n if (opts.recordedVoice || t.startsWith(\"audio/\")) return \"voice\";\n if (t.startsWith(\"image/\")) return \"image\";\n if (t.startsWith(\"video/\")) return \"video\";\n return \"file\";\n}\n\n/** Default limits (decision 5): an app may lower them, not raise them past the bucket's 100 MB. */\nexport const CHAT_LIMITS = {\n /** Voice notes and videos, for members. */\n recordingMs: 5 * 60_000,\n /** For owners, admins and observers (coaches, staff). */\n staffRecordingMs: 10 * 60_000,\n fileBytes: 50 * 1024 * 1024,\n videoBytes: 100 * 1024 * 1024,\n attachmentsPerMessage: 20,\n bodyChars: 10_000,\n} as const;\n\n/** The longest recording this role may make. */\nexport function recordingLimitMs(role: string | null | undefined): number {\n return role === \"owner\" || role === \"admin\" || role === \"observer\" ? CHAT_LIMITS.staffRecordingMs : CHAT_LIMITS.recordingMs;\n}\n\n/**\n * Peaks for a waveform: `count` values 0–100 from raw samples (-1…1), the loudest\n * in each bucket, scaled so the loudest bucket is 100. Quiet recordings still show\n * a shape; silence shows a flat line.\n */\nexport function waveformPeaks(samples: ArrayLike<number>, count = 48): number[] {\n const n = Math.max(1, Math.min(128, Math.floor(count)));\n if (samples.length === 0) return new Array(n).fill(0);\n const size = samples.length / n;\n const raw: number[] = [];\n for (let i = 0; i < n; i++) {\n let peak = 0;\n const end = Math.min(samples.length, Math.floor((i + 1) * size));\n for (let j = Math.floor(i * size); j < end; j++) {\n const v = Math.abs(samples[j]!);\n if (v > peak) peak = v;\n }\n raw.push(peak);\n }\n const max = Math.max(...raw);\n if (max < 0.01) return raw.map(() => 0);\n return raw.map((v) => Math.round((v / max) * 100));\n}\n\n/**\n * Peaks from a level meter read while recording (expo-audio's `metering`, in dB,\n * about -160…0): resampled to `count` values 0–100.\n */\nexport function waveformFromMetering(levelsDb: number[], count = 48): number[] {\n const linear = levelsDb.map((db) => (Number.isFinite(db) ? Math.pow(10, Math.max(-60, Math.min(0, db)) / 20) : 0));\n return waveformPeaks(linear, count);\n}\n\n/** 0:42, 1:05:09. */\nexport function formatDuration(ms: number | null | undefined): string {\n const total = Math.max(0, Math.round((ms ?? 0) / 1000));\n const h = Math.floor(total / 3600);\n const m = Math.floor((total % 3600) / 60);\n const s = total % 60;\n return h > 0 ? `${h}:${String(m).padStart(2, \"0\")}:${String(s).padStart(2, \"0\")}` : `${m}:${String(s).padStart(2, \"0\")}`;\n}\n\n/** Playback speeds offered for voice and video (free for everyone, decision 5). */\nexport const PLAYBACK_RATES = [1, 1.5, 2] as const;\n\nexport function nextPlaybackRate(rate: number): number {\n const i = PLAYBACK_RATES.indexOf(rate as (typeof PLAYBACK_RATES)[number]);\n return PLAYBACK_RATES[(i + 1) % PLAYBACK_RATES.length]!;\n}\n","/**\n * @feat:chat\n * The chat client: the app's own Supabase (migrations 0001 and 0002, the genesis_chat\n * schema) under row level security. Reads are table selects; every write is a\n * genesis_chat function. Live updates are hints on private Realtime topics,\n * after which the client fetches again, so nothing is trusted from the wire.\n */\nimport type { RealtimeChannel, SupabaseClient } from \"@supabase/supabase-js\";\nimport type {\n AttachmentInput,\n AvailabilityInput,\n ChatActivity,\n ChatAttachment,\n ChatAvailability,\n ChatLinkPreview,\n ChatSearchHit,\n ChatTopic,\n ScheduleInput,\n ScheduledMessage,\n TopicInput,\n ChatConversation,\n ChatInboxItem,\n ChatKindRules,\n ChatMember,\n ChatMessage,\n ChatRole,\n ChatSignal,\n SendInput,\n} from \"./types\";\nimport { normalizeHours } from \"./availability\";\nimport { fileExtension, isAllowedExtension, randomId } from \"./media\";\n\n/** Any supabase-js client; the app's generated Database types don't need to list genesis_chat. */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type ChatSupabase = SupabaseClient<any, any, any>;\n\nexport const CHAT_SCHEMA = \"genesis_chat\";\nexport const CHAT_BUCKET = \"genesis-chat\";\n\nexport const conversationTopic = (conversationId: string) => `genesis-chat:conv:${conversationId}`;\nexport const userTopic = (userId: string) => `genesis-chat:user:${userId}`;\n\n/** A refusal from the database, with its SQLSTATE (`42501` not allowed, `22023` bad input, `GS429` too many). */\nexport class ChatError extends Error {\n constructor(\n message: string,\n readonly code: string | undefined,\n readonly operation: string,\n ) {\n super(message);\n this.name = \"ChatError\";\n }\n get forbidden(): boolean {\n return this.code === \"42501\";\n }\n get rateLimited(): boolean {\n return this.code === \"GS429\";\n }\n /** Worth trying again: the network, not the database, said no. */\n get transient(): boolean {\n return this.code === undefined || this.code === \"\" || /^(08|57|53)/.test(this.code) || this.code === \"PGRST000\";\n }\n /**\n * Sending it again won't help: the database refused what was sent (not allowed 42501, bad\n * data 22xxx such as 22023, a conflict 23xxx such as 23505, another refusal 42xxx, or a\n * function's own `raise` P0001). A person may still retry by hand; nothing retries it alone.\n */\n get permanent(): boolean {\n return !this.transient && !this.rateLimited && /^(22|23|42|P0)/.test(this.code ?? \"\");\n }\n}\n\nfunction must<T>(operation: string, result: { data: T | null; error: { message: string; code?: string } | null }): T {\n if (result.error) throw new ChatError(result.error.message, result.error.code, operation);\n return result.data as T;\n}\n\ntype Row = Record<string, unknown>;\nconst str = (v: unknown) => (v == null ? null : String(v));\nconst num = (v: unknown) => (v == null ? null : Number(v));\n\nexport function toAttachment(r: Row): ChatAttachment {\n return {\n id: String(r.id),\n messageId: String(r.message_id),\n position: Number(r.position ?? 0),\n kind: String(r.kind),\n ref: (r.ref as Record<string, unknown>) ?? {},\n provider: (r.provider as ChatAttachment[\"provider\"]) ?? \"storage\",\n path: str(r.path),\n providerId: str(r.provider_id),\n playbackId: str(r.playback_id),\n url: str(r.url),\n status: (r.status as ChatAttachment[\"status\"]) ?? \"ready\",\n name: str(r.name),\n mime: str(r.mime),\n bytes: num(r.bytes),\n width: num(r.width),\n height: num(r.height),\n durationMs: num(r.duration_ms),\n waveform: (r.waveform as number[] | null) ?? null,\n posterPath: str(r.poster_path),\n thumbhash: str(r.thumbhash),\n transcript: str(r.transcript),\n transcriptStatus: (r.transcript_status as ChatAttachment[\"transcriptStatus\"]) ?? null,\n };\n}\n\nexport function toMessage(r: Row): ChatMessage {\n const attachments = ((r.attachments as Row[] | undefined) ?? []).map(toAttachment).sort((a, b) => a.position - b.position);\n const reactions = ((r.reactions as Row[] | undefined) ?? []).map((x) => ({ emoji: String(x.emoji), userId: String(x.user_id) }));\n return {\n id: String(r.id),\n conversationId: String(r.conversation_id),\n seq: Number(r.seq),\n clientId: String(r.client_id),\n senderId: str(r.sender_id),\n senderRole: r.sender_role as ChatMessage[\"senderRole\"],\n kind: (r.kind as ChatMessage[\"kind\"]) ?? \"text\",\n body: String(r.body ?? \"\"),\n mentions: (r.mentions as string[]) ?? [],\n replyToId: str(r.reply_to_id),\n threadRootId: str(r.thread_root_id),\n threadCount: Number(r.thread_count ?? 0),\n threadLastAt: str(r.thread_last_at),\n topic: str(r.topic),\n visibility: (r.visibility as ChatMessage[\"visibility\"]) ?? \"everyone\",\n silent: Boolean(r.silent),\n meta: (r.meta as Record<string, unknown>) ?? {},\n createdAt: String(r.created_at),\n editedAt: str(r.edited_at),\n deletedAt: str(r.deleted_at),\n moderation: r.moderation === \"hidden\" || r.moderation === \"flagged\" ? r.moderation : null,\n attachments,\n reactions,\n };\n}\n\nfunction toConversation(r: Row): ChatConversation {\n return {\n id: String(r.id),\n kind: String(r.kind),\n title: str(r.title),\n subjectType: str(r.subject_type),\n subjectId: str(r.subject_id),\n settings: (r.settings as ChatConversation[\"settings\"]) ?? {},\n status: (r.status as ChatConversation[\"status\"]) ?? null,\n assigneeId: str(r.assignee_id),\n lastSeq: Number(r.last_seq ?? 0),\n lastMessageAt: str(r.last_message_at),\n createdAt: String(r.created_at),\n archivedAt: str(r.archived_at),\n };\n}\n\nfunction toInboxItem(r: Row): ChatInboxItem {\n const last = r.last_message as Row | null;\n return {\n conversationId: String(r.conversation_id),\n kind: String(r.kind),\n title: str(r.title),\n subjectType: str(r.subject_type),\n subjectId: str(r.subject_id),\n status: (r.status as ChatInboxItem[\"status\"]) ?? null,\n role: r.role as ChatRole,\n otherUserId: str(r.other_user_id),\n memberCount: Number(r.member_count ?? 0),\n lastSeq: Number(r.last_seq ?? 0),\n lastReadSeq: Number(r.last_read_seq ?? 0),\n unread: Number(r.unread ?? 0),\n mentioned: Boolean(r.mentioned),\n muted: Boolean(r.muted),\n pinned: Boolean(r.pinned),\n archived: Boolean(r.archived),\n lastMessageAt: str(r.last_message_at),\n lastMessage: last\n ? {\n id: String(last.id),\n seq: Number(last.seq),\n senderId: str(last.sender_id),\n kind: (last.kind as \"text\" | \"system\") ?? \"text\",\n body: String(last.body ?? \"\"),\n deleted: Boolean(last.deleted),\n createdAt: String(last.created_at),\n attachment: (last.attachment as string | null) ?? null,\n }\n : null,\n };\n}\n\nexport function toTopic(r: Row): ChatTopic {\n return {\n conversationId: String(r.conversation_id),\n topic: String(r.topic),\n title: String(r.title ?? r.topic),\n position: Number(r.position ?? 0),\n closedAt: str(r.closed_at),\n createdBy: str(r.created_by),\n createdAt: String(r.created_at),\n };\n}\n\nfunction fromAttachmentArg(a: Row): AttachmentInput {\n const out: AttachmentInput = { kind: String(a.kind ?? \"file\") };\n const map: [keyof AttachmentInput, string][] = [\n [\"path\", \"path\"], [\"provider\", \"provider\"], [\"providerId\", \"provider_id\"], [\"url\", \"url\"], [\"ref\", \"ref\"],\n [\"status\", \"status\"], [\"name\", \"name\"], [\"mime\", \"mime\"], [\"bytes\", \"bytes\"], [\"width\", \"width\"],\n [\"height\", \"height\"], [\"durationMs\", \"duration_ms\"], [\"waveform\", \"waveform\"], [\"posterPath\", \"poster_path\"], [\"thumbhash\", \"thumbhash\"],\n ];\n for (const [k, col] of map) if (a[col] != null) (out as unknown as Record<string, unknown>)[k] = a[col];\n return out;\n}\n\nexport function toScheduled(r: Row): ScheduledMessage {\n const sentMessageId = str(r.sent_message_id);\n const cancelledAt = str(r.cancelled_at);\n const error = str(r.error);\n return {\n id: String(r.id),\n conversationId: String(r.conversation_id),\n clientId: String(r.client_id),\n body: String(r.body ?? \"\"),\n attachments: ((r.attachments as Row[] | null) ?? []).map(fromAttachmentArg),\n replyToId: str(r.reply_to_id),\n topic: str(r.topic),\n mentions: (r.mentions as string[] | null) ?? [],\n silent: Boolean(r.silent),\n sendAt: String(r.send_at),\n sentMessageId,\n cancelledAt,\n error,\n createdAt: String(r.created_at),\n status: sentMessageId ? \"sent\" : cancelledAt ? \"cancelled\" : error ? \"failed\" : \"scheduled\",\n };\n}\n\nexport function toAvailability(r: Row): ChatAvailability {\n return {\n userId: String(r.user_id),\n awayMessage: str(r.away_message),\n awayUntil: str(r.away_until),\n timeZone: str(r.time_zone),\n // Someone else's hours: only well-formed days and ranges reach the renderers.\n hours: normalizeHours(r.hours),\n };\n}\n\nexport function toSearchHit(r: Row): ChatSearchHit {\n return {\n messageId: String(r.message_id),\n conversationId: String(r.conversation_id),\n seq: Number(r.seq),\n senderId: str(r.sender_id),\n createdAt: String(r.created_at),\n snippet: String(r.snippet ?? \"\"),\n inTranscript: Boolean(r.in_transcript),\n };\n}\n\nexport function toLinkPreview(r: Row): ChatLinkPreview {\n const image = str(r.image_url);\n return {\n url: String(r.url),\n status: (r.status as ChatLinkPreview[\"status\"]) ?? \"ok\",\n title: str(r.title),\n description: str(r.description),\n imageUrl: image && /^https:\\/\\//i.test(image) ? image : null,\n siteName: str(r.site_name),\n fetchedAt: String(r.fetched_at),\n };\n}\n\nconst MESSAGE_COLUMNS = \"*, attachments(*), reactions(emoji, user_id)\";\n\nexport interface MessagePage {\n messages: ChatMessage[];\n /** More, older messages exist before the first one. */\n hasEarlier: boolean;\n}\n\nexport interface ChatClientOptions {\n /** Signed file links live this long (seconds). Default an hour. */\n signedUrlSeconds?: number;\n}\n\nexport interface Subscription {\n unsubscribe(): void;\n}\n\nexport interface ConversationHandlers {\n onSignal: (s: ChatSignal) => void;\n onActivity?: (a: ChatActivity) => void;\n /** Every join, the first included: catch up on what arrived before the channel was live. */\n onJoin?: () => void;\n /** Re-joins only. Prefer `onJoin`. */\n onReconnect?: () => void;\n}\n\nexport interface ConversationChannel extends Subscription {\n /** Tell the others you are typing or recording (throttle to once every 3 seconds). */\n signal(activity: ChatActivity[\"activity\"]): void;\n}\n\nexport function createChatClient(supabase: ChatSupabase, options: ChatClientOptions = {}) {\n const db = () => supabase.schema(CHAT_SCHEMA);\n const signedUrlSeconds = options.signedUrlSeconds ?? 3600;\n const signedCache = new Map<string, { url: string; until: number }>();\n\n /**\n * Private Realtime channels authorise with the signed-in user's token; set it before\n * joining (supabase-js doesn't for a channel joined before the session loads), or the\n * join is refused and no hint ever arrives. A refusal to set it still joins and retries.\n */\n const unsubscribed = new WeakSet<RealtimeChannel>();\n function join(channel: RealtimeChannel, onStatus?: (status: string) => void) {\n const realtime = (supabase as unknown as { realtime?: { setAuth?: (token?: string | null) => Promise<void> | void } }).realtime;\n void Promise.resolve(realtime?.setAuth?.())\n .catch(() => undefined)\n .then(() => {\n if (!unsubscribed.has(channel)) channel.subscribe(onStatus);\n });\n return () => {\n unsubscribed.add(channel);\n void supabase.removeChannel(channel);\n };\n }\n\n async function rpc<T>(fn: string, args: Record<string, unknown>): Promise<T> {\n return must<T>(fn, await db().rpc(fn, args));\n }\n\n return {\n supabase,\n\n /** Your conversations: one `kind`, several `kinds`, or all but `excludeKinds` (e.g. Messages without `support`). */\n async inbox(\n opts: { kind?: string; kinds?: string[]; excludeKinds?: string[]; archived?: boolean; limit?: number; before?: string } = {},\n ): Promise<ChatInboxItem[]> {\n const rows = await rpc<Row[]>(\"inbox\", {\n p_kind: opts.kind ?? null,\n p_archived: opts.archived ?? false,\n p_limit: opts.limit ?? 50,\n p_before: opts.before ?? null,\n ...(opts.kinds?.length ? { p_kinds: opts.kinds } : {}),\n ...(opts.excludeKinds?.length ? { p_exclude_kinds: opts.excludeKinds } : {}),\n });\n return rows.map(toInboxItem);\n },\n\n async observed(kind: string, opts: { status?: string; limit?: number; before?: string } = {}) {\n return rpc<Row[]>(\"observed\", { p_kind: kind, p_status: opts.status ?? null, p_limit: opts.limit ?? 50, p_before: opts.before ?? null });\n },\n\n /** Unread across your conversations (for a badge), leaving out `excludeKinds` to match an inbox that does. */\n async unreadTotal(opts: { excludeKinds?: string[] } = {}): Promise<number> {\n return rpc<number>(\"unread_total\", opts.excludeKinds?.length ? { p_exclude_kinds: opts.excludeKinds } : {});\n },\n\n async conversation(id: string): Promise<ChatConversation | null> {\n const row = must(\"conversation\", await db().from(\"conversations\").select(\"*\").eq(\"id\", id).maybeSingle());\n return row ? toConversation(row as Row) : null;\n },\n\n /** A kind's rules (how many members, who posts, threads), for what the UI offers. */\n async kind(kind: string): Promise<ChatKindRules | null> {\n const row = must(\"kind\", await db().from(\"kinds\").select(\"kind, label, max_members, who_posts, membership, threads, observers_post\").eq(\"kind\", kind).maybeSingle()) as Row | null;\n return row\n ? {\n kind: String(row.kind),\n label: String(row.label),\n maxMembers: row.max_members == null ? null : Number(row.max_members),\n whoPosts: row.who_posts as ChatKindRules[\"whoPosts\"],\n membership: row.membership as ChatKindRules[\"membership\"],\n threads: Boolean(row.threads),\n observersPost: Boolean(row.observers_post),\n }\n : null;\n },\n\n async myRole(id: string): Promise<ChatRole | null> {\n return rpc<ChatRole | null>(\"my_role\", { p_conversation_id: id });\n },\n\n async canPost(id: string): Promise<boolean> {\n return rpc<boolean>(\"can_post\", { p_conversation_id: id });\n },\n\n async members(id: string): Promise<ChatMember[]> {\n const rows = must<Row[]>(\n \"members\",\n await db().from(\"members\").select(\"*\").eq(\"conversation_id\", id).is(\"left_at\", null).neq(\"role\", \"observer\"),\n );\n return rows.map((r) => ({\n conversationId: String(r.conversation_id),\n userId: String(r.user_id),\n role: r.role as ChatRole,\n lastReadSeq: Number(r.last_read_seq ?? 0),\n joinedAt: String(r.joined_at),\n }));\n },\n\n /**\n * A page of messages, oldest first: the latest `limit` (default 50), or those\n * before `beforeSeq`, or (to catch up after a reconnect) those after `afterSeq`.\n * A thread's replies with `threadRootId`; one topic's with `topic`.\n */\n async messages(\n conversationId: string,\n opts: { beforeSeq?: number; afterSeq?: number; limit?: number; threadRootId?: string; topic?: string } = {},\n ): Promise<MessagePage> {\n const limit = Math.min(Math.max(opts.limit ?? 50, 1), 200);\n let q = db().from(\"messages\").select(MESSAGE_COLUMNS).eq(\"conversation_id\", conversationId);\n q = opts.threadRootId ? q.eq(\"thread_root_id\", opts.threadRootId) : q.is(\"thread_root_id\", null);\n if (opts.topic) q = q.eq(\"topic\", opts.topic);\n if (opts.afterSeq != null) {\n const rows = must<Row[]>(\"messages\", await q.gt(\"seq\", opts.afterSeq).order(\"seq\", { ascending: true }).limit(limit));\n return { messages: rows.map(toMessage), hasEarlier: false };\n }\n if (opts.beforeSeq != null) q = q.lt(\"seq\", opts.beforeSeq);\n const rows = must<Row[]>(\"messages\", await q.order(\"seq\", { ascending: false }).limit(limit + 1));\n const hasEarlier = rows.length > limit;\n return { messages: rows.slice(0, limit).map(toMessage).reverse(), hasEarlier };\n },\n\n async message(id: string): Promise<ChatMessage | null> {\n const row = must(\"message\", await db().from(\"messages\").select(MESSAGE_COLUMNS).eq(\"id\", id).maybeSingle());\n return row ? toMessage(row as Row) : null;\n },\n\n async startConversation(kind: string, memberIds: string[], opts: { title?: string; subjectType?: string; subjectId?: string } = {}) {\n return rpc<string>(\"start_conversation\", {\n p_kind: kind,\n p_member_ids: memberIds,\n p_title: opts.title ?? null,\n p_subject_type: opts.subjectType ?? null,\n p_subject_id: opts.subjectId ?? null,\n });\n },\n\n /** Sends a message. Safe to retry with the same clientId. */\n async send(input: SendInput): Promise<ChatMessage> {\n const row = await rpc<Row>(\"send_message\", {\n p_conversation_id: input.conversationId,\n p_client_id: input.clientId,\n p_body: input.body ?? \"\",\n p_attachments: (input.attachments ?? []).map(attachmentArg),\n p_reply_to_id: input.replyToId ?? null,\n p_thread_root_id: input.threadRootId ?? null,\n p_topic: input.topic ?? null,\n p_mentions: input.mentions ?? [],\n p_visibility: input.visibility ?? \"everyone\",\n p_silent: input.silent ?? false,\n });\n // The function returns the message row; fetch it again for its attachments.\n return (await this.message(String(row.id))) ?? toMessage(row);\n },\n\n async edit(messageId: string, body: string, mentions: string[] = []) {\n return toMessage(await rpc<Row>(\"edit_message\", { p_message_id: messageId, p_body: body, p_mentions: mentions }));\n },\n\n async remove(messageId: string) {\n await rpc(\"delete_message\", { p_message_id: messageId });\n },\n\n async react(messageId: string, emoji: string, on = true) {\n await rpc(\"react\", { p_message_id: messageId, p_emoji: emoji, p_on: on });\n },\n\n async markRead(conversationId: string, seq?: number) {\n return rpc<number>(\"mark_read\", { p_conversation_id: conversationId, p_seq: seq ?? null });\n },\n\n async setMySettings(\n conversationId: string,\n s: { mutedUntil?: string | null; notify?: \"all\" | \"mentions\" | \"none\"; archived?: boolean; pinned?: boolean },\n ) {\n await rpc(\"set_my_settings\", {\n p_conversation_id: conversationId,\n p_muted_until: s.mutedUntil ?? null,\n p_notify: s.notify ?? null,\n p_archived: s.archived ?? null,\n p_pinned: s.pinned ?? null,\n p_clear_mute: s.mutedUntil === null,\n });\n },\n\n async updateConversation(conversationId: string, s: { title?: string; settings?: Record<string, unknown> }) {\n await rpc(\"update_conversation\", { p_conversation_id: conversationId, p_title: s.title ?? null, p_settings: s.settings ?? null });\n },\n\n async addMembers(conversationId: string, userIds: string[]) {\n await rpc(\"add_members\", { p_conversation_id: conversationId, p_user_ids: userIds });\n },\n\n async removeMember(conversationId: string, userId?: string) {\n await rpc(\"remove_member\", { p_conversation_id: conversationId, p_user_id: userId ?? null });\n },\n\n async setStatus(conversationId: string, status: ChatConversation[\"status\"], assigneeId?: string | null) {\n await rpc(\"set_status\", { p_conversation_id: conversationId, p_status: status, p_assignee_id: assigneeId ?? null });\n },\n\n async pin(messageId: string, on = true) {\n await rpc(\"pin_message\", { p_message_id: messageId, p_on: on });\n },\n\n async pins(conversationId: string): Promise<string[]> {\n const rows = must<Row[]>(\"pins\", await db().from(\"pins\").select(\"message_id\").eq(\"conversation_id\", conversationId));\n return rows.map((r) => String(r.message_id));\n },\n\n async save(messageId: string, on = true, note?: string) {\n await rpc(\"save_message\", { p_message_id: messageId, p_on: on, p_note: note ?? null });\n },\n\n async report(messageId: string, reason: \"spam\" | \"harassment\" | \"safety\" | \"other\", note?: string) {\n return rpc<string>(\"report_message\", { p_message_id: messageId, p_reason: reason, p_note: note ?? null });\n },\n\n // ── Migration 0002 ──────────────────────────────────────────────────────\n\n /** A conversation's topics, in order (position, then key). */\n async topics(conversationId: string): Promise<ChatTopic[]> {\n const rows = must<Row[]>(\n \"topics\",\n await db().from(\"topics\").select(\"*\").eq(\"conversation_id\", conversationId).order(\"position\", { ascending: true }).order(\"topic\", { ascending: true }),\n );\n return rows.map(toTopic);\n },\n\n /** Adds a topic, or renames, reorders, closes (`closed: true`) or reopens it. Owners and admins. */\n async setTopic(conversationId: string, topic: string, input: TopicInput = {}) {\n await rpc(\"set_topic\", {\n p_conversation_id: conversationId,\n p_topic: topic,\n p_title: input.title ?? null,\n p_position: input.position ?? null,\n p_closed: input.closed ?? null,\n });\n },\n\n /** Schedules a message (a minute to a year ahead) and returns its id. Safe to retry with the same clientId. */\n async schedule(input: ScheduleInput): Promise<string> {\n const sendAt = typeof input.sendAt === \"string\" ? input.sendAt : input.sendAt.toISOString();\n return rpc<string>(\"schedule_message\", {\n p_conversation_id: input.conversationId,\n p_client_id: input.clientId,\n p_send_at: sendAt,\n p_body: input.body ?? \"\",\n p_attachments: (input.attachments ?? []).map(attachmentArg),\n p_reply_to_id: input.replyToId ?? null,\n p_topic: input.topic ?? null,\n p_mentions: input.mentions ?? [],\n p_silent: input.silent ?? false,\n });\n },\n\n /** Your messages still waiting to go (and ones that failed when due), soonest first; in one conversation or all. */\n async scheduled(conversationId?: string): Promise<ScheduledMessage[]> {\n let q = db().from(\"scheduled\").select(\"*\").is(\"sent_message_id\", null).is(\"cancelled_at\", null);\n if (conversationId) q = q.eq(\"conversation_id\", conversationId);\n const rows = must<Row[]>(\"scheduled\", await q.order(\"send_at\", { ascending: true }).limit(200));\n return rows.map(toScheduled);\n },\n\n async cancelScheduled(id: string) {\n await rpc(\"cancel_scheduled\", { p_id: id });\n },\n\n /** The away message and hours of a conversation's members who set them (not observers). */\n async availabilityFor(conversationId: string): Promise<ChatAvailability[]> {\n const rows = await rpc<Row[]>(\"availability_for\", { p_conversation_id: conversationId });\n return (rows ?? []).map(toAvailability);\n },\n\n /** Your own away message and hours, or null when never set. */\n async myAvailability(): Promise<ChatAvailability | null> {\n const row = must(\"myAvailability\", await db().from(\"availability\").select(\"*\").maybeSingle()) as Row | null;\n return row ? toAvailability(row) : null;\n },\n\n /** Replaces your away message and hours (a field left out is cleared). */\n async setAvailability(input: AvailabilityInput) {\n const until = input.awayUntil ?? null;\n await rpc(\"set_availability\", {\n p_away_message: input.awayMessage ?? null,\n p_away_until: until,\n p_time_zone: input.timeZone ?? null,\n p_hours: input.hours ?? null,\n });\n },\n\n /**\n * Sends one text message into each of these conversations where you may post (a coach to\n * each client's direct conversation), so replies come back privately. Text only. Safe to\n * retry with the same clientId. Returns the ids of the messages sent.\n */\n async broadcast(conversationIds: string[], clientId: string, body: string, opts: { silent?: boolean } = {}): Promise<string[]> {\n const ids = await rpc<string[] | null>(\"broadcast_message\", {\n p_conversation_ids: conversationIds,\n p_client_id: clientId,\n p_body: body,\n p_attachments: [],\n p_silent: opts.silent ?? false,\n });\n return (ids ?? []).map(String);\n },\n\n /** Messages (and transcripts) you can read that match, newest first: in one conversation or all of yours. Two characters at least. */\n async search(query: string, conversationId?: string | null, opts: { limit?: number } = {}): Promise<ChatSearchHit[]> {\n if (query.trim().length < 2) return [];\n const rows = await rpc<Row[] | null>(\"search_messages\", {\n p_query: query,\n p_conversation_id: conversationId ?? null,\n p_limit: opts.limit ?? 30,\n });\n return (rows ?? []).map(toSearchHit);\n },\n\n /**\n * The previews the server has fetched for the links in these messages, by message id (only\n * `ok` ones; links not fetched yet are left out). Read through link_previews_for, one call\n * per message (up to 6 at once), which answers only for messages you can read: the preview\n * table itself is closed, since a URL can carry a secret.\n */\n async linkPreviewsFor(messageIds: string[]): Promise<Record<string, ChatLinkPreview[]>> {\n const ids = [...new Set(messageIds.filter(Boolean))].slice(0, 200);\n const out: Record<string, ChatLinkPreview[]> = {};\n let next = 0;\n const worker = async () => {\n while (next < ids.length) {\n const id = ids[next++]!;\n const rows = await rpc<Row[] | null>(\"link_previews_for\", { p_message_id: id });\n out[id] = (rows ?? []).map(toLinkPreview).filter((p) => p.status === \"ok\");\n }\n };\n await Promise.all(Array.from({ length: Math.min(6, ids.length) }, worker));\n return out;\n },\n\n /**\n * Uploads a file into the conversation's folder for the signed-in person and\n * returns its path, ready to attach. Resumable for big files is the native\n * renderer's job (Supabase TUS); this is the plain upload.\n */\n async upload(conversationId: string, userId: string, file: Blob | ArrayBuffer, opts: { name: string; contentType: string; id?: string }) {\n const ext = fileExtension(opts.name, opts.contentType);\n if (!isAllowedExtension(ext)) throw new ChatError(`Files of type .${ext} can't be sent`, \"22023\", \"upload\");\n const id = opts.id ?? randomId();\n const path = `${conversationId}/${userId}/${id}.${ext}`;\n must(\"upload\", await supabase.storage.from(CHAT_BUCKET).upload(path, file, { contentType: opts.contentType, upsert: false }));\n return path;\n },\n\n /** Signed links for files, cached until shortly before they expire. */\n async fileUrls(paths: string[]): Promise<Record<string, string>> {\n const now = Date.now();\n const out: Record<string, string> = {};\n const missing: string[] = [];\n for (const p of new Set(paths)) {\n const hit = signedCache.get(p);\n if (hit && hit.until > now) out[p] = hit.url;\n else missing.push(p);\n }\n if (missing.length) {\n const { data, error } = await supabase.storage.from(CHAT_BUCKET).createSignedUrls(missing, signedUrlSeconds);\n if (error) throw new ChatError(error.message, undefined, \"fileUrls\");\n for (const d of data ?? []) {\n if (d.signedUrl && d.path) {\n out[d.path] = d.signedUrl;\n signedCache.set(d.path, { url: d.signedUrl, until: now + (signedUrlSeconds - 60) * 1000 });\n }\n }\n }\n return out;\n },\n\n /** Your inbox's live hints (a new message anywhere you are, a membership change). */\n subscribeInbox(userId: string, onSignal: (s: ChatSignal) => void): Subscription {\n const channel = supabase\n .channel(userTopic(userId), { config: { private: true } })\n .on(\"broadcast\", { event: \"inbox\" }, ({ payload }) =>\n onSignal({ type: \"inbox\", conversationId: String(payload?.conversation_id), seq: payload?.seq }),\n );\n return { unsubscribe: join(channel) };\n },\n\n /**\n * A conversation's live hints, plus who is typing or recording. `onJoin` runs every\n * time the channel joins, the first time included: the moment to fetch what arrived\n * before the subscription was live. `onReconnect` (kept for older callers) runs on\n * re-joins only.\n */\n subscribeConversation(\n conversationId: string,\n me: string,\n handlers: ConversationHandlers,\n ): ConversationChannel {\n let joinedOnce = false;\n const channel: RealtimeChannel = supabase\n .channel(conversationTopic(conversationId), { config: { private: true, broadcast: { self: false } } })\n .on(\"broadcast\", { event: \"message\" }, ({ payload }) =>\n handlers.onSignal({ type: \"message\", conversationId, id: String(payload?.id), seq: payload?.seq, op: payload?.op ?? \"insert\" }),\n )\n .on(\"broadcast\", { event: \"reaction\" }, ({ payload }) =>\n handlers.onSignal({ type: \"reaction\", conversationId, messageId: String(payload?.message_id) }),\n )\n .on(\"broadcast\", { event: \"members\" }, () => handlers.onSignal({ type: \"members\", conversationId }))\n .on(\"broadcast\", { event: \"conversation\" }, () => handlers.onSignal({ type: \"conversation\", conversationId }))\n .on(\"broadcast\", { event: \"activity\" }, ({ payload }) => {\n if (payload?.userId && payload.userId !== me) handlers.onActivity?.({ userId: payload.userId, activity: payload.activity, at: Date.now() });\n });\n // Typing and recording are ephemeral: until the channel has joined, they're dropped\n // rather than sent (supabase-js would fall back to REST and warn).\n let joined = false;\n const leave = join(channel, (status) => {\n joined = status === \"SUBSCRIBED\";\n if (status === \"SUBSCRIBED\") {\n handlers.onJoin?.();\n if (joinedOnce) handlers.onReconnect?.();\n joinedOnce = true;\n }\n });\n return {\n signal(activity) {\n if (!joined) return;\n void channel.send({ type: \"broadcast\", event: \"activity\", payload: { userId: me, activity } });\n },\n unsubscribe: leave,\n };\n },\n };\n}\n\nexport type ChatClient = ReturnType<typeof createChatClient>;\n\nfunction attachmentArg(a: AttachmentInput) {\n return {\n kind: a.kind,\n path: a.path,\n provider: a.provider,\n provider_id: a.providerId,\n url: a.url,\n ref: a.ref,\n status: a.status,\n name: a.name,\n mime: a.mime,\n bytes: a.bytes,\n width: a.width,\n height: a.height,\n duration_ms: a.durationMs,\n waveform: a.waveform,\n poster_path: a.posterPath,\n thumbhash: a.thumbhash,\n };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/react/index.tsx"],"names":["list"],"mappings":"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","file":"chunk-PZTOY2LY.js","sourcesContent":["/**\n * @feat:chat\n * React hooks for chat, the same on web and native: the inbox, one\n * conversation (its messages, members, your role, who is typing) kept live by\n * Realtime hints, sending through the outbox, and message actions. Server\n * state is TanStack Query's; the renderers in /web and /native only draw.\n */\nimport { useQueries, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, type ReactNode } from \"react\";\nimport type { ChatClient, ConversationChannel, MessagePage } from \"../core/client\";\nimport { createOutbox, type LocalFile, type Outbox, type OutboxStore, type QueuedMessage } from \"../core/outbox\";\nimport { currentActivity, firstUnreadId, mergeThread, throttle, upsertMessages, type ThreadItem } from \"../core/thread\";\nimport { attachmentKindFor, randomId } from \"../core/media\";\nimport type {\n AvailabilityInput,\n ChatActivity,\n ChatAttachment,\n ChatAvailability,\n ChatLinkPreview,\n ChatMessage,\n ChatSearchHit,\n ChatSignal,\n ChatTopic,\n ScheduleInput,\n ScheduledMessage,\n SendInput,\n TopicInput,\n} from \"../core/types\";\n\nexport const chatKeys = {\n all: [\"genesis-chat\"] as const,\n inbox: (opts?: object) => [\"genesis-chat\", \"inbox\", opts ?? {}] as const,\n unread: () => [\"genesis-chat\", \"unread\"] as const,\n conversation: (id: string) => [\"genesis-chat\", \"conversation\", id] as const,\n members: (id: string) => [\"genesis-chat\", \"members\", id] as const,\n role: (id: string) => [\"genesis-chat\", \"role\", id] as const,\n pins: (id: string) => [\"genesis-chat\", \"pins\", id] as const,\n files: (paths: string[]) => [\"genesis-chat\", \"files\", [...paths].sort()] as const,\n /** Under the conversation's key, so its `conversation` hint (set_topic broadcasts one) refreshes them. */\n topics: (id: string) => [\"genesis-chat\", \"conversation\", id, \"topics\"] as const,\n scheduled: (conversationId?: string | null) => [\"genesis-chat\", \"scheduled\", conversationId ?? null] as const,\n availability: (conversationId: string) => [\"genesis-chat\", \"conversation\", conversationId, \"availability\"] as const,\n myAvailability: () => [\"genesis-chat\", \"my-availability\"] as const,\n search: (query: string, conversationId?: string | null) => [\"genesis-chat\", \"search\", conversationId ?? null, query] as const,\n previews: (messageIds: string[]) => [\"genesis-chat\", \"previews\", [...messageIds].sort()] as const,\n /** One message's link previews (useLinkPreviews keeps one query per message). */\n preview: (messageId: string) => [\"genesis-chat\", \"preview\", messageId] as const,\n};\n\n/** How many messages a catch-up asks for at a time, and how many pages before it gives up and jumps to the newest. */\nexport const CATCH_UP_PAGE = 200;\nexport const CATCH_UP_MAX_PAGES = 10;\n\n/** What a messages list holds in the query cache: the page, and whether older messages exist. */\nexport type MessagesData = MessagePage;\n\nfunction isMessagesData(v: unknown): v is MessagesData {\n return typeof v === \"object\" && v !== null && Array.isArray((v as MessagesData).messages) && \"hasEarlier\" in v;\n}\n\n/** Adds or replaces messages in a cached list, keeping `hasEarlier`. */\nfunction upsertInto(prev: unknown, incoming: ChatMessage[]): MessagesData | undefined {\n return isMessagesData(prev) ? { ...prev, messages: upsertMessages(prev.messages, incoming) } : undefined;\n}\n\n/** Does a messages list (`[genesis-chat, conversation, id, messages, threadRootId, topic]`) hold this message? */\nexport function belongsTo(key: readonly unknown[], m: ChatMessage): boolean {\n return (\n key[0] === \"genesis-chat\" &&\n key[1] === \"conversation\" &&\n key[2] === m.conversationId &&\n key[3] === \"messages\" &&\n (key[4] ?? null) === (m.threadRootId ?? null) &&\n (key[5] == null || key[5] === m.topic)\n );\n}\n\n/**\n * Hosted video uploads (Mux direct uploads): your server makes an upload and returns its URL;\n * the renderer PUTs the recording there and sends `{ kind: \"video\", provider: \"mux\", providerId,\n * status: \"pending\" }`. Without it, videos go to storage as files.\n */\nexport interface ChatVideoUpload {\n create(conversationId: string): Promise<{ url: string; providerId: string; provider: \"mux\" }>;\n}\n\n/** What an app attachment kind's card shows (a form, a check-in): plain data, drawn by each renderer. */\nexport interface ChatAttachmentKind {\n title(attachment: ChatAttachment): string;\n subtitle?(attachment: ChatAttachment): string | null | undefined;\n /** The card's button: a link (`href`) or a handler (`onPress`). */\n action?(attachment: ChatAttachment): { label: string; href?: string; onPress?: () => void } | null | undefined;\n}\n\ninterface ChatContextValue {\n client: ChatClient;\n userId: string;\n outbox: Outbox;\n queue: QueuedMessage[];\n loadPeople?: (userIds: string[]) => Promise<Record<string, ChatPerson>>;\n videoUpload?: ChatVideoUpload;\n attachmentKinds?: Record<string, ChatAttachmentKind>;\n /** Retries every failed message (call it when the connection comes back: AppState, NetInfo). */\n retryAll(): Promise<void>;\n /** Forgets every unsent message, here and in the outbox store (call it on sign-out). */\n clearOutbox(): Promise<void>;\n /** Subscribe to inbox hints (one channel for the app, fanned out here). */\n onInbox(listener: (s: ChatSignal) => void): () => void;\n}\n\nconst ChatContext = createContext<ChatContextValue | null>(null);\n\nexport interface ChatProviderProps {\n client: ChatClient;\n /** The signed-in user's id (auth.users). */\n userId: string;\n /** Where unsent messages wait between launches (localStorage, MMKV…). Memory by default. */\n outboxStore?: OutboxStore;\n /** Reads a native file URI for upload. */\n readFile?: (uri: string) => Promise<Blob | ArrayBuffer>;\n /** Replaces the plain upload (resumable uploads on native). `signal` aborts when the message is discarded or the outbox cleared. */\n upload?: (conversationId: string, file: LocalFile, opts?: { signal?: AbortSignal }) => Promise<string>;\n /** Makes client ids (default: a random UUID that works without crypto.randomUUID). */\n newId?: () => string;\n /** Keeps a byte file (a pasted image, a recording) across launches: write it, return a URI. */\n persistFile?: (file: LocalFile) => Promise<string>;\n /** Lets go of a sent file's preview (default: revokes `blob:` object URLs only). */\n releasePreview?: (url: string) => void;\n /** Names and avatars for user ids, fetched in batches (usePeople, usePerson). */\n loadPeople?: (userIds: string[]) => Promise<Record<string, ChatPerson>>;\n /** Hosted video uploads (Mux); videos go to storage without it. */\n videoUpload?: ChatVideoUpload;\n /** Cards for your own attachment kinds (`{ form: { title, subtitle, action } }`). */\n attachmentKinds?: Record<string, ChatAttachmentKind>;\n children: ReactNode;\n}\n\n/** How the app shows a person. */\nexport interface ChatPerson {\n name: string;\n avatarUrl?: string | null;\n}\n\n/** Puts chat in reach of every hook below it. Needs a TanStack QueryClientProvider above it. */\nexport function ChatProvider({\n client,\n userId,\n outboxStore,\n readFile,\n upload,\n newId,\n persistFile,\n releasePreview,\n loadPeople,\n videoUpload,\n attachmentKinds,\n children,\n}: ChatProviderProps) {\n const queryClient = useQueryClient();\n const [queue, setQueue] = useState<QueuedMessage[]>([]);\n const listeners = useRef(new Set<(s: ChatSignal) => void>());\n\n const outbox = useMemo(\n () =>\n createOutbox({\n client,\n userId,\n store: outboxStore,\n readFile,\n upload,\n newId,\n persistFile,\n releasePreview,\n onChange: setQueue,\n onSent: (message) => {\n // Into every loaded list it belongs to (the main timeline, its thread, its topic), so\n // the bubble never disappears between the send landing and the live hint.\n queryClient.setQueriesData<MessagesData>(\n { predicate: (q) => belongsTo(q.queryKey, message) },\n (prev) => upsertInto(prev, [message]) ?? prev,\n );\n void queryClient.invalidateQueries({ queryKey: [\"genesis-chat\", \"scheduled\"] });\n void queryClient.invalidateQueries({ queryKey: [\"genesis-chat\", \"inbox\"] });\n },\n }),\n // A new person or client is a new outbox.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [client, userId],\n );\n\n useEffect(() => {\n // What a relaunch left unsent is retried once (messages waiting for a lost file stay put),\n // and again whenever the browser comes back online.\n void outbox.load().then(() => outbox.retryAll()).catch(() => undefined);\n const online = () => void outbox.retryAll().catch(() => undefined);\n const target = typeof window !== \"undefined\" && typeof window.addEventListener === \"function\" ? window : null;\n target?.addEventListener(\"online\", online);\n const sub = client.subscribeInbox(userId, (signal) => {\n void queryClient.invalidateQueries({ queryKey: [\"genesis-chat\", \"inbox\"] });\n void queryClient.invalidateQueries({ queryKey: chatKeys.unread() });\n for (const l of listeners.current) l(signal);\n });\n return () => {\n sub.unsubscribe();\n target?.removeEventListener(\"online\", online);\n };\n }, [client, userId, outbox, queryClient]);\n\n const value = useMemo<ChatContextValue>(\n () => ({\n client,\n userId,\n outbox,\n queue,\n loadPeople,\n videoUpload,\n attachmentKinds,\n retryAll: () => outbox.retryAll(),\n clearOutbox: () => outbox.clear(),\n onInbox: (l) => {\n listeners.current.add(l);\n return () => listeners.current.delete(l);\n },\n }),\n [client, userId, outbox, queue, loadPeople, videoUpload, attachmentKinds],\n );\n return <ChatContext.Provider value={value}>{children}</ChatContext.Provider>;\n}\n\nexport function useChat(): ChatContextValue {\n const ctx = useContext(ChatContext);\n if (!ctx) throw new Error(\"Chat hooks need a <ChatProvider> above them.\");\n return ctx;\n}\n\n/** Your conversations, live. `kind` narrows to one kind; `archived` shows the archived ones. */\nexport function useInbox(opts: { kind?: string; kinds?: string[]; excludeKinds?: string[]; archived?: boolean; limit?: number } = {}) {\n const { client } = useChat();\n const query = useQuery({ queryKey: chatKeys.inbox(opts), queryFn: () => client.inbox(opts), staleTime: 15_000 });\n return { items: query.data ?? [], isLoading: query.isLoading, error: query.error, refetch: query.refetch };\n}\n\n/** How many messages wait for you everywhere (for a badge), live. */\nexport function useUnreadTotal(opts: { excludeKinds?: string[] } = {}): number {\n const { client } = useChat();\n return (\n useQuery({ queryKey: [...chatKeys.unread(), opts.excludeKinds ?? []], queryFn: () => client.unreadTotal(opts), staleTime: 15_000 }).data ??\n 0\n );\n}\n\nexport interface UseConversationOptions {\n /** Mark messages read as they arrive while this is true (the thread is on screen). Default true. */\n markRead?: boolean;\n /** One thread's replies instead of the main timeline. */\n threadRootId?: string;\n /** One topic's messages. */\n topic?: string;\n pageSize?: number;\n}\n\n/** One conversation: its messages (with what you are still sending), members, your role, and who is typing. */\nexport function useConversation(conversationId: string | null | undefined, opts: UseConversationOptions = {}) {\n const { client, userId, outbox, queue } = useChat();\n const queryClient = useQueryClient();\n const id = conversationId ?? \"\";\n const enabled = Boolean(conversationId);\n const pageSize = opts.pageSize ?? 50;\n const messagesKey = useMemo(\n () => [...chatKeys.conversation(id), \"messages\", opts.threadRootId ?? null, opts.topic ?? null] as const,\n [id, opts.threadRootId, opts.topic],\n );\n\n const conversation = useQuery({ queryKey: chatKeys.conversation(id), queryFn: () => client.conversation(id), enabled });\n const members = useQuery({ queryKey: chatKeys.members(id), queryFn: () => client.members(id), enabled, staleTime: 60_000, refetchOnMount: \"always\" });\n const kindRules = useQuery({\n queryKey: [\"genesis-chat\", \"kind\", conversation.data?.kind ?? \"\"],\n queryFn: () => client.kind(conversation.data!.kind),\n enabled: Boolean(conversation.data?.kind),\n staleTime: 10 * 60_000,\n });\n const access = useQuery({\n queryKey: chatKeys.role(id),\n queryFn: async () => ({ role: await client.myRole(id), canPost: await client.canPost(id) }),\n enabled,\n staleTime: 60_000,\n });\n\n const [loadingEarlier, setLoadingEarlier] = useState(false);\n const fetchPage = useCallback(\n () => client.messages(id, { limit: pageSize, threadRootId: opts.threadRootId, topic: opts.topic }),\n [client, id, pageSize, opts.threadRootId, opts.topic],\n );\n // Kept fresh by live hints and the catch-up on every join, so never refetched on its own.\n const messages = useQuery<MessagesData>({ queryKey: messagesKey, queryFn: fetchPage, enabled, staleTime: Infinity });\n const hasEarlier = messages.data?.hasEarlier ?? false;\n // Where \"New\" goes: what you had read when the conversation opened.\n const [readWhenOpened, setReadWhenOpened] = useState<number | null>(null);\n\n const merge = useCallback(\n (incoming: ChatMessage[], hasEarlierNow?: boolean) =>\n queryClient.setQueryData<MessagesData>(messagesKey, (prev) => {\n const base = prev ?? { messages: [], hasEarlier: false };\n return { messages: upsertMessages(base.messages, incoming), hasEarlier: hasEarlierNow ?? base.hasEarlier };\n }),\n [queryClient, messagesKey],\n );\n\n /**\n * Fetches what came after the newest message held (everything, for an empty list). Runs on\n * every join of the live channel, the first included, so messages that arrived while the\n * thread was closed, or between the first fetch and the subscription, always show. Pages\n * until a short one; after CATCH_UP_MAX_PAGES full pages (a long time away from a busy group)\n * it shows the newest page instead, with the rest behind \"load earlier\".\n */\n const catchUp = useCallback(async () => {\n const current = queryClient.getQueryData<MessagesData>(messagesKey) ?? (await queryClient.ensureQueryData<MessagesData>({ queryKey: messagesKey, queryFn: fetchPage }));\n const list = current.messages;\n let after = list.length ? list[list.length - 1]!.seq : 0;\n for (let pages = 0; ; ) {\n const page = await client.messages(id, { afterSeq: after, limit: CATCH_UP_PAGE, threadRootId: opts.threadRootId, topic: opts.topic });\n if (page.messages.length) merge(page.messages);\n if (page.messages.length < CATCH_UP_PAGE) return;\n after = Math.max(after, ...page.messages.map((m) => m.seq));\n if (++pages >= CATCH_UP_MAX_PAGES) break;\n }\n const newest = await fetchPage();\n queryClient.setQueryData<MessagesData>(messagesKey, { messages: newest.messages, hasEarlier: true });\n }, [client, fetchPage, id, merge, messagesKey, opts.threadRootId, opts.topic, queryClient]);\n\n const [activity, setActivity] = useState<ChatActivity[]>([]);\n const channel = useRef<ConversationChannel | null>(null);\n useEffect(() => {\n if (!enabled) return;\n const fetchOne = async (messageId: string) => {\n const m = await client.message(messageId);\n if (!m) return;\n const belongs = opts.threadRootId ? m.threadRootId === opts.threadRootId : m.threadRootId === null;\n if (belongs && (!opts.topic || m.topic === opts.topic)) merge([m]);\n if (m.threadRootId && !opts.threadRootId) {\n const root = await client.message(m.threadRootId);\n if (root) merge([root]);\n }\n };\n channel.current = client.subscribeConversation(id, userId, {\n onSignal: (s) => {\n if (s.type === \"message\") void fetchOne(s.id);\n else if (s.type === \"reaction\") void fetchOne(s.messageId);\n else if (s.type === \"members\") {\n void queryClient.invalidateQueries({ queryKey: chatKeys.members(id) });\n void queryClient.invalidateQueries({ queryKey: chatKeys.role(id) });\n } else if (s.type === \"conversation\") {\n // The conversation row, its topics and availability (not its messages, kept by hints).\n void queryClient.invalidateQueries({ queryKey: chatKeys.conversation(id), exact: true });\n void queryClient.invalidateQueries({ queryKey: chatKeys.topics(id) });\n void queryClient.invalidateQueries({ queryKey: chatKeys.pins(id) });\n }\n },\n onActivity: (a) => setActivity((prev) => currentActivity([...prev, a])),\n onJoin: () => void catchUp().catch(() => undefined),\n });\n return () => {\n channel.current?.unsubscribe();\n channel.current = null;\n };\n }, [client, enabled, id, userId, merge, catchUp, queryClient, opts.threadRootId, opts.topic]);\n\n // Activity fades after a few seconds without news.\n useEffect(() => {\n if (activity.length === 0) return;\n const t = setTimeout(() => setActivity((prev) => currentActivity(prev)), 2000);\n return () => clearTimeout(t);\n }, [activity]);\n\n const list = useMemo(() => messages.data?.messages ?? [], [messages.data]);\n const latestSeq = list.length ? list[list.length - 1]!.seq : 0;\n // Where \"New\" goes comes from your read place as fetched for this opening, never a cached\n // copy from an earlier visit (which would draw the line above messages already read).\n const myLastRead = members.isFetchedAfterMount ? members.data?.find((m) => m.userId === userId)?.lastReadSeq : undefined;\n useEffect(() => {\n if (readWhenOpened === null && myLastRead !== undefined) setReadWhenOpened(myLastRead);\n }, [myLastRead, readWhenOpened]);\n\n const markRead = useCallback(async () => {\n if (!enabled || latestSeq === 0) return;\n await client.markRead(id, latestSeq);\n void queryClient.invalidateQueries({ queryKey: [\"genesis-chat\", \"inbox\"] });\n void queryClient.invalidateQueries({ queryKey: chatKeys.unread() });\n }, [client, enabled, id, latestSeq, queryClient]);\n\n // Your read place is one number for the whole conversation, so only the whole timeline moves\n // it: a topic (or a thread) shows a slice, and marking up to its newest message would also\n // mark unseen messages in other topics read.\n const shouldMark = opts.markRead !== false && !opts.threadRootId && !opts.topic;\n useEffect(() => {\n if (shouldMark && latestSeq > 0) void markRead().catch(() => undefined);\n }, [shouldMark, latestSeq, markRead]);\n\n const loadEarlier = useCallback(async () => {\n const first = list[0];\n if (!first || loadingEarlier) return;\n setLoadingEarlier(true);\n try {\n const page = await client.messages(id, { beforeSeq: first.seq, limit: pageSize, threadRootId: opts.threadRootId, topic: opts.topic });\n merge(page.messages, page.hasEarlier);\n } finally {\n setLoadingEarlier(false);\n }\n }, [client, id, list, loadingEarlier, merge, opts.threadRootId, opts.topic, pageSize]);\n\n /** Loads earlier messages until the one with this seq is held (a search result, a pinned message). True when it is. */\n const loadUntil = useCallback(\n async (seq: number) => {\n let current = queryClient.getQueryData<MessagesData>(messagesKey);\n for (let guard = 0; guard < 20 && current; guard++) {\n const first = current.messages[0];\n if (!first || first.seq <= seq || !current.hasEarlier) break;\n const page = await client.messages(id, {\n beforeSeq: first.seq,\n limit: Math.min(200, first.seq - seq + 10),\n threadRootId: opts.threadRootId,\n topic: opts.topic,\n });\n merge(page.messages, page.hasEarlier);\n current = queryClient.getQueryData<MessagesData>(messagesKey);\n }\n return Boolean(current?.messages.some((m) => m.seq === seq));\n },\n [client, id, merge, messagesKey, opts.threadRootId, opts.topic, queryClient],\n );\n\n const pending = useMemo(\n () =>\n queue.filter(\n (q) =>\n q.input.conversationId === id &&\n (q.input.threadRootId ?? null) === (opts.threadRootId ?? null) &&\n (!opts.topic || q.input.topic === opts.topic),\n ).map((q) => ({ ...q, files: q.pendingFiles })),\n [queue, id, opts.threadRootId, opts.topic],\n );\n const items: ThreadItem[] = useMemo(() => mergeThread(list, pending), [list, pending]);\n\n const signalTyping = useMemo(() => throttle(() => channel.current?.signal(\"typing\")), []);\n const signalRecording = useMemo(\n () => throttle(() => channel.current?.signal(\"recording-voice\")),\n [],\n );\n const signalRecordingVideo = useMemo(() => throttle(() => channel.current?.signal(\"recording-video\")), []);\n\n /** Sends text and files to this conversation (through the outbox: shown at once, retried safely). */\n const send = useCallback(\n (input: Omit<SendInput, \"conversationId\" | \"clientId\">, files: LocalFile[] = []) =>\n outbox.send({ ...input, conversationId: id, threadRootId: input.threadRootId ?? opts.threadRootId, topic: input.topic ?? opts.topic }, files),\n [outbox, id, opts.threadRootId, opts.topic],\n );\n\n return {\n conversation: conversation.data ?? null,\n members: members.data ?? [],\n role: access.data?.role ?? null,\n canPost: access.data?.canPost ?? false,\n /** Your role and posting rights are still loading: show the composer as waiting, not refused. */\n accessLoading: enabled && access.isLoading,\n /** The conversation itself is still loading (it settles to `null` when you can't see it). */\n conversationLoading: conversation.isLoading,\n /** Your role couldn't be loaded (offline): offer `refetchAccess`, don't say \"can't post\". */\n accessError: access.error ?? null,\n refetchAccess: access.refetch,\n /** The kind's rules (max members, threads, who posts). */\n kind: kindRules.data ?? null,\n /** May you pin here: owners and admins, or anyone in a two-person conversation. */\n canPin:\n access.data?.role === \"owner\" ||\n access.data?.role === \"admin\" ||\n (access.data?.role === \"member\" && kindRules.data?.maxMembers === 2),\n /** Gives a message whose files were lost on a relaunch its files again. */\n reattach: outbox.reattach,\n items,\n messages: list,\n isLoading: messages.isLoading || conversation.isLoading,\n error: messages.error ?? conversation.error,\n hasEarlier,\n loadingEarlier,\n loadEarlier,\n loadUntil,\n /** Where to draw the \"New\" line, from what you had read when it opened. */\n firstUnreadId: readWhenOpened === null ? null : firstUnreadId(list, readWhenOpened, userId),\n activity: currentActivity(activity),\n signalTyping,\n signalRecording,\n /** Tells the others you are recording a video (throttled). */\n signalRecordingVideo,\n markRead,\n send,\n retry: outbox.retry,\n discard: outbox.discard,\n refetch: catchUp,\n };\n}\n\nexport type ConversationState = ReturnType<typeof useConversation>;\n\n/** Edit, delete, react, pin, save and report, refreshing what they change. */\nexport function useMessageActions() {\n const { client } = useChat();\n const queryClient = useQueryClient();\n return useMemo(() => {\n const refresh = async (conversationId: string, messageId: string) => {\n const m = await client.message(messageId);\n queryClient.setQueriesData<MessagesData>({ queryKey: chatKeys.conversation(conversationId) }, (prev) =>\n m ? (upsertInto(prev, [m]) ?? prev) : prev,\n );\n };\n return {\n edit: async (m: ChatMessage, body: string, mentions: string[] = []) => {\n await client.edit(m.id, body, mentions);\n await refresh(m.conversationId, m.id);\n },\n remove: async (m: ChatMessage) => {\n await client.remove(m.id);\n await refresh(m.conversationId, m.id);\n },\n react: async (m: ChatMessage, emoji: string, on: boolean) => {\n await client.react(m.id, emoji, on);\n await refresh(m.conversationId, m.id);\n },\n pin: async (m: ChatMessage, on: boolean) => {\n await client.pin(m.id, on);\n void queryClient.invalidateQueries({ queryKey: chatKeys.pins(m.conversationId) });\n },\n save: (m: ChatMessage, on: boolean, note?: string) => client.save(m.id, on, note),\n report: (m: ChatMessage, reason: \"spam\" | \"harassment\" | \"safety\" | \"other\", note?: string) => client.report(m.id, reason, note),\n };\n }, [client, queryClient]);\n}\n\n/**\n * Names and avatars for these people, from the provider's `loadPeople`, fetched as one\n * batch per set of ids and cached. Unknown ids are left out.\n */\nexport function usePeople(userIds: (string | null | undefined)[]): Record<string, ChatPerson> {\n const { loadPeople } = useChat();\n const ids = useMemo(() => [...new Set(userIds.filter((x): x is string => Boolean(x)))].sort(), [userIds]);\n return (\n useQuery({\n queryKey: [\"genesis-chat\", \"people\", ids],\n queryFn: () => loadPeople!(ids),\n enabled: Boolean(loadPeople) && ids.length > 0,\n staleTime: 5 * 60_000,\n }).data ?? {}\n );\n}\n\n/** One person's name and avatar (see usePeople). */\nexport function usePerson(userId: string | null | undefined): ChatPerson | null {\n const people = usePeople(useMemo(() => [userId], [userId]));\n return userId ? (people[userId] ?? null) : null;\n}\n\n/** The pinned message ids of a conversation. */\nexport function usePins(conversationId: string | null | undefined): string[] {\n const { client } = useChat();\n return (\n useQuery({ queryKey: chatKeys.pins(conversationId ?? \"\"), queryFn: () => client.pins(conversationId!), enabled: Boolean(conversationId) }).data ?? []\n );\n}\n\n/** Signed links for files (cached by the client until shortly before they expire). */\nexport function useFileUrls(paths: (string | null | undefined)[]): Record<string, string> {\n const { client } = useChat();\n const list = useMemo(() => [...new Set(paths.filter((p): p is string => Boolean(p)))], [paths]);\n return (\n useQuery({ queryKey: chatKeys.files(list), queryFn: () => client.fileUrls(list), enabled: list.length > 0, staleTime: 50 * 60_000 }).data ?? {}\n );\n}\n\n/** Starts (or finds again) a conversation, then refreshes the inbox. */\nexport function useStartConversation() {\n const { client } = useChat();\n const queryClient = useQueryClient();\n return useCallback(\n async (kind: string, memberIds: string[], opts?: { title?: string; subjectType?: string; subjectId?: string }) => {\n const id = await client.startConversation(kind, memberIds, opts);\n void queryClient.invalidateQueries({ queryKey: [\"genesis-chat\", \"inbox\"] });\n return id;\n },\n [client, queryClient],\n );\n}\n\n// ── Migration 0002: topics, scheduled send, availability, broadcast, search, previews ──\n\n/**\n * A conversation's topics, live (set_topic's hint refreshes them), and `setTopic` for owners\n * and admins: add one (`setTopic(\"week-1\", { title: \"Week 1\" })`), close or reopen it.\n */\nexport function useTopics(conversationId: string | null | undefined) {\n const { client } = useChat();\n const queryClient = useQueryClient();\n const id = conversationId ?? \"\";\n const query = useQuery({ queryKey: chatKeys.topics(id), queryFn: () => client.topics(id), enabled: Boolean(conversationId), staleTime: 60_000 });\n const setTopic = useCallback(\n async (topic: string, input: TopicInput = {}) => {\n await client.setTopic(id, topic, input);\n await queryClient.invalidateQueries({ queryKey: chatKeys.topics(id) });\n },\n [client, id, queryClient],\n );\n const topics: ChatTopic[] = query.data ?? [];\n return { topics, isLoading: query.isLoading, error: query.error, setTopic, refetch: query.refetch };\n}\n\n/**\n * Your scheduled messages (in one conversation, or all), soonest first, with `schedule` and\n * `cancel`. `schedule` uploads byte files first (`LocalFile.data` a Blob or ArrayBuffer; a\n * native URI goes through the provider's `readFile`), then schedules them with the message.\n */\nexport function useScheduled(conversationId?: string | null, opts: { enabled?: boolean } = {}) {\n const { client, userId } = useChat();\n const queryClient = useQueryClient();\n const query = useQuery({\n queryKey: chatKeys.scheduled(conversationId),\n queryFn: () => client.scheduled(conversationId ?? undefined),\n enabled: opts.enabled ?? true,\n staleTime: 30_000,\n });\n const refresh = useCallback(() => queryClient.invalidateQueries({ queryKey: [\"genesis-chat\", \"scheduled\"] }), [queryClient]);\n const schedule = useCallback(\n async (input: Omit<ScheduleInput, \"clientId\"> & { clientId?: string }, files: LocalFile[] = []) => {\n const attachments = [...(input.attachments ?? [])];\n for (const f of files) {\n if (typeof f.data === \"string\") throw new Error(\"Scheduled files must be bytes (a Blob or ArrayBuffer)\");\n const path = await client.upload(input.conversationId, userId, f.data, { name: f.name, contentType: f.contentType });\n attachments.push({ ...f.meta, kind: f.meta?.kind ?? attachmentKindFor(f.contentType), path, name: f.meta?.name ?? f.name, mime: f.contentType });\n }\n const id = await client.schedule({ ...input, clientId: input.clientId ?? randomId(), attachments });\n await refresh();\n return id;\n },\n [client, refresh, userId],\n );\n const cancel = useCallback(\n async (id: string) => {\n queryClient.setQueriesData<ScheduledMessage[]>({ queryKey: [\"genesis-chat\", \"scheduled\"] }, (prev) => (Array.isArray(prev) ? prev.filter((s) => s.id !== id) : prev));\n try {\n await client.cancelScheduled(id);\n } finally {\n await refresh();\n }\n },\n [client, queryClient, refresh],\n );\n const items: ScheduledMessage[] = query.data ?? [];\n return { items, isLoading: query.isLoading, error: query.error, schedule, cancel, refetch: query.refetch };\n}\n\n/**\n * Availability: yours (`mine`, `setMine`) and, given a conversation, its members' (`members`,\n * `forUser`). Pair with `awayLine` and `isWithinWorkingHours` from the core.\n */\nexport function useAvailability(conversationId?: string | null) {\n const { client, userId } = useChat();\n const queryClient = useQueryClient();\n const mine = useQuery({ queryKey: chatKeys.myAvailability(), queryFn: () => client.myAvailability(), staleTime: 5 * 60_000 });\n const members = useQuery({\n queryKey: chatKeys.availability(conversationId ?? \"\"),\n queryFn: () => client.availabilityFor(conversationId!),\n enabled: Boolean(conversationId),\n staleTime: 5 * 60_000,\n });\n const setMine = useCallback(\n async (input: AvailabilityInput) => {\n await client.setAvailability(input);\n await queryClient.invalidateQueries({ queryKey: chatKeys.myAvailability() });\n await queryClient.invalidateQueries({ predicate: (q) => q.queryKey[0] === \"genesis-chat\" && q.queryKey[3] === \"availability\" });\n },\n [client, queryClient],\n );\n const list: ChatAvailability[] = members.data ?? [];\n const forUser = useCallback((id: string) => list.find((a) => a.userId === id) ?? null, [list]);\n return {\n mine: mine.data ?? null,\n mineLoading: mine.isLoading,\n setMine,\n members: list,\n /** Everyone else's, without yours. */\n others: list.filter((a) => a.userId !== userId),\n forUser,\n isLoading: mine.isLoading || (Boolean(conversationId) && members.isLoading),\n };\n}\n\n/** Sends one message into many conversations (replies come back privately in each). */\nexport function useBroadcast() {\n const { client } = useChat();\n const queryClient = useQueryClient();\n const [sending, setSending] = useState(false);\n const send = useCallback(\n async (conversationIds: string[], body: string, opts: { silent?: boolean; clientId?: string } = {}) => {\n setSending(true);\n try {\n const ids = await client.broadcast(conversationIds, opts.clientId ?? randomId(), body, { silent: opts.silent });\n void queryClient.invalidateQueries({ queryKey: [\"genesis-chat\", \"inbox\"] });\n return ids;\n } finally {\n setSending(false);\n }\n },\n [client, queryClient],\n );\n return { send, sending };\n}\n\n/** The value, once it has stopped changing for `ms`. */\nexport function useDebouncedValue<T>(value: T, ms: number): T {\n const [v, setV] = useState(value);\n useEffect(() => {\n if (ms <= 0) {\n setV(value);\n return;\n }\n const t = setTimeout(() => setV(value), ms);\n return () => clearTimeout(t);\n }, [value, ms]);\n return ms <= 0 ? value : v;\n}\n\n/** Search, debounced (250 ms by default), in one conversation or all of yours. Queries under two characters return nothing. */\nexport function useSearch(query: string, opts: { conversationId?: string | null; debounceMs?: number; limit?: number } = {}) {\n const { client } = useChat();\n const q = useDebouncedValue(query.trim(), opts.debounceMs ?? 250);\n const enabled = q.length >= 2;\n const result = useQuery({\n queryKey: chatKeys.search(q, opts.conversationId),\n queryFn: () => client.search(q, opts.conversationId ?? null, { limit: opts.limit }),\n enabled,\n staleTime: 30_000,\n });\n const hits: ChatSearchHit[] = enabled ? (result.data ?? []) : [];\n return {\n hits,\n /** The query the hits are for. */\n query: q,\n /** Typing, or fetching: results are on their way. */\n isSearching: query.trim() !== q || (enabled && result.isFetching),\n error: result.error,\n };\n}\n\n/** At most this many link-preview reads at once, per client. */\nexport const LINK_PREVIEW_CONCURRENCY = 4;\nconst previewGates = new WeakMap<object, <T>(task: () => Promise<T>) => Promise<T>>();\n\n/** A gate that lets `max` tasks run at once and queues the rest. */\nfunction gate(max: number) {\n let active = 0;\n const waiting: (() => void)[] = [];\n return async <T,>(task: () => Promise<T>): Promise<T> => {\n if (active >= max) await new Promise<void>((r) => waiting.push(r));\n active += 1;\n try {\n return await task();\n } finally {\n active -= 1;\n waiting.shift()?.();\n }\n };\n}\n\n/**\n * Link previews for these messages, by message id, in link order (only those the server has\n * fetched). Pass the messages whose text has links (`extractLinks(body).length > 0`). One query\n * per message, so a new message asks only for its own, and at most LINK_PREVIEW_CONCURRENCY\n * run at once. One with none yet is asked again a few times, since the runner fills them\n * moments after it lands.\n */\nexport function useLinkPreviews(messageIds: (string | null | undefined)[]): Record<string, ChatLinkPreview[]> {\n const { client } = useChat();\n const list = useMemo(() => [...new Set(messageIds.filter((u): u is string => Boolean(u)))].sort(), [messageIds]);\n let run = previewGates.get(client);\n if (!run) {\n run = gate(LINK_PREVIEW_CONCURRENCY);\n previewGates.set(client, run);\n }\n const limited = run;\n const combine = useCallback(\n (results: { data?: ChatLinkPreview[] }[]) => {\n let out: Record<string, ChatLinkPreview[]> | null = null;\n results.forEach((r, i) => {\n if (r.data) (out ??= {})[list[i]!] = r.data;\n });\n return out ?? EMPTY_PREVIEWS;\n },\n [list],\n );\n return useQueries({\n queries: list.map((id) => ({\n queryKey: chatKeys.preview(id),\n queryFn: () => limited(async () => (await client.linkPreviewsFor([id]))[id] ?? []),\n staleTime: 60_000,\n refetchInterval: (q: { state: { data?: ChatLinkPreview[]; dataUpdateCount: number } }) =>\n !q.state.data?.length && q.state.dataUpdateCount < 4 ? 5_000 : false,\n })),\n combine,\n });\n}\nconst EMPTY_PREVIEWS: Record<string, ChatLinkPreview[]> = {};\n\nexport type { ThreadItem, LocalFile, QueuedMessage };\n"]}