@helpai/elements 0.38.0 → 0.40.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/configurator.mjs +2 -1
- package/elements-web-component.esm.js +19 -19
- package/elements-web-component.esm.js.map +3 -3
- package/elements.cjs.js +19 -19
- package/elements.cjs.js.map +3 -3
- package/elements.esm.js +19 -19
- package/elements.esm.js.map +3 -3
- package/elements.js +19 -19
- package/elements.js.map +3 -3
- package/index.d.ts +15 -2
- package/index.mjs +43 -15
- package/package.json +1 -1
- package/schema.d.ts +26 -26
- package/schema.json +5 -0
- package/schema.mjs +2 -1
- package/web-component.mjs +43 -15
package/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, H as HandshakeResponse, L as Link, S as ServerConfig, b as SiteConfig, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial } from './deployment-
|
|
1
|
+
export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, H as HandshakeResponse, L as Link, S as ServerConfig, b as SiteConfig, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial } from './deployment-MbF78Pdq.js';
|
|
2
2
|
import 'zod';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -40,7 +40,7 @@ interface ClientStorage {
|
|
|
40
40
|
* populated {@link Strings} map. UI components then read `strings.send` as a
|
|
41
41
|
* normal property access — no per-render lookup, no per-render allocation.
|
|
42
42
|
*/
|
|
43
|
-
type StringKey = "launcherOpen" | "panelTitle" | "composerPlaceholder" | "send" | "stop" | "attach" | "micStart" | "micStop" | "micUnsupported" | "expand" | "collapse" | "fullscreen" | "exitFullscreen" | "resizeHandle" | "scrollToBottom" | "popOut" | "close" | "moreActions" | "soundOn" | "soundOff" | "language" | "theme" | "themeAuto" | "themeLight" | "themeDark" | "textSize" | "textSizeSmall" | "textSizeNormal" | "textSizeLarge" | "history" | "historyTitle" | "historyEmpty" | "historyLoading" | "historyBack" | "historyContinue" | "conversationLoading" | "conversationClosed" | "startNewConversation" | "dateToday" | "dateYesterday" | "dateLastWeek" | "dateOlder" | "newConversation" | "dropZone" | "attachmentTooLarge" | "attachmentTooMany" | "attachmentMimeRejected" | "errorRetry" | "errorGeneric" | "errorRateLimited" | "loading" | "thinking" | "thoughts" | "usedTool" | "collapseSidebar" | "expandSidebar" | "formSubmit" | "formSkip" | "formSubmitted" | "formSkipped" | "formFillOut" | "formRequired" | "formInvalidEmail" | "formInvalidTel" | "formInvalidUrl" | "formInvalidNumber" | "formTooShort" | "formTooLong" | "formNumberTooSmall" | "formNumberTooLarge" | "formPatternMismatch" | "formChooseAtLeast" | "formChooseAtMost" | "formOther" | "formOtherPlaceholder" | "inputRequired" | "inputSubmit" | "inputSkip" | "inputSubmitted" | "approvalRequired" | "approve" | "reject" | "approved" | "rejected" | "approvalReason" | "stepNoLongerActive" | "tabHome" | "tabConversations" | "tabHelp" | "tabNews" | "modulesEmpty" | "moduleBack" | "contentLoading" | "homeGreeting" | "homeGreetingNamed" | "homeGreetingLead" | "homeSearchPlaceholder" | "homeContentTitle" | "homeStatus" | "helpTitle" | "helpSearchPlaceholder" | "helpEmpty" | "helpLoading" | "helpSearchEmpty" | "newsTitle" | "newsEmpty" | "newsLoading" | "newsBack" | "newsPublishedAt";
|
|
43
|
+
type StringKey = "launcherOpen" | "launcherLabel" | "panelTitle" | "composerPlaceholder" | "send" | "stop" | "attach" | "micStart" | "micStop" | "micUnsupported" | "expand" | "collapse" | "fullscreen" | "exitFullscreen" | "resizeHandle" | "scrollToBottom" | "popOut" | "close" | "moreActions" | "soundOn" | "soundOff" | "language" | "theme" | "themeAuto" | "themeLight" | "themeDark" | "textSize" | "textSizeSmall" | "textSizeNormal" | "textSizeLarge" | "history" | "historyTitle" | "historyEmpty" | "historyLoading" | "historyBack" | "historyContinue" | "conversationLoading" | "conversationClosed" | "startNewConversation" | "dateToday" | "dateYesterday" | "dateLastWeek" | "dateOlder" | "newConversation" | "dropZone" | "attachmentTooLarge" | "attachmentTooMany" | "attachmentMimeRejected" | "errorRetry" | "errorGeneric" | "errorRateLimited" | "loading" | "thinking" | "thoughts" | "usedTool" | "collapseSidebar" | "expandSidebar" | "formSubmit" | "formSkip" | "formSubmitted" | "formSkipped" | "formFillOut" | "formRequired" | "formInvalidEmail" | "formInvalidTel" | "formInvalidUrl" | "formInvalidNumber" | "formTooShort" | "formTooLong" | "formNumberTooSmall" | "formNumberTooLarge" | "formPatternMismatch" | "formChooseAtLeast" | "formChooseAtMost" | "formOther" | "formOtherPlaceholder" | "inputRequired" | "inputSubmit" | "inputSkip" | "inputSubmitted" | "approvalRequired" | "approve" | "reject" | "approved" | "rejected" | "approvalReason" | "stepNoLongerActive" | "tabHome" | "tabConversations" | "tabHelp" | "tabNews" | "modulesEmpty" | "moduleBack" | "contentLoading" | "homeGreeting" | "homeGreetingNamed" | "homeGreetingLead" | "homeSearchPlaceholder" | "homeContentTitle" | "homeStatus" | "helpTitle" | "helpSearchPlaceholder" | "helpEmpty" | "helpLoading" | "helpSearchEmpty" | "newsTitle" | "newsEmpty" | "newsLoading" | "newsBack" | "newsPublishedAt";
|
|
44
44
|
/** A partial map for one locale — what overrides look like on the wire. */
|
|
45
45
|
type LocaleStrings = Partial<Record<StringKey, string>>;
|
|
46
46
|
/**
|
|
@@ -89,6 +89,11 @@ type StringsOverride = LocaleStrings | Partial<Record<string, LocaleStrings>>;
|
|
|
89
89
|
* `visitorId` is the deliberate exception: it stays global so the same browser
|
|
90
90
|
* is one anonymous visitor everywhere (`${brand.cssPrefix}.visitorId`).
|
|
91
91
|
*
|
|
92
|
+
* A `storageVersion` (when set) folds a `.v<version>` segment into EVERY key —
|
|
93
|
+
* including the global `visitorId` — so bumping it force-resets the entire
|
|
94
|
+
* client-side namespace for all users (a full fresh start: new visitor id,
|
|
95
|
+
* conversation, prefs, panel state). Unset → the unversioned keys.
|
|
96
|
+
*
|
|
92
97
|
* Storage is pluggable via {@link ClientStorage} — pass a custom adapter
|
|
93
98
|
* to add encryption, logging, or use a non-localStorage backend.
|
|
94
99
|
*/
|
|
@@ -1248,6 +1253,14 @@ interface ResolvedOptions {
|
|
|
1248
1253
|
interface ServerConfig {
|
|
1249
1254
|
/** Data-API base override — adopted only when the host didn't set one. */
|
|
1250
1255
|
dataApiBaseUrl?: string;
|
|
1256
|
+
/**
|
|
1257
|
+
* Storage-schema version — the deployment-owned force-reset lever, pushed ONLY
|
|
1258
|
+
* via the handshake (deliberately not an embed attribute / `init` option).
|
|
1259
|
+
* Pushing a new value abandons every client's prior storage namespace
|
|
1260
|
+
* (visitor id, conversation, prefs, panel state, caches) on next load. The
|
|
1261
|
+
* widget stashes it and the next mount folds `.v<version>` into every key.
|
|
1262
|
+
*/
|
|
1263
|
+
storageVersion?: string;
|
|
1251
1264
|
presentation?: PresentationOptions;
|
|
1252
1265
|
behavior?: BehaviorOptions;
|
|
1253
1266
|
theme?: ThemePreference | ThemeOverrides;
|
package/index.mjs
CHANGED
|
@@ -62,6 +62,7 @@ var STRINGS_EN = {
|
|
|
62
62
|
historyTitle: "Conversation history",
|
|
63
63
|
language: "Language",
|
|
64
64
|
launcherOpen: "Open chat",
|
|
65
|
+
launcherLabel: "Chat with us",
|
|
65
66
|
micStart: "Start voice input",
|
|
66
67
|
micStop: "Stop voice input",
|
|
67
68
|
micUnsupported: "Voice input is not supported in this browser",
|
|
@@ -175,6 +176,7 @@ var STRINGS_FR = {
|
|
|
175
176
|
historyTitle: "Historique des conversations",
|
|
176
177
|
language: "Langue",
|
|
177
178
|
launcherOpen: "Ouvrir le chat",
|
|
179
|
+
launcherLabel: "Discuter avec nous",
|
|
178
180
|
micStart: "D\xE9marrer la saisie vocale",
|
|
179
181
|
micStop: "Arr\xEAter la saisie vocale",
|
|
180
182
|
micUnsupported: "La saisie vocale n'est pas prise en charge par ce navigateur",
|
|
@@ -1047,8 +1049,11 @@ function fillRandom(view) {
|
|
|
1047
1049
|
var log2 = logger.scope("persistence");
|
|
1048
1050
|
function createPersistence(widgetId, storage = defaultStorage, deploymentId) {
|
|
1049
1051
|
const scope = deploymentId ? `${widgetId}.${deploymentId}` : widgetId;
|
|
1050
|
-
const
|
|
1051
|
-
const
|
|
1052
|
+
const KEY_STORAGE_VERSION = `${BRAND.cssPrefix}.storageVersion`;
|
|
1053
|
+
const activeVersion = storage.get(KEY_STORAGE_VERSION) ?? void 0;
|
|
1054
|
+
const version2 = activeVersion ? `.v${activeVersion}` : "";
|
|
1055
|
+
const prefix = `${BRAND.cssPrefix}.${scope}${version2}`;
|
|
1056
|
+
const KEY_VISITOR = `${BRAND.cssPrefix}${version2}.visitorId`;
|
|
1052
1057
|
const KEY_CONVERSATION = `${prefix}.conversationId`;
|
|
1053
1058
|
const KEY_USER_PREFS = `${prefix}.userPrefs`;
|
|
1054
1059
|
const KEY_PANEL_OPEN = `${prefix}.panelOpen`;
|
|
@@ -1159,6 +1164,12 @@ function createPersistence(widgetId, storage = defaultStorage, deploymentId) {
|
|
|
1159
1164
|
log2.warn("saveFormDone serialise failed", { error });
|
|
1160
1165
|
}
|
|
1161
1166
|
},
|
|
1167
|
+
rememberStorageVersion(serverVersion) {
|
|
1168
|
+
if (serverVersion && serverVersion !== storage.get(KEY_STORAGE_VERSION)) {
|
|
1169
|
+
log2.debug("rememberStorageVersion (force-reset on next load)", { version: serverVersion });
|
|
1170
|
+
storage.set(KEY_STORAGE_VERSION, serverVersion);
|
|
1171
|
+
}
|
|
1172
|
+
},
|
|
1162
1173
|
clearConversation() {
|
|
1163
1174
|
storage.remove(KEY_CONVERSATION);
|
|
1164
1175
|
}
|
|
@@ -1395,7 +1406,7 @@ import { h, render as renderPreact } from "preact";
|
|
|
1395
1406
|
|
|
1396
1407
|
// src/ui/app.tsx
|
|
1397
1408
|
import { useCallback as useCallback6, useEffect as useEffect17, useMemo as useMemo3, useRef as useRef9, useState as useState13 } from "preact/hooks";
|
|
1398
|
-
import { useComputed as useComputed7, useSignal as useSignal2 } from "@preact/signals";
|
|
1409
|
+
import { batch, useComputed as useComputed7, useSignal as useSignal2 } from "@preact/signals";
|
|
1399
1410
|
|
|
1400
1411
|
// src/core/handshake-shape.ts
|
|
1401
1412
|
function isPlainObject2(raw) {
|
|
@@ -3195,7 +3206,7 @@ function Launcher({ onToggle, launcher, strings, leaving, edgeTab }) {
|
|
|
3195
3206
|
"aria-label": strings.launcherOpen,
|
|
3196
3207
|
children: [
|
|
3197
3208
|
renderIcon(launcher.icon),
|
|
3198
|
-
showLabel ? /* @__PURE__ */ jsx2("span", { class: `${p3}-fab-label`, children: launcher.label }) : null
|
|
3209
|
+
showLabel ? /* @__PURE__ */ jsx2("span", { class: `${p3}-fab-label`, children: localizeText(strings, launcher.label ?? "") }) : null
|
|
3199
3210
|
]
|
|
3200
3211
|
}
|
|
3201
3212
|
);
|
|
@@ -6736,6 +6747,9 @@ function useLauncherCallout({ callout, persistence }) {
|
|
|
6736
6747
|
import { jsx as jsx36, jsxs as jsxs31 } from "preact/jsx-runtime";
|
|
6737
6748
|
var log17 = logger.scope("app");
|
|
6738
6749
|
var p32 = BRAND.cssPrefix;
|
|
6750
|
+
function makeLocalizedWelcome(w, strings) {
|
|
6751
|
+
return makeInstantWelcomeMessage({ ...w, text: localizeText(strings, w.text) });
|
|
6752
|
+
}
|
|
6739
6753
|
function App({ options, hostElement, bus }) {
|
|
6740
6754
|
const [persistence] = useState13(
|
|
6741
6755
|
() => createPersistence(options.widgetId, options.storage, options.aiAgentDeploymentId)
|
|
@@ -6806,6 +6820,7 @@ function App({ options, hostElement, bus }) {
|
|
|
6806
6820
|
const [agent, setAgent] = useState13(null);
|
|
6807
6821
|
const [suggestions, setSuggestions] = useState13([]);
|
|
6808
6822
|
const [activeCancel, setActiveCancel] = useState13(null);
|
|
6823
|
+
const stringsRef = useRef9(options.strings);
|
|
6809
6824
|
const [parsedSite, setParsedSite] = useState13(void 0);
|
|
6810
6825
|
const [parsedBlocks, setParsedBlocks] = useState13(void 0);
|
|
6811
6826
|
const [sidebarCollapsed, setSidebarCollapsed] = useState13(() => persistence.loadSidebarCollapsed() ?? false);
|
|
@@ -6890,7 +6905,7 @@ function App({ options, hostElement, bus }) {
|
|
|
6890
6905
|
const playWelcome = useCallback6(
|
|
6891
6906
|
(welcomeMessages) => {
|
|
6892
6907
|
if (!welcomeMessages || welcomeMessages.length === 0) return;
|
|
6893
|
-
messagesSig.value = welcomeMessages.map(
|
|
6908
|
+
messagesSig.value = welcomeMessages.map((w) => makeLocalizedWelcome(w, stringsRef.current));
|
|
6894
6909
|
},
|
|
6895
6910
|
[messagesSig]
|
|
6896
6911
|
);
|
|
@@ -6923,7 +6938,7 @@ function App({ options, hostElement, bus }) {
|
|
|
6923
6938
|
const welcomeAnchor = (timelineStamps.length ? Math.min(...timelineStamps) : Date.now()) - 1;
|
|
6924
6939
|
const loadedIds = new Set(loaded.map((m) => m.id));
|
|
6925
6940
|
const welcomeRows = (welcomeRef.current?.messages ?? []).filter((w) => !loadedIds.has(w.id)).map((w) => {
|
|
6926
|
-
const row =
|
|
6941
|
+
const row = makeLocalizedWelcome(w, stringsRef.current);
|
|
6927
6942
|
row.createdAt = welcomeAnchor;
|
|
6928
6943
|
return row;
|
|
6929
6944
|
});
|
|
@@ -7010,7 +7025,6 @@ function App({ options, hostElement, bus }) {
|
|
|
7010
7025
|
});
|
|
7011
7026
|
}
|
|
7012
7027
|
if (res.agent) setAgent(res.agent);
|
|
7013
|
-
if (res.welcome?.suggestions) setSuggestions(res.welcome.suggestions);
|
|
7014
7028
|
if (options.mode === "page") {
|
|
7015
7029
|
if (res.site && isSiteConfigShape(res.site)) setParsedSite(res.site);
|
|
7016
7030
|
else if (res.site) log17.warn("invalid site config, using fallback", { site: res.site });
|
|
@@ -7025,6 +7039,17 @@ function App({ options, hostElement, bus }) {
|
|
|
7025
7039
|
if (res.userPrefs.textSize) setActiveTextSize(res.userPrefs.textSize);
|
|
7026
7040
|
}
|
|
7027
7041
|
welcomeRef.current = res.welcome;
|
|
7042
|
+
if (!newConversation) bus.emit("handshake", res);
|
|
7043
|
+
if (res.welcome?.suggestions) {
|
|
7044
|
+
const strings = stringsRef.current;
|
|
7045
|
+
setSuggestions(
|
|
7046
|
+
res.welcome.suggestions.map((sg) => ({
|
|
7047
|
+
...sg,
|
|
7048
|
+
label: localizeText(strings, sg.label),
|
|
7049
|
+
...sg.text === void 0 ? {} : { text: localizeText(strings, sg.text) }
|
|
7050
|
+
}))
|
|
7051
|
+
);
|
|
7052
|
+
}
|
|
7028
7053
|
const isResume = !newConversation && persistedChatId && res.conversationId === persistedChatId;
|
|
7029
7054
|
if (isResume) {
|
|
7030
7055
|
if (activatedRef.current) void loadThread(persistedChatId);
|
|
@@ -7034,10 +7059,7 @@ function App({ options, hostElement, bus }) {
|
|
|
7034
7059
|
persistence.saveConversationId(res.conversationId);
|
|
7035
7060
|
playWelcome(res.welcome?.messages);
|
|
7036
7061
|
}
|
|
7037
|
-
if (!newConversation)
|
|
7038
|
-
bus.emit("handshake", res);
|
|
7039
|
-
setConversationReady(true);
|
|
7040
|
-
}
|
|
7062
|
+
if (!newConversation) setConversationReady(true);
|
|
7041
7063
|
},
|
|
7042
7064
|
[
|
|
7043
7065
|
transport,
|
|
@@ -7425,8 +7447,10 @@ function App({ options, hostElement, bus }) {
|
|
|
7425
7447
|
log17.info("clear \u2192 new conversation", { wasStreaming: streaming });
|
|
7426
7448
|
bus.emit("clear", void 0);
|
|
7427
7449
|
if (streaming) activeCancel?.();
|
|
7428
|
-
|
|
7429
|
-
|
|
7450
|
+
batch(() => {
|
|
7451
|
+
messagesSig.value = [];
|
|
7452
|
+
conversationIdSig.value = void 0;
|
|
7453
|
+
});
|
|
7430
7454
|
persistence.clearConversation();
|
|
7431
7455
|
setCanSend(true);
|
|
7432
7456
|
setFormMarkers([]);
|
|
@@ -7525,9 +7549,11 @@ function App({ options, hostElement, bus }) {
|
|
|
7525
7549
|
fetchFormMarkers(targetConversationId)
|
|
7526
7550
|
]);
|
|
7527
7551
|
const hydrated = res.messages.map(fromWireMessage);
|
|
7528
|
-
|
|
7552
|
+
batch(() => {
|
|
7553
|
+
messagesSig.value = withWelcomeRows(hydrated, markers);
|
|
7554
|
+
conversationIdSig.value = res.conversationId;
|
|
7555
|
+
});
|
|
7529
7556
|
setFormMarkers(markers);
|
|
7530
|
-
conversationIdSig.value = res.conversationId;
|
|
7531
7557
|
persistence.saveConversationId(res.conversationId);
|
|
7532
7558
|
if (res.agent) setAgent(res.agent);
|
|
7533
7559
|
setCanSend(res.canContinue);
|
|
@@ -7581,6 +7607,7 @@ function App({ options, hostElement, bus }) {
|
|
|
7581
7607
|
() => applyOptionOverrides(options, activeLocale, activeThemeMode, activeTextSize),
|
|
7582
7608
|
[options, activeLocale, activeThemeMode, activeTextSize]
|
|
7583
7609
|
);
|
|
7610
|
+
stringsRef.current = effectiveOptions.strings;
|
|
7584
7611
|
const enrichedFormMarkers = useMemo3(
|
|
7585
7612
|
() => formMarkers.map((m) => {
|
|
7586
7613
|
const def = effectiveForms.list.find((f) => f.id === m.formId);
|
|
@@ -7901,6 +7928,7 @@ function createWidgetRuntime(params) {
|
|
|
7901
7928
|
};
|
|
7902
7929
|
bus.on("handshake", (response) => {
|
|
7903
7930
|
if (!response.config) return;
|
|
7931
|
+
if (response.config.storageVersion) persistence.rememberStorageVersion(response.config.storageVersion);
|
|
7904
7932
|
serverConfig = response.config;
|
|
7905
7933
|
recompute();
|
|
7906
7934
|
render2();
|
package/package.json
CHANGED
package/schema.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, E as Endpoints, H as HandshakeResponse, L as Link, P as PAGE_AREA_SUGGESTIONS, f as PageContext, S as ServerConfig, b as SiteConfig, U as UserContext, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial, g as assetSchema, h as blocksConfigSchema, i as connectionConfigPartialSchema, j as connectionConfigSchema, k as cssColorSchema, l as cssLengthSchema, m as endpointsSchema, n as handshakeResponseSchema, o as linkSchema, p as localeSchema, q as pageContextSchema, s as serverConfigSchema, r as siteConfigSchema, u as userContextSchema, t as uuid7Schema, w as widgetConfigPartialSchema, v as widgetConfigSchema, x as widgetSettingsPartialSchema, y as widgetSettingsSchema } from './deployment-
|
|
1
|
+
export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, E as Endpoints, H as HandshakeResponse, L as Link, P as PAGE_AREA_SUGGESTIONS, f as PageContext, S as ServerConfig, b as SiteConfig, U as UserContext, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial, g as assetSchema, h as blocksConfigSchema, i as connectionConfigPartialSchema, j as connectionConfigSchema, k as cssColorSchema, l as cssLengthSchema, m as endpointsSchema, n as handshakeResponseSchema, o as linkSchema, p as localeSchema, q as pageContextSchema, s as serverConfigSchema, r as siteConfigSchema, u as userContextSchema, t as uuid7Schema, w as widgetConfigPartialSchema, v as widgetConfigSchema, x as widgetSettingsPartialSchema, y as widgetSettingsSchema } from './deployment-MbF78Pdq.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -56,9 +56,9 @@ declare const presentationSchema: z.ZodObject<{
|
|
|
56
56
|
inset: z.ZodOptional<z.ZodString>;
|
|
57
57
|
initialSize: z.ZodDefault<z.ZodEnum<{
|
|
58
58
|
fullscreen: "fullscreen";
|
|
59
|
-
normal: "normal";
|
|
60
59
|
expanded: "expanded";
|
|
61
60
|
auto: "auto";
|
|
61
|
+
normal: "normal";
|
|
62
62
|
}>>;
|
|
63
63
|
autoSizeBreakpoint: z.ZodDefault<z.ZodNumber>;
|
|
64
64
|
}, z.core.$loose>>;
|
|
@@ -240,9 +240,9 @@ type LauncherOptions = z.infer<typeof launcherOptionsSchema>;
|
|
|
240
240
|
|
|
241
241
|
declare const initialSizeSchema: z.ZodEnum<{
|
|
242
242
|
fullscreen: "fullscreen";
|
|
243
|
-
normal: "normal";
|
|
244
243
|
expanded: "expanded";
|
|
245
244
|
auto: "auto";
|
|
245
|
+
normal: "normal";
|
|
246
246
|
}>;
|
|
247
247
|
declare const resizeOptionsSchema: z.ZodObject<{
|
|
248
248
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -269,9 +269,9 @@ declare const sizeOptionsSchema: z.ZodObject<{
|
|
|
269
269
|
inset: z.ZodOptional<z.ZodString>;
|
|
270
270
|
initialSize: z.ZodDefault<z.ZodEnum<{
|
|
271
271
|
fullscreen: "fullscreen";
|
|
272
|
-
normal: "normal";
|
|
273
272
|
expanded: "expanded";
|
|
274
273
|
auto: "auto";
|
|
274
|
+
normal: "normal";
|
|
275
275
|
}>>;
|
|
276
276
|
autoSizeBreakpoint: z.ZodDefault<z.ZodNumber>;
|
|
277
277
|
}, z.core.$loose>;
|
|
@@ -323,43 +323,43 @@ type FeatureFlags = z.infer<typeof featureFlagsSchema>;
|
|
|
323
323
|
*/
|
|
324
324
|
|
|
325
325
|
declare const actionNameSchema: z.ZodEnum<{
|
|
326
|
+
close: "close";
|
|
326
327
|
expand: "expand";
|
|
327
328
|
fullscreen: "fullscreen";
|
|
328
329
|
popOut: "popOut";
|
|
329
|
-
|
|
330
|
-
language: "language";
|
|
330
|
+
clear: "clear";
|
|
331
331
|
theme: "theme";
|
|
332
|
+
language: "language";
|
|
332
333
|
textSize: "textSize";
|
|
333
334
|
history: "history";
|
|
334
|
-
clear: "clear";
|
|
335
335
|
sound: "sound";
|
|
336
336
|
}>;
|
|
337
337
|
type ActionName = z.infer<typeof actionNameSchema>;
|
|
338
338
|
declare const headerActionsSchema: z.ZodArray<z.ZodEnum<{
|
|
339
|
+
close: "close";
|
|
339
340
|
expand: "expand";
|
|
340
341
|
fullscreen: "fullscreen";
|
|
341
342
|
popOut: "popOut";
|
|
342
|
-
|
|
343
|
-
language: "language";
|
|
343
|
+
clear: "clear";
|
|
344
344
|
theme: "theme";
|
|
345
|
+
language: "language";
|
|
345
346
|
textSize: "textSize";
|
|
346
347
|
history: "history";
|
|
347
|
-
clear: "clear";
|
|
348
348
|
sound: "sound";
|
|
349
349
|
}>>;
|
|
350
350
|
type HeaderActions = z.infer<typeof headerActionsSchema>;
|
|
351
351
|
/** Section wrapper — `actions` list wrapped under `header` in the dashboard form. */
|
|
352
352
|
declare const headerSchema: z.ZodObject<{
|
|
353
353
|
actions: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
354
|
+
close: "close";
|
|
354
355
|
expand: "expand";
|
|
355
356
|
fullscreen: "fullscreen";
|
|
356
357
|
popOut: "popOut";
|
|
357
|
-
|
|
358
|
-
language: "language";
|
|
358
|
+
clear: "clear";
|
|
359
359
|
theme: "theme";
|
|
360
|
+
language: "language";
|
|
360
361
|
textSize: "textSize";
|
|
361
362
|
history: "history";
|
|
362
|
-
clear: "clear";
|
|
363
363
|
sound: "sound";
|
|
364
364
|
}>>>;
|
|
365
365
|
}, z.core.$loose>;
|
|
@@ -375,33 +375,33 @@ type HeaderOptions = z.infer<typeof headerSchema>;
|
|
|
375
375
|
*/
|
|
376
376
|
|
|
377
377
|
declare const feedbackEventSchema: z.ZodEnum<{
|
|
378
|
+
voiceStart: "voiceStart";
|
|
379
|
+
voiceStop: "voiceStop";
|
|
378
380
|
error: "error";
|
|
379
381
|
messageReceived: "messageReceived";
|
|
380
382
|
messageSent: "messageSent";
|
|
381
|
-
voiceStart: "voiceStart";
|
|
382
|
-
voiceStop: "voiceStop";
|
|
383
383
|
}>;
|
|
384
384
|
type FeedbackEvent = z.infer<typeof feedbackEventSchema>;
|
|
385
385
|
declare const soundOptionsSchema: z.ZodObject<{
|
|
386
386
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
387
387
|
volume: z.ZodDefault<z.ZodNumber>;
|
|
388
388
|
events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
|
|
389
|
+
voiceStart: "voiceStart";
|
|
390
|
+
voiceStop: "voiceStop";
|
|
389
391
|
error: "error";
|
|
390
392
|
messageReceived: "messageReceived";
|
|
391
393
|
messageSent: "messageSent";
|
|
392
|
-
voiceStart: "voiceStart";
|
|
393
|
-
voiceStop: "voiceStop";
|
|
394
394
|
}> & z.core.$partial, z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>>;
|
|
395
395
|
}, z.core.$loose>;
|
|
396
396
|
type SoundOptions = z.infer<typeof soundOptionsSchema>;
|
|
397
397
|
declare const hapticsOptionsSchema: z.ZodObject<{
|
|
398
398
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
399
399
|
events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
|
|
400
|
+
voiceStart: "voiceStart";
|
|
401
|
+
voiceStop: "voiceStop";
|
|
400
402
|
error: "error";
|
|
401
403
|
messageReceived: "messageReceived";
|
|
402
404
|
messageSent: "messageSent";
|
|
403
|
-
voiceStart: "voiceStart";
|
|
404
|
-
voiceStop: "voiceStop";
|
|
405
405
|
}> & z.core.$partial, z.ZodUnion<readonly [z.ZodBoolean, z.ZodNumber, z.ZodArray<z.ZodNumber>]>>>;
|
|
406
406
|
}, z.core.$loose>;
|
|
407
407
|
type HapticsOptions = z.infer<typeof hapticsOptionsSchema>;
|
|
@@ -410,21 +410,21 @@ declare const feedbackSchema: z.ZodObject<{
|
|
|
410
410
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
411
411
|
volume: z.ZodDefault<z.ZodNumber>;
|
|
412
412
|
events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
|
|
413
|
+
voiceStart: "voiceStart";
|
|
414
|
+
voiceStop: "voiceStop";
|
|
413
415
|
error: "error";
|
|
414
416
|
messageReceived: "messageReceived";
|
|
415
417
|
messageSent: "messageSent";
|
|
416
|
-
voiceStart: "voiceStart";
|
|
417
|
-
voiceStop: "voiceStop";
|
|
418
418
|
}> & z.core.$partial, z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>>;
|
|
419
419
|
}, z.core.$loose>>;
|
|
420
420
|
haptics: z.ZodOptional<z.ZodObject<{
|
|
421
421
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
422
422
|
events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
|
|
423
|
+
voiceStart: "voiceStart";
|
|
424
|
+
voiceStop: "voiceStop";
|
|
423
425
|
error: "error";
|
|
424
426
|
messageReceived: "messageReceived";
|
|
425
427
|
messageSent: "messageSent";
|
|
426
|
-
voiceStart: "voiceStart";
|
|
427
|
-
voiceStop: "voiceStop";
|
|
428
428
|
}> & z.core.$partial, z.ZodUnion<readonly [z.ZodBoolean, z.ZodNumber, z.ZodArray<z.ZodNumber>]>>>;
|
|
429
429
|
}, z.core.$loose>>;
|
|
430
430
|
}, z.core.$loose>;
|
|
@@ -859,18 +859,18 @@ type I18nOptions = z.infer<typeof i18nSchema>;
|
|
|
859
859
|
*/
|
|
860
860
|
|
|
861
861
|
declare const moduleLayoutSchema: z.ZodEnum<{
|
|
862
|
+
home: "home";
|
|
862
863
|
chat: "chat";
|
|
863
864
|
help: "help";
|
|
864
|
-
home: "home";
|
|
865
865
|
news: "news";
|
|
866
866
|
}>;
|
|
867
867
|
type ModuleLayout = z.infer<typeof moduleLayoutSchema>;
|
|
868
868
|
declare const moduleSchema: z.ZodObject<{
|
|
869
869
|
label: z.ZodString;
|
|
870
870
|
layout: z.ZodEnum<{
|
|
871
|
+
home: "home";
|
|
871
872
|
chat: "chat";
|
|
872
873
|
help: "help";
|
|
873
|
-
home: "home";
|
|
874
874
|
news: "news";
|
|
875
875
|
}>;
|
|
876
876
|
contentTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -896,9 +896,9 @@ type ModuleOptions = z.infer<typeof moduleSchema>;
|
|
|
896
896
|
declare const modulesSchema: z.ZodArray<z.ZodObject<{
|
|
897
897
|
label: z.ZodString;
|
|
898
898
|
layout: z.ZodEnum<{
|
|
899
|
+
home: "home";
|
|
899
900
|
chat: "chat";
|
|
900
901
|
help: "help";
|
|
901
|
-
home: "home";
|
|
902
902
|
news: "news";
|
|
903
903
|
}>;
|
|
904
904
|
contentTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
package/schema.json
CHANGED
package/schema.mjs
CHANGED
|
@@ -758,7 +758,8 @@ var connectionConfigPartialSchema = connectionConfigSchema.partial();
|
|
|
758
758
|
// src/schema/deployment.ts
|
|
759
759
|
import { z as z17 } from "zod";
|
|
760
760
|
var serverConfigSchema = widgetSettingsSchema.partial().omit({ forms: true }).extend({
|
|
761
|
-
dataApiBaseUrl: z17.string().min(1).max(2048).optional()
|
|
761
|
+
dataApiBaseUrl: z17.string().min(1).max(2048).optional(),
|
|
762
|
+
storageVersion: z17.string().min(1).max(64).optional()
|
|
762
763
|
});
|
|
763
764
|
var siteConfigSchema = z17.object({
|
|
764
765
|
title: z17.string().min(1).max(120).optional().describe("Brand / site name. Used as the logo's alt-text fallback."),
|
package/web-component.mjs
CHANGED
|
@@ -62,6 +62,7 @@ var STRINGS_EN = {
|
|
|
62
62
|
historyTitle: "Conversation history",
|
|
63
63
|
language: "Language",
|
|
64
64
|
launcherOpen: "Open chat",
|
|
65
|
+
launcherLabel: "Chat with us",
|
|
65
66
|
micStart: "Start voice input",
|
|
66
67
|
micStop: "Stop voice input",
|
|
67
68
|
micUnsupported: "Voice input is not supported in this browser",
|
|
@@ -175,6 +176,7 @@ var STRINGS_FR = {
|
|
|
175
176
|
historyTitle: "Historique des conversations",
|
|
176
177
|
language: "Langue",
|
|
177
178
|
launcherOpen: "Ouvrir le chat",
|
|
179
|
+
launcherLabel: "Discuter avec nous",
|
|
178
180
|
micStart: "D\xE9marrer la saisie vocale",
|
|
179
181
|
micStop: "Arr\xEAter la saisie vocale",
|
|
180
182
|
micUnsupported: "La saisie vocale n'est pas prise en charge par ce navigateur",
|
|
@@ -1085,8 +1087,11 @@ function fillRandom(view) {
|
|
|
1085
1087
|
var log2 = logger.scope("persistence");
|
|
1086
1088
|
function createPersistence(widgetId, storage = defaultStorage, deploymentId) {
|
|
1087
1089
|
const scope = deploymentId ? `${widgetId}.${deploymentId}` : widgetId;
|
|
1088
|
-
const
|
|
1089
|
-
const
|
|
1090
|
+
const KEY_STORAGE_VERSION = `${BRAND.cssPrefix}.storageVersion`;
|
|
1091
|
+
const activeVersion = storage.get(KEY_STORAGE_VERSION) ?? void 0;
|
|
1092
|
+
const version = activeVersion ? `.v${activeVersion}` : "";
|
|
1093
|
+
const prefix = `${BRAND.cssPrefix}.${scope}${version}`;
|
|
1094
|
+
const KEY_VISITOR = `${BRAND.cssPrefix}${version}.visitorId`;
|
|
1090
1095
|
const KEY_CONVERSATION = `${prefix}.conversationId`;
|
|
1091
1096
|
const KEY_USER_PREFS = `${prefix}.userPrefs`;
|
|
1092
1097
|
const KEY_PANEL_OPEN = `${prefix}.panelOpen`;
|
|
@@ -1197,6 +1202,12 @@ function createPersistence(widgetId, storage = defaultStorage, deploymentId) {
|
|
|
1197
1202
|
log2.warn("saveFormDone serialise failed", { error });
|
|
1198
1203
|
}
|
|
1199
1204
|
},
|
|
1205
|
+
rememberStorageVersion(serverVersion) {
|
|
1206
|
+
if (serverVersion && serverVersion !== storage.get(KEY_STORAGE_VERSION)) {
|
|
1207
|
+
log2.debug("rememberStorageVersion (force-reset on next load)", { version: serverVersion });
|
|
1208
|
+
storage.set(KEY_STORAGE_VERSION, serverVersion);
|
|
1209
|
+
}
|
|
1210
|
+
},
|
|
1200
1211
|
clearConversation() {
|
|
1201
1212
|
storage.remove(KEY_CONVERSATION);
|
|
1202
1213
|
}
|
|
@@ -1337,7 +1348,7 @@ import { h, render as renderPreact } from "preact";
|
|
|
1337
1348
|
|
|
1338
1349
|
// src/ui/app.tsx
|
|
1339
1350
|
import { useCallback as useCallback6, useEffect as useEffect17, useMemo as useMemo3, useRef as useRef9, useState as useState13 } from "preact/hooks";
|
|
1340
|
-
import { useComputed as useComputed7, useSignal as useSignal2 } from "@preact/signals";
|
|
1351
|
+
import { batch, useComputed as useComputed7, useSignal as useSignal2 } from "@preact/signals";
|
|
1341
1352
|
|
|
1342
1353
|
// src/core/handshake-shape.ts
|
|
1343
1354
|
function isPlainObject2(raw) {
|
|
@@ -3154,7 +3165,7 @@ function Launcher({ onToggle, launcher, strings, leaving, edgeTab }) {
|
|
|
3154
3165
|
"aria-label": strings.launcherOpen,
|
|
3155
3166
|
children: [
|
|
3156
3167
|
renderIcon(launcher.icon),
|
|
3157
|
-
showLabel ? /* @__PURE__ */ jsx2("span", { class: `${p3}-fab-label`, children: launcher.label }) : null
|
|
3168
|
+
showLabel ? /* @__PURE__ */ jsx2("span", { class: `${p3}-fab-label`, children: localizeText(strings, launcher.label ?? "") }) : null
|
|
3158
3169
|
]
|
|
3159
3170
|
}
|
|
3160
3171
|
);
|
|
@@ -6695,6 +6706,9 @@ function useLauncherCallout({ callout, persistence }) {
|
|
|
6695
6706
|
import { jsx as jsx36, jsxs as jsxs31 } from "preact/jsx-runtime";
|
|
6696
6707
|
var log16 = logger.scope("app");
|
|
6697
6708
|
var p32 = BRAND.cssPrefix;
|
|
6709
|
+
function makeLocalizedWelcome(w, strings) {
|
|
6710
|
+
return makeInstantWelcomeMessage({ ...w, text: localizeText(strings, w.text) });
|
|
6711
|
+
}
|
|
6698
6712
|
function App({ options, hostElement, bus }) {
|
|
6699
6713
|
const [persistence] = useState13(
|
|
6700
6714
|
() => createPersistence(options.widgetId, options.storage, options.aiAgentDeploymentId)
|
|
@@ -6765,6 +6779,7 @@ function App({ options, hostElement, bus }) {
|
|
|
6765
6779
|
const [agent, setAgent] = useState13(null);
|
|
6766
6780
|
const [suggestions, setSuggestions] = useState13([]);
|
|
6767
6781
|
const [activeCancel, setActiveCancel] = useState13(null);
|
|
6782
|
+
const stringsRef = useRef9(options.strings);
|
|
6768
6783
|
const [parsedSite, setParsedSite] = useState13(void 0);
|
|
6769
6784
|
const [parsedBlocks, setParsedBlocks] = useState13(void 0);
|
|
6770
6785
|
const [sidebarCollapsed, setSidebarCollapsed] = useState13(() => persistence.loadSidebarCollapsed() ?? false);
|
|
@@ -6849,7 +6864,7 @@ function App({ options, hostElement, bus }) {
|
|
|
6849
6864
|
const playWelcome = useCallback6(
|
|
6850
6865
|
(welcomeMessages) => {
|
|
6851
6866
|
if (!welcomeMessages || welcomeMessages.length === 0) return;
|
|
6852
|
-
messagesSig.value = welcomeMessages.map(
|
|
6867
|
+
messagesSig.value = welcomeMessages.map((w) => makeLocalizedWelcome(w, stringsRef.current));
|
|
6853
6868
|
},
|
|
6854
6869
|
[messagesSig]
|
|
6855
6870
|
);
|
|
@@ -6882,7 +6897,7 @@ function App({ options, hostElement, bus }) {
|
|
|
6882
6897
|
const welcomeAnchor = (timelineStamps.length ? Math.min(...timelineStamps) : Date.now()) - 1;
|
|
6883
6898
|
const loadedIds = new Set(loaded.map((m) => m.id));
|
|
6884
6899
|
const welcomeRows = (welcomeRef.current?.messages ?? []).filter((w) => !loadedIds.has(w.id)).map((w) => {
|
|
6885
|
-
const row =
|
|
6900
|
+
const row = makeLocalizedWelcome(w, stringsRef.current);
|
|
6886
6901
|
row.createdAt = welcomeAnchor;
|
|
6887
6902
|
return row;
|
|
6888
6903
|
});
|
|
@@ -6969,7 +6984,6 @@ function App({ options, hostElement, bus }) {
|
|
|
6969
6984
|
});
|
|
6970
6985
|
}
|
|
6971
6986
|
if (res.agent) setAgent(res.agent);
|
|
6972
|
-
if (res.welcome?.suggestions) setSuggestions(res.welcome.suggestions);
|
|
6973
6987
|
if (options.mode === "page") {
|
|
6974
6988
|
if (res.site && isSiteConfigShape(res.site)) setParsedSite(res.site);
|
|
6975
6989
|
else if (res.site) log16.warn("invalid site config, using fallback", { site: res.site });
|
|
@@ -6984,6 +6998,17 @@ function App({ options, hostElement, bus }) {
|
|
|
6984
6998
|
if (res.userPrefs.textSize) setActiveTextSize(res.userPrefs.textSize);
|
|
6985
6999
|
}
|
|
6986
7000
|
welcomeRef.current = res.welcome;
|
|
7001
|
+
if (!newConversation) bus.emit("handshake", res);
|
|
7002
|
+
if (res.welcome?.suggestions) {
|
|
7003
|
+
const strings = stringsRef.current;
|
|
7004
|
+
setSuggestions(
|
|
7005
|
+
res.welcome.suggestions.map((sg) => ({
|
|
7006
|
+
...sg,
|
|
7007
|
+
label: localizeText(strings, sg.label),
|
|
7008
|
+
...sg.text === void 0 ? {} : { text: localizeText(strings, sg.text) }
|
|
7009
|
+
}))
|
|
7010
|
+
);
|
|
7011
|
+
}
|
|
6987
7012
|
const isResume = !newConversation && persistedChatId && res.conversationId === persistedChatId;
|
|
6988
7013
|
if (isResume) {
|
|
6989
7014
|
if (activatedRef.current) void loadThread(persistedChatId);
|
|
@@ -6993,10 +7018,7 @@ function App({ options, hostElement, bus }) {
|
|
|
6993
7018
|
persistence.saveConversationId(res.conversationId);
|
|
6994
7019
|
playWelcome(res.welcome?.messages);
|
|
6995
7020
|
}
|
|
6996
|
-
if (!newConversation)
|
|
6997
|
-
bus.emit("handshake", res);
|
|
6998
|
-
setConversationReady(true);
|
|
6999
|
-
}
|
|
7021
|
+
if (!newConversation) setConversationReady(true);
|
|
7000
7022
|
},
|
|
7001
7023
|
[
|
|
7002
7024
|
transport,
|
|
@@ -7384,8 +7406,10 @@ function App({ options, hostElement, bus }) {
|
|
|
7384
7406
|
log16.info("clear \u2192 new conversation", { wasStreaming: streaming });
|
|
7385
7407
|
bus.emit("clear", void 0);
|
|
7386
7408
|
if (streaming) activeCancel?.();
|
|
7387
|
-
|
|
7388
|
-
|
|
7409
|
+
batch(() => {
|
|
7410
|
+
messagesSig.value = [];
|
|
7411
|
+
conversationIdSig.value = void 0;
|
|
7412
|
+
});
|
|
7389
7413
|
persistence.clearConversation();
|
|
7390
7414
|
setCanSend(true);
|
|
7391
7415
|
setFormMarkers([]);
|
|
@@ -7484,9 +7508,11 @@ function App({ options, hostElement, bus }) {
|
|
|
7484
7508
|
fetchFormMarkers(targetConversationId)
|
|
7485
7509
|
]);
|
|
7486
7510
|
const hydrated = res.messages.map(fromWireMessage);
|
|
7487
|
-
|
|
7511
|
+
batch(() => {
|
|
7512
|
+
messagesSig.value = withWelcomeRows(hydrated, markers);
|
|
7513
|
+
conversationIdSig.value = res.conversationId;
|
|
7514
|
+
});
|
|
7488
7515
|
setFormMarkers(markers);
|
|
7489
|
-
conversationIdSig.value = res.conversationId;
|
|
7490
7516
|
persistence.saveConversationId(res.conversationId);
|
|
7491
7517
|
if (res.agent) setAgent(res.agent);
|
|
7492
7518
|
setCanSend(res.canContinue);
|
|
@@ -7540,6 +7566,7 @@ function App({ options, hostElement, bus }) {
|
|
|
7540
7566
|
() => applyOptionOverrides(options, activeLocale, activeThemeMode, activeTextSize),
|
|
7541
7567
|
[options, activeLocale, activeThemeMode, activeTextSize]
|
|
7542
7568
|
);
|
|
7569
|
+
stringsRef.current = effectiveOptions.strings;
|
|
7543
7570
|
const enrichedFormMarkers = useMemo3(
|
|
7544
7571
|
() => formMarkers.map((m) => {
|
|
7545
7572
|
const def = effectiveForms.list.find((f) => f.id === m.formId);
|
|
@@ -7860,6 +7887,7 @@ function createWidgetRuntime(params) {
|
|
|
7860
7887
|
};
|
|
7861
7888
|
bus.on("handshake", (response) => {
|
|
7862
7889
|
if (!response.config) return;
|
|
7890
|
+
if (response.config.storageVersion) persistence.rememberStorageVersion(response.config.storageVersion);
|
|
7863
7891
|
serverConfig = response.config;
|
|
7864
7892
|
recompute();
|
|
7865
7893
|
render2();
|