@aparte/angular 0.16.10 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fesm2022/aparte-angular.mjs +189 -75
- package/dist/fesm2022/aparte-angular.mjs.map +1 -1
- package/dist/generated/element.directives.d.ts +38 -29
- package/dist/index.d.ts +1 -1
- package/dist/lib/aparte-ai.service.d.ts +12 -3
- package/dist/lib/aparte-chat.component.d.ts +38 -3
- package/dist/lib/aparte-ui.component.d.ts +20 -5
- package/dist/lib/provide-aparte.d.ts +24 -5
- package/package.json +3 -3
|
@@ -55,7 +55,7 @@ export declare class AparteChatBubbleDirective extends AparteElementBase {
|
|
|
55
55
|
readonly edit: EventEmitter<AparteEditEventDetail>;
|
|
56
56
|
/** The `‹1/2›` picker moved between sibling versions. */
|
|
57
57
|
readonly branchNavigate: EventEmitter<AparteBranchNavigateEventDetail>;
|
|
58
|
-
/** A link in the message body is about to be followed. Cancelable: `preventDefault()` keeps the browser from navigating, so a host can route the link itself. */
|
|
58
|
+
/** A link in the message body is about to be followed. Cancelable: `preventDefault()` keeps the browser from navigating, so a host can route the link itself. Angular: this Output emits the detail, so preventDefault() is not on it — bind the DOM event for that: (aparte-link-click)="$event.preventDefault()". */
|
|
59
59
|
readonly linkClick: EventEmitter<AparteLinkClickEventDetail>;
|
|
60
60
|
protected onAttachmentPreview(e: CustomEvent<AparteAttachmentPreviewEventDetail>): void;
|
|
61
61
|
protected onAction(e: CustomEvent<AparteActionEventDetail>): void;
|
|
@@ -85,6 +85,8 @@ export declare class AparteChatViewportDirective extends AparteElementBase {
|
|
|
85
85
|
set scrollThreshold(v: number);
|
|
86
86
|
/** Caps how many bubbles stay in the DOM; older ones are released. */
|
|
87
87
|
set maxRenderedBubbles(v: number);
|
|
88
|
+
/** The transcript is on its way: a conversation was chosen and its messages are being fetched. The element draws two skeleton turns, marks its scroll surface `aria-busy` and names the wait for a screen reader; `aparte-chat[center-empty]` does not count a loading viewport as empty. Set by `AparteConversationController` through its binding, or by hand from a loop of your own (`setLoading(true)`). */
|
|
89
|
+
set loading(v: boolean);
|
|
88
90
|
/** The wrapper's explicit hands-off signal: set it and this element builds no wrapper of its own and relocates none of the nodes the FRAMEWORK renders into it, because the framework owns them. Not "none of its children": core's own scroll-to-bottom button is re-appended whenever it stops being last, and that path runs in this mode only. All four wrappers set it. */
|
|
89
91
|
set frameworkManaged(v: boolean);
|
|
90
92
|
/** Reflected BY the element while a turn streams: the transcript is read-only meanwhile, and every bubble inside reads it (at connect, and when it changes). The vanilla path derives it from the repository; a framework host sets it through `setTranscriptBusy()`. Read-only from the outside. */
|
|
@@ -99,9 +101,10 @@ export declare class AparteChatViewportDirective extends AparteElementBase {
|
|
|
99
101
|
protected onResetDone(): void;
|
|
100
102
|
protected onPathChanged(e: CustomEvent<ApartePathChangedEventDetail>): void;
|
|
101
103
|
static ɵfac: i0.ɵɵFactoryDeclaration<AparteChatViewportDirective, never>;
|
|
102
|
-
static ɵdir: i0.ɵɵDirectiveDeclaration<AparteChatViewportDirective, "aparte-chat-viewport", never, { "scrollThreshold": { "alias": "scrollThreshold"; "required": false; }; "maxRenderedBubbles": { "alias": "maxRenderedBubbles"; "required": false; }; "frameworkManaged": { "alias": "frameworkManaged"; "required": false; }; "dataBusy": { "alias": "dataBusy"; "required": false; }; }, { "segmentUpdate": "segmentUpdate"; "resetDone": "resetDone"; "pathChanged": "pathChanged"; }, never, never, true, never>;
|
|
104
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<AparteChatViewportDirective, "aparte-chat-viewport", never, { "scrollThreshold": { "alias": "scrollThreshold"; "required": false; }; "maxRenderedBubbles": { "alias": "maxRenderedBubbles"; "required": false; }; "loading": { "alias": "loading"; "required": false; }; "frameworkManaged": { "alias": "frameworkManaged"; "required": false; }; "dataBusy": { "alias": "dataBusy"; "required": false; }; }, { "segmentUpdate": "segmentUpdate"; "resetDone": "resetDone"; "pathChanged": "pathChanged"; }, never, never, true, never>;
|
|
103
105
|
static ngAcceptInputType_scrollThreshold: unknown;
|
|
104
106
|
static ngAcceptInputType_maxRenderedBubbles: unknown;
|
|
107
|
+
static ngAcceptInputType_loading: unknown;
|
|
105
108
|
static ngAcceptInputType_frameworkManaged: unknown;
|
|
106
109
|
static ngAcceptInputType_dataBusy: unknown;
|
|
107
110
|
}
|
|
@@ -139,7 +142,7 @@ export declare class AparteComposerDirective extends AparteElementBase {
|
|
|
139
142
|
}
|
|
140
143
|
/** `<aparte-composer-action>` — Generic action button primitive for <aparte-composer>. */
|
|
141
144
|
export declare class AparteComposerActionDirective extends AparteElementBase {
|
|
142
|
-
/** Icon key for aparteGlobalConfig.getIcon(), or raw SVG/HTML starting with
|
|
145
|
+
/** Icon key for aparteGlobalConfig.getIcon(), or raw SVG/HTML starting with `<`. A key core's glyph set does not hold renders AS TEXT (`icon="star"` draws the word *star*), so bring your own set through `setIconProvider` or pass the SVG. */
|
|
143
146
|
set icon(v: string | undefined);
|
|
144
147
|
/** Accessible label (also used as tooltip) */
|
|
145
148
|
set label(v: string | undefined);
|
|
@@ -259,36 +262,42 @@ export declare class AparteContextDirective extends AparteElementBase {
|
|
|
259
262
|
static ngAcceptInputType_autoCompact: unknown;
|
|
260
263
|
static ngAcceptInputType_dataEmpty: unknown;
|
|
261
264
|
}
|
|
262
|
-
/** `<aparte-conversation-list>` — Conversation-history sidebar — a framework-agnostic web component. The host sets the `conversations` JS property and the `active-id` attribute; this renders the rows and fires the user's intent
|
|
265
|
+
/** `<aparte-conversation-list>` — Conversation-history sidebar — a framework-agnostic web component. The host sets the `conversations` JS property and the `active-id` attribute; this renders the rows and fires the user's intent. Acting on it is the host's, unless `manage` hands the row menu's writes to the registered conversation manager. */
|
|
263
266
|
export declare class AparteConversationListDirective extends AparteElementBase {
|
|
264
267
|
/** The id of the conversation to render as selected. */
|
|
265
268
|
set activeId(v: string | undefined);
|
|
266
269
|
/** Render the rows flat, in host order, with no date headings. */
|
|
267
|
-
set
|
|
268
|
-
/** The
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
|
|
272
|
-
/** The same item on an already-archived one; same detail shape, opposite intent. */
|
|
273
|
-
readonly unarchiveConversation: EventEmitter<AparteConversationArchiveDetail>;
|
|
274
|
-
/** The archive item was chosen on a live conversation. */
|
|
275
|
-
readonly archiveConversation: EventEmitter<AparteConversationArchiveDetail>;
|
|
276
|
-
/** The delete was confirmed. Nothing is removed here. */
|
|
277
|
-
readonly deleteConversation: EventEmitter<AparteConversationDeleteDetail>;
|
|
278
|
-
/** A rename was committed with a new, non-empty title. Nothing is renamed here. */
|
|
279
|
-
readonly renameConversation: EventEmitter<AparteConversationRenameDetail>;
|
|
270
|
+
set flat(v: boolean);
|
|
271
|
+
/** The list is on its way: six skeleton rows stand where the rows will be, the element is `aria-busy` and a visually hidden line names the wait. A list that is not there yet is not an empty list. Set it while your store answers, clear it when you assign `conversations`. */
|
|
272
|
+
set loading(v: boolean);
|
|
273
|
+
/** Let the list finish the gesture: rename, pin, unpin, archive, unarchive and delete are performed on the conversation manager registered with `setConversationManager()`, instead of leaving you six listeners to write. The event still fires first, and `preventDefault()` on it takes the gesture back. Off by default, and selecting stays yours either way. */
|
|
274
|
+
set manage(v: boolean);
|
|
280
275
|
/** A row's title was activated; the host loads that conversation. */
|
|
281
|
-
readonly
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
276
|
+
readonly conversationSelect: EventEmitter<AparteConversationSelectDetail>;
|
|
277
|
+
/** A rename was committed with a new, non-empty title. Cancelable: `preventDefault()` takes the gesture back from `manage`. Angular: this Output emits the detail, so preventDefault() is not on it — bind the DOM event for that: (aparte-conversation-rename)="$event.preventDefault()". */
|
|
278
|
+
readonly conversationRename: EventEmitter<AparteConversationRenameDetail>;
|
|
279
|
+
/** The pin item was chosen on an unpinned row. Cancelable: `preventDefault()` takes the gesture back from `manage`. Angular: this Output emits the detail, so preventDefault() is not on it — bind the DOM event for that: (aparte-conversation-pin)="$event.preventDefault()". */
|
|
280
|
+
readonly conversationPin: EventEmitter<AparteConversationPinDetail>;
|
|
281
|
+
/** The same item on a pinned row; same detail shape, opposite intent. Cancelable, like the rest. Angular: this Output emits the detail, so preventDefault() is not on it — bind the DOM event for that: (aparte-conversation-unpin)="$event.preventDefault()". */
|
|
282
|
+
readonly conversationUnpin: EventEmitter<AparteConversationPinDetail>;
|
|
283
|
+
/** The archive item was chosen on a live conversation. Cancelable: `preventDefault()` takes the gesture back from `manage`. Angular: this Output emits the detail, so preventDefault() is not on it — bind the DOM event for that: (aparte-conversation-archive)="$event.preventDefault()". */
|
|
284
|
+
readonly conversationArchive: EventEmitter<AparteConversationArchiveDetail>;
|
|
285
|
+
/** The same item on an already-archived one; same detail shape, opposite intent. Cancelable, like the rest. Angular: this Output emits the detail, so preventDefault() is not on it — bind the DOM event for that: (aparte-conversation-unarchive)="$event.preventDefault()". */
|
|
286
|
+
readonly conversationUnarchive: EventEmitter<AparteConversationArchiveDetail>;
|
|
287
|
+
/** The delete was confirmed. Cancelable: `preventDefault()` takes the gesture back from `manage`. Angular: this Output emits the detail, so preventDefault() is not on it — bind the DOM event for that: (aparte-conversation-delete)="$event.preventDefault()". */
|
|
288
|
+
readonly conversationDelete: EventEmitter<AparteConversationDeleteDetail>;
|
|
289
|
+
protected onConversationSelect(e: CustomEvent<AparteConversationSelectDetail>): void;
|
|
290
|
+
protected onConversationRename(e: CustomEvent<AparteConversationRenameDetail>): void;
|
|
291
|
+
protected onConversationPin(e: CustomEvent<AparteConversationPinDetail>): void;
|
|
292
|
+
protected onConversationUnpin(e: CustomEvent<AparteConversationPinDetail>): void;
|
|
293
|
+
protected onConversationArchive(e: CustomEvent<AparteConversationArchiveDetail>): void;
|
|
294
|
+
protected onConversationUnarchive(e: CustomEvent<AparteConversationArchiveDetail>): void;
|
|
295
|
+
protected onConversationDelete(e: CustomEvent<AparteConversationDeleteDetail>): void;
|
|
289
296
|
static ɵfac: i0.ɵɵFactoryDeclaration<AparteConversationListDirective, never>;
|
|
290
|
-
static ɵdir: i0.ɵɵDirectiveDeclaration<AparteConversationListDirective, "aparte-conversation-list", never, { "activeId": { "alias": "activeId"; "required": false; }; "
|
|
291
|
-
static
|
|
297
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<AparteConversationListDirective, "aparte-conversation-list", never, { "activeId": { "alias": "activeId"; "required": false; }; "flat": { "alias": "flat"; "required": false; }; "loading": { "alias": "loading"; "required": false; }; "manage": { "alias": "manage"; "required": false; }; }, { "conversationSelect": "conversationSelect"; "conversationRename": "conversationRename"; "conversationPin": "conversationPin"; "conversationUnpin": "conversationUnpin"; "conversationArchive": "conversationArchive"; "conversationUnarchive": "conversationUnarchive"; "conversationDelete": "conversationDelete"; }, never, never, true, never>;
|
|
298
|
+
static ngAcceptInputType_flat: unknown;
|
|
299
|
+
static ngAcceptInputType_loading: unknown;
|
|
300
|
+
static ngAcceptInputType_manage: unknown;
|
|
292
301
|
}
|
|
293
302
|
/** `<aparte-elicitation>` — The default presenter for a request to the human. It renders nothing itself: it registers as the presenter for the config governing its subtree, and mounts a panel inside the nearest `<aparte-composer>` when something asks — a tool handler calling `requestUserInput`, or core's own approval gate. */
|
|
294
303
|
/**
|
|
@@ -358,7 +367,7 @@ export declare class AparteScrollRailDirective extends AparteElementBase {
|
|
|
358
367
|
set every(v: string | undefined);
|
|
359
368
|
/** Reflected BY the element while it has fewer than two ticks. Read-only. */
|
|
360
369
|
set dataEmpty(v: boolean);
|
|
361
|
-
/** A tick was activated. Bubbles, cancelable: `preventDefault()` leaves the transcript where it is. */
|
|
370
|
+
/** A tick was activated. Bubbles, cancelable: `preventDefault()` leaves the transcript where it is. Angular: this Output emits the detail, so preventDefault() is not on it — bind the DOM event for that: (aparte-scroll-rail-jump)="$event.preventDefault()". */
|
|
362
371
|
readonly scrollRailJump: EventEmitter<AparteScrollRailJumpDetail>;
|
|
363
372
|
protected onScrollRailJump(e: CustomEvent<AparteScrollRailJumpDetail>): void;
|
|
364
373
|
static ɵfac: i0.ɵɵFactoryDeclaration<AparteScrollRailDirective, never>;
|
|
@@ -453,7 +462,7 @@ export declare class AparteSuggestionsDirective extends AparteElementBase {
|
|
|
453
462
|
set emptyOnly(v: boolean);
|
|
454
463
|
/** Reflected BY the element while it has no suggestion to show; the stylesheet hides it then. Read-only, do not set it yourself. */
|
|
455
464
|
set dataEmpty(v: boolean);
|
|
456
|
-
/** A starter was clicked. Bubbles, and is cancelable: `preventDefault()` stops the composer from being filled or submitted. */
|
|
465
|
+
/** A starter was clicked. Bubbles, and is cancelable: `preventDefault()` stops the composer from being filled or submitted. Angular: this Output emits the detail, so preventDefault() is not on it — bind the DOM event for that: (aparte-suggestion)="$event.preventDefault()". */
|
|
457
466
|
readonly suggestion: EventEmitter<AparteSuggestionEventDetail>;
|
|
458
467
|
protected onSuggestion(e: CustomEvent<AparteSuggestionEventDetail>): void;
|
|
459
468
|
static ɵfac: i0.ɵɵFactoryDeclaration<AparteSuggestionsDirective, never>;
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export { provideAparte, APARTE_CONFIG_TOKEN } from './lib/provide-aparte';
|
|
|
6
6
|
export type { ProvideAparteOptions, ApartePluginLoader } from './lib/provide-aparte';
|
|
7
7
|
export { AparteChatComponent } from './lib/aparte-chat.component';
|
|
8
8
|
export { AparteUiComponent } from './lib/aparte-ui.component';
|
|
9
|
-
export type { AparteUiHandle } from './lib/aparte-ui.component';
|
|
9
|
+
export type { AparteUiHandle, AparteUiProps } from './lib/aparte-ui.component';
|
|
10
10
|
export * from './generated/element.directives';
|
|
11
11
|
export { AparteAiService, APARTE_CLIENT_OPTIONS } from './lib/aparte-ai.service';
|
|
12
12
|
export { ConversationManagerService } from './lib/conversation-manager.service';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { OnDestroy, InjectionToken } from '@angular/core';
|
|
2
|
-
import { AparteClientOptions } from '@aparte/core';
|
|
2
|
+
import { AparteClient, AparteClientOptions } from '@aparte/core';
|
|
3
3
|
import * as i0 from "@angular/core";
|
|
4
4
|
/**
|
|
5
5
|
* Injection token for AparteClient configuration. Provided by `provideAparte()`;
|
|
@@ -14,7 +14,14 @@ export declare const APARTE_CLIENT_OPTIONS: InjectionToken<AparteClientOptions>;
|
|
|
14
14
|
*/
|
|
15
15
|
export declare class AparteAiService implements OnDestroy {
|
|
16
16
|
private readonly _clientOptions;
|
|
17
|
-
private _client;
|
|
17
|
+
private readonly _client;
|
|
18
|
+
/**
|
|
19
|
+
* The `AparteClient` this service drives — the same object React's
|
|
20
|
+
* `useAparteClient`, Vue's and Svelte's `createAparteClient` return as
|
|
21
|
+
* `{ client, abort }`. Angular alone kept it private, so the instance was
|
|
22
|
+
* unreachable while each service's docblock called itself the others' equivalent.
|
|
23
|
+
*/
|
|
24
|
+
get client(): AparteClient;
|
|
18
25
|
/**
|
|
19
26
|
* Start listening to `aparte-send` events globally.
|
|
20
27
|
* This connects the <aparte-chat> components to the AI Providers.
|
|
@@ -25,7 +32,9 @@ export declare class AparteAiService implements OnDestroy {
|
|
|
25
32
|
*/
|
|
26
33
|
connect(): void;
|
|
27
34
|
/**
|
|
28
|
-
* Stop listening.
|
|
35
|
+
* Stop listening. The client also takes its `keyResolver` back off the config,
|
|
36
|
+
* so a paused bridge no longer answers for keys — a model list refreshed while
|
|
37
|
+
* disconnected sees the config's other key sources only.
|
|
29
38
|
*/
|
|
30
39
|
disconnect(): void;
|
|
31
40
|
/**
|
|
@@ -43,6 +43,35 @@ export declare class AparteChatComponent implements AfterViewInit, OnDestroy, Ap
|
|
|
43
43
|
*/
|
|
44
44
|
set centerWhenEmptyInput(val: boolean);
|
|
45
45
|
readonly centerWhenEmpty: import("@angular/core").WritableSignal<boolean>;
|
|
46
|
+
/**
|
|
47
|
+
* The conversation is on its way: the viewport draws two skeleton turns, the empty
|
|
48
|
+
* state stays off and the composer is disabled until it lands. The conversation
|
|
49
|
+
* controller sets this itself while it fetches through your adapter's `loadFull()`;
|
|
50
|
+
* the input is for a wait of your own. Off by default.
|
|
51
|
+
*/
|
|
52
|
+
set loadingInput(val: boolean);
|
|
53
|
+
readonly loading: import("@angular/core").WritableSignal<boolean>;
|
|
54
|
+
/** The controller's wait (a conversation fetched through the adapter). */
|
|
55
|
+
readonly hostLoading: import("@angular/core").WritableSignal<boolean>;
|
|
56
|
+
readonly waiting: import("@angular/core").Signal<boolean>;
|
|
57
|
+
get loadingText(): string;
|
|
58
|
+
/**
|
|
59
|
+
* Class(es) merged onto the INNER `.aparte-chat-container`, not onto this
|
|
60
|
+
* component's own `<aparte-chat>` host.
|
|
61
|
+
*
|
|
62
|
+
* The other three wrappers have no such host: their root IS the container, so a
|
|
63
|
+
* consumer's `className` / `class` lands on the div that carries
|
|
64
|
+
* `.aparte-chat-container`, `[overlay-composer]` and `[data-aparte-empty]` — the
|
|
65
|
+
* three selectors core's shell recipe keys on. Here a class written on the tag
|
|
66
|
+
* lands one level above them, so overriding the shell needed a descendant
|
|
67
|
+
* selector on Angular alone. This input is that parity. Additive: the recipe's
|
|
68
|
+
* own classes stay.
|
|
69
|
+
*/
|
|
70
|
+
set containerClassInput(val: string);
|
|
71
|
+
readonly containerClass: import("@angular/core").WritableSignal<string>;
|
|
72
|
+
/** Inline style for the same div — a string or a `{ prop: value }` map. */
|
|
73
|
+
set containerStyleInput(val: string | Record<string, string> | null);
|
|
74
|
+
readonly containerStyle: import("@angular/core").WritableSignal<string | Record<string, string>>;
|
|
46
75
|
/**
|
|
47
76
|
* Overlay the composer on the transcript (the ChatGPT anatomy): the scroll
|
|
48
77
|
* surface spans the whole column, the scrollbar runs edge to edge, and the
|
|
@@ -168,8 +197,13 @@ export declare class AparteChatComponent implements AfterViewInit, OnDestroy, Ap
|
|
|
168
197
|
appendToSegment(segmentId: string, content: string): void;
|
|
169
198
|
/** Read the current message list. */
|
|
170
199
|
getMessages(): AparteMessage[];
|
|
171
|
-
/**
|
|
172
|
-
|
|
200
|
+
/**
|
|
201
|
+
* Clear all messages + reset state. `{ revokeAttachments: false }` keeps the
|
|
202
|
+
* attachments' object URLs alive — pass it when the same messages are going back.
|
|
203
|
+
*/
|
|
204
|
+
clearMessages(options?: {
|
|
205
|
+
revokeAttachments?: boolean;
|
|
206
|
+
}): void;
|
|
173
207
|
/** Scroll the viewport to the latest message. */
|
|
174
208
|
scrollToBottom(): void;
|
|
175
209
|
/**
|
|
@@ -209,10 +243,11 @@ export declare class AparteChatComponent implements AfterViewInit, OnDestroy, Ap
|
|
|
209
243
|
/** Handle aparte-send event from the composer Web Component. */
|
|
210
244
|
onAparteSend(event: Event): void;
|
|
211
245
|
static ɵfac: i0.ɵɵFactoryDeclaration<AparteChatComponent, never>;
|
|
212
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<AparteChatComponent, "aparte-chat", never, { "messagesInput": { "alias": "messages"; "required": false; }; "placeholderInput": { "alias": "placeholder"; "required": false; }; "disabledInput": { "alias": "disabled"; "required": false; }; "submitOnEnterInput": { "alias": "submitOnEnter"; "required": false; }; "centerWhenEmptyInput": { "alias": "centerWhenEmpty"; "required": false; }; "overlayComposerInput": { "alias": "overlayComposer"; "required": false; }; "attachmentsInput": { "alias": "attachments"; "required": false; }; "elicitationInput": { "alias": "elicitation"; "required": false; }; "isTypingInput": { "alias": "isTyping"; "required": false; }; "typingTextInput": { "alias": "typingText"; "required": false; }; "layoutTransitionMs": { "alias": "layoutTransitionMs"; "required": false; }; "conversationIdInput": { "alias": "conversationId"; "required": false; }; "config": { "alias": "config"; "required": false; }; "bubbleTemplate": { "alias": "bubbleTemplate"; "required": false; }; }, { "messageSent": "messageSent"; "action": "action"; "messagesChange": "messagesChange"; "messageAppended": "messageAppended"; "typingChange": "typingChange"; "conversationCreated": "conversationCreated"; }, never, ["[slot='empty-state']", "[slot='above-composer']", "[slot='toolbar']", "[slot='composer']"], true, never>;
|
|
246
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AparteChatComponent, "aparte-chat", never, { "messagesInput": { "alias": "messages"; "required": false; }; "placeholderInput": { "alias": "placeholder"; "required": false; }; "disabledInput": { "alias": "disabled"; "required": false; }; "submitOnEnterInput": { "alias": "submitOnEnter"; "required": false; }; "centerWhenEmptyInput": { "alias": "centerWhenEmpty"; "required": false; }; "loadingInput": { "alias": "loading"; "required": false; }; "containerClassInput": { "alias": "containerClass"; "required": false; }; "containerStyleInput": { "alias": "containerStyle"; "required": false; }; "overlayComposerInput": { "alias": "overlayComposer"; "required": false; }; "attachmentsInput": { "alias": "attachments"; "required": false; }; "elicitationInput": { "alias": "elicitation"; "required": false; }; "isTypingInput": { "alias": "isTyping"; "required": false; }; "typingTextInput": { "alias": "typingText"; "required": false; }; "layoutTransitionMs": { "alias": "layoutTransitionMs"; "required": false; }; "conversationIdInput": { "alias": "conversationId"; "required": false; }; "config": { "alias": "config"; "required": false; }; "bubbleTemplate": { "alias": "bubbleTemplate"; "required": false; }; }, { "messageSent": "messageSent"; "action": "action"; "messagesChange": "messagesChange"; "messageAppended": "messageAppended"; "typingChange": "typingChange"; "conversationCreated": "conversationCreated"; }, never, ["[slot='empty-state']", "[slot='above-composer']", "[slot='toolbar']", "[slot='composer']"], true, never>;
|
|
213
247
|
static ngAcceptInputType_disabledInput: unknown;
|
|
214
248
|
static ngAcceptInputType_submitOnEnterInput: unknown;
|
|
215
249
|
static ngAcceptInputType_centerWhenEmptyInput: unknown;
|
|
250
|
+
static ngAcceptInputType_loadingInput: unknown;
|
|
216
251
|
static ngAcceptInputType_overlayComposerInput: unknown;
|
|
217
252
|
static ngAcceptInputType_attachmentsInput: unknown;
|
|
218
253
|
static ngAcceptInputType_elicitationInput: unknown;
|
|
@@ -1,12 +1,27 @@
|
|
|
1
1
|
import { OnChanges, OnDestroy, AfterViewInit, SimpleChanges } from '@angular/core';
|
|
2
|
+
import { type AparteUiHandle } from '@aparte/core';
|
|
2
3
|
import * as i0 from "@angular/core";
|
|
3
4
|
/**
|
|
4
|
-
* The imperative surface of the `AparteUi` proxy —
|
|
5
|
-
*
|
|
5
|
+
* The imperative surface of the `AparteUi` proxy — one declaration in `@aparte/core`,
|
|
6
|
+
* re-exported by all four wrappers. It used to be four hand-written copies, each
|
|
7
|
+
* promising "the same contract on all four", and it had already drifted.
|
|
6
8
|
*/
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
export type { AparteUiHandle } from '@aparte/core';
|
|
10
|
+
/**
|
|
11
|
+
* The proxy's inputs, named for parity with React/Vue/Svelte, which all export an
|
|
12
|
+
* `AparteUiProps`. Angular's are `@Input`s on the component rather than an object, so
|
|
13
|
+
* this is the shape a caller building `[props]` programmatically writes against.
|
|
14
|
+
*/
|
|
15
|
+
export interface AparteUiProps {
|
|
16
|
+
/** The custom element tag name (e.g. 'aparte-model-selector'). */
|
|
17
|
+
name: string;
|
|
18
|
+
/** Props to apply. Keys starting with `--` become CSS variables. */
|
|
19
|
+
props?: Record<string, unknown>;
|
|
20
|
+
/**
|
|
21
|
+
* Which custom events to forward through `elementEvent`. Defaults to the
|
|
22
|
+
* interactive aparté surface ({@link APARTE_DEFAULT_UI_EVENTS}).
|
|
23
|
+
*/
|
|
24
|
+
events?: string[];
|
|
10
25
|
}
|
|
11
26
|
/**
|
|
12
27
|
* AparteUiComponent - Universal UI Proxy
|
|
@@ -2,8 +2,9 @@ import { InjectionToken, type EnvironmentProviders } from '@angular/core';
|
|
|
2
2
|
import { type AparteAIProvider, type AparteClientOptions, type AparteIconProvider, type AparteLocale, type AparteMarkdownProvider, type AparteModelConfig } from '@aparte/core';
|
|
3
3
|
/**
|
|
4
4
|
* Any function that initialises a plugin — sync or async, so it can wrap a
|
|
5
|
-
* dynamic `import()` of a package YOU choose
|
|
6
|
-
*
|
|
5
|
+
* dynamic `import()` of a package YOU choose. It resolves to nothing, so `await`
|
|
6
|
+
* the import rather than returning it:
|
|
7
|
+
* `async () => { await import('@aparte/plugin-model-selector'); }`.
|
|
7
8
|
*/
|
|
8
9
|
export type ApartePluginLoader = () => void | Promise<void>;
|
|
9
10
|
/**
|
|
@@ -17,7 +18,11 @@ export interface ProvideAparteOptions {
|
|
|
17
18
|
providers?: AparteAIProvider[];
|
|
18
19
|
/** Optional plugin wiring — objects or loaders, never package-name strings. */
|
|
19
20
|
plugins?: {
|
|
20
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Action plugins, as loaders. A loader resolves to nothing, so `await` the
|
|
23
|
+
* import rather than returning it:
|
|
24
|
+
* `[async () => { await import('@aparte/plugin-model-selector'); }]`.
|
|
25
|
+
*/
|
|
21
26
|
actions?: ApartePluginLoader[];
|
|
22
27
|
/** An icon provider object, or a loader that registers one. */
|
|
23
28
|
icons?: AparteIconProvider | ApartePluginLoader;
|
|
@@ -53,8 +58,22 @@ export declare const APARTE_CONFIG_TOKEN: InjectionToken<ProvideAparteOptions>;
|
|
|
53
58
|
* `AparteAiService.connect()` needed.
|
|
54
59
|
*
|
|
55
60
|
* The components (`AparteChatComponent`, `AparteUiComponent`) are standalone and
|
|
56
|
-
* work WITHOUT this — it is config sugar.
|
|
57
|
-
*
|
|
61
|
+
* work WITHOUT this — it is config sugar. Angular is the only wrapper that has it,
|
|
62
|
+
* and the other three lose nothing: what this provider exists for is an initializer
|
|
63
|
+
* that runs before the first component and a `DestroyRef` to release the theme
|
|
64
|
+
* listener. Everything it configures is a plain call — bar `theme: 'auto'`, which is a
|
|
65
|
+
* `matchMedia` listener you own — so React, Vue and Svelte make the same ones at module
|
|
66
|
+
* scope, before the app mounts:
|
|
67
|
+
*
|
|
68
|
+
* ```ts
|
|
69
|
+
* aparteGlobalConfig.registerAIProvider(createOpenAICompatProvider(presets.OPENROUTER));
|
|
70
|
+
* aparteGlobalConfig.setModelConfig({ defaultModel: 'openai/gpt-4o-mini' });
|
|
71
|
+
* aparteGlobalConfig.setLocale(fr);
|
|
72
|
+
* document.documentElement.setAttribute('data-aparte-theme', 'dark');
|
|
73
|
+
* // 'auto' is the one option with no one-liner: match prefers-color-scheme, rewrite the
|
|
74
|
+
* // attribute on change, and drop the listener when your app tears down.
|
|
75
|
+
* // The client stays the wrapper's own: useAparteClient(), createAparteClient().
|
|
76
|
+
* ```
|
|
58
77
|
*
|
|
59
78
|
* @example
|
|
60
79
|
* bootstrapApplication(App, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aparte/angular",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"homepage": "https://apartejs.dev/frameworks/angular/",
|
|
5
5
|
"description": "Angular 19 wrapper for aparté — an ergonomic <aparte-chat> component plus services over the framework-agnostic web components.",
|
|
6
6
|
"type": "module",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"peerDependencies": {
|
|
31
31
|
"@angular/common": "^19.2.0",
|
|
32
32
|
"@angular/core": "^19.2.0",
|
|
33
|
-
"@aparte/core": ">=0.
|
|
33
|
+
"@aparte/core": ">=0.17.0 <1.0.0",
|
|
34
34
|
"rxjs": "^7.8.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"typescript": "^5.4.0",
|
|
47
47
|
"vite": "^6.0.0",
|
|
48
48
|
"zone.js": "~0.15.0",
|
|
49
|
-
"@aparte/core": "0.
|
|
49
|
+
"@aparte/core": "0.17.0"
|
|
50
50
|
},
|
|
51
51
|
"keywords": [
|
|
52
52
|
"angular",
|