@aparte/core 0.2.0-alpha.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/LICENSE +21 -0
- package/README.md +53 -0
- package/dist/client/aparte-client.d.ts +326 -0
- package/dist/client/aparte-client.d.ts.map +1 -0
- package/dist/client/stream-adapter.d.ts +197 -0
- package/dist/client/stream-adapter.d.ts.map +1 -0
- package/dist/components/bubble/aparte-chat-bubble.d.ts +153 -0
- package/dist/components/bubble/aparte-chat-bubble.d.ts.map +1 -0
- package/dist/components/bubble/bubble-sync.d.ts +44 -0
- package/dist/components/bubble/bubble-sync.d.ts.map +1 -0
- package/dist/components/bubble/index.d.ts +4 -0
- package/dist/components/bubble/index.d.ts.map +1 -0
- package/dist/components/chat/aparte-chat.d.ts +49 -0
- package/dist/components/chat/aparte-chat.d.ts.map +1 -0
- package/dist/components/chat/index.d.ts +2 -0
- package/dist/components/chat/index.d.ts.map +1 -0
- package/dist/components/composer/aparte-composer-action.d.ts +37 -0
- package/dist/components/composer/aparte-composer-action.d.ts.map +1 -0
- package/dist/components/composer/aparte-composer-add-attachment.d.ts +27 -0
- package/dist/components/composer/aparte-composer-add-attachment.d.ts.map +1 -0
- package/dist/components/composer/aparte-composer-attachments.d.ts +26 -0
- package/dist/components/composer/aparte-composer-attachments.d.ts.map +1 -0
- package/dist/components/composer/aparte-composer-cancel.d.ts +21 -0
- package/dist/components/composer/aparte-composer-cancel.d.ts.map +1 -0
- package/dist/components/composer/aparte-composer-input.d.ts +63 -0
- package/dist/components/composer/aparte-composer-input.d.ts.map +1 -0
- package/dist/components/composer/aparte-composer-send.d.ts +25 -0
- package/dist/components/composer/aparte-composer-send.d.ts.map +1 -0
- package/dist/components/composer/aparte-composer.d.ts +150 -0
- package/dist/components/composer/aparte-composer.d.ts.map +1 -0
- package/dist/components/composer/index.d.ts +9 -0
- package/dist/components/composer/index.d.ts.map +1 -0
- package/dist/components/conversation-list/aparte-conversation-list.d.ts +50 -0
- package/dist/components/conversation-list/aparte-conversation-list.d.ts.map +1 -0
- package/dist/components/conversation-list/index.d.ts +2 -0
- package/dist/components/conversation-list/index.d.ts.map +1 -0
- package/dist/components/elicitation/aparte-elicitation.d.ts +29 -0
- package/dist/components/elicitation/aparte-elicitation.d.ts.map +1 -0
- package/dist/components/index.d.ts +10 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/status/aparte-chat-status.d.ts +34 -0
- package/dist/components/status/aparte-chat-status.d.ts.map +1 -0
- package/dist/components/status/index.d.ts +2 -0
- package/dist/components/status/index.d.ts.map +1 -0
- package/dist/components/viewport/aparte-chat-viewport.d.ts +358 -0
- package/dist/components/viewport/aparte-chat-viewport.d.ts.map +1 -0
- package/dist/components/viewport/index.d.ts +2 -0
- package/dist/components/viewport/index.d.ts.map +1 -0
- package/dist/config/action-provider.d.ts +59 -0
- package/dist/config/action-provider.d.ts.map +1 -0
- package/dist/config/aparte-config.d.ts +490 -0
- package/dist/config/aparte-config.d.ts.map +1 -0
- package/dist/config/attachment-renderer.d.ts +28 -0
- package/dist/config/attachment-renderer.d.ts.map +1 -0
- package/dist/config/avatar-provider.d.ts +35 -0
- package/dist/config/avatar-provider.d.ts.map +1 -0
- package/dist/config/bubble-shell-renderer.d.ts +41 -0
- package/dist/config/bubble-shell-renderer.d.ts.map +1 -0
- package/dist/config/config-context.d.ts +47 -0
- package/dist/config/config-context.d.ts.map +1 -0
- package/dist/config/error-renderer.d.ts +26 -0
- package/dist/config/error-renderer.d.ts.map +1 -0
- package/dist/config/icon-provider.d.ts +63 -0
- package/dist/config/icon-provider.d.ts.map +1 -0
- package/dist/config/index.d.ts +19 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/locale.d.ts +60 -0
- package/dist/config/locale.d.ts.map +1 -0
- package/dist/config/sanitize.d.ts +31 -0
- package/dist/config/sanitize.d.ts.map +1 -0
- package/dist/config/sibling-nav-renderer.d.ts +27 -0
- package/dist/config/sibling-nav-renderer.d.ts.map +1 -0
- package/dist/config/skeleton-provider.d.ts +26 -0
- package/dist/config/skeleton-provider.d.ts.map +1 -0
- package/dist/config/status-renderer.d.ts +23 -0
- package/dist/config/status-renderer.d.ts.map +1 -0
- package/dist/conversations/conversation-controller.d.ts +126 -0
- package/dist/conversations/conversation-controller.d.ts.map +1 -0
- package/dist/conversations/conversation-manager.d.ts +98 -0
- package/dist/conversations/conversation-manager.d.ts.map +1 -0
- package/dist/conversations/index.d.ts +5 -0
- package/dist/conversations/index.d.ts.map +1 -0
- package/dist/conversations/types.d.ts +172 -0
- package/dist/conversations/types.d.ts.map +1 -0
- package/dist/custom-elements.json +15833 -0
- package/dist/elicitation/index.d.ts +20 -0
- package/dist/elicitation/index.d.ts.map +1 -0
- package/dist/elicitation/panel.d.ts +18 -0
- package/dist/elicitation/panel.d.ts.map +1 -0
- package/dist/elicitation/types.d.ts +98 -0
- package/dist/elicitation/types.d.ts.map +1 -0
- package/dist/host/aparte-chat-host.d.ts +176 -0
- package/dist/host/aparte-chat-host.d.ts.map +1 -0
- package/dist/host/index.d.ts +2 -0
- package/dist/host/index.d.ts.map +1 -0
- package/dist/index-D89k-n2Q.js +6294 -0
- package/dist/index-D89k-n2Q.js.map +1 -0
- package/dist/index.css +2554 -0
- package/dist/index.d.ts +62 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3763 -0
- package/dist/index.js.map +1 -0
- package/dist/index.node.d.ts +53 -0
- package/dist/index.node.d.ts.map +1 -0
- package/dist/index.node.js +49 -0
- package/dist/index.node.js.map +1 -0
- package/dist/interop/element-props.d.ts +23 -0
- package/dist/interop/element-props.d.ts.map +1 -0
- package/dist/parsers/aparte-event-stream.d.ts +13 -0
- package/dist/parsers/aparte-event-stream.d.ts.map +1 -0
- package/dist/parsers/aparte-stream-parser.d.ts +137 -0
- package/dist/parsers/aparte-stream-parser.d.ts.map +1 -0
- package/dist/parsers/index.d.ts +4 -0
- package/dist/parsers/index.d.ts.map +1 -0
- package/dist/primitives/index.d.ts +8 -0
- package/dist/primitives/index.d.ts.map +1 -0
- package/dist/primitives/progress-spinner/aparte-progress-spinner.d.ts +25 -0
- package/dist/primitives/progress-spinner/aparte-progress-spinner.d.ts.map +1 -0
- package/dist/primitives/progress-spinner/index.d.ts +2 -0
- package/dist/primitives/progress-spinner/index.d.ts.map +1 -0
- package/dist/primitives/select/aparte-optgroup.d.ts +32 -0
- package/dist/primitives/select/aparte-optgroup.d.ts.map +1 -0
- package/dist/primitives/select/aparte-option.d.ts +30 -0
- package/dist/primitives/select/aparte-option.d.ts.map +1 -0
- package/dist/primitives/select/aparte-select.d.ts +74 -0
- package/dist/primitives/select/aparte-select.d.ts.map +1 -0
- package/dist/primitives/select/index.d.ts +9 -0
- package/dist/primitives/select/index.d.ts.map +1 -0
- package/dist/renderers/index.d.ts +5 -0
- package/dist/renderers/index.d.ts.map +1 -0
- package/dist/renderers/segment-renderers.d.ts +31 -0
- package/dist/renderers/segment-renderers.d.ts.map +1 -0
- package/dist/runtime/message-repository.d.ts +111 -0
- package/dist/runtime/message-repository.d.ts.map +1 -0
- package/dist/transport/backend-handler.d.ts +50 -0
- package/dist/transport/backend-handler.d.ts.map +1 -0
- package/dist/transport/backend-transport.d.ts +39 -0
- package/dist/transport/backend-transport.d.ts.map +1 -0
- package/dist/transport/direct-transport.d.ts +36 -0
- package/dist/transport/direct-transport.d.ts.map +1 -0
- package/dist/transport/index.d.ts +6 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/types.d.ts +73 -0
- package/dist/transport/types.d.ts.map +1 -0
- package/dist/types/chat.d.ts +223 -0
- package/dist/types/chat.d.ts.map +1 -0
- package/dist/types/errors.d.ts +25 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/event-map.d.ts +41 -0
- package/dist/types/event-map.d.ts.map +1 -0
- package/dist/types/events.d.ts +290 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/imperative-api.d.ts +38 -0
- package/dist/types/imperative-api.d.ts.map +1 -0
- package/dist/types/index.d.ts +22 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/model-provider.d.ts +229 -0
- package/dist/types/model-provider.d.ts.map +1 -0
- package/dist/types/models.d.ts +173 -0
- package/dist/types/models.d.ts.map +1 -0
- package/dist/types/parsers.d.ts +42 -0
- package/dist/types/parsers.d.ts.map +1 -0
- package/dist/types/providers.d.ts +93 -0
- package/dist/types/providers.d.ts.map +1 -0
- package/dist/types/segments.d.ts +221 -0
- package/dist/types/segments.d.ts.map +1 -0
- package/dist/types/theming.d.ts +44 -0
- package/dist/types/theming.d.ts.map +1 -0
- package/dist/types/tools.d.ts +98 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/utils/assert-never.d.ts +9 -0
- package/dist/utils/assert-never.d.ts.map +1 -0
- package/dist/utils/css-escape.d.ts +15 -0
- package/dist/utils/css-escape.d.ts.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import type { AparteMessage, AparteViewportConfig, AparteSegment, AparteUsage } from '../../types/index.js';
|
|
2
|
+
import type { ExportedMessageRepository } from '../../runtime/message-repository.js';
|
|
3
|
+
/**
|
|
4
|
+
* AparteChatViewport - The Core
|
|
5
|
+
*
|
|
6
|
+
* Container component with smart scroll, streaming, and segment support.
|
|
7
|
+
* Uses Light DOM for global CSS styling.
|
|
8
|
+
*
|
|
9
|
+
* @element aparte-chat-viewport
|
|
10
|
+
*
|
|
11
|
+
* Features:
|
|
12
|
+
* - Smart Scroll: Sticks to bottom when user is at bottom, stops on manual scroll up
|
|
13
|
+
* - appendToken(): For simple content streaming
|
|
14
|
+
* - appendToSegment(): For segment-aware streaming (thinking, code, etc.)
|
|
15
|
+
* - Internal message registry for memory management
|
|
16
|
+
*/
|
|
17
|
+
export declare class AparteChatViewport extends HTMLElement {
|
|
18
|
+
private _container;
|
|
19
|
+
private _scrollBtn;
|
|
20
|
+
private _bottomSpacer;
|
|
21
|
+
/**
|
|
22
|
+
* In framework-managed mode there is no spacer ELEMENT (an extra child would
|
|
23
|
+
* collide with the framework's own DOM reconciliation). The spacer is an
|
|
24
|
+
* additive `padding-bottom` on the host, tracked here so `_recalculateSpacer`
|
|
25
|
+
* can read the current value without measuring an element.
|
|
26
|
+
*/
|
|
27
|
+
private _fwSpacerHeight;
|
|
28
|
+
private _spacerRafId;
|
|
29
|
+
private _spacerFrozenUntil;
|
|
30
|
+
private _layoutTransitionMs;
|
|
31
|
+
private _repo;
|
|
32
|
+
private _isAutoScrollEnabled;
|
|
33
|
+
private _scrollThreshold;
|
|
34
|
+
/** When true, the next _autoScroll() call uses smooth instead of instant, then resets. */
|
|
35
|
+
private _smoothScrollOnce;
|
|
36
|
+
/**
|
|
37
|
+
* DOM render cap: the max number of `<aparte-chat-bubble>` elements kept in the
|
|
38
|
+
* DOM at once (a perf ceiling for very long conversations). This NEVER evicts
|
|
39
|
+
* messages from the repository — the full conversation tree and its persistence
|
|
40
|
+
* snapshot stay intact; only the oldest rendered bubbles are dropped from view.
|
|
41
|
+
*/
|
|
42
|
+
private _maxRenderedBubbles;
|
|
43
|
+
/** One-time guard for the deprecated `maxMessages` warning. */
|
|
44
|
+
private _warnedMaxMessagesDeprecation;
|
|
45
|
+
private _resizeObserver;
|
|
46
|
+
private _mutationObserver;
|
|
47
|
+
private _boundResetHandler;
|
|
48
|
+
/**
|
|
49
|
+
* When true, _reRenderActivePath() only dispatches aparte-path-changed without
|
|
50
|
+
* touching the DOM. Set via setFrameworkManagedDOM(true) when a framework
|
|
51
|
+
* (e.g. Angular) owns the bubble elements.
|
|
52
|
+
*/
|
|
53
|
+
private _frameworkManagedDOM;
|
|
54
|
+
static get observedAttributes(): string[];
|
|
55
|
+
constructor();
|
|
56
|
+
connectedCallback(): void;
|
|
57
|
+
disconnectedCallback(): void;
|
|
58
|
+
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
|
|
59
|
+
/**
|
|
60
|
+
* Configure viewport with options
|
|
61
|
+
*/
|
|
62
|
+
configure(config: AparteViewportConfig): void;
|
|
63
|
+
/**
|
|
64
|
+
* Append a token chunk to a message's content (simple text streaming)
|
|
65
|
+
* @param messageId - Unique identifier for the message
|
|
66
|
+
* @param chunk - Token chunk to append
|
|
67
|
+
*/
|
|
68
|
+
appendToken(messageId: string, chunk: string): void;
|
|
69
|
+
/**
|
|
70
|
+
* Append content to a specific segment within a message
|
|
71
|
+
* @param messageId - Message containing the segment
|
|
72
|
+
* @param segmentId - Target segment ID
|
|
73
|
+
* @param chunk - Content to append
|
|
74
|
+
*/
|
|
75
|
+
appendToSegment(messageId: string, segmentId: string, chunk: string): void;
|
|
76
|
+
/**
|
|
77
|
+
* The active (head) message id — the target of `AparteClient`'s 1-argument
|
|
78
|
+
* streaming convention (`addSegment(segment)`, `updateSegment(segmentId,
|
|
79
|
+
* updates)`, …) which operates on "the current message". Lets a bare
|
|
80
|
+
* `<aparte-chat-viewport>` be a valid `AparteClient` target, exactly like a
|
|
81
|
+
* framework wrapper's host element.
|
|
82
|
+
*/
|
|
83
|
+
private _activeMessageId;
|
|
84
|
+
/**
|
|
85
|
+
* Add a new segment. Two calling conventions are accepted:
|
|
86
|
+
* - `addSegment(segment)` — AparteClient's 1-arg "operate on the current
|
|
87
|
+
* (head) message" convention (also what a wrapper host installs);
|
|
88
|
+
* - `addSegment(messageId, segment)` — explicit standalone form.
|
|
89
|
+
* The first argument's type disambiguates (string = messageId, object =
|
|
90
|
+
* segment), so a raw viewport driven by `AparteClient` no longer drops text
|
|
91
|
+
* (the args used to bind one position short, creating a phantom message).
|
|
92
|
+
*/
|
|
93
|
+
addSegment(segment: AparteSegment): void;
|
|
94
|
+
addSegment(messageId: string, segment: AparteSegment): void;
|
|
95
|
+
/**
|
|
96
|
+
* Update a segment. `updateSegment(segmentId, updates)` (1-arg client
|
|
97
|
+
* convention → current message) or `updateSegment(messageId, segmentId,
|
|
98
|
+
* updates)` (explicit). Disambiguated by arity: the 3rd arg is absent and
|
|
99
|
+
* the 2nd is the `updates` object in the 1-arg form.
|
|
100
|
+
*/
|
|
101
|
+
updateSegment(segmentId: string, updates: Partial<AparteSegment>): void;
|
|
102
|
+
updateSegment(messageId: string, segmentId: string, updates: Partial<AparteSegment>): void;
|
|
103
|
+
/**
|
|
104
|
+
* Remove a segment. `removeSegment(segmentId)` (1-arg client convention →
|
|
105
|
+
* current message) or `removeSegment(messageId, segmentId)` (explicit).
|
|
106
|
+
*/
|
|
107
|
+
removeSegment(segmentId: string): void;
|
|
108
|
+
removeSegment(messageId: string, segmentId: string): void;
|
|
109
|
+
/**
|
|
110
|
+
* Start a new streaming segment (e.g., thinking or code block)
|
|
111
|
+
* Creates the segment and marks it as streaming
|
|
112
|
+
*/
|
|
113
|
+
startSegment(messageId: string, segment: AparteSegment): void;
|
|
114
|
+
/**
|
|
115
|
+
* Complete a streaming segment
|
|
116
|
+
*/
|
|
117
|
+
completeSegment(messageId: string, segmentId: string): void;
|
|
118
|
+
/**
|
|
119
|
+
* Persist token usage on a message and propagate to the live bubble so the
|
|
120
|
+
* perf chip (tokens/sec) renders in the action bar.
|
|
121
|
+
*/
|
|
122
|
+
setUsage(messageId: string, usage: AparteUsage): void;
|
|
123
|
+
/**
|
|
124
|
+
* Mark a message as finished streaming
|
|
125
|
+
*/
|
|
126
|
+
completeMessage(messageId: string): void;
|
|
127
|
+
/**
|
|
128
|
+
* Atomic update for a message by ID
|
|
129
|
+
* Supports updating content, status, segments, and other metadata
|
|
130
|
+
*/
|
|
131
|
+
updateMessage(messageId: string, updates: Partial<AparteMessage>): void;
|
|
132
|
+
/**
|
|
133
|
+
* Add a complete message to the message registry.
|
|
134
|
+
*
|
|
135
|
+
* @remarks
|
|
136
|
+
* **Framework-managed DOM only.** Records the message in the tree but does NOT
|
|
137
|
+
* paint a bubble on its own (a framework wrapper reconciles the DOM from the
|
|
138
|
+
* list). For standalone / vanilla usage call {@link appendMessage} instead,
|
|
139
|
+
* which both records the message and creates its bubble element.
|
|
140
|
+
*/
|
|
141
|
+
addMessage(message: AparteMessage): void;
|
|
142
|
+
/**
|
|
143
|
+
* Append a new message and create its bubble in the DOM.
|
|
144
|
+
* Implements the same contract as the Angular wrapper's appendMessage(),
|
|
145
|
+
* making aparte-chat-viewport a fully standalone target for aparte-client.
|
|
146
|
+
* When `_frameworkManagedDOM` is true, only the internal repo is updated —
|
|
147
|
+
* the framework owns the DOM and will create the bubble element itself.
|
|
148
|
+
*/
|
|
149
|
+
appendMessage(message: AparteMessage): void;
|
|
150
|
+
/**
|
|
151
|
+
* Update the last message content, optionally appending.
|
|
152
|
+
* Implements the same contract as the Angular wrapper's updateLastMessage(),'
|
|
153
|
+
* making aparte-chat-viewport a fully standalone streaming target for aparte-client.
|
|
154
|
+
*/
|
|
155
|
+
updateLastMessage(content: string, options?: {
|
|
156
|
+
append?: boolean;
|
|
157
|
+
}): void;
|
|
158
|
+
/**
|
|
159
|
+
* Add a new sibling branch to an assistant message (retry flow).
|
|
160
|
+
* Creates a new empty assistant message as a sibling of `messageId`
|
|
161
|
+
* under the same parent, switches the active branch to it, and
|
|
162
|
+
* re-renders the active path.
|
|
163
|
+
* @returns The index of the new branch in the siblings array, or 0 on failure.
|
|
164
|
+
*/
|
|
165
|
+
addBranch(messageId: string): number;
|
|
166
|
+
/**
|
|
167
|
+
* Add a new message relative to `existingId`, switch to it, and re-render.
|
|
168
|
+
*
|
|
169
|
+
* Role-aware semantics:
|
|
170
|
+
* - existingId is an **assistant** message → create a sibling (same parent),
|
|
171
|
+
* so the active path replaces the old response with the new one.
|
|
172
|
+
* - existingId is a **user** message → create a child of that message,
|
|
173
|
+
* so the user message stays on the active path and the new response follows it.
|
|
174
|
+
*
|
|
175
|
+
* Returns the new message's ID, or null if `existingId` is not found.
|
|
176
|
+
*/
|
|
177
|
+
addSiblingOf(existingId: string, newMessage: AparteMessage): string | null;
|
|
178
|
+
/**
|
|
179
|
+
* Navigate to the previous or next sibling branch of a message.
|
|
180
|
+
* Triggers a full re-render of the active path.
|
|
181
|
+
*/
|
|
182
|
+
navigateBranch(messageId: string, direction: 'prev' | 'next'): void;
|
|
183
|
+
/**
|
|
184
|
+
* Remove ALL responses to a user message (every child branch) and set head
|
|
185
|
+
* back to `userMessageId`. Cleaner than `truncateFrom` for edit flows: it
|
|
186
|
+
* discards stale sibling branches so the regenerated response starts alone.
|
|
187
|
+
*/
|
|
188
|
+
truncateResponsesAfter(userMessageId: string): void;
|
|
189
|
+
/**
|
|
190
|
+
* Remove all messages from `messageId` onwards (inclusive) from state and DOM.
|
|
191
|
+
* Used by edit to truncate history before re-generating.
|
|
192
|
+
*/
|
|
193
|
+
truncateFrom(messageId: string): void;
|
|
194
|
+
/**
|
|
195
|
+
* Get a message by ID
|
|
196
|
+
*/
|
|
197
|
+
getMessage(messageId: string): AparteMessage | undefined;
|
|
198
|
+
getMessages(): AparteMessage[];
|
|
199
|
+
/**
|
|
200
|
+
* Export the full conversation tree (all branches, not just the active path).
|
|
201
|
+
* The returned snapshot can be persisted and restored via `importTree()`.
|
|
202
|
+
*/
|
|
203
|
+
exportTree(): ExportedMessageRepository;
|
|
204
|
+
/**
|
|
205
|
+
* Import a previously-exported tree snapshot, restoring the full branch
|
|
206
|
+
* topology and the active head. Replaces any existing repo content.
|
|
207
|
+
*
|
|
208
|
+
* Always calls `_reRenderActivePath()`:
|
|
209
|
+
* - In native DOM mode: rebuilds bubble elements.
|
|
210
|
+
* - In framework-managed mode: skips DOM manipulation but dispatches
|
|
211
|
+
* `aparte-path-changed` with sibling metadata so the wrapper can update
|
|
212
|
+
* branch arrows on already-rendered bubbles.
|
|
213
|
+
*/
|
|
214
|
+
importTree(tree: ExportedMessageRepository): void;
|
|
215
|
+
/**
|
|
216
|
+
* Clear all messages and remove all bubble elements from the DOM.
|
|
217
|
+
* Also dispatches a aparte-reset-done event.
|
|
218
|
+
*
|
|
219
|
+
* In framework-managed mode the DOM is owned by the host framework
|
|
220
|
+
* (Angular @for, React, etc.) and we must not clear `innerHTML` — doing
|
|
221
|
+
* so desynchronises the framework's view tree from the live DOM and the
|
|
222
|
+
* next change-detection pass throws `NotFoundError` on insertBefore.
|
|
223
|
+
*/
|
|
224
|
+
clearAll(): void;
|
|
225
|
+
/**
|
|
226
|
+
* Clear all messages
|
|
227
|
+
* @deprecated Use clearAll() to also remove DOM bubbles
|
|
228
|
+
*/
|
|
229
|
+
clearMessages(): void;
|
|
230
|
+
/**
|
|
231
|
+
* Replace the entire message list in one shot. Used when switching
|
|
232
|
+
* conversations: clears existing repo + DOM, then appends each message.
|
|
233
|
+
*
|
|
234
|
+
* In framework-managed mode the framework re-renders the bubble DOM
|
|
235
|
+
* itself; we only update the internal repo (used by aparte-client to
|
|
236
|
+
* build chat history).
|
|
237
|
+
*/
|
|
238
|
+
setMessages(messages: AparteMessage[]): void;
|
|
239
|
+
/**
|
|
240
|
+
* Scroll to bottom of viewport
|
|
241
|
+
*/
|
|
242
|
+
scrollToBottom(): void;
|
|
243
|
+
/**
|
|
244
|
+
* Reset the bottom spacer to 0 height immediately and freeze it for
|
|
245
|
+
* 350 ms so the host-app layout transition (e.g. flex: 0→1 animation)
|
|
246
|
+
* does not trigger a premature recalculation with mid-animation geometry.
|
|
247
|
+
* Call before a full messages swap.
|
|
248
|
+
*/
|
|
249
|
+
resetSpacer(): void;
|
|
250
|
+
/**
|
|
251
|
+
* Enable or disable auto-scroll
|
|
252
|
+
*/
|
|
253
|
+
setAutoScroll(enabled: boolean): void;
|
|
254
|
+
/**
|
|
255
|
+
* Signal that a framework (e.g. Angular) manages the bubble DOM.
|
|
256
|
+
* When true, branch navigation dispatches `aparte-path-changed` without
|
|
257
|
+
* clearing/rebuilding the messages wrapper — the framework re-renders instead.
|
|
258
|
+
*/
|
|
259
|
+
setFrameworkManagedDOM(managed: boolean): void;
|
|
260
|
+
private _getOrCreateMessage;
|
|
261
|
+
private _notifyBubble;
|
|
262
|
+
/**
|
|
263
|
+
* Re-render the active path: clears the messages wrapper and rebuilds bubbles
|
|
264
|
+
* for every message on the current active branch path (root → head).
|
|
265
|
+
* Calls `setSiblings(count, index)` on each bubble that has siblings, and
|
|
266
|
+
* dispatches `aparte-path-changed` so Angular wrapper can sync its signal.
|
|
267
|
+
*
|
|
268
|
+
* When `_frameworkManagedDOM` is true (set via setFrameworkManagedDOM), the DOM
|
|
269
|
+
* manipulation is skipped — only `aparte-path-changed` is dispatched so the
|
|
270
|
+
* framework can re-render from updated signal state.
|
|
271
|
+
*/
|
|
272
|
+
private _reRenderActivePath;
|
|
273
|
+
private _dispatchPathChanged;
|
|
274
|
+
private _autoScroll;
|
|
275
|
+
/**
|
|
276
|
+
* Request that the next auto-scroll triggered by a DOM mutation uses
|
|
277
|
+
* smooth behaviour instead of instant. Call this just before adding a
|
|
278
|
+
* user message bubble so the viewport animates down rather than jumping.
|
|
279
|
+
* Resets automatically after the first auto-scroll fires.
|
|
280
|
+
*/
|
|
281
|
+
requestSmoothScroll(): void;
|
|
282
|
+
private _render;
|
|
283
|
+
/**
|
|
284
|
+
* DOM setup for framework-managed mode. The framework (React/Vue/Svelte/
|
|
285
|
+
* Angular) renders the bubble elements as DIRECT children of the host, so we
|
|
286
|
+
* must NOT relocate them into an internal wrapper — that desyncs the
|
|
287
|
+
* framework's virtual DOM from the real DOM and throws NotFoundError on the
|
|
288
|
+
* next append. Instead the HOST itself is the scroll surface, the spacer is
|
|
289
|
+
* additive `padding-bottom` (no element), and the scroll button is a
|
|
290
|
+
* `position: sticky` TRAILING foreign child (kept last by the framework
|
|
291
|
+
* MutationObserver). A present foreign node is still a valid `insertBefore`
|
|
292
|
+
* reference for the framework — the crash came from a RELOCATED node, not a
|
|
293
|
+
* foreign one.
|
|
294
|
+
*/
|
|
295
|
+
private _setupFrameworkDOM;
|
|
296
|
+
/**
|
|
297
|
+
* Keep the sticky scroll button as the last child in framework-managed mode.
|
|
298
|
+
* The framework usually inserts bubbles before its own trailing nodes (so the
|
|
299
|
+
* button stays last), but a plain `appendChild` at the very end (e.g. some
|
|
300
|
+
* Angular @for paths) can land a bubble after it — move it back. Idempotent:
|
|
301
|
+
* a no-op when already last, so it never loops the MutationObserver.
|
|
302
|
+
*/
|
|
303
|
+
private _keepScrollButtonLast;
|
|
304
|
+
/** Current spacer height — a padding value (framework) or the element's height (core). */
|
|
305
|
+
private _getSpacerHeight;
|
|
306
|
+
/** Set the spacer — host padding (framework, additive to base padding) or element height (core). */
|
|
307
|
+
private _setSpacerHeight;
|
|
308
|
+
private _setupEventListeners;
|
|
309
|
+
private _setupObservers;
|
|
310
|
+
private _handleScroll;
|
|
311
|
+
private _scrollToBottom;
|
|
312
|
+
private _smoothScrollToBottom;
|
|
313
|
+
private _prefersReducedMotion;
|
|
314
|
+
/**
|
|
315
|
+
* Show/hide the scroll-to-bottom button based on the current auto-scroll state.
|
|
316
|
+
* Hidden when already at bottom (_isAutoScrollEnabled = true).
|
|
317
|
+
*/
|
|
318
|
+
private _updateScrollButton;
|
|
319
|
+
/**
|
|
320
|
+
* Recalculate the bottom spacer height so the last user message is always
|
|
321
|
+
* pinned to the top of the scroll area when a response is being generated.
|
|
322
|
+
*
|
|
323
|
+
* spacer = max(0, viewportHeight - lastUserBubble.offsetHeight - lastAssistantBubble.offsetHeight)
|
|
324
|
+
*
|
|
325
|
+
* The spacer shrinks progressively as the assistant streams content, eventually
|
|
326
|
+
* reaching 0 when the combined height fills the viewport.
|
|
327
|
+
*/
|
|
328
|
+
private _recalculateSpacer;
|
|
329
|
+
/**
|
|
330
|
+
* Schedule a spacer recalculation on the next animation frame.
|
|
331
|
+
* Batches multiple rapid calls (e.g. during token streaming) into one.
|
|
332
|
+
*
|
|
333
|
+
* Single-RAF intentional: both the scroll-to-bottom queued by MutationObserver
|
|
334
|
+
* and this spacer recalculation must land in the *same* frame so the browser
|
|
335
|
+
* paints exactly once — with the correct scroll position *and* the correct
|
|
336
|
+
* spacer height. A double-RAF would put the spacer shrink one frame after the
|
|
337
|
+
* scroll, causing a 1-frame layout jump during streaming.
|
|
338
|
+
*/
|
|
339
|
+
private _scheduleSpacerUpdate;
|
|
340
|
+
/**
|
|
341
|
+
* Cap the number of rendered bubbles in the DOM (perf ceiling only).
|
|
342
|
+
*
|
|
343
|
+
* Drops the oldest `<aparte-chat-bubble>` elements beyond `_maxRenderedBubbles`
|
|
344
|
+
* from the DOM. It **never** touches the MessageRepository — the conversation
|
|
345
|
+
* model and its persistence snapshot stay complete (retention/eviction is a
|
|
346
|
+
* consumer/persistence concern, not the viewport's). No-op when a framework
|
|
347
|
+
* owns the DOM.
|
|
348
|
+
*/
|
|
349
|
+
private _pruneRenderedBubbles;
|
|
350
|
+
private _warnMaxMessagesDeprecated;
|
|
351
|
+
private _cleanup;
|
|
352
|
+
}
|
|
353
|
+
declare global {
|
|
354
|
+
interface HTMLElementTagNameMap {
|
|
355
|
+
'aparte-chat-viewport': AparteChatViewport;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
//# sourceMappingURL=aparte-chat-viewport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aparte-chat-viewport.d.ts","sourceRoot":"","sources":["../../../src/components/viewport/aparte-chat-viewport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/viewport/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/** Zones where a custom action can appear. */
|
|
2
|
+
export type AparteActionZone = 'composer' | 'bubble';
|
|
3
|
+
/**
|
|
4
|
+
* A custom action button, registered once via `AparteConfig.registerAction(...)`
|
|
5
|
+
* and placed in one or more zones — the composer toolbar and/or the message
|
|
6
|
+
* (bubble) toolbar — via `zones`.
|
|
7
|
+
*
|
|
8
|
+
* Declarative and framework-agnostic: clicking it emits an `aparte-action`
|
|
9
|
+
* CustomEvent (bubbles, composed) carrying `{ actionId, zone, … }`, exactly like
|
|
10
|
+
* the built-in retry/feedback buttons — so you wire it the same way in
|
|
11
|
+
* React/Vue/Svelte/Angular and in vanilla. An optional `onClick` callback fires
|
|
12
|
+
* alongside the event for imperative convenience.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* AparteConfig.registerAction({
|
|
16
|
+
* id: 'share', icon: '<svg>…</svg>', label: 'Share',
|
|
17
|
+
* zones: ['bubble'], bubble: { roles: ['assistant'] },
|
|
18
|
+
* });
|
|
19
|
+
* chatEl.addEventListener('aparte-action', (e) => {
|
|
20
|
+
* if (e.detail.actionId === 'share') share(e.detail.messageId);
|
|
21
|
+
* });
|
|
22
|
+
*/
|
|
23
|
+
export interface AparteAction {
|
|
24
|
+
/** Stable id — echoed as `actionId` in the `aparte-action` event. */
|
|
25
|
+
id: string;
|
|
26
|
+
/**
|
|
27
|
+
* Icon for the button:
|
|
28
|
+
* - If it starts with `<`, it is treated as raw HTML/SVG and used directly.
|
|
29
|
+
* - Otherwise it is treated as a key for `AparteConfig.getIcon()`. If the
|
|
30
|
+
* provider doesn't have the key, falls back to `iconFallback` or `id`.
|
|
31
|
+
*/
|
|
32
|
+
icon: string;
|
|
33
|
+
/** Inline SVG/HTML fallback used when the icon provider doesn't have the key. */
|
|
34
|
+
iconFallback?: string;
|
|
35
|
+
/** Accessible label (sets `aria-label` + `title`) — a locale key or a raw string. */
|
|
36
|
+
label: string;
|
|
37
|
+
/** Lower renders first among custom actions (they follow the built-ins). */
|
|
38
|
+
order?: number;
|
|
39
|
+
/** Which zones this action appears in. */
|
|
40
|
+
zones: AparteActionZone[];
|
|
41
|
+
/** Composer-toolbar placement (used when `zones` includes `'composer'`). */
|
|
42
|
+
composer?: {
|
|
43
|
+
/** Toolbar side. Default: `'left'`. */
|
|
44
|
+
position?: 'left' | 'right';
|
|
45
|
+
/**
|
|
46
|
+
* When `true`, the button is hidden from the composer toolbar.
|
|
47
|
+
* Toggle at runtime with `AparteConfig.setActionHidden(id, hidden)`.
|
|
48
|
+
*/
|
|
49
|
+
hidden?: boolean;
|
|
50
|
+
};
|
|
51
|
+
/** Bubble-toolbar placement (used when `zones` includes `'bubble'`). */
|
|
52
|
+
bubble?: {
|
|
53
|
+
/** Bubble roles this action shows on. Default: both user and assistant. */
|
|
54
|
+
roles?: ('user' | 'assistant')[];
|
|
55
|
+
};
|
|
56
|
+
/** Optional imperative callback, fired alongside the `aparte-action` event. */
|
|
57
|
+
onClick?: (event: Event, context?: unknown) => void;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=action-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-provider.d.ts","sourceRoot":"","sources":["../../src/config/action-provider.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,QAAQ,CAAC;AAErD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,YAAY;IACzB,qEAAqE;IACrE,EAAE,EAAE,MAAM,CAAC;IACX;;;;;OAKG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qFAAqF;IACrF,KAAK,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,4EAA4E;IAC5E,QAAQ,CAAC,EAAE;QACP,uCAAuC;QACvC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAC5B;;;WAGG;QACH,MAAM,CAAC,EAAE,OAAO,CAAC;KACpB,CAAC;IACF,wEAAwE;IACxE,MAAM,CAAC,EAAE;QACL,2EAA2E;QAC3E,KAAK,CAAC,EAAE,CAAC,MAAM,GAAG,WAAW,CAAC,EAAE,CAAC;KACpC,CAAC;IACF,+EAA+E;IAC/E,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CACvD"}
|