@aparte/vue 0.16.11 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/AparteChat.vue.d.ts +23 -3
- package/dist/components/AparteChat.vue.d.ts.map +1 -1
- package/dist/composables/useAparteChat.d.ts +8 -1
- package/dist/composables/useAparteChat.d.ts.map +1 -1
- package/dist/index.js +60 -30
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +4 -6
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -26,6 +26,13 @@ interface Props {
|
|
|
26
26
|
* attribute the shipped `aparte.css` recipe keys off).
|
|
27
27
|
*/
|
|
28
28
|
centerWhenEmpty?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* The conversation is on its way: the viewport draws two skeleton turns, the empty
|
|
31
|
+
* state stays off and the composer is disabled until it lands. The conversation
|
|
32
|
+
* controller sets this itself while it fetches through your adapter's `loadFull()`;
|
|
33
|
+
* the prop is for a wait of your own. Off by default.
|
|
34
|
+
*/
|
|
35
|
+
loading?: boolean;
|
|
29
36
|
/** Overlay the composer on the transcript: full-column scroll surface, edge-to-edge scrollbar, floating composer. Read when the viewport mounts. */
|
|
30
37
|
overlayComposer?: boolean;
|
|
31
38
|
/**
|
|
@@ -73,6 +80,7 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
73
80
|
structuredResult?: unknown;
|
|
74
81
|
id: string;
|
|
75
82
|
isStreaming?: boolean | undefined;
|
|
83
|
+
fallback?: string | undefined;
|
|
76
84
|
messageId?: string | undefined;
|
|
77
85
|
index?: number | undefined;
|
|
78
86
|
meta?: {
|
|
@@ -87,6 +95,7 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
87
95
|
content: string;
|
|
88
96
|
id: string;
|
|
89
97
|
isStreaming?: boolean | undefined;
|
|
98
|
+
fallback?: string | undefined;
|
|
90
99
|
messageId?: string | undefined;
|
|
91
100
|
index?: number | undefined;
|
|
92
101
|
meta?: {
|
|
@@ -103,6 +112,7 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
103
112
|
label?: string | undefined;
|
|
104
113
|
id: string;
|
|
105
114
|
isStreaming?: boolean | undefined;
|
|
115
|
+
fallback?: string | undefined;
|
|
106
116
|
messageId?: string | undefined;
|
|
107
117
|
index?: number | undefined;
|
|
108
118
|
meta?: {
|
|
@@ -120,6 +130,7 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
120
130
|
showLineNumbers?: boolean | undefined;
|
|
121
131
|
id: string;
|
|
122
132
|
isStreaming?: boolean | undefined;
|
|
133
|
+
fallback?: string | undefined;
|
|
123
134
|
messageId?: string | undefined;
|
|
124
135
|
index?: number | undefined;
|
|
125
136
|
meta?: {
|
|
@@ -136,6 +147,7 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
136
147
|
stack?: string | undefined;
|
|
137
148
|
id: string;
|
|
138
149
|
isStreaming?: boolean | undefined;
|
|
150
|
+
fallback?: string | undefined;
|
|
139
151
|
messageId?: string | undefined;
|
|
140
152
|
index?: number | undefined;
|
|
141
153
|
meta?: {
|
|
@@ -149,9 +161,9 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
149
161
|
type: "custom";
|
|
150
162
|
subType: string;
|
|
151
163
|
data?: unknown;
|
|
152
|
-
fallback?: string | undefined;
|
|
153
164
|
id: string;
|
|
154
165
|
isStreaming?: boolean | undefined;
|
|
166
|
+
fallback?: string | undefined;
|
|
155
167
|
messageId?: string | undefined;
|
|
156
168
|
index?: number | undefined;
|
|
157
169
|
meta?: {
|
|
@@ -213,6 +225,7 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
213
225
|
structuredResult?: unknown;
|
|
214
226
|
id: string;
|
|
215
227
|
isStreaming?: boolean | undefined;
|
|
228
|
+
fallback?: string | undefined;
|
|
216
229
|
messageId?: string | undefined;
|
|
217
230
|
index?: number | undefined;
|
|
218
231
|
meta?: {
|
|
@@ -227,6 +240,7 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
227
240
|
content: string;
|
|
228
241
|
id: string;
|
|
229
242
|
isStreaming?: boolean | undefined;
|
|
243
|
+
fallback?: string | undefined;
|
|
230
244
|
messageId?: string | undefined;
|
|
231
245
|
index?: number | undefined;
|
|
232
246
|
meta?: {
|
|
@@ -243,6 +257,7 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
243
257
|
label?: string | undefined;
|
|
244
258
|
id: string;
|
|
245
259
|
isStreaming?: boolean | undefined;
|
|
260
|
+
fallback?: string | undefined;
|
|
246
261
|
messageId?: string | undefined;
|
|
247
262
|
index?: number | undefined;
|
|
248
263
|
meta?: {
|
|
@@ -260,6 +275,7 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
260
275
|
showLineNumbers?: boolean | undefined;
|
|
261
276
|
id: string;
|
|
262
277
|
isStreaming?: boolean | undefined;
|
|
278
|
+
fallback?: string | undefined;
|
|
263
279
|
messageId?: string | undefined;
|
|
264
280
|
index?: number | undefined;
|
|
265
281
|
meta?: {
|
|
@@ -276,6 +292,7 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
276
292
|
stack?: string | undefined;
|
|
277
293
|
id: string;
|
|
278
294
|
isStreaming?: boolean | undefined;
|
|
295
|
+
fallback?: string | undefined;
|
|
279
296
|
messageId?: string | undefined;
|
|
280
297
|
index?: number | undefined;
|
|
281
298
|
meta?: {
|
|
@@ -289,9 +306,9 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
289
306
|
type: "custom";
|
|
290
307
|
subType: string;
|
|
291
308
|
data?: unknown;
|
|
292
|
-
fallback?: string | undefined;
|
|
293
309
|
id: string;
|
|
294
310
|
isStreaming?: boolean | undefined;
|
|
311
|
+
fallback?: string | undefined;
|
|
295
312
|
messageId?: string | undefined;
|
|
296
313
|
index?: number | undefined;
|
|
297
314
|
meta?: {
|
|
@@ -333,7 +350,9 @@ declare const __VLS_component: import("vue").DefineComponent<Props, {
|
|
|
333
350
|
removeSegment: (id: string) => void | undefined;
|
|
334
351
|
appendToSegment: (id: string, c: string) => void | undefined;
|
|
335
352
|
getMessages: () => AparteMessage[];
|
|
336
|
-
clearMessages: (
|
|
353
|
+
clearMessages: (options?: {
|
|
354
|
+
revokeAttachments?: boolean;
|
|
355
|
+
}) => void | undefined;
|
|
337
356
|
addBranch: (id: string) => number;
|
|
338
357
|
addSiblingOf: (id: string, m: AparteMessage) => string | null;
|
|
339
358
|
truncateFrom: (id: string) => void | undefined;
|
|
@@ -362,6 +381,7 @@ declare const __VLS_component: import("vue").DefineComponent<Props, {
|
|
|
362
381
|
onTypingChange?: ((isTyping: boolean) => any) | undefined;
|
|
363
382
|
onConversationCreated?: ((id: string) => any) | undefined;
|
|
364
383
|
}>, {
|
|
384
|
+
loading: boolean;
|
|
365
385
|
attachments: boolean;
|
|
366
386
|
messages: AparteMessage[];
|
|
367
387
|
disabled: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AparteChat.vue.d.ts","sourceRoot":"","sources":["../../src/components/AparteChat.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AparteChat.vue.d.ts","sourceRoot":"","sources":["../../src/components/AparteChat.vue"],"names":[],"mappings":"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"}
|
|
@@ -81,7 +81,10 @@ export declare function useAparteChat(initial?: AparteMessage[]): {
|
|
|
81
81
|
updateSegment: (id: string, u: Partial<AparteSegment>) => void | undefined;
|
|
82
82
|
removeSegment: (id: string) => void | undefined;
|
|
83
83
|
appendToSegment: (id: string, content: string) => void | undefined;
|
|
84
|
-
|
|
84
|
+
getMessages: () => AparteMessage[];
|
|
85
|
+
clearMessages: (options?: {
|
|
86
|
+
revokeAttachments?: boolean;
|
|
87
|
+
}) => void | undefined;
|
|
85
88
|
addBranch: (id: string) => number;
|
|
86
89
|
addSiblingOf: (id: string, m: AparteMessage) => string | null;
|
|
87
90
|
truncateFrom: (id: string) => void | undefined;
|
|
@@ -90,5 +93,9 @@ export declare function useAparteChat(initial?: AparteMessage[]): {
|
|
|
90
93
|
stopTokenStream: () => void | undefined;
|
|
91
94
|
setConversationId: (id: string | null) => Promise<void>;
|
|
92
95
|
isStreaming: () => boolean;
|
|
96
|
+
scrollToBottom: () => void | undefined;
|
|
97
|
+
focusInput: () => void | undefined;
|
|
98
|
+
/** The `<aparte-chat-viewport>` element — same accessor on all four wrappers. */
|
|
99
|
+
getViewport: () => HTMLElement | null;
|
|
93
100
|
};
|
|
94
101
|
//# sourceMappingURL=useAparteChat.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAparteChat.d.ts","sourceRoot":"","sources":["../../src/composables/useAparteChat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,GAAG,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEhE;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,aAAa,EAAO;;;uDAanC,CAAC;sBAAc,CAAC;;;oDAEJ,CAAC;kBAAU,CAAC;;;;;;;+
|
|
1
|
+
{"version":3,"file":"useAparteChat.d.ts","sourceRoot":"","sources":["../../src/composables/useAparteChat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,GAAG,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEhE;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,aAAa,EAAO;;;uDAanC,CAAC;sBAAc,CAAC;;;oDAEJ,CAAC;kBAAU,CAAC;;;;;;;+BAcJ,CAAC;6BACnC,CAAC;;;;;;;;;;;;;;uDAjBa,CAAC;sBAAc,CAAC;;;oDAEJ,CAAC;kBAAU,CAAC;;;;;;;+BAcJ,CAAC;6BACnC,CAAC;;;;;;;;;;;;;;0BA1BsB,aAAa,EAAE;uBAMrB,aAAa,MAAM;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE;wBAC1C,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC;iCACxB,MAAM,MAAM;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE;oBAC7C,aAAa;wBACT,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC;wBACjC,MAAM;0BACJ,MAAM,WAAW,MAAM;uBAG5B,aAAa,EAAE;8BACN;QAAE,iBAAiB,CAAC,EAAE,OAAO,CAAA;KAAE;oBACzC,MAAM;uBACH,MAAM,KAAK,aAAa;uBACxB,MAAM;iCACI,MAAM;4BACX,MAAM,UAAU,aAAa,CAAC,MAAM,CAAC;;4BAGrC,MAAM,GAAG,IAAI;;;;IAIrC,iFAAiF;uBAChE,WAAW,GAAG,IAAI;EAE1C"}
|
package/dist/index.js
CHANGED
|
@@ -1,15 +1,26 @@
|
|
|
1
|
-
import { defineComponent, useId, ref, onMounted, toRaw, onBeforeUnmount, watch, nextTick, openBlock, createElementBlock, unref, normalizeClass, createElementVNode,
|
|
2
|
-
import { AparteChatHost, isAwaitingReply, AparteClient,
|
|
1
|
+
import { defineComponent, useId, ref, computed, onMounted, toRaw, onBeforeUnmount, watch, nextTick, openBlock, createElementBlock, unref, normalizeClass, createElementVNode, createStaticVNode, createCommentVNode, toDisplayString, renderSlot, Fragment, renderList } from "vue";
|
|
2
|
+
import { aparteGlobalConfig, AparteChatHost, isAwaitingReply, AparteClient, AparteConversationManager, APARTE_DEFAULT_UI_EVENTS, applyElementProps } from "@aparte/core";
|
|
3
3
|
const _hoisted_1 = ["overlay-composer", "data-aparte-empty", "id"];
|
|
4
|
-
const _hoisted_2 = ["
|
|
5
|
-
const _hoisted_3 =
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
const _hoisted_2 = ["loading"];
|
|
5
|
+
const _hoisted_3 = {
|
|
6
|
+
key: 0,
|
|
7
|
+
class: "aparte-viewport-loading",
|
|
8
|
+
"aria-hidden": "true"
|
|
9
|
+
};
|
|
10
|
+
const _hoisted_4 = {
|
|
11
|
+
key: 1,
|
|
12
|
+
class: "aparte-viewport-loading-status aparte-sr-only",
|
|
13
|
+
role: "status"
|
|
14
|
+
};
|
|
15
|
+
const _hoisted_5 = ["message-id", "data-role", "data-kind", "timestamp", "content", "streaming"];
|
|
16
|
+
const _hoisted_6 = ["visible", "text"];
|
|
9
17
|
const _hoisted_7 = { key: 0 };
|
|
10
|
-
const _hoisted_8 =
|
|
11
|
-
const _hoisted_9 = {
|
|
12
|
-
const _hoisted_10 = { key:
|
|
18
|
+
const _hoisted_8 = ["target", "^placeholder", "^disabled", "submit-on-enter"];
|
|
19
|
+
const _hoisted_9 = { class: "aparte-composer-shell" };
|
|
20
|
+
const _hoisted_10 = { key: 0 };
|
|
21
|
+
const _hoisted_11 = { class: "aparte-composer-row" };
|
|
22
|
+
const _hoisted_12 = { key: 0 };
|
|
23
|
+
const _hoisted_13 = { key: 1 };
|
|
13
24
|
const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
14
25
|
__name: "AparteChat",
|
|
15
26
|
props: {
|
|
@@ -22,6 +33,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
22
33
|
submitOnEnter: { type: Boolean, default: true },
|
|
23
34
|
layoutTransitionMs: { default: 0 },
|
|
24
35
|
centerWhenEmpty: { type: Boolean, default: false },
|
|
36
|
+
loading: { type: Boolean, default: false },
|
|
25
37
|
overlayComposer: { type: Boolean, default: false },
|
|
26
38
|
attachments: { type: Boolean, default: false },
|
|
27
39
|
elicitation: { type: Boolean, default: true },
|
|
@@ -47,6 +59,9 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
47
59
|
function onAction(e) {
|
|
48
60
|
emit("action", e.detail);
|
|
49
61
|
}
|
|
62
|
+
const hostLoading = ref(false);
|
|
63
|
+
const waiting = computed(() => props.loading || hostLoading.value);
|
|
64
|
+
const loadingText = computed(() => (props.config ?? aparteGlobalConfig).t("loadingConversation"));
|
|
50
65
|
onMounted(() => {
|
|
51
66
|
const binding = {
|
|
52
67
|
hostId,
|
|
@@ -70,7 +85,10 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
70
85
|
afterRender: (cb) => {
|
|
71
86
|
void nextTick(cb);
|
|
72
87
|
},
|
|
73
|
-
resetComposer: () => composerRef.value?.reset?.()
|
|
88
|
+
resetComposer: () => composerRef.value?.reset?.(),
|
|
89
|
+
onLoadingChange: (on) => {
|
|
90
|
+
hostLoading.value = on;
|
|
91
|
+
}
|
|
74
92
|
};
|
|
75
93
|
host = new AparteChatHost(binding, {
|
|
76
94
|
layoutTransitionMs: props.layoutTransitionMs,
|
|
@@ -115,7 +133,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
115
133
|
const removeSegment = (id) => host?.removeSegment(id);
|
|
116
134
|
const appendToSegment = (id, c) => host?.appendToSegment(id, c);
|
|
117
135
|
const getMessages = () => host?.getMessages() ?? internalMessages.value;
|
|
118
|
-
const clearMessages = () => host?.clearMessages();
|
|
136
|
+
const clearMessages = (options) => host?.clearMessages(options);
|
|
119
137
|
const addBranch = (id) => host?.addBranch(id) ?? 0;
|
|
120
138
|
const addSiblingOf = (id, m) => host?.addSiblingOf(id, m) ?? null;
|
|
121
139
|
const truncateFrom = (id) => host?.truncateFrom(id);
|
|
@@ -154,7 +172,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
154
172
|
class: normalizeClass(["aparte-chat-container", { "aparte-chat-container--auto-center": __props.centerWhenEmpty }]),
|
|
155
173
|
"data-aparte-chat": "",
|
|
156
174
|
"overlay-composer": __props.overlayComposer ? "" : null,
|
|
157
|
-
"data-aparte-empty": __props.centerWhenEmpty && internalMessages.value.length === 0 ? "" : null,
|
|
175
|
+
"data-aparte-empty": __props.centerWhenEmpty && internalMessages.value.length === 0 && !waiting.value ? "" : null,
|
|
158
176
|
id: unref(hostId),
|
|
159
177
|
ref_key: "rootRef",
|
|
160
178
|
ref: rootRef
|
|
@@ -162,9 +180,14 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
162
180
|
createElementVNode("aparte-chat-viewport", {
|
|
163
181
|
ref_key: "viewportRef",
|
|
164
182
|
ref: viewportRef,
|
|
165
|
-
"framework-managed": ""
|
|
183
|
+
"framework-managed": "",
|
|
184
|
+
loading: waiting.value ? "" : null
|
|
166
185
|
}, [
|
|
167
|
-
|
|
186
|
+
waiting.value ? (openBlock(), createElementBlock("div", _hoisted_3, [..._cache[0] || (_cache[0] = [
|
|
187
|
+
createStaticVNode('<span class="aparte-skeleton aparte-skeleton--rect aparte-viewport-loading__user"></span><span class="aparte-skeleton aparte-skeleton--text"></span><span class="aparte-skeleton aparte-skeleton--text"></span><span class="aparte-skeleton aparte-skeleton--text"></span><span class="aparte-skeleton aparte-skeleton--text aparte-viewport-loading__last"></span>', 5)
|
|
188
|
+
])])) : createCommentVNode("", true),
|
|
189
|
+
waiting.value ? (openBlock(), createElementBlock("span", _hoisted_4, toDisplayString(loadingText.value), 1)) : createCommentVNode("", true),
|
|
190
|
+
internalMessages.value.length === 0 && !waiting.value ? renderSlot(_ctx.$slots, "empty-state", { key: 2 }) : createCommentVNode("", true),
|
|
168
191
|
(openBlock(true), createElementBlock(Fragment, null, renderList(internalMessages.value, (m) => {
|
|
169
192
|
return renderSlot(_ctx.$slots, "bubble", {
|
|
170
193
|
key: m.id,
|
|
@@ -177,38 +200,38 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
177
200
|
timestamp: m.timestamp,
|
|
178
201
|
content: m.content,
|
|
179
202
|
streaming: unref(isAwaitingReply)(m) ? "" : null
|
|
180
|
-
}, null, 8,
|
|
203
|
+
}, null, 8, _hoisted_5)
|
|
181
204
|
]);
|
|
182
205
|
}), 128)),
|
|
183
206
|
createElementVNode("aparte-chat-status", {
|
|
184
207
|
visible: typingActive.value ? "" : null,
|
|
185
208
|
text: __props.typingText
|
|
186
|
-
}, null, 8,
|
|
187
|
-
],
|
|
188
|
-
__props.elicitation ? (openBlock(), createElementBlock("aparte-elicitation",
|
|
209
|
+
}, null, 8, _hoisted_6)
|
|
210
|
+
], 8, _hoisted_2),
|
|
211
|
+
__props.elicitation ? (openBlock(), createElementBlock("aparte-elicitation", _hoisted_7)) : createCommentVNode("", true),
|
|
189
212
|
renderSlot(_ctx.$slots, "above-composer"),
|
|
190
213
|
createElementVNode("aparte-composer", {
|
|
191
214
|
ref_key: "composerRef",
|
|
192
215
|
ref: composerRef,
|
|
193
216
|
target: unref(hostId),
|
|
194
217
|
"^placeholder": __props.placeholder,
|
|
195
|
-
"^disabled": __props.disabled ? "" : null,
|
|
218
|
+
"^disabled": __props.disabled || waiting.value ? "" : null,
|
|
196
219
|
"submit-on-enter": __props.submitOnEnter ? null : "false"
|
|
197
220
|
}, [
|
|
198
221
|
renderSlot(_ctx.$slots, "composer", {}, () => [
|
|
199
|
-
createElementVNode("div",
|
|
200
|
-
__props.attachments ? (openBlock(), createElementBlock("aparte-composer-attachments",
|
|
201
|
-
createElementVNode("div",
|
|
202
|
-
__props.attachments ? (openBlock(), createElementBlock("aparte-composer-add-attachment",
|
|
203
|
-
_cache[
|
|
204
|
-
_cache[
|
|
222
|
+
createElementVNode("div", _hoisted_9, [
|
|
223
|
+
__props.attachments ? (openBlock(), createElementBlock("aparte-composer-attachments", _hoisted_10)) : createCommentVNode("", true),
|
|
224
|
+
createElementVNode("div", _hoisted_11, [
|
|
225
|
+
__props.attachments ? (openBlock(), createElementBlock("aparte-composer-add-attachment", _hoisted_12)) : createCommentVNode("", true),
|
|
226
|
+
_cache[1] || (_cache[1] = createElementVNode("aparte-composer-input", null, null, -1)),
|
|
227
|
+
_cache[2] || (_cache[2] = createElementVNode("aparte-composer-send", null, null, -1))
|
|
205
228
|
]),
|
|
206
|
-
_ctx.$slots.toolbar ? (openBlock(), createElementBlock("aparte-composer-toolbar",
|
|
229
|
+
_ctx.$slots.toolbar ? (openBlock(), createElementBlock("aparte-composer-toolbar", _hoisted_13, [
|
|
207
230
|
renderSlot(_ctx.$slots, "toolbar")
|
|
208
231
|
])) : createCommentVNode("", true)
|
|
209
232
|
])
|
|
210
233
|
])
|
|
211
|
-
], 8,
|
|
234
|
+
], 8, _hoisted_8)
|
|
212
235
|
], 10, _hoisted_1);
|
|
213
236
|
};
|
|
214
237
|
}
|
|
@@ -231,7 +254,10 @@ function useAparteChat(initial = []) {
|
|
|
231
254
|
updateSegment: (id, u) => c()?.updateSegment(id, u),
|
|
232
255
|
removeSegment: (id) => c()?.removeSegment(id),
|
|
233
256
|
appendToSegment: (id, content) => c()?.appendToSegment(id, content),
|
|
234
|
-
|
|
257
|
+
// The host's list — the authority, and mid-stream a frame ahead of the
|
|
258
|
+
// `messages` ref, which is synced once per paint rather than per token.
|
|
259
|
+
getMessages: () => c()?.getMessages() ?? messages.value,
|
|
260
|
+
clearMessages: (options) => c()?.clearMessages(options),
|
|
235
261
|
addBranch: (id) => c()?.addBranch(id) ?? 0,
|
|
236
262
|
addSiblingOf: (id, m) => c()?.addSiblingOf(id, m) ?? null,
|
|
237
263
|
truncateFrom: (id) => c()?.truncateFrom(id),
|
|
@@ -239,7 +265,11 @@ function useAparteChat(initial = []) {
|
|
|
239
265
|
injectTokenStream: (id, tokens) => c()?.injectTokenStream(id, tokens) ?? Promise.resolve(),
|
|
240
266
|
stopTokenStream: () => c()?.stopTokenStream(),
|
|
241
267
|
setConversationId: (id) => c()?.setConversationId(id) ?? Promise.resolve(),
|
|
242
|
-
isStreaming: () => c()?.isStreaming() ?? false
|
|
268
|
+
isStreaming: () => c()?.isStreaming() ?? false,
|
|
269
|
+
scrollToBottom: () => c()?.scrollToBottom(),
|
|
270
|
+
focusInput: () => c()?.focusInput(),
|
|
271
|
+
/** The `<aparte-chat-viewport>` element — same accessor on all four wrappers. */
|
|
272
|
+
getViewport: () => c()?.getViewport() ?? null
|
|
243
273
|
};
|
|
244
274
|
}
|
|
245
275
|
function useAparteClient(options) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/components/AparteChat.vue","../src/composables/useAparteChat.ts","../src/composables/useAparteClient.ts","../src/composables/useConversationManager.ts","../src/components/AparteUi.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, watch, onMounted, onBeforeUnmount, nextTick, useId, toRaw } from 'vue';\nimport { AparteChatHost, isAwaitingReply, type AparteChatHostBinding, type AparteConfig, type AparteChatImperativeApi } from '@aparte/core';\nimport type { AparteMessage, AparteSegment, AparteSendEventDetail, AparteActionEventDetail } from '../types.js';\n\ninterface Props {\n /**\n * The host element's `id`, and therefore the `targetId` every event this chat\n * dispatches carries. Generated when omitted — but it used to be generated and\n * neither accepted nor exposed, which made `AparteClientOptions.scopeToTargetId`\n * unreachable from this component.\n */\n id?: string;\n /** Optional: omit for an uncontrolled chat (defaults to []); use `v-model:messages` to control. */\n messages?: AparteMessage[];\n placeholder?: string;\n disabled?: boolean;\n isTyping?: boolean;\n typingText?: string;\n /** When false, Shift+Enter submits and a bare Enter inserts a newline. */\n submitOnEnter?: boolean;\n /** Freeze viewport spacer recalculation for this many ms after a conv swap. */\n layoutTransitionMs?: number;\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 (adds the `--auto-center` modifier + a `data-aparte-empty`\n * attribute the shipped `aparte.css` recipe keys off).\n */\n centerWhenEmpty?: boolean;\n /** Overlay the composer on the transcript: full-column scroll surface, edge-to-edge scrollbar, floating composer. Read when the viewport mounts. */\n overlayComposer?: boolean;\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 attachments?: boolean;\n /**\n * Render the `<aparte-elicitation>` presenter inside the host — **on by default**,\n * as it is in `<aparte-chat>`: the built-in approval gate and `requestUserInput()`\n * ask through it, and it renders nothing until something asks. Pass `false` when\n * you mount a presenter of your own (`setElicitationPresenter`) or place the\n * element yourself.\n */\n elicitation?: boolean;\n /** Active conversation id (loads/persists via the registered AparteConversationManager). */\n conversationId?: string | null;\n /**\n * Instance {@link AparteConfig} for this chat. When set, aparté components\n * inside resolve THIS config instead of `aparteGlobalConfig`, 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 config?: AparteConfig;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n messages: () => [],\n placeholder: 'Type a message...',\n disabled: false,\n isTyping: false,\n typingText: 'Assistant is thinking...',\n submitOnEnter: true,\n layoutTransitionMs: 0,\n centerWhenEmpty: false,\n overlayComposer: false,\n attachments: false,\n elicitation: true,\n conversationId: null,\n});\n\nconst emit = defineEmits<{\n /**\n * User submitted a message from the composer. The message is **appended to\n * the thread automatically** (optimistic UI) before this fires — do NOT add\n * it again in the handler (uncontrolled → duplicates; controlled → mirror it\n * into your own `messages`). For side-effects: scroll, analytics, send.\n */\n messageSent: [event: AparteSendEventDetail];\n /** A custom bubble action (registerBubbleAction) was clicked — typed aparte-action. */\n action: [detail: AparteActionEventDetail];\n /** Active path changed (branch nav/edit/retry/streaming) — bind back to `messages`. */\n messagesChange: [messages: AparteMessage[]];\n /** Same payload as `messagesChange`, enabling `v-model:messages`. */\n 'update:messages': [messages: AparteMessage[]];\n messageAppended: [message: AparteMessage];\n /** The typing/\"thinking\" indicator toggled (the host flips it off on the first streamed token). */\n typingChange: [isTyping: boolean];\n conversationCreated: [id: string];\n}>();\n\n// useId() (Vue 3.5+) is SSR-stable — server and client agree, no hydration mismatch.\n// A caller-supplied `id` wins, so `scopeToTargetId` has something to match; the\n// generated one stays SSR-stable for the common case.\nconst hostId = props.id ?? `aparte-chat-${useId()}`;\nconst rootRef = ref<HTMLElement>();\nconst viewportRef = ref<HTMLElement>();\nconst composerRef = ref<HTMLElement>();\nconst internalMessages = ref<AparteMessage[]>([...props.messages]);\nconst typingActive = ref(props.isTyping);\n\nlet host: AparteChatHost | null = null;\nlet teardown: (() => void) | null = null;\n\nfunction onSend(e: Event) {\n (viewportRef.value as unknown as { requestSmoothScroll?: () => void })?.requestSmoothScroll?.();\n emit('messageSent', (e as CustomEvent<AparteSendEventDetail>).detail);\n}\n\n// Custom bubble actions bubble to the root as `aparte-action` — surface them typed.\nfunction onAction(e: Event) {\n emit('action', (e as CustomEvent<AparteActionEventDetail>).detail);\n}\n\nonMounted(() => {\n const binding: AparteChatHostBinding = {\n hostId,\n host: rootRef.value as HTMLElement,\n viewport: viewportRef.value ?? null,\n getMessages: () => internalMessages.value,\n setMessages: (m) => { internalMessages.value = m as AparteMessage[]; },\n onMessagesChange: (m) => { emit('messagesChange', m as AparteMessage[]); emit('update:messages', m as AparteMessage[]); },\n onMessageAppended: (m) => emit('messageAppended', m as AparteMessage),\n onTypingChange: (t) => { typingActive.value = t; emit('typingChange', t); },\n onStreamingChange: () => { /* exposed via isStreaming() */ },\n afterRender: (cb) => { void nextTick(cb); },\n resetComposer: () => (composerRef.value as unknown as { reset?: () => void })?.reset?.(),\n };\n host = new AparteChatHost(binding, {\n layoutTransitionMs: props.layoutTransitionMs,\n conversationId: props.conversationId ?? null,\n onConversationCreated: (id) => emit('conversationCreated', id),\n // Unwrap Vue's reactive proxy: the config is a plain class with internal\n // Map registries the host/components must operate on directly, not through a\n // deep reactive proxy (which would wrap those Maps and break lookups).\n config: props.config ? toRaw(props.config) : undefined,\n });\n teardown = host.bind();\n host.syncBubbles();\n composerRef.value?.addEventListener('aparte-send', onSend);\n rootRef.value?.addEventListener('aparte-action', onAction);\n});\n\nonBeforeUnmount(() => {\n composerRef.value?.removeEventListener('aparte-send', onSend);\n rootRef.value?.removeEventListener('aparte-action', onAction);\n teardown?.();\n teardown = null;\n host = null;\n});\n\n// Parent push → internal list (guarded against the host's own emit round-trip).\nwatch(() => props.messages, (m) => {\n if (m === internalMessages.value) return;\n internalMessages.value = [...m];\n if (m.length === 0) host?.clearRenderCache();\n});\n\n// Reconcile bubbles after the rendered list changes (host queries the DOM).\nwatch(internalMessages, () => { void nextTick(() => host?.syncBubbles()); });\n\nwatch(() => props.isTyping, (t) => { typingActive.value = t; });\nwatch(() => props.conversationId, (id) => { void host?.setConversationId(id ?? null); });\n\n// ── Imperative API (forwards to the host) ──\nconst appendMessage = (m: AparteMessage, o?: { historical?: boolean }) => host?.appendMessage(m, o);\nconst updateMessage = (id: string, u: Partial<AparteMessage>) => host?.updateMessage(id, u);\nconst updateLastMessage = (c: string, o?: { append?: boolean }) => host?.updateLastMessage(c, o);\nconst addSegment = (s: AparteSegment) => host?.addSegment(s);\nconst updateSegment = (id: string, u: Partial<AparteSegment>) => host?.updateSegment(id, u);\nconst removeSegment = (id: string) => host?.removeSegment(id);\nconst appendToSegment = (id: string, c: string) => host?.appendToSegment(id, c);\nconst getMessages = () => host?.getMessages() ?? internalMessages.value;\nconst clearMessages = () => host?.clearMessages();\nconst addBranch = (id: string) => host?.addBranch(id) ?? 0;\nconst addSiblingOf = (id: string, m: AparteMessage) => host?.addSiblingOf(id, m) ?? null;\nconst truncateFrom = (id: string) => host?.truncateFrom(id);\nconst truncateResponsesAfter = (id: string) => host?.truncateResponsesAfter(id);\nconst injectTokenStream = (id: string, tokens: AsyncIterable<string>) =>\n host?.streamTokens(id, tokens) ?? Promise.resolve();\nconst stopTokenStream = () => host?.stopTokenStream();\nconst setConversationId = (id: string | null) => host?.setConversationId(id) ?? Promise.resolve();\nconst scrollToBottom = () => (viewportRef.value as unknown as { scrollToBottom?: () => void })?.scrollToBottom?.();\nconst focusInput = () => (composerRef.value as unknown as { focus?: () => void })?.focus?.();\nconst isStreaming = () => host?.isStreaming ?? false;\n\n// `getViewport()` (not a raw `viewport` ref): the same accessor on all four\n// wrappers — Svelte 4 can only expose functions, so the shared name is one.\nconst getViewport = () => viewportRef.value ?? null;\n\n// `satisfies` makes a dropped or mistyped method a compile error — the canonical\n// AparteChatImperativeApi is enforced here, not just aliased for consumers.\ndefineExpose({\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} satisfies AparteChatImperativeApi);\n</script>\n\n<template>\n <div\n :class=\"['aparte-chat-container', { 'aparte-chat-container--auto-center': centerWhenEmpty }]\"\n data-aparte-chat\n :overlay-composer=\"overlayComposer ? '' : null\"\n :data-aparte-empty=\"centerWhenEmpty && internalMessages.length === 0 ? '' : null\"\n :id=\"hostId\"\n ref=\"rootRef\"\n >\n <aparte-chat-viewport ref=\"viewportRef\" framework-managed=\"\">\n <!-- Welcome / placeholder shown inside the viewport while there are no\n messages (a real empty-state region). -->\n <slot v-if=\"internalMessages.length === 0\" name=\"empty-state\" />\n <!-- `bubble` scoped slot renders your OWN element per message in place of\n <aparte-chat-bubble>; driven by the reactive list so it streams live. -->\n <template v-for=\"m in internalMessages\" :key=\"m.id\">\n <slot name=\"bubble\" :message=\"m\">\n <aparte-chat-bubble\n :message-id=\"m.id\"\n :data-role=\"m.role\"\n :data-kind=\"m.compaction ? 'compaction' : undefined\"\n :timestamp=\"m.timestamp\"\n :content=\"m.content\"\n :streaming=\"isAwaitingReply(m) ? '' : null\"\n />\n </slot>\n </template>\n <aparte-chat-status :visible=\"typingActive ? '' : null\" :text=\"typingText\" />\n </aparte-chat-viewport>\n\n <!-- The presenter for a request to the human (approval gate, ask_user…). Renders\n nothing until something asks; on by default as in <aparte-chat>. -->\n <aparte-elicitation v-if=\"elicitation\"></aparte-elicitation>\n\n <!-- Content above the composer (banner, disclaimer, context chip). -->\n <slot name=\"above-composer\" />\n\n <!-- `.attr` forces attribute-setting: core's <aparte-composer> exposes\n `placeholder`/`disabled` as getter-only accessors, so Vue's default\n property-set (it prefers props on custom elements) would throw and the\n value would silently never apply. -->\n <aparte-composer\n ref=\"composerRef\"\n :target=\"hostId\"\n :placeholder.attr=\"placeholder\"\n :disabled.attr=\"disabled ? '' : null\"\n :submit-on-enter=\"submitOnEnter ? null : 'false'\"\n >\n <!-- Custom composer via the `composer` slot; falls back to the default\n shell (input · send, plus the attachment primitives when `attachments`\n is 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 <aparte-composer-attachments v-if=\"attachments\"></aparte-composer-attachments>\n <div class=\"aparte-composer-row\">\n <aparte-composer-add-attachment v-if=\"attachments\"></aparte-composer-add-attachment>\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 <aparte-composer-toolbar v-if=\"$slots.toolbar\">\n <slot name=\"toolbar\" />\n </aparte-composer-toolbar>\n </div>\n </slot>\n </aparte-composer>\n </div>\n</template>\n","import { ref, type Ref } from 'vue';\nimport type { AparteChatImperativeApi } from '@aparte/core';\nimport type { AparteMessage, AparteSegment } from '../types.js';\n\n/**\n * Idiomatic Vue ergonomics for `<AparteChat>`. Owns the `messages` ref and a\n * component template ref so the consumer skips the manual\n * `@messages-change` → `messages` round-trip.\n *\n * @example\n * const chat = useAparteChat();\n * // template:\n * // <AparteChat :ref=\"chat.chatRef\" :messages=\"chat.messages.value\"\n * // @messages-change=\"chat.onMessagesChange\" />\n */\nexport function useAparteChat(initial: AparteMessage[] = []) {\n const messages = ref<AparteMessage[]>([...initial]) as Ref<AparteMessage[]>;\n const chatRef = ref<AparteChatImperativeApi | null>(null);\n const c = () => chatRef.value;\n const onMessagesChange = (m: AparteMessage[]) => { messages.value = m; };\n\n return {\n messages,\n chatRef,\n onMessagesChange,\n appendMessage: (m: AparteMessage, o?: { historical?: boolean }) => c()?.appendMessage(m, o),\n updateMessage: (id: string, u: Partial<AparteMessage>) => c()?.updateMessage(id, u),\n updateLastMessage: (content: string, o?: { append?: boolean }) => c()?.updateLastMessage(content, o),\n addSegment: (s: AparteSegment) => c()?.addSegment(s),\n updateSegment: (id: string, u: Partial<AparteSegment>) => c()?.updateSegment(id, u),\n removeSegment: (id: string) => c()?.removeSegment(id),\n appendToSegment: (id: string, content: string) => c()?.appendToSegment(id, content),\n clearMessages: () => c()?.clearMessages(),\n addBranch: (id: string) => c()?.addBranch(id) ?? 0,\n addSiblingOf: (id: string, m: AparteMessage) => c()?.addSiblingOf(id, m) ?? null,\n truncateFrom: (id: string) => c()?.truncateFrom(id),\n truncateResponsesAfter: (id: string) => c()?.truncateResponsesAfter(id),\n injectTokenStream: (id: string, tokens: AsyncIterable<string>) =>\n c()?.injectTokenStream(id, tokens) ?? Promise.resolve(),\n stopTokenStream: () => c()?.stopTokenStream(),\n setConversationId: (id: string | null) => c()?.setConversationId(id) ?? Promise.resolve(),\n isStreaming: () => c()?.isStreaming() ?? false,\n };\n}\n","import { onMounted, onBeforeUnmount } from 'vue';\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 unmount. Vue equivalent of Angular's\n * `AparteAiService`.\n */\nexport function useAparteClient(options?: AparteClientOptions) {\n const client = new AparteClient(options ?? {});\n onMounted(() => client.start());\n onBeforeUnmount(() => client.stop());\n return { client, abort: () => client.abort() };\n}\n","import { ref, computed, onBeforeUnmount, type Ref } from 'vue';\nimport {\n aparteGlobalConfig,\n type AparteConfig,\n AparteConversationManager,\n type AparteConversation,\n type AparteStorageAdapter,\n} from '@aparte/core';\nimport type { AparteMessage } from '../types.js';\n\n/**\n * Vue-reactive wrapper around the core `AparteConversationManager`. The active\n * conversation is owned by the chat component's controller; switch by binding\n * `conversationId` on `<AparteChat>`. Vue equivalent of Angular's\n * `ConversationManagerService`.\n */\nexport function useConversationManager() {\n let manager: AparteConversationManager | null = null;\n let unsub: (() => void) | null = null;\n\n const conversations = ref<AparteConversation[]>([]) as Ref<AparteConversation[]>;\n const activeId = ref<string | null>(null);\n\n const activeConversations = computed(() =>\n conversations.value.filter((c) => !c.archivedAt).sort((a, b) => b.updatedAt - a.updatedAt),\n );\n const archivedConversations = computed(() =>\n conversations.value.filter((c) => !!c.archivedAt).sort((a, b) => b.updatedAt - a.updatedAt),\n );\n const activeConversation = computed(() =>\n activeId.value ? conversations.value.find((c) => c.id === activeId.value) ?? null : null,\n );\n\n onBeforeUnmount(() => unsub?.());\n\n const assert = (): AparteConversationManager => {\n if (!manager) throw new Error('[useConversationManager] Not initialised. Call init(adapter) first.');\n return manager;\n };\n\n /**\n * Initialise with a storage adapter.\n *\n * `config` defaults to the global singleton. Pass the SAME config you gave\n * `<AparteChat config={…}>`: the controller resolves the config governing its\n * host element, so a manager registered on the global is invisible to a chat\n * with its own — persistence silently does nothing while the optimistic UI\n * keeps working.\n */\n const init = async (adapter: AparteStorageAdapter, config: AparteConfig = aparteGlobalConfig): Promise<void> => {\n const m = new AparteConversationManager(adapter);\n manager = m;\n unsub = m.subscribe((convs) => {\n conversations.value = [...convs];\n activeId.value = m.activeId;\n });\n await m.init();\n activeId.value = m.activeId;\n config.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 pin: (id: string) => assert().pin(id),\n unpin: (id: string) => assert().unpin(id),\n updateTitle: (id: string, title: string) => assert().updateTitle(id, title),\n };\n}\n","<script setup lang=\"ts\">\nimport { ref, computed, watch, onMounted, onBeforeUnmount, toRaw } from 'vue';\nimport { applyElementProps, APARTE_DEFAULT_UI_EVENTS } from '@aparte/core';\nimport type { AparteUiHandle } from '../types.js';\n\nconst p = defineProps<{\n /** The custom element tag name (e.g. 'aparte-model-selector'). */\n name: string;\n /** Props to apply. Keys starting with `--` become CSS variables. */\n props?: Record<string, unknown>;\n /**\n * Which custom events to forward through `elementEvent`. Defaults to the\n * interactive aparté surface (APARTE_DEFAULT_UI_EVENTS); pass your own list to listen to\n * other events (e.g. ['aparte-composer-change'] for attachments).\n */\n events?: string[];\n}>();\n\nconst emit = defineEmits<{ elementEvent: [event: CustomEvent] }>();\n\n// A stable key so a fresh inline `:events` array doesn't thrash the element —\n// only a real change to the event names rebinds (mirrors React's evtsKey).\nconst evtsKey = computed(() => (p.events ?? APARTE_DEFAULT_UI_EVENTS).join('|'));\n\nconst hostRef = ref<HTMLElement>();\nlet el: HTMLElement | null = null;\nlet cleanups: Array<() => void> = [];\n\n// Vue passes `toRaw` so objects are unwrapped from the reactive proxy before\n// reaching the plain custom element (a deep proxy breaks Maps/class internals).\nfunction applyProps() {\n if (el) applyElementProps(el, p.props ?? {}, toRaw);\n}\n\nfunction create() {\n if (!hostRef.value) return;\n el = document.createElement(p.name);\n applyProps();\n for (const ev of evtsKey.value.split('|').filter(Boolean)) {\n const listener = (e: Event) => emit('elementEvent', e as CustomEvent);\n el.addEventListener(ev, listener);\n cleanups.push(() => el?.removeEventListener(ev, listener));\n }\n hostRef.value.appendChild(el);\n}\n\nfunction destroy() {\n for (const c of cleanups) c();\n cleanups = [];\n el?.remove();\n el = null;\n}\n\nonMounted(create);\nonBeforeUnmount(destroy);\nwatch(() => p.name, () => { destroy(); create(); });\nwatch(evtsKey, () => { destroy(); create(); });\nwatch(() => p.props, applyProps, { deep: true });\n\n/*\n * Typed as `AparteUiHandle`, the way React's `useImperativeHandle` already is.\n *\n * It used to be a bare object literal, so the exposed `getElement` returned\n * `HTMLElement | null` instead of the interface's `<T extends HTMLElement>() => T | null`\n * — and the barrel exports that interface with a docblock promising \"the same contract on\n * all four wrappers\". A consumer following the documented `ref` pattern got a type error\n * on Vue and Svelte and none on React or Angular. Found by a cold audit that compiled it\n * rather than read it.\n *\n * `as never` is the same bridge React uses at AparteUi.tsx:85: the value really is the\n * element, and only the caller knows which subtype it asked for.\n */\ndefineExpose<AparteUiHandle>({\n getElement: () => el as never,\n 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) as never;\n },\n});\n</script>\n\n<template>\n <span ref=\"hostRef\" style=\"display: contents\"></span>\n</template>\n"],"names":["_createElementBlock","_unref","_createElementVNode","_renderSlot","_Fragment","_renderList","$slots"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/components/AparteChat.vue","../src/composables/useAparteChat.ts","../src/composables/useAparteClient.ts","../src/composables/useConversationManager.ts","../src/components/AparteUi.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed, watch, onMounted, onBeforeUnmount, nextTick, useId, toRaw } from 'vue';\nimport { AparteChatHost, aparteGlobalConfig, isAwaitingReply, type AparteChatHostBinding, type AparteConfig, type AparteChatImperativeApi } from '@aparte/core';\nimport type { AparteMessage, AparteSegment, AparteSendEventDetail, AparteActionEventDetail } from '../types.js';\n\ninterface Props {\n /**\n * The host element's `id`, and therefore the `targetId` every event this chat\n * dispatches carries. Generated when omitted — but it used to be generated and\n * neither accepted nor exposed, which made `AparteClientOptions.scopeToTargetId`\n * unreachable from this component.\n */\n id?: string;\n /** Optional: omit for an uncontrolled chat (defaults to []); use `v-model:messages` to control. */\n messages?: AparteMessage[];\n placeholder?: string;\n disabled?: boolean;\n isTyping?: boolean;\n typingText?: string;\n /** When false, Shift+Enter submits and a bare Enter inserts a newline. */\n submitOnEnter?: boolean;\n /** Freeze viewport spacer recalculation for this many ms after a conv swap. */\n layoutTransitionMs?: number;\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 (adds the `--auto-center` modifier + a `data-aparte-empty`\n * attribute the shipped `aparte.css` recipe keys off).\n */\n centerWhenEmpty?: boolean;\n /**\n * The conversation is on its way: the viewport draws two skeleton turns, the empty\n * state stays off and the composer is disabled until it lands. The conversation\n * controller sets this itself while it fetches through your adapter's `loadFull()`;\n * the prop is for a wait of your own. Off by default.\n */\n loading?: boolean;\n /** Overlay the composer on the transcript: full-column scroll surface, edge-to-edge scrollbar, floating composer. Read when the viewport mounts. */\n overlayComposer?: boolean;\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 attachments?: boolean;\n /**\n * Render the `<aparte-elicitation>` presenter inside the host — **on by default**,\n * as it is in `<aparte-chat>`: the built-in approval gate and `requestUserInput()`\n * ask through it, and it renders nothing until something asks. Pass `false` when\n * you mount a presenter of your own (`setElicitationPresenter`) or place the\n * element yourself.\n */\n elicitation?: boolean;\n /** Active conversation id (loads/persists via the registered AparteConversationManager). */\n conversationId?: string | null;\n /**\n * Instance {@link AparteConfig} for this chat. When set, aparté components\n * inside resolve THIS config instead of `aparteGlobalConfig`, 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 config?: AparteConfig;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n messages: () => [],\n placeholder: 'Type a message...',\n disabled: false,\n isTyping: false,\n typingText: 'Assistant is thinking...',\n submitOnEnter: true,\n layoutTransitionMs: 0,\n centerWhenEmpty: false,\n loading: false,\n overlayComposer: false,\n attachments: false,\n elicitation: true,\n conversationId: null,\n});\n\nconst emit = defineEmits<{\n /**\n * User submitted a message from the composer. The message is **appended to\n * the thread automatically** (optimistic UI) before this fires — do NOT add\n * it again in the handler (uncontrolled → duplicates; controlled → mirror it\n * into your own `messages`). For side-effects: scroll, analytics, send.\n */\n messageSent: [event: AparteSendEventDetail];\n /** A custom bubble action (registerBubbleAction) was clicked — typed aparte-action. */\n action: [detail: AparteActionEventDetail];\n /** Active path changed (branch nav/edit/retry/streaming) — bind back to `messages`. */\n messagesChange: [messages: AparteMessage[]];\n /** Same payload as `messagesChange`, enabling `v-model:messages`. */\n 'update:messages': [messages: AparteMessage[]];\n messageAppended: [message: AparteMessage];\n /** The typing/\"thinking\" indicator toggled (the host flips it off on the first streamed token). */\n typingChange: [isTyping: boolean];\n conversationCreated: [id: string];\n}>();\n\n// useId() (Vue 3.5+) is SSR-stable — server and client agree, no hydration mismatch.\n// A caller-supplied `id` wins, so `scopeToTargetId` has something to match; the\n// generated one stays SSR-stable for the common case.\nconst hostId = props.id ?? `aparte-chat-${useId()}`;\nconst rootRef = ref<HTMLElement>();\nconst viewportRef = ref<HTMLElement>();\nconst composerRef = ref<HTMLElement>();\nconst internalMessages = ref<AparteMessage[]>([...props.messages]);\nconst typingActive = ref(props.isTyping);\n\nlet host: AparteChatHost | null = null;\nlet teardown: (() => void) | null = null;\n\nfunction onSend(e: Event) {\n (viewportRef.value as unknown as { requestSmoothScroll?: () => void })?.requestSmoothScroll?.();\n emit('messageSent', (e as CustomEvent<AparteSendEventDetail>).detail);\n}\n\n// Custom bubble actions bubble to the root as `aparte-action` — surface them typed.\nfunction onAction(e: Event) {\n emit('action', (e as CustomEvent<AparteActionEventDetail>).detail);\n}\n\n// The controller's wait (a conversation fetched through the adapter) OR the consumer's.\nconst hostLoading = ref(false);\nconst waiting = computed(() => props.loading || hostLoading.value);\nconst loadingText = computed(() => (props.config ?? aparteGlobalConfig).t('loadingConversation'));\n\nonMounted(() => {\n const binding: AparteChatHostBinding = {\n hostId,\n host: rootRef.value as HTMLElement,\n viewport: viewportRef.value ?? null,\n getMessages: () => internalMessages.value,\n setMessages: (m) => { internalMessages.value = m as AparteMessage[]; },\n onMessagesChange: (m) => { emit('messagesChange', m as AparteMessage[]); emit('update:messages', m as AparteMessage[]); },\n onMessageAppended: (m) => emit('messageAppended', m as AparteMessage),\n onTypingChange: (t) => { typingActive.value = t; emit('typingChange', t); },\n onStreamingChange: () => { /* exposed via isStreaming() */ },\n afterRender: (cb) => { void nextTick(cb); },\n resetComposer: () => (composerRef.value as unknown as { reset?: () => void })?.reset?.(),\n onLoadingChange: (on) => { hostLoading.value = on; },\n };\n host = new AparteChatHost(binding, {\n layoutTransitionMs: props.layoutTransitionMs,\n conversationId: props.conversationId ?? null,\n onConversationCreated: (id) => emit('conversationCreated', id),\n // Unwrap Vue's reactive proxy: the config is a plain class with internal\n // Map registries the host/components must operate on directly, not through a\n // deep reactive proxy (which would wrap those Maps and break lookups).\n config: props.config ? toRaw(props.config) : undefined,\n });\n teardown = host.bind();\n host.syncBubbles();\n composerRef.value?.addEventListener('aparte-send', onSend);\n rootRef.value?.addEventListener('aparte-action', onAction);\n});\n\nonBeforeUnmount(() => {\n composerRef.value?.removeEventListener('aparte-send', onSend);\n rootRef.value?.removeEventListener('aparte-action', onAction);\n teardown?.();\n teardown = null;\n host = null;\n});\n\n// Parent push → internal list (guarded against the host's own emit round-trip).\nwatch(() => props.messages, (m) => {\n if (m === internalMessages.value) return;\n internalMessages.value = [...m];\n if (m.length === 0) host?.clearRenderCache();\n});\n\n// Reconcile bubbles after the rendered list changes (host queries the DOM).\nwatch(internalMessages, () => { void nextTick(() => host?.syncBubbles()); });\n\nwatch(() => props.isTyping, (t) => { typingActive.value = t; });\nwatch(() => props.conversationId, (id) => { void host?.setConversationId(id ?? null); });\n\n// ── Imperative API (forwards to the host) ──\nconst appendMessage = (m: AparteMessage, o?: { historical?: boolean }) => host?.appendMessage(m, o);\nconst updateMessage = (id: string, u: Partial<AparteMessage>) => host?.updateMessage(id, u);\nconst updateLastMessage = (c: string, o?: { append?: boolean }) => host?.updateLastMessage(c, o);\nconst addSegment = (s: AparteSegment) => host?.addSegment(s);\nconst updateSegment = (id: string, u: Partial<AparteSegment>) => host?.updateSegment(id, u);\nconst removeSegment = (id: string) => host?.removeSegment(id);\nconst appendToSegment = (id: string, c: string) => host?.appendToSegment(id, c);\nconst getMessages = () => host?.getMessages() ?? internalMessages.value;\nconst clearMessages = (options?: { revokeAttachments?: boolean }) => host?.clearMessages(options);\nconst addBranch = (id: string) => host?.addBranch(id) ?? 0;\nconst addSiblingOf = (id: string, m: AparteMessage) => host?.addSiblingOf(id, m) ?? null;\nconst truncateFrom = (id: string) => host?.truncateFrom(id);\nconst truncateResponsesAfter = (id: string) => host?.truncateResponsesAfter(id);\nconst injectTokenStream = (id: string, tokens: AsyncIterable<string>) =>\n host?.streamTokens(id, tokens) ?? Promise.resolve();\nconst stopTokenStream = () => host?.stopTokenStream();\nconst setConversationId = (id: string | null) => host?.setConversationId(id) ?? Promise.resolve();\nconst scrollToBottom = () => (viewportRef.value as unknown as { scrollToBottom?: () => void })?.scrollToBottom?.();\nconst focusInput = () => (composerRef.value as unknown as { focus?: () => void })?.focus?.();\nconst isStreaming = () => host?.isStreaming ?? false;\n\n// `getViewport()` (not a raw `viewport` ref): the same accessor on all four\n// wrappers — Svelte 4 can only expose functions, so the shared name is one.\nconst getViewport = () => viewportRef.value ?? null;\n\n// `satisfies` makes a dropped or mistyped method a compile error — the canonical\n// AparteChatImperativeApi is enforced here, not just aliased for consumers.\ndefineExpose({\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} satisfies AparteChatImperativeApi);\n</script>\n\n<template>\n <div\n :class=\"['aparte-chat-container', { 'aparte-chat-container--auto-center': centerWhenEmpty }]\"\n data-aparte-chat\n :overlay-composer=\"overlayComposer ? '' : null\"\n :data-aparte-empty=\"centerWhenEmpty && internalMessages.length === 0 && !waiting ? '' : null\"\n :id=\"hostId\"\n ref=\"rootRef\"\n >\n <aparte-chat-viewport ref=\"viewportRef\" framework-managed=\"\" :loading=\"waiting ? '' : null\">\n <!-- The wait, drawn here because this DOM is Vue's: the kit's skeleton recipe,\n and a line for a screen reader. -->\n <div v-if=\"waiting\" class=\"aparte-viewport-loading\" aria-hidden=\"true\">\n <span class=\"aparte-skeleton aparte-skeleton--rect aparte-viewport-loading__user\"></span>\n <span class=\"aparte-skeleton aparte-skeleton--text\"></span>\n <span class=\"aparte-skeleton aparte-skeleton--text\"></span>\n <span class=\"aparte-skeleton aparte-skeleton--text\"></span>\n <span class=\"aparte-skeleton aparte-skeleton--text aparte-viewport-loading__last\"></span>\n </div>\n <span v-if=\"waiting\" class=\"aparte-viewport-loading-status aparte-sr-only\" role=\"status\">{{ loadingText }}</span>\n <!-- Welcome / placeholder shown inside the viewport while there are no\n messages (a real empty-state region). -->\n <slot v-if=\"internalMessages.length === 0 && !waiting\" name=\"empty-state\" />\n <!-- `bubble` scoped slot renders your OWN element per message in place of\n <aparte-chat-bubble>; driven by the reactive list so it streams live. -->\n <template v-for=\"m in internalMessages\" :key=\"m.id\">\n <slot name=\"bubble\" :message=\"m\">\n <aparte-chat-bubble\n :message-id=\"m.id\"\n :data-role=\"m.role\"\n :data-kind=\"m.compaction ? 'compaction' : undefined\"\n :timestamp=\"m.timestamp\"\n :content=\"m.content\"\n :streaming=\"isAwaitingReply(m) ? '' : null\"\n />\n </slot>\n </template>\n <aparte-chat-status :visible=\"typingActive ? '' : null\" :text=\"typingText\" />\n </aparte-chat-viewport>\n\n <!-- The presenter for a request to the human (approval gate, ask_user…). Renders\n nothing until something asks; on by default as in <aparte-chat>. -->\n <aparte-elicitation v-if=\"elicitation\"></aparte-elicitation>\n\n <!-- Content above the composer (banner, disclaimer, context chip). -->\n <slot name=\"above-composer\" />\n\n <!-- `.attr` forces attribute-setting, and stays: the attribute IS the state\n core's composer parts read (`getAttribute('placeholder')`, `hasAttribute\n ('disabled')`). Core gained the matching setters in 0.16.12 — before that\n they were getter-only and Vue's default property-set on a custom element\n threw — so this is now a direct write rather than a way around a crash. -->\n <aparte-composer\n ref=\"composerRef\"\n :target=\"hostId\"\n :placeholder.attr=\"placeholder\"\n :disabled.attr=\"disabled || waiting ? '' : null\"\n :submit-on-enter=\"submitOnEnter ? null : 'false'\"\n >\n <!-- Custom composer via the `composer` slot; falls back to the default\n shell (input · send, plus the attachment primitives when `attachments`\n is 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 <aparte-composer-attachments v-if=\"attachments\"></aparte-composer-attachments>\n <div class=\"aparte-composer-row\">\n <aparte-composer-add-attachment v-if=\"attachments\"></aparte-composer-add-attachment>\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 <aparte-composer-toolbar v-if=\"$slots.toolbar\">\n <slot name=\"toolbar\" />\n </aparte-composer-toolbar>\n </div>\n </slot>\n </aparte-composer>\n </div>\n</template>\n","import { ref, type Ref } from 'vue';\nimport type { AparteChatImperativeApi } from '@aparte/core';\nimport type { AparteMessage, AparteSegment } from '../types.js';\n\n/**\n * Idiomatic Vue ergonomics for `<AparteChat>`. Owns the `messages` ref and a\n * component template ref so the consumer skips the manual\n * `@messages-change` → `messages` round-trip.\n *\n * @example\n * const chat = useAparteChat();\n * // template:\n * // <AparteChat :ref=\"chat.chatRef\" :messages=\"chat.messages.value\"\n * // @messages-change=\"chat.onMessagesChange\" />\n */\nexport function useAparteChat(initial: AparteMessage[] = []) {\n const messages = ref<AparteMessage[]>([...initial]) as Ref<AparteMessage[]>;\n const chatRef = ref<AparteChatImperativeApi | null>(null);\n const c = () => chatRef.value;\n const onMessagesChange = (m: AparteMessage[]) => { messages.value = m; };\n\n return {\n messages,\n chatRef,\n onMessagesChange,\n appendMessage: (m: AparteMessage, o?: { historical?: boolean }) => c()?.appendMessage(m, o),\n updateMessage: (id: string, u: Partial<AparteMessage>) => c()?.updateMessage(id, u),\n updateLastMessage: (content: string, o?: { append?: boolean }) => c()?.updateLastMessage(content, o),\n addSegment: (s: AparteSegment) => c()?.addSegment(s),\n updateSegment: (id: string, u: Partial<AparteSegment>) => c()?.updateSegment(id, u),\n removeSegment: (id: string) => c()?.removeSegment(id),\n appendToSegment: (id: string, content: string) => c()?.appendToSegment(id, content),\n // The host's list — the authority, and mid-stream a frame ahead of the\n // `messages` ref, which is synced once per paint rather than per token.\n getMessages: (): AparteMessage[] => c()?.getMessages() ?? messages.value,\n clearMessages: (options?: { revokeAttachments?: boolean }) => c()?.clearMessages(options),\n addBranch: (id: string) => c()?.addBranch(id) ?? 0,\n addSiblingOf: (id: string, m: AparteMessage) => c()?.addSiblingOf(id, m) ?? null,\n truncateFrom: (id: string) => c()?.truncateFrom(id),\n truncateResponsesAfter: (id: string) => c()?.truncateResponsesAfter(id),\n injectTokenStream: (id: string, tokens: AsyncIterable<string>) =>\n c()?.injectTokenStream(id, tokens) ?? Promise.resolve(),\n stopTokenStream: () => c()?.stopTokenStream(),\n setConversationId: (id: string | null) => c()?.setConversationId(id) ?? Promise.resolve(),\n isStreaming: () => c()?.isStreaming() ?? false,\n scrollToBottom: () => c()?.scrollToBottom(),\n focusInput: () => c()?.focusInput(),\n /** The `<aparte-chat-viewport>` element — same accessor on all four wrappers. */\n getViewport: (): HTMLElement | null => c()?.getViewport() ?? null,\n };\n}\n","import { onMounted, onBeforeUnmount } from 'vue';\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 unmount. Vue equivalent of Angular's\n * `AparteAiService`.\n */\nexport function useAparteClient(options?: AparteClientOptions) {\n const client = new AparteClient(options ?? {});\n onMounted(() => client.start());\n onBeforeUnmount(() => client.stop());\n return { client, abort: () => client.abort() };\n}\n","import { ref, computed, onBeforeUnmount, type Ref } from 'vue';\nimport {\n aparteGlobalConfig,\n type AparteConfig,\n AparteConversationManager,\n type AparteConversation,\n type AparteStorageAdapter,\n} from '@aparte/core';\nimport type { AparteMessage } from '../types.js';\n\n/**\n * Vue-reactive wrapper around the core `AparteConversationManager`. The active\n * conversation is owned by the chat component's controller; switch by binding\n * `conversationId` on `<AparteChat>`. Vue equivalent of Angular's\n * `ConversationManagerService`.\n */\nexport function useConversationManager() {\n let manager: AparteConversationManager | null = null;\n let unsub: (() => void) | null = null;\n\n const conversations = ref<AparteConversation[]>([]) as Ref<AparteConversation[]>;\n const activeId = ref<string | null>(null);\n\n const activeConversations = computed(() =>\n conversations.value.filter((c) => !c.archivedAt).sort((a, b) => b.updatedAt - a.updatedAt),\n );\n const archivedConversations = computed(() =>\n conversations.value.filter((c) => !!c.archivedAt).sort((a, b) => b.updatedAt - a.updatedAt),\n );\n const activeConversation = computed(() =>\n activeId.value ? conversations.value.find((c) => c.id === activeId.value) ?? null : null,\n );\n\n onBeforeUnmount(() => unsub?.());\n\n const assert = (): AparteConversationManager => {\n if (!manager) throw new Error('[useConversationManager] Not initialised. Call init(adapter) first.');\n return manager;\n };\n\n /**\n * Initialise with a storage adapter.\n *\n * `config` defaults to the global singleton. Pass the SAME config you gave\n * `<AparteChat config={…}>`: the controller resolves the config governing its\n * host element, so a manager registered on the global is invisible to a chat\n * with its own — persistence silently does nothing while the optimistic UI\n * keeps working.\n */\n const init = async (adapter: AparteStorageAdapter, config: AparteConfig = aparteGlobalConfig): Promise<void> => {\n const m = new AparteConversationManager(adapter);\n manager = m;\n unsub = m.subscribe((convs) => {\n conversations.value = [...convs];\n activeId.value = m.activeId;\n });\n await m.init();\n activeId.value = m.activeId;\n config.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 pin: (id: string) => assert().pin(id),\n unpin: (id: string) => assert().unpin(id),\n updateTitle: (id: string, title: string) => assert().updateTitle(id, title),\n };\n}\n","<script setup lang=\"ts\">\nimport { ref, computed, watch, onMounted, onBeforeUnmount, toRaw } from 'vue';\nimport { applyElementProps, APARTE_DEFAULT_UI_EVENTS } from '@aparte/core';\nimport type { AparteUiHandle } from '../types.js';\n\nconst p = defineProps<{\n /** The custom element tag name (e.g. 'aparte-model-selector'). */\n name: string;\n /** Props to apply. Keys starting with `--` become CSS variables. */\n props?: Record<string, unknown>;\n /**\n * Which custom events to forward through `elementEvent`. Defaults to the\n * interactive aparté surface (APARTE_DEFAULT_UI_EVENTS); pass your own list to listen to\n * other events (e.g. ['aparte-composer-change'] for attachments).\n */\n events?: string[];\n}>();\n\nconst emit = defineEmits<{ elementEvent: [event: CustomEvent] }>();\n\n// A stable key so a fresh inline `:events` array doesn't thrash the element —\n// only a real change to the event names rebinds (mirrors React's evtsKey).\nconst evtsKey = computed(() => (p.events ?? APARTE_DEFAULT_UI_EVENTS).join('|'));\n\nconst hostRef = ref<HTMLElement>();\nlet el: HTMLElement | null = null;\nlet cleanups: Array<() => void> = [];\n\n// Vue passes `toRaw` so objects are unwrapped from the reactive proxy before\n// reaching the plain custom element (a deep proxy breaks Maps/class internals).\nfunction applyProps() {\n if (el) applyElementProps(el, p.props ?? {}, toRaw);\n}\n\nfunction create() {\n if (!hostRef.value) return;\n el = document.createElement(p.name);\n applyProps();\n for (const ev of evtsKey.value.split('|').filter(Boolean)) {\n const listener = (e: Event) => emit('elementEvent', e as CustomEvent);\n el.addEventListener(ev, listener);\n cleanups.push(() => el?.removeEventListener(ev, listener));\n }\n hostRef.value.appendChild(el);\n}\n\nfunction destroy() {\n for (const c of cleanups) c();\n cleanups = [];\n el?.remove();\n el = null;\n}\n\nonMounted(create);\nonBeforeUnmount(destroy);\nwatch(() => p.name, () => { destroy(); create(); });\nwatch(evtsKey, () => { destroy(); create(); });\nwatch(() => p.props, applyProps, { deep: true });\n\n/*\n * Typed as `AparteUiHandle`, the way React's `useImperativeHandle` already is.\n *\n * It used to be a bare object literal, so the exposed `getElement` returned\n * `HTMLElement | null` instead of the interface's `<T extends HTMLElement>() => T | null`\n * — and the barrel exports that interface with a docblock promising \"the same contract on\n * all four wrappers\". A consumer following the documented `ref` pattern got a type error\n * on Vue and Svelte and none on React or Angular. Found by a cold audit that compiled it\n * rather than read it.\n *\n * `as never` is the same bridge React uses at AparteUi.tsx:85: the value really is the\n * element, and only the caller knows which subtype it asked for.\n */\ndefineExpose<AparteUiHandle>({\n getElement: () => el as never,\n 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) as never;\n },\n});\n</script>\n\n<template>\n <span ref=\"hostRef\" style=\"display: contents\"></span>\n</template>\n"],"names":["_createElementBlock","_unref","_createElementVNode","_openBlock","_toDisplayString","_renderSlot","_Fragment","_renderList","$slots"],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -18,11 +18,9 @@ export interface AparteUiProps {
|
|
|
18
18
|
events?: string[];
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
|
-
* The imperative surface `<AparteUi>` exposes (template ref) —
|
|
22
|
-
*
|
|
21
|
+
* The imperative surface `<AparteUi>` exposes (template ref) — one declaration in
|
|
22
|
+
* `@aparte/core`, re-exported by all four wrappers. It used to be four hand-written
|
|
23
|
+
* copies, each promising "the same contract on all four", and it had already drifted.
|
|
23
24
|
*/
|
|
24
|
-
export
|
|
25
|
-
getElement<T extends HTMLElement = HTMLElement>(): T | null;
|
|
26
|
-
callMethod<T = unknown>(methodName: string, ...args: unknown[]): T | undefined;
|
|
27
|
-
}
|
|
25
|
+
export type { AparteUiHandle } from '@aparte/core';
|
|
28
26
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,YAAY,EACR,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,GAC1B,MAAM,cAAc,CAAC;AAEtB,8DAA8D;AAC9D,MAAM,WAAW,aAAa;IAC1B,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,YAAY,EACR,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,GAC1B,MAAM,cAAc,CAAC;AAEtB,8DAA8D;AAC9D,MAAM,WAAW,aAAa;IAC1B,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;;;GAIG;AACH,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aparte/vue",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"homepage": "https://apartejs.dev/frameworks/vue/",
|
|
5
5
|
"description": "Vue 3 wrapper for aparté — an ergonomic <AparteChat> component plus composables over the framework-agnostic web components.",
|
|
6
6
|
"type": "module",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"node": ">=18"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"@aparte/core": ">=0.
|
|
28
|
+
"@aparte/core": ">=0.17.0 <1.0.0",
|
|
29
29
|
"vue": "^3.5.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"vite": "^6.0.0",
|
|
37
37
|
"vue": "^3.5.0",
|
|
38
38
|
"vue-tsc": "^2.0.0",
|
|
39
|
-
"@aparte/core": "0.
|
|
39
|
+
"@aparte/core": "0.17.0"
|
|
40
40
|
},
|
|
41
41
|
"keywords": [
|
|
42
42
|
"vue",
|