@aparte/vue 0.7.1 → 0.9.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 +153 -6
- package/dist/components/AparteChat.vue.d.ts.map +1 -1
- package/dist/components/AparteUi.vue.d.ts +1 -1
- package/dist/composables/useAparteChat.d.ts +0 -5
- package/dist/composables/useAparteChat.d.ts.map +1 -1
- package/dist/composables/useConversationManager.d.ts +3 -3
- package/dist/composables/useConversationManager.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -11
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/package.json +3 -3
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type AparteConfig } from '@aparte/core';
|
|
2
2
|
import type { AparteMessage, AparteSegment, AparteSendEventDetail, AparteActionEventDetail } from '../types.js';
|
|
3
3
|
interface Props {
|
|
4
|
+
/**
|
|
5
|
+
* The host element's `id`, and therefore the `targetId` every event this chat
|
|
6
|
+
* dispatches carries. Generated when omitted — but it used to be generated and
|
|
7
|
+
* neither accepted nor exposed, which made `AparteClientOptions.scopeToTargetId`
|
|
8
|
+
* unreachable from this component.
|
|
9
|
+
*/
|
|
10
|
+
id?: string;
|
|
4
11
|
/** Optional: omit for an uncontrolled chat (defaults to []); use `v-model:messages` to control. */
|
|
5
12
|
messages?: AparteMessage[];
|
|
6
13
|
placeholder?: string;
|
|
@@ -29,15 +36,15 @@ interface Props {
|
|
|
29
36
|
* `<aparte-composer-attachments>` in it yourself).
|
|
30
37
|
*/
|
|
31
38
|
attachments?: boolean;
|
|
32
|
-
/** Active conversation id (loads/persists via the registered
|
|
39
|
+
/** Active conversation id (loads/persists via the registered AparteConversationManager). */
|
|
33
40
|
conversationId?: string | null;
|
|
34
41
|
/**
|
|
35
|
-
* Instance {@link
|
|
36
|
-
* inside resolve THIS config instead of
|
|
42
|
+
* Instance {@link AparteConfig} for this chat. When set, aparté components
|
|
43
|
+
* inside resolve THIS config instead of `aparteGlobalConfig`, so
|
|
37
44
|
* several independently-configured chats can coexist on one page. Omit for the
|
|
38
45
|
* global config. Read once when the host mounts.
|
|
39
46
|
*/
|
|
40
|
-
config?:
|
|
47
|
+
config?: AparteConfig;
|
|
41
48
|
}
|
|
42
49
|
declare var __VLS_7: {}, __VLS_9: {
|
|
43
50
|
message: {
|
|
@@ -55,11 +62,21 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
55
62
|
result?: string | undefined;
|
|
56
63
|
id: string;
|
|
57
64
|
isStreaming?: boolean | undefined;
|
|
65
|
+
messageId?: string | undefined;
|
|
66
|
+
index?: number | undefined;
|
|
67
|
+
startedAt?: number | undefined;
|
|
68
|
+
endedAt?: number | undefined;
|
|
69
|
+
meta?: Record<string, unknown> | undefined;
|
|
58
70
|
} | {
|
|
59
71
|
type: "text";
|
|
60
72
|
content: string;
|
|
61
73
|
id: string;
|
|
62
74
|
isStreaming?: boolean | undefined;
|
|
75
|
+
messageId?: string | undefined;
|
|
76
|
+
index?: number | undefined;
|
|
77
|
+
startedAt?: number | undefined;
|
|
78
|
+
endedAt?: number | undefined;
|
|
79
|
+
meta?: Record<string, unknown> | undefined;
|
|
63
80
|
} | {
|
|
64
81
|
type: "thinking";
|
|
65
82
|
content: string;
|
|
@@ -67,6 +84,11 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
67
84
|
label?: string | undefined;
|
|
68
85
|
id: string;
|
|
69
86
|
isStreaming?: boolean | undefined;
|
|
87
|
+
messageId?: string | undefined;
|
|
88
|
+
index?: number | undefined;
|
|
89
|
+
startedAt?: number | undefined;
|
|
90
|
+
endedAt?: number | undefined;
|
|
91
|
+
meta?: Record<string, unknown> | undefined;
|
|
70
92
|
} | {
|
|
71
93
|
type: "code";
|
|
72
94
|
content: string;
|
|
@@ -75,6 +97,11 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
75
97
|
showLineNumbers?: boolean | undefined;
|
|
76
98
|
id: string;
|
|
77
99
|
isStreaming?: boolean | undefined;
|
|
100
|
+
messageId?: string | undefined;
|
|
101
|
+
index?: number | undefined;
|
|
102
|
+
startedAt?: number | undefined;
|
|
103
|
+
endedAt?: number | undefined;
|
|
104
|
+
meta?: Record<string, unknown> | undefined;
|
|
78
105
|
} | {
|
|
79
106
|
type: "diff";
|
|
80
107
|
filename?: string | undefined;
|
|
@@ -88,6 +115,11 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
88
115
|
}[];
|
|
89
116
|
id: string;
|
|
90
117
|
isStreaming?: boolean | undefined;
|
|
118
|
+
messageId?: string | undefined;
|
|
119
|
+
index?: number | undefined;
|
|
120
|
+
startedAt?: number | undefined;
|
|
121
|
+
endedAt?: number | undefined;
|
|
122
|
+
meta?: Record<string, unknown> | undefined;
|
|
91
123
|
} | {
|
|
92
124
|
type: "terminal";
|
|
93
125
|
command?: string | undefined;
|
|
@@ -96,6 +128,11 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
96
128
|
isRunning?: boolean | undefined;
|
|
97
129
|
id: string;
|
|
98
130
|
isStreaming?: boolean | undefined;
|
|
131
|
+
messageId?: string | undefined;
|
|
132
|
+
index?: number | undefined;
|
|
133
|
+
startedAt?: number | undefined;
|
|
134
|
+
endedAt?: number | undefined;
|
|
135
|
+
meta?: Record<string, unknown> | undefined;
|
|
99
136
|
} | {
|
|
100
137
|
type: "file-tree";
|
|
101
138
|
files: {
|
|
@@ -108,6 +145,11 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
108
145
|
title?: string | undefined;
|
|
109
146
|
id: string;
|
|
110
147
|
isStreaming?: boolean | undefined;
|
|
148
|
+
messageId?: string | undefined;
|
|
149
|
+
index?: number | undefined;
|
|
150
|
+
startedAt?: number | undefined;
|
|
151
|
+
endedAt?: number | undefined;
|
|
152
|
+
meta?: Record<string, unknown> | undefined;
|
|
111
153
|
} | {
|
|
112
154
|
type: "image";
|
|
113
155
|
url: string;
|
|
@@ -115,6 +157,11 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
115
157
|
caption?: string | undefined;
|
|
116
158
|
id: string;
|
|
117
159
|
isStreaming?: boolean | undefined;
|
|
160
|
+
messageId?: string | undefined;
|
|
161
|
+
index?: number | undefined;
|
|
162
|
+
startedAt?: number | undefined;
|
|
163
|
+
endedAt?: number | undefined;
|
|
164
|
+
meta?: Record<string, unknown> | undefined;
|
|
118
165
|
} | {
|
|
119
166
|
type: "preview";
|
|
120
167
|
url: string;
|
|
@@ -122,6 +169,11 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
122
169
|
height?: number | undefined;
|
|
123
170
|
id: string;
|
|
124
171
|
isStreaming?: boolean | undefined;
|
|
172
|
+
messageId?: string | undefined;
|
|
173
|
+
index?: number | undefined;
|
|
174
|
+
startedAt?: number | undefined;
|
|
175
|
+
endedAt?: number | undefined;
|
|
176
|
+
meta?: Record<string, unknown> | undefined;
|
|
125
177
|
} | {
|
|
126
178
|
type: "error";
|
|
127
179
|
content: string;
|
|
@@ -129,6 +181,11 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
129
181
|
stack?: string | undefined;
|
|
130
182
|
id: string;
|
|
131
183
|
isStreaming?: boolean | undefined;
|
|
184
|
+
messageId?: string | undefined;
|
|
185
|
+
index?: number | undefined;
|
|
186
|
+
startedAt?: number | undefined;
|
|
187
|
+
endedAt?: number | undefined;
|
|
188
|
+
meta?: Record<string, unknown> | undefined;
|
|
132
189
|
} | {
|
|
133
190
|
type: "progress";
|
|
134
191
|
label: string;
|
|
@@ -136,6 +193,11 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
136
193
|
status?: "pending" | "running" | "complete" | "error" | undefined;
|
|
137
194
|
id: string;
|
|
138
195
|
isStreaming?: boolean | undefined;
|
|
196
|
+
messageId?: string | undefined;
|
|
197
|
+
index?: number | undefined;
|
|
198
|
+
startedAt?: number | undefined;
|
|
199
|
+
endedAt?: number | undefined;
|
|
200
|
+
meta?: Record<string, unknown> | undefined;
|
|
139
201
|
} | {
|
|
140
202
|
type: "custom";
|
|
141
203
|
subType: string;
|
|
@@ -143,6 +205,11 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
143
205
|
fallback?: string | undefined;
|
|
144
206
|
id: string;
|
|
145
207
|
isStreaming?: boolean | undefined;
|
|
208
|
+
messageId?: string | undefined;
|
|
209
|
+
index?: number | undefined;
|
|
210
|
+
startedAt?: number | undefined;
|
|
211
|
+
endedAt?: number | undefined;
|
|
212
|
+
meta?: Record<string, unknown> | undefined;
|
|
146
213
|
} | {
|
|
147
214
|
type: "artifact";
|
|
148
215
|
mimeType: string;
|
|
@@ -152,10 +219,20 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
152
219
|
inline?: boolean | undefined;
|
|
153
220
|
id: string;
|
|
154
221
|
isStreaming?: boolean | undefined;
|
|
222
|
+
messageId?: string | undefined;
|
|
223
|
+
index?: number | undefined;
|
|
224
|
+
startedAt?: number | undefined;
|
|
225
|
+
endedAt?: number | undefined;
|
|
226
|
+
meta?: Record<string, unknown> | undefined;
|
|
155
227
|
} | {
|
|
156
228
|
type: "pipeline-waiting";
|
|
157
229
|
id: string;
|
|
158
230
|
isStreaming?: boolean | undefined;
|
|
231
|
+
messageId?: string | undefined;
|
|
232
|
+
index?: number | undefined;
|
|
233
|
+
startedAt?: number | undefined;
|
|
234
|
+
endedAt?: number | undefined;
|
|
235
|
+
meta?: Record<string, unknown> | undefined;
|
|
159
236
|
})[] | undefined;
|
|
160
237
|
timestamp: number;
|
|
161
238
|
isStreaming?: boolean | undefined;
|
|
@@ -206,11 +283,21 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
206
283
|
result?: string | undefined;
|
|
207
284
|
id: string;
|
|
208
285
|
isStreaming?: boolean | undefined;
|
|
286
|
+
messageId?: string | undefined;
|
|
287
|
+
index?: number | undefined;
|
|
288
|
+
startedAt?: number | undefined;
|
|
289
|
+
endedAt?: number | undefined;
|
|
290
|
+
meta?: Record<string, unknown> | undefined;
|
|
209
291
|
} | {
|
|
210
292
|
type: "text";
|
|
211
293
|
content: string;
|
|
212
294
|
id: string;
|
|
213
295
|
isStreaming?: boolean | undefined;
|
|
296
|
+
messageId?: string | undefined;
|
|
297
|
+
index?: number | undefined;
|
|
298
|
+
startedAt?: number | undefined;
|
|
299
|
+
endedAt?: number | undefined;
|
|
300
|
+
meta?: Record<string, unknown> | undefined;
|
|
214
301
|
} | {
|
|
215
302
|
type: "thinking";
|
|
216
303
|
content: string;
|
|
@@ -218,6 +305,11 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
218
305
|
label?: string | undefined;
|
|
219
306
|
id: string;
|
|
220
307
|
isStreaming?: boolean | undefined;
|
|
308
|
+
messageId?: string | undefined;
|
|
309
|
+
index?: number | undefined;
|
|
310
|
+
startedAt?: number | undefined;
|
|
311
|
+
endedAt?: number | undefined;
|
|
312
|
+
meta?: Record<string, unknown> | undefined;
|
|
221
313
|
} | {
|
|
222
314
|
type: "code";
|
|
223
315
|
content: string;
|
|
@@ -226,6 +318,11 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
226
318
|
showLineNumbers?: boolean | undefined;
|
|
227
319
|
id: string;
|
|
228
320
|
isStreaming?: boolean | undefined;
|
|
321
|
+
messageId?: string | undefined;
|
|
322
|
+
index?: number | undefined;
|
|
323
|
+
startedAt?: number | undefined;
|
|
324
|
+
endedAt?: number | undefined;
|
|
325
|
+
meta?: Record<string, unknown> | undefined;
|
|
229
326
|
} | {
|
|
230
327
|
type: "diff";
|
|
231
328
|
filename?: string | undefined;
|
|
@@ -239,6 +336,11 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
239
336
|
}[];
|
|
240
337
|
id: string;
|
|
241
338
|
isStreaming?: boolean | undefined;
|
|
339
|
+
messageId?: string | undefined;
|
|
340
|
+
index?: number | undefined;
|
|
341
|
+
startedAt?: number | undefined;
|
|
342
|
+
endedAt?: number | undefined;
|
|
343
|
+
meta?: Record<string, unknown> | undefined;
|
|
242
344
|
} | {
|
|
243
345
|
type: "terminal";
|
|
244
346
|
command?: string | undefined;
|
|
@@ -247,6 +349,11 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
247
349
|
isRunning?: boolean | undefined;
|
|
248
350
|
id: string;
|
|
249
351
|
isStreaming?: boolean | undefined;
|
|
352
|
+
messageId?: string | undefined;
|
|
353
|
+
index?: number | undefined;
|
|
354
|
+
startedAt?: number | undefined;
|
|
355
|
+
endedAt?: number | undefined;
|
|
356
|
+
meta?: Record<string, unknown> | undefined;
|
|
250
357
|
} | {
|
|
251
358
|
type: "file-tree";
|
|
252
359
|
files: {
|
|
@@ -259,6 +366,11 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
259
366
|
title?: string | undefined;
|
|
260
367
|
id: string;
|
|
261
368
|
isStreaming?: boolean | undefined;
|
|
369
|
+
messageId?: string | undefined;
|
|
370
|
+
index?: number | undefined;
|
|
371
|
+
startedAt?: number | undefined;
|
|
372
|
+
endedAt?: number | undefined;
|
|
373
|
+
meta?: Record<string, unknown> | undefined;
|
|
262
374
|
} | {
|
|
263
375
|
type: "image";
|
|
264
376
|
url: string;
|
|
@@ -266,6 +378,11 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
266
378
|
caption?: string | undefined;
|
|
267
379
|
id: string;
|
|
268
380
|
isStreaming?: boolean | undefined;
|
|
381
|
+
messageId?: string | undefined;
|
|
382
|
+
index?: number | undefined;
|
|
383
|
+
startedAt?: number | undefined;
|
|
384
|
+
endedAt?: number | undefined;
|
|
385
|
+
meta?: Record<string, unknown> | undefined;
|
|
269
386
|
} | {
|
|
270
387
|
type: "preview";
|
|
271
388
|
url: string;
|
|
@@ -273,6 +390,11 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
273
390
|
height?: number | undefined;
|
|
274
391
|
id: string;
|
|
275
392
|
isStreaming?: boolean | undefined;
|
|
393
|
+
messageId?: string | undefined;
|
|
394
|
+
index?: number | undefined;
|
|
395
|
+
startedAt?: number | undefined;
|
|
396
|
+
endedAt?: number | undefined;
|
|
397
|
+
meta?: Record<string, unknown> | undefined;
|
|
276
398
|
} | {
|
|
277
399
|
type: "error";
|
|
278
400
|
content: string;
|
|
@@ -280,6 +402,11 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
280
402
|
stack?: string | undefined;
|
|
281
403
|
id: string;
|
|
282
404
|
isStreaming?: boolean | undefined;
|
|
405
|
+
messageId?: string | undefined;
|
|
406
|
+
index?: number | undefined;
|
|
407
|
+
startedAt?: number | undefined;
|
|
408
|
+
endedAt?: number | undefined;
|
|
409
|
+
meta?: Record<string, unknown> | undefined;
|
|
283
410
|
} | {
|
|
284
411
|
type: "progress";
|
|
285
412
|
label: string;
|
|
@@ -287,6 +414,11 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
287
414
|
status?: "pending" | "running" | "complete" | "error" | undefined;
|
|
288
415
|
id: string;
|
|
289
416
|
isStreaming?: boolean | undefined;
|
|
417
|
+
messageId?: string | undefined;
|
|
418
|
+
index?: number | undefined;
|
|
419
|
+
startedAt?: number | undefined;
|
|
420
|
+
endedAt?: number | undefined;
|
|
421
|
+
meta?: Record<string, unknown> | undefined;
|
|
290
422
|
} | {
|
|
291
423
|
type: "custom";
|
|
292
424
|
subType: string;
|
|
@@ -294,6 +426,11 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
294
426
|
fallback?: string | undefined;
|
|
295
427
|
id: string;
|
|
296
428
|
isStreaming?: boolean | undefined;
|
|
429
|
+
messageId?: string | undefined;
|
|
430
|
+
index?: number | undefined;
|
|
431
|
+
startedAt?: number | undefined;
|
|
432
|
+
endedAt?: number | undefined;
|
|
433
|
+
meta?: Record<string, unknown> | undefined;
|
|
297
434
|
} | {
|
|
298
435
|
type: "artifact";
|
|
299
436
|
mimeType: string;
|
|
@@ -303,10 +440,20 @@ declare var __VLS_7: {}, __VLS_9: {
|
|
|
303
440
|
inline?: boolean | undefined;
|
|
304
441
|
id: string;
|
|
305
442
|
isStreaming?: boolean | undefined;
|
|
443
|
+
messageId?: string | undefined;
|
|
444
|
+
index?: number | undefined;
|
|
445
|
+
startedAt?: number | undefined;
|
|
446
|
+
endedAt?: number | undefined;
|
|
447
|
+
meta?: Record<string, unknown> | undefined;
|
|
306
448
|
} | {
|
|
307
449
|
type: "pipeline-waiting";
|
|
308
450
|
id: string;
|
|
309
451
|
isStreaming?: boolean | undefined;
|
|
452
|
+
messageId?: string | undefined;
|
|
453
|
+
index?: number | undefined;
|
|
454
|
+
startedAt?: number | undefined;
|
|
455
|
+
endedAt?: number | undefined;
|
|
456
|
+
meta?: Record<string, unknown> | undefined;
|
|
310
457
|
})[] | undefined;
|
|
311
458
|
status?: import("@aparte/core").AparteStatus | undefined;
|
|
312
459
|
timestamp: number;
|
|
@@ -370,9 +517,9 @@ declare const __VLS_component: import("vue").DefineComponent<Props, {
|
|
|
370
517
|
messages: AparteMessage[];
|
|
371
518
|
disabled: boolean;
|
|
372
519
|
placeholder: string;
|
|
520
|
+
submitOnEnter: boolean;
|
|
373
521
|
isTyping: boolean;
|
|
374
522
|
typingText: string;
|
|
375
|
-
submitOnEnter: boolean;
|
|
376
523
|
layoutTransitionMs: number;
|
|
377
524
|
centerWhenEmpty: boolean;
|
|
378
525
|
conversationId: string | null;
|
|
@@ -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":"AAuQA,OAAO,EAA+D,KAAK,YAAY,EAAgC,MAAM,cAAc,CAAC;AAC5I,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAEhH,UAAU,KAAK;IACb;;;;;OAKG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,mGAAmG;IACnG,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,+EAA+E;IAC/E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4FAA4F;IAC5F,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAmTD,QAAA,IAAuB,OAAO,IAAU,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAU,EAAE,QAAQ,IAAW,EAAuB,QAAQ,IAAW,EAAE,QAAQ,IAAY,CAAE;AAClJ,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,GAClD;IAAE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,GAC3C;IAAE,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,QAAQ,KAAK,GAAG,CAAA;CAAE,GACtD;IAAE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,QAAQ,KAAK,GAAG,CAAA;CAAE,GAC9C;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,QAAQ,KAAK,GAAG,CAAA;CAAE,CAAC;AA+BhD,QAAA,MAAM,eAAe;uBAzOK,aAAa;wBACZ,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC;2BAC9B,MAAM,MAAM;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE;oBACvC,aAAa;wBACT,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC;wBACjC,MAAM;0BACJ,MAAM,KAAK,MAAM;;;oBAGvB,MAAM;uBACH,MAAM,KAAK,aAAa;uBACxB,MAAM;iCACI,MAAM;4BACX,MAAM,UAAU,aAAa,CAAC,MAAM,CAAC;;4BAGrC,MAAM,GAAG,IAAI;;;;;;;;;;;;;;;;;;;;;;iBAzI5B,OAAO;cA1BV,aAAa,EAAE;cAEf,OAAO;iBADJ,MAAM;mBAKJ,OAAO;cAHZ,OAAO;gBACL,MAAM;wBAIE,MAAM;qBAQT,OAAO;oBAYR,MAAM,GAAG,IAAI;6EAyW9B,CAAC;wBACkB,eAAe,CAAC,OAAO,eAAe,EAAE,WAAW,CAAC;AAAzE,wBAA0E;AAa1E,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
|
|
@@ -5,7 +5,7 @@ type __VLS_Props = {
|
|
|
5
5
|
props?: Record<string, unknown>;
|
|
6
6
|
/**
|
|
7
7
|
* Which custom events to forward through `elementEvent`. Defaults to the
|
|
8
|
-
* interactive aparté surface (
|
|
8
|
+
* interactive aparté surface (APARTE_DEFAULT_UI_EVENTS); pass your own list to listen to
|
|
9
9
|
* other events (e.g. ['aparte-composer-change'] for attachments).
|
|
10
10
|
*/
|
|
11
11
|
events?: string[];
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import { type Ref } from 'vue';
|
|
2
2
|
import type { AparteChatImperativeApi } from '@aparte/core';
|
|
3
3
|
import type { AparteMessage, AparteSegment } from '../types.js';
|
|
4
|
-
/**
|
|
5
|
-
* The imperative surface `<AparteChat>` exposes via `defineExpose` — the
|
|
6
|
-
* canonical contract shared by all four wrappers (`AparteChatImperativeApi`).
|
|
7
|
-
*/
|
|
8
|
-
export type AparteChatInstance = AparteChatImperativeApi;
|
|
9
4
|
/**
|
|
10
5
|
* Idiomatic Vue ergonomics for `<AparteChat>`. Owns the `messages` ref and a
|
|
11
6
|
* component template ref so the consumer skips the manual
|
|
@@ -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
|
|
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;;;;;oDAUrB,CAAC;kBAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;oDAAZ,CAAC;kBAAU,CAAC;;;;;;;;;;;;;;;;;;;;0BANjB,aAAa,EAAE;uBAMrB,aAAa;wBACZ,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,8 +1,8 @@
|
|
|
1
1
|
import { type Ref } from 'vue';
|
|
2
|
-
import { type AparteConversation, type AparteStorageAdapter } from '@aparte/core';
|
|
2
|
+
import { type AparteConfig, type AparteConversation, type AparteStorageAdapter } from '@aparte/core';
|
|
3
3
|
import type { AparteMessage } from '../types.js';
|
|
4
4
|
/**
|
|
5
|
-
* Vue-reactive wrapper around the core `
|
|
5
|
+
* Vue-reactive wrapper around the core `AparteConversationManager`. The active
|
|
6
6
|
* conversation is owned by the chat component's controller; switch by binding
|
|
7
7
|
* `conversationId` on `<AparteChat>`. Vue equivalent of Angular's
|
|
8
8
|
* `ConversationManagerService`.
|
|
@@ -13,7 +13,7 @@ export declare function useConversationManager(): {
|
|
|
13
13
|
archivedConversations: import("vue").ComputedRef<AparteConversation[]>;
|
|
14
14
|
activeId: Ref<string | null, string | null>;
|
|
15
15
|
activeConversation: import("vue").ComputedRef<AparteConversation | null>;
|
|
16
|
-
init: (adapter: AparteStorageAdapter) => Promise<void>;
|
|
16
|
+
init: (adapter: AparteStorageAdapter, config?: AparteConfig) => Promise<void>;
|
|
17
17
|
createNew: (title?: string) => Promise<AparteConversation>;
|
|
18
18
|
addMessage: (convId: string, message: AparteMessage) => Promise<void>;
|
|
19
19
|
updateMessages: (convId: string, messages: AparteMessage[]) => Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useConversationManager.d.ts","sourceRoot":"","sources":["../../src/composables/useConversationManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkC,KAAK,GAAG,EAAE,MAAM,KAAK,CAAC;AAC/D,OAAO,
|
|
1
|
+
{"version":3,"file":"useConversationManager.d.ts","sourceRoot":"","sources":["../../src/composables/useConversationManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkC,KAAK,GAAG,EAAE,MAAM,KAAK,CAAC;AAC/D,OAAO,EAEH,KAAK,YAAY,EAEjB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EAC5B,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;;;;GAKG;AACH,wBAAgB,sBAAsB;;;;;;oBAiCL,oBAAoB,WAAU,YAAY,KAAwB,OAAO,CAAC,IAAI,CAAC;wBAmBpF,MAAM;yBACL,MAAM,WAAW,aAAa;6BAC1B,MAAM,YAAY,aAAa,EAAE;iBAC7C,MAAM;kBACL,MAAM;oBACJ,MAAM;EAE7B"}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import AparteChat from './components/AparteChat.vue';
|
|
6
6
|
export { AparteChat };
|
|
7
7
|
export { useAparteChat } from './composables/useAparteChat.js';
|
|
8
|
-
export type {
|
|
8
|
+
export type { AparteChatImperativeApi } from '@aparte/core';
|
|
9
9
|
export { useAparteClient } from './composables/useAparteClient.js';
|
|
10
10
|
export { useConversationManager } from './composables/useConversationManager.js';
|
|
11
11
|
import AparteUi from './components/AparteUi.vue';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,UAAU,MAAM,6BAA6B,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,CAAC;AAGtB,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,UAAU,MAAM,6BAA6B,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,CAAC;AAGtB,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAK/D,YAAY,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAG5D,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AACjF,OAAO,QAAQ,MAAM,2BAA2B,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEhE,YAAY,EACR,aAAa,EACb,qBAAqB,EACrB,uBAAuB,EACvB,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACxB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { defineComponent, useId, ref, onMounted, toRaw, onBeforeUnmount, watch, nextTick, openBlock, createElementBlock, normalizeClass, createElementVNode, renderSlot, createCommentVNode, Fragment, renderList,
|
|
2
|
-
import { AparteChatHost, isAwaitingReply, AparteClient,
|
|
3
|
-
const _hoisted_1 = ["data-aparte-empty"];
|
|
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";
|
|
3
|
+
const _hoisted_1 = ["data-aparte-empty", "id"];
|
|
4
4
|
const _hoisted_2 = ["message-id", "data-role", "timestamp", "content", "streaming"];
|
|
5
5
|
const _hoisted_3 = ["visible", "text"];
|
|
6
|
-
const _hoisted_4 = ["^placeholder", "^disabled", "submit-on-enter"];
|
|
6
|
+
const _hoisted_4 = ["target", "^placeholder", "^disabled", "submit-on-enter"];
|
|
7
7
|
const _hoisted_5 = { class: "aparte-composer-shell" };
|
|
8
8
|
const _hoisted_6 = { key: 0 };
|
|
9
9
|
const _hoisted_7 = { class: "aparte-composer-row" };
|
|
@@ -12,6 +12,7 @@ const _hoisted_9 = { key: 1 };
|
|
|
12
12
|
const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
13
13
|
__name: "AparteChat",
|
|
14
14
|
props: {
|
|
15
|
+
id: {},
|
|
15
16
|
messages: { default: () => [] },
|
|
16
17
|
placeholder: { default: "Type a message..." },
|
|
17
18
|
disabled: { type: Boolean, default: false },
|
|
@@ -28,7 +29,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
28
29
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
29
30
|
const props = __props;
|
|
30
31
|
const emit = __emit;
|
|
31
|
-
const hostId = `aparte-chat-${useId()}`;
|
|
32
|
+
const hostId = props.id ?? `aparte-chat-${useId()}`;
|
|
32
33
|
const rootRef = ref();
|
|
33
34
|
const viewportRef = ref();
|
|
34
35
|
const composerRef = ref();
|
|
@@ -150,7 +151,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
150
151
|
class: normalizeClass(["aparte-chat-container", { "aparte-chat-container--auto-center": __props.centerWhenEmpty }]),
|
|
151
152
|
"data-aparte-chat": "",
|
|
152
153
|
"data-aparte-empty": __props.centerWhenEmpty && internalMessages.value.length === 0 ? "" : null,
|
|
153
|
-
id: hostId,
|
|
154
|
+
id: unref(hostId),
|
|
154
155
|
ref_key: "rootRef",
|
|
155
156
|
ref: rootRef
|
|
156
157
|
}, [
|
|
@@ -183,7 +184,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
183
184
|
createElementVNode("aparte-composer", {
|
|
184
185
|
ref_key: "composerRef",
|
|
185
186
|
ref: composerRef,
|
|
186
|
-
target: hostId,
|
|
187
|
+
target: unref(hostId),
|
|
187
188
|
"^placeholder": __props.placeholder,
|
|
188
189
|
"^disabled": __props.disabled ? "" : null,
|
|
189
190
|
"submit-on-enter": __props.submitOnEnter ? null : "false"
|
|
@@ -260,8 +261,8 @@ function useConversationManager() {
|
|
|
260
261
|
if (!manager) throw new Error("[useConversationManager] Not initialised. Call init(adapter) first.");
|
|
261
262
|
return manager;
|
|
262
263
|
};
|
|
263
|
-
const init = async (adapter) => {
|
|
264
|
-
const m = new
|
|
264
|
+
const init = async (adapter, config = aparteGlobalConfig) => {
|
|
265
|
+
const m = new AparteConversationManager(adapter);
|
|
265
266
|
manager = m;
|
|
266
267
|
unsub = m.subscribe((convs) => {
|
|
267
268
|
conversations.value = [...convs];
|
|
@@ -269,7 +270,7 @@ function useConversationManager() {
|
|
|
269
270
|
});
|
|
270
271
|
await m.init();
|
|
271
272
|
activeId.value = m.activeId;
|
|
272
|
-
|
|
273
|
+
config.setConversationManager(m);
|
|
273
274
|
};
|
|
274
275
|
return {
|
|
275
276
|
conversations,
|
|
@@ -297,7 +298,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
297
298
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
298
299
|
const p = __props;
|
|
299
300
|
const emit = __emit;
|
|
300
|
-
const evtsKey = computed(() => (p.events ??
|
|
301
|
+
const evtsKey = computed(() => (p.events ?? APARTE_DEFAULT_UI_EVENTS).join("|"));
|
|
301
302
|
const hostRef = ref();
|
|
302
303
|
let el = null;
|
|
303
304
|
let cleanups = [];
|
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 AparteConfigClass, type AparteChatImperativeApi } from '@aparte/core';\nimport type { AparteMessage, AparteSegment, AparteSendEventDetail, AparteActionEventDetail } from '../types.js';\n\ninterface Props {\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 * 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 /** Active conversation id (loads/persists via the registered ConversationManager). */\n conversationId?: string | null;\n /**\n * Instance {@link AparteConfigClass} for this chat. When set, aparté components\n * inside resolve THIS config instead of the global `AparteConfig` singleton, so\n * several independently-configured chats can coexist on one page. Omit for the\n * global config. Read once when the host mounts.\n */\n config?: AparteConfigClass;\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 attachments: false,\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.\nconst hostId = `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) => host?.appendMessage(m);\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 :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 :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 <!-- 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 * The imperative surface `<AparteChat>` exposes via `defineExpose` — the\n * canonical contract shared by all four wrappers (`AparteChatImperativeApi`).\n */\nexport type AparteChatInstance = AparteChatImperativeApi;\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<AparteChatInstance | 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) => c()?.appendMessage(m),\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 AparteConfig,\n ConversationManager,\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 `ConversationManager`. 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: ConversationManager | 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 = (): ConversationManager => {\n if (!manager) throw new Error('[useConversationManager] Not initialised. Call init(adapter) first.');\n return manager;\n };\n\n const init = async (adapter: AparteStorageAdapter): Promise<void> => {\n const m = new ConversationManager(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 AparteConfig.setConversationManager(m);\n };\n\n return {\n conversations,\n activeConversations,\n archivedConversations,\n activeId,\n activeConversation,\n init,\n createNew: (title?: string) => assert().createNew(title),\n addMessage: (convId: string, message: AparteMessage) => assert().addMessage(convId, message),\n updateMessages: (convId: string, messages: AparteMessage[]) => assert().updateMessages(convId, messages),\n delete: (id: string) => assert().delete(id),\n archive: (id: string) => assert().archive(id),\n unarchive: (id: string) => assert().unarchive(id),\n };\n}\n","<script setup lang=\"ts\">\nimport { ref, computed, watch, onMounted, onBeforeUnmount, toRaw } from 'vue';\nimport { applyElementProps, DEFAULT_UI_EVENTS } from '@aparte/core';\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 (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 ?? 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\ndefineExpose({\n getElement: () => el,\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;\n },\n});\n</script>\n\n<template>\n <span ref=\"hostRef\" style=\"display: contents\"></span>\n</template>\n"],"names":["_createElementBlock","_createElementVNode","_renderSlot","_Fragment","_renderList","_unref","$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, 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 /**\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 /** 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 attachments: false,\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) => host?.appendMessage(m);\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 :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 :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 <!-- 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) => c()?.appendMessage(m),\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 };\n}\n","<script setup lang=\"ts\">\nimport { ref, computed, watch, onMounted, onBeforeUnmount, toRaw } from 'vue';\nimport { applyElementProps, APARTE_DEFAULT_UI_EVENTS } from '@aparte/core';\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\ndefineExpose({\n getElement: () => el,\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;\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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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export interface AparteUiProps {
|
|
|
13
13
|
props?: Record<string, unknown>;
|
|
14
14
|
/**
|
|
15
15
|
* Which custom events to forward through `elementEvent`. Defaults to the
|
|
16
|
-
* interactive aparté surface (`
|
|
16
|
+
* interactive aparté surface (`APARTE_DEFAULT_UI_EVENTS` from `@aparte/core`).
|
|
17
17
|
*/
|
|
18
18
|
events?: string[];
|
|
19
19
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aparte/vue",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Vue 3 wrapper for aparté — an ergonomic <AparteChat> component plus composables over the framework-agnostic web components.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"node": ">=18"
|
|
25
25
|
},
|
|
26
26
|
"peerDependencies": {
|
|
27
|
-
"@aparte/core": ">=0.
|
|
27
|
+
"@aparte/core": ">=0.7.0 <1.0.0",
|
|
28
28
|
"vue": "^3.5.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"vite": "^6.0.0",
|
|
36
36
|
"vue": "^3.5.0",
|
|
37
37
|
"vue-tsc": "^2.0.0",
|
|
38
|
-
"@aparte/core": "0.
|
|
38
|
+
"@aparte/core": "0.9.0"
|
|
39
39
|
},
|
|
40
40
|
"keywords": [
|
|
41
41
|
"vue",
|