@aiden-voice/widget 0.7.3 → 0.8.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 CHANGED
@@ -72,6 +72,35 @@ init({
72
72
  short-lived JWT to the page some other way. The widget itself never
73
73
  holds, requests, or sees a secret key under any circumstance.
74
74
 
75
+ Session tokens are short-lived (30 minutes), and a visitor can keep a page
76
+ open much longer before using the chat. The widget renews its session when
77
+ needed: before a request, if the token has run out or will within a minute,
78
+ and once after a `401`, retrying the request once. Conversations continue
79
+ across renewals.
80
+
81
+ - With `publishableKey` it mints a new session itself; nothing to do. Each
82
+ renewal counts toward the key's daily session quota, but only when someone
83
+ uses the chat after the token ran out (there is no background timer).
84
+ - With `sessionToken` it can't mint (that needs your secret key), so pass
85
+ `getSessionToken`: a function that fetches a fresh token from your backend
86
+ the same way you got the first. It is only called when a new token is
87
+ needed, and may return the token or a promise of it:
88
+
89
+ ```js
90
+ window.whooAidenWidget.init({
91
+ sessionToken: initialToken,
92
+ getSessionToken: async () => {
93
+ const response = await fetch('/api/aiden-session', { method: 'POST' })
94
+ return (await response.json()).token
95
+ },
96
+ })
97
+ ```
98
+
99
+ Without it, or when it fails or returns an unusable token, the visitor sees
100
+ "This chat session has expired. Reload the page to continue." and their
101
+ message is put back in the message box. A page served with an already
102
+ expired `sessionToken` also tries `getSessionToken` before giving up.
103
+
75
104
  Branding (`color`, `inkColor`, `accentColor`, `name`) follows one rule in
76
105
  both modes: **a value you pass to `init()` always wins**, anything you leave
77
106
  out is filled in from the agent's settings in whoo-aiden, and anything still
@@ -97,6 +126,9 @@ throws synchronously, at call time, if you pass both or neither.
97
126
  | --- | --- | --- |
98
127
  | `publishableKey` | Public key used to mint a session server-side. Mutually exclusive with `sessionToken`. | none (required unless `sessionToken` is set) |
99
128
  | `sessionToken` | A pre-minted session JWT from your own backend. Mutually exclusive with `publishableKey`. | none (required unless `publishableKey` is set) |
129
+ | `getSessionToken` | `sessionToken` mode only: a function returning a fresh session token (or a promise of one) from your backend, called when the current one has run out or is refused. Without it an expired session ends the chat until the page is reloaded. Ignored, with a warning, with `publishableKey` or when not a function. | none |
130
+ | `language` | Language of the widget's own text, as a BCP 47 tag (`'fr'`, `'pt-BR'`, `'zh-CN'`). Without it the widget follows the page's `<html lang>`, then English. See [Language](#language). | the page's language, else `'en'` |
131
+ | `messages` | Replaces individual built-in strings in the active language, e.g. `{ newConversation: 'Start over' }`. See [Language](#language). | none |
100
132
  | `position` | Launcher/panel corner: `'bottom-right'` or `'bottom-left'`. | `'bottom-right'` |
101
133
  | `color` | Primary accent color (any valid CSS color). Overrides the color configured in whoo-aiden; omit it to use that one. | whoo-aiden's, else `'#4f46e5'` |
102
134
  | `inkColor` | Body text color (chat title and replies). Darkened automatically if needed to stay readable. Overrides the color configured in whoo-aiden; omit it to use that one. | whoo-aiden's, else `'#111111'` |
@@ -110,13 +142,66 @@ throws synchronously, at call time, if you pass both or neither.
110
142
  | `emptyStateImageUrl` | Image (e.g. a brand lockup) shown above the greeting while the conversation is empty. `https:` or `data:image/` only. Removed if it fails to load. | none |
111
143
  | `emptyStateImageAlt` | Alt text for `emptyStateImageUrl`. Set it when the image carries meaning (e.g. your brand name); omit it for a purely decorative image. | none (decorative) |
112
144
  | `showFeedback` | Show thumbs up/down controls under each reply so visitors can rate answers (a thumbs-down opens an optional correction form). | `false` (hidden) |
113
- | `zIndex` | Stacking level of the launcher and panel over your page. The default sits above carousels, sticky headers and most overlays, while leaving room above it for a cookie or consent modal. Lower it if one of your own layers should cover the chat (see the accessibility note below). An invalid value logs a warning and uses the default. | `2147483000` |
145
+ | `zIndex` | Stacking level of the launcher and panel over your page. The default sits above carousels, sticky headers and most overlays, while leaving room above it for a cookie or consent modal. Lower it if one of your own layers should cover the chat (see the accessibility note below). While the panel fills the screen (a viewport 400px wide or less, or 420px tall or less), it is a modal dialog drawn above everything, whatever `zIndex` says. An invalid value logs a warning and uses the default. | `2147483000` |
114
146
  | `apiBaseUrl` | Override the whoo-aiden API host the widget talks to. | `'https://api.aidenvoice.com'` |
115
147
 
116
148
  ### When something else already owns the corner
117
149
 
118
150
  Some third-party overlays (accessibility toolbars, chat or cookie widgets) sit at the maximum possible z-index, `2147483647`, in the same corner. No `zIndex` value can beat that: at an equal level, whichever element comes later in the page wins, and those overlays are usually injected after the widget. Move the widget to the other corner with `position: 'bottom-left'` instead.
119
151
 
152
+ ## Language
153
+
154
+ The widget's own text (buttons, labels, status and error messages, and what screen readers announce) comes in eleven languages: English (`en`), French (`fr`), Spanish (`es`), Portuguese (`pt`), German (`de`), Italian (`it`), Japanese (`ja`), Simplified Chinese (`zh`), Russian (`ru`), Hindi (`hi`) and Arabic (`ar`).
155
+
156
+ - **How the language is chosen:** the `language` option if you pass one, then your page's `<html lang>`, then English. So a French page gets a French widget without any setup. An unsupported `language` value is ignored with a console warning; an unsupported page language falls back to English silently.
157
+ - **Regional tags** match their language: `fr-CA` is French, any `pt-*` gets Brazilian Portuguese, any `es-*` gets Latin American Spanish. Simplified Chinese matches `zh`, `zh-CN`, `zh-SG` and `zh-Hans`. Traditional Chinese (`zh-TW`, `zh-HK`, `zh-Hant`) is not supported and falls back to English.
158
+ - **Decided once, at `init()`.** If your single-page app changes `<html lang>` later, pass `language` (unmount and `init()` again to switch).
159
+ - **Arabic is right to left:** the panel's layout mirrors (the visitor's messages on the left). The corner set by `position` doesn't change.
160
+ - **Not translated:** the agent's replies (the model answers in whatever language it does), and `greeting`, `title` and `name`, which you write in the language you want. Each message's text takes its direction from its own content, so an English reply in an Arabic widget, or the reverse, still reads correctly.
161
+ - **The widget marks its own language** (`lang` and `dir` on its root, naming the variant it ships: `pt-BR`, `es-419`, `zh-Hans`), so screen readers pronounce it correctly even on a page in another language.
162
+ - **Upgrading from a version before 0.8.0:** a page whose `<html lang>` is one of these languages now gets the widget in that language, where it was English before. Pass `language: 'en'` to keep it in English.
163
+
164
+ **Changing the wording.** `messages` replaces any built-in string in the active language. Write overrides in that language, or set `language` to the language of your overrides. `chatWith` takes `{name}`, the agent's name. Unknown keys, and values that aren't non-blank strings, are ignored with a console warning.
165
+
166
+ ```js
167
+ window.whooAidenWidget.init({
168
+ publishableKey: 'pk_live_…',
169
+ language: 'es',
170
+ messages: { newConversation: 'Empezar de nuevo' },
171
+ })
172
+ ```
173
+
174
+ | Key | English | Where |
175
+ |---|---|---|
176
+ | `openChat` | Open chat | launcher name, closed |
177
+ | `closeChat` | Close chat | launcher name while open, header ✕ |
178
+ | `chatWith` | Chat with {name} | panel title and dialog name (unless `title` is set) |
179
+ | `newConversation` | New conversation | header button |
180
+ | `conversation` | Conversation | message list region name |
181
+ | `you` | You | screen-reader speaker label on the visitor's messages |
182
+ | `message` | Message | message box label |
183
+ | `send` | Send | composer button |
184
+ | `lookingItUp` | Looking that up for you… | slow-reply notice |
185
+ | `goodResponse` | Good response | thumbs-up name |
186
+ | `badResponse` | Bad response | thumbs-down name |
187
+ | `additionalFeedback` | Additional feedback | feedback text field label |
188
+ | `feedbackPlaceholder` | What was wrong? (optional) | feedback text field placeholder |
189
+ | `feedbackCategory` | Feedback category | feedback select label |
190
+ | `selectReason` | Select a reason (optional) | feedback select first option |
191
+ | `categoryFactual` | Factual error | feedback option |
192
+ | `categoryIncomplete` | Incomplete | feedback option |
193
+ | `categoryTone` | Off tone | feedback option |
194
+ | `categoryOther` | Other | feedback option |
195
+ | `submit` | Submit | feedback form button |
196
+ | `cancel` | Cancel | feedback form button |
197
+ | `feedbackThanks` | Thanks for the feedback | feedback status |
198
+ | `feedbackFailed` | Couldn't send feedback | feedback status |
199
+ | `conversationCleared` | Conversation cleared | screen-reader announcement |
200
+ | `genericError` | Something went wrong, please try again. | error alert |
201
+ | `sessionExpired` | This chat session has expired. Reload the page to continue. | error alert |
202
+
203
+ **About the translations:** they were machine-drafted and cross-checked by independent AI agents (back-translation, critique, and rendering checks), not reviewed by native speakers. [docs/translation-verification.md](docs/translation-verification.md) records every check. If any wording reads wrong, override it with `messages`, and please tell us.
204
+
120
205
  ## Theming
121
206
 
122
207
  `color`, `inkColor` and `accentColor` set the brand colors, and the widget calculates the rest (the text on your color, the header text, and so on) so everything stays readable. When an edge case breaks that, the `theme` option overrides any individual color, the font, and the launcher icons.
@@ -441,9 +526,10 @@ responsibility:
441
526
  accent for links in replies) get the same treatment: each is darkened
442
527
  just enough to stay readable on the reply bubble. See
443
528
  `docs/accessibility-report.md` for details.
444
- - **Page language:** the widget renders inside your page's DOM and
445
- inherits language from your document's `<html lang>` attribute; there is
446
- no separate widget-level locale override.
529
+ - **Page language:** set `<html lang>` correctly. The widget follows it (or
530
+ your `language` option, which wins) and marks its own `lang` and `dir`, so
531
+ screen readers pronounce it correctly even when it differs from your page.
532
+ See [Language](#language).
447
533
  - **Don't hide the mount point:** don't place the widget's container (or
448
534
  move it, via your own script) inside an element with `aria-hidden="true"`
449
535
  or `inert` — that hides it from assistive technology regardless of the
@@ -473,19 +559,23 @@ The widget distinguishes two deliberately different error tiers:
473
559
  broken-looking ever appears on the page.
474
560
  - **Failures once the widget is already visible and in an active chat**
475
561
  (a network error, an SSE connection dropping mid-stream, an error
476
- response from the server, a session that runs out while the page is open)
477
- show a short, non-technical inline message in the chat panel itself (e.g.
478
- "Something went wrong, please try again"), leaving any partial response
479
- already rendered in place above it.
562
+ response from the server) show a short, non-technical inline message in the
563
+ chat panel itself (e.g. "Something went wrong, please try again"), leaving
564
+ any partial response already rendered in place above it. A session that
565
+ runs out while the page is open is renewed (see Usage); only when that is
566
+ impossible does the panel say "This chat session has expired. Reload the
567
+ page to continue." instead.
480
568
 
481
569
  How a bad `sessionToken` is caught at start-up, without the widget ever
482
570
  holding a key to check its signature:
483
571
 
484
- - If the token is a JWT whose `exp` has already passed, `init()` treats it as
485
- an init failure straight away, with no network request. A token the widget
572
+ - If the token is a JWT whose `exp` has already passed, `init()` asks
573
+ `getSessionToken` for a new one when you passed it, and otherwise treats it
574
+ as an init failure straight away, with no network request. A token the widget
486
575
  can't read (not a JWT, no `exp`) is never rejected locally.
487
576
  - Otherwise, when the widget looks up the agent's branding with the token
488
- (see above), a `401` or `403` answer is an init failure too. That lookup is
577
+ (see above), a `403` answer is an init failure too, and so is a `401` unless
578
+ `getSessionToken` supplies a token the server accepts. That lookup is
489
579
  skipped when you pass every branding value yourself, so in that case only the
490
580
  expiry check applies and a token the server would refuse for another reason
491
581
  fails on the visitor's first message instead.
@@ -1,8 +1,10 @@
1
1
  import { RefObject } from 'preact';
2
- export declare function Composer({ value, onChange, onSend, disabled, inputRef, }: {
2
+ import { WidgetMessages } from '../i18n/messages';
3
+ export declare function Composer({ value, onChange, onSend, disabled, inputRef, text, }: {
3
4
  value: string;
4
5
  onChange: (value: string) => void;
5
6
  onSend: () => void;
6
7
  disabled: boolean;
7
8
  inputRef?: RefObject<HTMLInputElement | null>;
9
+ text?: WidgetMessages;
8
10
  }): import('preact').JSX.Element;
@@ -1,6 +1,7 @@
1
1
  import { RefObject } from 'preact';
2
+ import { WidgetMessages } from '../i18n/messages';
2
3
  import { LauncherIcon, LauncherOpenIcon } from '../types';
3
- export declare function Launcher({ isOpen, onClick, iconUrl, icon, openIconUrl, openIcon, buttonRef, }: {
4
+ export declare function Launcher({ isOpen, onClick, iconUrl, icon, openIconUrl, openIcon, buttonRef, text, }: {
4
5
  isOpen: boolean;
5
6
  onClick: () => void;
6
7
  iconUrl?: string;
@@ -8,4 +9,5 @@ export declare function Launcher({ isOpen, onClick, iconUrl, icon, openIconUrl,
8
9
  openIconUrl?: string;
9
10
  openIcon?: LauncherOpenIcon;
10
11
  buttonRef?: RefObject<HTMLButtonElement | null>;
12
+ text?: WidgetMessages;
11
13
  }): import('preact').JSX.Element;
@@ -1,6 +1,7 @@
1
1
  import { RefObject } from 'preact';
2
2
  import { FeedbackCategory, MessageFeedbackState } from '../controller';
3
- export declare function MessageFeedback({ state, containerRef, onThumbsUp, onThumbsDown, onDraftChange, onSubmitDetailed, onCancel, }: {
3
+ import { WidgetMessages } from '../i18n/messages';
4
+ export declare function MessageFeedback({ state, containerRef, onThumbsUp, onThumbsDown, onDraftChange, onSubmitDetailed, onCancel, text, }: {
4
5
  state: MessageFeedbackState;
5
6
  containerRef?: RefObject<HTMLElement>;
6
7
  onThumbsUp: () => void;
@@ -8,4 +9,5 @@ export declare function MessageFeedback({ state, containerRef, onThumbsUp, onThu
8
9
  onDraftChange: (correction: string, category: '' | FeedbackCategory) => void;
9
10
  onSubmitDetailed: (correction: string, category: '' | FeedbackCategory) => void;
10
11
  onCancel: () => void;
12
+ text?: WidgetMessages;
11
13
  }): import('preact').JSX.Element;
@@ -1,7 +1,8 @@
1
1
  import { FeedbackCategory, Message, MessageFeedbackState } from '../controller';
2
+ import { WidgetMessages } from '../i18n/messages';
2
3
  type DraftChangeHandler = (messageId: string, correction: string, category: '' | FeedbackCategory) => void;
3
4
  type SubmitHandler = (messageId: string, correction: string, category: '' | FeedbackCategory) => void;
4
- export declare function MessageList({ messages, messageFeedback, announcement, emptyStateImage, agentName, showFeedback, isStreaming, isSlowResponse, onThumbsUp, onThumbsDown, onDraftChange, onSubmitDetailed, onCancelFeedback, }: {
5
+ export declare function MessageList({ messages, messageFeedback, announcement, emptyStateImage, agentName, showFeedback, isStreaming, isSlowResponse, onThumbsUp, onThumbsDown, onDraftChange, onSubmitDetailed, onCancelFeedback, text, }: {
5
6
  messages: Message[];
6
7
  messageFeedback: Record<string, MessageFeedbackState>;
7
8
  announcement: string | null;
@@ -18,5 +19,6 @@ export declare function MessageList({ messages, messageFeedback, announcement, e
18
19
  onDraftChange?: DraftChangeHandler;
19
20
  onSubmitDetailed: SubmitHandler;
20
21
  onCancelFeedback: (messageId: string) => void;
22
+ text?: WidgetMessages;
21
23
  }): import('preact').JSX.Element;
22
24
  export {};
package/dist/config.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { WidgetMessages } from './i18n/messages';
1
2
  import { ThemeColorOverrides } from './themeRoles';
2
3
  import { LauncherIcon, LauncherOpenIcon, WidgetConfig } from './types';
3
4
  export declare const DEFAULT_API_BASE_URL = "https://api.aidenvoice.com";
@@ -6,6 +7,8 @@ export declare function resolveZIndex(zIndex: unknown): number;
6
7
  export declare const DEFAULT_AGENT_NAME = "Aiden";
7
8
  export declare function trimmedName(name: unknown): string;
8
9
  export declare function validateConfig(config: WidgetConfig): void;
10
+ export declare function normalizeGetSessionToken(config: WidgetConfig): (() => string | Promise<string>) | undefined;
11
+ export declare function normalizeMessages(value: unknown): Partial<WidgetMessages>;
9
12
  export declare function safeFontFamily(value: unknown): string | undefined;
10
13
  export interface NormalizedTheme {
11
14
  colors: ThemeColorOverrides;
@@ -1,7 +1,10 @@
1
1
  import { NormalizedTheme } from './config';
2
+ import { SupportedLanguage } from './i18n';
3
+ import { WidgetMessages } from './i18n/messages';
2
4
  import { WidgetConfig } from './types';
3
5
  export declare const SLOW_RESPONSE_DELAY_MS = 8000;
4
6
  export declare const BRANDING_LOOKUP_WAIT_MS = 3000;
7
+ export declare const TOKEN_RENEWAL_MARGIN_MS = 60000;
5
8
  export interface Message {
6
9
  role: 'user' | 'assistant';
7
10
  content: string;
@@ -36,6 +39,9 @@ export declare class WidgetController {
36
39
  private state;
37
40
  private readonly listeners;
38
41
  private sessionToken;
42
+ private sessionTokenExpiresAt;
43
+ private tokenRenewal;
44
+ private readonly getSessionToken;
39
45
  private conversationId;
40
46
  private readonly storageIdentifier;
41
47
  private activeRequestController;
@@ -46,6 +52,10 @@ export declare class WidgetController {
46
52
  readonly emptyStateImageUrl: string | undefined;
47
53
  readonly emptyStateImageAlt: string;
48
54
  readonly showFeedback: boolean;
55
+ readonly text: WidgetMessages;
56
+ readonly language: SupportedLanguage;
57
+ readonly languageTag: string;
58
+ readonly dir: 'ltr' | 'rtl';
49
59
  constructor(config: WidgetConfig);
50
60
  getState(): WidgetState;
51
61
  subscribe(listener: Listener): () => void;
@@ -63,5 +73,9 @@ export declare class WidgetController {
63
73
  setFeedbackDraft(messageId: string, correction: string, category: '' | FeedbackCategory): void;
64
74
  cancelFeedback(messageId: string): void;
65
75
  submitFeedback(messageId: string, rating: 'up' | 'down', correction?: string, category?: FeedbackCategory): Promise<void>;
76
+ private currentToken;
77
+ private renewToken;
78
+ private fetchNewToken;
79
+ private withSession;
66
80
  }
67
81
  export {};
@@ -0,0 +1,26 @@
1
+ import { WidgetMessages } from './messages';
2
+ declare const DICTIONARIES: {
3
+ readonly en: WidgetMessages;
4
+ readonly fr: WidgetMessages;
5
+ readonly es: WidgetMessages;
6
+ readonly pt: WidgetMessages;
7
+ readonly de: WidgetMessages;
8
+ readonly it: WidgetMessages;
9
+ readonly ja: WidgetMessages;
10
+ readonly zh: WidgetMessages;
11
+ readonly ru: WidgetMessages;
12
+ readonly hi: WidgetMessages;
13
+ readonly ar: WidgetMessages;
14
+ };
15
+ export type SupportedLanguage = keyof typeof DICTIONARIES;
16
+ export declare const SUPPORTED_LANGUAGES: readonly SupportedLanguage[];
17
+ export declare function messagesFor(language: SupportedLanguage): WidgetMessages;
18
+ export declare function resolveLanguage(option: unknown, pageLang: unknown): {
19
+ language: SupportedLanguage;
20
+ tag: string;
21
+ dir: 'ltr' | 'rtl';
22
+ };
23
+ export declare function format(template: string, values: {
24
+ name: string;
25
+ }): string;
26
+ export type { WidgetMessages };
@@ -0,0 +1,2 @@
1
+ import { WidgetMessages } from '../messages';
2
+ export declare const ar: WidgetMessages;
@@ -0,0 +1,2 @@
1
+ import { WidgetMessages } from '../messages';
2
+ export declare const de: WidgetMessages;
@@ -0,0 +1,2 @@
1
+ import { WidgetMessages } from '../messages';
2
+ export declare const es: WidgetMessages;
@@ -0,0 +1,2 @@
1
+ import { WidgetMessages } from '../messages';
2
+ export declare const fr: WidgetMessages;
@@ -0,0 +1,2 @@
1
+ import { WidgetMessages } from '../messages';
2
+ export declare const hi: WidgetMessages;
@@ -0,0 +1,2 @@
1
+ import { WidgetMessages } from '../messages';
2
+ export declare const it: WidgetMessages;
@@ -0,0 +1,2 @@
1
+ import { WidgetMessages } from '../messages';
2
+ export declare const ja: WidgetMessages;
@@ -0,0 +1,2 @@
1
+ import { WidgetMessages } from '../messages';
2
+ export declare const pt: WidgetMessages;
@@ -0,0 +1,2 @@
1
+ import { WidgetMessages } from '../messages';
2
+ export declare const ru: WidgetMessages;
@@ -0,0 +1,2 @@
1
+ import { WidgetMessages } from '../messages';
2
+ export declare const zh: WidgetMessages;
@@ -0,0 +1,30 @@
1
+ export interface WidgetMessages {
2
+ openChat: string;
3
+ closeChat: string;
4
+ chatWith: string;
5
+ newConversation: string;
6
+ conversation: string;
7
+ you: string;
8
+ message: string;
9
+ send: string;
10
+ lookingItUp: string;
11
+ goodResponse: string;
12
+ badResponse: string;
13
+ additionalFeedback: string;
14
+ feedbackPlaceholder: string;
15
+ feedbackCategory: string;
16
+ selectReason: string;
17
+ categoryFactual: string;
18
+ categoryIncomplete: string;
19
+ categoryTone: string;
20
+ categoryOther: string;
21
+ submit: string;
22
+ cancel: string;
23
+ feedbackThanks: string;
24
+ feedbackFailed: string;
25
+ conversationCleared: string;
26
+ genericError: string;
27
+ sessionExpired: string;
28
+ }
29
+ export declare const ENGLISH: WidgetMessages;
30
+ export declare const MESSAGE_KEYS: (keyof WidgetMessages)[];
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import { LauncherIcon, LauncherOpenIcon, WidgetConfig, WidgetHandle, WidgetLayout, WidgetTheme } from './types';
2
2
  export declare function init(config: WidgetConfig): WidgetHandle;
3
+ export { SUPPORTED_LANGUAGES } from './i18n';
4
+ export type { WidgetMessages } from './i18n/messages';
3
5
  export type { ContrastWarning, ResolvedTheme, ThemeInput } from './theme';
4
6
  export { resolveTheme } from './theme';
5
7
  export type { ThemeColorOverrides, ThemeColorRole } from './themeRoles';
@@ -1 +1,3 @@
1
+ export declare function sessionTokenExp(token: string): number | null;
1
2
  export declare function isExpiredSessionToken(token: string, nowMs?: number): boolean;
3
+ export declare function receivedTokenExpiresAt(token: string, receivedAtMs?: number): number | null;
package/dist/types.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { WidgetMessages } from './i18n/messages';
1
2
  export type LauncherIcon = 'chat' | 'message' | 'sparkle';
2
3
  export type LauncherOpenIcon = 'chevron-down' | 'close';
3
4
  export interface WidgetTheme {
@@ -72,6 +73,27 @@ export interface WidgetLayout {
72
73
  export interface WidgetConfig {
73
74
  publishableKey?: string;
74
75
  sessionToken?: string;
76
+ /**
77
+ * `sessionToken` mode only. Called when the session token has run out (or
78
+ * the server refuses it), to get a fresh one from your backend, which mints
79
+ * it the same way as the first. Without it, an expired session ends the
80
+ * chat until the page is reloaded. May return the token or a promise of it.
81
+ * (With `publishableKey` the widget renews its session by itself.)
82
+ */
83
+ getSessionToken?: () => string | Promise<string>;
84
+ /**
85
+ * The language of the widget's own text, as a BCP 47 tag ('fr', 'pt-BR',
86
+ * 'zh-CN'). Without it the widget follows the page's <html lang>, then
87
+ * English. Supported: en, fr, es, pt, de, it, ja, zh (Simplified), ru, hi,
88
+ * ar (right to left). An unsupported value is ignored with a warning.
89
+ */
90
+ language?: string;
91
+ /**
92
+ * Replaces individual built-in strings in whichever language is active,
93
+ * e.g. { newConversation: 'Start over' }. `chatWith` takes {name}.
94
+ * Unknown keys and blank or non-string values are ignored with a warning.
95
+ */
96
+ messages?: Partial<WidgetMessages>;
75
97
  position?: 'bottom-right' | 'bottom-left';
76
98
  /**
77
99
  * Primary accent color. Overrides the color configured in whoo-aiden, in
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const WIDGET_VERSION = "0.7.3";
1
+ export declare const WIDGET_VERSION = "0.8.0";
@@ -2,3 +2,4 @@ export declare const FULL_SCREEN_QUERY = "(max-width: 400px), (max-height: 420px
2
2
  export declare const FIT_VISIBLE_ATTRIBUTE = "data-fit-visible";
3
3
  export declare function followVisualViewport(panel: HTMLElement): () => void;
4
4
  export declare function lockPageScrollWhileFullScreen(): () => void;
5
+ export declare function modalWhileFullScreen(panel: HTMLDialogElement): () => void;