@convokitapp/vue-ui 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/components/avatar.ts","../src/utils.ts","../src/components/conversation.ts","../src/composables/use-conversation.ts","../src/conversation-store.ts","../src/components/message-list.ts","../src/components/conversation-list.ts","../src/composables/use-conversation-list.ts","../src/conversation-list-store.ts","../src/theme.ts"],"sourcesContent":["import './styles.css'\n\nexport { createConvoKitUiClient } from './client'\nexport { ConvoKitAvatar } from './components/avatar'\nexport { Conversation, ConversationView, type ConversationProps, type ConversationViewProps } from './components/conversation'\nexport { ConversationList, ConversationListView, type ConversationListProps, type ConversationListViewProps } from './components/conversation-list'\nexport { MessageListView, defaultReadersResolver, type MessageListViewProps } from './components/message-list'\nexport {\n useConversation,\n type ConversationController,\n type UseConversationOptions,\n} from './composables/use-conversation'\nexport {\n useConversationList,\n type ConversationListController,\n type UseConversationListOptions,\n} from './composables/use-conversation-list'\nexport {\n ConvoKitThemeProvider,\n defaultConvoKitTheme,\n useConvoKitTheme,\n type ConvoKitTheme,\n} from './theme'\nexport type {\n BaseViewProps,\n ComposerSlotProps,\n ConversationFilter,\n ConversationItemSlotProps,\n ConversationListState,\n ConversationPageLoader,\n ConversationPageRequest,\n ConversationState,\n ConvoKitAppearanceProps,\n ConvoKitUiClient,\n ConvoKitUiDensity,\n ConvoKitUiPart,\n ErrorSlot,\n ErrorSlotProps,\n MediaSlotProps,\n MessageSlotProps,\n ReadReceiptSlotProps,\n ScrollOptions,\n StateSlot,\n TypingSlotProps,\n} from './types'\nexport {\n applyConversationFilter,\n formatFileSize,\n isConvoKitPendingMessage,\n matchesConversation,\n mergeConversations,\n mergeInboxEntries,\n mergeMessages,\n readerIdsFor,\n} from './utils'\n","import type { ConvoKitClient } from '@convokitapp/sdk'\nimport type { ConvoKitUiClient } from './types'\n\n/** Adapts a connected `@convokitapp/sdk` client to the replaceable UI boundary. */\nexport function createConvoKitUiClient(client: ConvoKitClient): ConvoKitUiClient {\n return {\n get sessionIdentity() { return client.connected ? client.realtime : null },\n onConnectionEvent: (handlers) => client.realtime.onConnectionEvent(handlers),\n onInboxChanged: (handler, onError) => client.realtime.onInboxChanged(client.clientId, {\n onEvent: handler,\n ...(onError ? { onError } : {}),\n }),\n onInboxActivity: (handler, onError) => client.realtime.onInboxActivity(client.clientId, {\n onEvent: handler,\n ...(onError ? { onError } : {}),\n }),\n onMessageDeleted: (conversationId, handler, onError) => client.realtime.onMessageDeleted(conversationId, {\n onEvent: handler,\n ...(onError ? { onError } : {}),\n }),\n get currentUserId() { return client.connected ? client.currentUserId : '' },\n getConversations: (options) => client.getConversations(options),\n listInbox: (options) => client.listInbox(options),\n getConversation: (conversationId) => client.getConversation(conversationId),\n getMessages: (options) => client.getMessages(options),\n getMessage: (id) => client.getMessage(id),\n sendMessage: (input) => client.sendMessage(input),\n markConversationRead: (conversationId, options) => client.markConversationRead(conversationId, options),\n markConversationUnread: (conversationId) => client.markConversationUnread(conversationId),\n clearConversationUnread: (conversationId, options) => client.clearConversationUnread(conversationId, options),\n sendTyping: (input) => client.sendTyping(input),\n onMessage: (conversationId, handler, onError) => client.realtime.onMessage(conversationId, {\n onEvent: handler,\n ...(onError ? { onError } : {}),\n }),\n onReadReceipt: (conversationId, handler, onError) => client.realtime.onReadReceipt(conversationId, {\n onEvent: handler,\n ...(onError ? { onError } : {}),\n }),\n onTyping: (conversationId, handler, onError) => client.realtime.onTyping(conversationId, {\n onEvent: handler,\n ...(onError ? { onError } : {}),\n }),\n }\n}\n","import { AvatarFallback, AvatarImage, AvatarRoot } from 'reka-ui'\nimport { defineComponent, h, type PropType } from 'vue'\nimport { cx, initials } from '../utils'\n\n/** Accessible avatar built on Reka UI, the primitive layer used by shadcn-vue. */\nexport const ConvoKitAvatar = defineComponent({\n name: 'ConvoKitAvatar',\n inheritAttrs: false,\n props: {\n name: { type: String, required: true },\n src: { type: String as PropType<string | null>, default: null },\n },\n setup(props, { attrs }) {\n return () => h(AvatarRoot, {\n ...attrs,\n class: cx('ckui-avatar', attrs.class),\n }, {\n default: () => [\n props.src ? h(AvatarImage, { class: 'ckui-avatar__image', src: props.src, alt: '' }) : null,\n h(AvatarFallback, {\n class: 'ckui-avatar__fallback',\n ...(props.src ? { delayMs: 300 } : {}),\n }, () => initials(props.name)),\n ],\n })\n },\n})\n","import type { Conversation, InboxEntry, InboxSummary, Message, ReadPosition } from '@convokitapp/sdk'\nimport { readThrough } from '@convokitapp/sdk'\nimport { clsx } from 'clsx'\nimport { normalizeClass } from 'vue'\nimport type { CSSProperties } from 'vue'\nimport type { ConversationFilter, ConvoKitAppearanceProps, ConvoKitUiPart } from './types'\n\nconst pendingMessageIdPrefix = 'convokit-pending-'\n\n/** Message cursor order: createdAt, then id by UTF-16 code units (the server's TEXT order for its lowercase UUIDs). */\nexport function compareMessageOrder(left: Pick<Message, 'createdAt' | 'id'>, right: Pick<Message, 'createdAt' | 'id'>): number {\n return left.createdAt.getTime() - right.createdAt.getTime()\n || (left.id < right.id ? -1 : left.id > right.id ? 1 : 0)\n}\n\n/** Whether a message is an optimistic row awaiting server acknowledgement. */\nexport function isConvoKitPendingMessage(message: Message): boolean {\n return message.id.startsWith(pendingMessageIdPrefix)\n}\n\n/** Vue class attributes accept nested arrays/objects, including unknown attrs on Vue 3.4. */\nexport function cx(...values: unknown[]): string { return clsx(values.map(normalizeClass)) }\n\nfunction requestedParticipantIds(filter: ConversationFilter): ReadonlySet<string> {\n const values = filter.participantIds ?? []\n return values instanceof Set ? values : new Set(values)\n}\n\nexport function matchesConversation(conversation: Conversation, filter: ConversationFilter): boolean {\n const query = filter.query?.trim().toLocaleLowerCase() ?? ''\n if (query) {\n const haystack = [\n conversation.id,\n conversation.displayTitle,\n conversation.title ?? '',\n conversation.description ?? '',\n ...conversation.participants.flatMap((participant) => [participant.id, participant.appUserId, participant.name]),\n ].join(' ').toLocaleLowerCase()\n if (!haystack.includes(query)) return false\n }\n const requested = requestedParticipantIds(filter)\n if (requested.size > 0) {\n const available = new Set(conversation.participants.flatMap((participant) => [participant.id, participant.appUserId]))\n const values = [...requested]\n const matches = filter.requireAllParticipants\n ? values.every((id) => available.has(id))\n : values.some((id) => available.has(id))\n if (!matches) return false\n }\n return filter.predicate?.(conversation) ?? true\n}\n\nexport function applyConversationFilter(conversations: readonly Conversation[], filter: ConversationFilter): Conversation[] {\n const result = conversations.filter((conversation) => matchesConversation(conversation, filter))\n if (filter.comparator) result.sort(filter.comparator)\n return result\n}\n\nexport function mergeConversations(current: readonly Conversation[], incoming: readonly Conversation[]): Conversation[] {\n const byId = new Map(current.map((conversation) => [conversation.id, conversation]))\n for (const conversation of incoming) byId.set(conversation.id, conversation)\n return [...byId.values()]\n}\n\n/** Inbox order: newest activity first, ties by id descending in UTF-16 code units (the server's TEXT order). */\nexport function compareInboxOrder(left: InboxEntry, right: InboxEntry): number {\n return right.activityAt.getTime() - left.activityAt.getTime()\n || (left.conversation.id < right.conversation.id ? 1 : left.conversation.id > right.conversation.id ? -1 : 0)\n}\n\n/** Merge inbox pages by conversation ID: a later entry replaces an earlier one (its room moved), and the result is\n * re-ordered by `(activityAt desc, id desc)`. Server order is authoritative within a page; this is the rule applied\n * whenever pages are combined (load more, refresh).\n */\nexport function mergeInboxEntries(current: readonly InboxEntry[], incoming: readonly InboxEntry[]): InboxEntry[] {\n const byId = new Map(current.map((entry) => [entry.conversation.id, entry]))\n for (const entry of incoming) byId.set(entry.conversation.id, entry)\n return [...byId.values()].sort(compareInboxOrder)\n}\n\n/** The default row's one-line preview, or `''` when the row should keep its participants/description line. */\nexport function inboxPreview(conversation: Conversation, summary: InboxSummary | undefined, currentUserId: string | undefined): string {\n const message = summary?.latestMessage\n if (!message) return ''\n const first = message.media[0]\n const body = message.text?.trim() || (!first ? ''\n : first.type === 'image' ? 'Photo'\n : first.type === 'file' ? first.name?.trim() || 'File'\n : first.type === 'location' ? 'Location'\n : first.type === 'contact' ? 'Contact' : '')\n if (!body) return ''\n if (currentUserId !== undefined && message.senderId === currentUserId) return `You: ${body}`\n if (conversation.participants.length > 2) {\n const sender = conversation.participants.find((participant) => participant.appUserId === message.senderId || participant.id === message.senderId)\n const name = sender?.name.trim()\n if (name) return `${name}: ${body}`\n }\n return body\n}\n\n/** Device-zone clock time, shared by message rows and inbox rows. */\nexport function formatMessageTime(date: Date): string {\n return new Intl.DateTimeFormat(undefined, { hour: 'numeric', minute: '2-digit' }).format(date)\n}\n\nexport function mergeMessages(current: readonly Message[], incoming: readonly Message[]): Message[] {\n const byId = new Map(current.map((message) => [message.id, message]))\n for (const message of incoming) byId.set(message.id, message)\n return [...byId.values()].sort((left, right) => {\n const leftPending = isConvoKitPendingMessage(left)\n const rightPending = isConvoKitPendingMessage(right)\n if (leftPending !== rightPending) return leftPending ? 1 : -1\n return compareMessageOrder(left, right)\n })\n}\n\n/** Readers of a message under the unified rule: a user's read position (createdAt, id) wins when present,\n * otherwise the acknowledgement time is compared with createdAt (legacy participants, empty-room acknowledgements).\n * The sender and pending rows never have readers.\n */\nexport function readerIdsFor(\n message: Message,\n readAtByUserId: ReadonlyMap<string, Date>,\n readPositionByUserId: ReadonlyMap<string, ReadPosition> = new Map(),\n): ReadonlySet<string> {\n if (isConvoKitPendingMessage(message)) return new Set()\n const userIds = new Set([...readAtByUserId.keys(), ...readPositionByUserId.keys()])\n return new Set([...userIds].filter((userId) => userId !== message.senderId && readThrough({\n readPosition: readPositionByUserId.get(userId) ?? null, lastReadAt: readAtByUserId.get(userId) ?? null,\n }, message)))\n}\n\nexport function partClass(part: ConvoKitUiPart, appearance: ConvoKitAppearanceProps, defaultClass: string): string {\n return cx(!appearance.unstyled && defaultClass, appearance.classNames?.[part])\n}\n\nexport function partStyle(part: ConvoKitUiPart, appearance: ConvoKitAppearanceProps): CSSProperties | undefined {\n return appearance.styles?.[part]\n}\n\nexport function errorMessage(error: unknown): string { return error instanceof Error ? error.message : String(error) }\n\nexport function formatFileSize(size: number | undefined): string | null {\n if (size === undefined || !Number.isFinite(size) || size < 0) return null\n if (size < 1024) return `${Math.round(size)} B`\n if (size < 1024 * 1024) return `${(size / 1024).toFixed(size < 10 * 1024 ? 1 : 0)} KB`\n return `${(size / (1024 * 1024)).toFixed(size < 10 * 1024 * 1024 ? 1 : 0)} MB`\n}\n\nexport function initials(value: string): string {\n const words = value.trim().split(/\\s+/).filter(Boolean)\n return (words.length > 1 ? `${words[0]?.[0] ?? ''}${words.at(-1)?.[0] ?? ''}` : value[0] ?? '?').toLocaleUpperCase()\n}\n","import type { Conversation as ConversationModel, Message, MessageMedia, ReadPosition } from '@convokitapp/sdk'\nimport { ArrowLeft, LoaderCircle, Paperclip, RefreshCw, Send } from '@lucide/vue'\nimport {\n defineComponent,\n h,\n onBeforeUnmount,\n ref,\n watchEffect,\n type CSSProperties,\n type PropType,\n type TextareaHTMLAttributes,\n type VNodeChild,\n} from 'vue'\nimport type { ConversationController, UseConversationOptions } from '../composables/use-conversation'\nimport { useConversation } from '../composables/use-conversation'\nimport type {\n ComposerSlotProps,\n ConvoKitAppearanceProps,\n ConvoKitUiClient,\n ConvoKitUiDensity,\n ConvoKitUiPart,\n TypingSlotProps,\n} from '../types'\nimport { cx, errorMessage, partClass, partStyle } from '../utils'\nimport { ConvoKitAvatar } from './avatar'\nimport { MessageListView } from './message-list'\n\nexport interface ConversationViewProps extends ConvoKitAppearanceProps {\n conversation: ConversationModel\n messages: readonly Message[]\n currentUserId: string\n onSendMessage: (text: string) => boolean | void | Promise<boolean | void>\n typingUserIds?: ReadonlySet<string>\n readAtByUserId?: ReadonlyMap<string, Date>\n readPositionByUserId?: ReadonlyMap<string, ReadPosition>\n readersResolver?: (message: Message) => ReadonlySet<string>\n onBack?: () => void\n onRefresh?: () => void | Promise<void>\n onLoadOlder?: () => void | Promise<void>\n onTypingChange?: (isTyping: boolean) => void | Promise<void>\n onAddAttachment?: () => void\n onAttachmentClick?: (media: MessageMedia, message: Message) => void\n isInitialLoading?: boolean\n isLoadingOlder?: boolean\n isSending?: boolean\n hasOlderMessages?: boolean\n error?: unknown\n messageError?: unknown\n displayNameForUser?: (userId: string) => string | null | undefined\n reverseMessages?: boolean\n stickToBottom?: boolean\n paginationThreshold?: number\n formatTime?: (date: Date) => string\n imageLoading?: 'eager' | 'lazy'\n composerPlaceholder?: string\n composerAriaLabel?: string\n composerProps?: Omit<TextareaHTMLAttributes, 'value' | 'disabled'>\n modelValue?: string\n defaultDraft?: string\n onDraftChange?: (value: string) => void\n class?: unknown\n style?: unknown\n}\n\nconst appearanceProps = {\n classNames: { type: Object as PropType<Partial<Record<ConvoKitUiPart, string>>>, default: undefined },\n styles: { type: Object as PropType<Partial<Record<ConvoKitUiPart, CSSProperties>>>, default: undefined },\n density: { type: String as PropType<ConvoKitUiDensity>, default: 'comfortable' },\n unstyled: { type: Boolean, default: false },\n} as const\n\nconst viewProps = {\n ...appearanceProps,\n conversation: { type: Object as PropType<ConversationModel>, required: true },\n messages: { type: Array as PropType<readonly Message[]>, required: true },\n currentUserId: { type: String, required: true },\n onSendMessage: { type: Function as PropType<(text: string) => boolean | void | Promise<boolean | void>>, required: true },\n typingUserIds: { type: Object as PropType<ReadonlySet<string>>, default: () => new Set() },\n readAtByUserId: { type: Object as PropType<ReadonlyMap<string, Date>>, default: () => new Map() },\n readPositionByUserId: { type: Object as PropType<ReadonlyMap<string, ReadPosition>>, default: () => new Map() },\n readersResolver: { type: Function as PropType<(message: Message) => ReadonlySet<string>>, default: undefined },\n onBack: { type: Function as PropType<() => void>, default: undefined },\n onRefresh: { type: Function as PropType<() => void | Promise<void>>, default: undefined },\n onLoadOlder: { type: Function as PropType<() => void | Promise<void>>, default: undefined },\n onTypingChange: { type: Function as PropType<(isTyping: boolean) => void | Promise<void>>, default: undefined },\n onAddAttachment: { type: Function as PropType<() => void>, default: undefined },\n onAttachmentClick: { type: Function as PropType<(media: MessageMedia, message: Message) => void>, default: undefined },\n isInitialLoading: { type: Boolean, default: false },\n isLoadingOlder: { type: Boolean, default: false },\n isSending: { type: Boolean, default: false },\n hasOlderMessages: { type: Boolean, default: false },\n error: { type: null as unknown as PropType<unknown>, required: false },\n messageError: { type: null as unknown as PropType<unknown>, required: false },\n displayNameForUser: { type: Function as PropType<(userId: string) => string | null | undefined>, default: undefined },\n reverseMessages: { type: Boolean, default: true },\n stickToBottom: { type: Boolean, default: true },\n paginationThreshold: { type: Number, default: 240 },\n formatTime: { type: Function as PropType<(date: Date) => string>, default: undefined },\n imageLoading: { type: String as PropType<'eager' | 'lazy'>, default: 'lazy' },\n composerPlaceholder: { type: String, default: 'Write a message' },\n composerAriaLabel: { type: String, default: 'Message' },\n composerProps: { type: Object as PropType<Omit<TextareaHTMLAttributes, 'value' | 'disabled'>>, default: undefined },\n modelValue: { type: String, default: undefined },\n defaultDraft: { type: String, default: '' },\n onDraftChange: { type: Function as PropType<(value: string) => void>, default: undefined },\n} as const\n\nfunction typingLabel(userIds: ReadonlySet<string>, displayNameForUser: (userId: string) => string): string {\n const names = [...userIds].map(displayNameForUser)\n if (names.length === 0) return ''\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 `${names[0]} and ${names.length - 1} others are typing…`\n}\n\n/** Controlled, complete selected-conversation surface. */\nexport const ConversationView = defineComponent({\n name: 'ConversationView',\n inheritAttrs: false,\n props: viewProps,\n emits: [\n 'send-message', 'typing-change', 'back', 'refresh', 'load-older',\n 'add-attachment', 'attachment-click', 'update:modelValue',\n ],\n setup(props, { attrs, emit, slots }) {\n const internalDraft = ref(props.defaultDraft)\n const submitting = ref(false)\n const appearance = (): ConvoKitAppearanceProps => ({\n density: props.density,\n unstyled: props.unstyled,\n ...(props.classNames ? { classNames: props.classNames } : {}),\n ...(props.styles ? { styles: props.styles } : {}),\n })\n const draft = () => props.modelValue ?? internalDraft.value\n let latestDraft = draft()\n const setDraft = (value: string) => {\n latestDraft = value\n if (props.modelValue === undefined) internalDraft.value = value\n props.onDraftChange?.(value)\n emit('update:modelValue', value)\n const isTyping = value.trim().length > 0\n void props.onTypingChange?.(isTyping)\n }\n const submit = async () => {\n const originalDraft = draft()\n const text = originalDraft.trim()\n if (!text || props.isSending || submitting.value) return\n submitting.value = true\n setDraft('')\n try {\n const shouldClear = await props.onSendMessage(text)\n if (shouldClear === false && latestDraft.length === 0) setDraft(originalDraft)\n } finally {\n submitting.value = false\n }\n }\n const nameForUser = (userId: string) => {\n const custom = props.displayNameForUser?.(userId)?.trim()\n if (custom) return custom\n const participant = props.conversation.participants.find((value) => value.id === userId || value.appUserId === userId)\n return participant?.name.trim() || userId\n }\n const goBack = () => { props.onBack?.() }\n const refresh = () => props.onRefresh?.()\n const loadOlder = () => props.onLoadOlder?.()\n const addAttachment = () => { props.onAddAttachment?.() }\n\n const renderHeader = (): VNodeChild => {\n const slotProps = {\n conversation: props.conversation,\n ...(props.onBack ? { onBack: goBack } : {}),\n ...(props.onRefresh ? { onRefresh: refresh } : {}),\n }\n return slots.header?.(slotProps) ?? h('header', {\n class: partClass('header', appearance(), 'ckui-conversation-header'),\n style: partStyle('header', appearance()),\n }, [\n props.onBack ? h('button', {\n type: 'button', 'aria-label': 'Back', onClick: goBack,\n class: partClass('button', appearance(), 'ckui-icon-button'),\n style: partStyle('button', appearance()),\n }, [h(ArrowLeft, { size: 20, 'aria-hidden': 'true' })]) : null,\n h(ConvoKitAvatar, { name: props.conversation.displayTitle, src: props.conversation.imageUrl }),\n h('div', { class: 'ckui-conversation-header__body' }, [\n h('strong', props.conversation.displayTitle),\n h('span', `${props.conversation.participants.length} participant${props.conversation.participants.length === 1 ? '' : 's'}`),\n ]),\n props.onRefresh ? h('button', {\n type: 'button', 'aria-label': 'Refresh conversation', onClick: () => { void refresh() },\n class: partClass('button', appearance(), 'ckui-icon-button'),\n style: partStyle('button', appearance()),\n }, [h(RefreshCw, { size: 18, 'aria-hidden': 'true' })]) : null,\n ])\n }\n\n const renderTyping = (): VNodeChild => {\n const slotProps: TypingSlotProps = { userIds: props.typingUserIds, displayNameForUser: nameForUser }\n return slots['typing-indicator']?.(slotProps) ?? h('div', {\n class: partClass('typing', appearance(), 'ckui-typing'),\n style: partStyle('typing', appearance()),\n 'aria-live': 'polite',\n }, typingLabel(props.typingUserIds, nameForUser))\n }\n\n const renderComposer = (): VNodeChild => {\n const slotProps: ComposerSlotProps = {\n value: draft(), setValue: setDraft, isSending: props.isSending || submitting.value,\n send: () => { void submit() },\n ...(props.onAddAttachment ? { addAttachment } : {}),\n }\n return slots.composer?.(slotProps) ?? h('form', {\n class: partClass('composer', appearance(), 'ckui-composer'),\n style: partStyle('composer', appearance()),\n onSubmit: (event: Event) => { event.preventDefault(); void submit() },\n }, [\n props.onAddAttachment ? h('button', {\n type: 'button', 'aria-label': 'Add attachment', onClick: addAttachment,\n class: partClass('button', appearance(), 'ckui-icon-button'),\n style: partStyle('button', appearance()),\n }, [h(Paperclip, { size: 20, 'aria-hidden': 'true' })]) : null,\n h('textarea', {\n ...props.composerProps,\n rows: props.composerProps?.rows ?? 1,\n placeholder: props.composerPlaceholder,\n 'aria-label': props.composerAriaLabel,\n class: cx(!props.unstyled && 'ckui-composer__input', props.classNames?.input, props.composerProps?.class),\n style: [props.styles?.input, props.composerProps?.style],\n value: draft(),\n onInput: (event: InputEvent) => {\n const handler = props.composerProps?.onInput\n if (typeof handler === 'function') handler(event)\n if (!event.defaultPrevented) setDraft((event.currentTarget as HTMLTextAreaElement).value)\n },\n onKeydown: (event: KeyboardEvent) => {\n const handler = props.composerProps?.onKeydown\n if (typeof handler === 'function') handler(event)\n if (event.defaultPrevented) return\n if (event.key === 'Enter' && !event.shiftKey) { event.preventDefault(); void submit() }\n },\n }),\n h('button', {\n type: 'submit', 'aria-label': 'Send message', disabled: !draft().trim() || props.isSending || submitting.value,\n class: partClass('button', appearance(), 'ckui-send-button'),\n style: partStyle('button', appearance()),\n }, [props.isSending || submitting.value\n ? h(LoaderCircle, { class: 'ckui-spin', size: 18, 'aria-hidden': 'true' })\n : h(Send, { size: 18, 'aria-hidden': 'true' })]),\n ])\n }\n\n return () => {\n if (props.isInitialLoading && props.messages.length === 0) {\n return h('div', {\n ...attrs,\n class: cx(!props.unstyled && 'ckui ckui-conversation', props.classNames?.root, attrs.class),\n style: [props.styles?.root, attrs.style],\n 'data-density': props.density,\n }, slots.loading?.() ?? h('div', {\n class: partClass('loading', appearance(), 'ckui-state'), style: partStyle('loading', appearance()), role: 'status',\n }, [h(LoaderCircle, { class: 'ckui-spin', 'aria-hidden': 'true' }), ' Loading conversation…']))\n }\n const children: VNodeChild[] = [renderHeader()]\n if (props.error) {\n const retry = props.onRefresh ? () => { void refresh() } : undefined\n children.push(slots.error?.({ error: props.error, ...(retry ? { retry } : {}) }) ?? h('div', {\n class: partClass('error', appearance(), 'ckui-conversation-error'),\n style: partStyle('error', appearance()), role: 'alert',\n }, [h('span', errorMessage(props.error)), retry ? h('button', { type: 'button', class: 'ckui-link-button', onClick: retry }, 'Retry') : null]))\n }\n const messageSlots = {\n ...(slots.message ? { message: slots.message } : {}),\n ...(slots.media ? { media: slots.media } : {}),\n ...(slots['read-receipt'] ? { 'read-receipt': slots['read-receipt'] } : {}),\n ...(slots.empty ? { empty: slots.empty } : {}),\n ...(slots['loading-older'] ? { 'loading-older': slots['loading-older'] } : {}),\n ...(slots['message-error'] ? { error: slots['message-error'] } : {}),\n }\n children.push(h(MessageListView, {\n conversation: props.conversation,\n messages: props.messages,\n currentUserId: props.currentUserId,\n readAtByUserId: props.readAtByUserId,\n readPositionByUserId: props.readPositionByUserId,\n ...(props.readersResolver ? { readersResolver: props.readersResolver } : {}),\n ...(props.onLoadOlder ? { onLoadOlder: loadOlder } : {}),\n hasOlderMessages: props.hasOlderMessages,\n isLoadingOlder: props.isLoadingOlder,\n ...(props.messageError == null ? {} : { error: props.messageError }),\n ...(props.onAttachmentClick ? { onAttachmentClick: (media: MessageMedia, message: Message) => {\n props.onAttachmentClick?.(media, message)\n } } : {}),\n reverse: props.reverseMessages,\n stickToBottom: props.stickToBottom,\n paginationThreshold: props.paginationThreshold,\n ...(props.formatTime ? { formatTime: props.formatTime } : {}),\n imageLoading: props.imageLoading,\n ...(props.classNames ? { classNames: props.classNames } : {}),\n ...(props.styles ? { styles: props.styles } : {}),\n density: props.density,\n unstyled: props.unstyled,\n }, messageSlots))\n children.push(renderTyping(), renderComposer())\n return h('section', {\n ...attrs,\n class: cx(!props.unstyled && 'ckui ckui-conversation', props.classNames?.root, attrs.class),\n style: [props.styles?.root, attrs.style],\n 'data-density': props.density,\n 'aria-label': props.conversation.displayTitle,\n }, children)\n }\n },\n})\n\nexport interface ConversationProps extends Omit<ConversationViewProps,\n 'conversation' | 'messages' | 'currentUserId' | 'onSendMessage' | 'typingUserIds' |\n 'readAtByUserId' | 'readPositionByUserId' | 'onRefresh' | 'onLoadOlder' | 'onTypingChange' |\n 'isInitialLoading' | 'isLoadingOlder' | 'isSending' | 'hasOlderMessages' | 'error'>,\n Omit<UseConversationOptions, 'client' | 'conversationId'> {\n client: ConvoKitUiClient\n conversationId: string\n onControllerChange?: (controller: ConversationController) => void\n}\n\n/** Plug-and-play SDK-backed UI for one conversation. */\nexport const Conversation = defineComponent({\n name: 'Conversation',\n inheritAttrs: false,\n props: {\n ...viewProps,\n conversation: { type: Object as PropType<ConversationModel>, default: undefined },\n messages: { type: Array as PropType<readonly Message[]>, default: () => [] },\n currentUserId: { type: String, default: '' },\n onSendMessage: { type: Function as PropType<(text: string) => boolean | void | Promise<boolean | void>>, default: undefined },\n client: { type: Object as PropType<ConvoKitUiClient>, required: true },\n conversationId: { type: String, required: true },\n messagePageSize: { type: Number, default: 30 },\n markReadOnLoad: { type: Boolean, default: true },\n markReadOnReceive: { type: Boolean, default: true },\n typingTimeoutMs: { type: Number, default: 3000 },\n autoLoad: { type: Boolean, default: true },\n onControllerChange: { type: Function as PropType<(controller: ConversationController) => void>, default: undefined },\n },\n emits: ['controller-change', 'send-message', 'typing-change', 'back', 'refresh', 'load-older', 'add-attachment', 'attachment-click', 'update:modelValue'],\n setup(props, { attrs, emit, expose, slots }) {\n const controller = useConversation({\n client: () => props.client,\n conversationId: () => props.conversationId,\n messagePageSize: props.messagePageSize,\n markReadOnLoad: props.markReadOnLoad,\n markReadOnReceive: props.markReadOnReceive,\n typingTimeoutMs: props.typingTimeoutMs,\n autoLoad: props.autoLoad,\n })\n expose({ controller })\n watchEffect(() => {\n emit('controller-change', controller)\n })\n // Automatic acknowledgements only while the document is visible; prerender/unknown/no document count as visible.\n if (typeof document !== 'undefined') {\n const syncVisibility = () => controller.setVisible(document.visibilityState !== 'hidden')\n syncVisibility()\n document.addEventListener('visibilitychange', syncVisibility)\n onBeforeUnmount(() => document.removeEventListener('visibilitychange', syncVisibility))\n }\n return () => {\n const loadedConversation = controller.conversation.value\n if (!loadedConversation) {\n const retry = () => { void controller.refresh() }\n return h('div', {\n ...attrs,\n class: cx(!props.unstyled && 'ckui ckui-conversation', props.classNames?.root, attrs.class),\n style: [props.styles?.root, attrs.style],\n 'data-density': props.density,\n }, controller.error.value\n ? slots.error?.({ error: controller.error.value, retry }) ?? h('div', { class: 'ckui-state ckui-state--error', role: 'alert' }, [\n h('span', errorMessage(controller.error.value)),\n h('button', { type: 'button', class: 'ckui-link-button', onClick: retry }, 'Try again'),\n ])\n : slots.loading?.() ?? h('div', { class: 'ckui-state', role: 'status' }, [\n h(LoaderCircle, { class: 'ckui-spin', 'aria-hidden': 'true' }), ' Loading conversation…',\n ]))\n }\n const {\n client: _client,\n conversationId: _conversationId,\n messagePageSize: _messagePageSize,\n markReadOnLoad: _markReadOnLoad,\n markReadOnReceive: _markReadOnReceive,\n typingTimeoutMs: _typingTimeoutMs,\n autoLoad: _autoLoad,\n onControllerChange: _onControllerChange,\n conversation: _conversation,\n messages: _messages,\n currentUserId: _currentUserId,\n onSendMessage: _onSendMessage,\n typingUserIds: _typingUserIds,\n readAtByUserId: _readAtByUserId,\n readPositionByUserId: _readPositionByUserId,\n onRefresh: _onRefresh,\n onLoadOlder: _onLoadOlder,\n onTypingChange: _onTypingChange,\n isInitialLoading: _isInitialLoading,\n isLoadingOlder: _isLoadingOlder,\n isSending: _isSending,\n hasOlderMessages: _hasOlderMessages,\n error: _error,\n ...forwarded\n } = props\n return h(ConversationView, {\n ...attrs,\n ...forwarded,\n conversation: loadedConversation,\n messages: controller.messages.value,\n currentUserId: controller.currentUserId.value,\n onSendMessage: async (text: string) => {\n emit('send-message', text)\n return (await controller.sendMessage({ text })) !== null\n },\n typingUserIds: controller.typingUserIds.value,\n readAtByUserId: controller.readAtByUserId.value,\n readPositionByUserId: controller.readPositionByUserId.value,\n onRefresh: controller.refresh,\n onLoadOlder: controller.loadOlderMessages,\n onTypingChange: controller.updateTyping,\n isInitialLoading: controller.isInitialLoading.value,\n isLoadingOlder: controller.isLoadingOlder.value,\n isSending: controller.isSending.value,\n hasOlderMessages: controller.hasOlderMessages.value,\n ...(controller.error.value == null ? {} : { error: controller.error.value }),\n 'onUpdate:modelValue': (value: string) => emit('update:modelValue', value),\n ...(props.onBack ? { onBack: () => { props.onBack?.(); emit('back') } } : {}),\n ...(props.onAddAttachment ? { onAddAttachment: () => { props.onAddAttachment?.(); emit('add-attachment') } } : {}),\n ...(props.onAttachmentClick ? { onAttachmentClick: (media: MessageMedia, message: Message) => {\n props.onAttachmentClick?.(media, message)\n emit('attachment-click', media, message)\n } } : {}),\n } as never, slots)\n }\n },\n})\n","import type { Message, MessageMedia } from '@convokitapp/sdk'\nimport { computed, getCurrentScope, onScopeDispose, shallowRef, toValue, watch, type MaybeRefOrGetter } from 'vue'\nimport type { ConversationState, ConvoKitUiClient } from '../types'\nimport { ConversationStore, type ConversationSnapshot } from '../conversation-store'\n\nexport interface UseConversationOptions {\n client: MaybeRefOrGetter<ConvoKitUiClient>\n conversationId: MaybeRefOrGetter<string>\n messagePageSize?: number\n markReadOnLoad?: boolean\n markReadOnReceive?: boolean\n typingTimeoutMs?: number\n autoLoad?: boolean\n}\nexport interface ConversationController extends ConversationState {\n loadInitial(): Promise<void>\n refresh(): Promise<void>\n loadOlderMessages(): Promise<void>\n sendMessage(input: { text?: string; media?: MessageMedia[] }): Promise<Message | null>\n /** Acknowledge through the newest rendered message now; no request is sent while nothing is rendered. */\n markRead(): Promise<void>\n /** Automatic acknowledgements pause while hidden and resume when the view becomes visible again. */\n setVisible(visible: boolean): void\n updateTyping(isTyping: boolean): Promise<void>\n dispose(): Promise<void>\n}\n\n/** Each room/login gets an independent owner; disposal also stops reactive reloads. */\nexport function useConversation(options: UseConversationOptions): ConversationController {\n const createStore = () => new ConversationStore({\n ...options, client: toValue(options.client), conversationId: toValue(options.conversationId),\n })\n let store = createStore()\n const snapshot = shallowRef(store.getSnapshot())\n let unsubscribe: (() => void) | undefined\n let visible = true\n const stop = watch(\n () => [toValue(options.client), toValue(options.client).sessionIdentity, toValue(options.conversationId)] as const,\n () => {\n store.dispose()\n unsubscribe?.()\n store = createStore()\n snapshot.value = store.getSnapshot()\n unsubscribe = store.subscribe(() => { snapshot.value = store.getSnapshot() })\n store.setVisible(visible)\n store.start(options.autoLoad ?? true)\n },\n { immediate: true, flush: 'sync' },\n )\n const field = <K extends keyof ConversationSnapshot>(key: K) => computed(() => snapshot.value[key])\n const dispose = async () => {\n stop()\n store.dispose()\n unsubscribe?.()\n unsubscribe = undefined\n }\n if (getCurrentScope()) onScopeDispose(() => { void dispose() })\n return {\n conversation: field('conversation'), messages: field('messages'),\n typingUserIds: field('typingUserIds'), readAtByUserId: field('readAtByUserId'),\n readPositionByUserId: field('readPositionByUserId'),\n isInitialLoading: field('isInitialLoading'), isLoadingOlder: field('isLoadingOlder'),\n isReconciling: field('isReconciling'), isSending: field('isSending'),\n hasOlderMessages: field('hasOlderMessages'), hasLoaded: field('hasLoaded'),\n error: field('error'), currentUserId: field('currentUserId'),\n readerIdsFor: (message) => store.readerIdsFor(message),\n loadInitial: () => store.loadInitial(), refresh: () => store.refresh(),\n loadOlderMessages: () => store.loadOlderMessages(), sendMessage: (input) => store.sendMessage(input),\n markRead: () => store.markRead(), updateTyping: (isTyping) => store.updateTyping(isTyping),\n setVisible: (value) => { visible = value; store.setVisible(value) },\n dispose,\n }\n}\n","import type { Conversation, Message, MessageEvent, MessageMedia, Participant, ReadPosition, RealtimeSubscription } from '@convokitapp/sdk'\nimport { createClientMessageId } from '@convokitapp/sdk'\nimport type { ConvoKitUiClient } from './ui-client'\nimport { compareMessageOrder, isConvoKitPendingMessage, mergeMessages, readerIdsFor } from './utils'\n\nexport interface ConversationSnapshot {\n conversation: Conversation | null\n messages: Message[]\n typingUserIds: ReadonlySet<string>\n /** Last acknowledgement time per user; kept for custom renderers. */\n readAtByUserId: ReadonlyMap<string, Date>\n /** Monotonic read-through position per user; wins over `readAtByUserId` where present. */\n readPositionByUserId: ReadonlyMap<string, ReadPosition>\n isInitialLoading: boolean\n isLoadingOlder: boolean\n isReconciling: boolean\n isSending: boolean\n hasOlderMessages: boolean\n hasLoaded: boolean\n error: unknown\n currentUserId: string\n}\n\ninterface Options {\n client: ConvoKitUiClient\n conversationId: string\n messagePageSize?: number\n markReadOnLoad?: boolean\n markReadOnReceive?: boolean\n typingTimeoutMs?: number\n}\n\ntype Cursor = Pick<Message, 'createdAt' | 'id'>\ntype Change = { revision: number; message: Message; insert: boolean; complete: boolean }\ntype Hydration = { revision: number; generation: number; message: Message; insert: boolean }\ntype HydrationPool = { running: Set<string>; queued: Map<string, Hydration> }\ntype ReadEntry = { userId: string; readAt: Date | null; readPosition: ReadPosition | null | undefined }\n/** One acknowledgement pipeline per load: a single request in flight, one boolean follow-up resolved at send time. */\ntype Acknowledgement = {\n inFlight: Promise<void> | undefined\n followUp: boolean\n /** An automatic acknowledgement was wanted while hidden or before this open's DTO (and so its version) was in\n * hand; re-issued once the view becomes visible or the open captures.\n */\n suppressed: boolean\n /** Target of the request in flight. */\n target: string | undefined\n /** Last target the server accepted; older or equal targets are never re-sent. */\n acknowledged: Cursor | undefined\n /** Targets the server does not know (or that were removed): never targeted again. */\n unacknowledgeable: Set<string>\n}\n/** The caller's private state captured once per open, the first time `conversation` goes from null to a DTO.\n * `version` stays undefined until then and for a DTO without `membership` (0.6 backend: acknowledgements send no\n * version); `clearPending` is set when the opened membership carried an unread marker and consumed by the single\n * empty-room clear of that open.\n */\ntype Capture = { version: number | undefined; clearPending: boolean }\n\nfunction version(message: Message): number { return message.updatedAt?.getTime() ?? message.createdAt.getTime() }\nfunction hasContent(message: Message): boolean { return !!message.text?.trim() || message.media.length > 0 }\nfunction newest(current: Message, incoming: Message, incomingComplete = true): Message {\n return version(current) > version(incoming) || (!incomingComplete && version(current) === version(incoming)) ? current : incoming\n}\n\nconst compare = compareMessageOrder\nfunction positionCursor(position: ReadPosition): Cursor { return { createdAt: position.createdAt, id: position.messageId } }\nfunction readEntry(participant: Participant): ReadEntry {\n return { userId: participant.appUserId, readAt: participant.lastReadAt, readPosition: participant.readPosition }\n}\nfunction acknowledgement(): Acknowledgement {\n return { inFlight: undefined, followUp: false, suppressed: false, target: undefined, acknowledged: undefined, unacknowledgeable: new Set() }\n}\nfunction capture(conversation?: Conversation): Capture {\n const membership = conversation?.membership\n return { version: membership?.privateStateVersion, clearPending: membership?.unreadMarkedAt != null }\n}\n/** A targeted read the server rejected because the target is unknown to it (deleted or foreign). Membership\n * failures carry no `MESSAGE_NOT_FOUND` code (the core SDK reports `HTTP_ERROR`), so they remain errors; a\n * bare 404 counts as a miss only for adapters that expose no code at all.\n */\nfunction isTargetMiss(cause: unknown): boolean {\n if (typeof cause !== 'object' || cause === null) return false\n const { code, status } = cause as { code?: unknown; status?: unknown }\n return code === 'MESSAGE_NOT_FOUND' || (code === undefined && status === 404)\n}\n\nfunction blank(currentUserId = ''): ConversationSnapshot {\n return {\n conversation: null, messages: [], typingUserIds: new Set(), readAtByUserId: new Map(), readPositionByUserId: new Map(),\n isInitialLoading: false, isLoadingOlder: false, isReconciling: false, isSending: false,\n hasOlderMessages: true, hasLoaded: false, error: null, currentUserId,\n }\n}\n\n/** Internal, framework-independent room lifecycle. Never shared across client sessions. */\nexport class ConversationStore {\n private readonly client: ConvoKitUiClient\n private readonly room: string\n private readonly owner: object | null\n private readonly user: string\n private readonly pageSize: number\n private readonly typingTimeout: number\n private state: ConversationSnapshot\n private listeners = new Set<() => void>()\n private subscriptions: RealtimeSubscription[] = []\n private disposed = true\n private generation = 0\n private cursor: Cursor | undefined\n private revision = 0\n private changes = new Map<string, Change>()\n private hydrations = new Map<string, Hydration>()\n private hydrationPool: HydrationPool = { running: new Set(), queued: new Map() }\n // Keep tombstones until an explicit reload/session change, including across refreshes.\n private deleted = new Set<string>()\n private ack = acknowledgement()\n private captured = capture()\n // Visible until the platform reports otherwise; unknown/prerender/no document count as visible.\n private visible = true\n private sendRevision: number | undefined\n private activeSend: { pending: Message; confirmed?: Message } | undefined\n private refreshQueued = false\n private typingTimers = new Map<string, ReturnType<typeof setTimeout>>()\n private ownTypingTimer: ReturnType<typeof setTimeout> | undefined\n private sentTyping = false\n private typingRevision = 0\n private lastTypingSentAt = -Infinity\n\n constructor(private readonly options: Options) {\n this.client = options.client\n this.room = options.conversationId.trim()\n this.pageSize = options.messagePageSize ?? 30\n this.typingTimeout = options.typingTimeoutMs ?? 3000\n if (!this.room) throw new TypeError('conversationId is required')\n if (!Number.isInteger(this.pageSize) || this.pageSize < 1 || this.pageSize > 100) {\n throw new RangeError('messagePageSize must be an integer between 1 and 100')\n }\n if (!Number.isFinite(this.typingTimeout) || this.typingTimeout < 0) {\n throw new RangeError('typingTimeoutMs must be non-negative')\n }\n this.owner = this.client.sessionIdentity\n this.user = this.owner ? this.client.currentUserId : ''\n this.state = blank(this.user)\n }\n\n getSnapshot = (): ConversationSnapshot => this.state\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener)\n return () => { this.listeners.delete(listener) }\n }\n private patch(patch: Partial<ConversationSnapshot>): void {\n if (patch.messages && this.activeSend) {\n for (const message of patch.messages) this.confirmSend(message)\n if (this.activeSend.confirmed) patch.messages = patch.messages.filter(message => message.id !== this.activeSend!.pending.id)\n }\n this.state = { ...this.state, ...patch }\n for (const listener of this.listeners) listener()\n }\n private alive(generation = this.generation): boolean {\n return !this.disposed && generation === this.generation\n && this.owner !== null && this.client.sessionIdentity === this.owner\n }\n\n start = (autoLoad = true): void => {\n if (this.owner === null || this.client.sessionIdentity !== this.owner) return\n this.disposed = false\n this.patch({ currentUserId: this.user })\n if (autoLoad) void this.loadInitial()\n else {\n try { this.attach(this.generation, false) } catch { /* attach reports adapter failures */ }\n }\n }\n\n private detach(): void {\n const active = this.subscriptions\n this.subscriptions = []\n for (const subscription of active) void subscription.unsubscribe().catch(() => undefined)\n }\n\n private clearTyping(): void {\n for (const timer of this.typingTimers.values()) clearTimeout(timer)\n this.typingTimers.clear()\n clearTimeout(this.ownTypingTimer)\n this.ownTypingTimer = undefined\n this.sentTyping = false\n this.typingRevision++\n this.lastTypingSentAt = -Infinity\n this.patch({ typingUserIds: new Set() })\n }\n\n private clear(): void {\n this.generation++\n this.detach()\n this.clearTyping()\n this.cursor = undefined\n this.changes.clear()\n this.hydrations.clear()\n this.hydrationPool.queued.clear()\n // In-flight adapter promises cannot be aborted through this interface.\n // Keep their slots across reloads so repeated loads cannot exceed the cap.\n this.deleted.clear()\n // A retired pipeline's response settles against the old generation and is ignored.\n this.ack = acknowledgement()\n // Every open captures the caller's private state afresh; nothing captured survives `conversation` going null.\n this.captured = capture()\n this.sendRevision = undefined\n this.activeSend = undefined\n this.refreshQueued = false\n }\n\n dispose = (): void => {\n // A retired session must never send a typing update using a replacement login.\n if (this.alive() && this.sentTyping) {\n void this.client.sendTyping({ conversationId: this.room, isTyping: false }).catch(() => undefined)\n }\n this.disposed = true\n this.clear()\n this.patch(blank())\n }\n\n private fail(cause: unknown, generation: number, history = false): void {\n if (!this.alive(generation)) return\n const status = typeof cause === 'object' && cause !== null && 'status' in cause ? cause.status : undefined\n if (history && (status === 401 || status === 403 || status === 404)) {\n this.clear()\n this.patch({ ...blank(this.user), error: cause, hasLoaded: true, hasOlderMessages: false })\n } else this.patch({ error: cause })\n }\n\n private attach(generation: number, data = true): void {\n const report = (cause: Error) => this.fail(cause, generation)\n const add = (create: () => RealtimeSubscription) => {\n if (!this.alive(generation)) return\n const subscription = create()\n if (this.alive(generation)) this.subscriptions.push(subscription)\n else void subscription.unsubscribe().catch(() => undefined)\n }\n try {\n // Install lifecycle ownership before providers can synchronously report a join.\n add(() => this.client.onConnectionEvent({\n onEvent: ({ topic, status }) => {\n if (!data || !this.alive(generation) || (topic !== `messages:${this.room}` && topic !== `conversation:${this.room}`)) return\n if (status === 'SUBSCRIBED') this.queueRefresh()\n else this.clearTyping()\n },\n onSessionEnded: () => {\n if (this.disposed || generation !== this.generation) return\n this.dispose()\n },\n onError: report,\n }))\n if (!data) return\n add(() => this.client.onInboxChanged(() => {\n if (this.alive(generation)) this.queueRefresh()\n }, cause => {\n if (this.alive(generation)) { report(cause); this.queueRefresh() }\n }))\n add(() => this.client.onMessage(this.room, (event) => this.onMessage(event, generation), report))\n add(() => this.client.onMessageDeleted(this.room, ({ id, conversationId }) => {\n if (!this.alive(generation) || conversationId !== this.room || !id.trim()) return\n this.removeMessage(id)\n }, report))\n add(() => this.client.onReadReceipt(this.room, ({ userId, readAt, readPosition }) => {\n if (this.alive(generation)) this.mergeReads([{ userId, readAt, readPosition }])\n }, report))\n add(() => this.client.onTyping(this.room, ({ userId, isTyping }) => {\n if (!this.alive(generation) || !userId.trim() || userId === this.user) return\n clearTimeout(this.typingTimers.get(userId))\n this.typingTimers.delete(userId)\n const next = new Set(this.state.typingUserIds)\n if (isTyping) {\n next.add(userId)\n this.typingTimers.set(userId, setTimeout(() => {\n this.typingTimers.delete(userId)\n if (!this.alive(generation)) return\n const remaining = new Set(this.state.typingUserIds)\n remaining.delete(userId)\n this.patch({ typingUserIds: remaining })\n }, this.typingTimeout))\n } else next.delete(userId)\n this.patch({ typingUserIds: next })\n }, report))\n } catch (cause) {\n this.detach()\n this.fail(cause, generation)\n throw cause\n }\n }\n\n private validMessage(message: Message): boolean {\n return message.conversationId === this.room && !!message.id.trim()\n && !!message.senderId.trim() && !isConvoKitPendingMessage(message)\n && Number.isFinite(message.createdAt.getTime()) && Number.isFinite(version(message))\n }\n\n private onMessage(event: MessageEvent, generation: number): void {\n const { message, type } = event\n if (!this.alive(generation) || (type !== 'insert' && type !== 'update')\n || !this.validMessage(message) || this.deleted.has(message.id)) return\n const existing = this.state.messages.find((item) => item.id === message.id)\n const known = existing ?? this.changes.get(message.id)?.message\n if (known && version(message) < version(known)) return\n const insert = type === 'insert' || this.changes.get(message.id)?.insert === true\n if (!existing && !insert && type === 'update' && !this.state.isInitialLoading && !this.state.isLoadingOlder && !this.state.isReconciling) return\n const revision = ++this.revision\n // A raw Message row has no related Media; absence is not authoritative removal.\n const provisional = existing && !message.media.length ? { ...message, media: existing.media } : message\n this.record(provisional, insert, revision, false)\n const job: Hydration = { revision, generation, message, insert }\n this.hydrations.set(message.id, job)\n this.hydrationPool.queued.set(message.id, job)\n this.drainHydration()\n }\n\n private record(message: Message, insert: boolean, revision: number, complete: boolean): void {\n const existing = this.state.messages.find((item) => item.id === message.id)\n if (existing && version(existing) > version(message)) return\n // The exact server-echoed send ID also confirms media-only rows before hydration.\n // Keep that send's local media until the complete authorized response arrives.\n if (this.confirmSend(message) && !complete && !message.media.length) {\n message = { ...message, media: this.activeSend!.pending.media }\n this.confirmSend(message)\n }\n this.changes.set(message.id, { revision, message, insert, complete })\n if (!existing && !(insert && hasContent(message))) return\n this.patch({ messages: mergeMessages(this.state.messages, [message]) })\n // A foreign row entering the rendered list is the receive trigger, so a withheld\n // media-only row is acknowledged once its hydration renders it, never before.\n if (!existing && message.senderId !== this.user && (this.options.markReadOnReceive ?? true)) void this.acknowledge(true)\n }\n\n private confirmSend(message: Message): boolean {\n const send = this.activeSend\n if (!send || !this.validMessage(message) || message.senderId !== this.user\n || message.clientMessageId !== send.pending.clientMessageId) return false\n send.confirmed = send.confirmed ? newest(send.confirmed, message) : message\n return true\n }\n\n private currentHydration(job: Hydration): boolean {\n return this.alive(job.generation) && !this.deleted.has(job.message.id) && this.hydrations.get(job.message.id) === job\n }\n\n private removeMessage(id: string): void {\n this.forget(id)\n this.patch({ messages: this.state.messages.filter((message) => message.id !== id) })\n }\n\n /** Tombstone a row learned to be gone; a removed acknowledgement target is re-resolved from what remains. */\n private forget(id: string): void {\n this.deleted.add(id)\n this.changes.delete(id)\n this.hydrations.delete(id)\n this.hydrationPool.queued.delete(id)\n const ack = this.ack\n if (ack.target !== id && ack.acknowledged?.id !== id) return\n ack.unacknowledgeable.add(id)\n if (ack.target === id) ack.followUp = true\n }\n\n private drainHydration(): void {\n const pool = this.hydrationPool\n for (const [id, job] of pool.queued) {\n if (pool.running.size >= 8) break\n if (pool.running.has(id)) continue\n pool.queued.delete(id)\n if (!this.currentHydration(job)) continue\n pool.running.add(id)\n void this.hydrate(job, pool)\n }\n }\n\n private async hydrate(job: Hydration, pool: HydrationPool): Promise<void> {\n const id = job.message.id\n try {\n if (!this.currentHydration(job)) return\n const full = await this.client.getMessage(id)\n if (!this.currentHydration(job)) return\n if (!this.validMessage(full) || full.id !== id || full.senderId !== job.message.senderId || version(full) < version(job.message)) {\n throw new Error('Complete message response does not match the observed resource/revision')\n }\n // Completion is not a fresh change: a later snapshot outranks the originating event.\n this.record(full, job.insert, job.revision, true)\n } catch (cause) {\n if (!this.currentHydration(job)) return\n const status = typeof cause === 'object' && cause !== null && 'status' in cause ? cause.status : undefined\n if (status === 404) this.removeMessage(id)\n this.fail(cause, job.generation)\n this.queueRefresh()\n } finally {\n if (this.hydrations.get(id) === job) this.hydrations.delete(id)\n pool.running.delete(id)\n queueMicrotask(() => { if (this.hydrationPool === pool) this.drainHydration() })\n }\n }\n\n /** Both maps only ever advance: acknowledgement times by time, positions by (createdAt, id). Participants and\n * read events are the only sources; the local user's own read is never written from the device clock.\n */\n private mergeReads(entries: Iterable<ReadEntry>): void {\n const readAt = new Map(this.state.readAtByUserId)\n const positions = new Map(this.state.readPositionByUserId)\n for (const entry of entries) {\n const { userId, readPosition } = entry\n if (!userId.trim()) continue\n if (entry.readAt && Number.isFinite(entry.readAt.getTime()) && entry.readAt.getTime() > (readAt.get(userId)?.getTime() ?? -Infinity)) {\n readAt.set(userId, entry.readAt)\n }\n if (!readPosition || typeof readPosition.messageId !== 'string' || !readPosition.messageId.trim()\n || !(readPosition.createdAt instanceof Date) || !Number.isFinite(readPosition.createdAt.getTime())) continue\n const current = positions.get(userId)\n if (!current || compare(positionCursor(readPosition), positionCursor(current)) > 0) positions.set(userId, readPosition)\n }\n this.patch({ readAtByUserId: readAt, readPositionByUserId: positions })\n }\n\n private validatePage(page: Message[], before?: Cursor): void {\n if (page.length > this.pageSize) throw new Error('Message page exceeds the requested limit')\n let previous = before\n for (const message of page) {\n if (!this.validMessage(message) || (previous && compare(message, previous) >= 0)) {\n throw new Error('Message history must contain distinct, room-scoped rows in newest-first cursor order')\n }\n previous = message\n }\n }\n\n private fetchPage(before?: Cursor): Promise<Message[]> {\n return this.client.getMessages({\n conversationId: this.room, limit: this.pageSize,\n ...(before ? { beforeCreatedAt: before.createdAt, beforeId: before.id } : {}),\n })\n }\n\n private overlay(rows: Message[], revision: number): Message[] {\n const byId = new Map(rows.filter((message) => !this.deleted.has(message.id)).map((message) => [message.id, message]))\n for (const [id, change] of this.changes) {\n if (change.revision > revision && !this.deleted.has(id) && (change.insert || byId.has(id))) {\n const current = byId.get(id)\n if (current || change.complete || hasContent(change.message)) {\n byId.set(id, current ? newest(current, change.message, change.complete) : change.message)\n }\n }\n }\n for (const message of this.state.messages) {\n if (isConvoKitPendingMessage(message)) byId.set(message.id, message)\n }\n return mergeMessages([], [...byId.values()])\n }\n\n private prune(revision: number): void {\n const safeRevision = Math.min(revision, this.sendRevision ?? Infinity)\n for (const [id, change] of this.changes) if (change.revision <= safeRevision) this.changes.delete(id)\n for (const [id, job] of this.hydrations) if (job.revision <= revision) {\n this.hydrations.delete(id)\n this.hydrationPool.queued.delete(id)\n }\n }\n\n loadInitial = async (): Promise<void> => {\n if (!this.alive()) return\n this.clear()\n const generation = this.generation\n this.patch({ ...blank(this.user), isInitialLoading: true })\n const revision = this.revision\n try {\n this.attach(generation)\n if (!this.alive(generation)) return\n const [conversation, page] = await Promise.all([this.client.getConversation(this.room), this.fetchPage()])\n if (!this.alive(generation)) return\n if (conversation.id !== this.room) throw new Error('Conversation response belongs to a different room')\n this.validatePage(page)\n this.cursor = page.at(-1)\n this.patch({ conversation, messages: this.overlay(page, revision), hasOlderMessages: page.length === this.pageSize })\n // The DTO is in hand before this open's first acknowledgement: capture its private state now.\n this.captured = capture(conversation)\n this.mergeReads(conversation.participants.map(readEntry))\n this.prune(revision)\n // The load acknowledgement also covers an automatic one that waited for the DTO (a row inserted during the load).\n if ((this.options.markReadOnLoad ?? true) || this.ack.suppressed) {\n this.ack.suppressed = false\n await this.acknowledge(true)\n }\n } catch (cause) {\n this.fail(cause, generation, true)\n } finally {\n if (this.alive(generation)) {\n this.patch({ isInitialLoading: false, hasLoaded: true })\n this.flushRefresh()\n }\n }\n }\n\n private queueRefresh(): void {\n this.refreshQueued = true\n this.flushRefresh()\n }\n private flushRefresh(): void {\n const generation = this.generation\n void Promise.resolve().then(() => {\n if (!this.alive(generation) || !this.refreshQueued || this.state.isInitialLoading\n || this.state.isLoadingOlder || this.state.isReconciling) return\n this.refreshQueued = false\n void this.refresh()\n })\n }\n\n /** Re-fetch the entire viewed range atomically; a first-page-only refresh loses history. */\n refresh = async (): Promise<void> => {\n if (!this.alive()) return\n if (this.state.isInitialLoading || this.state.isLoadingOlder || this.state.isReconciling) {\n this.refreshQueued = true\n return\n }\n if (!this.state.hasLoaded || !this.subscriptions.length) return this.loadInitial()\n const generation = this.generation\n const revision = this.revision\n const observed = this.state.messages.filter((message) => !isConvoKitPendingMessage(message))\n .concat([...this.changes.values()].filter((change) => change.insert).map((change) => change.message))\n const boundary = observed.reduce<Cursor | undefined>((oldest, message) =>\n !oldest || compare(message, oldest) < 0 ? message : oldest, this.cursor)\n const previouslyExhausted = !this.state.hasOlderMessages\n this.patch({ isReconciling: true, error: null })\n try {\n const conversation = await this.client.getConversation(this.room)\n if (!this.alive(generation)) return\n if (conversation.id !== this.room) throw new Error('Conversation response belongs to a different room')\n const rows: Message[] = []\n let before: Cursor | undefined\n let hasOlder = true\n while (this.alive(generation)) {\n const page = await this.fetchPage(before)\n if (!this.alive(generation)) return\n this.validatePage(page, before)\n rows.push(...page)\n before = page.at(-1) ?? before\n hasOlder = page.length === this.pageSize\n // An empty previous view has no history range to recover: keep its first\n // returning page bounded even if many messages arrived while offline.\n if (!hasOlder || !boundary || (!previouslyExhausted && before && compare(before, boundary) < 0)) break\n }\n this.cursor = before\n const reconciled = this.overlay(rows, revision)\n const survivingIds = new Set(reconciled.map((message) => message.id))\n const known = this.state.messages.filter((message) => !isConvoKitPendingMessage(message)).map((message) => message.id)\n .concat([...this.changes].filter(([, change]) => change.insert && change.revision <= revision).map(([id]) => id))\n // A missed deletion learned from the full viewed range also defeats late acks/replays.\n for (const id of known) if (!survivingIds.has(id)) this.forget(id)\n // A reconcile after a transient first-load failure is this open's first DTO; replacing one never recaptures.\n const opening = this.state.conversation === null\n this.patch({ conversation, messages: reconciled, hasOlderMessages: hasOlder })\n if (opening) this.captured = capture(conversation)\n this.mergeReads(conversation.participants.map(readEntry))\n this.prune(revision)\n // Rows received while the DTO was missing waited for its version; this open's first DTO issues them.\n if (opening) void this.resumeAcknowledgement()\n } catch (cause) {\n this.fail(cause, generation, true)\n } finally {\n if (this.alive(generation)) {\n this.patch({ isReconciling: false })\n this.flushRefresh()\n }\n }\n }\n\n loadOlderMessages = async (): Promise<void> => {\n if (!this.alive() || !this.state.hasLoaded || this.state.isInitialLoading || this.state.isLoadingOlder\n || this.state.isReconciling || !this.state.hasOlderMessages) return\n const generation = this.generation\n const revision = this.revision\n const cursor = this.cursor\n this.patch({ isLoadingOlder: true, error: null })\n try {\n const page = await this.fetchPage(cursor)\n if (!this.alive(generation)) return\n this.validatePage(page, cursor)\n this.cursor = page.at(-1) ?? cursor\n // Existing live edits always win over an older-page duplicate.\n this.patch({\n messages: this.overlay(mergeMessages(page, this.state.messages), revision),\n hasOlderMessages: page.length === this.pageSize,\n })\n } catch (cause) {\n this.fail(cause, generation, true)\n } finally {\n if (this.alive(generation)) {\n this.patch({ isLoadingOlder: false })\n this.flushRefresh()\n }\n }\n }\n\n /** Acknowledge through the newest rendered row now, regardless of visibility; no acknowledgement without a\n * target (a room opened with a marker that renders nothing clears the marker instead, once).\n */\n markRead = (): Promise<void> => this.alive() ? this.acknowledge(false) : Promise.resolve()\n\n /** Automatic acknowledgements wait while hidden and are re-issued (once) on becoming visible. */\n setVisible = (visible: boolean): void => {\n this.visible = visible\n if (!visible || !this.alive()) return\n void this.resumeAcknowledgement()\n }\n\n /** Re-issue (once) the automatic acknowledgement that waited while hidden or before this open's DTO, if any. */\n private resumeAcknowledgement(): Promise<void> {\n if (!this.ack.suppressed) return Promise.resolve()\n this.ack.suppressed = false\n return this.acknowledge(true)\n }\n\n /** The newest non-pending rendered row by (createdAt, id), never by list index and never a raw realtime\n * row; rows the server does not know are skipped, and nothing at or before the accepted target is re-sent.\n */\n private ackTarget(ack: Acknowledgement): Cursor | undefined {\n let target: Cursor | undefined\n for (const message of this.state.messages) {\n if (isConvoKitPendingMessage(message) || ack.unacknowledgeable.has(message.id)) continue\n if (!target || compare(message, target) > 0) target = { createdAt: message.createdAt, id: message.id }\n }\n return target && (!ack.acknowledged || compare(target, ack.acknowledged) > 0) ? target : undefined\n }\n\n /** Resolves when the request this call issued or joined settles; a follow-up is issued, not awaited. */\n private acknowledge(automatic: boolean): Promise<void> {\n const ack = this.ack\n // Before this open's DTO is in hand there is no captured version to send: a row inserted during the load (or\n // while a transient first-load failure stands) waits for the capture, like it waits while hidden.\n if (automatic && (!this.visible || this.state.conversation === null)) {\n ack.suppressed = true\n return Promise.resolve()\n }\n if (ack.inFlight) {\n ack.followUp = true\n return ack.inFlight\n }\n return this.issue(ack, this.generation) ?? Promise.resolve()\n }\n\n private issue(ack: Acknowledgement, generation: number): Promise<void> | undefined {\n ack.followUp = false\n const target = this.ackTarget(ack)\n // An empty marked room clears its marker in the acknowledgement's slot; nothing else is sent without a target.\n const request = target ? this.send(ack, generation, target) : this.clearMarker(ack, generation)\n if (!request) return undefined\n ack.target = target?.id\n ack.inFlight = request.finally(() => {\n ack.inFlight = undefined\n ack.target = undefined\n if (!this.alive(generation) || !ack.followUp) return\n if (!this.visible) {\n ack.followUp = false\n ack.suppressed = true\n } else this.issue(ack, generation)\n })\n return ack.inFlight\n }\n\n /** A room opened with the caller's unread marker that renders no non-pending, acknowledgeable row cannot clear\n * it through a targeted acknowledgement, so it asks the adapter to clear the marker conditionally on the captured\n * version, once per open, under the acknowledgement triggers and visibility gating. Rows rendered later clear it\n * through their acknowledgements; adapters without the member leave it; `cleared: false` is not an error.\n */\n private clearMarker(ack: Acknowledgement, generation: number): Promise<void> | undefined {\n const captured = this.captured\n if (!captured.clearPending || captured.version === undefined || typeof this.client.clearConversationUnread !== 'function'\n || this.state.messages.some((message) => !isConvoKitPendingMessage(message) && !ack.unacknowledgeable.has(message.id))) return undefined\n captured.clearPending = false\n return this.clearUnread(captured.version, generation)\n }\n\n private async clearUnread(version: number, generation: number): Promise<void> {\n try {\n await this.client.clearConversationUnread!(this.room, { ifVersion: version })\n } catch (cause) {\n if (this.alive(generation)) this.fail(cause, generation)\n }\n }\n\n private async send(ack: Acknowledgement, generation: number, target: Cursor): Promise<void> {\n try {\n // Every targeted acknowledgement of this open carries the version captured when it opened (none on 0.6).\n const version = this.captured.version\n await this.client.markConversationRead(this.room, {\n throughMessageId: target.id, ...(version === undefined ? {} : { privateStateVersion: version }),\n })\n if (!this.alive(generation)) return\n // Only persisted participant positions / server read events advance receipts.\n if (!ack.acknowledged || compare(target, ack.acknowledged) > 0) ack.acknowledged = target\n } catch (cause) {\n if (!this.alive(generation)) return\n if (isTargetMiss(cause)) {\n // The server does not know this target (deleted meanwhile): re-issue once with the next newest row.\n ack.unacknowledgeable.add(target.id)\n ack.followUp = true\n } else this.fail(cause, generation)\n }\n }\n\n updateTyping = async (isTyping: boolean): Promise<void> => {\n if (!this.alive()) return\n const generation = this.generation\n clearTimeout(this.ownTypingTimer)\n if (isTyping) this.ownTypingTimer = setTimeout(() => {\n if (this.alive(generation)) void this.updateTyping(false)\n }, this.typingTimeout)\n const now = performance.now()\n // Renew while keystrokes continue, so the receiver's expiry does not hide\n // someone who is still typing. Idle input never generates a keepalive.\n const renew = isTyping && now - this.lastTypingSentAt >= Math.max(1, this.typingTimeout / 2)\n if (this.sentTyping === isTyping && !renew) return\n const revision = ++this.typingRevision\n this.sentTyping = isTyping\n this.lastTypingSentAt = isTyping ? now : -Infinity\n try {\n await this.client.sendTyping({ conversationId: this.room, isTyping })\n } catch (cause) {\n if (this.alive(generation) && revision === this.typingRevision) {\n this.sentTyping = false\n this.fail(cause, generation)\n }\n }\n }\n\n sendMessage = async ({ text, media }: { text?: string; media?: MessageMedia[] }): Promise<Message | null> => {\n const normalized = text?.trim()\n if (!this.alive() || this.state.isSending || (!normalized && !media?.length)) return null\n const generation = this.generation\n const revision = this.revision\n this.sendRevision = revision\n const clientMessageId = createClientMessageId()\n const pendingId = `convokit-pending-${clientMessageId}`\n const pending: Message = {\n id: pendingId, clientMessageId, conversationId: this.room, senderId: this.user, text: normalized || null,\n media: media ?? [], createdAt: new Date(), updatedAt: null,\n }\n const send = { pending } as { pending: Message; confirmed?: Message }\n this.activeSend = send\n this.patch({ messages: mergeMessages(this.state.messages, [pending]), isSending: true, error: null })\n try {\n const message = await this.client.sendMessage({\n conversationId: this.room, clientMessageId, ...(normalized ? { text: normalized } : {}), ...(media?.length ? { media } : {}),\n })\n if (!this.alive(generation)) return null\n if (!this.validMessage(message) || message.senderId !== this.user) throw new Error('Send response belongs to a different room or sender')\n if (message.clientMessageId && message.clientMessageId !== clientMessageId) throw new Error('Send response belongs to a different send')\n const live = this.changes.get(message.id)\n const existing = this.state.messages.find((item) => item.id === message.id)\n let latest = existing ? newest(message, existing, live?.complete !== false) : message\n if (live && live.revision > revision) latest = newest(latest, live.message, live.complete)\n if (!this.deleted.has(message.id)) this.changes.set(message.id, { revision: ++this.revision, message: latest, insert: true, complete: true })\n this.patch({ messages: mergeMessages(\n this.state.messages.filter((item) => item.id !== pendingId),\n this.deleted.has(message.id) ? [] : [latest],\n ) })\n void this.updateTyping(false)\n return this.alive(generation) ? latest : null\n } catch (cause) {\n if (this.alive(generation)) {\n this.patch({ messages: this.state.messages.filter((item) => item.id !== pendingId) })\n // A live/history confirmation is authoritative even if its HTTP acknowledgement was lost.\n // Returning success clears the composer; deleted confirmations are never reinserted.\n if (send.confirmed) {\n void this.updateTyping(false)\n return send.confirmed\n }\n this.fail(cause, generation)\n }\n return null\n } finally {\n if (this.alive(generation)) {\n this.sendRevision = undefined\n this.activeSend = undefined\n this.patch({ isSending: false })\n }\n }\n }\n\n readerIdsFor = (message: Message): ReadonlySet<string> =>\n readerIdsFor(message, this.state.readAtByUserId, this.state.readPositionByUserId)\n}\n","import type { Conversation, Message, MessageMedia, ReadPosition } from '@convokitapp/sdk'\nimport {\n Check,\n CheckCheck,\n ContactRound,\n Download,\n FileText,\n ImageOff,\n LoaderCircle,\n MapPin,\n MessageCircle,\n} from '@lucide/vue'\nimport {\n computed,\n defineComponent,\n h,\n nextTick,\n ref,\n watch,\n type CSSProperties,\n type PropType,\n type Ref,\n type VNodeChild,\n} from 'vue'\nimport type {\n ConvoKitAppearanceProps,\n ConvoKitUiDensity,\n ConvoKitUiPart,\n MediaSlotProps,\n MessageSlotProps,\n ReadReceiptSlotProps,\n} from '../types'\nimport { cx, errorMessage, formatFileSize, formatMessageTime, isConvoKitPendingMessage, partClass, partStyle, readerIdsFor } from '../utils'\n\nexport interface MessageListViewProps extends ConvoKitAppearanceProps {\n conversation: Conversation\n messages: readonly Message[]\n currentUserId: string\n /** Acknowledgement times; the fallback for users without a read position. */\n readAtByUserId?: ReadonlyMap<string, Date>\n /** Read-through positions; a user's position decides their receipts whenever one is present. */\n readPositionByUserId?: ReadonlyMap<string, ReadPosition>\n readersResolver?: (message: Message) => ReadonlySet<string>\n onLoadOlder?: () => void | Promise<void>\n hasOlderMessages?: boolean\n isLoadingOlder?: boolean\n error?: unknown\n onAttachmentClick?: (media: MessageMedia, message: Message) => void\n scrollElement?: Ref<HTMLElement | null>\n paginationThreshold?: number\n reverse?: boolean\n stickToBottom?: boolean\n formatTime?: (date: Date) => string\n imageLoading?: 'eager' | 'lazy'\n class?: unknown\n style?: unknown\n}\n\nconst appearanceProps = {\n classNames: { type: Object as PropType<Partial<Record<ConvoKitUiPart, string>>>, default: undefined },\n styles: { type: Object as PropType<Partial<Record<ConvoKitUiPart, CSSProperties>>>, default: undefined },\n density: { type: String as PropType<ConvoKitUiDensity>, default: 'comfortable' },\n unstyled: { type: Boolean, default: false },\n} as const\n\nfunction defaultMedia(\n media: MessageMedia,\n open: (() => void) | undefined,\n imageLoading: 'eager' | 'lazy',\n): VNodeChild {\n const tag = open ? 'button' : 'div'\n const interactive = open ? { type: 'button', onClick: open } : {}\n if (media.type === 'image') {\n return h(tag, { ...interactive, class: 'ckui-media-card ckui-media-card--image' }, [\n media.url\n ? h('img', { src: media.url, alt: media.name ?? 'Shared image', loading: imageLoading })\n : h('span', { class: 'ckui-media-placeholder' }, [h(ImageOff, { 'aria-hidden': 'true' }), ' Image unavailable']),\n media.name ? h('span', { class: 'ckui-media-name' }, media.name) : null,\n ])\n }\n if (media.type === 'file') {\n const size = formatFileSize(media.size)\n return h(tag, { ...interactive, class: 'ckui-media-card ckui-media-card--file' }, [\n h(FileText, { 'aria-hidden': 'true' }),\n h('span', [h('strong', media.name || 'Attachment'), size ? h('small', size) : null]),\n open ? h(Download, { size: 18, 'aria-hidden': 'true' }) : null,\n ])\n }\n if (media.type === 'location') {\n const label = media.name || `${media.metadata.lat}, ${media.metadata.lng}`\n return h(tag, { ...interactive, class: 'ckui-media-card ckui-media-card--location' }, [\n h(MapPin, { 'aria-hidden': 'true' }),\n h('span', [h('strong', label), h('small', `${media.metadata.lat}, ${media.metadata.lng}`)]),\n ])\n }\n const contact = media.metadata.email || media.metadata.phone || 'Contact details'\n return h(tag, { ...interactive, class: 'ckui-media-card ckui-media-card--contact' }, [\n h(ContactRound, { 'aria-hidden': 'true' }),\n h('span', [h('strong', media.name || 'Shared contact'), h('small', String(contact))]),\n ])\n}\n\n/** Controlled message history with read receipts, structured media, and older-page loading. */\nexport const MessageListView = defineComponent({\n name: 'MessageListView',\n inheritAttrs: false,\n props: {\n ...appearanceProps,\n conversation: { type: Object as PropType<Conversation>, required: true },\n messages: { type: Array as PropType<readonly Message[]>, required: true },\n currentUserId: { type: String, required: true },\n readAtByUserId: { type: Object as PropType<ReadonlyMap<string, Date>>, default: () => new Map() },\n readPositionByUserId: { type: Object as PropType<ReadonlyMap<string, ReadPosition>>, default: () => new Map() },\n readersResolver: { type: Function as PropType<(message: Message) => ReadonlySet<string>>, default: undefined },\n onLoadOlder: { type: Function as PropType<() => void | Promise<void>>, default: undefined },\n hasOlderMessages: { type: Boolean, default: false },\n isLoadingOlder: { type: Boolean, default: false },\n error: { type: null as unknown as PropType<unknown>, required: false },\n onAttachmentClick: { type: Function as PropType<(media: MessageMedia, message: Message) => void>, default: undefined },\n scrollElement: { type: Object as PropType<Ref<HTMLElement | null>>, default: undefined },\n paginationThreshold: { type: Number, default: 240 },\n reverse: { type: Boolean, default: true },\n stickToBottom: { type: Boolean, default: true },\n formatTime: { type: Function as PropType<(date: Date) => string>, default: formatMessageTime },\n imageLoading: { type: String as PropType<'eager' | 'lazy'>, default: 'lazy' },\n },\n emits: ['load-older', 'attachment-click'],\n setup(props, { attrs, emit, slots }) {\n const internalElement = ref<HTMLElement | null>(null)\n let requestInFlight = false\n let lastRequestedLength: number | null = null\n let previousMessageCount = 0\n const participants = computed(() => new Map(props.conversation.participants.flatMap((participant) => [\n [participant.id, participant] as const,\n [participant.appUserId, participant] as const,\n ])))\n const appearance = (): ConvoKitAppearanceProps => ({\n density: props.density,\n unstyled: props.unstyled,\n ...(props.classNames ? { classNames: props.classNames } : {}),\n ...(props.styles ? { styles: props.styles } : {}),\n })\n\n const requestOlder = async () => {\n if (requestInFlight || lastRequestedLength === props.messages.length || props.isLoadingOlder || !props.hasOlderMessages || !props.onLoadOlder) return\n requestInFlight = true\n lastRequestedLength = props.messages.length\n try { await props.onLoadOlder() }\n catch { lastRequestedLength = null }\n finally { requestInFlight = false }\n }\n\n watch(() => [props.messages.length, props.hasOlderMessages] as const, async ([count, hasOlder]) => {\n const previous = previousMessageCount\n if (count !== previousMessageCount || !hasOlder) lastRequestedLength = null\n const appended = count > previous\n const element = internalElement.value\n previousMessageCount = count\n if (element && props.reverse && props.stickToBottom && appended) {\n const distanceFromBottom = element.scrollHeight - element.scrollTop - element.clientHeight\n if (previous === 0 || distanceFromBottom < 320) {\n await nextTick()\n element.scrollTop = element.scrollHeight\n }\n }\n }, { flush: 'post', immediate: true })\n\n const renderMessage = (message: Message, index: number): VNodeChild => {\n const isCurrentUser = message.senderId === props.currentUserId\n const sender = participants.value.get(message.senderId)\n const isPending = isConvoKitPendingMessage(message)\n const readerIds = isPending\n ? new Set<string>()\n : props.readersResolver ? props.readersResolver(message) : readerIdsFor(message, props.readAtByUserId, props.readPositionByUserId)\n const slotProps: MessageSlotProps = { message, chronologicalIndex: index, isCurrentUser, sender, readerIds }\n const custom = slots.message?.(slotProps)\n if (custom) return h('div', { key: message.id, role: 'listitem' }, custom)\n const currentAppearance = appearance()\n const messagePart = isCurrentUser ? 'outgoingMessage' : 'incomingMessage'\n const mediaNodes = message.media.map((media, mediaIndex) => {\n const open = props.onAttachmentClick\n ? () => {\n props.onAttachmentClick?.(media, message)\n }\n : undefined\n const mediaSlotProps: MediaSlotProps = { media, message, isCurrentUser, ...(open ? { open } : {}) }\n return h('div', {\n key: media.id ?? `${media.type}-${mediaIndex}`,\n class: partClass('media', currentAppearance, 'ckui-media'),\n style: partStyle('media', currentAppearance),\n }, slots.media?.(mediaSlotProps) ?? [defaultMedia(media, open, props.imageLoading)])\n })\n const receiptSlotProps: ReadReceiptSlotProps = { message, readerIds }\n return h('div', { key: message.id, role: 'listitem' }, [\n h('article', {\n class: cx(\n !props.unstyled && 'ckui-message-row',\n isCurrentUser && !props.unstyled && 'ckui-message-row--outgoing',\n props.classNames?.message,\n props.classNames?.[messagePart],\n ),\n style: [props.styles?.message, props.styles?.[messagePart]],\n 'data-message-id': message.id,\n }, [\n h('div', { class: 'ckui-message-bubble' }, [\n !isCurrentUser ? h('strong', { class: 'ckui-message-sender' }, sender?.name || message.senderId) : null,\n message.text ? h('div', { class: 'ckui-message-text' }, message.text) : null,\n ...mediaNodes,\n h('span', { class: 'ckui-message-time' }, [\n isPending ? 'Sending…' : props.formatTime(message.createdAt),\n isCurrentUser && !isPending\n ? readerIds.size > 0\n ? h(CheckCheck, { size: 14, 'aria-label': 'Read' })\n : h(Check, { size: 14, 'aria-label': 'Sent' })\n : null,\n ]),\n ]),\n isCurrentUser && !isPending\n ? slots['read-receipt']?.(receiptSlotProps) ?? h('div', {\n class: partClass('receipt', currentAppearance, 'ckui-read-receipt'),\n style: partStyle('receipt', currentAppearance),\n }, readerIds.size > 0 ? `Read by ${readerIds.size}` : 'Sent')\n : null,\n ]),\n ])\n }\n\n return () => {\n const currentAppearance = appearance()\n const children: VNodeChild[] = []\n if (props.isLoadingOlder) {\n children.push(slots['loading-older']?.() ?? h('div', {\n class: partClass('loading', currentAppearance, 'ckui-inline-state'),\n style: partStyle('loading', currentAppearance),\n role: 'status',\n }, [h(LoaderCircle, { class: 'ckui-spin', 'aria-hidden': 'true' }), ' Loading older messages…']))\n }\n if (props.error) {\n const retry = props.onLoadOlder ? () => { void requestOlder() } : undefined\n children.push(slots.error?.({ error: props.error, ...(retry ? { retry } : {}) }) ?? h('div', {\n class: partClass('error', currentAppearance, 'ckui-inline-state ckui-state--error'),\n style: partStyle('error', currentAppearance),\n role: 'alert',\n }, [\n h('span', errorMessage(props.error)),\n retry ? h('button', { type: 'button', class: 'ckui-link-button', onClick: retry }, 'Retry') : null,\n ]))\n }\n if (props.messages.length === 0 && !props.isLoadingOlder) {\n children.push(slots.empty?.() ?? h('div', {\n class: partClass('empty', currentAppearance, 'ckui-state'),\n style: partStyle('empty', currentAppearance),\n }, [h(MessageCircle, { 'aria-hidden': 'true' }), ' No messages yet']))\n } else {\n children.push(...props.messages.map(renderMessage))\n }\n return h('div', {\n ...attrs,\n ref: (element: unknown) => {\n internalElement.value = element as HTMLElement | null\n if (props.scrollElement) props.scrollElement.value = element as HTMLElement | null\n },\n class: cx(!props.unstyled && 'ckui ckui-message-list', props.classNames?.messages, attrs.class),\n style: [props.styles?.messages, attrs.style],\n 'data-density': props.density,\n role: 'log',\n 'aria-live': 'polite',\n 'aria-label': `Messages in ${props.conversation.displayTitle}`,\n onScroll: (event: Event) => {\n const nativeHandler = attrs.onScroll\n if (typeof nativeHandler === 'function') nativeHandler(event)\n const element = event.currentTarget as HTMLElement\n const distanceFromOldest = props.reverse\n ? element.scrollTop\n : element.scrollHeight - element.scrollTop - element.clientHeight\n if (distanceFromOldest <= props.paginationThreshold) void requestOlder()\n },\n }, children)\n }\n },\n})\n\nexport function defaultReadersResolver(\n readAtByUserId: ReadonlyMap<string, Date>,\n readPositionByUserId: ReadonlyMap<string, ReadPosition> = new Map(),\n): (message: Message) => ReadonlySet<string> {\n return (message) => readerIdsFor(message, readAtByUserId, readPositionByUserId)\n}\n","import type { Conversation, InboxSummary } from '@convokitapp/sdk'\nimport { ChevronRight, Inbox, LoaderCircle, RefreshCw } from '@lucide/vue'\nimport {\n defineComponent,\n h,\n ref,\n watchEffect,\n type CSSProperties,\n type PropType,\n type Ref,\n type VNodeChild,\n} from 'vue'\nimport type { ConversationListController, UseConversationListOptions } from '../composables/use-conversation-list'\nimport { useConversationList } from '../composables/use-conversation-list'\nimport type {\n ConversationFilter,\n ConversationItemSlotProps,\n ConversationPageLoader,\n ConvoKitAppearanceProps,\n ConvoKitUiClient,\n ConvoKitUiDensity,\n ConvoKitUiPart,\n} from '../types'\nimport { cx, errorMessage, formatMessageTime, inboxPreview, partClass, partStyle } from '../utils'\nimport { ConvoKitAvatar } from './avatar'\n\nexport interface ConversationListViewProps extends ConvoKitAppearanceProps {\n conversations: readonly Conversation[]\n /** Inbox summaries by conversation ID (0.6.0). Rows with one show a preview, time and unread badge: the count, or\n * a numberless dot when `isUnread` is set without one (0.7.0).\n */\n summaries?: ReadonlyMap<string, InboxSummary>\n /** The viewer; a preview from them reads `You: …`. Absent → no prefix. */\n currentUserId?: string\n selectedConversationId?: string\n onConversationSelect?: (conversation: Conversation) => void\n onRefresh?: () => void | Promise<void>\n onLoadMore?: () => void | Promise<void>\n isInitialLoading?: boolean\n isLoadingMore?: boolean\n hasMore?: boolean\n error?: unknown\n scrollElement?: Ref<HTMLElement | null>\n paginationThreshold?: number\n ariaLabel?: string\n class?: unknown\n style?: unknown\n}\n\nconst appearanceProps = {\n classNames: { type: Object as PropType<Partial<Record<ConvoKitUiPart, string>>>, default: undefined },\n styles: { type: Object as PropType<Partial<Record<ConvoKitUiPart, CSSProperties>>>, default: undefined },\n density: { type: String as PropType<ConvoKitUiDensity>, default: 'comfortable' },\n unstyled: { type: Boolean, default: false },\n} as const\n\nconst listViewProps = {\n ...appearanceProps,\n conversations: { type: Array as PropType<readonly Conversation[]>, required: true },\n summaries: { type: Object as PropType<ReadonlyMap<string, InboxSummary>>, default: undefined },\n currentUserId: { type: String, default: undefined },\n selectedConversationId: { type: String, default: undefined },\n onConversationSelect: { type: Function as PropType<(conversation: Conversation) => void>, default: undefined },\n onRefresh: { type: Function as PropType<() => void | Promise<void>>, default: undefined },\n onLoadMore: { type: Function as PropType<() => void | Promise<void>>, default: undefined },\n isInitialLoading: { type: Boolean, default: false },\n isLoadingMore: { type: Boolean, default: false },\n hasMore: { type: Boolean, default: false },\n error: { type: null as unknown as PropType<unknown>, required: false },\n scrollElement: { type: Object as PropType<Ref<HTMLElement | null>>, default: undefined },\n paginationThreshold: { type: Number, default: 240 },\n ariaLabel: { type: String, default: 'Conversations' },\n} as const\n\n/** Controlled conversation list. It can be used with any state-management layer. */\nexport const ConversationListView = defineComponent({\n name: 'ConversationListView',\n inheritAttrs: false,\n props: listViewProps,\n emits: {\n 'conversation-select': (_conversation: Conversation) => true,\n refresh: () => true,\n 'load-more': () => true,\n },\n setup(props, { attrs, emit, slots }) {\n const internalElement = ref<HTMLElement | null>(null)\n let requestInFlight = false\n let lastRequestedLength: number | null = null\n\n const appearance = (): ConvoKitAppearanceProps => ({\n density: props.density,\n unstyled: props.unstyled,\n ...(props.classNames ? { classNames: props.classNames } : {}),\n ...(props.styles ? { styles: props.styles } : {}),\n })\n\n const requestMore = async () => {\n if (requestInFlight || lastRequestedLength === props.conversations.length || props.isInitialLoading || props.isLoadingMore || !props.hasMore || !props.onLoadMore) return\n requestInFlight = true\n lastRequestedLength = props.conversations.length\n try { await props.onLoadMore() }\n catch { lastRequestedLength = null }\n finally { requestInFlight = false }\n }\n\n const selectConversation = (conversation: Conversation) => {\n props.onConversationSelect?.(conversation)\n }\n\n const refresh = () => {\n return props.onRefresh?.()\n }\n\n /** Inline errors retry the next page when one is pending (past the duplicate guard), otherwise refresh. */\n const inlineRetry = (): (() => void) | undefined => {\n if (props.hasMore && props.onLoadMore) return () => { lastRequestedLength = null; void requestMore() }\n if (props.onRefresh) return () => { void refresh() }\n return undefined\n }\n\n /** A count (or a capped count) keeps the numeric badge; a marker without one is a numberless dot named\n * `Unread` (never `0 unread`). Returned as a spread so an absent badge adds no child.\n */\n const unreadBadge = (summary: InboxSummary): VNodeChild[] => {\n if (summary.unreadCount > 0 || summary.unreadCountCapped) {\n const capped = summary.unreadCountCapped || summary.unreadCount > 99\n return [h('span', {\n class: 'ckui-unread-badge',\n role: 'img',\n 'aria-label': `${summary.unreadCountCapped ? '99+' : summary.unreadCount} unread`,\n }, [h('span', { 'aria-hidden': 'true' }, capped ? '99+' : String(summary.unreadCount))])]\n }\n if (summary.isUnread) return [h('span', { class: 'ckui-unread-badge ckui-unread-badge--dot', role: 'img', 'aria-label': 'Unread' })]\n return []\n }\n\n const renderContent = () => {\n const currentAppearance = appearance()\n if (props.isInitialLoading && props.conversations.length === 0) {\n return slots['initial-loading']?.() ?? h('div', {\n class: partClass('loading', currentAppearance, 'ckui-state'),\n style: partStyle('loading', currentAppearance),\n role: 'status',\n }, [h(LoaderCircle, { class: 'ckui-spin', 'aria-hidden': 'true' }), ' Loading conversations…'])\n }\n if (props.error && props.conversations.length === 0) {\n const retry = props.onRefresh ? () => { void refresh() } : undefined\n return slots.error?.({ error: props.error, ...(retry ? { retry } : {}) }) ?? h('div', {\n class: partClass('error', currentAppearance, 'ckui-state ckui-state--error'),\n style: partStyle('error', currentAppearance),\n role: 'alert',\n }, [\n h('span', errorMessage(props.error)),\n retry ? h('button', { type: 'button', class: 'ckui-link-button', onClick: retry }, 'Try again') : null,\n ])\n }\n if (props.conversations.length === 0) {\n return slots.empty?.() ?? h('div', {\n class: partClass('empty', currentAppearance, 'ckui-state'),\n style: partStyle('empty', currentAppearance),\n }, [h(Inbox, { 'aria-hidden': 'true' }), ' No conversations yet'])\n }\n const children: VNodeChild[] = props.conversations.flatMap((conversation, index) => {\n const selected = props.selectedConversationId === conversation.id\n const select = () => selectConversation(conversation)\n const summary = props.summaries?.get(conversation.id)\n const slotProps: ConversationItemSlotProps = {\n conversation, index, selected, select,\n ...(summary ? { summary } : {}),\n ...(props.currentUserId === undefined ? {} : { currentUserId: props.currentUserId }),\n }\n const preview = inboxPreview(conversation, summary, props.currentUserId)\n // Consumer-built summaries that omit `isUnread` keep their count-driven badges.\n const unread = summary !== undefined && (summary.isUnread || summary.unreadCount > 0 || summary.unreadCountCapped)\n const item = slots['conversation-item']?.(slotProps) ?? h('button', {\n type: 'button',\n 'data-selected': selected || undefined,\n 'data-unread': unread || undefined,\n 'aria-current': selected ? 'true' : undefined,\n onClick: select,\n class: partClass('listItem', currentAppearance, 'ckui-conversation-item'),\n style: partStyle('listItem', currentAppearance),\n }, [\n h(ConvoKitAvatar, {\n name: conversation.displayTitle,\n src: conversation.imageUrl,\n class: partClass('avatar', currentAppearance, ''),\n style: partStyle('avatar', currentAppearance),\n } as never),\n h('span', { class: 'ckui-conversation-item__body' }, [\n h('strong', conversation.displayTitle),\n h('span', preview || conversation.participants.map((participant) => participant.name).join(', ') || conversation.description || 'No participants'),\n ]),\n // Spread rather than emit `null`: a null child renders a `<!---->` comment, and rows without a\n // summary must keep 0.5's exact markup.\n ...(summary ? [h('span', { class: 'ckui-conversation-item__meta' }, [\n h('time', { class: 'ckui-conversation-item__time', datetime: summary.activityAt.toISOString() }, formatMessageTime(summary.activityAt)),\n ...unreadBadge(summary),\n ])] : []),\n h(ChevronRight, { size: 18, 'aria-hidden': 'true' }),\n ])\n const nodes = [h('div', { key: conversation.id, role: 'listitem' }, [item])]\n if (index < props.conversations.length - 1) {\n nodes.push(h('div', { key: `${conversation.id}-separator` }, slots.separator?.({ index }) ?? h('div', { class: 'ckui-separator' })))\n }\n return nodes\n })\n if (props.error) {\n const retry = inlineRetry()\n children.push(slots.error?.({ error: props.error, ...(retry ? { retry } : {}) }) ?? h('div', {\n class: partClass('error', currentAppearance, 'ckui-inline-state ckui-state--error'),\n style: partStyle('error', currentAppearance),\n role: 'alert',\n }, [\n h('span', errorMessage(props.error)),\n ...(retry ? [h('button', { type: 'button', class: 'ckui-link-button', onClick: retry }, 'Retry')] : []),\n ]))\n } else if (props.isLoadingMore) {\n children.push(slots['load-more']?.() ?? h('div', {\n class: partClass('loading', currentAppearance, 'ckui-inline-state'),\n style: partStyle('loading', currentAppearance),\n role: 'status',\n }, [h(LoaderCircle, { class: 'ckui-spin', 'aria-hidden': 'true' }), ' Loading more…']))\n }\n return h('div', {\n role: 'list',\n class: partClass('list', currentAppearance, 'ckui-conversation-list__items'),\n style: partStyle('list', currentAppearance),\n }, children)\n }\n\n return () => h('div', {\n ...attrs,\n class: cx(!props.unstyled && 'ckui ckui-conversation-list', props.classNames?.root, attrs.class),\n style: [props.styles?.root, attrs.style],\n 'data-density': props.density,\n }, [\n props.onRefresh ? h('div', { class: 'ckui-conversation-list__toolbar' }, [\n h('span', props.ariaLabel),\n h('button', {\n type: 'button',\n 'aria-label': 'Refresh conversations',\n class: partClass('button', appearance(), 'ckui-icon-button'),\n style: partStyle('button', appearance()),\n onClick: () => { void refresh() },\n }, [h(RefreshCw, { size: 17, 'aria-hidden': 'true' })]),\n ]) : null,\n h('div', {\n ref: (element: unknown) => {\n internalElement.value = element as HTMLElement | null\n if (props.scrollElement) props.scrollElement.value = element as HTMLElement | null\n },\n class: cx(!props.unstyled && 'ckui-scroll-area', props.classNames?.list),\n style: props.styles?.list,\n 'aria-label': props.ariaLabel,\n onScroll: (event: Event) => {\n const nativeHandler = attrs.onScroll\n if (typeof nativeHandler === 'function') nativeHandler(event)\n const element = event.currentTarget as HTMLElement\n if (element.scrollHeight - element.scrollTop - element.clientHeight <= props.paginationThreshold) void requestMore()\n },\n }, [renderContent()]),\n ])\n },\n})\n\nexport interface ConversationListProps extends Omit<ConversationListViewProps,\n 'conversations' | 'onRefresh' | 'onLoadMore' | 'isInitialLoading' | 'isLoadingMore' | 'hasMore' | 'error'>,\n Omit<UseConversationListOptions, 'client'> {\n client: ConvoKitUiClient\n onControllerChange?: (controller: ConversationListController) => void\n}\n\n/** Plug-and-play SDK-backed conversation list. */\nexport const ConversationList = defineComponent({\n name: 'ConversationList',\n inheritAttrs: false,\n props: {\n ...listViewProps,\n conversations: { type: Array as PropType<readonly Conversation[]>, default: () => [] },\n client: { type: Object as PropType<ConvoKitUiClient>, required: true },\n pageLoader: { type: Function as PropType<ConversationPageLoader>, default: undefined },\n initialFilter: { type: Object as PropType<ConversationFilter>, default: undefined },\n pageSize: { type: Number, default: 30 },\n autoLoad: { type: Boolean, default: true },\n activityRefreshWindowMs: { type: Number, default: undefined },\n onControllerChange: { type: Function as PropType<(controller: ConversationListController) => void>, default: undefined },\n },\n emits: ['conversation-select', 'controller-change'],\n setup(props, { attrs, emit, expose, slots }) {\n const controller = useConversationList({\n client: () => props.client,\n ...(props.pageLoader ? { pageLoader: props.pageLoader } : {}),\n ...(props.initialFilter ? { initialFilter: props.initialFilter } : {}),\n pageSize: props.pageSize,\n autoLoad: props.autoLoad,\n ...(props.activityRefreshWindowMs === undefined ? {} : { activityRefreshWindowMs: props.activityRefreshWindowMs }),\n })\n expose({ controller })\n watchEffect(() => {\n emit('controller-change', controller)\n })\n return () => {\n const {\n client: _client,\n pageLoader: _pageLoader,\n initialFilter: _initialFilter,\n pageSize: _pageSize,\n autoLoad: _autoLoad,\n activityRefreshWindowMs: _activityRefreshWindowMs,\n onControllerChange: _onControllerChange,\n conversations: _conversations,\n summaries: _summaries,\n currentUserId: _currentUserId,\n onRefresh: _onRefresh,\n onLoadMore: _onLoadMore,\n isInitialLoading: _isInitialLoading,\n isLoadingMore: _isLoadingMore,\n hasMore: _hasMore,\n error: _error,\n ...forwarded\n } = props\n return h(ConversationListView, {\n ...attrs,\n ...forwarded,\n conversations: controller.conversations.value,\n summaries: controller.summaries.value,\n currentUserId: controller.currentUserId.value,\n onRefresh: controller.refresh,\n onLoadMore: controller.loadMore,\n isInitialLoading: controller.isInitialLoading.value,\n isLoadingMore: controller.isLoadingMore.value,\n hasMore: controller.hasMore.value,\n ...(controller.error.value == null ? {} : { error: controller.error.value }),\n onConversationSelect: (conversation: Conversation) => {\n emit('conversation-select', conversation)\n },\n } as never, slots)\n }\n },\n})\n","import type { ClearConversationUnreadOptions } from '@convokitapp/sdk'\nimport { computed, getCurrentScope, onScopeDispose, shallowRef, toValue, watch, type MaybeRefOrGetter } from 'vue'\nimport type { ConversationFilter, ConversationListState, ConversationPageLoader, ConvoKitUiClient } from '../types'\nimport { ConversationListStore, type ConversationListSnapshot } from '../conversation-list-store'\n\nexport interface UseConversationListOptions {\n client: MaybeRefOrGetter<ConvoKitUiClient>\n pageLoader?: ConversationPageLoader\n initialFilter?: ConversationFilter\n pageSize?: number\n autoLoad?: boolean\n /** Max-wait window (ms) that coalesces `inbox_activity` signals into one refresh; default 500, 0 = immediate. */\n activityRefreshWindowMs?: number\n}\nexport interface ConversationListController extends ConversationListState {\n loadInitial(): Promise<void>\n refresh(): Promise<void>\n loadMore(): Promise<void>\n setFilter(filter: ConversationFilter): Promise<void>\n setQuery(query: string): Promise<void>\n /** Mark a room unread for the viewer only (0.7.0); its summary shows the marker at once. Rejects when the adapter\n * lacks `markConversationUnread`.\n */\n markUnread(conversationId: string): Promise<void>\n /** Remove the viewer's marker, only while it still has `options.ifVersion` when given; resolves to whether this\n * request removed it. Rejects when the adapter lacks `clearConversationUnread`.\n */\n clearUnread(conversationId: string, options?: ClearConversationUnreadOptions): Promise<boolean>\n dispose(): Promise<void>\n}\n\nexport function useConversationList(options: UseConversationListOptions): ConversationListController {\n const createStore = () => new ConversationListStore({ ...options, client: toValue(options.client) })\n let store = createStore()\n const snapshot = shallowRef(store.getSnapshot())\n let unsubscribe: (() => void) | undefined\n const stop = watch(\n () => [toValue(options.client), toValue(options.client).sessionIdentity] as const,\n () => {\n store.dispose()\n unsubscribe?.()\n store = createStore()\n snapshot.value = store.getSnapshot()\n unsubscribe = store.subscribe(() => { snapshot.value = store.getSnapshot() })\n store.start(options.autoLoad ?? true)\n },\n { immediate: true, flush: 'sync' },\n )\n const field = <K extends keyof ConversationListSnapshot>(key: K) => computed(() => snapshot.value[key])\n const dispose = async () => {\n stop()\n store.dispose()\n unsubscribe?.()\n unsubscribe = undefined\n }\n if (getCurrentScope()) onScopeDispose(() => { void dispose() })\n return {\n conversations: field('conversations'), summaries: field('summaries'), currentUserId: field('currentUserId'),\n filter: field('filter'),\n isInitialLoading: field('isInitialLoading'), isLoadingMore: field('isLoadingMore'),\n hasMore: field('hasMore'), hasLoaded: field('hasLoaded'), error: field('error'),\n loadInitial: () => store.loadInitial(), refresh: () => store.refresh(),\n loadMore: () => store.loadMore(), setFilter: (filter) => store.setFilter(filter),\n setQuery: (query) => store.setQuery(query),\n markUnread: (conversationId) => store.markUnread(conversationId),\n clearUnread: (conversationId, options) => store.clearUnread(conversationId, options),\n dispose,\n }\n}\n","import type {\n ClearConversationUnreadOptions, Conversation, ConversationPrivateState, InboxEntry, InboxPage, InboxSummary, RealtimeSubscription,\n} from '@convokitapp/sdk'\nimport type { ConversationFilter, ConversationPageLoader, ConvoKitUiClient } from './types'\nimport { applyConversationFilter, mergeConversations, mergeInboxEntries } from './utils'\n\nexport interface ConversationListSnapshot {\n conversations: Conversation[]\n summaries: ReadonlyMap<string, InboxSummary>\n currentUserId: string\n filter: ConversationFilter\n isInitialLoading: boolean\n isLoadingMore: boolean\n hasMore: boolean\n hasLoaded: boolean\n error: unknown\n}\ninterface Options {\n client: ConvoKitUiClient\n pageLoader?: ConversationPageLoader\n initialFilter?: ConversationFilter\n pageSize?: number\n /** Max-wait window for coalescing `inbox_activity` signals into one refresh; 0 refreshes immediately. */\n activityRefreshWindowMs?: number\n}\nconst defaultActivityRefreshWindowMs = 500\nfunction blank(filter: ConversationFilter): ConversationListSnapshot {\n return {\n conversations: [], summaries: new Map(), currentUserId: '', filter,\n isInitialLoading: false, isLoadingMore: false, hasMore: true, hasLoaded: false, error: null,\n }\n}\nfunction statusOf(cause: unknown): unknown {\n return typeof cause === 'object' && cause !== null && 'status' in cause ? cause.status : undefined\n}\nfunction summaryOf(entry: InboxEntry): InboxSummary {\n const { conversation: _conversation, ...summary } = entry\n return summary\n}\nfunction ids(entries: readonly InboxEntry[]): Conversation[] { return entries.map((entry) => entry.conversation) }\n\n/** Session-owned inbox paging. A page loader must belong to the same authenticated app.\n *\n * Inbox mode (an adapter with `listInbox`, no custom page loader, endpoint available) pages by opaque cursor in\n * activity order and carries per-room summaries; every other configuration is the legacy offset path over\n * `getConversations`, unchanged from 0.5 and without summaries.\n */\nexport class ConversationListStore {\n private readonly owner: object | null\n private readonly user: string\n private readonly pageSize: number\n private readonly activityRefreshWindowMs: number\n private state: ConversationListSnapshot\n private source: Conversation[] = []\n private entries: InboxEntry[] = []\n private offset = 0\n private cursor: string | null = null\n private inboxUnavailable = false\n private inboxWarned = false\n private generation = 0\n private lifecycleGeneration = 0\n private disposed = true\n private lifecycle: RealtimeSubscription | undefined\n private inbox: RealtimeSubscription | undefined\n private activity: RealtimeSubscription | undefined\n private activityTimer: ReturnType<typeof setTimeout> | undefined\n private refreshQueued = false\n private refreshing = false\n private listeners = new Set<() => void>()\n\n constructor(private readonly options: Options) {\n this.owner = options.client.sessionIdentity\n this.user = this.owner ? options.client.currentUserId : ''\n this.pageSize = options.pageSize ?? 30\n if (!Number.isInteger(this.pageSize) || this.pageSize < 1 || this.pageSize > 100) {\n throw new RangeError('pageSize must be an integer between 1 and 100')\n }\n this.activityRefreshWindowMs = options.activityRefreshWindowMs ?? defaultActivityRefreshWindowMs\n if (!Number.isFinite(this.activityRefreshWindowMs) || this.activityRefreshWindowMs < 0) {\n throw new RangeError('activityRefreshWindowMs must be a non-negative number')\n }\n this.state = blank(options.initialFilter ?? {})\n }\n getSnapshot = (): ConversationListSnapshot => this.state\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener)\n return () => { this.listeners.delete(listener) }\n }\n private patch(patch: Partial<ConversationListSnapshot>): void {\n this.state = { ...this.state, ...patch }\n for (const listener of this.listeners) listener()\n }\n private alive(generation = this.generation): boolean {\n return !this.disposed && generation === this.generation && this.owner !== null\n && this.options.client.sessionIdentity === this.owner\n }\n private get inboxMode(): boolean {\n return !this.options.pageLoader && typeof this.options.client.listInbox === 'function' && !this.inboxUnavailable\n }\n private currentUserId(): string { return this.inboxMode ? this.user : '' }\n start = (autoLoad = true): void => {\n if (!this.owner || this.options.client.sessionIdentity !== this.owner) return\n if (!this.disposed) return\n this.disposed = false\n this.inboxUnavailable = false\n const lifecycleGeneration = ++this.lifecycleGeneration\n const current = () => this.alive() && lifecycleGeneration === this.lifecycleGeneration\n const reconcile = (cause: Error) => {\n if (current()) {\n this.patch({ error: cause })\n // Reconcile authoritative REST after terminal topic denial as well.\n this.queueRefresh()\n }\n }\n try {\n this.patch({ currentUserId: this.currentUserId() })\n const subscription = this.options.client.onConnectionEvent({\n onEvent: () => {},\n onSessionEnded: () => {\n if (!this.disposed && lifecycleGeneration === this.lifecycleGeneration) this.dispose()\n },\n })\n if (this.alive()) this.lifecycle = subscription\n else void subscription.unsubscribe().catch(() => undefined)\n if (!this.alive()) return\n const inbox = this.options.client.onInboxChanged(() => {\n if (!current()) return\n // Structural changes are immediate and supersede a pending activity window.\n this.clearActivityTimer()\n this.queueRefresh()\n }, reconcile)\n if (this.alive()) this.inbox = inbox\n else void inbox.unsubscribe().catch(() => undefined)\n if (!this.alive()) return\n if (this.inboxMode && typeof this.options.client.onInboxActivity === 'function') {\n const activity = this.options.client.onInboxActivity(() => {\n if (current()) this.scheduleActivityRefresh(lifecycleGeneration)\n }, reconcile)\n if (this.alive()) this.activity = activity\n else void activity.unsubscribe().catch(() => undefined)\n }\n if (autoLoad) void this.loadInitial()\n } catch (cause) { if (this.alive()) this.patch({ error: cause }) }\n }\n dispose = (): void => {\n this.disposed = true\n this.generation++\n this.lifecycleGeneration++\n this.clearActivityTimer()\n const subscription = this.lifecycle\n this.lifecycle = undefined\n if (subscription) void subscription.unsubscribe().catch(() => undefined)\n if (this.inbox) void this.inbox.unsubscribe().catch(() => undefined)\n this.inbox = undefined\n this.stopActivity()\n this.refreshQueued = false\n this.refreshing = false\n this.source = []\n this.entries = []\n this.offset = 0\n this.cursor = null\n this.patch(blank(this.state.filter))\n }\n private stopActivity(): void {\n if (this.activity) void this.activity.unsubscribe().catch(() => undefined)\n this.activity = undefined\n }\n private clearActivityTimer(): void {\n if (this.activityTimer !== undefined) clearTimeout(this.activityTimer)\n this.activityTimer = undefined\n }\n /** Max-wait throttle: the first signal opens a window; later signals wait for it; one refresh runs when it closes. */\n private scheduleActivityRefresh(lifecycleGeneration: number): void {\n if (this.activityRefreshWindowMs === 0) return this.queueRefresh()\n if (this.activityTimer !== undefined) return\n const timer = setTimeout(() => {\n this.activityTimer = undefined\n if (this.alive() && lifecycleGeneration === this.lifecycleGeneration) this.queueRefresh()\n }, this.activityRefreshWindowMs)\n ;(timer as { unref?: () => void }).unref?.()\n this.activityTimer = timer\n }\n private fail(cause: unknown, generation: number): void {\n if (!this.alive(generation)) return\n const status = statusOf(cause)\n if (status === 401 || status === 403 || status === 404) {\n this.source = []\n this.entries = []\n this.offset = 0\n this.cursor = null\n this.patch({ conversations: [], summaries: new Map(), hasMore: false })\n }\n this.patch({ error: cause })\n }\n /** Run an operation in inbox mode, falling back to the legacy path for the rest of this store's life when the\n * inbox route is absent (404: rollback, staging). Loaded rows are kept and the same operation continues.\n */\n private async withFallback(generation: number, inbox: () => Promise<void>, legacy: () => Promise<void>): Promise<void> {\n if (!this.inboxMode) return legacy()\n try { await inbox() }\n catch (cause) {\n if (!this.alive(generation) || statusOf(cause) !== 404) throw cause\n this.inboxUnavailable = true\n this.clearActivityTimer()\n this.stopActivity()\n this.entries = []\n this.cursor = null\n this.offset = this.source.length\n if (!this.inboxWarned) {\n this.inboxWarned = true\n console.warn('ConvoKit inbox endpoint unavailable (404); using getConversations without previews or unread counts.')\n }\n this.patch({ summaries: new Map(), currentUserId: '' })\n await legacy()\n }\n }\n private validateInboxPage(page: InboxPage, limit: number, requestedCursor: string | null): void {\n const seen = new Set<string>()\n for (const entry of page.entries) {\n const id = entry.conversation.id\n if (!id.trim() || seen.has(id)) throw new Error('Invalid conversation page')\n seen.add(id)\n }\n if (page.entries.length > limit) throw new Error('Invalid conversation page')\n if (page.nextCursor !== null && (page.nextCursor === requestedCursor || page.entries.length === 0)) {\n throw new Error('Inbox pagination did not advance')\n }\n }\n /** Swap rows, summaries, cursor and hasMore together, filtered by the filter current at commit time. */\n private commitInbox(entries: InboxEntry[], cursor: string | null): void {\n this.entries = entries\n this.source = ids(entries)\n this.cursor = cursor\n this.patch({\n conversations: applyConversationFilter(this.source, this.state.filter),\n summaries: new Map(entries.map((entry) => [entry.conversation.id, summaryOf(entry)])),\n hasMore: cursor !== null,\n })\n }\n private async loadInboxUntilVisible(generation: number, filter: ConversationFilter): Promise<void> {\n const visibleBefore = applyConversationFilter(this.source, filter).length\n while (this.alive(generation)) {\n const requested = this.cursor\n const page = await this.options.client.listInbox!({ limit: this.pageSize, cursor: requested, archived: filter.archived ?? false })\n if (!this.alive(generation)) return\n this.validateInboxPage(page, this.pageSize, requested)\n this.commitInbox(mergeInboxEntries(this.entries, page.entries), page.nextCursor)\n if (page.nextCursor === null || this.state.conversations.length > visibleBefore) return\n }\n }\n private async loadUntilVisible(generation: number, filter: ConversationFilter): Promise<void> {\n const visibleBefore = applyConversationFilter(this.source, filter).length\n while (this.alive(generation)) {\n const request = { limit: this.pageSize, offset: this.offset, filter }\n const page = this.options.pageLoader\n ? await this.options.pageLoader(request)\n : await this.options.client.getConversations({ limit: this.pageSize, offset: this.offset, archived: filter.archived ?? false })\n if (!this.alive(generation)) return\n if (page.length > this.pageSize || page.some((conversation) => !conversation.id.trim())) {\n throw new Error('Invalid conversation page')\n }\n const merged = mergeConversations(this.source, page)\n if (page.length === this.pageSize && merged.length === this.source.length) {\n throw new Error('Conversation pagination did not advance')\n }\n this.offset += page.length\n this.source = merged\n const visible = applyConversationFilter(merged, filter)\n const hasMore = page.length === this.pageSize\n this.patch({ conversations: visible, hasMore })\n if (!hasMore || visible.length > visibleBefore) return\n }\n }\n loadInitial = async (): Promise<void> => {\n if (!this.alive()) return\n const generation = ++this.generation\n this.refreshing = false\n this.source = []\n this.entries = []\n this.offset = 0\n this.cursor = null\n this.patch({ ...blank(this.state.filter), currentUserId: this.currentUserId(), isInitialLoading: true })\n const filter = this.state.filter\n try {\n await this.withFallback(generation,\n () => this.loadInboxUntilVisible(generation, filter),\n () => this.loadUntilVisible(generation, filter))\n } catch (cause) { this.fail(cause, generation) }\n finally {\n if (this.alive(generation)) {\n this.patch({ isInitialLoading: false, hasLoaded: true })\n this.flushRefresh()\n }\n }\n }\n private queueRefresh(): void {\n this.refreshQueued = true\n this.flushRefresh()\n }\n private flushRefresh(): void {\n const lifecycle = this.lifecycleGeneration\n void Promise.resolve().then(() => {\n if (!this.alive() || lifecycle !== this.lifecycleGeneration || !this.refreshQueued\n || this.refreshing || this.state.isInitialLoading || this.state.isLoadingMore) return\n this.refreshQueued = false\n void this.refresh()\n })\n }\n /** Re-walk the inbox from the head until the loaded window is covered and something is visible, or the inbox\n * ends. Rooms that moved are re-positioned by the merge; an exhausted inbox publishes what it found.\n */\n private async refreshInbox(generation: number, filter: ConversationFilter): Promise<void> {\n const target = Math.max(this.pageSize, this.entries.length)\n let rows: InboxEntry[] = [], consumed = 0, cursor: string | null = null\n while (this.alive(generation)) {\n const remaining = target - consumed\n // Past the covered window (still nothing visible) continue in page-size steps.\n const limit = remaining >= 1 ? Math.min(100, remaining) : this.pageSize\n const page = await this.options.client.listInbox!({ limit, cursor, archived: filter.archived ?? false })\n if (!this.alive(generation)) return\n this.validateInboxPage(page, limit, cursor)\n rows = mergeInboxEntries(rows, page.entries)\n consumed += page.entries.length\n cursor = page.nextCursor\n if (cursor === null || (consumed >= target && applyConversationFilter(ids(rows), this.state.filter).length > 0)) break\n }\n if (!this.alive(generation)) return\n this.commitInbox(rows, cursor)\n }\n private async refreshLegacy(generation: number, filter: ConversationFilter): Promise<void> {\n const target = Math.max(this.pageSize, this.offset)\n // Default REST order is immutable creation time/ID, independent of UI sorting.\n const compare = (a: Conversation, b: Conversation) => a.createdAt.getTime() - b.createdAt.getTime()\n || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)\n const boundary = this.options.pageLoader ? undefined\n : this.source.reduce<Conversation | undefined>((oldest, row) => !oldest || compare(row, oldest) < 0 ? row : oldest, undefined)\n let rows: Conversation[] = [], offset = 0, hasMore = true\n while (this.alive(generation)) {\n const page = this.options.pageLoader\n ? await this.options.pageLoader({ limit: this.pageSize, offset, filter })\n : await this.options.client.getConversations({ limit: this.pageSize, offset, archived: filter.archived ?? false })\n if (!this.alive(generation)) return\n if (page.length > this.pageSize || page.some(row => !row.id.trim())) throw new Error('Invalid conversation page')\n const merged = mergeConversations(rows, page)\n if (page.length === this.pageSize && merged.length === rows.length) throw new Error('Conversation pagination did not advance')\n rows = merged\n offset += page.length\n hasMore = page.length === this.pageSize\n if (!hasMore || (offset >= target && applyConversationFilter(rows, this.state.filter).length > 0\n && (!boundary || page.some(row => compare(row, boundary) <= 0)))) break\n }\n if (!this.alive(generation)) return\n this.source = rows\n this.offset = offset\n this.patch({ conversations: applyConversationFilter(rows, this.state.filter), hasMore })\n }\n /** Replace the loaded window atomically, retaining filters and rows during transient failures. */\n refresh = async (): Promise<void> => {\n if (!this.alive()) return\n if (this.refreshing || this.state.isInitialLoading || this.state.isLoadingMore) {\n this.refreshQueued = true\n return\n }\n if (!this.state.hasLoaded) return this.loadInitial()\n const generation = this.generation\n const filter = this.state.filter\n this.refreshing = true\n this.patch({ error: null })\n try {\n await this.withFallback(generation,\n () => this.refreshInbox(generation, filter),\n () => this.refreshLegacy(generation, filter))\n } catch (cause) { this.fail(cause, generation) }\n finally {\n if (this.alive(generation)) {\n this.refreshing = false\n this.flushRefresh()\n }\n }\n }\n loadMore = async (): Promise<void> => {\n if (!this.alive() || this.refreshing || this.state.isInitialLoading || this.state.isLoadingMore || !this.state.hasMore) return\n const generation = this.generation\n const filter = this.state.filter\n this.patch({ isLoadingMore: true, error: null })\n try {\n await this.withFallback(generation,\n () => this.loadInboxUntilVisible(generation, filter),\n () => this.loadUntilVisible(generation, filter))\n } catch (cause) { this.fail(cause, generation) }\n finally {\n if (this.alive(generation)) {\n this.patch({ isLoadingMore: false })\n this.flushRefresh()\n }\n }\n }\n setFilter = async (filter: ConversationFilter): Promise<void> => {\n if (!this.alive()) return\n const reload = this.options.pageLoader || !this.state.hasLoaded || this.state.isInitialLoading\n || this.state.isLoadingMore || (filter.archived ?? false) !== (this.state.filter.archived ?? false)\n this.patch({ filter, conversations: applyConversationFilter(this.source, filter), error: null })\n if (reload) await this.loadInitial()\n else if (!this.state.conversations.length && this.state.hasMore) await this.loadMore()\n }\n setQuery = (query: string): Promise<void> => this.setFilter({ ...this.state.filter, query })\n /** Mark a room unread for the viewer only; the row's summary takes the response (D10). Rejects when the adapter\n * lacks `markConversationUnread` or the store is not active; a request failure is reported through `error`\n * without evicting rows and rejects.\n */\n markUnread = async (conversationId: string): Promise<void> => {\n const client = this.options.client\n if (typeof client.markConversationUnread !== 'function') {\n throw new TypeError('markUnread requires a ConvoKitUiClient adapter with markConversationUnread (core SDK 0.7)')\n }\n this.assertActive()\n this.applyPrivateState(conversationId, await this.mutate(client.markConversationUnread(conversationId)))\n }\n /** Remove the viewer's marker (conditionally on `options.ifVersion`); resolves to the response's `cleared` (\"this\n * request removed the marker\", not \"the room is read\") and patches the summary on true and false alike (D10).\n * Rejects when the adapter lacks `clearConversationUnread` or the store is not active; failures are reported like\n * `markUnread`.\n */\n clearUnread = async (conversationId: string, options?: ClearConversationUnreadOptions): Promise<boolean> => {\n const client = this.options.client\n if (typeof client.clearConversationUnread !== 'function') {\n throw new TypeError('clearUnread requires a ConvoKitUiClient adapter with clearConversationUnread (core SDK 0.7)')\n }\n this.assertActive()\n const result = await this.mutate(client.clearConversationUnread(conversationId, options))\n this.applyPrivateState(conversationId, result)\n return result.cleared\n }\n /** A disposed or session-evicted store never sends a private-state mutation: on a shared client it could go out\n * under a replacement login. Rejected without touching `error` (there is no live snapshot to report into).\n */\n private assertActive(): void {\n if (!this.alive()) throw new Error('ConversationListStore is not active')\n }\n private async mutate<T>(request: Promise<T>): Promise<T> {\n try { return await request }\n catch (cause) {\n if (this.alive()) this.patch({ error: cause })\n throw cause\n }\n }\n /** Apply a mark/clear response to the row's CURRENT summary (a refresh may have swapped it) as one unit, only while\n * the store is alive and the response is not older than the stored version: a delayed response never resurrects a\n * marker a newer action removed (equal versions are an idempotent no-op). `isUnread` is recomputed from the stored\n * counts and the response marker. Other devices learn of the change through `inbox_activity`.\n */\n private applyPrivateState(conversationId: string, state: ConversationPrivateState): void {\n if (!this.alive()) return\n const current = this.entries.find((entry) => entry.conversation.id === conversationId)\n if (!current || state.privateStateVersion < current.privateStateVersion) return\n const { unreadMarkedAt, privateStateVersion } = state\n const patched: InboxEntry = {\n ...current, unreadMarkedAt, privateStateVersion,\n isUnread: current.unreadCount > 0 || current.unreadCountCapped || unreadMarkedAt !== null,\n }\n this.entries = this.entries.map((entry) => entry === current ? patched : entry)\n this.patch({ summaries: new Map(this.entries.map((entry) => [entry.conversation.id, summaryOf(entry)])) })\n }\n}\n","import {\n computed,\n defineComponent,\n h,\n inject,\n provide,\n type CSSProperties,\n type InjectionKey,\n type PropType,\n type Ref,\n} from 'vue'\nimport { cx } from './utils'\n\nexport interface ConvoKitTheme {\n background: string\n surface: string\n primary: string\n text: string\n mutedText: string\n border: string\n error: string\n incomingBubble: string\n outgoingBubble: string\n outgoingText: string\n /** Unread badge and dot background (0.6.0); the badge label uses `outgoingText`. Defaults to the primary color. */\n badge: string\n radius: string\n avatarSize: string\n fontFamily: string\n}\n\nexport const defaultConvoKitTheme: ConvoKitTheme = {\n background: '#fafafa',\n surface: '#ffffff',\n primary: '#18181b',\n text: '#09090b',\n mutedText: '#71717a',\n border: '#e4e4e7',\n error: '#dc2626',\n incomingBubble: '#f4f4f5',\n outgoingBubble: '#18181b',\n outgoingText: '#fafafa',\n badge: '#18181b',\n radius: '10px',\n avatarSize: '40px',\n fontFamily: 'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif',\n}\n\nconst themeKey: InjectionKey<Readonly<Ref<ConvoKitTheme>>> = Symbol('ConvoKitTheme')\nconst defaultThemeRef = computed(() => defaultConvoKitTheme)\n\nexport const ConvoKitThemeProvider = defineComponent({\n name: 'ConvoKitThemeProvider',\n inheritAttrs: false,\n props: {\n theme: { type: Object as PropType<Partial<ConvoKitTheme>>, default: () => ({}) },\n class: { type: [String, Array, Object] as PropType<unknown>, default: undefined },\n style: { type: [String, Array, Object] as PropType<unknown>, default: undefined },\n },\n setup(props, { attrs, slots }) {\n const parent = inject(themeKey, defaultThemeRef)\n const value = computed(() => ({ ...parent.value, ...props.theme }))\n provide(themeKey, value)\n return () => {\n const theme = value.value\n const variables = {\n '--ckui-background': theme.background,\n '--ckui-surface': theme.surface,\n '--ckui-primary': theme.primary,\n '--ckui-text': theme.text,\n '--ckui-muted': theme.mutedText,\n '--ckui-border': theme.border,\n '--ckui-error': theme.error,\n '--ckui-incoming': theme.incomingBubble,\n '--ckui-outgoing': theme.outgoingBubble,\n '--ckui-outgoing-text': theme.outgoingText,\n '--ckui-badge': theme.badge,\n '--ckui-radius': theme.radius,\n '--ckui-avatar-size': theme.avatarSize,\n '--ckui-font': theme.fontFamily,\n } as CSSProperties\n return h('div', {\n ...attrs,\n class: cx('ckui-theme', props.class, attrs.class),\n style: [variables, props.style, attrs.style],\n }, slots.default?.())\n }\n },\n})\n\nexport function useConvoKitTheme(): Readonly<Ref<ConvoKitTheme>> {\n return inject(themeKey, defaultThemeRef)\n}\n"],"mappings":"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","names":["import_vue","import_vue","import_vue","import_sdk","version","import_vue","appearanceProps","import_vue","import_vue","blank","compare","options","appearanceProps","import_vue"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/components/avatar.ts","../src/utils.ts","../src/components/conversation.ts","../src/composables/use-conversation.ts","../src/conversation-store.ts","../src/components/message-list.ts","../src/components/conversation-list.ts","../src/composables/use-conversation-list.ts","../src/conversation-list-store.ts","../src/theme.ts"],"sourcesContent":["import './styles.css'\n\nexport { createConvoKitUiClient } from './client'\nexport { ConvoKitAvatar } from './components/avatar'\nexport { Conversation, ConversationView, type ConversationProps, type ConversationViewProps } from './components/conversation'\nexport { ConversationList, ConversationListView, type ConversationListProps, type ConversationListViewProps } from './components/conversation-list'\nexport { MessageListView, defaultReadersResolver, type MessageListViewProps } from './components/message-list'\nexport {\n useConversation,\n type ConversationController,\n type UseConversationOptions,\n} from './composables/use-conversation'\nexport {\n useConversationList,\n type ConversationListController,\n type UseConversationListOptions,\n} from './composables/use-conversation-list'\nexport {\n ConvoKitThemeProvider,\n defaultConvoKitTheme,\n useConvoKitTheme,\n type ConvoKitTheme,\n} from './theme'\nexport type {\n BaseViewProps,\n ComposerSlotProps,\n ConversationFilter,\n ConversationItemSlotProps,\n ConversationListState,\n ConversationPageLoader,\n ConversationPageRequest,\n ConversationState,\n ConvoKitAppearanceProps,\n ConvoKitUiClient,\n ConvoKitUiDensity,\n ConvoKitUiPart,\n ErrorSlot,\n ErrorSlotProps,\n MediaSlotProps,\n MessageSlotProps,\n ReadReceiptSlotProps,\n ScrollOptions,\n StateSlot,\n TypingSlotProps,\n} from './types'\nexport {\n applyConversationFilter,\n formatFileSize,\n isConvoKitPendingMessage,\n matchesConversation,\n mergeConversations,\n mergeInboxEntries,\n mergeMessages,\n readerIdsFor,\n} from './utils'\n","import type { ConvoKitClient } from '@convokitapp/sdk'\nimport type { ConvoKitUiClient } from './types'\n\n/** Adapts a connected `@convokitapp/sdk` client to the replaceable UI boundary. */\nexport function createConvoKitUiClient(client: ConvoKitClient): ConvoKitUiClient {\n return {\n get sessionIdentity() { return client.connected ? client.realtime : null },\n onConnectionEvent: (handlers) => client.realtime.onConnectionEvent(handlers),\n onInboxChanged: (handler, onError) => client.realtime.onInboxChanged(client.clientId, {\n onEvent: handler,\n ...(onError ? { onError } : {}),\n }),\n onInboxActivity: (handler, onError) => client.realtime.onInboxActivity(client.clientId, {\n onEvent: handler,\n ...(onError ? { onError } : {}),\n }),\n onMessageDeleted: (conversationId, handler, onError) => client.realtime.onMessageDeleted(conversationId, {\n onEvent: handler,\n ...(onError ? { onError } : {}),\n }),\n get currentUserId() { return client.connected ? client.currentUserId : '' },\n getConversations: (options) => client.getConversations(options),\n listInbox: (options) => client.listInbox(options),\n getConversation: (conversationId) => client.getConversation(conversationId),\n getMessages: (options) => client.getMessages(options),\n getMessage: (id) => client.getMessage(id),\n sendMessage: (input) => client.sendMessage(input),\n editMessage: (messageId, input) => client.editMessage(messageId, input),\n deleteMessage: (messageId) => client.deleteMessage(messageId),\n markConversationRead: (conversationId, options) => client.markConversationRead(conversationId, options),\n markConversationUnread: (conversationId) => client.markConversationUnread(conversationId),\n clearConversationUnread: (conversationId, options) => client.clearConversationUnread(conversationId, options),\n sendTyping: (input) => client.sendTyping(input),\n onMessage: (conversationId, handler, onError) => client.realtime.onMessage(conversationId, {\n onEvent: handler,\n ...(onError ? { onError } : {}),\n }),\n onReadReceipt: (conversationId, handler, onError) => client.realtime.onReadReceipt(conversationId, {\n onEvent: handler,\n ...(onError ? { onError } : {}),\n }),\n onTyping: (conversationId, handler, onError) => client.realtime.onTyping(conversationId, {\n onEvent: handler,\n ...(onError ? { onError } : {}),\n }),\n }\n}\n","import { AvatarFallback, AvatarImage, AvatarRoot } from 'reka-ui'\nimport { defineComponent, h, type PropType } from 'vue'\nimport { cx, initials } from '../utils'\n\n/** Accessible avatar built on Reka UI, the primitive layer used by shadcn-vue. */\nexport const ConvoKitAvatar = defineComponent({\n name: 'ConvoKitAvatar',\n inheritAttrs: false,\n props: {\n name: { type: String, required: true },\n src: { type: String as PropType<string | null>, default: null },\n },\n setup(props, { attrs }) {\n return () => h(AvatarRoot, {\n ...attrs,\n class: cx('ckui-avatar', attrs.class),\n }, {\n default: () => [\n props.src ? h(AvatarImage, { class: 'ckui-avatar__image', src: props.src, alt: '' }) : null,\n h(AvatarFallback, {\n class: 'ckui-avatar__fallback',\n ...(props.src ? { delayMs: 300 } : {}),\n }, () => initials(props.name)),\n ],\n })\n },\n})\n","import type { Conversation, InboxEntry, InboxSummary, Message, ReadPosition } from '@convokitapp/sdk'\nimport { readThrough } from '@convokitapp/sdk'\nimport { clsx } from 'clsx'\nimport { normalizeClass } from 'vue'\nimport type { CSSProperties } from 'vue'\nimport type { ConversationFilter, ConvoKitAppearanceProps, ConvoKitUiPart } from './types'\n\nconst pendingMessageIdPrefix = 'convokit-pending-'\n\n/** Message cursor order: createdAt, then id by UTF-16 code units (the server's TEXT order for its lowercase UUIDs). */\nexport function compareMessageOrder(left: Pick<Message, 'createdAt' | 'id'>, right: Pick<Message, 'createdAt' | 'id'>): number {\n return left.createdAt.getTime() - right.createdAt.getTime()\n || (left.id < right.id ? -1 : left.id > right.id ? 1 : 0)\n}\n\n/** Whether a message is an optimistic row awaiting server acknowledgement. */\nexport function isConvoKitPendingMessage(message: Message): boolean {\n return message.id.startsWith(pendingMessageIdPrefix)\n}\n\n/** Vue class attributes accept nested arrays/objects, including unknown attrs on Vue 3.4. */\nexport function cx(...values: unknown[]): string { return clsx(values.map(normalizeClass)) }\n\nfunction requestedParticipantIds(filter: ConversationFilter): ReadonlySet<string> {\n const values = filter.participantIds ?? []\n return values instanceof Set ? values : new Set(values)\n}\n\nexport function matchesConversation(conversation: Conversation, filter: ConversationFilter): boolean {\n const query = filter.query?.trim().toLocaleLowerCase() ?? ''\n if (query) {\n const haystack = [\n conversation.id,\n conversation.displayTitle,\n conversation.title ?? '',\n conversation.description ?? '',\n ...conversation.participants.flatMap((participant) => [participant.id, participant.appUserId, participant.name]),\n ].join(' ').toLocaleLowerCase()\n if (!haystack.includes(query)) return false\n }\n const requested = requestedParticipantIds(filter)\n if (requested.size > 0) {\n const available = new Set(conversation.participants.flatMap((participant) => [participant.id, participant.appUserId]))\n const values = [...requested]\n const matches = filter.requireAllParticipants\n ? values.every((id) => available.has(id))\n : values.some((id) => available.has(id))\n if (!matches) return false\n }\n return filter.predicate?.(conversation) ?? true\n}\n\nexport function applyConversationFilter(conversations: readonly Conversation[], filter: ConversationFilter): Conversation[] {\n const result = conversations.filter((conversation) => matchesConversation(conversation, filter))\n if (filter.comparator) result.sort(filter.comparator)\n return result\n}\n\nexport function mergeConversations(current: readonly Conversation[], incoming: readonly Conversation[]): Conversation[] {\n const byId = new Map(current.map((conversation) => [conversation.id, conversation]))\n for (const conversation of incoming) byId.set(conversation.id, conversation)\n return [...byId.values()]\n}\n\n/** Inbox order: newest activity first, ties by id descending in UTF-16 code units (the server's TEXT order). */\nexport function compareInboxOrder(left: InboxEntry, right: InboxEntry): number {\n return right.activityAt.getTime() - left.activityAt.getTime()\n || (left.conversation.id < right.conversation.id ? 1 : left.conversation.id > right.conversation.id ? -1 : 0)\n}\n\n/** Merge inbox pages by conversation ID: a later entry replaces an earlier one (its room moved), and the result is\n * re-ordered by `(activityAt desc, id desc)`. Server order is authoritative within a page; this is the rule applied\n * whenever pages are combined (load more, refresh).\n */\nexport function mergeInboxEntries(current: readonly InboxEntry[], incoming: readonly InboxEntry[]): InboxEntry[] {\n const byId = new Map(current.map((entry) => [entry.conversation.id, entry]))\n for (const entry of incoming) byId.set(entry.conversation.id, entry)\n return [...byId.values()].sort(compareInboxOrder)\n}\n\n/** The default row's one-line preview, or `''` when the row should keep its participants/description line. */\nexport function inboxPreview(conversation: Conversation, summary: InboxSummary | undefined, currentUserId: string | undefined): string {\n const message = summary?.latestMessage\n if (!message) return ''\n const first = message.media[0]\n const body = message.text?.trim() || (!first ? ''\n : first.type === 'image' ? 'Photo'\n : first.type === 'file' ? first.name?.trim() || 'File'\n : first.type === 'location' ? 'Location'\n : first.type === 'contact' ? 'Contact' : '')\n if (!body) return ''\n if (currentUserId !== undefined && message.senderId === currentUserId) return `You: ${body}`\n if (conversation.participants.length > 2) {\n const sender = conversation.participants.find((participant) => participant.appUserId === message.senderId || participant.id === message.senderId)\n const name = sender?.name.trim()\n if (name) return `${name}: ${body}`\n }\n return body\n}\n\n/** Device-zone clock time, shared by message rows and inbox rows. */\nexport function formatMessageTime(date: Date): string {\n return new Intl.DateTimeFormat(undefined, { hour: 'numeric', minute: '2-digit' }).format(date)\n}\n\nexport function mergeMessages(current: readonly Message[], incoming: readonly Message[]): Message[] {\n const byId = new Map(current.map((message) => [message.id, message]))\n for (const message of incoming) byId.set(message.id, message)\n return [...byId.values()].sort((left, right) => {\n const leftPending = isConvoKitPendingMessage(left)\n const rightPending = isConvoKitPendingMessage(right)\n if (leftPending !== rightPending) return leftPending ? 1 : -1\n return compareMessageOrder(left, right)\n })\n}\n\n/** Readers of a message under the unified rule: a user's read position (createdAt, id) wins when present,\n * otherwise the acknowledgement time is compared with createdAt (legacy participants, empty-room acknowledgements).\n * The sender and pending rows never have readers.\n */\nexport function readerIdsFor(\n message: Message,\n readAtByUserId: ReadonlyMap<string, Date>,\n readPositionByUserId: ReadonlyMap<string, ReadPosition> = new Map(),\n): ReadonlySet<string> {\n if (isConvoKitPendingMessage(message)) return new Set()\n const userIds = new Set([...readAtByUserId.keys(), ...readPositionByUserId.keys()])\n return new Set([...userIds].filter((userId) => userId !== message.senderId && readThrough({\n readPosition: readPositionByUserId.get(userId) ?? null, lastReadAt: readAtByUserId.get(userId) ?? null,\n }, message)))\n}\n\nexport function partClass(part: ConvoKitUiPart, appearance: ConvoKitAppearanceProps, defaultClass: string): string {\n return cx(!appearance.unstyled && defaultClass, appearance.classNames?.[part])\n}\n\nexport function partStyle(part: ConvoKitUiPart, appearance: ConvoKitAppearanceProps): CSSProperties | undefined {\n return appearance.styles?.[part]\n}\n\nexport function errorMessage(error: unknown): string { return error instanceof Error ? error.message : String(error) }\n\nexport function formatFileSize(size: number | undefined): string | null {\n if (size === undefined || !Number.isFinite(size) || size < 0) return null\n if (size < 1024) return `${Math.round(size)} B`\n if (size < 1024 * 1024) return `${(size / 1024).toFixed(size < 10 * 1024 ? 1 : 0)} KB`\n return `${(size / (1024 * 1024)).toFixed(size < 10 * 1024 * 1024 ? 1 : 0)} MB`\n}\n\nexport function initials(value: string): string {\n const words = value.trim().split(/\\s+/).filter(Boolean)\n return (words.length > 1 ? `${words[0]?.[0] ?? ''}${words.at(-1)?.[0] ?? ''}` : value[0] ?? '?').toLocaleUpperCase()\n}\n","import type { Conversation as ConversationModel, Message, MessageMedia, ReadPosition } from '@convokitapp/sdk'\nimport { ArrowLeft, Check, LoaderCircle, Paperclip, Pencil, RefreshCw, Send } from '@lucide/vue'\nimport {\n defineComponent,\n h,\n onBeforeUnmount,\n ref,\n watch,\n watchEffect,\n type CSSProperties,\n type PropType,\n type TextareaHTMLAttributes,\n type VNodeChild,\n} from 'vue'\nimport type { ConversationController, UseConversationOptions } from '../composables/use-conversation'\nimport { useConversation } from '../composables/use-conversation'\nimport type {\n ComposerSlotProps,\n ConvoKitAppearanceProps,\n ConvoKitUiClient,\n ConvoKitUiDensity,\n ConvoKitUiPart,\n TypingSlotProps,\n} from '../types'\nimport { cx, errorMessage, partClass, partStyle } from '../utils'\nimport { ConvoKitAvatar } from './avatar'\nimport { MessageListView } from './message-list'\n\nexport interface ConversationViewProps extends ConvoKitAppearanceProps {\n conversation: ConversationModel\n messages: readonly Message[]\n currentUserId: string\n onSendMessage: (text: string) => boolean | void | Promise<boolean | void>\n typingUserIds?: ReadonlySet<string>\n readAtByUserId?: ReadonlyMap<string, Date>\n readPositionByUserId?: ReadonlyMap<string, ReadPosition>\n readersResolver?: (message: Message) => ReadonlySet<string>\n onBack?: () => void\n onRefresh?: () => void | Promise<void>\n onLoadOlder?: () => void | Promise<void>\n onTypingChange?: (isTyping: boolean) => void | Promise<void>\n onAddAttachment?: () => void\n onAttachmentClick?: (media: MessageMedia, message: Message) => void\n /** The message being edited (0.8.0), or null. Entering edit mode stashes the unsent draft and prefills the field\n * with the message text without a typing update; the composer then saves instead of sending.\n */\n editingMessage?: Message | null\n /** Start editing a message (0.8.0): set `editingMessage` in response. Without it rows offer no edit action. */\n onEditMessage?: (message: Message) => void\n /** Save the edit in progress (0.8.0); the composer's submit calls it instead of `onSendMessage` while\n * `editingMessage` is set. `false` keeps edit mode and the draft (like `onSendMessage`); any other result\n * restores the stashed unsent draft. Clear `editingMessage` when the edit is done.\n */\n onSaveEdit?: (message: Message, text: string) => boolean | void | Promise<boolean | void>\n /** Leave edit mode (0.8.0): clear `editingMessage` in response; the view restores the unsent draft. */\n onCancelEdit?: () => void\n /** Delete a message after confirmation (0.8.0); `false` means it was not accepted. Without it rows offer no\n * delete action.\n */\n onDeleteMessage?: (message: Message) => boolean | void | Promise<boolean | void>\n /** Replaces the default row eligibility (own confirmed rows while the viewer's role is not `READ`). */\n canEditMessage?: (message: Message) => boolean\n /** Replaces the inline \"Delete this message?\" prompt (and confirms `remove()` from custom rows). */\n confirmDelete?: (message: Message) => boolean | Promise<boolean>\n isInitialLoading?: boolean\n isLoadingOlder?: boolean\n isSending?: boolean\n hasOlderMessages?: boolean\n error?: unknown\n messageError?: unknown\n displayNameForUser?: (userId: string) => string | null | undefined\n reverseMessages?: boolean\n stickToBottom?: boolean\n paginationThreshold?: number\n formatTime?: (date: Date) => string\n imageLoading?: 'eager' | 'lazy'\n composerPlaceholder?: string\n composerAriaLabel?: string\n composerProps?: Omit<TextareaHTMLAttributes, 'value' | 'disabled'>\n modelValue?: string\n defaultDraft?: string\n onDraftChange?: (value: string) => void\n class?: unknown\n style?: unknown\n}\n\nconst appearanceProps = {\n classNames: { type: Object as PropType<Partial<Record<ConvoKitUiPart, string>>>, default: undefined },\n styles: { type: Object as PropType<Partial<Record<ConvoKitUiPart, CSSProperties>>>, default: undefined },\n density: { type: String as PropType<ConvoKitUiDensity>, default: 'comfortable' },\n unstyled: { type: Boolean, default: false },\n} as const\n\nconst viewProps = {\n ...appearanceProps,\n conversation: { type: Object as PropType<ConversationModel>, required: true },\n messages: { type: Array as PropType<readonly Message[]>, required: true },\n currentUserId: { type: String, required: true },\n onSendMessage: { type: Function as PropType<(text: string) => boolean | void | Promise<boolean | void>>, required: true },\n typingUserIds: { type: Object as PropType<ReadonlySet<string>>, default: () => new Set() },\n readAtByUserId: { type: Object as PropType<ReadonlyMap<string, Date>>, default: () => new Map() },\n readPositionByUserId: { type: Object as PropType<ReadonlyMap<string, ReadPosition>>, default: () => new Map() },\n readersResolver: { type: Function as PropType<(message: Message) => ReadonlySet<string>>, default: undefined },\n onBack: { type: Function as PropType<() => void>, default: undefined },\n onRefresh: { type: Function as PropType<() => void | Promise<void>>, default: undefined },\n onLoadOlder: { type: Function as PropType<() => void | Promise<void>>, default: undefined },\n onTypingChange: { type: Function as PropType<(isTyping: boolean) => void | Promise<void>>, default: undefined },\n onAddAttachment: { type: Function as PropType<() => void>, default: undefined },\n onAttachmentClick: { type: Function as PropType<(media: MessageMedia, message: Message) => void>, default: undefined },\n editingMessage: { type: Object as PropType<Message | null>, default: null },\n onEditMessage: { type: Function as PropType<(message: Message) => void>, default: undefined },\n onSaveEdit: { type: Function as PropType<(message: Message, text: string) => boolean | void | Promise<boolean | void>>, default: undefined },\n onCancelEdit: { type: Function as PropType<() => void>, default: undefined },\n onDeleteMessage: { type: Function as PropType<(message: Message) => boolean | void | Promise<boolean | void>>, default: undefined },\n canEditMessage: { type: Function as PropType<(message: Message) => boolean>, default: undefined },\n confirmDelete: { type: Function as PropType<(message: Message) => boolean | Promise<boolean>>, default: undefined },\n isInitialLoading: { type: Boolean, default: false },\n isLoadingOlder: { type: Boolean, default: false },\n isSending: { type: Boolean, default: false },\n hasOlderMessages: { type: Boolean, default: false },\n error: { type: null as unknown as PropType<unknown>, required: false },\n messageError: { type: null as unknown as PropType<unknown>, required: false },\n displayNameForUser: { type: Function as PropType<(userId: string) => string | null | undefined>, default: undefined },\n reverseMessages: { type: Boolean, default: true },\n stickToBottom: { type: Boolean, default: true },\n paginationThreshold: { type: Number, default: 240 },\n formatTime: { type: Function as PropType<(date: Date) => string>, default: undefined },\n imageLoading: { type: String as PropType<'eager' | 'lazy'>, default: 'lazy' },\n composerPlaceholder: { type: String, default: 'Write a message' },\n composerAriaLabel: { type: String, default: 'Message' },\n composerProps: { type: Object as PropType<Omit<TextareaHTMLAttributes, 'value' | 'disabled'>>, default: undefined },\n modelValue: { type: String, default: undefined },\n defaultDraft: { type: String, default: '' },\n onDraftChange: { type: Function as PropType<(value: string) => void>, default: undefined },\n} as const\n\n/** The edit banner's summary of the message: its text, or its attachments when the caption is empty. */\nfunction editingSummary(message: Message): string {\n return message.text?.trim() || (message.media.length === 1 ? '1 attachment' : `${message.media.length} attachments`)\n}\n\nfunction typingLabel(userIds: ReadonlySet<string>, displayNameForUser: (userId: string) => string): string {\n const names = [...userIds].map(displayNameForUser)\n if (names.length === 0) return ''\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 `${names[0]} and ${names.length - 1} others are typing…`\n}\n\n/** Controlled, complete selected-conversation surface. */\nexport const ConversationView = defineComponent({\n name: 'ConversationView',\n inheritAttrs: false,\n props: viewProps,\n emits: [\n 'send-message', 'typing-change', 'back', 'refresh', 'load-older',\n 'add-attachment', 'attachment-click', 'update:modelValue',\n 'edit-message', 'save-edit', 'cancel-edit', 'delete-message',\n ],\n setup(props, { attrs, emit, slots }) {\n const internalDraft = ref(props.defaultDraft)\n const submitting = ref(false)\n const appearance = (): ConvoKitAppearanceProps => ({\n density: props.density,\n unstyled: props.unstyled,\n ...(props.classNames ? { classNames: props.classNames } : {}),\n ...(props.styles ? { styles: props.styles } : {}),\n })\n const draft = () => props.modelValue ?? internalDraft.value\n let latestDraft = draft()\n // Edit mode (0.8.0) is the host's/store's (`editingMessage`); the view owns the draft: the unsent draft is\n // stashed on entry and the field prefilled silently (no typing update). Cancel and a successful save restore\n // the stash; an external end (the row removed) keeps text the user changed and restores the stash otherwise.\n /** The unsent draft stashed on entering edit mode; undefined while not editing. */\n let stash: string | undefined\n /** A save request is in flight: its continuation, not the `editingMessage` watcher, settles the draft. */\n let saving = false\n const setDraft = (value: string, typing = true) => {\n latestDraft = value\n if (props.modelValue === undefined) internalDraft.value = value\n props.onDraftChange?.(value)\n emit('update:modelValue', value)\n if (typing) void props.onTypingChange?.(value.trim().length > 0)\n }\n const enterEdit = (message: Message) => {\n if (stash === undefined) stash = draft()\n setDraft(message.text ?? '', false)\n }\n /** Leave edit mode in the view: restore the stash always, or only when the field is empty or still the snapshot's text. */\n const leaveEdit = (message: Message, restore: 'always' | 'unchanged') => {\n if (stash === undefined) return\n const saved = stash\n stash = undefined\n const current = draft()\n if (restore === 'always' || current.trim() === '' || current === (message.text ?? '')) setDraft(saved)\n }\n watch(() => props.editingMessage, (next, previous) => {\n if (next && (!previous || previous.id !== next.id)) enterEdit(next)\n else if (!next && previous && !saving) leaveEdit(previous, 'unchanged')\n }, { immediate: true })\n const cancelEdit = () => {\n const editing = props.editingMessage\n if (!editing) return\n leaveEdit(editing, 'always')\n props.onCancelEdit?.()\n }\n /** Save is possible while the field has text or the edited row has attachments (an empty caption). */\n const canSave = (editing: Message) => draft().trim().length > 0 || editing.media.length > 0\n const submit = async () => {\n const editing = props.editingMessage\n if (editing) {\n const text = draft().trim()\n if (!canSave(editing) || props.isSending || submitting.value) return\n submitting.value = true\n saving = true\n try {\n // The field keeps the edited text during the request; a failure or a conflict leaves it in place.\n const saved = await props.onSaveEdit?.(editing, text)\n if (saved === false) {\n if (props.editingMessage === null) leaveEdit(editing, 'unchanged')\n return\n }\n leaveEdit(editing, 'always')\n } finally {\n saving = false\n submitting.value = false\n }\n return\n }\n const originalDraft = draft()\n const text = originalDraft.trim()\n if (!text || props.isSending || submitting.value) return\n submitting.value = true\n setDraft('')\n try {\n const shouldClear = await props.onSendMessage(text)\n if (shouldClear === false && latestDraft.length === 0) setDraft(originalDraft)\n } finally {\n submitting.value = false\n }\n }\n const nameForUser = (userId: string) => {\n const custom = props.displayNameForUser?.(userId)?.trim()\n if (custom) return custom\n const participant = props.conversation.participants.find((value) => value.id === userId || value.appUserId === userId)\n return participant?.name.trim() || userId\n }\n const goBack = () => { props.onBack?.() }\n const refresh = () => props.onRefresh?.()\n const loadOlder = () => props.onLoadOlder?.()\n const addAttachment = () => { props.onAddAttachment?.() }\n\n const renderHeader = (): VNodeChild => {\n const slotProps = {\n conversation: props.conversation,\n ...(props.onBack ? { onBack: goBack } : {}),\n ...(props.onRefresh ? { onRefresh: refresh } : {}),\n }\n return slots.header?.(slotProps) ?? h('header', {\n class: partClass('header', appearance(), 'ckui-conversation-header'),\n style: partStyle('header', appearance()),\n }, [\n props.onBack ? h('button', {\n type: 'button', 'aria-label': 'Back', onClick: goBack,\n class: partClass('button', appearance(), 'ckui-icon-button'),\n style: partStyle('button', appearance()),\n }, [h(ArrowLeft, { size: 20, 'aria-hidden': 'true' })]) : null,\n h(ConvoKitAvatar, { name: props.conversation.displayTitle, src: props.conversation.imageUrl }),\n h('div', { class: 'ckui-conversation-header__body' }, [\n h('strong', props.conversation.displayTitle),\n h('span', `${props.conversation.participants.length} participant${props.conversation.participants.length === 1 ? '' : 's'}`),\n ]),\n props.onRefresh ? h('button', {\n type: 'button', 'aria-label': 'Refresh conversation', onClick: () => { void refresh() },\n class: partClass('button', appearance(), 'ckui-icon-button'),\n style: partStyle('button', appearance()),\n }, [h(RefreshCw, { size: 18, 'aria-hidden': 'true' })]) : null,\n ])\n }\n\n const renderTyping = (): VNodeChild => {\n const slotProps: TypingSlotProps = { userIds: props.typingUserIds, displayNameForUser: nameForUser }\n return slots['typing-indicator']?.(slotProps) ?? h('div', {\n class: partClass('typing', appearance(), 'ckui-typing'),\n style: partStyle('typing', appearance()),\n 'aria-live': 'polite',\n }, typingLabel(props.typingUserIds, nameForUser))\n }\n\n const renderComposer = (): VNodeChild => {\n const editing = props.editingMessage\n const slotProps: ComposerSlotProps = {\n value: draft(), setValue: setDraft, isSending: props.isSending || submitting.value,\n send: () => { void submit() },\n ...(props.onAddAttachment ? { addAttachment } : {}),\n ...(editing ? { editing, cancelEdit } : {}),\n }\n const busy = props.isSending || submitting.value\n return slots.composer?.(slotProps) ?? h('form', {\n class: cx(partClass('composer', appearance(), 'ckui-composer'), editing && !props.unstyled && 'ckui-composer--editing'),\n style: partStyle('composer', appearance()),\n onSubmit: (event: Event) => { event.preventDefault(); void submit() },\n }, [\n // Spread, not null: outside edit mode the composer markup stays byte-identical to 0.7.\n ...(editing ? [h('div', { class: 'ckui-composer__editing', role: 'status' }, [\n h(Pencil, { size: 14, 'aria-hidden': 'true' }),\n h('span', { class: 'ckui-composer__editing-body' }, [\n h('strong', 'Editing message'),\n h('span', editingSummary(editing)),\n ]),\n h('button', { type: 'button', class: 'ckui-link-button', 'aria-label': 'Cancel editing', onClick: cancelEdit }, 'Cancel'),\n ])] : []),\n props.onAddAttachment ? h('button', {\n type: 'button', 'aria-label': 'Add attachment', onClick: addAttachment,\n class: partClass('button', appearance(), 'ckui-icon-button'),\n style: partStyle('button', appearance()),\n }, [h(Paperclip, { size: 20, 'aria-hidden': 'true' })]) : null,\n h('textarea', {\n ...props.composerProps,\n rows: props.composerProps?.rows ?? 1,\n placeholder: props.composerPlaceholder,\n 'aria-label': props.composerAriaLabel,\n class: cx(!props.unstyled && 'ckui-composer__input', props.classNames?.input, props.composerProps?.class),\n style: [props.styles?.input, props.composerProps?.style],\n value: draft(),\n onInput: (event: InputEvent) => {\n const handler = props.composerProps?.onInput\n if (typeof handler === 'function') handler(event)\n if (!event.defaultPrevented) setDraft((event.currentTarget as HTMLTextAreaElement).value)\n },\n onKeydown: (event: KeyboardEvent) => {\n const handler = props.composerProps?.onKeydown\n if (typeof handler === 'function') handler(event)\n if (event.defaultPrevented) return\n if (event.key === 'Enter' && !event.shiftKey) { event.preventDefault(); void submit() }\n if (event.key === 'Escape' && props.editingMessage) { event.preventDefault(); cancelEdit() }\n },\n }),\n h('button', {\n type: 'submit', 'aria-label': editing ? 'Save message' : 'Send message',\n disabled: (editing ? !canSave(editing) : !draft().trim()) || busy,\n class: partClass('button', appearance(), 'ckui-send-button'),\n style: partStyle('button', appearance()),\n }, [busy\n ? h(LoaderCircle, { class: 'ckui-spin', size: 18, 'aria-hidden': 'true' })\n : h(editing ? Check : Send, { size: 18, 'aria-hidden': 'true' })]),\n ])\n }\n\n return () => {\n if (props.isInitialLoading && props.messages.length === 0) {\n return h('div', {\n ...attrs,\n class: cx(!props.unstyled && 'ckui ckui-conversation', props.classNames?.root, attrs.class),\n style: [props.styles?.root, attrs.style],\n 'data-density': props.density,\n }, slots.loading?.() ?? h('div', {\n class: partClass('loading', appearance(), 'ckui-state'), style: partStyle('loading', appearance()), role: 'status',\n }, [h(LoaderCircle, { class: 'ckui-spin', 'aria-hidden': 'true' }), ' Loading conversation…']))\n }\n const children: VNodeChild[] = [renderHeader()]\n if (props.error) {\n const retry = props.onRefresh ? () => { void refresh() } : undefined\n children.push(slots.error?.({ error: props.error, ...(retry ? { retry } : {}) }) ?? h('div', {\n class: partClass('error', appearance(), 'ckui-conversation-error'),\n style: partStyle('error', appearance()), role: 'alert',\n }, [h('span', errorMessage(props.error)), retry ? h('button', { type: 'button', class: 'ckui-link-button', onClick: retry }, 'Retry') : null]))\n }\n const messageSlots = {\n ...(slots.message ? { message: slots.message } : {}),\n ...(slots.media ? { media: slots.media } : {}),\n ...(slots['read-receipt'] ? { 'read-receipt': slots['read-receipt'] } : {}),\n ...(slots.empty ? { empty: slots.empty } : {}),\n ...(slots['loading-older'] ? { 'loading-older': slots['loading-older'] } : {}),\n ...(slots['message-error'] ? { error: slots['message-error'] } : {}),\n }\n children.push(h(MessageListView, {\n conversation: props.conversation,\n messages: props.messages,\n currentUserId: props.currentUserId,\n readAtByUserId: props.readAtByUserId,\n readPositionByUserId: props.readPositionByUserId,\n ...(props.readersResolver ? { readersResolver: props.readersResolver } : {}),\n ...(props.onLoadOlder ? { onLoadOlder: loadOlder } : {}),\n hasOlderMessages: props.hasOlderMessages,\n isLoadingOlder: props.isLoadingOlder,\n ...(props.messageError == null ? {} : { error: props.messageError }),\n ...(props.onAttachmentClick ? { onAttachmentClick: (media: MessageMedia, message: Message) => {\n props.onAttachmentClick?.(media, message)\n } } : {}),\n ...(props.onEditMessage ? { onEditMessage: (message: Message) => { props.onEditMessage?.(message) } } : {}),\n ...(props.onDeleteMessage ? { onDeleteMessage: (message: Message) => props.onDeleteMessage?.(message) } : {}),\n ...(props.canEditMessage ? { canEditMessage: props.canEditMessage } : {}),\n ...(props.confirmDelete ? { confirmDelete: props.confirmDelete } : {}),\n reverse: props.reverseMessages,\n stickToBottom: props.stickToBottom,\n paginationThreshold: props.paginationThreshold,\n ...(props.formatTime ? { formatTime: props.formatTime } : {}),\n imageLoading: props.imageLoading,\n ...(props.classNames ? { classNames: props.classNames } : {}),\n ...(props.styles ? { styles: props.styles } : {}),\n density: props.density,\n unstyled: props.unstyled,\n }, messageSlots))\n children.push(renderTyping(), renderComposer())\n return h('section', {\n ...attrs,\n class: cx(!props.unstyled && 'ckui ckui-conversation', props.classNames?.root, attrs.class),\n style: [props.styles?.root, attrs.style],\n 'data-density': props.density,\n 'aria-label': props.conversation.displayTitle,\n }, children)\n }\n },\n})\n\nexport interface ConversationProps extends Omit<ConversationViewProps,\n 'conversation' | 'messages' | 'currentUserId' | 'onSendMessage' | 'typingUserIds' |\n 'readAtByUserId' | 'readPositionByUserId' | 'onRefresh' | 'onLoadOlder' | 'onTypingChange' |\n 'isInitialLoading' | 'isLoadingOlder' | 'isSending' | 'hasOlderMessages' | 'error' |\n 'editingMessage' | 'onEditMessage' | 'onSaveEdit' | 'onCancelEdit' | 'onDeleteMessage'>,\n Omit<UseConversationOptions, 'client' | 'conversationId'> {\n client: ConvoKitUiClient\n conversationId: string\n onControllerChange?: (controller: ConversationController) => void\n}\n\n/** Plug-and-play SDK-backed UI for one conversation. */\nexport const Conversation = defineComponent({\n name: 'Conversation',\n inheritAttrs: false,\n props: {\n ...viewProps,\n conversation: { type: Object as PropType<ConversationModel>, default: undefined },\n messages: { type: Array as PropType<readonly Message[]>, default: () => [] },\n currentUserId: { type: String, default: '' },\n onSendMessage: { type: Function as PropType<(text: string) => boolean | void | Promise<boolean | void>>, default: undefined },\n editingMessage: { type: Object as PropType<Message | null>, default: undefined },\n onEditMessage: { type: Function as PropType<(message: Message) => void>, default: undefined },\n onSaveEdit: { type: Function as PropType<(message: Message, text: string) => boolean | void | Promise<boolean | void>>, default: undefined },\n onCancelEdit: { type: Function as PropType<() => void>, default: undefined },\n onDeleteMessage: { type: Function as PropType<(message: Message) => boolean | void | Promise<boolean | void>>, default: undefined },\n client: { type: Object as PropType<ConvoKitUiClient>, required: true },\n conversationId: { type: String, required: true },\n messagePageSize: { type: Number, default: 30 },\n markReadOnLoad: { type: Boolean, default: true },\n markReadOnReceive: { type: Boolean, default: true },\n typingTimeoutMs: { type: Number, default: 3000 },\n autoLoad: { type: Boolean, default: true },\n onControllerChange: { type: Function as PropType<(controller: ConversationController) => void>, default: undefined },\n },\n emits: [\n 'controller-change', 'send-message', 'typing-change', 'back', 'refresh', 'load-older', 'add-attachment', 'attachment-click', 'update:modelValue',\n 'edit-message', 'save-edit', 'cancel-edit', 'delete-message',\n ],\n setup(props, { attrs, emit, expose, slots }) {\n const controller = useConversation({\n client: () => props.client,\n conversationId: () => props.conversationId,\n messagePageSize: props.messagePageSize,\n markReadOnLoad: props.markReadOnLoad,\n markReadOnReceive: props.markReadOnReceive,\n typingTimeoutMs: props.typingTimeoutMs,\n autoLoad: props.autoLoad,\n })\n expose({ controller })\n watchEffect(() => {\n emit('controller-change', controller)\n })\n // Automatic acknowledgements only while the document is visible; prerender/unknown/no document count as visible.\n if (typeof document !== 'undefined') {\n const syncVisibility = () => controller.setVisible(document.visibilityState !== 'hidden')\n syncVisibility()\n document.addEventListener('visibilitychange', syncVisibility)\n onBeforeUnmount(() => document.removeEventListener('visibilitychange', syncVisibility))\n }\n return () => {\n const loadedConversation = controller.conversation.value\n if (!loadedConversation) {\n const retry = () => { void controller.refresh() }\n return h('div', {\n ...attrs,\n class: cx(!props.unstyled && 'ckui ckui-conversation', props.classNames?.root, attrs.class),\n style: [props.styles?.root, attrs.style],\n 'data-density': props.density,\n }, controller.error.value\n ? slots.error?.({ error: controller.error.value, retry }) ?? h('div', { class: 'ckui-state ckui-state--error', role: 'alert' }, [\n h('span', errorMessage(controller.error.value)),\n h('button', { type: 'button', class: 'ckui-link-button', onClick: retry }, 'Try again'),\n ])\n : slots.loading?.() ?? h('div', { class: 'ckui-state', role: 'status' }, [\n h(LoaderCircle, { class: 'ckui-spin', 'aria-hidden': 'true' }), ' Loading conversation…',\n ]))\n }\n const {\n client: _client,\n conversationId: _conversationId,\n messagePageSize: _messagePageSize,\n markReadOnLoad: _markReadOnLoad,\n markReadOnReceive: _markReadOnReceive,\n typingTimeoutMs: _typingTimeoutMs,\n autoLoad: _autoLoad,\n onControllerChange: _onControllerChange,\n conversation: _conversation,\n messages: _messages,\n currentUserId: _currentUserId,\n onSendMessage: _onSendMessage,\n typingUserIds: _typingUserIds,\n readAtByUserId: _readAtByUserId,\n readPositionByUserId: _readPositionByUserId,\n onRefresh: _onRefresh,\n onLoadOlder: _onLoadOlder,\n onTypingChange: _onTypingChange,\n isInitialLoading: _isInitialLoading,\n isLoadingOlder: _isLoadingOlder,\n isSending: _isSending,\n hasOlderMessages: _hasOlderMessages,\n error: _error,\n editingMessage: _editingMessage,\n onEditMessage: _onEditMessage,\n onSaveEdit: _onSaveEdit,\n onCancelEdit: _onCancelEdit,\n onDeleteMessage: _onDeleteMessage,\n ...forwarded\n } = props\n return h(ConversationView, {\n ...attrs,\n ...forwarded,\n conversation: loadedConversation,\n messages: controller.messages.value,\n currentUserId: controller.currentUserId.value,\n onSendMessage: async (text: string) => {\n emit('send-message', text)\n return (await controller.sendMessage({ text })) !== null\n },\n typingUserIds: controller.typingUserIds.value,\n readAtByUserId: controller.readAtByUserId.value,\n readPositionByUserId: controller.readPositionByUserId.value,\n onRefresh: controller.refresh,\n onLoadOlder: controller.loadOlderMessages,\n onTypingChange: controller.updateTyping,\n isInitialLoading: controller.isInitialLoading.value,\n isLoadingOlder: controller.isLoadingOlder.value,\n isSending: controller.isSending.value,\n hasOlderMessages: controller.hasOlderMessages.value,\n ...(controller.error.value == null ? {} : { error: controller.error.value }),\n // Edit mode is the store's; the actions render only while the adapter supports them (0.8.0).\n editingMessage: controller.editingMessage.value,\n ...(controller.canEditMessages.value ? {\n onEditMessage: (message: Message) => { emit('edit-message', message); controller.startEditing(message.id) },\n onSaveEdit: async (message: Message, text: string) => { emit('save-edit', message, text); return controller.saveEdit(text) },\n onCancelEdit: () => { emit('cancel-edit'); controller.cancelEditing() },\n } : {}),\n ...(controller.canDeleteMessages.value ? {\n onDeleteMessage: async (message: Message) => { emit('delete-message', message); return controller.deleteMessage(message.id) },\n } : {}),\n 'onUpdate:modelValue': (value: string) => emit('update:modelValue', value),\n ...(props.onBack ? { onBack: () => { props.onBack?.(); emit('back') } } : {}),\n ...(props.onAddAttachment ? { onAddAttachment: () => { props.onAddAttachment?.(); emit('add-attachment') } } : {}),\n ...(props.onAttachmentClick ? { onAttachmentClick: (media: MessageMedia, message: Message) => {\n props.onAttachmentClick?.(media, message)\n emit('attachment-click', media, message)\n } } : {}),\n } as never, slots)\n }\n },\n})\n","import type { Message, MessageMedia } from '@convokitapp/sdk'\nimport { computed, getCurrentScope, onScopeDispose, shallowRef, toValue, watch, type MaybeRefOrGetter } from 'vue'\nimport type { ConversationState, ConvoKitUiClient } from '../types'\nimport { ConversationStore, type ConversationSnapshot } from '../conversation-store'\n\nexport interface UseConversationOptions {\n client: MaybeRefOrGetter<ConvoKitUiClient>\n conversationId: MaybeRefOrGetter<string>\n messagePageSize?: number\n markReadOnLoad?: boolean\n markReadOnReceive?: boolean\n typingTimeoutMs?: number\n autoLoad?: boolean\n}\nexport interface ConversationController extends ConversationState {\n loadInitial(): Promise<void>\n refresh(): Promise<void>\n loadOlderMessages(): Promise<void>\n sendMessage(input: { text?: string; media?: MessageMedia[] }): Promise<Message | null>\n /** Enter edit mode on one of the caller's own confirmed messages (0.8.0); a no-op for other rows, for a `READ`\n * role and for adapters without `editMessage`. Sends nothing (no typing update either).\n */\n startEditing(messageId: string): void\n /** Leave edit mode without a request. */\n cancelEditing(): void\n /** Save the edit in progress with the snapshot's revision; resolves true when the server accepted it. A stale\n * revision reloads the row, refreshes `editingMessage` and reports `REVISION_CONFLICT` through `error` (edit mode\n * and draft kept); see the README for the other outcomes. Rejects when the adapter lacks `editMessage`.\n */\n saveEdit(text: string): Promise<boolean>\n /** Delete one of the caller's own confirmed messages; resolves true once the row is gone (accepted, or already\n * unknown to the server). No optimistic removal. Rejects when the adapter lacks `deleteMessage`.\n */\n deleteMessage(messageId: string): Promise<boolean>\n /** Acknowledge through the newest rendered message now; no request is sent while nothing is rendered. */\n markRead(): Promise<void>\n /** Automatic acknowledgements pause while hidden and resume when the view becomes visible again. */\n setVisible(visible: boolean): void\n updateTyping(isTyping: boolean): Promise<void>\n dispose(): Promise<void>\n}\n\n/** Each room/login gets an independent owner; disposal also stops reactive reloads. */\nexport function useConversation(options: UseConversationOptions): ConversationController {\n const createStore = () => new ConversationStore({\n ...options, client: toValue(options.client), conversationId: toValue(options.conversationId),\n })\n let store = createStore()\n const snapshot = shallowRef(store.getSnapshot())\n let unsubscribe: (() => void) | undefined\n let visible = true\n const stop = watch(\n () => [toValue(options.client), toValue(options.client).sessionIdentity, toValue(options.conversationId)] as const,\n () => {\n store.dispose()\n unsubscribe?.()\n store = createStore()\n snapshot.value = store.getSnapshot()\n unsubscribe = store.subscribe(() => { snapshot.value = store.getSnapshot() })\n store.setVisible(visible)\n store.start(options.autoLoad ?? true)\n },\n { immediate: true, flush: 'sync' },\n )\n const field = <K extends keyof ConversationSnapshot>(key: K) => computed(() => snapshot.value[key])\n const dispose = async () => {\n stop()\n store.dispose()\n unsubscribe?.()\n unsubscribe = undefined\n }\n if (getCurrentScope()) onScopeDispose(() => { void dispose() })\n return {\n conversation: field('conversation'), messages: field('messages'),\n typingUserIds: field('typingUserIds'), readAtByUserId: field('readAtByUserId'),\n readPositionByUserId: field('readPositionByUserId'),\n isInitialLoading: field('isInitialLoading'), isLoadingOlder: field('isLoadingOlder'),\n isReconciling: field('isReconciling'), isSending: field('isSending'),\n hasOlderMessages: field('hasOlderMessages'), hasLoaded: field('hasLoaded'),\n error: field('error'), currentUserId: field('currentUserId'),\n editingMessage: field('editingMessage'), canEditMessages: field('canEditMessages'), canDeleteMessages: field('canDeleteMessages'),\n readerIdsFor: (message) => store.readerIdsFor(message),\n loadInitial: () => store.loadInitial(), refresh: () => store.refresh(),\n loadOlderMessages: () => store.loadOlderMessages(), sendMessage: (input) => store.sendMessage(input),\n startEditing: (messageId) => store.startEditing(messageId), cancelEditing: () => store.cancelEditing(),\n saveEdit: (text) => store.saveEdit(text), deleteMessage: (messageId) => store.deleteMessage(messageId),\n markRead: () => store.markRead(), updateTyping: (isTyping) => store.updateTyping(isTyping),\n setVisible: (value) => { visible = value; store.setVisible(value) },\n dispose,\n }\n}\n","import type { Conversation, Message, MessageEvent, MessageMedia, Participant, ReadPosition, RealtimeSubscription } from '@convokitapp/sdk'\nimport { createClientMessageId } from '@convokitapp/sdk'\nimport type { ConvoKitUiClient } from './ui-client'\nimport { compareMessageOrder, isConvoKitPendingMessage, mergeMessages, readerIdsFor } from './utils'\n\nexport interface ConversationSnapshot {\n conversation: Conversation | null\n messages: Message[]\n typingUserIds: ReadonlySet<string>\n /** Last acknowledgement time per user; kept for custom renderers. */\n readAtByUserId: ReadonlyMap<string, Date>\n /** Monotonic read-through position per user; wins over `readAtByUserId` where present. */\n readPositionByUserId: ReadonlyMap<string, ReadPosition>\n isInitialLoading: boolean\n isLoadingOlder: boolean\n isReconciling: boolean\n isSending: boolean\n hasOlderMessages: boolean\n hasLoaded: boolean\n error: unknown\n currentUserId: string\n /** The row being edited, as the user saw it when editing started (0.8.0): its `revision` is what `saveEdit`\n * sends. Replaced by the current row when a conflict is detected; null when not editing.\n */\n editingMessage: Message | null\n /** Whether the adapter implements `editMessage` / `deleteMessage` (0.8.0); computed once at construction. */\n canEditMessages: boolean\n canDeleteMessages: boolean\n}\n\ninterface Options {\n client: ConvoKitUiClient\n conversationId: string\n messagePageSize?: number\n markReadOnLoad?: boolean\n markReadOnReceive?: boolean\n typingTimeoutMs?: number\n}\n\ntype Cursor = Pick<Message, 'createdAt' | 'id'>\n// `revision` on changes, hydrations and the store is the store's own change counter (`this.revision`), unrelated to\n// `Message.revision`, the server's content revision that `revisionOrder` compares.\ntype Change = { revision: number; message: Message; insert: boolean; complete: boolean }\ntype Hydration = { revision: number; generation: number; message: Message; insert: boolean }\ntype Support = { edit: boolean; delete: boolean }\ntype HydrationPool = { running: Set<string>; queued: Map<string, Hydration> }\ntype ReadEntry = { userId: string; readAt: Date | null; readPosition: ReadPosition | null | undefined }\n/** One acknowledgement pipeline per load: a single request in flight, one boolean follow-up resolved at send time. */\ntype Acknowledgement = {\n inFlight: Promise<void> | undefined\n followUp: boolean\n /** An automatic acknowledgement was wanted while hidden or before this open's DTO (and so its version) was in\n * hand; re-issued once the view becomes visible or the open captures.\n */\n suppressed: boolean\n /** Target of the request in flight. */\n target: string | undefined\n /** Last target the server accepted; older or equal targets are never re-sent. */\n acknowledged: Cursor | undefined\n /** Targets the server does not know (or that were removed): never targeted again. */\n unacknowledgeable: Set<string>\n}\n/** The caller's private state captured once per open, the first time `conversation` goes from null to a DTO.\n * `version` stays undefined until then and for a DTO without `membership` (0.6 backend: acknowledgements send no\n * version); `clearPending` is set when the opened membership carried an unread marker and consumed by the single\n * empty-room clear of that open.\n */\ntype Capture = { version: number | undefined; clearPending: boolean }\n\nfunction version(message: Message): number { return message.updatedAt?.getTime() ?? message.createdAt.getTime() }\nfunction hasContent(message: Message): boolean { return !!message.text?.trim() || message.media.length > 0 }\n/** Row precedence (0.8.0): when both rows carry a usable content revision (both present, at least one above 0)\n * the higher `Message.revision` decides (negative: `left` is older, positive: newer); equal revisions and rows\n * without a usable one (pending rows, 0.7 backends where every row is 0) answer undefined and fall back to the\n * `updatedAt ?? createdAt` rule.\n */\nfunction revisionOrder(left: Message, right: Message): number | undefined {\n const a = left.revision, b = right.revision\n if (typeof a !== 'number' || typeof b !== 'number' || (a <= 0 && b <= 0)) return undefined\n return a === b ? undefined : a - b\n}\n/** Whether `candidate` is strictly older than `reference`: by revision when usable, else by timestamp. */\nfunction older(candidate: Message, reference: Message): boolean {\n const byRevision = revisionOrder(candidate, reference)\n return byRevision === undefined ? version(candidate) < version(reference) : byRevision < 0\n}\nfunction newest(current: Message, incoming: Message, incomingComplete = true): Message {\n const byRevision = revisionOrder(current, incoming)\n if (byRevision !== undefined) return byRevision > 0 ? current : incoming\n return version(current) > version(incoming) || (!incomingComplete && version(current) === version(incoming)) ? current : incoming\n}\n/** A stale expected revision, as the backend reports it (409 `REVISION_CONFLICT`); a bare 409 counts only for\n * adapters that expose no code at all, like `isTargetMiss`.\n */\nfunction isRevisionConflict(cause: unknown): boolean {\n if (typeof cause !== 'object' || cause === null) return false\n const { code, status } = cause as { code?: unknown; status?: unknown }\n return code === 'REVISION_CONFLICT' || (code === undefined && status === 409)\n}\n/** An author mutation rejected because the message is gone: only the coded 404. An uncoded 404 (a 0.7 backend's\n * unmatched `/own` route, a proxy, a custom adapter) is reported as an error and never evicts the row.\n */\nfunction isMessageMissing(cause: unknown): boolean {\n return typeof cause === 'object' && cause !== null && (cause as { code?: unknown }).code === 'MESSAGE_NOT_FOUND'\n}\n/** The local conflict signal: a newer row for the edited message reached the store without a request. */\nfunction localConflict(): Error {\n return Object.assign(new Error('Message was changed since it was loaded'), { code: 'REVISION_CONFLICT' })\n}\n\nconst compare = compareMessageOrder\nfunction positionCursor(position: ReadPosition): Cursor { return { createdAt: position.createdAt, id: position.messageId } }\nfunction readEntry(participant: Participant): ReadEntry {\n return { userId: participant.appUserId, readAt: participant.lastReadAt, readPosition: participant.readPosition }\n}\nfunction acknowledgement(): Acknowledgement {\n return { inFlight: undefined, followUp: false, suppressed: false, target: undefined, acknowledged: undefined, unacknowledgeable: new Set() }\n}\nfunction capture(conversation?: Conversation): Capture {\n const membership = conversation?.membership\n return { version: membership?.privateStateVersion, clearPending: membership?.unreadMarkedAt != null }\n}\n/** A targeted read the server rejected because the target is unknown to it (deleted or foreign). Membership\n * failures carry no `MESSAGE_NOT_FOUND` code (the core SDK reports `HTTP_ERROR`), so they remain errors; a\n * bare 404 counts as a miss only for adapters that expose no code at all.\n */\nfunction isTargetMiss(cause: unknown): boolean {\n if (typeof cause !== 'object' || cause === null) return false\n const { code, status } = cause as { code?: unknown; status?: unknown }\n return code === 'MESSAGE_NOT_FOUND' || (code === undefined && status === 404)\n}\n\nfunction blank(currentUserId = '', support: Support = { edit: false, delete: false }): ConversationSnapshot {\n return {\n conversation: null, messages: [], typingUserIds: new Set(), readAtByUserId: new Map(), readPositionByUserId: new Map(),\n isInitialLoading: false, isLoadingOlder: false, isReconciling: false, isSending: false,\n hasOlderMessages: true, hasLoaded: false, error: null, currentUserId,\n editingMessage: null, canEditMessages: support.edit, canDeleteMessages: support.delete,\n }\n}\n\n/** Internal, framework-independent room lifecycle. Never shared across client sessions. */\nexport class ConversationStore {\n private readonly client: ConvoKitUiClient\n private readonly room: string\n private readonly owner: object | null\n private readonly user: string\n private readonly pageSize: number\n private readonly typingTimeout: number\n private state: ConversationSnapshot\n private listeners = new Set<() => void>()\n private subscriptions: RealtimeSubscription[] = []\n private disposed = true\n private generation = 0\n private cursor: Cursor | undefined\n private revision = 0\n private changes = new Map<string, Change>()\n private hydrations = new Map<string, Hydration>()\n private hydrationPool: HydrationPool = { running: new Set(), queued: new Map() }\n // Keep tombstones until an explicit reload/session change, including across refreshes.\n private deleted = new Set<string>()\n private ack = acknowledgement()\n private captured = capture()\n // Visible until the platform reports otherwise; unknown/prerender/no document count as visible.\n private visible = true\n private sendRevision: number | undefined\n private activeSend: { pending: Message; confirmed?: Message } | undefined\n /** Adapter support for author edits/deletes, decided once like `listInbox`. */\n private readonly support: Support\n /** The id whose `saveEdit` request is in flight: its outcome (success or 409) decides the edit, so newer rows for\n * it arriving meanwhile (its own UPDATE image, typically) are not reported as a local conflict while it lasts;\n * `settleEditing` re-evaluates them once the request has settled any other way.\n */\n private activeEdit: string | undefined\n private refreshQueued = false\n private typingTimers = new Map<string, ReturnType<typeof setTimeout>>()\n private ownTypingTimer: ReturnType<typeof setTimeout> | undefined\n private sentTyping = false\n private typingRevision = 0\n private lastTypingSentAt = -Infinity\n\n constructor(private readonly options: Options) {\n this.client = options.client\n this.room = options.conversationId.trim()\n this.pageSize = options.messagePageSize ?? 30\n this.typingTimeout = options.typingTimeoutMs ?? 3000\n if (!this.room) throw new TypeError('conversationId is required')\n if (!Number.isInteger(this.pageSize) || this.pageSize < 1 || this.pageSize > 100) {\n throw new RangeError('messagePageSize must be an integer between 1 and 100')\n }\n if (!Number.isFinite(this.typingTimeout) || this.typingTimeout < 0) {\n throw new RangeError('typingTimeoutMs must be non-negative')\n }\n this.owner = this.client.sessionIdentity\n this.user = this.owner ? this.client.currentUserId : ''\n this.support = { edit: typeof this.client.editMessage === 'function', delete: typeof this.client.deleteMessage === 'function' }\n this.state = blank(this.user, this.support)\n }\n\n getSnapshot = (): ConversationSnapshot => this.state\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener)\n return () => { this.listeners.delete(listener) }\n }\n private patch(patch: Partial<ConversationSnapshot>): void {\n if (patch.messages && this.activeSend) {\n for (const message of patch.messages) this.confirmSend(message)\n if (this.activeSend.confirmed) patch.messages = patch.messages.filter(message => message.id !== this.activeSend!.pending.id)\n }\n if (patch.messages) patch = this.trackEditing(patch)\n this.state = { ...this.state, ...patch }\n for (const listener of this.listeners) listener()\n }\n /** Edit mode follows the edited row wherever a message list reaches the state: the row leaving the list (deletion,\n * reconcile tombstone, eviction) ends it, and a row for it with a higher revision than the snapshot (UPDATE image,\n * hydration, reconcile, refresh) is the local conflict: the snapshot is replaced and `error` carries the conflict\n * code, without a request. A save in flight owns its own outcome (`activeEdit`) and re-checks when it settles\n * (`settleEditing`).\n */\n private trackEditing(patch: Partial<ConversationSnapshot>): Partial<ConversationSnapshot> {\n const editing = patch.editingMessage === undefined ? this.state.editingMessage : patch.editingMessage\n if (!editing || !patch.messages) return patch\n const live = patch.messages.find((message) => message.id === editing.id)\n if (!live) return { ...patch, editingMessage: null }\n if (this.activeEdit === editing.id || !(live.revision > editing.revision)) return patch\n return { ...patch, editingMessage: live, error: localConflict() }\n }\n /** After a save for `id` has settled without deciding the edit (a failure, or a 409 whose reload failed), a newer\n * row for it that arrived during the request is the local conflict after all: the snapshot is replaced and\n * `error` carries the conflict code, so the next save carries the fresh revision without another round trip.\n */\n private settleEditing(id: string): void {\n const editing = this.state.editingMessage\n const live = editing?.id === id ? this.state.messages.find((message) => message.id === id) : undefined\n if (editing && live && live.revision > editing.revision) this.patch({ editingMessage: live, error: localConflict() })\n }\n private alive(generation = this.generation): boolean {\n return !this.disposed && generation === this.generation\n && this.owner !== null && this.client.sessionIdentity === this.owner\n }\n\n start = (autoLoad = true): void => {\n if (this.owner === null || this.client.sessionIdentity !== this.owner) return\n this.disposed = false\n this.patch({ currentUserId: this.user })\n if (autoLoad) void this.loadInitial()\n else {\n try { this.attach(this.generation, false) } catch { /* attach reports adapter failures */ }\n }\n }\n\n private detach(): void {\n const active = this.subscriptions\n this.subscriptions = []\n for (const subscription of active) void subscription.unsubscribe().catch(() => undefined)\n }\n\n private clearTyping(): void {\n for (const timer of this.typingTimers.values()) clearTimeout(timer)\n this.typingTimers.clear()\n clearTimeout(this.ownTypingTimer)\n this.ownTypingTimer = undefined\n this.sentTyping = false\n this.typingRevision++\n this.lastTypingSentAt = -Infinity\n this.patch({ typingUserIds: new Set() })\n }\n\n private clear(): void {\n this.generation++\n this.detach()\n this.clearTyping()\n this.cursor = undefined\n this.changes.clear()\n this.hydrations.clear()\n this.hydrationPool.queued.clear()\n // In-flight adapter promises cannot be aborted through this interface.\n // Keep their slots across reloads so repeated loads cannot exceed the cap.\n this.deleted.clear()\n // A retired pipeline's response settles against the old generation and is ignored.\n this.ack = acknowledgement()\n // Every open captures the caller's private state afresh; nothing captured survives `conversation` going null.\n this.captured = capture()\n this.sendRevision = undefined\n this.activeSend = undefined\n this.activeEdit = undefined\n this.refreshQueued = false\n }\n\n dispose = (): void => {\n // A retired session must never send a typing update using a replacement login.\n if (this.alive() && this.sentTyping) {\n void this.client.sendTyping({ conversationId: this.room, isTyping: false }).catch(() => undefined)\n }\n this.disposed = true\n this.clear()\n this.patch(blank('', this.support))\n }\n\n private fail(cause: unknown, generation: number, history = false): void {\n if (!this.alive(generation)) return\n const status = typeof cause === 'object' && cause !== null && 'status' in cause ? cause.status : undefined\n if (history && (status === 401 || status === 403 || status === 404)) {\n this.clear()\n this.patch({ ...blank(this.user, this.support), error: cause, hasLoaded: true, hasOlderMessages: false })\n } else this.patch({ error: cause })\n }\n\n private attach(generation: number, data = true): void {\n const report = (cause: Error) => this.fail(cause, generation)\n const add = (create: () => RealtimeSubscription) => {\n if (!this.alive(generation)) return\n const subscription = create()\n if (this.alive(generation)) this.subscriptions.push(subscription)\n else void subscription.unsubscribe().catch(() => undefined)\n }\n try {\n // Install lifecycle ownership before providers can synchronously report a join.\n add(() => this.client.onConnectionEvent({\n onEvent: ({ topic, status }) => {\n if (!data || !this.alive(generation) || (topic !== `messages:${this.room}` && topic !== `conversation:${this.room}`)) return\n if (status === 'SUBSCRIBED') this.queueRefresh()\n else this.clearTyping()\n },\n onSessionEnded: () => {\n if (this.disposed || generation !== this.generation) return\n this.dispose()\n },\n onError: report,\n }))\n if (!data) return\n add(() => this.client.onInboxChanged(() => {\n if (this.alive(generation)) this.queueRefresh()\n }, cause => {\n if (this.alive(generation)) { report(cause); this.queueRefresh() }\n }))\n add(() => this.client.onMessage(this.room, (event) => this.onMessage(event, generation), report))\n add(() => this.client.onMessageDeleted(this.room, ({ id, conversationId }) => {\n if (!this.alive(generation) || conversationId !== this.room || !id.trim()) return\n this.removeMessage(id)\n }, report))\n add(() => this.client.onReadReceipt(this.room, ({ userId, readAt, readPosition }) => {\n if (this.alive(generation)) this.mergeReads([{ userId, readAt, readPosition }])\n }, report))\n add(() => this.client.onTyping(this.room, ({ userId, isTyping }) => {\n if (!this.alive(generation) || !userId.trim() || userId === this.user) return\n clearTimeout(this.typingTimers.get(userId))\n this.typingTimers.delete(userId)\n const next = new Set(this.state.typingUserIds)\n if (isTyping) {\n next.add(userId)\n this.typingTimers.set(userId, setTimeout(() => {\n this.typingTimers.delete(userId)\n if (!this.alive(generation)) return\n const remaining = new Set(this.state.typingUserIds)\n remaining.delete(userId)\n this.patch({ typingUserIds: remaining })\n }, this.typingTimeout))\n } else next.delete(userId)\n this.patch({ typingUserIds: next })\n }, report))\n } catch (cause) {\n this.detach()\n this.fail(cause, generation)\n throw cause\n }\n }\n\n private validMessage(message: Message): boolean {\n return message.conversationId === this.room && !!message.id.trim()\n && !!message.senderId.trim() && !isConvoKitPendingMessage(message)\n && Number.isFinite(message.createdAt.getTime()) && Number.isFinite(version(message))\n }\n\n private onMessage(event: MessageEvent, generation: number): void {\n const { message, type } = event\n if (!this.alive(generation) || (type !== 'insert' && type !== 'update')\n || !this.validMessage(message) || this.deleted.has(message.id)) return\n const existing = this.state.messages.find((item) => item.id === message.id)\n const known = existing ?? this.changes.get(message.id)?.message\n if (known && older(message, known)) return\n const insert = type === 'insert' || this.changes.get(message.id)?.insert === true\n if (!existing && !insert && type === 'update' && !this.state.isInitialLoading && !this.state.isLoadingOlder && !this.state.isReconciling) return\n const revision = ++this.revision\n // A raw Message row has no related Media; absence is not authoritative removal.\n const provisional = existing && !message.media.length ? { ...message, media: existing.media } : message\n this.record(provisional, insert, revision, false)\n const job: Hydration = { revision, generation, message, insert }\n this.hydrations.set(message.id, job)\n this.hydrationPool.queued.set(message.id, job)\n this.drainHydration()\n }\n\n private record(message: Message, insert: boolean, revision: number, complete: boolean): void {\n const existing = this.state.messages.find((item) => item.id === message.id)\n if (existing && older(message, existing)) return\n // The exact server-echoed send ID also confirms media-only rows before hydration.\n // Keep that send's local media until the complete authorized response arrives.\n if (this.confirmSend(message) && !complete && !message.media.length) {\n message = { ...message, media: this.activeSend!.pending.media }\n this.confirmSend(message)\n }\n this.changes.set(message.id, { revision, message, insert, complete })\n if (!existing && !(insert && hasContent(message))) return\n this.patch({ messages: mergeMessages(this.state.messages, [message]) })\n // A foreign row entering the rendered list is the receive trigger, so a withheld\n // media-only row is acknowledged once its hydration renders it, never before.\n if (!existing && message.senderId !== this.user && (this.options.markReadOnReceive ?? true)) void this.acknowledge(true)\n }\n\n private confirmSend(message: Message): boolean {\n const send = this.activeSend\n if (!send || !this.validMessage(message) || message.senderId !== this.user\n || message.clientMessageId !== send.pending.clientMessageId) return false\n send.confirmed = send.confirmed ? newest(send.confirmed, message) : message\n return true\n }\n\n private currentHydration(job: Hydration): boolean {\n return this.alive(job.generation) && !this.deleted.has(job.message.id) && this.hydrations.get(job.message.id) === job\n }\n\n private removeMessage(id: string): void {\n this.forget(id)\n this.patch({ messages: this.state.messages.filter((message) => message.id !== id) })\n }\n\n /** Tombstone a row learned to be gone; a removed acknowledgement target is re-resolved from what remains. */\n private forget(id: string): void {\n this.deleted.add(id)\n this.changes.delete(id)\n this.hydrations.delete(id)\n this.hydrationPool.queued.delete(id)\n const ack = this.ack\n if (ack.target !== id && ack.acknowledged?.id !== id) return\n ack.unacknowledgeable.add(id)\n if (ack.target === id) ack.followUp = true\n }\n\n private drainHydration(): void {\n const pool = this.hydrationPool\n for (const [id, job] of pool.queued) {\n if (pool.running.size >= 8) break\n if (pool.running.has(id)) continue\n pool.queued.delete(id)\n if (!this.currentHydration(job)) continue\n pool.running.add(id)\n void this.hydrate(job, pool)\n }\n }\n\n private async hydrate(job: Hydration, pool: HydrationPool): Promise<void> {\n const id = job.message.id\n try {\n if (!this.currentHydration(job)) return\n const full = await this.client.getMessage(id)\n if (!this.currentHydration(job)) return\n if (!this.validMessage(full) || full.id !== id || full.senderId !== job.message.senderId || older(full, job.message)) {\n throw new Error('Complete message response does not match the observed resource/revision')\n }\n // Completion is not a fresh change: a later snapshot outranks the originating event.\n this.record(full, job.insert, job.revision, true)\n } catch (cause) {\n if (!this.currentHydration(job)) return\n const status = typeof cause === 'object' && cause !== null && 'status' in cause ? cause.status : undefined\n if (status === 404) this.removeMessage(id)\n this.fail(cause, job.generation)\n this.queueRefresh()\n } finally {\n if (this.hydrations.get(id) === job) this.hydrations.delete(id)\n pool.running.delete(id)\n queueMicrotask(() => { if (this.hydrationPool === pool) this.drainHydration() })\n }\n }\n\n /** Both maps only ever advance: acknowledgement times by time, positions by (createdAt, id). Participants and\n * read events are the only sources; the local user's own read is never written from the device clock.\n */\n private mergeReads(entries: Iterable<ReadEntry>): void {\n const readAt = new Map(this.state.readAtByUserId)\n const positions = new Map(this.state.readPositionByUserId)\n for (const entry of entries) {\n const { userId, readPosition } = entry\n if (!userId.trim()) continue\n if (entry.readAt && Number.isFinite(entry.readAt.getTime()) && entry.readAt.getTime() > (readAt.get(userId)?.getTime() ?? -Infinity)) {\n readAt.set(userId, entry.readAt)\n }\n if (!readPosition || typeof readPosition.messageId !== 'string' || !readPosition.messageId.trim()\n || !(readPosition.createdAt instanceof Date) || !Number.isFinite(readPosition.createdAt.getTime())) continue\n const current = positions.get(userId)\n if (!current || compare(positionCursor(readPosition), positionCursor(current)) > 0) positions.set(userId, readPosition)\n }\n this.patch({ readAtByUserId: readAt, readPositionByUserId: positions })\n }\n\n private validatePage(page: Message[], before?: Cursor): void {\n if (page.length > this.pageSize) throw new Error('Message page exceeds the requested limit')\n let previous = before\n for (const message of page) {\n if (!this.validMessage(message) || (previous && compare(message, previous) >= 0)) {\n throw new Error('Message history must contain distinct, room-scoped rows in newest-first cursor order')\n }\n previous = message\n }\n }\n\n private fetchPage(before?: Cursor): Promise<Message[]> {\n return this.client.getMessages({\n conversationId: this.room, limit: this.pageSize,\n ...(before ? { beforeCreatedAt: before.createdAt, beforeId: before.id } : {}),\n })\n }\n\n private overlay(rows: Message[], revision: number): Message[] {\n const byId = new Map(rows.filter((message) => !this.deleted.has(message.id)).map((message) => [message.id, message]))\n for (const [id, change] of this.changes) {\n if (change.revision > revision && !this.deleted.has(id) && (change.insert || byId.has(id))) {\n const current = byId.get(id)\n if (current || change.complete || hasContent(change.message)) {\n byId.set(id, current ? newest(current, change.message, change.complete) : change.message)\n }\n }\n }\n for (const message of this.state.messages) {\n if (isConvoKitPendingMessage(message)) byId.set(message.id, message)\n }\n return mergeMessages([], [...byId.values()])\n }\n\n private prune(revision: number): void {\n const safeRevision = Math.min(revision, this.sendRevision ?? Infinity)\n for (const [id, change] of this.changes) if (change.revision <= safeRevision) this.changes.delete(id)\n for (const [id, job] of this.hydrations) if (job.revision <= revision) {\n this.hydrations.delete(id)\n this.hydrationPool.queued.delete(id)\n }\n }\n\n loadInitial = async (): Promise<void> => {\n if (!this.alive()) return\n this.clear()\n const generation = this.generation\n this.patch({ ...blank(this.user, this.support), isInitialLoading: true })\n const revision = this.revision\n try {\n this.attach(generation)\n if (!this.alive(generation)) return\n const [conversation, page] = await Promise.all([this.client.getConversation(this.room), this.fetchPage()])\n if (!this.alive(generation)) return\n if (conversation.id !== this.room) throw new Error('Conversation response belongs to a different room')\n this.validatePage(page)\n this.cursor = page.at(-1)\n this.patch({ conversation, messages: this.overlay(page, revision), hasOlderMessages: page.length === this.pageSize })\n // The DTO is in hand before this open's first acknowledgement: capture its private state now.\n this.captured = capture(conversation)\n this.mergeReads(conversation.participants.map(readEntry))\n this.prune(revision)\n // The load acknowledgement also covers an automatic one that waited for the DTO (a row inserted during the load).\n if ((this.options.markReadOnLoad ?? true) || this.ack.suppressed) {\n this.ack.suppressed = false\n await this.acknowledge(true)\n }\n } catch (cause) {\n this.fail(cause, generation, true)\n } finally {\n if (this.alive(generation)) {\n this.patch({ isInitialLoading: false, hasLoaded: true })\n this.flushRefresh()\n }\n }\n }\n\n private queueRefresh(): void {\n this.refreshQueued = true\n this.flushRefresh()\n }\n private flushRefresh(): void {\n const generation = this.generation\n void Promise.resolve().then(() => {\n if (!this.alive(generation) || !this.refreshQueued || this.state.isInitialLoading\n || this.state.isLoadingOlder || this.state.isReconciling) return\n this.refreshQueued = false\n void this.refresh()\n })\n }\n\n /** Re-fetch the entire viewed range atomically; a first-page-only refresh loses history. */\n refresh = async (): Promise<void> => {\n if (!this.alive()) return\n if (this.state.isInitialLoading || this.state.isLoadingOlder || this.state.isReconciling) {\n this.refreshQueued = true\n return\n }\n if (!this.state.hasLoaded || !this.subscriptions.length) return this.loadInitial()\n const generation = this.generation\n const revision = this.revision\n const observed = this.state.messages.filter((message) => !isConvoKitPendingMessage(message))\n .concat([...this.changes.values()].filter((change) => change.insert).map((change) => change.message))\n const boundary = observed.reduce<Cursor | undefined>((oldest, message) =>\n !oldest || compare(message, oldest) < 0 ? message : oldest, this.cursor)\n const previouslyExhausted = !this.state.hasOlderMessages\n this.patch({ isReconciling: true, error: null })\n try {\n const conversation = await this.client.getConversation(this.room)\n if (!this.alive(generation)) return\n if (conversation.id !== this.room) throw new Error('Conversation response belongs to a different room')\n const rows: Message[] = []\n let before: Cursor | undefined\n let hasOlder = true\n while (this.alive(generation)) {\n const page = await this.fetchPage(before)\n if (!this.alive(generation)) return\n this.validatePage(page, before)\n rows.push(...page)\n before = page.at(-1) ?? before\n hasOlder = page.length === this.pageSize\n // An empty previous view has no history range to recover: keep its first\n // returning page bounded even if many messages arrived while offline.\n if (!hasOlder || !boundary || (!previouslyExhausted && before && compare(before, boundary) < 0)) break\n }\n this.cursor = before\n const reconciled = this.overlay(rows, revision)\n const survivingIds = new Set(reconciled.map((message) => message.id))\n const known = this.state.messages.filter((message) => !isConvoKitPendingMessage(message)).map((message) => message.id)\n .concat([...this.changes].filter(([, change]) => change.insert && change.revision <= revision).map(([id]) => id))\n // A missed deletion learned from the full viewed range also defeats late acks/replays.\n for (const id of known) if (!survivingIds.has(id)) this.forget(id)\n // A reconcile after a transient first-load failure is this open's first DTO; replacing one never recaptures.\n const opening = this.state.conversation === null\n this.patch({ conversation, messages: reconciled, hasOlderMessages: hasOlder })\n if (opening) this.captured = capture(conversation)\n this.mergeReads(conversation.participants.map(readEntry))\n this.prune(revision)\n // Rows received while the DTO was missing waited for its version; this open's first DTO issues them.\n if (opening) void this.resumeAcknowledgement()\n } catch (cause) {\n this.fail(cause, generation, true)\n } finally {\n if (this.alive(generation)) {\n this.patch({ isReconciling: false })\n this.flushRefresh()\n }\n }\n }\n\n loadOlderMessages = async (): Promise<void> => {\n if (!this.alive() || !this.state.hasLoaded || this.state.isInitialLoading || this.state.isLoadingOlder\n || this.state.isReconciling || !this.state.hasOlderMessages) return\n const generation = this.generation\n const revision = this.revision\n const cursor = this.cursor\n this.patch({ isLoadingOlder: true, error: null })\n try {\n const page = await this.fetchPage(cursor)\n if (!this.alive(generation)) return\n this.validatePage(page, cursor)\n this.cursor = page.at(-1) ?? cursor\n // Existing live edits always win over an older-page duplicate.\n this.patch({\n messages: this.overlay(mergeMessages(page, this.state.messages), revision),\n hasOlderMessages: page.length === this.pageSize,\n })\n } catch (cause) {\n this.fail(cause, generation, true)\n } finally {\n if (this.alive(generation)) {\n this.patch({ isLoadingOlder: false })\n this.flushRefresh()\n }\n }\n }\n\n /** Acknowledge through the newest rendered row now, regardless of visibility; no acknowledgement without a\n * target (a room opened with a marker that renders nothing clears the marker instead, once).\n */\n markRead = (): Promise<void> => this.alive() ? this.acknowledge(false) : Promise.resolve()\n\n /** Automatic acknowledgements wait while hidden and are re-issued (once) on becoming visible. */\n setVisible = (visible: boolean): void => {\n this.visible = visible\n if (!visible || !this.alive()) return\n void this.resumeAcknowledgement()\n }\n\n /** Re-issue (once) the automatic acknowledgement that waited while hidden or before this open's DTO, if any. */\n private resumeAcknowledgement(): Promise<void> {\n if (!this.ack.suppressed) return Promise.resolve()\n this.ack.suppressed = false\n return this.acknowledge(true)\n }\n\n /** The newest non-pending rendered row by (createdAt, id), never by list index and never a raw realtime\n * row; rows the server does not know are skipped, and nothing at or before the accepted target is re-sent.\n */\n private ackTarget(ack: Acknowledgement): Cursor | undefined {\n let target: Cursor | undefined\n for (const message of this.state.messages) {\n if (isConvoKitPendingMessage(message) || ack.unacknowledgeable.has(message.id)) continue\n if (!target || compare(message, target) > 0) target = { createdAt: message.createdAt, id: message.id }\n }\n return target && (!ack.acknowledged || compare(target, ack.acknowledged) > 0) ? target : undefined\n }\n\n /** Resolves when the request this call issued or joined settles; a follow-up is issued, not awaited. */\n private acknowledge(automatic: boolean): Promise<void> {\n const ack = this.ack\n // Before this open's DTO is in hand there is no captured version to send: a row inserted during the load (or\n // while a transient first-load failure stands) waits for the capture, like it waits while hidden.\n if (automatic && (!this.visible || this.state.conversation === null)) {\n ack.suppressed = true\n return Promise.resolve()\n }\n if (ack.inFlight) {\n ack.followUp = true\n return ack.inFlight\n }\n return this.issue(ack, this.generation) ?? Promise.resolve()\n }\n\n private issue(ack: Acknowledgement, generation: number): Promise<void> | undefined {\n ack.followUp = false\n const target = this.ackTarget(ack)\n // An empty marked room clears its marker in the acknowledgement's slot; nothing else is sent without a target.\n const request = target ? this.send(ack, generation, target) : this.clearMarker(ack, generation)\n if (!request) return undefined\n ack.target = target?.id\n ack.inFlight = request.finally(() => {\n ack.inFlight = undefined\n ack.target = undefined\n if (!this.alive(generation) || !ack.followUp) return\n if (!this.visible) {\n ack.followUp = false\n ack.suppressed = true\n } else this.issue(ack, generation)\n })\n return ack.inFlight\n }\n\n /** A room opened with the caller's unread marker that renders no non-pending, acknowledgeable row cannot clear\n * it through a targeted acknowledgement, so it asks the adapter to clear the marker conditionally on the captured\n * version, once per open, under the acknowledgement triggers and visibility gating. Rows rendered later clear it\n * through their acknowledgements; adapters without the member leave it; `cleared: false` is not an error.\n */\n private clearMarker(ack: Acknowledgement, generation: number): Promise<void> | undefined {\n const captured = this.captured\n if (!captured.clearPending || captured.version === undefined || typeof this.client.clearConversationUnread !== 'function'\n || this.state.messages.some((message) => !isConvoKitPendingMessage(message) && !ack.unacknowledgeable.has(message.id))) return undefined\n captured.clearPending = false\n return this.clearUnread(captured.version, generation)\n }\n\n private async clearUnread(version: number, generation: number): Promise<void> {\n try {\n await this.client.clearConversationUnread!(this.room, { ifVersion: version })\n } catch (cause) {\n if (this.alive(generation)) this.fail(cause, generation)\n }\n }\n\n private async send(ack: Acknowledgement, generation: number, target: Cursor): Promise<void> {\n try {\n // Every targeted acknowledgement of this open carries the version captured when it opened (none on 0.6).\n const version = this.captured.version\n await this.client.markConversationRead(this.room, {\n throughMessageId: target.id, ...(version === undefined ? {} : { privateStateVersion: version }),\n })\n if (!this.alive(generation)) return\n // Only persisted participant positions / server read events advance receipts.\n if (!ack.acknowledged || compare(target, ack.acknowledged) > 0) ack.acknowledged = target\n } catch (cause) {\n if (!this.alive(generation)) return\n if (isTargetMiss(cause)) {\n // The server does not know this target (deleted meanwhile): re-issue once with the next newest row.\n ack.unacknowledgeable.add(target.id)\n ack.followUp = true\n } else this.fail(cause, generation)\n }\n }\n\n updateTyping = async (isTyping: boolean): Promise<void> => {\n if (!this.alive()) return\n const generation = this.generation\n clearTimeout(this.ownTypingTimer)\n if (isTyping) this.ownTypingTimer = setTimeout(() => {\n if (this.alive(generation)) void this.updateTyping(false)\n }, this.typingTimeout)\n const now = performance.now()\n // Renew while keystrokes continue, so the receiver's expiry does not hide\n // someone who is still typing. Idle input never generates a keepalive.\n const renew = isTyping && now - this.lastTypingSentAt >= Math.max(1, this.typingTimeout / 2)\n if (this.sentTyping === isTyping && !renew) return\n const revision = ++this.typingRevision\n this.sentTyping = isTyping\n this.lastTypingSentAt = isTyping ? now : -Infinity\n try {\n await this.client.sendTyping({ conversationId: this.room, isTyping })\n } catch (cause) {\n if (this.alive(generation) && revision === this.typingRevision) {\n this.sentTyping = false\n this.fail(cause, generation)\n }\n }\n }\n\n sendMessage = async ({ text, media }: { text?: string; media?: MessageMedia[] }): Promise<Message | null> => {\n const normalized = text?.trim()\n if (!this.alive() || this.state.isSending || (!normalized && !media?.length)) return null\n const generation = this.generation\n const revision = this.revision\n this.sendRevision = revision\n const clientMessageId = createClientMessageId()\n const pendingId = `convokit-pending-${clientMessageId}`\n const pending: Message = {\n id: pendingId, clientMessageId, conversationId: this.room, senderId: this.user, text: normalized || null,\n media: media ?? [], createdAt: new Date(), updatedAt: null, revision: 0,\n }\n const send = { pending } as { pending: Message; confirmed?: Message }\n this.activeSend = send\n this.patch({ messages: mergeMessages(this.state.messages, [pending]), isSending: true, error: null })\n try {\n const message = await this.client.sendMessage({\n conversationId: this.room, clientMessageId, ...(normalized ? { text: normalized } : {}), ...(media?.length ? { media } : {}),\n })\n if (!this.alive(generation)) return null\n if (!this.validMessage(message) || message.senderId !== this.user) throw new Error('Send response belongs to a different room or sender')\n if (message.clientMessageId && message.clientMessageId !== clientMessageId) throw new Error('Send response belongs to a different send')\n const live = this.changes.get(message.id)\n const existing = this.state.messages.find((item) => item.id === message.id)\n let latest = existing ? newest(message, existing, live?.complete !== false) : message\n if (live && live.revision > revision) latest = newest(latest, live.message, live.complete)\n if (!this.deleted.has(message.id)) this.changes.set(message.id, { revision: ++this.revision, message: latest, insert: true, complete: true })\n this.patch({ messages: mergeMessages(\n this.state.messages.filter((item) => item.id !== pendingId),\n this.deleted.has(message.id) ? [] : [latest],\n ) })\n void this.updateTyping(false)\n return this.alive(generation) ? latest : null\n } catch (cause) {\n if (this.alive(generation)) {\n this.patch({ messages: this.state.messages.filter((item) => item.id !== pendingId) })\n // A live/history confirmation is authoritative even if its HTTP acknowledgement was lost.\n // Returning success clears the composer; deleted confirmations are never reinserted.\n if (send.confirmed) {\n void this.updateTyping(false)\n return send.confirmed\n }\n this.fail(cause, generation)\n }\n return null\n } finally {\n if (this.alive(generation)) {\n this.sendRevision = undefined\n this.activeSend = undefined\n this.patch({ isSending: false })\n }\n }\n }\n\n /** The caller's role in the open room when known (0.7 `membership`, else the caller's participant row). */\n private ownRole(): string | undefined {\n const conversation = this.state.conversation\n return conversation?.membership?.role\n ?? conversation?.participants.find((participant) => participant.appUserId === this.user || participant.id === this.user)?.role\n }\n\n /** A rendered, confirmed row of the caller's own that is not known to be gone. */\n private ownRow(messageId: string): Message | undefined {\n const row = this.state.messages.find((message) => message.id === messageId)\n return row && row.senderId === this.user && !isConvoKitPendingMessage(row) && !this.deleted.has(messageId) ? row : undefined\n }\n\n /** Enter edit mode on one of the caller's own confirmed messages (0.8.0): the row as it stands now becomes the\n * snapshot whose `revision` every save sends. A no-op unless the adapter implements `editMessage`, the row is\n * rendered, own, confirmed, not tombstoned and the caller's role (when known) is not `READ`. Sends nothing.\n */\n startEditing = (messageId: string): void => {\n if (!this.alive() || !this.support.edit || this.ownRole() === 'READ') return\n const row = this.ownRow(messageId)\n if (row) this.patch({ editingMessage: row })\n }\n\n /** Leave edit mode without a request; the draft is the view's to restore. */\n cancelEditing = (): void => {\n if (this.state.editingMessage) this.patch({ editingMessage: null })\n }\n\n /** Save the edit in progress with the snapshot's revision (never the live row's), trimming the text and sending\n * `null` for an empty caption. Resolves true when the server accepted the edit (the response is merged through the\n * tombstone and precedence guards and edit mode ends); false when nothing was saved: a stale revision (409\n * `REVISION_CONFLICT`) reloads the row once through `getMessage`, replaces the snapshot with it (the next save\n * carries the fresh revision) and reports the conflict through `error`, keeping edit mode; a coded 404\n * (`MESSAGE_NOT_FOUND`, on the save or on that reload) removes the row and ends edit mode; any other failure\n * (403, 500, network, an uncoded 404 from a 0.7 backend) is reported through `error` without evicting anything and\n * keeps edit mode; if a newer row for the message arrived during such a request, that row is then the local\n * conflict (`settleEditing`). A text-only message cannot be saved empty (no request). Rejects when the adapter\n * lacks `editMessage`.\n */\n saveEdit = async (text: string): Promise<boolean> => {\n const client = this.client\n if (typeof client.editMessage !== 'function') {\n throw new TypeError('This ConvoKitUiClient adapter does not implement editMessage (0.8)')\n }\n const snapshot = this.state.editingMessage\n if (!this.alive() || !snapshot || this.activeEdit !== undefined) return false\n const trimmed = text.trim()\n const normalized = trimmed === '' ? null : trimmed\n if (normalized === null && snapshot.media.length === 0) return false\n const generation = this.generation\n const id = snapshot.id\n this.activeEdit = id\n this.patch({ error: null })\n try {\n const message = await client.editMessage(id, { text: normalized, revision: snapshot.revision })\n if (!this.alive(generation)) return false\n if (!this.validMessage(message) || message.id !== id || message.senderId !== this.user) {\n throw new Error('Edit response belongs to a different message or sender')\n }\n // Edit mode ends before the merge so the accepted row is not mistaken for a local conflict.\n if (this.state.editingMessage?.id === id) this.patch({ editingMessage: null })\n this.applyRow(message)\n return true\n } catch (cause) {\n if (!this.alive(generation)) return false\n if (isRevisionConflict(cause)) await this.reloadConflict(id, cause, generation)\n else if (isMessageMissing(cause)) {\n this.removeMessage(id)\n this.patch({ error: cause })\n } else this.fail(cause, generation)\n return false\n } finally {\n if (this.alive(generation)) {\n this.activeEdit = undefined\n this.settleEditing(id)\n }\n }\n }\n\n /** Merge a complete REST row for a known id through the live-row guards: a tombstoned id is dropped, and an older\n * revision (or timestamp) never overwrites the newer row already recorded. Recorded as a non-insert change, so a\n * reconcile keeps it only while the row is still in the fetched range.\n */\n private applyRow(message: Message): void {\n if (this.deleted.has(message.id)) return\n this.record(message, this.changes.get(message.id)?.insert === true, ++this.revision, true)\n }\n\n /** The 409 path: one `getMessage` shows the conflicting content. Its row is merged through the guards and becomes\n * the new snapshot; a `MESSAGE_NOT_FOUND` answer removes the row and ends edit mode; another failure keeps the\n * snapshot. `error` carries the conflict (or the reload failure).\n */\n private async reloadConflict(id: string, conflict: unknown, generation: number): Promise<void> {\n try {\n const current = await this.client.getMessage(id)\n if (!this.alive(generation)) return\n if (!this.validMessage(current) || current.id !== id) throw new Error('Complete message response does not match the edited message')\n this.applyRow(current)\n const row = this.state.messages.find((message) => message.id === id)\n const editing = this.state.editingMessage?.id === id && row ? { editingMessage: row } : {}\n this.patch({ ...editing, error: conflict })\n } catch (cause) {\n if (!this.alive(generation)) return\n if (isTargetMiss(cause)) this.removeMessage(id)\n this.patch({ error: cause })\n }\n }\n\n /** Delete one of the caller's own confirmed messages (0.8.0). The row stays until the server answers: on success,\n * or when the server no longer knows it (`MESSAGE_NOT_FOUND`), it is tombstoned and removed (late responses, row\n * images and hydrations for it are dropped, the acknowledgement target is re-resolved and edit mode on it ends)\n * and the call resolves true; any other failure keeps the row, reports through `error` and resolves false. Rejects\n * when the adapter lacks `deleteMessage`.\n */\n deleteMessage = async (messageId: string): Promise<boolean> => {\n const client = this.client\n if (typeof client.deleteMessage !== 'function') {\n throw new TypeError('This ConvoKitUiClient adapter does not implement deleteMessage (0.8)')\n }\n if (!this.alive() || !this.ownRow(messageId)) return false\n const generation = this.generation\n this.patch({ error: null })\n try {\n await client.deleteMessage(messageId)\n } catch (cause) {\n if (!this.alive(generation)) return false\n if (!isMessageMissing(cause)) {\n this.fail(cause, generation)\n return false\n }\n }\n if (!this.alive(generation)) return false\n this.removeMessage(messageId)\n return true\n }\n\n readerIdsFor = (message: Message): ReadonlySet<string> =>\n readerIdsFor(message, this.state.readAtByUserId, this.state.readPositionByUserId)\n}\n","import type { Conversation, Message, MessageMedia, ReadPosition } from '@convokitapp/sdk'\nimport { isEditedMessage } from '@convokitapp/sdk'\nimport {\n Check,\n CheckCheck,\n ContactRound,\n Download,\n FileText,\n ImageOff,\n LoaderCircle,\n MapPin,\n MessageCircle,\n Pencil,\n Trash2,\n} from '@lucide/vue'\nimport {\n computed,\n defineComponent,\n h,\n nextTick,\n ref,\n watch,\n type CSSProperties,\n type PropType,\n type Ref,\n type VNodeChild,\n} from 'vue'\nimport type {\n ConvoKitAppearanceProps,\n ConvoKitUiDensity,\n ConvoKitUiPart,\n MediaSlotProps,\n MessageSlotProps,\n ReadReceiptSlotProps,\n} from '../types'\nimport { cx, errorMessage, formatFileSize, formatMessageTime, isConvoKitPendingMessage, partClass, partStyle, readerIdsFor } from '../utils'\n\nexport interface MessageListViewProps extends ConvoKitAppearanceProps {\n conversation: Conversation\n messages: readonly Message[]\n currentUserId: string\n /** Acknowledgement times; the fallback for users without a read position. */\n readAtByUserId?: ReadonlyMap<string, Date>\n /** Read-through positions; a user's position decides their receipts whenever one is present. */\n readPositionByUserId?: ReadonlyMap<string, ReadPosition>\n readersResolver?: (message: Message) => ReadonlySet<string>\n onLoadOlder?: () => void | Promise<void>\n hasOlderMessages?: boolean\n isLoadingOlder?: boolean\n error?: unknown\n onAttachmentClick?: (media: MessageMedia, message: Message) => void\n /** Start editing a message (0.8.0). Without it no row offers an edit action and the markup is unchanged. */\n onEditMessage?: (message: Message) => void\n /** Delete a message after confirmation (0.8.0); `false` means the deletion was not accepted. Without it no row\n * offers a delete action.\n */\n onDeleteMessage?: (message: Message) => boolean | void | Promise<boolean | void>\n /** Replaces the default eligibility (the viewer's own confirmed rows while the viewer's role is not `READ`) for\n * both actions; pending rows are never eligible.\n */\n canEditMessage?: (message: Message) => boolean\n /** Replaces the row's inline \"Delete this message?\" prompt (and confirms `remove()` from custom rows). */\n confirmDelete?: (message: Message) => boolean | Promise<boolean>\n scrollElement?: Ref<HTMLElement | null>\n paginationThreshold?: number\n reverse?: boolean\n stickToBottom?: boolean\n formatTime?: (date: Date) => string\n imageLoading?: 'eager' | 'lazy'\n class?: unknown\n style?: unknown\n}\n\nconst appearanceProps = {\n classNames: { type: Object as PropType<Partial<Record<ConvoKitUiPart, string>>>, default: undefined },\n styles: { type: Object as PropType<Partial<Record<ConvoKitUiPart, CSSProperties>>>, default: undefined },\n density: { type: String as PropType<ConvoKitUiDensity>, default: 'comfortable' },\n unstyled: { type: Boolean, default: false },\n} as const\n\nfunction defaultMedia(\n media: MessageMedia,\n open: (() => void) | undefined,\n imageLoading: 'eager' | 'lazy',\n): VNodeChild {\n const tag = open ? 'button' : 'div'\n const interactive = open ? { type: 'button', onClick: open } : {}\n if (media.type === 'image') {\n return h(tag, { ...interactive, class: 'ckui-media-card ckui-media-card--image' }, [\n media.url\n ? h('img', { src: media.url, alt: media.name ?? 'Shared image', loading: imageLoading })\n : h('span', { class: 'ckui-media-placeholder' }, [h(ImageOff, { 'aria-hidden': 'true' }), ' Image unavailable']),\n media.name ? h('span', { class: 'ckui-media-name' }, media.name) : null,\n ])\n }\n if (media.type === 'file') {\n const size = formatFileSize(media.size)\n return h(tag, { ...interactive, class: 'ckui-media-card ckui-media-card--file' }, [\n h(FileText, { 'aria-hidden': 'true' }),\n h('span', [h('strong', media.name || 'Attachment'), size ? h('small', size) : null]),\n open ? h(Download, { size: 18, 'aria-hidden': 'true' }) : null,\n ])\n }\n if (media.type === 'location') {\n const label = media.name || `${media.metadata.lat}, ${media.metadata.lng}`\n return h(tag, { ...interactive, class: 'ckui-media-card ckui-media-card--location' }, [\n h(MapPin, { 'aria-hidden': 'true' }),\n h('span', [h('strong', label), h('small', `${media.metadata.lat}, ${media.metadata.lng}`)]),\n ])\n }\n const contact = media.metadata.email || media.metadata.phone || 'Contact details'\n return h(tag, { ...interactive, class: 'ckui-media-card ckui-media-card--contact' }, [\n h(ContactRound, { 'aria-hidden': 'true' }),\n h('span', [h('strong', media.name || 'Shared contact'), h('small', String(contact))]),\n ])\n}\n\n/** Controlled message history with read receipts, structured media, and older-page loading. */\nexport const MessageListView = defineComponent({\n name: 'MessageListView',\n inheritAttrs: false,\n props: {\n ...appearanceProps,\n conversation: { type: Object as PropType<Conversation>, required: true },\n messages: { type: Array as PropType<readonly Message[]>, required: true },\n currentUserId: { type: String, required: true },\n readAtByUserId: { type: Object as PropType<ReadonlyMap<string, Date>>, default: () => new Map() },\n readPositionByUserId: { type: Object as PropType<ReadonlyMap<string, ReadPosition>>, default: () => new Map() },\n readersResolver: { type: Function as PropType<(message: Message) => ReadonlySet<string>>, default: undefined },\n onLoadOlder: { type: Function as PropType<() => void | Promise<void>>, default: undefined },\n hasOlderMessages: { type: Boolean, default: false },\n isLoadingOlder: { type: Boolean, default: false },\n error: { type: null as unknown as PropType<unknown>, required: false },\n onAttachmentClick: { type: Function as PropType<(media: MessageMedia, message: Message) => void>, default: undefined },\n onEditMessage: { type: Function as PropType<(message: Message) => void>, default: undefined },\n onDeleteMessage: { type: Function as PropType<(message: Message) => boolean | void | Promise<boolean | void>>, default: undefined },\n canEditMessage: { type: Function as PropType<(message: Message) => boolean>, default: undefined },\n confirmDelete: { type: Function as PropType<(message: Message) => boolean | Promise<boolean>>, default: undefined },\n scrollElement: { type: Object as PropType<Ref<HTMLElement | null>>, default: undefined },\n paginationThreshold: { type: Number, default: 240 },\n reverse: { type: Boolean, default: true },\n stickToBottom: { type: Boolean, default: true },\n formatTime: { type: Function as PropType<(date: Date) => string>, default: formatMessageTime },\n imageLoading: { type: String as PropType<'eager' | 'lazy'>, default: 'lazy' },\n },\n emits: ['load-older', 'attachment-click', 'edit-message', 'delete-message'],\n setup(props, { attrs, emit, slots }) {\n const internalElement = ref<HTMLElement | null>(null)\n /** The row whose inline \"Delete this message?\" prompt is open. */\n const confirming = ref<string | null>(null)\n let requestInFlight = false\n let lastRequestedLength: number | null = null\n let previousMessageCount = 0\n const participants = computed(() => new Map(props.conversation.participants.flatMap((participant) => [\n [participant.id, participant] as const,\n [participant.appUserId, participant] as const,\n ])))\n const appearance = (): ConvoKitAppearanceProps => ({\n density: props.density,\n unstyled: props.unstyled,\n ...(props.classNames ? { classNames: props.classNames } : {}),\n ...(props.styles ? { styles: props.styles } : {}),\n })\n\n const requestOlder = async () => {\n if (requestInFlight || lastRequestedLength === props.messages.length || props.isLoadingOlder || !props.hasOlderMessages || !props.onLoadOlder) return\n requestInFlight = true\n lastRequestedLength = props.messages.length\n try { await props.onLoadOlder() }\n catch { lastRequestedLength = null }\n finally { requestInFlight = false }\n }\n\n watch(() => [props.messages.length, props.hasOlderMessages] as const, async ([count, hasOlder]) => {\n const previous = previousMessageCount\n if (count !== previousMessageCount || !hasOlder) lastRequestedLength = null\n const appended = count > previous\n const element = internalElement.value\n previousMessageCount = count\n if (element && props.reverse && props.stickToBottom && appended) {\n const distanceFromBottom = element.scrollHeight - element.scrollTop - element.clientHeight\n if (previous === 0 || distanceFromBottom < 320) {\n await nextTick()\n element.scrollTop = element.scrollHeight\n }\n }\n }, { flush: 'post', immediate: true })\n\n /** The viewer's role when the room knows it: the 0.7 `membership` sibling, else the viewer's participant row. */\n const viewerRole = computed(() => props.conversation.membership?.role\n ?? props.conversation.participants.find((participant) => participant.appUserId === props.currentUserId || participant.id === props.currentUserId)?.role)\n /** Delete after confirmation: `confirmDelete` when the view has one, otherwise at once (custom rows own their\n * prompt; the default row opens its inline prompt instead of calling this without one).\n */\n const remove = async (message: Message): Promise<boolean> => {\n if (props.confirmDelete && !(await props.confirmDelete(message))) return false\n return (await props.onDeleteMessage?.(message)) !== false\n }\n\n const renderMessage = (message: Message, index: number): VNodeChild => {\n const isCurrentUser = message.senderId === props.currentUserId\n const sender = participants.value.get(message.senderId)\n const isPending = isConvoKitPendingMessage(message)\n const readerIds = isPending\n ? new Set<string>()\n : props.readersResolver ? props.readersResolver(message) : readerIdsFor(message, props.readAtByUserId, props.readPositionByUserId)\n const isEdited = !isPending && isEditedMessage(message)\n const eligible = !isPending && (props.canEditMessage ? props.canEditMessage(message) : isCurrentUser && viewerRole.value !== 'READ')\n const canEdit = eligible && !!props.onEditMessage\n const canDelete = eligible && !!props.onDeleteMessage\n const edit = () => { props.onEditMessage?.(message) }\n const slotProps: MessageSlotProps = {\n message, chronologicalIndex: index, isCurrentUser, sender, readerIds, isEdited, canEdit, canDelete,\n ...(canEdit ? { edit } : {}),\n ...(canDelete ? { remove: () => remove(message) } : {}),\n }\n const custom = slots.message?.(slotProps)\n if (custom) return h('div', { key: message.id, role: 'listitem' }, custom)\n const currentAppearance = appearance()\n const messagePart = isCurrentUser ? 'outgoingMessage' : 'incomingMessage'\n const iconButton = (label: string, onClick: () => void, icon: VNodeChild) => h('button', {\n type: 'button', 'aria-label': label, onClick,\n class: partClass('button', currentAppearance, 'ckui-icon-button'),\n style: partStyle('button', currentAppearance),\n }, [icon])\n const actions = canEdit || canDelete ? h('div', { class: 'ckui-message-actions' }, [\n ...(canEdit ? [iconButton('Edit message', edit, h(Pencil, { size: 16, 'aria-hidden': 'true' }))] : []),\n ...(canDelete ? [iconButton('Delete message', () => {\n if (props.confirmDelete) void remove(message)\n else confirming.value = message.id\n }, h(Trash2, { size: 16, 'aria-hidden': 'true' }))] : []),\n ]) : null\n const confirm = canDelete && confirming.value === message.id ? h('div', {\n class: 'ckui-message-confirm', role: 'group', 'aria-label': 'Delete this message?',\n }, [\n h('span', 'Delete this message?'),\n h('button', {\n type: 'button', class: 'ckui-link-button', 'aria-label': 'Confirm delete',\n onClick: () => { confirming.value = null; void props.onDeleteMessage?.(message) },\n }, 'Delete'),\n h('button', {\n type: 'button', class: 'ckui-link-button', 'aria-label': 'Cancel delete',\n onClick: () => { confirming.value = null },\n }, 'Cancel'),\n ]) : null\n const mediaNodes = message.media.map((media, mediaIndex) => {\n const open = props.onAttachmentClick\n ? () => {\n props.onAttachmentClick?.(media, message)\n }\n : undefined\n const mediaSlotProps: MediaSlotProps = { media, message, isCurrentUser, ...(open ? { open } : {}) }\n return h('div', {\n key: media.id ?? `${media.type}-${mediaIndex}`,\n class: partClass('media', currentAppearance, 'ckui-media'),\n style: partStyle('media', currentAppearance),\n }, slots.media?.(mediaSlotProps) ?? [defaultMedia(media, open, props.imageLoading)])\n })\n const receiptSlotProps: ReadReceiptSlotProps = { message, readerIds }\n return h('div', { key: message.id, role: 'listitem' }, [\n h('article', {\n class: cx(\n !props.unstyled && 'ckui-message-row',\n isCurrentUser && !props.unstyled && 'ckui-message-row--outgoing',\n props.classNames?.message,\n props.classNames?.[messagePart],\n ),\n style: [props.styles?.message, props.styles?.[messagePart]],\n 'data-message-id': message.id,\n }, [\n // Spread, not null: an absent action/label/prompt must not leave a comment node (0.7 markup stays byte-identical).\n ...(actions ? [actions] : []),\n h('div', { class: 'ckui-message-bubble' }, [\n !isCurrentUser ? h('strong', { class: 'ckui-message-sender' }, sender?.name || message.senderId) : null,\n message.text ? h('div', { class: 'ckui-message-text' }, message.text) : null,\n ...mediaNodes,\n h('span', { class: 'ckui-message-time' }, [\n isPending ? 'Sending…' : props.formatTime(message.createdAt),\n ...(isEdited ? [h('span', { class: 'ckui-message-edited', 'aria-label': 'Edited' }, 'Edited')] : []),\n isCurrentUser && !isPending\n ? readerIds.size > 0\n ? h(CheckCheck, { size: 14, 'aria-label': 'Read' })\n : h(Check, { size: 14, 'aria-label': 'Sent' })\n : null,\n ]),\n ]),\n ...(confirm ? [confirm] : []),\n isCurrentUser && !isPending\n ? slots['read-receipt']?.(receiptSlotProps) ?? h('div', {\n class: partClass('receipt', currentAppearance, 'ckui-read-receipt'),\n style: partStyle('receipt', currentAppearance),\n }, readerIds.size > 0 ? `Read by ${readerIds.size}` : 'Sent')\n : null,\n ]),\n ])\n }\n\n return () => {\n const currentAppearance = appearance()\n const children: VNodeChild[] = []\n if (props.isLoadingOlder) {\n children.push(slots['loading-older']?.() ?? h('div', {\n class: partClass('loading', currentAppearance, 'ckui-inline-state'),\n style: partStyle('loading', currentAppearance),\n role: 'status',\n }, [h(LoaderCircle, { class: 'ckui-spin', 'aria-hidden': 'true' }), ' Loading older messages…']))\n }\n if (props.error) {\n const retry = props.onLoadOlder ? () => { void requestOlder() } : undefined\n children.push(slots.error?.({ error: props.error, ...(retry ? { retry } : {}) }) ?? h('div', {\n class: partClass('error', currentAppearance, 'ckui-inline-state ckui-state--error'),\n style: partStyle('error', currentAppearance),\n role: 'alert',\n }, [\n h('span', errorMessage(props.error)),\n retry ? h('button', { type: 'button', class: 'ckui-link-button', onClick: retry }, 'Retry') : null,\n ]))\n }\n if (props.messages.length === 0 && !props.isLoadingOlder) {\n children.push(slots.empty?.() ?? h('div', {\n class: partClass('empty', currentAppearance, 'ckui-state'),\n style: partStyle('empty', currentAppearance),\n }, [h(MessageCircle, { 'aria-hidden': 'true' }), ' No messages yet']))\n } else {\n children.push(...props.messages.map(renderMessage))\n }\n return h('div', {\n ...attrs,\n ref: (element: unknown) => {\n internalElement.value = element as HTMLElement | null\n if (props.scrollElement) props.scrollElement.value = element as HTMLElement | null\n },\n class: cx(!props.unstyled && 'ckui ckui-message-list', props.classNames?.messages, attrs.class),\n style: [props.styles?.messages, attrs.style],\n 'data-density': props.density,\n role: 'log',\n 'aria-live': 'polite',\n 'aria-label': `Messages in ${props.conversation.displayTitle}`,\n onScroll: (event: Event) => {\n const nativeHandler = attrs.onScroll\n if (typeof nativeHandler === 'function') nativeHandler(event)\n const element = event.currentTarget as HTMLElement\n const distanceFromOldest = props.reverse\n ? element.scrollTop\n : element.scrollHeight - element.scrollTop - element.clientHeight\n if (distanceFromOldest <= props.paginationThreshold) void requestOlder()\n },\n }, children)\n }\n },\n})\n\nexport function defaultReadersResolver(\n readAtByUserId: ReadonlyMap<string, Date>,\n readPositionByUserId: ReadonlyMap<string, ReadPosition> = new Map(),\n): (message: Message) => ReadonlySet<string> {\n return (message) => readerIdsFor(message, readAtByUserId, readPositionByUserId)\n}\n","import type { Conversation, InboxSummary } from '@convokitapp/sdk'\nimport { ChevronRight, Inbox, LoaderCircle, RefreshCw } from '@lucide/vue'\nimport {\n defineComponent,\n h,\n ref,\n watchEffect,\n type CSSProperties,\n type PropType,\n type Ref,\n type VNodeChild,\n} from 'vue'\nimport type { ConversationListController, UseConversationListOptions } from '../composables/use-conversation-list'\nimport { useConversationList } from '../composables/use-conversation-list'\nimport type {\n ConversationFilter,\n ConversationItemSlotProps,\n ConversationPageLoader,\n ConvoKitAppearanceProps,\n ConvoKitUiClient,\n ConvoKitUiDensity,\n ConvoKitUiPart,\n} from '../types'\nimport { cx, errorMessage, formatMessageTime, inboxPreview, partClass, partStyle } from '../utils'\nimport { ConvoKitAvatar } from './avatar'\n\nexport interface ConversationListViewProps extends ConvoKitAppearanceProps {\n conversations: readonly Conversation[]\n /** Inbox summaries by conversation ID (0.6.0). Rows with one show a preview, time and unread badge: the count, or\n * a numberless dot when `isUnread` is set without one (0.7.0).\n */\n summaries?: ReadonlyMap<string, InboxSummary>\n /** The viewer; a preview from them reads `You: …`. Absent → no prefix. */\n currentUserId?: string\n selectedConversationId?: string\n onConversationSelect?: (conversation: Conversation) => void\n onRefresh?: () => void | Promise<void>\n onLoadMore?: () => void | Promise<void>\n isInitialLoading?: boolean\n isLoadingMore?: boolean\n hasMore?: boolean\n error?: unknown\n scrollElement?: Ref<HTMLElement | null>\n paginationThreshold?: number\n ariaLabel?: string\n class?: unknown\n style?: unknown\n}\n\nconst appearanceProps = {\n classNames: { type: Object as PropType<Partial<Record<ConvoKitUiPart, string>>>, default: undefined },\n styles: { type: Object as PropType<Partial<Record<ConvoKitUiPart, CSSProperties>>>, default: undefined },\n density: { type: String as PropType<ConvoKitUiDensity>, default: 'comfortable' },\n unstyled: { type: Boolean, default: false },\n} as const\n\nconst listViewProps = {\n ...appearanceProps,\n conversations: { type: Array as PropType<readonly Conversation[]>, required: true },\n summaries: { type: Object as PropType<ReadonlyMap<string, InboxSummary>>, default: undefined },\n currentUserId: { type: String, default: undefined },\n selectedConversationId: { type: String, default: undefined },\n onConversationSelect: { type: Function as PropType<(conversation: Conversation) => void>, default: undefined },\n onRefresh: { type: Function as PropType<() => void | Promise<void>>, default: undefined },\n onLoadMore: { type: Function as PropType<() => void | Promise<void>>, default: undefined },\n isInitialLoading: { type: Boolean, default: false },\n isLoadingMore: { type: Boolean, default: false },\n hasMore: { type: Boolean, default: false },\n error: { type: null as unknown as PropType<unknown>, required: false },\n scrollElement: { type: Object as PropType<Ref<HTMLElement | null>>, default: undefined },\n paginationThreshold: { type: Number, default: 240 },\n ariaLabel: { type: String, default: 'Conversations' },\n} as const\n\n/** Controlled conversation list. It can be used with any state-management layer. */\nexport const ConversationListView = defineComponent({\n name: 'ConversationListView',\n inheritAttrs: false,\n props: listViewProps,\n emits: {\n 'conversation-select': (_conversation: Conversation) => true,\n refresh: () => true,\n 'load-more': () => true,\n },\n setup(props, { attrs, emit, slots }) {\n const internalElement = ref<HTMLElement | null>(null)\n let requestInFlight = false\n let lastRequestedLength: number | null = null\n\n const appearance = (): ConvoKitAppearanceProps => ({\n density: props.density,\n unstyled: props.unstyled,\n ...(props.classNames ? { classNames: props.classNames } : {}),\n ...(props.styles ? { styles: props.styles } : {}),\n })\n\n const requestMore = async () => {\n if (requestInFlight || lastRequestedLength === props.conversations.length || props.isInitialLoading || props.isLoadingMore || !props.hasMore || !props.onLoadMore) return\n requestInFlight = true\n lastRequestedLength = props.conversations.length\n try { await props.onLoadMore() }\n catch { lastRequestedLength = null }\n finally { requestInFlight = false }\n }\n\n const selectConversation = (conversation: Conversation) => {\n props.onConversationSelect?.(conversation)\n }\n\n const refresh = () => {\n return props.onRefresh?.()\n }\n\n /** Inline errors retry the next page when one is pending (past the duplicate guard), otherwise refresh. */\n const inlineRetry = (): (() => void) | undefined => {\n if (props.hasMore && props.onLoadMore) return () => { lastRequestedLength = null; void requestMore() }\n if (props.onRefresh) return () => { void refresh() }\n return undefined\n }\n\n /** A count (or a capped count) keeps the numeric badge; a marker without one is a numberless dot named\n * `Unread` (never `0 unread`). Returned as a spread so an absent badge adds no child.\n */\n const unreadBadge = (summary: InboxSummary): VNodeChild[] => {\n if (summary.unreadCount > 0 || summary.unreadCountCapped) {\n const capped = summary.unreadCountCapped || summary.unreadCount > 99\n return [h('span', {\n class: 'ckui-unread-badge',\n role: 'img',\n 'aria-label': `${summary.unreadCountCapped ? '99+' : summary.unreadCount} unread`,\n }, [h('span', { 'aria-hidden': 'true' }, capped ? '99+' : String(summary.unreadCount))])]\n }\n if (summary.isUnread) return [h('span', { class: 'ckui-unread-badge ckui-unread-badge--dot', role: 'img', 'aria-label': 'Unread' })]\n return []\n }\n\n const renderContent = () => {\n const currentAppearance = appearance()\n if (props.isInitialLoading && props.conversations.length === 0) {\n return slots['initial-loading']?.() ?? h('div', {\n class: partClass('loading', currentAppearance, 'ckui-state'),\n style: partStyle('loading', currentAppearance),\n role: 'status',\n }, [h(LoaderCircle, { class: 'ckui-spin', 'aria-hidden': 'true' }), ' Loading conversations…'])\n }\n if (props.error && props.conversations.length === 0) {\n const retry = props.onRefresh ? () => { void refresh() } : undefined\n return slots.error?.({ error: props.error, ...(retry ? { retry } : {}) }) ?? h('div', {\n class: partClass('error', currentAppearance, 'ckui-state ckui-state--error'),\n style: partStyle('error', currentAppearance),\n role: 'alert',\n }, [\n h('span', errorMessage(props.error)),\n retry ? h('button', { type: 'button', class: 'ckui-link-button', onClick: retry }, 'Try again') : null,\n ])\n }\n if (props.conversations.length === 0) {\n return slots.empty?.() ?? h('div', {\n class: partClass('empty', currentAppearance, 'ckui-state'),\n style: partStyle('empty', currentAppearance),\n }, [h(Inbox, { 'aria-hidden': 'true' }), ' No conversations yet'])\n }\n const children: VNodeChild[] = props.conversations.flatMap((conversation, index) => {\n const selected = props.selectedConversationId === conversation.id\n const select = () => selectConversation(conversation)\n const summary = props.summaries?.get(conversation.id)\n const slotProps: ConversationItemSlotProps = {\n conversation, index, selected, select,\n ...(summary ? { summary } : {}),\n ...(props.currentUserId === undefined ? {} : { currentUserId: props.currentUserId }),\n }\n const preview = inboxPreview(conversation, summary, props.currentUserId)\n // Consumer-built summaries that omit `isUnread` keep their count-driven badges.\n const unread = summary !== undefined && (summary.isUnread || summary.unreadCount > 0 || summary.unreadCountCapped)\n const item = slots['conversation-item']?.(slotProps) ?? h('button', {\n type: 'button',\n 'data-selected': selected || undefined,\n 'data-unread': unread || undefined,\n 'aria-current': selected ? 'true' : undefined,\n onClick: select,\n class: partClass('listItem', currentAppearance, 'ckui-conversation-item'),\n style: partStyle('listItem', currentAppearance),\n }, [\n h(ConvoKitAvatar, {\n name: conversation.displayTitle,\n src: conversation.imageUrl,\n class: partClass('avatar', currentAppearance, ''),\n style: partStyle('avatar', currentAppearance),\n } as never),\n h('span', { class: 'ckui-conversation-item__body' }, [\n h('strong', conversation.displayTitle),\n h('span', preview || conversation.participants.map((participant) => participant.name).join(', ') || conversation.description || 'No participants'),\n ]),\n // Spread rather than emit `null`: a null child renders a `<!---->` comment, and rows without a\n // summary must keep 0.5's exact markup.\n ...(summary ? [h('span', { class: 'ckui-conversation-item__meta' }, [\n h('time', { class: 'ckui-conversation-item__time', datetime: summary.activityAt.toISOString() }, formatMessageTime(summary.activityAt)),\n ...unreadBadge(summary),\n ])] : []),\n h(ChevronRight, { size: 18, 'aria-hidden': 'true' }),\n ])\n const nodes = [h('div', { key: conversation.id, role: 'listitem' }, [item])]\n if (index < props.conversations.length - 1) {\n nodes.push(h('div', { key: `${conversation.id}-separator` }, slots.separator?.({ index }) ?? h('div', { class: 'ckui-separator' })))\n }\n return nodes\n })\n if (props.error) {\n const retry = inlineRetry()\n children.push(slots.error?.({ error: props.error, ...(retry ? { retry } : {}) }) ?? h('div', {\n class: partClass('error', currentAppearance, 'ckui-inline-state ckui-state--error'),\n style: partStyle('error', currentAppearance),\n role: 'alert',\n }, [\n h('span', errorMessage(props.error)),\n ...(retry ? [h('button', { type: 'button', class: 'ckui-link-button', onClick: retry }, 'Retry')] : []),\n ]))\n } else if (props.isLoadingMore) {\n children.push(slots['load-more']?.() ?? h('div', {\n class: partClass('loading', currentAppearance, 'ckui-inline-state'),\n style: partStyle('loading', currentAppearance),\n role: 'status',\n }, [h(LoaderCircle, { class: 'ckui-spin', 'aria-hidden': 'true' }), ' Loading more…']))\n }\n return h('div', {\n role: 'list',\n class: partClass('list', currentAppearance, 'ckui-conversation-list__items'),\n style: partStyle('list', currentAppearance),\n }, children)\n }\n\n return () => h('div', {\n ...attrs,\n class: cx(!props.unstyled && 'ckui ckui-conversation-list', props.classNames?.root, attrs.class),\n style: [props.styles?.root, attrs.style],\n 'data-density': props.density,\n }, [\n props.onRefresh ? h('div', { class: 'ckui-conversation-list__toolbar' }, [\n h('span', props.ariaLabel),\n h('button', {\n type: 'button',\n 'aria-label': 'Refresh conversations',\n class: partClass('button', appearance(), 'ckui-icon-button'),\n style: partStyle('button', appearance()),\n onClick: () => { void refresh() },\n }, [h(RefreshCw, { size: 17, 'aria-hidden': 'true' })]),\n ]) : null,\n h('div', {\n ref: (element: unknown) => {\n internalElement.value = element as HTMLElement | null\n if (props.scrollElement) props.scrollElement.value = element as HTMLElement | null\n },\n class: cx(!props.unstyled && 'ckui-scroll-area', props.classNames?.list),\n style: props.styles?.list,\n 'aria-label': props.ariaLabel,\n onScroll: (event: Event) => {\n const nativeHandler = attrs.onScroll\n if (typeof nativeHandler === 'function') nativeHandler(event)\n const element = event.currentTarget as HTMLElement\n if (element.scrollHeight - element.scrollTop - element.clientHeight <= props.paginationThreshold) void requestMore()\n },\n }, [renderContent()]),\n ])\n },\n})\n\nexport interface ConversationListProps extends Omit<ConversationListViewProps,\n 'conversations' | 'onRefresh' | 'onLoadMore' | 'isInitialLoading' | 'isLoadingMore' | 'hasMore' | 'error'>,\n Omit<UseConversationListOptions, 'client'> {\n client: ConvoKitUiClient\n onControllerChange?: (controller: ConversationListController) => void\n}\n\n/** Plug-and-play SDK-backed conversation list. */\nexport const ConversationList = defineComponent({\n name: 'ConversationList',\n inheritAttrs: false,\n props: {\n ...listViewProps,\n conversations: { type: Array as PropType<readonly Conversation[]>, default: () => [] },\n client: { type: Object as PropType<ConvoKitUiClient>, required: true },\n pageLoader: { type: Function as PropType<ConversationPageLoader>, default: undefined },\n initialFilter: { type: Object as PropType<ConversationFilter>, default: undefined },\n pageSize: { type: Number, default: 30 },\n autoLoad: { type: Boolean, default: true },\n activityRefreshWindowMs: { type: Number, default: undefined },\n onControllerChange: { type: Function as PropType<(controller: ConversationListController) => void>, default: undefined },\n },\n emits: ['conversation-select', 'controller-change'],\n setup(props, { attrs, emit, expose, slots }) {\n const controller = useConversationList({\n client: () => props.client,\n ...(props.pageLoader ? { pageLoader: props.pageLoader } : {}),\n ...(props.initialFilter ? { initialFilter: props.initialFilter } : {}),\n pageSize: props.pageSize,\n autoLoad: props.autoLoad,\n ...(props.activityRefreshWindowMs === undefined ? {} : { activityRefreshWindowMs: props.activityRefreshWindowMs }),\n })\n expose({ controller })\n watchEffect(() => {\n emit('controller-change', controller)\n })\n return () => {\n const {\n client: _client,\n pageLoader: _pageLoader,\n initialFilter: _initialFilter,\n pageSize: _pageSize,\n autoLoad: _autoLoad,\n activityRefreshWindowMs: _activityRefreshWindowMs,\n onControllerChange: _onControllerChange,\n conversations: _conversations,\n summaries: _summaries,\n currentUserId: _currentUserId,\n onRefresh: _onRefresh,\n onLoadMore: _onLoadMore,\n isInitialLoading: _isInitialLoading,\n isLoadingMore: _isLoadingMore,\n hasMore: _hasMore,\n error: _error,\n ...forwarded\n } = props\n return h(ConversationListView, {\n ...attrs,\n ...forwarded,\n conversations: controller.conversations.value,\n summaries: controller.summaries.value,\n currentUserId: controller.currentUserId.value,\n onRefresh: controller.refresh,\n onLoadMore: controller.loadMore,\n isInitialLoading: controller.isInitialLoading.value,\n isLoadingMore: controller.isLoadingMore.value,\n hasMore: controller.hasMore.value,\n ...(controller.error.value == null ? {} : { error: controller.error.value }),\n onConversationSelect: (conversation: Conversation) => {\n emit('conversation-select', conversation)\n },\n } as never, slots)\n }\n },\n})\n","import type { ClearConversationUnreadOptions } from '@convokitapp/sdk'\nimport { computed, getCurrentScope, onScopeDispose, shallowRef, toValue, watch, type MaybeRefOrGetter } from 'vue'\nimport type { ConversationFilter, ConversationListState, ConversationPageLoader, ConvoKitUiClient } from '../types'\nimport { ConversationListStore, type ConversationListSnapshot } from '../conversation-list-store'\n\nexport interface UseConversationListOptions {\n client: MaybeRefOrGetter<ConvoKitUiClient>\n pageLoader?: ConversationPageLoader\n initialFilter?: ConversationFilter\n pageSize?: number\n autoLoad?: boolean\n /** Max-wait window (ms) that coalesces `inbox_activity` signals into one refresh; default 500, 0 = immediate. */\n activityRefreshWindowMs?: number\n}\nexport interface ConversationListController extends ConversationListState {\n loadInitial(): Promise<void>\n refresh(): Promise<void>\n loadMore(): Promise<void>\n setFilter(filter: ConversationFilter): Promise<void>\n setQuery(query: string): Promise<void>\n /** Mark a room unread for the viewer only (0.7.0); its summary shows the marker at once. Rejects when the adapter\n * lacks `markConversationUnread`.\n */\n markUnread(conversationId: string): Promise<void>\n /** Remove the viewer's marker, only while it still has `options.ifVersion` when given; resolves to whether this\n * request removed it. Rejects when the adapter lacks `clearConversationUnread`.\n */\n clearUnread(conversationId: string, options?: ClearConversationUnreadOptions): Promise<boolean>\n dispose(): Promise<void>\n}\n\nexport function useConversationList(options: UseConversationListOptions): ConversationListController {\n const createStore = () => new ConversationListStore({ ...options, client: toValue(options.client) })\n let store = createStore()\n const snapshot = shallowRef(store.getSnapshot())\n let unsubscribe: (() => void) | undefined\n const stop = watch(\n () => [toValue(options.client), toValue(options.client).sessionIdentity] as const,\n () => {\n store.dispose()\n unsubscribe?.()\n store = createStore()\n snapshot.value = store.getSnapshot()\n unsubscribe = store.subscribe(() => { snapshot.value = store.getSnapshot() })\n store.start(options.autoLoad ?? true)\n },\n { immediate: true, flush: 'sync' },\n )\n const field = <K extends keyof ConversationListSnapshot>(key: K) => computed(() => snapshot.value[key])\n const dispose = async () => {\n stop()\n store.dispose()\n unsubscribe?.()\n unsubscribe = undefined\n }\n if (getCurrentScope()) onScopeDispose(() => { void dispose() })\n return {\n conversations: field('conversations'), summaries: field('summaries'), currentUserId: field('currentUserId'),\n filter: field('filter'),\n isInitialLoading: field('isInitialLoading'), isLoadingMore: field('isLoadingMore'),\n hasMore: field('hasMore'), hasLoaded: field('hasLoaded'), error: field('error'),\n loadInitial: () => store.loadInitial(), refresh: () => store.refresh(),\n loadMore: () => store.loadMore(), setFilter: (filter) => store.setFilter(filter),\n setQuery: (query) => store.setQuery(query),\n markUnread: (conversationId) => store.markUnread(conversationId),\n clearUnread: (conversationId, options) => store.clearUnread(conversationId, options),\n dispose,\n }\n}\n","import type {\n ClearConversationUnreadOptions, Conversation, ConversationPrivateState, InboxEntry, InboxPage, InboxSummary, RealtimeSubscription,\n} from '@convokitapp/sdk'\nimport type { ConversationFilter, ConversationPageLoader, ConvoKitUiClient } from './types'\nimport { applyConversationFilter, mergeConversations, mergeInboxEntries } from './utils'\n\nexport interface ConversationListSnapshot {\n conversations: Conversation[]\n summaries: ReadonlyMap<string, InboxSummary>\n currentUserId: string\n filter: ConversationFilter\n isInitialLoading: boolean\n isLoadingMore: boolean\n hasMore: boolean\n hasLoaded: boolean\n error: unknown\n}\ninterface Options {\n client: ConvoKitUiClient\n pageLoader?: ConversationPageLoader\n initialFilter?: ConversationFilter\n pageSize?: number\n /** Max-wait window for coalescing `inbox_activity` signals into one refresh; 0 refreshes immediately. */\n activityRefreshWindowMs?: number\n}\nconst defaultActivityRefreshWindowMs = 500\nfunction blank(filter: ConversationFilter): ConversationListSnapshot {\n return {\n conversations: [], summaries: new Map(), currentUserId: '', filter,\n isInitialLoading: false, isLoadingMore: false, hasMore: true, hasLoaded: false, error: null,\n }\n}\nfunction statusOf(cause: unknown): unknown {\n return typeof cause === 'object' && cause !== null && 'status' in cause ? cause.status : undefined\n}\nfunction summaryOf(entry: InboxEntry): InboxSummary {\n const { conversation: _conversation, ...summary } = entry\n return summary\n}\nfunction ids(entries: readonly InboxEntry[]): Conversation[] { return entries.map((entry) => entry.conversation) }\n\n/** Session-owned inbox paging. A page loader must belong to the same authenticated app.\n *\n * Inbox mode (an adapter with `listInbox`, no custom page loader, endpoint available) pages by opaque cursor in\n * activity order and carries per-room summaries; every other configuration is the legacy offset path over\n * `getConversations`, unchanged from 0.5 and without summaries.\n */\nexport class ConversationListStore {\n private readonly owner: object | null\n private readonly user: string\n private readonly pageSize: number\n private readonly activityRefreshWindowMs: number\n private state: ConversationListSnapshot\n private source: Conversation[] = []\n private entries: InboxEntry[] = []\n private offset = 0\n private cursor: string | null = null\n private inboxUnavailable = false\n private inboxWarned = false\n private generation = 0\n private lifecycleGeneration = 0\n private disposed = true\n private lifecycle: RealtimeSubscription | undefined\n private inbox: RealtimeSubscription | undefined\n private activity: RealtimeSubscription | undefined\n private activityTimer: ReturnType<typeof setTimeout> | undefined\n private refreshQueued = false\n private refreshing = false\n private listeners = new Set<() => void>()\n\n constructor(private readonly options: Options) {\n this.owner = options.client.sessionIdentity\n this.user = this.owner ? options.client.currentUserId : ''\n this.pageSize = options.pageSize ?? 30\n if (!Number.isInteger(this.pageSize) || this.pageSize < 1 || this.pageSize > 100) {\n throw new RangeError('pageSize must be an integer between 1 and 100')\n }\n this.activityRefreshWindowMs = options.activityRefreshWindowMs ?? defaultActivityRefreshWindowMs\n if (!Number.isFinite(this.activityRefreshWindowMs) || this.activityRefreshWindowMs < 0) {\n throw new RangeError('activityRefreshWindowMs must be a non-negative number')\n }\n this.state = blank(options.initialFilter ?? {})\n }\n getSnapshot = (): ConversationListSnapshot => this.state\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener)\n return () => { this.listeners.delete(listener) }\n }\n private patch(patch: Partial<ConversationListSnapshot>): void {\n this.state = { ...this.state, ...patch }\n for (const listener of this.listeners) listener()\n }\n private alive(generation = this.generation): boolean {\n return !this.disposed && generation === this.generation && this.owner !== null\n && this.options.client.sessionIdentity === this.owner\n }\n private get inboxMode(): boolean {\n return !this.options.pageLoader && typeof this.options.client.listInbox === 'function' && !this.inboxUnavailable\n }\n private currentUserId(): string { return this.inboxMode ? this.user : '' }\n start = (autoLoad = true): void => {\n if (!this.owner || this.options.client.sessionIdentity !== this.owner) return\n if (!this.disposed) return\n this.disposed = false\n this.inboxUnavailable = false\n const lifecycleGeneration = ++this.lifecycleGeneration\n const current = () => this.alive() && lifecycleGeneration === this.lifecycleGeneration\n const reconcile = (cause: Error) => {\n if (current()) {\n this.patch({ error: cause })\n // Reconcile authoritative REST after terminal topic denial as well.\n this.queueRefresh()\n }\n }\n try {\n this.patch({ currentUserId: this.currentUserId() })\n const subscription = this.options.client.onConnectionEvent({\n onEvent: () => {},\n onSessionEnded: () => {\n if (!this.disposed && lifecycleGeneration === this.lifecycleGeneration) this.dispose()\n },\n })\n if (this.alive()) this.lifecycle = subscription\n else void subscription.unsubscribe().catch(() => undefined)\n if (!this.alive()) return\n const inbox = this.options.client.onInboxChanged(() => {\n if (!current()) return\n // Structural changes are immediate and supersede a pending activity window.\n this.clearActivityTimer()\n this.queueRefresh()\n }, reconcile)\n if (this.alive()) this.inbox = inbox\n else void inbox.unsubscribe().catch(() => undefined)\n if (!this.alive()) return\n if (this.inboxMode && typeof this.options.client.onInboxActivity === 'function') {\n const activity = this.options.client.onInboxActivity(() => {\n if (current()) this.scheduleActivityRefresh(lifecycleGeneration)\n }, reconcile)\n if (this.alive()) this.activity = activity\n else void activity.unsubscribe().catch(() => undefined)\n }\n if (autoLoad) void this.loadInitial()\n } catch (cause) { if (this.alive()) this.patch({ error: cause }) }\n }\n dispose = (): void => {\n this.disposed = true\n this.generation++\n this.lifecycleGeneration++\n this.clearActivityTimer()\n const subscription = this.lifecycle\n this.lifecycle = undefined\n if (subscription) void subscription.unsubscribe().catch(() => undefined)\n if (this.inbox) void this.inbox.unsubscribe().catch(() => undefined)\n this.inbox = undefined\n this.stopActivity()\n this.refreshQueued = false\n this.refreshing = false\n this.source = []\n this.entries = []\n this.offset = 0\n this.cursor = null\n this.patch(blank(this.state.filter))\n }\n private stopActivity(): void {\n if (this.activity) void this.activity.unsubscribe().catch(() => undefined)\n this.activity = undefined\n }\n private clearActivityTimer(): void {\n if (this.activityTimer !== undefined) clearTimeout(this.activityTimer)\n this.activityTimer = undefined\n }\n /** Max-wait throttle: the first signal opens a window; later signals wait for it; one refresh runs when it closes. */\n private scheduleActivityRefresh(lifecycleGeneration: number): void {\n if (this.activityRefreshWindowMs === 0) return this.queueRefresh()\n if (this.activityTimer !== undefined) return\n const timer = setTimeout(() => {\n this.activityTimer = undefined\n if (this.alive() && lifecycleGeneration === this.lifecycleGeneration) this.queueRefresh()\n }, this.activityRefreshWindowMs)\n ;(timer as { unref?: () => void }).unref?.()\n this.activityTimer = timer\n }\n private fail(cause: unknown, generation: number): void {\n if (!this.alive(generation)) return\n const status = statusOf(cause)\n if (status === 401 || status === 403 || status === 404) {\n this.source = []\n this.entries = []\n this.offset = 0\n this.cursor = null\n this.patch({ conversations: [], summaries: new Map(), hasMore: false })\n }\n this.patch({ error: cause })\n }\n /** Run an operation in inbox mode, falling back to the legacy path for the rest of this store's life when the\n * inbox route is absent (404: rollback, staging). Loaded rows are kept and the same operation continues.\n */\n private async withFallback(generation: number, inbox: () => Promise<void>, legacy: () => Promise<void>): Promise<void> {\n if (!this.inboxMode) return legacy()\n try { await inbox() }\n catch (cause) {\n if (!this.alive(generation) || statusOf(cause) !== 404) throw cause\n this.inboxUnavailable = true\n this.clearActivityTimer()\n this.stopActivity()\n this.entries = []\n this.cursor = null\n this.offset = this.source.length\n if (!this.inboxWarned) {\n this.inboxWarned = true\n console.warn('ConvoKit inbox endpoint unavailable (404); using getConversations without previews or unread counts.')\n }\n this.patch({ summaries: new Map(), currentUserId: '' })\n await legacy()\n }\n }\n private validateInboxPage(page: InboxPage, limit: number, requestedCursor: string | null): void {\n const seen = new Set<string>()\n for (const entry of page.entries) {\n const id = entry.conversation.id\n if (!id.trim() || seen.has(id)) throw new Error('Invalid conversation page')\n seen.add(id)\n }\n if (page.entries.length > limit) throw new Error('Invalid conversation page')\n if (page.nextCursor !== null && (page.nextCursor === requestedCursor || page.entries.length === 0)) {\n throw new Error('Inbox pagination did not advance')\n }\n }\n /** Swap rows, summaries, cursor and hasMore together, filtered by the filter current at commit time. */\n private commitInbox(entries: InboxEntry[], cursor: string | null): void {\n this.entries = entries\n this.source = ids(entries)\n this.cursor = cursor\n this.patch({\n conversations: applyConversationFilter(this.source, this.state.filter),\n summaries: new Map(entries.map((entry) => [entry.conversation.id, summaryOf(entry)])),\n hasMore: cursor !== null,\n })\n }\n private async loadInboxUntilVisible(generation: number, filter: ConversationFilter): Promise<void> {\n const visibleBefore = applyConversationFilter(this.source, filter).length\n while (this.alive(generation)) {\n const requested = this.cursor\n const page = await this.options.client.listInbox!({ limit: this.pageSize, cursor: requested, archived: filter.archived ?? false })\n if (!this.alive(generation)) return\n this.validateInboxPage(page, this.pageSize, requested)\n this.commitInbox(mergeInboxEntries(this.entries, page.entries), page.nextCursor)\n if (page.nextCursor === null || this.state.conversations.length > visibleBefore) return\n }\n }\n private async loadUntilVisible(generation: number, filter: ConversationFilter): Promise<void> {\n const visibleBefore = applyConversationFilter(this.source, filter).length\n while (this.alive(generation)) {\n const request = { limit: this.pageSize, offset: this.offset, filter }\n const page = this.options.pageLoader\n ? await this.options.pageLoader(request)\n : await this.options.client.getConversations({ limit: this.pageSize, offset: this.offset, archived: filter.archived ?? false })\n if (!this.alive(generation)) return\n if (page.length > this.pageSize || page.some((conversation) => !conversation.id.trim())) {\n throw new Error('Invalid conversation page')\n }\n const merged = mergeConversations(this.source, page)\n if (page.length === this.pageSize && merged.length === this.source.length) {\n throw new Error('Conversation pagination did not advance')\n }\n this.offset += page.length\n this.source = merged\n const visible = applyConversationFilter(merged, filter)\n const hasMore = page.length === this.pageSize\n this.patch({ conversations: visible, hasMore })\n if (!hasMore || visible.length > visibleBefore) return\n }\n }\n loadInitial = async (): Promise<void> => {\n if (!this.alive()) return\n const generation = ++this.generation\n this.refreshing = false\n this.source = []\n this.entries = []\n this.offset = 0\n this.cursor = null\n this.patch({ ...blank(this.state.filter), currentUserId: this.currentUserId(), isInitialLoading: true })\n const filter = this.state.filter\n try {\n await this.withFallback(generation,\n () => this.loadInboxUntilVisible(generation, filter),\n () => this.loadUntilVisible(generation, filter))\n } catch (cause) { this.fail(cause, generation) }\n finally {\n if (this.alive(generation)) {\n this.patch({ isInitialLoading: false, hasLoaded: true })\n this.flushRefresh()\n }\n }\n }\n private queueRefresh(): void {\n this.refreshQueued = true\n this.flushRefresh()\n }\n private flushRefresh(): void {\n const lifecycle = this.lifecycleGeneration\n void Promise.resolve().then(() => {\n if (!this.alive() || lifecycle !== this.lifecycleGeneration || !this.refreshQueued\n || this.refreshing || this.state.isInitialLoading || this.state.isLoadingMore) return\n this.refreshQueued = false\n void this.refresh()\n })\n }\n /** Re-walk the inbox from the head until the loaded window is covered and something is visible, or the inbox\n * ends. Rooms that moved are re-positioned by the merge; an exhausted inbox publishes what it found.\n */\n private async refreshInbox(generation: number, filter: ConversationFilter): Promise<void> {\n const target = Math.max(this.pageSize, this.entries.length)\n let rows: InboxEntry[] = [], consumed = 0, cursor: string | null = null\n while (this.alive(generation)) {\n const remaining = target - consumed\n // Past the covered window (still nothing visible) continue in page-size steps.\n const limit = remaining >= 1 ? Math.min(100, remaining) : this.pageSize\n const page = await this.options.client.listInbox!({ limit, cursor, archived: filter.archived ?? false })\n if (!this.alive(generation)) return\n this.validateInboxPage(page, limit, cursor)\n rows = mergeInboxEntries(rows, page.entries)\n consumed += page.entries.length\n cursor = page.nextCursor\n if (cursor === null || (consumed >= target && applyConversationFilter(ids(rows), this.state.filter).length > 0)) break\n }\n if (!this.alive(generation)) return\n this.commitInbox(rows, cursor)\n }\n private async refreshLegacy(generation: number, filter: ConversationFilter): Promise<void> {\n const target = Math.max(this.pageSize, this.offset)\n // Default REST order is immutable creation time/ID, independent of UI sorting.\n const compare = (a: Conversation, b: Conversation) => a.createdAt.getTime() - b.createdAt.getTime()\n || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)\n const boundary = this.options.pageLoader ? undefined\n : this.source.reduce<Conversation | undefined>((oldest, row) => !oldest || compare(row, oldest) < 0 ? row : oldest, undefined)\n let rows: Conversation[] = [], offset = 0, hasMore = true\n while (this.alive(generation)) {\n const page = this.options.pageLoader\n ? await this.options.pageLoader({ limit: this.pageSize, offset, filter })\n : await this.options.client.getConversations({ limit: this.pageSize, offset, archived: filter.archived ?? false })\n if (!this.alive(generation)) return\n if (page.length > this.pageSize || page.some(row => !row.id.trim())) throw new Error('Invalid conversation page')\n const merged = mergeConversations(rows, page)\n if (page.length === this.pageSize && merged.length === rows.length) throw new Error('Conversation pagination did not advance')\n rows = merged\n offset += page.length\n hasMore = page.length === this.pageSize\n if (!hasMore || (offset >= target && applyConversationFilter(rows, this.state.filter).length > 0\n && (!boundary || page.some(row => compare(row, boundary) <= 0)))) break\n }\n if (!this.alive(generation)) return\n this.source = rows\n this.offset = offset\n this.patch({ conversations: applyConversationFilter(rows, this.state.filter), hasMore })\n }\n /** Replace the loaded window atomically, retaining filters and rows during transient failures. */\n refresh = async (): Promise<void> => {\n if (!this.alive()) return\n if (this.refreshing || this.state.isInitialLoading || this.state.isLoadingMore) {\n this.refreshQueued = true\n return\n }\n if (!this.state.hasLoaded) return this.loadInitial()\n const generation = this.generation\n const filter = this.state.filter\n this.refreshing = true\n this.patch({ error: null })\n try {\n await this.withFallback(generation,\n () => this.refreshInbox(generation, filter),\n () => this.refreshLegacy(generation, filter))\n } catch (cause) { this.fail(cause, generation) }\n finally {\n if (this.alive(generation)) {\n this.refreshing = false\n this.flushRefresh()\n }\n }\n }\n loadMore = async (): Promise<void> => {\n if (!this.alive() || this.refreshing || this.state.isInitialLoading || this.state.isLoadingMore || !this.state.hasMore) return\n const generation = this.generation\n const filter = this.state.filter\n this.patch({ isLoadingMore: true, error: null })\n try {\n await this.withFallback(generation,\n () => this.loadInboxUntilVisible(generation, filter),\n () => this.loadUntilVisible(generation, filter))\n } catch (cause) { this.fail(cause, generation) }\n finally {\n if (this.alive(generation)) {\n this.patch({ isLoadingMore: false })\n this.flushRefresh()\n }\n }\n }\n setFilter = async (filter: ConversationFilter): Promise<void> => {\n if (!this.alive()) return\n const reload = this.options.pageLoader || !this.state.hasLoaded || this.state.isInitialLoading\n || this.state.isLoadingMore || (filter.archived ?? false) !== (this.state.filter.archived ?? false)\n this.patch({ filter, conversations: applyConversationFilter(this.source, filter), error: null })\n if (reload) await this.loadInitial()\n else if (!this.state.conversations.length && this.state.hasMore) await this.loadMore()\n }\n setQuery = (query: string): Promise<void> => this.setFilter({ ...this.state.filter, query })\n /** Mark a room unread for the viewer only; the row's summary takes the response (D10). Rejects when the adapter\n * lacks `markConversationUnread` or the store is not active; a request failure is reported through `error`\n * without evicting rows and rejects.\n */\n markUnread = async (conversationId: string): Promise<void> => {\n const client = this.options.client\n if (typeof client.markConversationUnread !== 'function') {\n throw new TypeError('markUnread requires a ConvoKitUiClient adapter with markConversationUnread (core SDK 0.7)')\n }\n this.assertActive()\n this.applyPrivateState(conversationId, await this.mutate(client.markConversationUnread(conversationId)))\n }\n /** Remove the viewer's marker (conditionally on `options.ifVersion`); resolves to the response's `cleared` (\"this\n * request removed the marker\", not \"the room is read\") and patches the summary on true and false alike (D10).\n * Rejects when the adapter lacks `clearConversationUnread` or the store is not active; failures are reported like\n * `markUnread`.\n */\n clearUnread = async (conversationId: string, options?: ClearConversationUnreadOptions): Promise<boolean> => {\n const client = this.options.client\n if (typeof client.clearConversationUnread !== 'function') {\n throw new TypeError('clearUnread requires a ConvoKitUiClient adapter with clearConversationUnread (core SDK 0.7)')\n }\n this.assertActive()\n const result = await this.mutate(client.clearConversationUnread(conversationId, options))\n this.applyPrivateState(conversationId, result)\n return result.cleared\n }\n /** A disposed or session-evicted store never sends a private-state mutation: on a shared client it could go out\n * under a replacement login. Rejected without touching `error` (there is no live snapshot to report into).\n */\n private assertActive(): void {\n if (!this.alive()) throw new Error('ConversationListStore is not active')\n }\n private async mutate<T>(request: Promise<T>): Promise<T> {\n try { return await request }\n catch (cause) {\n if (this.alive()) this.patch({ error: cause })\n throw cause\n }\n }\n /** Apply a mark/clear response to the row's CURRENT summary (a refresh may have swapped it) as one unit, only while\n * the store is alive and the response is not older than the stored version: a delayed response never resurrects a\n * marker a newer action removed (equal versions are an idempotent no-op). `isUnread` is recomputed from the stored\n * counts and the response marker. Other devices learn of the change through `inbox_activity`.\n */\n private applyPrivateState(conversationId: string, state: ConversationPrivateState): void {\n if (!this.alive()) return\n const current = this.entries.find((entry) => entry.conversation.id === conversationId)\n if (!current || state.privateStateVersion < current.privateStateVersion) return\n const { unreadMarkedAt, privateStateVersion } = state\n const patched: InboxEntry = {\n ...current, unreadMarkedAt, privateStateVersion,\n isUnread: current.unreadCount > 0 || current.unreadCountCapped || unreadMarkedAt !== null,\n }\n this.entries = this.entries.map((entry) => entry === current ? patched : entry)\n this.patch({ summaries: new Map(this.entries.map((entry) => [entry.conversation.id, summaryOf(entry)])) })\n }\n}\n","import {\n computed,\n defineComponent,\n h,\n inject,\n provide,\n type CSSProperties,\n type InjectionKey,\n type PropType,\n type Ref,\n} from 'vue'\nimport { cx } from './utils'\n\nexport interface ConvoKitTheme {\n background: string\n surface: string\n primary: string\n text: string\n mutedText: string\n border: string\n error: string\n incomingBubble: string\n outgoingBubble: string\n outgoingText: string\n /** Unread badge and dot background (0.6.0); the badge label uses `outgoingText`. Defaults to the primary color. */\n badge: string\n radius: string\n avatarSize: string\n fontFamily: string\n}\n\nexport const defaultConvoKitTheme: ConvoKitTheme = {\n background: '#fafafa',\n surface: '#ffffff',\n primary: '#18181b',\n text: '#09090b',\n mutedText: '#71717a',\n border: '#e4e4e7',\n error: '#dc2626',\n incomingBubble: '#f4f4f5',\n outgoingBubble: '#18181b',\n outgoingText: '#fafafa',\n badge: '#18181b',\n radius: '10px',\n avatarSize: '40px',\n fontFamily: 'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif',\n}\n\nconst themeKey: InjectionKey<Readonly<Ref<ConvoKitTheme>>> = Symbol('ConvoKitTheme')\nconst defaultThemeRef = computed(() => defaultConvoKitTheme)\n\nexport const ConvoKitThemeProvider = defineComponent({\n name: 'ConvoKitThemeProvider',\n inheritAttrs: false,\n props: {\n theme: { type: Object as PropType<Partial<ConvoKitTheme>>, default: () => ({}) },\n class: { type: [String, Array, Object] as PropType<unknown>, default: undefined },\n style: { type: [String, Array, Object] as PropType<unknown>, default: undefined },\n },\n setup(props, { attrs, slots }) {\n const parent = inject(themeKey, defaultThemeRef)\n const value = computed(() => ({ ...parent.value, ...props.theme }))\n provide(themeKey, value)\n return () => {\n const theme = value.value\n const variables = {\n '--ckui-background': theme.background,\n '--ckui-surface': theme.surface,\n '--ckui-primary': theme.primary,\n '--ckui-text': theme.text,\n '--ckui-muted': theme.mutedText,\n '--ckui-border': theme.border,\n '--ckui-error': theme.error,\n '--ckui-incoming': theme.incomingBubble,\n '--ckui-outgoing': theme.outgoingBubble,\n '--ckui-outgoing-text': theme.outgoingText,\n '--ckui-badge': theme.badge,\n '--ckui-radius': theme.radius,\n '--ckui-avatar-size': theme.avatarSize,\n '--ckui-font': theme.fontFamily,\n } as CSSProperties\n return h('div', {\n ...attrs,\n class: cx('ckui-theme', props.class, attrs.class),\n style: [variables, props.style, attrs.style],\n }, slots.default?.())\n }\n },\n})\n\nexport function useConvoKitTheme(): Readonly<Ref<ConvoKitTheme>> {\n return inject(themeKey, defaultThemeRef)\n}\n"],"mappings":"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","names":["import_vue","import_vue","import_vue","import_sdk","version","import_sdk","import_vue","appearanceProps","text","import_vue","import_vue","blank","compare","options","appearanceProps","import_vue"]}