@aparte/vue 0.16.10 → 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.
@@ -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: () => void | undefined;
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":"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"}
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
- clearMessages: () => void | undefined;
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;;;;;;;+BAc8N,CAAC;6BAAqB,CAAC;;;;;;;;;;;;;;uDAhB7Q,CAAC;sBAAc,CAAC;;;oDAEJ,CAAC;kBAAU,CAAC;;;;;;;+BAc8N,CAAC;6BAAqB,CAAC;;;;;;;;;;;;;;0BAzBpQ,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;;oBAE7B,MAAM;uBACH,MAAM,KAAK,aAAa;uBACxB,MAAM;iCACI,MAAM;4BACX,MAAM,UAAU,aAAa,CAAC,MAAM,CAAC;;4BAGrC,MAAM,GAAG,IAAI;;EAG5C"}
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, renderSlot, createCommentVNode, Fragment, renderList, computed } from "vue";
2
- import { AparteChatHost, isAwaitingReply, AparteClient, aparteGlobalConfig, AparteConversationManager, APARTE_DEFAULT_UI_EVENTS, applyElementProps } from "@aparte/core";
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 = ["message-id", "data-role", "data-kind", "timestamp", "content", "streaming"];
5
- const _hoisted_3 = ["visible", "text"];
6
- const _hoisted_4 = { key: 0 };
7
- const _hoisted_5 = ["target", "^placeholder", "^disabled", "submit-on-enter"];
8
- const _hoisted_6 = { class: "aparte-composer-shell" };
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 = { class: "aparte-composer-row" };
11
- const _hoisted_9 = { key: 0 };
12
- const _hoisted_10 = { key: 1 };
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
- internalMessages.value.length === 0 ? renderSlot(_ctx.$slots, "empty-state", { key: 0 }) : createCommentVNode("", true),
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, _hoisted_2)
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, _hoisted_3)
187
- ], 512),
188
- __props.elicitation ? (openBlock(), createElementBlock("aparte-elicitation", _hoisted_4)) : createCommentVNode("", true),
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", _hoisted_6, [
200
- __props.attachments ? (openBlock(), createElementBlock("aparte-composer-attachments", _hoisted_7)) : createCommentVNode("", true),
201
- createElementVNode("div", _hoisted_8, [
202
- __props.attachments ? (openBlock(), createElementBlock("aparte-composer-add-attachment", _hoisted_9)) : createCommentVNode("", true),
203
- _cache[0] || (_cache[0] = createElementVNode("aparte-composer-input", null, null, -1)),
204
- _cache[1] || (_cache[1] = createElementVNode("aparte-composer-send", null, null, -1))
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", _hoisted_10, [
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, _hoisted_5)
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
- clearMessages: () => c()?.clearMessages(),
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) — the same
22
- * `getElement`/`callMethod` contract on all four wrappers.
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 interface AparteUiHandle {
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
@@ -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;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC3B,UAAU,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,KAAK,CAAC,GAAG,IAAI,CAAC;IAC5D,UAAU,CAAC,CAAC,GAAG,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,GAAG,SAAS,CAAC;CAClF"}
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.16.10",
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.16.10 <1.0.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.16.10"
39
+ "@aparte/core": "0.17.0"
40
40
  },
41
41
  "keywords": [
42
42
  "vue",