@convokitapp/vue-ui 0.4.1 → 0.5.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 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 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 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) => client.markConversationRead(conversationId),\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, Message } 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/** 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\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 const byTime = left.createdAt.getTime() - right.createdAt.getTime()\n return byTime === 0 ? left.id.localeCompare(right.id) : byTime\n })\n}\n\nexport function readerIdsFor(message: Message, readAtByUserId: ReadonlyMap<string, Date>): ReadonlySet<string> {\n if (isConvoKitPendingMessage(message)) return new Set()\n return new Set([...readAtByUserId.entries()]\n .filter(([userId, readAt]) => userId !== message.senderId && readAt.getTime() >= message.createdAt.getTime())\n .map(([userId]) => userId))\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 } from '@convokitapp/sdk'\nimport { ArrowLeft, LoaderCircle, Paperclip, RefreshCw, Send } from '@lucide/vue'\nimport {\n defineComponent,\n h,\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 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 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 ...(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' | '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 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 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 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 markRead(): Promise<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 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.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 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 dispose,\n }\n}\n","import type { Conversation, Message, MessageEvent, MessageMedia, RealtimeSubscription } from '@convokitapp/sdk'\nimport { createClientMessageId } from '@convokitapp/sdk'\nimport type { ConvoKitUiClient } from './ui-client'\nimport { isConvoKitPendingMessage, mergeMessages, readerIdsFor } from './utils'\n\nexport interface ConversationSnapshot {\n conversation: Conversation | null\n messages: Message[]\n typingUserIds: ReadonlySet<string>\n readAtByUserId: ReadonlyMap<string, Date>\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> }\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\nfunction compare(left: Cursor, right: Cursor): number {\n return left.createdAt.getTime() - right.createdAt.getTime()\n || (left.id < right.id ? -1 : left.id > right.id ? 1 : 0)\n}\n\nfunction blank(currentUserId = ''): ConversationSnapshot {\n return {\n conversation: null, messages: [], typingUserIds: new Set(), readAtByUserId: 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 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 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 }) => {\n if (this.alive(generation)) this.mergeReads([[userId, readAt]])\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 if (type === 'insert' && !existing && message.senderId !== this.user && (this.options.markReadOnReceive ?? true)) {\n void this.markRead()\n }\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))) this.patch({ messages: mergeMessages(this.state.messages, [message]) })\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.deleted.add(id)\n this.changes.delete(id)\n this.hydrations.delete(id)\n this.hydrationPool.queued.delete(id)\n this.patch({ messages: this.state.messages.filter((message) => message.id !== id) })\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 private mergeReads(entries: Iterable<readonly [string, Date]>): void {\n const next = new Map(this.state.readAtByUserId)\n for (const [userId, readAt] of entries) {\n if (!userId.trim() || !Number.isFinite(readAt.getTime())) continue\n if (readAt.getTime() > (next.get(userId)?.getTime() ?? -Infinity)) next.set(userId, readAt)\n }\n this.patch({ readAtByUserId: next })\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 this.mergeReads(conversation.participants.flatMap((participant) => participant.lastReadAt ? [[participant.appUserId, participant.lastReadAt] as const] : []))\n this.prune(revision)\n if (this.options.markReadOnLoad ?? true) await this.markRead()\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)) {\n this.deleted.add(id)\n this.changes.delete(id)\n this.hydrations.delete(id)\n this.hydrationPool.queued.delete(id)\n }\n this.patch({ conversation, messages: reconciled, hasOlderMessages: hasOlder })\n this.mergeReads(conversation.participants.flatMap((participant) => participant.lastReadAt ? [[participant.appUserId, participant.lastReadAt] as const] : []))\n this.prune(revision)\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 markRead = async (): Promise<void> => {\n if (!this.alive()) return\n const generation = this.generation\n try {\n await this.client.markConversationRead(this.room)\n // Only persisted participant positions / server read events advance receipts.\n } catch (cause) { this.fail(cause, generation) }\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> => readerIdsFor(message, this.state.readAtByUserId)\n}\n","import type { Conversation, Message, MessageMedia } 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, isConvoKitPendingMessage, partClass, partStyle, readerIdsFor } from '../utils'\n\nexport interface MessageListViewProps extends ConvoKitAppearanceProps {\n conversation: Conversation\n messages: readonly Message[]\n currentUserId: string\n readAtByUserId?: ReadonlyMap<string, Date>\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 defaultFormatTime(date: Date): string {\n return new Intl.DateTimeFormat(undefined, { hour: 'numeric', minute: '2-digit' }).format(date)\n}\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 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: defaultFormatTime },\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)\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(readAtByUserId: ReadonlyMap<string, Date>): (message: Message) => ReadonlySet<string> {\n return (message) => readerIdsFor(message, readAtByUserId)\n}\n","import type { Conversation } 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, partClass, partStyle } from '../utils'\nimport { ConvoKitAvatar } from './avatar'\n\nexport interface ConversationListViewProps extends ConvoKitAppearanceProps {\n conversations: readonly Conversation[]\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 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 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 slotProps: ConversationItemSlotProps = { conversation, index, selected, select }\n const item = slots['conversation-item']?.(slotProps) ?? h('button', {\n type: 'button',\n 'data-selected': selected || 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', conversation.participants.map((participant) => participant.name).join(', ') || conversation.description || 'No participants'),\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 children.push(slots.error?.({ error: props.error, retry: requestMore }) ?? h('div', {\n class: partClass('error', currentAppearance, 'ckui-inline-state ckui-state--error'),\n style: partStyle('error', currentAppearance),\n role: 'alert',\n }, [h('span', errorMessage(props.error)), h('button', { type: 'button', class: 'ckui-link-button', onClick: () => { void requestMore() } }, 'Retry')]))\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 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 })\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 onControllerChange: _onControllerChange,\n conversations: _conversations,\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 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 { 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}\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 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'), 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), dispose,\n }\n}\n","import type { Conversation, RealtimeSubscription } from '@convokitapp/sdk'\nimport type { ConversationFilter, ConversationPageLoader, ConvoKitUiClient } from './types'\nimport { applyConversationFilter, mergeConversations } from './utils'\n\nexport interface ConversationListSnapshot {\n conversations: Conversation[]\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}\nfunction blank(filter: ConversationFilter): ConversationListSnapshot {\n return { conversations: [], filter, isInitialLoading: false, isLoadingMore: false, hasMore: true, hasLoaded: false, error: null }\n}\n\n/** Session-owned inbox paging. A page loader must belong to the same authenticated app. */\nexport class ConversationListStore {\n private readonly owner: object | null\n private readonly pageSize: number\n private state: ConversationListSnapshot\n private source: Conversation[] = []\n private offset = 0\n private generation = 0\n private lifecycleGeneration = 0\n private disposed = true\n private lifecycle: RealtimeSubscription | undefined\n private inbox: RealtimeSubscription | 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.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.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 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 const lifecycleGeneration = ++this.lifecycleGeneration\n try {\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 (this.alive() && lifecycleGeneration === this.lifecycleGeneration) this.queueRefresh()\n }, (cause) => {\n if (this.alive() && lifecycleGeneration === this.lifecycleGeneration) {\n this.patch({ error: cause })\n // Reconcile authoritative REST after terminal topic denial as well.\n this.queueRefresh()\n }\n })\n if (this.alive()) this.inbox = inbox\n else void inbox.unsubscribe().catch(() => undefined)\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 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.refreshQueued = false\n this.refreshing = false\n this.source = []\n this.offset = 0\n this.patch(blank(this.state.filter))\n }\n private fail(cause: unknown, generation: number): void {\n if (!this.alive(generation)) return\n const status = typeof cause === 'object' && cause !== null && 'status' in cause ? cause.status : undefined\n if (status === 401 || status === 403 || status === 404) {\n this.source = []\n this.offset = 0\n this.patch({ conversations: [], hasMore: false })\n }\n this.patch({ error: cause })\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.offset = 0\n this.patch({ ...blank(this.state.filter), isInitialLoading: true })\n try { await this.loadUntilVisible(generation, this.state.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 /** 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 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 this.refreshing = true\n this.patch({ error: null })\n try {\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 } 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 this.patch({ isLoadingMore: true, error: null })\n try { await this.loadUntilVisible(generation, this.state.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}\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 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 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-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_vue","appearanceProps","import_vue","import_vue","blank","compare","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 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 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 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 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, 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\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; re-issued once the view becomes visible. */\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\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}\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 // 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 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 this.mergeReads(conversation.participants.map(readEntry))\n this.prune(revision)\n if (this.options.markReadOnLoad ?? true) await this.acknowledge(true)\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 this.patch({ conversation, messages: reconciled, hasOlderMessages: hasOlder })\n this.mergeReads(conversation.participants.map(readEntry))\n this.prune(revision)\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 request without a target. */\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.ack.suppressed || !this.alive()) return\n this.ack.suppressed = false\n void 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 if (automatic && !this.visible) {\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 if (!target) return undefined\n ack.target = target.id\n ack.inFlight = this.send(ack, generation, target).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 private async send(ack: Acknowledgement, generation: number, target: Cursor): Promise<void> {\n try {\n await this.client.markConversationRead(this.room, { throughMessageId: target.id })\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, 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 defaultFormatTime(date: Date): string {\n return new Intl.DateTimeFormat(undefined, { hour: 'numeric', minute: '2-digit' }).format(date)\n}\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: defaultFormatTime },\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 } 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, partClass, partStyle } from '../utils'\nimport { ConvoKitAvatar } from './avatar'\n\nexport interface ConversationListViewProps extends ConvoKitAppearanceProps {\n conversations: readonly Conversation[]\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 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 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 slotProps: ConversationItemSlotProps = { conversation, index, selected, select }\n const item = slots['conversation-item']?.(slotProps) ?? h('button', {\n type: 'button',\n 'data-selected': selected || 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', conversation.participants.map((participant) => participant.name).join(', ') || conversation.description || 'No participants'),\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 children.push(slots.error?.({ error: props.error, retry: requestMore }) ?? h('div', {\n class: partClass('error', currentAppearance, 'ckui-inline-state ckui-state--error'),\n style: partStyle('error', currentAppearance),\n role: 'alert',\n }, [h('span', errorMessage(props.error)), h('button', { type: 'button', class: 'ckui-link-button', onClick: () => { void requestMore() } }, 'Retry')]))\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 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 })\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 onControllerChange: _onControllerChange,\n conversations: _conversations,\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 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 { 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}\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 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'), 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), dispose,\n }\n}\n","import type { Conversation, RealtimeSubscription } from '@convokitapp/sdk'\nimport type { ConversationFilter, ConversationPageLoader, ConvoKitUiClient } from './types'\nimport { applyConversationFilter, mergeConversations } from './utils'\n\nexport interface ConversationListSnapshot {\n conversations: Conversation[]\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}\nfunction blank(filter: ConversationFilter): ConversationListSnapshot {\n return { conversations: [], filter, isInitialLoading: false, isLoadingMore: false, hasMore: true, hasLoaded: false, error: null }\n}\n\n/** Session-owned inbox paging. A page loader must belong to the same authenticated app. */\nexport class ConversationListStore {\n private readonly owner: object | null\n private readonly pageSize: number\n private state: ConversationListSnapshot\n private source: Conversation[] = []\n private offset = 0\n private generation = 0\n private lifecycleGeneration = 0\n private disposed = true\n private lifecycle: RealtimeSubscription | undefined\n private inbox: RealtimeSubscription | 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.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.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 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 const lifecycleGeneration = ++this.lifecycleGeneration\n try {\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 (this.alive() && lifecycleGeneration === this.lifecycleGeneration) this.queueRefresh()\n }, (cause) => {\n if (this.alive() && lifecycleGeneration === this.lifecycleGeneration) {\n this.patch({ error: cause })\n // Reconcile authoritative REST after terminal topic denial as well.\n this.queueRefresh()\n }\n })\n if (this.alive()) this.inbox = inbox\n else void inbox.unsubscribe().catch(() => undefined)\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 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.refreshQueued = false\n this.refreshing = false\n this.source = []\n this.offset = 0\n this.patch(blank(this.state.filter))\n }\n private fail(cause: unknown, generation: number): void {\n if (!this.alive(generation)) return\n const status = typeof cause === 'object' && cause !== null && 'status' in cause ? cause.status : undefined\n if (status === 401 || status === 403 || status === 404) {\n this.source = []\n this.offset = 0\n this.patch({ conversations: [], hasMore: false })\n }\n this.patch({ error: cause })\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.offset = 0\n this.patch({ ...blank(this.state.filter), isInitialLoading: true })\n try { await this.loadUntilVisible(generation, this.state.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 /** 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 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 this.refreshing = true\n this.patch({ error: null })\n try {\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 } 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 this.patch({ isLoadingMore: true, error: null })\n try { await this.loadUntilVisible(generation, this.state.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}\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 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 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-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","import_vue","appearanceProps","import_vue","import_vue","blank","compare","appearanceProps","import_vue"]}