@aparte/svelte 0.24.0 → 0.26.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/README.md +5 -0
- package/dist/AparteChat.svelte +301 -226
- package/dist/AparteChat.svelte.d.ts +136 -133
- package/dist/AparteUi.svelte +82 -52
- package/dist/AparteUi.svelte.d.ts +36 -33
- package/dist/elements.d.ts +44 -0
- package/dist/elements.d.ts.map +1 -0
- package/dist/elements.js +1 -0
- package/dist/index.d.ts +1 -38
- package/dist/index.d.ts.map +1 -1
- package/dist/runes/AparteChat.svelte +304 -0
- package/dist/runes/AparteChat.svelte.d.ts +32 -0
- package/dist/runes/AparteSegmentUI.svelte +35 -0
- package/dist/runes/AparteSegmentUI.svelte.d.ts +38 -0
- package/dist/runes/AparteToolUI.svelte +44 -0
- package/dist/runes/AparteToolUI.svelte.d.ts +44 -0
- package/dist/runes/AparteUi.svelte +68 -0
- package/dist/runes/AparteUi.svelte.d.ts +16 -0
- package/dist/runes/SnippetHost.svelte +11 -0
- package/dist/runes/SnippetHost.svelte.d.ts +32 -0
- package/dist/runes/conversations.svelte.d.ts +42 -0
- package/dist/runes/conversations.svelte.d.ts.map +1 -0
- package/dist/runes/conversations.svelte.js +66 -0
- package/dist/runes/index.d.ts +18 -0
- package/dist/runes/index.d.ts.map +1 -0
- package/dist/runes/index.js +12 -0
- package/dist/runes/mount-snippet.svelte.d.ts +10 -0
- package/dist/runes/mount-snippet.svelte.d.ts.map +1 -0
- package/dist/runes/mount-snippet.svelte.js +24 -0
- package/dist/runes/types.d.ts +68 -0
- package/dist/runes/types.d.ts.map +1 -0
- package/dist/runes/types.js +1 -0
- package/dist/stores/aparteChat.d.ts +4 -0
- package/dist/stores/aparteChat.d.ts.map +1 -1
- package/dist/stores/aparteChat.js +4 -0
- package/dist/stores/aparteClient.d.ts +5 -0
- package/dist/stores/aparteClient.d.ts.map +1 -1
- package/dist/stores/aparteClient.js +5 -0
- package/dist/stores/conversationManager.d.ts +4 -0
- package/dist/stores/conversationManager.d.ts.map +1 -1
- package/dist/stores/conversationManager.js +4 -0
- package/package.json +19 -8
|
@@ -1,143 +1,146 @@
|
|
|
1
|
-
import { SvelteComponent } from "svelte";
|
|
2
1
|
import { type AparteConfig } from '@aparte/core';
|
|
3
2
|
import type { AparteMessage, AparteSegment, AparteSendEventDetail, AparteActionEventDetail } from './types.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
disabled?: boolean;
|
|
15
|
-
isTyping?: boolean;
|
|
16
|
-
typingText?: string | undefined;
|
|
17
|
-
/** When false, Shift+Enter submits and a bare Enter inserts a newline. */ submitOnEnter?: boolean;
|
|
18
|
-
/** Freeze viewport spacer recalculation for this many ms after a conv swap. */ layoutTransitionMs?: number;
|
|
19
|
-
/**
|
|
20
|
-
* Opt in to the "centered composer when empty" layout: the composer sits
|
|
21
|
-
* vertically centered with the `empty-state` slot above it while the list is
|
|
22
|
-
* empty, then slides to the bottom on the first message (~0.3s). Off by
|
|
23
|
-
* default — additive.
|
|
24
|
-
*/ centerWhenEmpty?: boolean;
|
|
25
|
-
/**
|
|
26
|
-
* The conversation is on its way: the viewport draws two skeleton turns, the empty
|
|
27
|
-
* state stays off and the composer is disabled until it lands. The conversation
|
|
28
|
-
* controller sets this itself while it fetches through your adapter's `loadFull()`;
|
|
29
|
-
* the prop is for a wait of your own. Off by default.
|
|
30
|
-
*/ loading?: boolean;
|
|
31
|
-
/** Overlay the composer on the transcript: full-column scroll surface, edge-to-edge scrollbar, floating composer. Read when the viewport mounts. */ overlayComposer?: boolean;
|
|
32
|
-
/**
|
|
33
|
-
* Add the file picker + chips strip to the default composer shell. **Off by
|
|
34
|
-
* default**, because the capability needs a host that consumes the files: an
|
|
35
|
-
* `AparteClient` inlines them per its `rawFileInject` option, but if you drive
|
|
36
|
-
* your own loop you must read `event.files` on `messageSent` — otherwise the file
|
|
37
|
-
* the user deliberately attached is dropped in silence. No effect when you fill
|
|
38
|
-
* the `composer` slot (drop `<aparte-composer-add-attachment>` and
|
|
39
|
-
* `<aparte-composer-attachments>` in it yourself).
|
|
40
|
-
*/ attachments?: boolean;
|
|
41
|
-
/**
|
|
42
|
-
* Render the `<aparte-elicitation>` presenter inside the host — on by default, as it
|
|
43
|
-
* is in `<aparte-chat>`: the built-in approval gate and `requestUserInput()` ask
|
|
44
|
-
* through it, and it renders nothing until something asks. Pass `false` when you
|
|
45
|
-
* mount a presenter of your own (`setElicitationPresenter`) or place the element
|
|
46
|
-
* yourself.
|
|
47
|
-
*/ elicitation?: boolean;
|
|
48
|
-
/** Extra class names for the root element (`[data-aparte-chat]`), merged after core's own. */ class?: string;
|
|
49
|
-
/** Inline style for the root element (`[data-aparte-chat]`). */ style?: string | undefined;
|
|
50
|
-
/** Active conversation id (loads/persists via the registered AparteConversationManager). */ conversationId?: string | null;
|
|
51
|
-
/**
|
|
52
|
-
* Instance {@link AparteConfig} for this chat. When set, aparté components
|
|
53
|
-
* inside resolve THIS config instead of `aparteGlobalConfig`, so
|
|
54
|
-
* several independently-configured chats can coexist on one page. Omit for the
|
|
55
|
-
* global config. Read once when the host mounts.
|
|
56
|
-
*/ config?: AparteConfig | undefined;
|
|
57
|
-
/** User submitted a message from the composer — see `messageSent` below for the append rule. */ onmessageSent?: ((detail: AparteSendEventDetail) => void) | undefined;
|
|
58
|
-
/** A custom bubble action (registerBubbleAction) was clicked. */ onaction?: ((detail: AparteActionEventDetail) => void) | undefined;
|
|
59
|
-
/** Active path changed — the list to bind back to `messages`. */ onmessagesChange?: ((messages: AparteMessage[]) => void) | undefined;
|
|
60
|
-
/** One message was appended. */ onmessageAppended?: ((message: AparteMessage) => void) | undefined;
|
|
61
|
-
/** The typing/"thinking" indicator toggled. */ ontypingChange?: ((typing: boolean) => void) | undefined;
|
|
62
|
-
/** The host created a conversation id (persistence). */ onconversationCreated?: ((id: string) => void) | undefined;
|
|
63
|
-
appendMessage?: (m: AparteMessage, options?: {
|
|
64
|
-
historical?: boolean;
|
|
65
|
-
}) => void;
|
|
66
|
-
updateMessage?: (id: string, u: Partial<AparteMessage>) => void;
|
|
67
|
-
updateLastMessage?: (content: string, options?: {
|
|
68
|
-
append?: boolean;
|
|
69
|
-
}) => void;
|
|
70
|
-
addSegment?: (segment: AparteSegment) => void;
|
|
71
|
-
updateSegment?: (segmentId: string, updates: Partial<AparteSegment>) => void;
|
|
72
|
-
removeSegment?: (segmentId: string) => void;
|
|
73
|
-
appendToSegment?: (segmentId: string, content: string) => void;
|
|
74
|
-
getMessages?: () => AparteMessage[];
|
|
75
|
-
clearMessages?: (options?: {
|
|
76
|
-
revokeAttachments?: boolean;
|
|
77
|
-
}) => void;
|
|
78
|
-
addBranch?: (messageId: string) => number;
|
|
79
|
-
addSiblingOf?: (existingId: string, message: AparteMessage) => string | null;
|
|
80
|
-
truncateFrom?: (messageId: string) => void;
|
|
81
|
-
truncateResponsesAfter?: (userMessageId: string) => void;
|
|
82
|
-
injectTokenStream?: (messageId: string, tokens: AsyncIterable<string>) => Promise<void>;
|
|
83
|
-
stopTokenStream?: () => void;
|
|
84
|
-
setConversationId?: (id: string | null) => Promise<void>;
|
|
85
|
-
scrollToBottom?: () => void;
|
|
86
|
-
getViewport?: () => HTMLElement | null;
|
|
87
|
-
focusInput?: () => void;
|
|
88
|
-
isStreaming?: () => boolean;
|
|
3
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
4
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
5
|
+
$$bindings?: Bindings;
|
|
6
|
+
} & Exports;
|
|
7
|
+
(internal: unknown, props: Props & {
|
|
8
|
+
$$events?: Events;
|
|
9
|
+
$$slots?: Slots;
|
|
10
|
+
}): Exports & {
|
|
11
|
+
$set?: any;
|
|
12
|
+
$on?: any;
|
|
89
13
|
};
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
14
|
+
z_$$bindings?: Bindings;
|
|
15
|
+
}
|
|
16
|
+
declare const AparteChat: $$__sveltets_2_IsomorphicComponent<{
|
|
17
|
+
/**
|
|
18
|
+
* The host element's `id`, and therefore the `targetId` every event this chat
|
|
19
|
+
* dispatches carries. Generated when omitted — but it used to be generated and
|
|
20
|
+
* neither accepted nor exposed, which made `scopeToTargetId` unreachable from
|
|
21
|
+
* this component.
|
|
22
|
+
*/ id?: string | undefined;
|
|
23
|
+
messages?: AparteMessage[];
|
|
24
|
+
placeholder?: string;
|
|
25
|
+
disabled?: boolean;
|
|
26
|
+
isTyping?: boolean;
|
|
27
|
+
typingText?: string | undefined;
|
|
28
|
+
/** When false, Shift+Enter submits and a bare Enter inserts a newline. */ submitOnEnter?: boolean;
|
|
29
|
+
/** Freeze viewport spacer recalculation for this many ms after a conv swap. */ layoutTransitionMs?: number;
|
|
30
|
+
/**
|
|
31
|
+
* Opt in to the "centered composer when empty" layout: the composer sits
|
|
32
|
+
* vertically centered with the `empty-state` slot above it while the list is
|
|
33
|
+
* empty, then slides to the bottom on the first message (~0.3s). Off by
|
|
34
|
+
* default — additive.
|
|
35
|
+
*/ centerWhenEmpty?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* The conversation is on its way: the viewport draws two skeleton turns, the empty
|
|
38
|
+
* state stays off and the composer is disabled until it lands. The conversation
|
|
39
|
+
* controller sets this itself while it fetches through your adapter's `loadFull()`;
|
|
40
|
+
* the prop is for a wait of your own. Off by default.
|
|
41
|
+
*/ loading?: boolean;
|
|
42
|
+
/** Overlay the composer on the transcript: full-column scroll surface, edge-to-edge scrollbar, floating composer. Read when the viewport mounts. */ overlayComposer?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Add the file picker + chips strip to the default composer shell. **Off by
|
|
45
|
+
* default**, because the capability needs a host that consumes the files: an
|
|
46
|
+
* `AparteClient` inlines them per its `rawFileInject` option, but if you drive
|
|
47
|
+
* your own loop you must read `event.files` on `messageSent` — otherwise the file
|
|
48
|
+
* the user deliberately attached is dropped in silence. No effect when you fill
|
|
49
|
+
* the `composer` slot (drop `<aparte-composer-add-attachment>` and
|
|
50
|
+
* `<aparte-composer-attachments>` in it yourself).
|
|
51
|
+
*/ attachments?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Render the `<aparte-elicitation>` presenter inside the host — on by default, as it
|
|
54
|
+
* is in `<aparte-chat>`: the built-in approval gate and `requestUserInput()` ask
|
|
55
|
+
* through it, and it renders nothing until something asks. Pass `false` when you
|
|
56
|
+
* mount a presenter of your own (`setElicitationPresenter`) or place the element
|
|
57
|
+
* yourself.
|
|
58
|
+
*/ elicitation?: boolean;
|
|
59
|
+
/** Extra class names for the root element (`[data-aparte-chat]`), merged after core's own. */ class?: string;
|
|
60
|
+
/** Inline style for the root element (`[data-aparte-chat]`). */ style?: string | undefined;
|
|
61
|
+
/** Active conversation id (loads/persists via the registered AparteConversationManager). */ conversationId?: string | null;
|
|
62
|
+
/**
|
|
63
|
+
* Instance {@link AparteConfig} for this chat. When set, aparté components
|
|
64
|
+
* inside resolve THIS config instead of `aparteGlobalConfig`, so
|
|
65
|
+
* several independently-configured chats can coexist on one page. Omit for the
|
|
66
|
+
* global config. Read once when the host mounts.
|
|
67
|
+
*/ config?: AparteConfig | undefined;
|
|
68
|
+
/** User submitted a message from the composer — see `messageSent` below for the append rule. */ onmessageSent?: ((detail: AparteSendEventDetail) => void) | undefined;
|
|
69
|
+
/** A custom bubble action (registerBubbleAction) was clicked. */ onaction?: ((detail: AparteActionEventDetail) => void) | undefined;
|
|
70
|
+
/** Active path changed — the list to bind back to `messages`. */ onmessagesChange?: ((messages: AparteMessage[]) => void) | undefined;
|
|
71
|
+
/** One message was appended. */ onmessageAppended?: ((message: AparteMessage) => void) | undefined;
|
|
72
|
+
/** The typing/"thinking" indicator toggled. */ ontypingChange?: ((typing: boolean) => void) | undefined;
|
|
73
|
+
/** The host created a conversation id (persistence). */ onconversationCreated?: ((id: string) => void) | undefined;
|
|
74
|
+
appendMessage?: (m: AparteMessage, options?: {
|
|
75
|
+
historical?: boolean;
|
|
76
|
+
}) => void;
|
|
77
|
+
updateMessage?: (id: string, u: Partial<AparteMessage>) => void;
|
|
78
|
+
updateLastMessage?: (content: string, options?: {
|
|
79
|
+
append?: boolean;
|
|
80
|
+
}) => void;
|
|
81
|
+
addSegment?: (segment: AparteSegment) => void;
|
|
82
|
+
updateSegment?: (segmentId: string, updates: Partial<AparteSegment>) => void;
|
|
83
|
+
removeSegment?: (segmentId: string) => void;
|
|
84
|
+
appendToSegment?: (segmentId: string, content: string) => void;
|
|
85
|
+
getMessages?: () => AparteMessage[];
|
|
86
|
+
clearMessages?: (options?: {
|
|
87
|
+
revokeAttachments?: boolean;
|
|
88
|
+
}) => void;
|
|
89
|
+
addBranch?: (messageId: string) => number;
|
|
90
|
+
addSiblingOf?: (existingId: string, message: AparteMessage) => string | null;
|
|
91
|
+
truncateFrom?: (messageId: string) => void;
|
|
92
|
+
truncateResponsesAfter?: (userMessageId: string) => void;
|
|
93
|
+
injectTokenStream?: (messageId: string, tokens: AsyncIterable<string>) => Promise<void>;
|
|
94
|
+
stopTokenStream?: () => void;
|
|
95
|
+
setConversationId?: (id: string | null) => Promise<void>;
|
|
96
|
+
scrollToBottom?: () => void;
|
|
97
|
+
getViewport?: () => HTMLElement | null;
|
|
98
|
+
focusInput?: () => void;
|
|
99
|
+
isStreaming?: () => boolean;
|
|
100
|
+
}, {
|
|
101
|
+
messageSent: CustomEvent<AparteSendEventDetail>;
|
|
102
|
+
action: CustomEvent<AparteActionEventDetail>;
|
|
103
|
+
messagesChange: CustomEvent<AparteMessage[]>;
|
|
104
|
+
messageAppended: CustomEvent<AparteMessage>;
|
|
105
|
+
typingChange: CustomEvent<boolean>;
|
|
106
|
+
conversationCreated: CustomEvent<string>;
|
|
107
|
+
} & {
|
|
108
|
+
[evt: string]: CustomEvent<any>;
|
|
109
|
+
}, {
|
|
110
|
+
'empty-state': {};
|
|
111
|
+
bubble: {
|
|
112
|
+
message: AparteMessage;
|
|
108
113
|
};
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
export type AparteChatSlots = typeof __propDef.slots;
|
|
115
|
-
export default class AparteChat extends SvelteComponent<AparteChatProps, AparteChatEvents, AparteChatSlots> {
|
|
116
|
-
get appendMessage(): (m: AparteMessage, options?: {
|
|
114
|
+
'above-composer': {};
|
|
115
|
+
composer: {};
|
|
116
|
+
toolbar: {};
|
|
117
|
+
}, {
|
|
118
|
+
appendMessage: (m: AparteMessage, options?: {
|
|
117
119
|
historical?: boolean;
|
|
118
120
|
}) => void;
|
|
119
|
-
|
|
120
|
-
|
|
121
|
+
updateMessage: (id: string, u: Partial<AparteMessage>) => void;
|
|
122
|
+
updateLastMessage: (content: string, options?: {
|
|
121
123
|
append?: boolean;
|
|
122
124
|
}) => void;
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
125
|
+
addSegment: (segment: AparteSegment) => void;
|
|
126
|
+
updateSegment: (segmentId: string, updates: Partial<AparteSegment>) => void;
|
|
127
|
+
removeSegment: (segmentId: string) => void;
|
|
128
|
+
appendToSegment: (segmentId: string, content: string) => void;
|
|
129
|
+
getMessages: () => AparteMessage[];
|
|
130
|
+
clearMessages: (options?: {
|
|
129
131
|
revokeAttachments?: boolean;
|
|
130
132
|
}) => void;
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
}
|
|
143
|
-
|
|
133
|
+
addBranch: (messageId: string) => number;
|
|
134
|
+
addSiblingOf: (existingId: string, message: AparteMessage) => string | null;
|
|
135
|
+
truncateFrom: (messageId: string) => void;
|
|
136
|
+
truncateResponsesAfter: (userMessageId: string) => void;
|
|
137
|
+
injectTokenStream: (messageId: string, tokens: AsyncIterable<string>) => Promise<void>;
|
|
138
|
+
stopTokenStream: () => void;
|
|
139
|
+
setConversationId: (id: string | null) => Promise<void>;
|
|
140
|
+
scrollToBottom: () => void;
|
|
141
|
+
getViewport: () => HTMLElement | null;
|
|
142
|
+
focusInput: () => void;
|
|
143
|
+
isStreaming: () => boolean;
|
|
144
|
+
}, string>;
|
|
145
|
+
type AparteChat = InstanceType<typeof AparteChat>;
|
|
146
|
+
export default AparteChat;
|
package/dist/AparteUi.svelte
CHANGED
|
@@ -1,57 +1,87 @@
|
|
|
1
|
-
<script
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export let
|
|
7
|
-
|
|
8
|
-
let
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onMount, onDestroy, createEventDispatcher } from 'svelte';
|
|
3
|
+
import { applyElementProps, APARTE_DEFAULT_UI_EVENTS } from '@aparte/core';
|
|
4
|
+
|
|
5
|
+
/** The custom element tag name (e.g. 'aparte-model-selector'). */
|
|
6
|
+
export let name: string;
|
|
7
|
+
/** Props to apply. Keys starting with `--` become CSS variables. */
|
|
8
|
+
export let props: Record<string, unknown> = {};
|
|
9
|
+
/**
|
|
10
|
+
* Which custom events to forward through `elementEvent`. Defaults to the
|
|
11
|
+
* interactive aparté surface (APARTE_DEFAULT_UI_EVENTS); pass your own list to listen to
|
|
12
|
+
* other events (e.g. ['aparte-composer-change'] for attachments).
|
|
13
|
+
*/
|
|
14
|
+
export let events: string[] | undefined = undefined;
|
|
15
|
+
/**
|
|
16
|
+
* Callback prop for the same forwarding as the `elementEvent` component event (#47):
|
|
17
|
+
* called with the element's own CustomEvent, then the event is dispatched. The path
|
|
18
|
+
* Svelte 5 recommends over `createEventDispatcher`; Svelte 4 keeps `on:elementEvent`.
|
|
19
|
+
*/
|
|
20
|
+
export let onelementEvent: ((event: CustomEvent) => void) | undefined = undefined;
|
|
21
|
+
|
|
22
|
+
const dispatch = createEventDispatcher<{ elementEvent: CustomEvent }>();
|
|
23
|
+
|
|
24
|
+
let host: HTMLElement;
|
|
25
|
+
let el: HTMLElement | null = null;
|
|
26
|
+
let cleanups: Array<() => void> = [];
|
|
27
|
+
|
|
28
|
+
function applyProps() {
|
|
29
|
+
if (el) applyElementProps(el, props);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function create() {
|
|
33
|
+
if (!host) return;
|
|
34
|
+
el = document.createElement(name);
|
|
35
|
+
applyProps();
|
|
36
|
+
for (const ev of events ?? APARTE_DEFAULT_UI_EVENTS) {
|
|
37
|
+
const listener = (e: Event) => { onelementEvent?.(e as CustomEvent); dispatch('elementEvent', e as CustomEvent); };
|
|
38
|
+
el.addEventListener(ev, listener);
|
|
39
|
+
cleanups.push(() => el?.removeEventListener(ev, listener));
|
|
40
|
+
}
|
|
41
|
+
host.appendChild(el);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function destroy() {
|
|
45
|
+
for (const c of cleanups) c();
|
|
46
|
+
cleanups = [];
|
|
47
|
+
el?.remove();
|
|
48
|
+
el = null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
onMount(create);
|
|
52
|
+
onDestroy(destroy);
|
|
53
|
+
|
|
54
|
+
// Recreate the element when `name` (or the forwarded event set) changes. A
|
|
55
|
+
// joined key so a fresh inline `events` array doesn't thrash the element.
|
|
56
|
+
let lastName = name;
|
|
57
|
+
let lastEvtsKey = (events ?? APARTE_DEFAULT_UI_EVENTS).join('|');
|
|
58
|
+
$: {
|
|
59
|
+
const evtsKey = (events ?? APARTE_DEFAULT_UI_EVENTS).join('|');
|
|
60
|
+
if (el && (name !== lastName || evtsKey !== lastEvtsKey)) {
|
|
61
|
+
lastName = name;
|
|
62
|
+
lastEvtsKey = evtsKey;
|
|
63
|
+
destroy();
|
|
64
|
+
create();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
$: if (el && props) applyProps();
|
|
68
|
+
|
|
69
|
+
/*
|
|
70
|
+
* Generic, to honour `AparteUiHandle` — which this package exports with a docblock
|
|
71
|
+
* promising "the same contract on all four wrappers", and which React and Angular both
|
|
72
|
+
* honour. These two used to return `HTMLElement | null` and `unknown`, so a consumer
|
|
73
|
+
* following the documented `bind:this` pattern got a type error here and none there.
|
|
74
|
+
* A cold audit compiled it and produced the real TS2322 rather than reporting a doubt.
|
|
75
|
+
*/
|
|
76
|
+
export function getElement<T extends HTMLElement = HTMLElement>(): T | null {
|
|
77
|
+
return el as T | null;
|
|
25
78
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
function
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
el?.remove();
|
|
32
|
-
el = null;
|
|
33
|
-
}
|
|
34
|
-
onMount(create);
|
|
35
|
-
onDestroy(destroy);
|
|
36
|
-
let lastName = name;
|
|
37
|
-
let lastEvtsKey = (events ?? APARTE_DEFAULT_UI_EVENTS).join("|");
|
|
38
|
-
$: {
|
|
39
|
-
const evtsKey = (events ?? APARTE_DEFAULT_UI_EVENTS).join("|");
|
|
40
|
-
if (el && (name !== lastName || evtsKey !== lastEvtsKey)) {
|
|
41
|
-
lastName = name;
|
|
42
|
-
lastEvtsKey = evtsKey;
|
|
43
|
-
destroy();
|
|
44
|
-
create();
|
|
79
|
+
export function callMethod<T = unknown>(methodName: string, ...args: unknown[]): T | undefined {
|
|
80
|
+
const fn = (el as unknown as Record<string, unknown>)?.[methodName];
|
|
81
|
+
return (typeof fn === 'function' ? (fn as (...a: unknown[]) => unknown).apply(el, args) : undefined) as
|
|
82
|
+
| T
|
|
83
|
+
| undefined;
|
|
45
84
|
}
|
|
46
|
-
}
|
|
47
|
-
$: if (el && props) applyProps();
|
|
48
|
-
export function getElement() {
|
|
49
|
-
return el;
|
|
50
|
-
}
|
|
51
|
-
export function callMethod(methodName, ...args) {
|
|
52
|
-
const fn = el?.[methodName];
|
|
53
|
-
return typeof fn === "function" ? fn.apply(el, args) : void 0;
|
|
54
|
-
}
|
|
55
85
|
</script>
|
|
56
86
|
|
|
57
87
|
<span bind:this={host} style="display: contents"></span>
|
|
@@ -1,35 +1,38 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Callback prop for the same forwarding as the `elementEvent` component event (#47):
|
|
13
|
-
* called with the element's own CustomEvent, then the event is dispatched. The path
|
|
14
|
-
* Svelte 5 recommends over `createEventDispatcher`; Svelte 4 keeps `on:elementEvent`.
|
|
15
|
-
*/ onelementEvent?: ((event: CustomEvent) => void) | undefined;
|
|
16
|
-
getElement?: <T extends HTMLElement = HTMLElement>() => T | null;
|
|
17
|
-
callMethod?: <T = unknown>(methodName: string, ...args: unknown[]) => T | undefined;
|
|
1
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: Props & {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
18
11
|
};
|
|
19
|
-
|
|
20
|
-
elementEvent: CustomEvent<CustomEvent<any>>;
|
|
21
|
-
} & {
|
|
22
|
-
[evt: string]: CustomEvent<any>;
|
|
23
|
-
};
|
|
24
|
-
slots: {};
|
|
25
|
-
exports?: {} | undefined;
|
|
26
|
-
bindings?: string | undefined;
|
|
27
|
-
};
|
|
28
|
-
export type AparteUiProps = typeof __propDef.props;
|
|
29
|
-
export type AparteUiEvents = typeof __propDef.events;
|
|
30
|
-
export type AparteUiSlots = typeof __propDef.slots;
|
|
31
|
-
export default class AparteUi extends SvelteComponent<AparteUiProps, AparteUiEvents, AparteUiSlots> {
|
|
32
|
-
get getElement(): <T extends HTMLElement = HTMLElement>() => T | null;
|
|
33
|
-
get callMethod(): <T = unknown>(methodName: string, ...args: unknown[]) => T | undefined;
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
34
13
|
}
|
|
35
|
-
|
|
14
|
+
declare const AparteUi: $$__sveltets_2_IsomorphicComponent<{
|
|
15
|
+
/** The custom element tag name (e.g. 'aparte-model-selector'). */ name: string;
|
|
16
|
+
/** Props to apply. Keys starting with `--` become CSS variables. */ props?: Record<string, unknown>;
|
|
17
|
+
/**
|
|
18
|
+
* Which custom events to forward through `elementEvent`. Defaults to the
|
|
19
|
+
* interactive aparté surface (APARTE_DEFAULT_UI_EVENTS); pass your own list to listen to
|
|
20
|
+
* other events (e.g. ['aparte-composer-change'] for attachments).
|
|
21
|
+
*/ events?: string[] | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Callback prop for the same forwarding as the `elementEvent` component event (#47):
|
|
24
|
+
* called with the element's own CustomEvent, then the event is dispatched. The path
|
|
25
|
+
* Svelte 5 recommends over `createEventDispatcher`; Svelte 4 keeps `on:elementEvent`.
|
|
26
|
+
*/ onelementEvent?: ((event: CustomEvent) => void) | undefined;
|
|
27
|
+
getElement?: <T extends HTMLElement = HTMLElement>() => T | null;
|
|
28
|
+
callMethod?: <T = unknown>(methodName: string, ...args: unknown[]) => T | undefined;
|
|
29
|
+
}, {
|
|
30
|
+
elementEvent: CustomEvent<CustomEvent<any>>;
|
|
31
|
+
} & {
|
|
32
|
+
[evt: string]: CustomEvent<any>;
|
|
33
|
+
}, {}, {
|
|
34
|
+
getElement: <T extends HTMLElement = HTMLElement>() => T | null;
|
|
35
|
+
callMethod: <T = unknown>(methodName: string, ...args: unknown[]) => T | undefined;
|
|
36
|
+
}, string>;
|
|
37
|
+
type AparteUi = InstanceType<typeof AparteUi>;
|
|
38
|
+
export default AparteUi;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every element of core typed for a Svelte template — loaded by both entries, `@aparte/svelte`
|
|
3
|
+
* and `@aparte/svelte/runes`, so a Svelte 5 app importing only the runes entry has it too.
|
|
4
|
+
*/
|
|
5
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
6
|
+
import type { AparteElementAttributes, AparteElementTagName, AparteTemplateAttrs, AparteUiEventName } from '@aparte/core';
|
|
7
|
+
/**
|
|
8
|
+
* Svelte's `on:` handlers, for every event aparté dispatches.
|
|
9
|
+
*
|
|
10
|
+
* Derived from TWO sources, and it needs both. `HTMLElementEventMap` — which
|
|
11
|
+
* `@aparte/core` augments — carries the events with a detail. It deliberately omits the
|
|
12
|
+
* five that have none (`aparte-cancel`, `aparte-composer-submit`, `aparte-reset-done`,
|
|
13
|
+
* `aparte-select-open`, `aparte-select-close`), because a map entry would type
|
|
14
|
+
* `e.detail` as `null` and gain nothing.
|
|
15
|
+
*
|
|
16
|
+
* That omission was harmless while it only governed `addEventListener`. Declaring the
|
|
17
|
+
* tags here made it a regression: `SvelteHTMLElements` used to end in a catch-all index
|
|
18
|
+
* signature that accepted any `on:` name, and narrowing the tags removed it — so
|
|
19
|
+
* `on:aparte-cancel`, the STOP BUTTON, stopped type-checking. A typed surface that takes
|
|
20
|
+
* a capability away is worse than no typed surface.
|
|
21
|
+
*
|
|
22
|
+
* `AparteUiEventName` closes it: core's proxy list already enumerates every event an
|
|
23
|
+
* element dispatches on itself, those five included, and it is the list `AparteUi`
|
|
24
|
+
* forwards — so the two are the same set by construction. Still no hand-written list
|
|
25
|
+
* here, which is the property that mattered.
|
|
26
|
+
*/
|
|
27
|
+
type AparteEventName = Extract<keyof HTMLElementEventMap, `aparte-${string}`>;
|
|
28
|
+
type AparteAnyEventName = AparteEventName | AparteUiEventName;
|
|
29
|
+
/** The typed event for a name, or a detail-free `CustomEvent` when the map has none. */
|
|
30
|
+
type AparteEventFor<K extends string> = K extends keyof HTMLElementEventMap ? HTMLElementEventMap[K] : CustomEvent<null>;
|
|
31
|
+
type AparteSvelteHandlers = {
|
|
32
|
+
[K in AparteAnyEventName as `on:${K}`]?: (event: AparteEventFor<K>) => void;
|
|
33
|
+
} & {
|
|
34
|
+
[K in AparteAnyEventName as `on${K}`]?: (event: AparteEventFor<K>) => void;
|
|
35
|
+
};
|
|
36
|
+
export type AparteSvelteElements = {
|
|
37
|
+
[K in AparteElementTagName]: HTMLAttributes<HTMLElement> & AparteTemplateAttrs<AparteElementAttributes[K]> & AparteSvelteHandlers;
|
|
38
|
+
};
|
|
39
|
+
declare module 'svelte/elements' {
|
|
40
|
+
interface SvelteHTMLElements extends AparteSvelteElements {
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export {};
|
|
44
|
+
//# sourceMappingURL=elements.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"elements.d.ts","sourceRoot":"","sources":["../src/lib/elements.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAgBH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAE1H;;;;;;;;;;;;;;;;;;;GAmBG;AACH,KAAK,eAAe,GAAG,OAAO,CAAC,MAAM,mBAAmB,EAAE,UAAU,MAAM,EAAE,CAAC,CAAC;AAC9E,KAAK,kBAAkB,GAAG,eAAe,GAAG,iBAAiB,CAAC;AAE9D,wFAAwF;AACxF,KAAK,cAAc,CAAC,CAAC,SAAS,MAAM,IAChC,CAAC,SAAS,MAAM,mBAAmB,GAAG,mBAAmB,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;AAErF,KAAK,oBAAoB,GAAG;KACvB,CAAC,IAAI,kBAAkB,IAAI,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,KAAK,IAAI;CAC9E,GAAG;KAGC,CAAC,IAAI,kBAAkB,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,KAAK,IAAI;CAC7E,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;KAC9B,CAAC,IAAI,oBAAoB,GACtB,cAAc,CAAC,WAAW,CAAC,GACzB,mBAAmB,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,GAC/C,oBAAoB;CAC7B,CAAC;AAEF,OAAO,QAAQ,iBAAiB,CAAC;IAC7B,UAAU,kBAAmB,SAAQ,oBAAoB;KAAG;CAC/D"}
|
package/dist/elements.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -14,42 +14,5 @@ export { createConversationManager } from './stores/conversationManager.js';
|
|
|
14
14
|
export { default as AparteUi } from './AparteUi.svelte';
|
|
15
15
|
export type { AparteUiProps, AparteUiHandle } from './types.js';
|
|
16
16
|
export type { AparteMessage, AparteSendEventDetail, AparteActionEventDetail, AparteSegment, AparteTextSegment, AparteCodeSegment, AparteThinkingSegment } from './types.js';
|
|
17
|
-
|
|
18
|
-
import type { AparteElementAttributes, AparteElementTagName, AparteTemplateAttrs, AparteUiEventName } from '@aparte/core';
|
|
19
|
-
/**
|
|
20
|
-
* Svelte's `on:` handlers, for every event aparté dispatches.
|
|
21
|
-
*
|
|
22
|
-
* Derived from TWO sources, and it needs both. `HTMLElementEventMap` — which
|
|
23
|
-
* `@aparte/core` augments — carries the events with a detail. It deliberately omits the
|
|
24
|
-
* five that have none (`aparte-cancel`, `aparte-composer-submit`, `aparte-reset-done`,
|
|
25
|
-
* `aparte-select-open`, `aparte-select-close`), because a map entry would type
|
|
26
|
-
* `e.detail` as `null` and gain nothing.
|
|
27
|
-
*
|
|
28
|
-
* That omission was harmless while it only governed `addEventListener`. Declaring the
|
|
29
|
-
* tags here made it a regression: `SvelteHTMLElements` used to end in a catch-all index
|
|
30
|
-
* signature that accepted any `on:` name, and narrowing the tags removed it — so
|
|
31
|
-
* `on:aparte-cancel`, the STOP BUTTON, stopped type-checking. A typed surface that takes
|
|
32
|
-
* a capability away is worse than no typed surface.
|
|
33
|
-
*
|
|
34
|
-
* `AparteUiEventName` closes it: core's proxy list already enumerates every event an
|
|
35
|
-
* element dispatches on itself, those five included, and it is the list `AparteUi`
|
|
36
|
-
* forwards — so the two are the same set by construction. Still no hand-written list
|
|
37
|
-
* here, which is the property that mattered.
|
|
38
|
-
*/
|
|
39
|
-
type AparteEventName = Extract<keyof HTMLElementEventMap, `aparte-${string}`>;
|
|
40
|
-
type AparteAnyEventName = AparteEventName | AparteUiEventName;
|
|
41
|
-
/** The typed event for a name, or a detail-free `CustomEvent` when the map has none. */
|
|
42
|
-
type AparteEventFor<K extends string> = K extends keyof HTMLElementEventMap ? HTMLElementEventMap[K] : CustomEvent<null>;
|
|
43
|
-
type AparteSvelteHandlers = {
|
|
44
|
-
[K in AparteAnyEventName as `on:${K}`]?: (event: AparteEventFor<K>) => void;
|
|
45
|
-
} & {
|
|
46
|
-
[K in AparteAnyEventName as `on${K}`]?: (event: AparteEventFor<K>) => void;
|
|
47
|
-
};
|
|
48
|
-
type AparteSvelteElements = {
|
|
49
|
-
[K in AparteElementTagName]: HTMLAttributes<HTMLElement> & AparteTemplateAttrs<AparteElementAttributes[K]> & AparteSvelteHandlers;
|
|
50
|
-
};
|
|
51
|
-
declare module 'svelte/elements' {
|
|
52
|
-
interface SvelteHTMLElements extends AparteSvelteElements {
|
|
53
|
-
}
|
|
54
|
-
}
|
|
17
|
+
export type { AparteSvelteElements } from './elements.js';
|
|
55
18
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAG5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAK9D,YAAY,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAG5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAC5E,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,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,EACxB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAG5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAK9D,YAAY,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAG5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAC5E,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,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,EACxB,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC"}
|