@aparte/svelte 0.6.1 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +26 -123
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -3,12 +3,8 @@ import "svelte/internal/disclose-version";
|
|
|
3
3
|
import { createEventDispatcher, onMount, onDestroy, tick } from "svelte";
|
|
4
4
|
import { AparteChatHost, isAwaitingReply, AparteClient, ConversationManager, AparteConfig, DEFAULT_UI_EVENTS, applyElementProps } from "@aparte/core";
|
|
5
5
|
import { writable, derived } from "svelte/store";
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const get_footer_center_slot_changes = (dirty) => ({});
|
|
9
|
-
const get_footer_center_slot_context = (ctx) => ({});
|
|
10
|
-
const get_footer_left_slot_changes = (dirty) => ({});
|
|
11
|
-
const get_footer_left_slot_context = (ctx) => ({});
|
|
6
|
+
const get_toolbar_slot_changes = (dirty) => ({});
|
|
7
|
+
const get_toolbar_slot_context = (ctx) => ({});
|
|
12
8
|
const get_composer_slot_changes = (dirty) => ({});
|
|
13
9
|
const get_composer_slot_context = (ctx) => ({});
|
|
14
10
|
const get_above_composer_slot_changes = (dirty) => ({});
|
|
@@ -264,98 +260,38 @@ function create_if_block_1(ctx) {
|
|
|
264
260
|
};
|
|
265
261
|
}
|
|
266
262
|
function create_if_block(ctx) {
|
|
267
|
-
let
|
|
268
|
-
let t0;
|
|
269
|
-
let t1;
|
|
263
|
+
let aparte_composer_toolbar;
|
|
270
264
|
let current;
|
|
271
|
-
const
|
|
272
|
-
/*#slots*/
|
|
273
|
-
ctx[44]["footer-left"]
|
|
274
|
-
);
|
|
275
|
-
const footer_left_slot = create_slot(
|
|
276
|
-
footer_left_slot_template,
|
|
277
|
-
ctx,
|
|
278
|
-
/*$$scope*/
|
|
279
|
-
ctx[43],
|
|
280
|
-
get_footer_left_slot_context
|
|
281
|
-
);
|
|
282
|
-
const footer_center_slot_template = (
|
|
265
|
+
const toolbar_slot_template = (
|
|
283
266
|
/*#slots*/
|
|
284
|
-
ctx[44]
|
|
267
|
+
ctx[44].toolbar
|
|
285
268
|
);
|
|
286
|
-
const
|
|
287
|
-
|
|
269
|
+
const toolbar_slot = create_slot(
|
|
270
|
+
toolbar_slot_template,
|
|
288
271
|
ctx,
|
|
289
272
|
/*$$scope*/
|
|
290
273
|
ctx[43],
|
|
291
|
-
|
|
292
|
-
);
|
|
293
|
-
const footer_right_slot_template = (
|
|
294
|
-
/*#slots*/
|
|
295
|
-
ctx[44]["footer-right"]
|
|
296
|
-
);
|
|
297
|
-
const footer_right_slot = create_slot(
|
|
298
|
-
footer_right_slot_template,
|
|
299
|
-
ctx,
|
|
300
|
-
/*$$scope*/
|
|
301
|
-
ctx[43],
|
|
302
|
-
get_footer_right_slot_context
|
|
274
|
+
get_toolbar_slot_context
|
|
303
275
|
);
|
|
304
276
|
return {
|
|
305
277
|
c() {
|
|
306
|
-
|
|
307
|
-
if (
|
|
308
|
-
t0 = space();
|
|
309
|
-
if (footer_center_slot) footer_center_slot.c();
|
|
310
|
-
t1 = space();
|
|
311
|
-
if (footer_right_slot) footer_right_slot.c();
|
|
312
|
-
attr(div, "class", "aparte-composer-footer");
|
|
278
|
+
aparte_composer_toolbar = element("aparte-composer-toolbar");
|
|
279
|
+
if (toolbar_slot) toolbar_slot.c();
|
|
313
280
|
},
|
|
314
281
|
m(target, anchor) {
|
|
315
|
-
insert(target,
|
|
316
|
-
if (
|
|
317
|
-
|
|
318
|
-
}
|
|
319
|
-
append(div, t0);
|
|
320
|
-
if (footer_center_slot) {
|
|
321
|
-
footer_center_slot.m(div, null);
|
|
322
|
-
}
|
|
323
|
-
append(div, t1);
|
|
324
|
-
if (footer_right_slot) {
|
|
325
|
-
footer_right_slot.m(div, null);
|
|
282
|
+
insert(target, aparte_composer_toolbar, anchor);
|
|
283
|
+
if (toolbar_slot) {
|
|
284
|
+
toolbar_slot.m(aparte_composer_toolbar, null);
|
|
326
285
|
}
|
|
327
286
|
current = true;
|
|
328
287
|
},
|
|
329
288
|
p(ctx2, dirty) {
|
|
330
|
-
if (
|
|
331
|
-
if (
|
|
332
|
-
4096)) {
|
|
333
|
-
update_slot_base(
|
|
334
|
-
footer_left_slot,
|
|
335
|
-
footer_left_slot_template,
|
|
336
|
-
ctx2,
|
|
337
|
-
/*$$scope*/
|
|
338
|
-
ctx2[43],
|
|
339
|
-
!current ? get_all_dirty_from_scope(
|
|
340
|
-
/*$$scope*/
|
|
341
|
-
ctx2[43]
|
|
342
|
-
) : get_slot_changes(
|
|
343
|
-
footer_left_slot_template,
|
|
344
|
-
/*$$scope*/
|
|
345
|
-
ctx2[43],
|
|
346
|
-
dirty,
|
|
347
|
-
get_footer_left_slot_changes
|
|
348
|
-
),
|
|
349
|
-
get_footer_left_slot_context
|
|
350
|
-
);
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
if (footer_center_slot) {
|
|
354
|
-
if (footer_center_slot.p && (!current || dirty[1] & /*$$scope*/
|
|
289
|
+
if (toolbar_slot) {
|
|
290
|
+
if (toolbar_slot.p && (!current || dirty[1] & /*$$scope*/
|
|
355
291
|
4096)) {
|
|
356
292
|
update_slot_base(
|
|
357
|
-
|
|
358
|
-
|
|
293
|
+
toolbar_slot,
|
|
294
|
+
toolbar_slot_template,
|
|
359
295
|
ctx2,
|
|
360
296
|
/*$$scope*/
|
|
361
297
|
ctx2[43],
|
|
@@ -363,60 +299,31 @@ function create_if_block(ctx) {
|
|
|
363
299
|
/*$$scope*/
|
|
364
300
|
ctx2[43]
|
|
365
301
|
) : get_slot_changes(
|
|
366
|
-
|
|
302
|
+
toolbar_slot_template,
|
|
367
303
|
/*$$scope*/
|
|
368
304
|
ctx2[43],
|
|
369
305
|
dirty,
|
|
370
|
-
|
|
306
|
+
get_toolbar_slot_changes
|
|
371
307
|
),
|
|
372
|
-
|
|
373
|
-
);
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
if (footer_right_slot) {
|
|
377
|
-
if (footer_right_slot.p && (!current || dirty[1] & /*$$scope*/
|
|
378
|
-
4096)) {
|
|
379
|
-
update_slot_base(
|
|
380
|
-
footer_right_slot,
|
|
381
|
-
footer_right_slot_template,
|
|
382
|
-
ctx2,
|
|
383
|
-
/*$$scope*/
|
|
384
|
-
ctx2[43],
|
|
385
|
-
!current ? get_all_dirty_from_scope(
|
|
386
|
-
/*$$scope*/
|
|
387
|
-
ctx2[43]
|
|
388
|
-
) : get_slot_changes(
|
|
389
|
-
footer_right_slot_template,
|
|
390
|
-
/*$$scope*/
|
|
391
|
-
ctx2[43],
|
|
392
|
-
dirty,
|
|
393
|
-
get_footer_right_slot_changes
|
|
394
|
-
),
|
|
395
|
-
get_footer_right_slot_context
|
|
308
|
+
get_toolbar_slot_context
|
|
396
309
|
);
|
|
397
310
|
}
|
|
398
311
|
}
|
|
399
312
|
},
|
|
400
313
|
i(local) {
|
|
401
314
|
if (current) return;
|
|
402
|
-
transition_in(
|
|
403
|
-
transition_in(footer_center_slot, local);
|
|
404
|
-
transition_in(footer_right_slot, local);
|
|
315
|
+
transition_in(toolbar_slot, local);
|
|
405
316
|
current = true;
|
|
406
317
|
},
|
|
407
318
|
o(local) {
|
|
408
|
-
transition_out(
|
|
409
|
-
transition_out(footer_center_slot, local);
|
|
410
|
-
transition_out(footer_right_slot, local);
|
|
319
|
+
transition_out(toolbar_slot, local);
|
|
411
320
|
current = false;
|
|
412
321
|
},
|
|
413
322
|
d(detaching) {
|
|
414
323
|
if (detaching) {
|
|
415
|
-
detach(
|
|
324
|
+
detach(aparte_composer_toolbar);
|
|
416
325
|
}
|
|
417
|
-
if (
|
|
418
|
-
if (footer_center_slot) footer_center_slot.d(detaching);
|
|
419
|
-
if (footer_right_slot) footer_right_slot.d(detaching);
|
|
326
|
+
if (toolbar_slot) toolbar_slot.d(detaching);
|
|
420
327
|
}
|
|
421
328
|
};
|
|
422
329
|
}
|
|
@@ -440,9 +347,7 @@ function fallback_block(ctx) {
|
|
|
440
347
|
);
|
|
441
348
|
let if_block2 = (
|
|
442
349
|
/*$$slots*/
|
|
443
|
-
|
|
444
|
-
ctx[10]["footer-center"] || /*$$slots*/
|
|
445
|
-
ctx[10]["footer-right"]) && create_if_block(ctx)
|
|
350
|
+
ctx[10].toolbar && create_if_block(ctx)
|
|
446
351
|
);
|
|
447
352
|
return {
|
|
448
353
|
c() {
|
|
@@ -505,9 +410,7 @@ function fallback_block(ctx) {
|
|
|
505
410
|
}
|
|
506
411
|
if (
|
|
507
412
|
/*$$slots*/
|
|
508
|
-
ctx2[10]
|
|
509
|
-
ctx2[10]["footer-center"] || /*$$slots*/
|
|
510
|
-
ctx2[10]["footer-right"]
|
|
413
|
+
ctx2[10].toolbar
|
|
511
414
|
) {
|
|
512
415
|
if (if_block2) {
|
|
513
416
|
if_block2.p(ctx2, dirty);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/lib/AparteChat.svelte","../src/lib/stores/aparteChat.ts","../src/lib/stores/aparteClient.ts","../src/lib/stores/conversationManager.ts","../src/lib/AparteUi.svelte"],"sourcesContent":["<script lang=\"ts\">\n import { onMount, onDestroy, tick, createEventDispatcher } from 'svelte';\n import { AparteChatHost, isAwaitingReply, type AparteChatHostBinding, type AparteConfigClass, type AparteChatImperativeApi } from '@aparte/core';\n import type { AparteMessage, AparteSegment, AparteSendEventDetail, AparteActionEventDetail } from './types';\n\n export let messages: AparteMessage[] = [];\n export let placeholder = 'Type a message...';\n export let disabled = false;\n export let isTyping = false;\n export let typingText = 'Assistant is thinking...';\n /** When false, Shift+Enter submits and a bare Enter inserts a newline. */\n export let submitOnEnter = true;\n /** Freeze viewport spacer recalculation for this many ms after a conv swap. */\n export let layoutTransitionMs = 0;\n /**\n * Opt in to the \"centered composer when empty\" layout: the composer sits\n * vertically centered with the `empty-state` slot above it while the list is\n * empty, then slides to the bottom on the first message (~0.3s). Off by\n * default — additive.\n */\n export let centerWhenEmpty = false;\n /**\n * Add the file picker + chips strip to the default composer shell. **Off by\n * default**, because the capability needs a host that consumes the files: an\n * `AparteClient` inlines them per its `rawFileInject` option, but if you drive\n * your own loop you must read `event.files` on `messageSent` — otherwise the file\n * the user deliberately attached is dropped in silence. No effect when you fill\n * the `composer` slot (drop `<aparte-composer-add-attachment>` and\n * `<aparte-composer-attachments>` in it yourself).\n */\n export let attachments = false;\n /** Active conversation id (loads/persists via the registered ConversationManager). */\n export let conversationId: string | null = null;\n /**\n * Instance {@link AparteConfigClass} for this chat. When set, aparté components\n * inside resolve THIS config instead of the global `AparteConfig` singleton, so\n * several independently-configured chats can coexist on one page. Omit for the\n * global config. Read once when the host mounts.\n */\n export let config: AparteConfigClass | undefined = undefined;\n\n const dispatch = createEventDispatcher<{\n /**\n * User submitted a message from the composer. It is **appended to the\n * thread automatically** (optimistic UI) before this fires — do NOT add it\n * again (uncontrolled → duplicates; controlled → mirror into your own\n * `messages`). For side-effects: scroll, analytics, send.\n */\n messageSent: AparteSendEventDetail;\n /** A custom bubble action (registerBubbleAction) was clicked — typed aparte-action. */\n action: AparteActionEventDetail;\n /** Active path changed (branch nav/edit/retry/streaming) — bind back to `messages`. */\n messagesChange: AparteMessage[];\n messageAppended: AparteMessage;\n /** The typing/\"thinking\" indicator toggled (the host flips it off on the first streamed token). */\n typingChange: boolean;\n conversationCreated: string;\n }>();\n\n // Generated client-side in onMount (below): during SSR this stays empty so the\n // server and first client render agree on the id — no hydration mismatch.\n let hostId = '';\n\n let rootRef: HTMLElement;\n let viewportRef: HTMLElement;\n let composerRef: HTMLElement;\n let internalMessages: AparteMessage[] = [...messages];\n let typingActive = isTyping;\n let host: AparteChatHost | null = null;\n let teardown: (() => void) | null = null;\n\n // Parent push → internal list (guarded against the host's own emit round-trip).\n let lastProp = messages;\n $: if (messages !== lastProp) {\n lastProp = messages;\n internalMessages = [...messages];\n if (messages.length === 0) host?.clearRenderCache();\n }\n\n // Controlled typing indicator (host may flip it off on the first token).\n let lastTyping = isTyping;\n $: if (isTyping !== lastTyping) { lastTyping = isTyping; typingActive = isTyping; }\n\n // Conversation id changes (initial value loaded by the host on bind).\n let lastConv = conversationId;\n $: if (conversationId !== lastConv) {\n lastConv = conversationId;\n void host?.setConversationId(conversationId ?? null);\n }\n\n // Reconcile bubbles after the rendered list changes (host queries the DOM).\n $: if (host && internalMessages) { void tick().then(() => host?.syncBubbles()); }\n\n // Composer attributes set imperatively (like Angular's `[attr.x]`): Svelte's\n // custom-element binding assigns to *properties*, but aparte-composer exposes\n // some of these (e.g. `placeholder`) as getter-only — assigning throws.\n function toggleAttr(el: HTMLElement, name: string, on: boolean, value: string) {\n if (on) el.setAttribute(name, value); else el.removeAttribute(name);\n }\n $: if (composerRef) {\n composerRef.setAttribute('target', hostId);\n composerRef.setAttribute('placeholder', placeholder);\n toggleAttr(composerRef, 'disabled', disabled, '');\n toggleAttr(composerRef, 'submit-on-enter', !submitOnEnter, 'false');\n }\n\n function handleSend(event: Event) {\n (viewportRef as unknown as { requestSmoothScroll?: () => void })?.requestSmoothScroll?.();\n dispatch('messageSent', (event as CustomEvent<AparteSendEventDetail>).detail);\n }\n\n // Custom bubble actions bubble to the root as `aparte-action` — dispatch typed.\n function handleAction(event: Event) {\n dispatch('action', (event as CustomEvent<AparteActionEventDetail>).detail);\n }\n\n onMount(() => {\n hostId = `aparte-chat-${crypto.randomUUID()}`;\n // Set the id imperatively (deterministic, like Angular's ngAfterViewInit) rather\n // than waiting on a reactive re-render of `id={hostId}`; the composer target\n // reactive block below picks up the same hostId.\n if (rootRef) rootRef.id = hostId;\n const binding: AparteChatHostBinding = {\n hostId,\n host: rootRef,\n viewport: viewportRef,\n getMessages: () => internalMessages,\n setMessages: (m) => { internalMessages = m as AparteMessage[]; },\n onMessagesChange: (m) => dispatch('messagesChange', m as AparteMessage[]),\n onMessageAppended: (m) => dispatch('messageAppended', m as AparteMessage),\n onTypingChange: (t) => { typingActive = t; dispatch('typingChange', t); },\n onStreamingChange: () => { /* exposed via isStreaming() */ },\n afterRender: (cb) => { void tick().then(cb); },\n resetComposer: () => (composerRef as unknown as { reset?: () => void })?.reset?.(),\n };\n host = new AparteChatHost(binding, {\n layoutTransitionMs,\n conversationId: conversationId ?? null,\n onConversationCreated: (id) => dispatch('conversationCreated', id),\n config,\n });\n teardown = host.bind();\n host.syncBubbles();\n rootRef?.addEventListener('aparte-action', handleAction);\n });\n\n onDestroy(() => {\n rootRef?.removeEventListener('aparte-action', handleAction);\n teardown?.();\n teardown = null;\n host = null;\n });\n\n // ── Imperative API (bind:this on the component) ──\n export function appendMessage(m: AparteMessage) { host?.appendMessage(m); }\n export function updateMessage(id: string, u: Partial<AparteMessage>) { host?.updateMessage(id, u); }\n export function updateLastMessage(content: string, options?: { append?: boolean }) {\n host?.updateLastMessage(content, options);\n }\n export function addSegment(segment: AparteSegment) { host?.addSegment(segment); }\n export function updateSegment(segmentId: string, updates: Partial<AparteSegment>) {\n host?.updateSegment(segmentId, updates);\n }\n export function removeSegment(segmentId: string) { host?.removeSegment(segmentId); }\n export function appendToSegment(segmentId: string, content: string) {\n host?.appendToSegment(segmentId, content);\n }\n export function getMessages(): AparteMessage[] { return host?.getMessages() ?? internalMessages; }\n export function clearMessages() { host?.clearMessages(); }\n export function addBranch(messageId: string): number { return host?.addBranch(messageId) ?? 0; }\n export function addSiblingOf(existingId: string, message: AparteMessage): string | null {\n return host?.addSiblingOf(existingId, message) ?? null;\n }\n export function truncateFrom(messageId: string) { host?.truncateFrom(messageId); }\n export function truncateResponsesAfter(userMessageId: string) {\n host?.truncateResponsesAfter(userMessageId);\n }\n export function injectTokenStream(messageId: string, tokens: AsyncIterable<string>): Promise<void> {\n return host?.streamTokens(messageId, tokens) ?? Promise.resolve();\n }\n export function stopTokenStream() { host?.stopTokenStream(); }\n export function setConversationId(id: string | null): Promise<void> {\n return host?.setConversationId(id) ?? Promise.resolve();\n }\n export function scrollToBottom() {\n (viewportRef as unknown as { scrollToBottom?: () => void })?.scrollToBottom?.();\n }\n /**\n * The `<aparte-chat-viewport>` element — for custom scroll handling, an\n * IntersectionObserver, etc. Same `getViewport()` accessor on all four\n * wrappers.\n */\n export function getViewport(): HTMLElement | null { return viewportRef ?? null; }\n export function focusInput() {\n (composerRef as unknown as { focus?: () => void })?.focus?.();\n }\n export function isStreaming(): boolean { return host?.isStreaming ?? false; }\n\n // Compile-time parity check: Svelte 4 can't generic-annotate `export function`s,\n // so this never-called factory type-checks that the exported surface matches the\n // canonical AparteChatImperativeApi. A dropped/mistyped method is a build error.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n function _assertImperativeParity(): AparteChatImperativeApi {\n return {\n appendMessage, updateMessage, updateLastMessage, addSegment, updateSegment, removeSegment,\n appendToSegment, getMessages, clearMessages, addBranch, addSiblingOf, truncateFrom,\n truncateResponsesAfter, injectTokenStream, stopTokenStream, setConversationId,\n scrollToBottom, focusInput, isStreaming, getViewport,\n };\n }\n</script>\n\n<div\n class=\"aparte-chat-container\"\n class:aparte-chat-container--auto-center={centerWhenEmpty}\n data-aparte-chat\n data-aparte-empty={centerWhenEmpty && internalMessages.length === 0 ? '' : null}\n id={hostId}\n bind:this={rootRef}\n>\n <aparte-chat-viewport bind:this={viewportRef} framework-managed=\"\">\n <!-- Welcome / placeholder shown inside the viewport while empty. -->\n {#if internalMessages.length === 0}\n <slot name=\"empty-state\" />\n {/if}\n <!-- `bubble` slot renders your OWN element per message in place of\n <aparte-chat-bubble>; driven by the reactive list so it streams live. -->\n {#each internalMessages as m (m.id)}\n <slot name=\"bubble\" message={m}>\n <aparte-chat-bubble\n message-id={m.id}\n data-role={m.role}\n timestamp={m.timestamp}\n content={m.content}\n streaming={isAwaitingReply(m) ? '' : null}\n />\n </slot>\n {/each}\n <aparte-chat-status visible={typingActive ? '' : null} text={typingText} />\n </aparte-chat-viewport>\n\n <!-- Content above the composer (banner, disclaimer, context chip). -->\n <slot name=\"above-composer\" />\n\n <aparte-composer\n bind:this={composerRef}\n on:aparte-send={handleSend}\n >\n <!-- Custom composer via the `composer` slot; falls back to the default\n shell (input · send, plus the attachment primitives when `attachments` is\n set). Compose the headless aparte-composer-* primitives freely for a\n skin-specific layout. -->\n <slot name=\"composer\">\n <div class=\"aparte-composer-shell\">\n {#if attachments}<aparte-composer-attachments></aparte-composer-attachments>{/if}\n <div class=\"aparte-composer-row\">\n {#if attachments}<aparte-composer-add-attachment></aparte-composer-add-attachment>{/if}\n <aparte-composer-input></aparte-composer-input>\n <aparte-composer-send></aparte-composer-send>\n </div>\n <!-- Footer slots (model selector, token counter…). The row is\n removed from view by .aparte-composer-footer:empty when unused. -->\n {#if $$slots['footer-left'] || $$slots['footer-center'] || $$slots['footer-right']}\n <div class=\"aparte-composer-footer\">\n <slot name=\"footer-left\" />\n <slot name=\"footer-center\" />\n <slot name=\"footer-right\" />\n </div>\n {/if}\n </div>\n </slot>\n </aparte-composer>\n</div>\n","import { writable, type Writable } from 'svelte/store';\nimport type { AparteChatImperativeApi } from '@aparte/core';\nimport type { AparteMessage, AparteSegment } from '../types.js';\n\n/**\n * The imperative surface `<AparteChat>` exposes (its `export function`s) — the\n * canonical contract shared by all four wrappers (`AparteChatImperativeApi`).\n */\nexport type AparteChatInstance = AparteChatImperativeApi;\n\nexport interface AparteChatStore {\n /** Subscribe with `$messages` and bind to `<AparteChat messages={$messages}>`. */\n messages: Writable<AparteMessage[]>;\n /** Register the component instance via `bind:this`. */\n connect(component: AparteChatInstance | null): void;\n /** Wire to `on:messagesChange={(e) => chat.onMessagesChange(e.detail)}`. */\n onMessagesChange(messages: AparteMessage[]): void;\n appendMessage(message: AparteMessage): void;\n updateMessage(messageId: string, updates: Partial<AparteMessage>): void;\n updateLastMessage(content: string, options?: { append?: boolean }): void;\n addSegment(segment: AparteSegment): void;\n updateSegment(segmentId: string, updates: Partial<AparteSegment>): void;\n removeSegment(segmentId: string): void;\n appendToSegment(segmentId: string, content: string): void;\n clearMessages(): void;\n addBranch(messageId: string): number;\n addSiblingOf(existingId: string, message: AparteMessage): string | null;\n truncateFrom(messageId: string): void;\n truncateResponsesAfter(userMessageId: string): void;\n injectTokenStream(messageId: string, tokens: AsyncIterable<string>): Promise<void>;\n stopTokenStream(): void;\n setConversationId(id: string | null): Promise<void>;\n isStreaming(): boolean;\n}\n\n/**\n * Idiomatic Svelte ergonomics for `<AparteChat>`. Owns the `messages` store so the\n * consumer skips the manual `on:messagesChange` → `messages` round-trip.\n *\n * @example\n * const chat = createAparteChat();\n * const { messages } = chat;\n * let comp;\n * $: chat.connect(comp);\n * // <AparteChat bind:this={comp} messages={$messages}\n * // on:messagesChange={(e) => chat.onMessagesChange(e.detail)} />\n */\nexport function createAparteChat(initial: AparteMessage[] = []): AparteChatStore {\n const messages = writable<AparteMessage[]>([...initial]);\n let comp: AparteChatInstance | null = null;\n return {\n messages,\n connect: (component) => { comp = component; },\n onMessagesChange: (m) => messages.set(m),\n appendMessage: (m) => comp?.appendMessage(m),\n updateMessage: (id, u) => comp?.updateMessage(id, u),\n updateLastMessage: (c, o) => comp?.updateLastMessage(c, o),\n addSegment: (s) => comp?.addSegment(s),\n updateSegment: (id, u) => comp?.updateSegment(id, u),\n removeSegment: (id) => comp?.removeSegment(id),\n appendToSegment: (id, c) => comp?.appendToSegment(id, c),\n clearMessages: () => comp?.clearMessages(),\n addBranch: (id) => comp?.addBranch(id) ?? 0,\n addSiblingOf: (id, m) => comp?.addSiblingOf(id, m) ?? null,\n truncateFrom: (id) => comp?.truncateFrom(id),\n truncateResponsesAfter: (id) => comp?.truncateResponsesAfter(id),\n injectTokenStream: (id, tokens) => comp?.injectTokenStream(id, tokens) ?? Promise.resolve(),\n stopTokenStream: () => comp?.stopTokenStream(),\n setConversationId: (id) => comp?.setConversationId(id) ?? Promise.resolve(),\n isStreaming: () => comp?.isStreaming() ?? false,\n };\n}\n","import { onMount, onDestroy } from 'svelte';\nimport { AparteClient, type AparteClientOptions } from '@aparte/core';\n\n/**\n * Mounts an `AparteClient` that bridges `aparte-send` events to the configured AI\n * providers. Starts on mount, stops on destroy. Call from a component's script.\n * Svelte equivalent of Angular's `AparteAiService`.\n */\nexport function createAparteClient(options?: AparteClientOptions) {\n const client = new AparteClient(options ?? {});\n onMount(() => { client.start(); });\n onDestroy(() => client.stop());\n return { client, abort: () => client.abort() };\n}\n","import { writable, derived } from 'svelte/store';\nimport { onDestroy } from 'svelte';\nimport {\n AparteConfig,\n ConversationManager,\n type AparteConversation,\n type AparteStorageAdapter,\n} from '@aparte/core';\nimport type { AparteMessage } from '../types.js';\n\n/**\n * Svelte-store wrapper around the core `ConversationManager`. The active\n * conversation is owned by the chat component's controller; switch by binding\n * `conversationId` on `<AparteChat>`. Call from a component's script. Svelte\n * equivalent of Angular's `ConversationManagerService`.\n */\nexport function createConversationManager() {\n let manager: ConversationManager | null = null;\n let unsub: (() => void) | null = null;\n\n const conversations = writable<AparteConversation[]>([]);\n const activeId = writable<string | null>(null);\n const activeConversations = derived(conversations, ($c) =>\n $c.filter((c) => !c.archivedAt).sort((a, b) => b.updatedAt - a.updatedAt),\n );\n const archivedConversations = derived(conversations, ($c) =>\n $c.filter((c) => !!c.archivedAt).sort((a, b) => b.updatedAt - a.updatedAt),\n );\n const activeConversation = derived([conversations, activeId], ([$c, $id]) =>\n $id ? $c.find((c) => c.id === $id) ?? null : null,\n );\n\n onDestroy(() => unsub?.());\n\n const assert = (): ConversationManager => {\n if (!manager) throw new Error('[createConversationManager] Not initialised. Call init(adapter) first.');\n return manager;\n };\n\n async function init(adapter: AparteStorageAdapter): Promise<void> {\n const m = new ConversationManager(adapter);\n manager = m;\n unsub = m.subscribe((convs) => {\n conversations.set([...convs]);\n activeId.set(m.activeId);\n });\n await m.init();\n activeId.set(m.activeId);\n AparteConfig.setConversationManager(m);\n }\n\n return {\n conversations,\n activeConversations,\n archivedConversations,\n activeId,\n activeConversation,\n init,\n createNew: (title?: string) => assert().createNew(title),\n addMessage: (convId: string, message: AparteMessage) => assert().addMessage(convId, message),\n updateMessages: (convId: string, messages: AparteMessage[]) => assert().updateMessages(convId, messages),\n delete: (id: string) => assert().delete(id),\n archive: (id: string) => assert().archive(id),\n unarchive: (id: string) => assert().unarchive(id),\n };\n}\n","<script lang=\"ts\">\n import { onMount, onDestroy, createEventDispatcher } from 'svelte';\n import { applyElementProps, DEFAULT_UI_EVENTS } from '@aparte/core';\n\n /** The custom element tag name (e.g. 'aparte-model-selector'). */\n export let name: string;\n /** Props to apply. Keys starting with `--` become CSS variables. */\n export let props: Record<string, unknown> = {};\n /**\n * Which custom events to forward through `elementEvent`. Defaults to the\n * interactive aparté surface (DEFAULT_UI_EVENTS); pass your own list to listen to\n * other events (e.g. ['aparte-composer-change'] for attachments).\n */\n export let events: string[] | undefined = undefined;\n\n const dispatch = createEventDispatcher<{ elementEvent: CustomEvent }>();\n\n let host: HTMLElement;\n let el: HTMLElement | null = null;\n let cleanups: Array<() => void> = [];\n\n function applyProps() {\n if (el) applyElementProps(el, props);\n }\n\n function create() {\n if (!host) return;\n el = document.createElement(name);\n applyProps();\n for (const ev of events ?? DEFAULT_UI_EVENTS) {\n const listener = (e: Event) => dispatch('elementEvent', e as CustomEvent);\n el.addEventListener(ev, listener);\n cleanups.push(() => el?.removeEventListener(ev, listener));\n }\n host.appendChild(el);\n }\n\n function destroy() {\n for (const c of cleanups) c();\n cleanups = [];\n el?.remove();\n el = null;\n }\n\n onMount(create);\n onDestroy(destroy);\n\n // Recreate the element when `name` (or the forwarded event set) changes. A\n // joined key so a fresh inline `events` array doesn't thrash the element.\n let lastName = name;\n let lastEvtsKey = (events ?? DEFAULT_UI_EVENTS).join('|');\n $: {\n const evtsKey = (events ?? DEFAULT_UI_EVENTS).join('|');\n if (el && (name !== lastName || evtsKey !== lastEvtsKey)) {\n lastName = name;\n lastEvtsKey = evtsKey;\n destroy();\n create();\n }\n }\n $: if (el && props) applyProps();\n\n export function getElement() { return el; }\n export function callMethod(methodName: string, ...args: unknown[]) {\n const fn = (el as unknown as Record<string, unknown>)?.[methodName];\n return typeof fn === 'function' ? (fn as (...a: unknown[]) => unknown).apply(el, args) : undefined;\n }\n</script>\n\n<span bind:this={host} style=\"display: contents\"></span>\n"],"names":["ctx","init"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/lib/AparteChat.svelte","../src/lib/stores/aparteChat.ts","../src/lib/stores/aparteClient.ts","../src/lib/stores/conversationManager.ts","../src/lib/AparteUi.svelte"],"sourcesContent":["<script lang=\"ts\">\n import { onMount, onDestroy, tick, createEventDispatcher } from 'svelte';\n import { AparteChatHost, isAwaitingReply, type AparteChatHostBinding, type AparteConfigClass, type AparteChatImperativeApi } from '@aparte/core';\n import type { AparteMessage, AparteSegment, AparteSendEventDetail, AparteActionEventDetail } from './types';\n\n export let messages: AparteMessage[] = [];\n export let placeholder = 'Type a message...';\n export let disabled = false;\n export let isTyping = false;\n export let typingText = 'Assistant is thinking...';\n /** When false, Shift+Enter submits and a bare Enter inserts a newline. */\n export let submitOnEnter = true;\n /** Freeze viewport spacer recalculation for this many ms after a conv swap. */\n export let layoutTransitionMs = 0;\n /**\n * Opt in to the \"centered composer when empty\" layout: the composer sits\n * vertically centered with the `empty-state` slot above it while the list is\n * empty, then slides to the bottom on the first message (~0.3s). Off by\n * default — additive.\n */\n export let centerWhenEmpty = false;\n /**\n * Add the file picker + chips strip to the default composer shell. **Off by\n * default**, because the capability needs a host that consumes the files: an\n * `AparteClient` inlines them per its `rawFileInject` option, but if you drive\n * your own loop you must read `event.files` on `messageSent` — otherwise the file\n * the user deliberately attached is dropped in silence. No effect when you fill\n * the `composer` slot (drop `<aparte-composer-add-attachment>` and\n * `<aparte-composer-attachments>` in it yourself).\n */\n export let attachments = false;\n /** Active conversation id (loads/persists via the registered ConversationManager). */\n export let conversationId: string | null = null;\n /**\n * Instance {@link AparteConfigClass} for this chat. When set, aparté components\n * inside resolve THIS config instead of the global `AparteConfig` singleton, so\n * several independently-configured chats can coexist on one page. Omit for the\n * global config. Read once when the host mounts.\n */\n export let config: AparteConfigClass | undefined = undefined;\n\n const dispatch = createEventDispatcher<{\n /**\n * User submitted a message from the composer. It is **appended to the\n * thread automatically** (optimistic UI) before this fires — do NOT add it\n * again (uncontrolled → duplicates; controlled → mirror into your own\n * `messages`). For side-effects: scroll, analytics, send.\n */\n messageSent: AparteSendEventDetail;\n /** A custom bubble action (registerBubbleAction) was clicked — typed aparte-action. */\n action: AparteActionEventDetail;\n /** Active path changed (branch nav/edit/retry/streaming) — bind back to `messages`. */\n messagesChange: AparteMessage[];\n messageAppended: AparteMessage;\n /** The typing/\"thinking\" indicator toggled (the host flips it off on the first streamed token). */\n typingChange: boolean;\n conversationCreated: string;\n }>();\n\n // Generated client-side in onMount (below): during SSR this stays empty so the\n // server and first client render agree on the id — no hydration mismatch.\n let hostId = '';\n\n let rootRef: HTMLElement;\n let viewportRef: HTMLElement;\n let composerRef: HTMLElement;\n let internalMessages: AparteMessage[] = [...messages];\n let typingActive = isTyping;\n let host: AparteChatHost | null = null;\n let teardown: (() => void) | null = null;\n\n // Parent push → internal list (guarded against the host's own emit round-trip).\n let lastProp = messages;\n $: if (messages !== lastProp) {\n lastProp = messages;\n internalMessages = [...messages];\n if (messages.length === 0) host?.clearRenderCache();\n }\n\n // Controlled typing indicator (host may flip it off on the first token).\n let lastTyping = isTyping;\n $: if (isTyping !== lastTyping) { lastTyping = isTyping; typingActive = isTyping; }\n\n // Conversation id changes (initial value loaded by the host on bind).\n let lastConv = conversationId;\n $: if (conversationId !== lastConv) {\n lastConv = conversationId;\n void host?.setConversationId(conversationId ?? null);\n }\n\n // Reconcile bubbles after the rendered list changes (host queries the DOM).\n $: if (host && internalMessages) { void tick().then(() => host?.syncBubbles()); }\n\n // Composer attributes set imperatively (like Angular's `[attr.x]`): Svelte's\n // custom-element binding assigns to *properties*, but aparte-composer exposes\n // some of these (e.g. `placeholder`) as getter-only — assigning throws.\n function toggleAttr(el: HTMLElement, name: string, on: boolean, value: string) {\n if (on) el.setAttribute(name, value); else el.removeAttribute(name);\n }\n $: if (composerRef) {\n composerRef.setAttribute('target', hostId);\n composerRef.setAttribute('placeholder', placeholder);\n toggleAttr(composerRef, 'disabled', disabled, '');\n toggleAttr(composerRef, 'submit-on-enter', !submitOnEnter, 'false');\n }\n\n function handleSend(event: Event) {\n (viewportRef as unknown as { requestSmoothScroll?: () => void })?.requestSmoothScroll?.();\n dispatch('messageSent', (event as CustomEvent<AparteSendEventDetail>).detail);\n }\n\n // Custom bubble actions bubble to the root as `aparte-action` — dispatch typed.\n function handleAction(event: Event) {\n dispatch('action', (event as CustomEvent<AparteActionEventDetail>).detail);\n }\n\n onMount(() => {\n hostId = `aparte-chat-${crypto.randomUUID()}`;\n // Set the id imperatively (deterministic, like Angular's ngAfterViewInit) rather\n // than waiting on a reactive re-render of `id={hostId}`; the composer target\n // reactive block below picks up the same hostId.\n if (rootRef) rootRef.id = hostId;\n const binding: AparteChatHostBinding = {\n hostId,\n host: rootRef,\n viewport: viewportRef,\n getMessages: () => internalMessages,\n setMessages: (m) => { internalMessages = m as AparteMessage[]; },\n onMessagesChange: (m) => dispatch('messagesChange', m as AparteMessage[]),\n onMessageAppended: (m) => dispatch('messageAppended', m as AparteMessage),\n onTypingChange: (t) => { typingActive = t; dispatch('typingChange', t); },\n onStreamingChange: () => { /* exposed via isStreaming() */ },\n afterRender: (cb) => { void tick().then(cb); },\n resetComposer: () => (composerRef as unknown as { reset?: () => void })?.reset?.(),\n };\n host = new AparteChatHost(binding, {\n layoutTransitionMs,\n conversationId: conversationId ?? null,\n onConversationCreated: (id) => dispatch('conversationCreated', id),\n config,\n });\n teardown = host.bind();\n host.syncBubbles();\n rootRef?.addEventListener('aparte-action', handleAction);\n });\n\n onDestroy(() => {\n rootRef?.removeEventListener('aparte-action', handleAction);\n teardown?.();\n teardown = null;\n host = null;\n });\n\n // ── Imperative API (bind:this on the component) ──\n export function appendMessage(m: AparteMessage) { host?.appendMessage(m); }\n export function updateMessage(id: string, u: Partial<AparteMessage>) { host?.updateMessage(id, u); }\n export function updateLastMessage(content: string, options?: { append?: boolean }) {\n host?.updateLastMessage(content, options);\n }\n export function addSegment(segment: AparteSegment) { host?.addSegment(segment); }\n export function updateSegment(segmentId: string, updates: Partial<AparteSegment>) {\n host?.updateSegment(segmentId, updates);\n }\n export function removeSegment(segmentId: string) { host?.removeSegment(segmentId); }\n export function appendToSegment(segmentId: string, content: string) {\n host?.appendToSegment(segmentId, content);\n }\n export function getMessages(): AparteMessage[] { return host?.getMessages() ?? internalMessages; }\n export function clearMessages() { host?.clearMessages(); }\n export function addBranch(messageId: string): number { return host?.addBranch(messageId) ?? 0; }\n export function addSiblingOf(existingId: string, message: AparteMessage): string | null {\n return host?.addSiblingOf(existingId, message) ?? null;\n }\n export function truncateFrom(messageId: string) { host?.truncateFrom(messageId); }\n export function truncateResponsesAfter(userMessageId: string) {\n host?.truncateResponsesAfter(userMessageId);\n }\n export function injectTokenStream(messageId: string, tokens: AsyncIterable<string>): Promise<void> {\n return host?.streamTokens(messageId, tokens) ?? Promise.resolve();\n }\n export function stopTokenStream() { host?.stopTokenStream(); }\n export function setConversationId(id: string | null): Promise<void> {\n return host?.setConversationId(id) ?? Promise.resolve();\n }\n export function scrollToBottom() {\n (viewportRef as unknown as { scrollToBottom?: () => void })?.scrollToBottom?.();\n }\n /**\n * The `<aparte-chat-viewport>` element — for custom scroll handling, an\n * IntersectionObserver, etc. Same `getViewport()` accessor on all four\n * wrappers.\n */\n export function getViewport(): HTMLElement | null { return viewportRef ?? null; }\n export function focusInput() {\n (composerRef as unknown as { focus?: () => void })?.focus?.();\n }\n export function isStreaming(): boolean { return host?.isStreaming ?? false; }\n\n // Compile-time parity check: Svelte 4 can't generic-annotate `export function`s,\n // so this never-called factory type-checks that the exported surface matches the\n // canonical AparteChatImperativeApi. A dropped/mistyped method is a build error.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n function _assertImperativeParity(): AparteChatImperativeApi {\n return {\n appendMessage, updateMessage, updateLastMessage, addSegment, updateSegment, removeSegment,\n appendToSegment, getMessages, clearMessages, addBranch, addSiblingOf, truncateFrom,\n truncateResponsesAfter, injectTokenStream, stopTokenStream, setConversationId,\n scrollToBottom, focusInput, isStreaming, getViewport,\n };\n }\n</script>\n\n<div\n class=\"aparte-chat-container\"\n class:aparte-chat-container--auto-center={centerWhenEmpty}\n data-aparte-chat\n data-aparte-empty={centerWhenEmpty && internalMessages.length === 0 ? '' : null}\n id={hostId}\n bind:this={rootRef}\n>\n <aparte-chat-viewport bind:this={viewportRef} framework-managed=\"\">\n <!-- Welcome / placeholder shown inside the viewport while empty. -->\n {#if internalMessages.length === 0}\n <slot name=\"empty-state\" />\n {/if}\n <!-- `bubble` slot renders your OWN element per message in place of\n <aparte-chat-bubble>; driven by the reactive list so it streams live. -->\n {#each internalMessages as m (m.id)}\n <slot name=\"bubble\" message={m}>\n <aparte-chat-bubble\n message-id={m.id}\n data-role={m.role}\n timestamp={m.timestamp}\n content={m.content}\n streaming={isAwaitingReply(m) ? '' : null}\n />\n </slot>\n {/each}\n <aparte-chat-status visible={typingActive ? '' : null} text={typingText} />\n </aparte-chat-viewport>\n\n <!-- Content above the composer (banner, disclaimer, context chip). -->\n <slot name=\"above-composer\" />\n\n <aparte-composer\n bind:this={composerRef}\n on:aparte-send={handleSend}\n >\n <!-- Custom composer via the `composer` slot; falls back to the default\n shell (input · send, plus the attachment primitives when `attachments` is\n set). Compose the headless aparte-composer-* primitives freely for a\n skin-specific layout. -->\n <slot name=\"composer\">\n <div class=\"aparte-composer-shell\">\n {#if attachments}<aparte-composer-attachments></aparte-composer-attachments>{/if}\n <div class=\"aparte-composer-row\">\n {#if attachments}<aparte-composer-add-attachment></aparte-composer-add-attachment>{/if}\n <aparte-composer-input></aparte-composer-input>\n <aparte-composer-send></aparte-composer-send>\n </div>\n <!-- The composer's bottom row. ONE slot: placement is the DOM order, and\n `margin-inline-start: auto` pushes a control to the end (a logical\n property, so it reads correctly in RTL). Nothing is rendered at all when\n the slot is unused. -->\n {#if $$slots.toolbar}\n <aparte-composer-toolbar>\n <slot name=\"toolbar\" />\n </aparte-composer-toolbar>\n {/if}\n </div>\n </slot>\n </aparte-composer>\n</div>\n","import { writable, type Writable } from 'svelte/store';\nimport type { AparteChatImperativeApi } from '@aparte/core';\nimport type { AparteMessage, AparteSegment } from '../types.js';\n\n/**\n * The imperative surface `<AparteChat>` exposes (its `export function`s) — the\n * canonical contract shared by all four wrappers (`AparteChatImperativeApi`).\n */\nexport type AparteChatInstance = AparteChatImperativeApi;\n\nexport interface AparteChatStore {\n /** Subscribe with `$messages` and bind to `<AparteChat messages={$messages}>`. */\n messages: Writable<AparteMessage[]>;\n /** Register the component instance via `bind:this`. */\n connect(component: AparteChatInstance | null): void;\n /** Wire to `on:messagesChange={(e) => chat.onMessagesChange(e.detail)}`. */\n onMessagesChange(messages: AparteMessage[]): void;\n appendMessage(message: AparteMessage): void;\n updateMessage(messageId: string, updates: Partial<AparteMessage>): void;\n updateLastMessage(content: string, options?: { append?: boolean }): void;\n addSegment(segment: AparteSegment): void;\n updateSegment(segmentId: string, updates: Partial<AparteSegment>): void;\n removeSegment(segmentId: string): void;\n appendToSegment(segmentId: string, content: string): void;\n clearMessages(): void;\n addBranch(messageId: string): number;\n addSiblingOf(existingId: string, message: AparteMessage): string | null;\n truncateFrom(messageId: string): void;\n truncateResponsesAfter(userMessageId: string): void;\n injectTokenStream(messageId: string, tokens: AsyncIterable<string>): Promise<void>;\n stopTokenStream(): void;\n setConversationId(id: string | null): Promise<void>;\n isStreaming(): boolean;\n}\n\n/**\n * Idiomatic Svelte ergonomics for `<AparteChat>`. Owns the `messages` store so the\n * consumer skips the manual `on:messagesChange` → `messages` round-trip.\n *\n * @example\n * const chat = createAparteChat();\n * const { messages } = chat;\n * let comp;\n * $: chat.connect(comp);\n * // <AparteChat bind:this={comp} messages={$messages}\n * // on:messagesChange={(e) => chat.onMessagesChange(e.detail)} />\n */\nexport function createAparteChat(initial: AparteMessage[] = []): AparteChatStore {\n const messages = writable<AparteMessage[]>([...initial]);\n let comp: AparteChatInstance | null = null;\n return {\n messages,\n connect: (component) => { comp = component; },\n onMessagesChange: (m) => messages.set(m),\n appendMessage: (m) => comp?.appendMessage(m),\n updateMessage: (id, u) => comp?.updateMessage(id, u),\n updateLastMessage: (c, o) => comp?.updateLastMessage(c, o),\n addSegment: (s) => comp?.addSegment(s),\n updateSegment: (id, u) => comp?.updateSegment(id, u),\n removeSegment: (id) => comp?.removeSegment(id),\n appendToSegment: (id, c) => comp?.appendToSegment(id, c),\n clearMessages: () => comp?.clearMessages(),\n addBranch: (id) => comp?.addBranch(id) ?? 0,\n addSiblingOf: (id, m) => comp?.addSiblingOf(id, m) ?? null,\n truncateFrom: (id) => comp?.truncateFrom(id),\n truncateResponsesAfter: (id) => comp?.truncateResponsesAfter(id),\n injectTokenStream: (id, tokens) => comp?.injectTokenStream(id, tokens) ?? Promise.resolve(),\n stopTokenStream: () => comp?.stopTokenStream(),\n setConversationId: (id) => comp?.setConversationId(id) ?? Promise.resolve(),\n isStreaming: () => comp?.isStreaming() ?? false,\n };\n}\n","import { onMount, onDestroy } from 'svelte';\nimport { AparteClient, type AparteClientOptions } from '@aparte/core';\n\n/**\n * Mounts an `AparteClient` that bridges `aparte-send` events to the configured AI\n * providers. Starts on mount, stops on destroy. Call from a component's script.\n * Svelte equivalent of Angular's `AparteAiService`.\n */\nexport function createAparteClient(options?: AparteClientOptions) {\n const client = new AparteClient(options ?? {});\n onMount(() => { client.start(); });\n onDestroy(() => client.stop());\n return { client, abort: () => client.abort() };\n}\n","import { writable, derived } from 'svelte/store';\nimport { onDestroy } from 'svelte';\nimport {\n AparteConfig,\n ConversationManager,\n type AparteConversation,\n type AparteStorageAdapter,\n} from '@aparte/core';\nimport type { AparteMessage } from '../types.js';\n\n/**\n * Svelte-store wrapper around the core `ConversationManager`. The active\n * conversation is owned by the chat component's controller; switch by binding\n * `conversationId` on `<AparteChat>`. Call from a component's script. Svelte\n * equivalent of Angular's `ConversationManagerService`.\n */\nexport function createConversationManager() {\n let manager: ConversationManager | null = null;\n let unsub: (() => void) | null = null;\n\n const conversations = writable<AparteConversation[]>([]);\n const activeId = writable<string | null>(null);\n const activeConversations = derived(conversations, ($c) =>\n $c.filter((c) => !c.archivedAt).sort((a, b) => b.updatedAt - a.updatedAt),\n );\n const archivedConversations = derived(conversations, ($c) =>\n $c.filter((c) => !!c.archivedAt).sort((a, b) => b.updatedAt - a.updatedAt),\n );\n const activeConversation = derived([conversations, activeId], ([$c, $id]) =>\n $id ? $c.find((c) => c.id === $id) ?? null : null,\n );\n\n onDestroy(() => unsub?.());\n\n const assert = (): ConversationManager => {\n if (!manager) throw new Error('[createConversationManager] Not initialised. Call init(adapter) first.');\n return manager;\n };\n\n async function init(adapter: AparteStorageAdapter): Promise<void> {\n const m = new ConversationManager(adapter);\n manager = m;\n unsub = m.subscribe((convs) => {\n conversations.set([...convs]);\n activeId.set(m.activeId);\n });\n await m.init();\n activeId.set(m.activeId);\n AparteConfig.setConversationManager(m);\n }\n\n return {\n conversations,\n activeConversations,\n archivedConversations,\n activeId,\n activeConversation,\n init,\n createNew: (title?: string) => assert().createNew(title),\n addMessage: (convId: string, message: AparteMessage) => assert().addMessage(convId, message),\n updateMessages: (convId: string, messages: AparteMessage[]) => assert().updateMessages(convId, messages),\n delete: (id: string) => assert().delete(id),\n archive: (id: string) => assert().archive(id),\n unarchive: (id: string) => assert().unarchive(id),\n };\n}\n","<script lang=\"ts\">\n import { onMount, onDestroy, createEventDispatcher } from 'svelte';\n import { applyElementProps, DEFAULT_UI_EVENTS } from '@aparte/core';\n\n /** The custom element tag name (e.g. 'aparte-model-selector'). */\n export let name: string;\n /** Props to apply. Keys starting with `--` become CSS variables. */\n export let props: Record<string, unknown> = {};\n /**\n * Which custom events to forward through `elementEvent`. Defaults to the\n * interactive aparté surface (DEFAULT_UI_EVENTS); pass your own list to listen to\n * other events (e.g. ['aparte-composer-change'] for attachments).\n */\n export let events: string[] | undefined = undefined;\n\n const dispatch = createEventDispatcher<{ elementEvent: CustomEvent }>();\n\n let host: HTMLElement;\n let el: HTMLElement | null = null;\n let cleanups: Array<() => void> = [];\n\n function applyProps() {\n if (el) applyElementProps(el, props);\n }\n\n function create() {\n if (!host) return;\n el = document.createElement(name);\n applyProps();\n for (const ev of events ?? DEFAULT_UI_EVENTS) {\n const listener = (e: Event) => dispatch('elementEvent', e as CustomEvent);\n el.addEventListener(ev, listener);\n cleanups.push(() => el?.removeEventListener(ev, listener));\n }\n host.appendChild(el);\n }\n\n function destroy() {\n for (const c of cleanups) c();\n cleanups = [];\n el?.remove();\n el = null;\n }\n\n onMount(create);\n onDestroy(destroy);\n\n // Recreate the element when `name` (or the forwarded event set) changes. A\n // joined key so a fresh inline `events` array doesn't thrash the element.\n let lastName = name;\n let lastEvtsKey = (events ?? DEFAULT_UI_EVENTS).join('|');\n $: {\n const evtsKey = (events ?? DEFAULT_UI_EVENTS).join('|');\n if (el && (name !== lastName || evtsKey !== lastEvtsKey)) {\n lastName = name;\n lastEvtsKey = evtsKey;\n destroy();\n create();\n }\n }\n $: if (el && props) applyProps();\n\n export function getElement() { return el; }\n export function callMethod(methodName: string, ...args: unknown[]) {\n const fn = (el as unknown as Record<string, unknown>)?.[methodName];\n return typeof fn === 'function' ? (fn as (...a: unknown[]) => unknown).apply(el, args) : undefined;\n }\n</script>\n\n<span bind:this={host} style=\"display: contents\"></span>\n"],"names":["ctx","init"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aparte/svelte",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "Svelte 4 wrapper for aparté — an ergonomic <AparteChat> component plus stores over the framework-agnostic web components.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"svelte-check": "^3.8.0",
|
|
36
36
|
"typescript": "^5.4.0",
|
|
37
37
|
"vite": "^6.0.0",
|
|
38
|
-
"@aparte/core": "0.
|
|
38
|
+
"@aparte/core": "0.7.1"
|
|
39
39
|
},
|
|
40
40
|
"keywords": [
|
|
41
41
|
"svelte",
|