@gengage/assistant-fe 0.4.5 → 0.4.7

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.
Files changed (63) hide show
  1. package/README.md +22 -2
  2. package/dist/api-paths-DR5bPNhi.js +1213 -0
  3. package/dist/assistant-fe.css +1 -1
  4. package/dist/chat/index.d.ts +1 -374
  5. package/dist/chat/runtime.d.ts +374 -0
  6. package/dist/chat-BRKK63lt.js +303 -0
  7. package/dist/chat-runtime.js +13 -0
  8. package/dist/chat.iife.js +8 -8
  9. package/dist/chat.js +11 -10
  10. package/dist/common/config-constants.d.ts +1 -0
  11. package/dist/common/config-schema.d.ts +0 -1
  12. package/dist/common/overlay.d.ts +8 -4
  13. package/dist/common/protocol-adapter.d.ts +1 -1
  14. package/dist/common/safe-html.d.ts +1 -1
  15. package/dist/common-c-awF96O.js +491 -0
  16. package/dist/common.js +78 -76
  17. package/dist/{connection-warning-n88bjkqL.js → connection-warning-ecZqpczd.js} +1 -1
  18. package/dist/context-DGz5F81j.js +532 -0
  19. package/dist/index.d.ts +4 -4
  20. package/dist/index.js +73 -68
  21. package/dist/locale-CfqNifrU.js +7 -0
  22. package/dist/native-webview-C_PmKnzm.js +273 -0
  23. package/dist/native.iife.js +28 -91
  24. package/dist/native.js +1 -1
  25. package/dist/overlay-DJ1ZRMfI.js +212 -0
  26. package/dist/overlay.d.ts +4 -0
  27. package/dist/overlay.js +10 -0
  28. package/dist/pill-launcher-DSEeJT9h.js +364 -0
  29. package/dist/qna/index.d.ts +1 -61
  30. package/dist/qna/runtime.d.ts +62 -0
  31. package/dist/qna/types.d.ts +14 -0
  32. package/dist/qna-BNvttR6s.js +40 -0
  33. package/dist/qna-runtime.js +8 -0
  34. package/dist/qna.css +1 -1
  35. package/dist/qna.iife.js +21 -21
  36. package/dist/qna.js +6 -5
  37. package/dist/{simrel-K2TGFi1r.js → runtime-BsZZ8zTg.js} +245 -293
  38. package/dist/{chat-B1lLKIxj.js → runtime-DNbjpTCh.js} +1643 -2297
  39. package/dist/runtime-SKDvc0Xc.js +660 -0
  40. package/dist/schemas-CLo8wCjs.js +3207 -0
  41. package/dist/simbut/index.d.ts +3 -1
  42. package/dist/simbut/types.d.ts +11 -0
  43. package/dist/simbut-Bw3vBFtW.js +109 -0
  44. package/dist/simbut.css +1 -1
  45. package/dist/simbut.iife.js +10 -10
  46. package/dist/simbut.js +1 -1
  47. package/dist/simrel/index.d.ts +3 -59
  48. package/dist/simrel/renderers/default.d.ts +40 -0
  49. package/dist/simrel/runtime.d.ts +59 -0
  50. package/dist/simrel-DJZ983BF.js +513 -0
  51. package/dist/simrel-runtime.js +8 -0
  52. package/dist/simrel.css +3 -0
  53. package/dist/simrel.iife.js +38 -38
  54. package/dist/simrel.js +8 -6
  55. package/dist/widget-base-2-B1Ch5I.js +578 -0
  56. package/package.json +22 -1
  57. package/dist/common-C5e2gLuG.js +0 -387
  58. package/dist/locale-MM0U5eeR.js +0 -1109
  59. package/dist/native-webview-niMtkiHX.js +0 -586
  60. package/dist/qna-C5Ok3wd0.js +0 -663
  61. package/dist/schemas-JpRGzRQT.js +0 -4419
  62. package/dist/simbut-Cb5RfaAp.js +0 -79
  63. /package/dist/{price-formatter-CR6VT5z4.js → price-formatter-xI3g9Cd4.js} +0 -0
package/dist/native.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a, i, n as t, r, t as s } from "./native-webview-niMtkiHX.js";
1
+ import { a, i, n as t, r, t as s } from "./native-webview-C_PmKnzm.js";
2
2
  export {
3
3
  s as DEFAULT_NATIVE_TRACKED_EVENTS,
4
4
  t as applyNativeSession,
@@ -0,0 +1,212 @@
1
+ import { j as g, r as m, s as f, y as _ } from "./context-DGz5F81j.js";
2
+ var v = "__gengageWidgetsInit", l = `${v}_overlay_`, y = "#gengage-qna", w = "#gengage-simrel", C = "#gengage-simbut";
3
+ function d() {
4
+ const i = window;
5
+ return i.__gengageOverlayRegistry || (i.__gengageOverlayRegistry = {
6
+ instances: {},
7
+ pending: {}
8
+ }), i.__gengageOverlayRegistry;
9
+ }
10
+ function T(i) {
11
+ const t = { pageType: i.pageContext?.pageType ?? (typeof i.sku == "string" ? "pdp" : "other") }, s = i.pageContext;
12
+ return typeof s?.sku == "string" && (t.sku = s.sku), s?.skuList !== void 0 && (t.skuList = s.skuList), s?.price !== void 0 && (t.price = s.price), s?.categoryTree !== void 0 && (t.categoryTree = s.categoryTree), s?.url !== void 0 && (t.url = s.url), s?.extra !== void 0 && (t.extra = s.extra), typeof i.sku == "string" && (t.sku = i.sku), t;
13
+ }
14
+ function b(i, t) {
15
+ const s = {
16
+ ...i,
17
+ ...t,
18
+ pageType: t.pageType ?? i.pageType
19
+ };
20
+ return t.sku !== void 0 && typeof t.sku != "string" && delete s.sku, t.pageType !== void 0 && t.pageType !== i.pageType ? (t.pageType !== "pdp" && t.sku === void 0 && delete s.sku, t.pageType !== "plp" && t.skuList === void 0 && delete s.skuList) : (t.sku === void 0 && i.sku !== void 0 && (s.sku = i.sku), t.skuList === void 0 && i.skuList !== void 0 && (s.skuList = i.skuList)), s;
21
+ }
22
+ function r(i) {
23
+ return i instanceof HTMLElement || document.querySelector(i) ? i : null;
24
+ }
25
+ function p(i) {
26
+ return i.idempotencyKey ?? `${l}${i.accountId}`;
27
+ }
28
+ var S = class {
29
+ constructor(i, t) {
30
+ this.options = i, this.onDestroy = t, this._chat = null, this._qna = null, this._simrel = null, this._simbut = null, this._analyticsClient = null, this._offQnaWire = null, this._destroyed = !1, this._queue = Promise.resolve(), this._warnedQnaMountMissing = !1, this._warnedSimRelMountMissing = !1, this._warnedSimButMountMissing = !1, this._warnedSimButNoChat = !1, this.idempotencyKey = p(i), this.session = m(i.session), this._pageContext = T(i);
31
+ }
32
+ get chat() {
33
+ return this._chat;
34
+ }
35
+ get qna() {
36
+ return this._qna;
37
+ }
38
+ get simrel() {
39
+ return this._simrel;
40
+ }
41
+ get simbut() {
42
+ return this._simbut;
43
+ }
44
+ get analyticsClient() {
45
+ return this._analyticsClient;
46
+ }
47
+ async init() {
48
+ window.gengage || (window.gengage = {}), window.gengage.sessionId = this.session.sessionId, window.gengage.pageContext = this._pageContext, await this._initChat(), this.options.wireQnaToChat !== !1 && (this._offQnaWire = f()), await this._syncPdpWidgets(), window.gengage.overlay = this;
49
+ }
50
+ openChat(i) {
51
+ this._chat?.open(i);
52
+ }
53
+ closeChat() {
54
+ this._chat?.close();
55
+ }
56
+ async updateContext(i) {
57
+ this._destroyed || await this._enqueue(async () => {
58
+ this._pageContext = b(this._pageContext, i), window.gengage || (window.gengage = {}), window.gengage.pageContext = this._pageContext, this._chat?.update(this._pageContext), this._qna?.update(this._pageContext), this._simrel?.update(this._pageContext), this._simbut?.update(this._pageContext), await this._syncPdpWidgets();
59
+ });
60
+ }
61
+ async updateSku(i, t = "pdp") {
62
+ await this.updateContext({
63
+ sku: i,
64
+ pageType: t
65
+ });
66
+ }
67
+ async updatePageContext(i) {
68
+ await this.updateContext(i);
69
+ }
70
+ async setPageContext(i) {
71
+ await this.updateContext(i);
72
+ }
73
+ destroy() {
74
+ this._destroyed || (this._destroyed = !0, this._offQnaWire?.(), this._offQnaWire = null, this._chat?.destroy(), this._qna?.destroy(), this._simrel?.destroy(), this._simbut?.destroy(), this._chat = null, this._qna = null, this._simrel = null, this._simbut = null, window.gengage?.overlay === this && delete window.gengage.overlay, this.onDestroy());
75
+ }
76
+ async _initChat() {
77
+ if (this.options.chat?.enabled === !1) return;
78
+ const i = this.options.middlewareUrl, t = this.options.chat?.productDetailsExtended ?? this.options.productDetailsExtended, s = this.options.chat?.isDemoWebsite ?? this.options.isDemoWebsite, e = {
79
+ accountId: this.options.accountId,
80
+ middlewareUrl: i,
81
+ session: this.session,
82
+ pageContext: this._pageContext,
83
+ variant: this.options.chat?.variant ?? "floating"
84
+ };
85
+ this.options.theme !== void 0 && (e.theme = this.options.theme), this.options.locale !== void 0 && (e.locale = this.options.locale), this.options.pricing !== void 0 && (e.pricing = this.options.pricing), this.options.chat?.mountTarget !== void 0 && (e.mountTarget = this.options.chat.mountTarget), this.options.chat?.pillLauncher !== void 0 && (e.pillLauncher = this.options.chat.pillLauncher), this.options.chat?.launcherImageUrl !== void 0 ? e.launcherImageUrl = this.options.chat.launcherImageUrl : this.options.chat?.launcherSvg !== void 0 && (e.launcherSvg = this.options.chat.launcherSvg), this.options.chat?.headerTitle !== void 0 && (e.headerTitle = this.options.chat.headerTitle), this.options.chat?.headerAvatarUrl !== void 0 && (e.headerAvatarUrl = this.options.chat.headerAvatarUrl), this.options.chat?.headerBadge !== void 0 && (e.headerBadge = this.options.chat.headerBadge), this.options.chat?.headerCartUrl !== void 0 && (e.headerCartUrl = this.options.chat.headerCartUrl), this.options.chat?.headerFavoritesToggle !== void 0 && (e.headerFavoritesToggle = this.options.chat.headerFavoritesToggle), this.options.chat?.onFavoritesClick !== void 0 && (e.onFavoritesClick = this.options.chat.onFavoritesClick), this.options.chat?.hideMobileLauncher !== void 0 && (e.hideMobileLauncher = this.options.chat.hideMobileLauncher), this.options.chat?.mobileBreakpoint !== void 0 && (e.mobileBreakpoint = this.options.chat.mobileBreakpoint), this.options.chat?.mobileInitialState !== void 0 && (e.mobileInitialState = this.options.chat.mobileInitialState), this.options.chat?.i18n !== void 0 && (e.i18n = this.options.chat.i18n), this.options.chat?.actionHandling !== void 0 && (e.actionHandling = this.options.chat.actionHandling), this.options.chat?.renderer !== void 0 && (e.renderer = this.options.chat.renderer), t !== void 0 && (e.productDetailsExtended = t), s !== void 0 && (e.isDemoWebsite = s), this.options.chat?.productPriceUi !== void 0 && (e.productPriceUi = this.options.chat.productPriceUi), this.options.chat?.hideProductDiscountBadge !== void 0 && (e.hideProductDiscountBadge = this.options.chat.hideProductDiscountBadge), this.options.chat?.hideUserReviews !== void 0 && (e.hideUserReviews = this.options.chat.hideUserReviews), this.options.chat?.hideStockStatus !== void 0 && (e.hideStockStatus = this.options.chat.hideStockStatus), this.options.onScriptCall !== void 0 && (e.onScriptCall = this.options.onScriptCall), this.options.onAddToCart !== void 0 && (e.onAddToCart = this.options.onAddToCart), this.options.chat?.onOpen !== void 0 && (e.onOpen = this.options.chat.onOpen), this.options.chat?.onClose !== void 0 && (e.onClose = this.options.chat.onClose);
86
+ const { GengageChat: a } = await import("./chat-runtime.js");
87
+ this._chat = new a(), await this._chat.init(e);
88
+ }
89
+ async _syncPdpWidgets() {
90
+ if (this._destroyed) return;
91
+ const i = typeof this._pageContext.sku == "string" ? this._pageContext.sku : void 0;
92
+ if (!(this._pageContext.pageType === "pdp" && i !== void 0 && i.length > 0)) {
93
+ this._qna?.hide(), this._simrel?.hide(), this._simbut?.hide();
94
+ return;
95
+ }
96
+ const t = this.options.middlewareUrl;
97
+ if (this.options.qna?.enabled !== !1) {
98
+ const s = this.options.qna?.mountTarget ?? y, e = r(s);
99
+ if (e)
100
+ if (this._warnedQnaMountMissing = !1, this._qna)
101
+ this._qna.show(), this._qna.update({
102
+ pageType: "pdp",
103
+ sku: i
104
+ });
105
+ else {
106
+ const { GengageQNA: a } = await import("./qna-runtime.js"), h = new a(), o = {
107
+ accountId: this.options.accountId,
108
+ middlewareUrl: t,
109
+ session: this.session,
110
+ pageContext: {
111
+ pageType: "pdp",
112
+ sku: i
113
+ },
114
+ mountTarget: e
115
+ };
116
+ this.options.theme !== void 0 && (o.theme = this.options.theme), this.options.qna?.chrome !== void 0 && (o.chrome = this.options.qna.chrome), this.options.qna?.ctaText !== void 0 && (o.ctaText = this.options.qna.ctaText), this.options.qna?.hideButtonRowCta !== void 0 && (o.hideButtonRowCta = this.options.qna.hideButtonRowCta), this.options.qna?.inputPlaceholder !== void 0 && (o.inputPlaceholder = this.options.qna.inputPlaceholder), this.options.qna?.i18n !== void 0 && (o.i18n = this.options.qna.i18n), this.options.qna?.renderer !== void 0 && (o.renderer = this.options.qna.renderer);
117
+ const n = this.options.qna?.headerTitle ?? this.options.qna?.headingTitle;
118
+ n !== void 0 && (o.headerTitle = n), await h.init(o), this._qna = h;
119
+ }
120
+ else
121
+ this._qna?.destroy(), this._qna = null, this._warnedQnaMountMissing || (console.warn(`[gengage] QNA mount target not found: ${s}`), this._warnedQnaMountMissing = !0);
122
+ } else
123
+ this._qna?.destroy(), this._qna = null;
124
+ if (this.options.simrel !== void 0 && this.options.simrel.enabled !== !1) {
125
+ const s = this.options.simrel?.mountTarget ?? w, e = r(s);
126
+ if (e)
127
+ if (this._warnedSimRelMountMissing = !1, this._simrel)
128
+ this._simrel.show(), this._simrel.update({
129
+ pageType: "pdp",
130
+ sku: i
131
+ });
132
+ else {
133
+ const { GengageSimRel: a } = await import("./simrel-runtime.js"), h = new a(), o = {
134
+ accountId: this.options.accountId,
135
+ middlewareUrl: t,
136
+ session: this.session,
137
+ sku: i,
138
+ mountTarget: e
139
+ };
140
+ this.options.theme !== void 0 && (o.theme = this.options.theme), this.options.pricing !== void 0 && (o.pricing = this.options.pricing), this.options.simrel?.discountType !== void 0 && (o.discountType = this.options.simrel.discountType), this.options.simrel?.gridColumns !== void 0 && (o.gridColumns = this.options.simrel.gridColumns), this.options.simrel?.renderCardElement !== void 0 && (o.renderCardElement = this.options.simrel.renderCardElement), this.options.simrel?.renderer !== void 0 && (o.renderer = this.options.simrel.renderer), this.options.onAddToCart !== void 0 && (o.onAddToCart = this.options.onAddToCart), this.options.onProductNavigate !== void 0 ? o.onProductNavigate = this.options.onProductNavigate : o.onProductNavigate = (n, u, c) => {
141
+ g(n) && (this._chat?.saveSession(c ?? this.session.sessionId, u), window.location.href = n);
142
+ }, await h.init(o), this._simrel = h;
143
+ }
144
+ else
145
+ this._simrel?.destroy(), this._simrel = null, this._warnedSimRelMountMissing || (console.warn(`[gengage] SimRel mount target not found: ${s}`), this._warnedSimRelMountMissing = !0);
146
+ } else
147
+ this._simrel?.destroy(), this._simrel = null;
148
+ if (this.options.simbut && this.options.simbut.enabled !== !1) {
149
+ const s = this.options.simbut.mountTarget ?? C, e = r(s), a = this._chat ?? this.options.simbut.onFindSimilar;
150
+ if (e && a)
151
+ if (this._warnedSimButMountMissing = !1, this._warnedSimButNoChat = !1, this._simbut)
152
+ this._simbut.show(), this._simbut.setChat(this._chat), this._simbut.update({
153
+ pageType: "pdp",
154
+ sku: i
155
+ });
156
+ else {
157
+ const { GengageSimBut: h } = await import("./simbut.js"), o = new h(), n = {
158
+ accountId: this.options.accountId,
159
+ middlewareUrl: t,
160
+ session: this.session,
161
+ pageContext: {
162
+ pageType: "pdp",
163
+ sku: i
164
+ },
165
+ mountTarget: e,
166
+ chat: this._chat
167
+ };
168
+ this.options.theme !== void 0 && (n.theme = this.options.theme), this.options.locale !== void 0 && (n.locale = this.options.locale), this.options.simbut.layout !== void 0 && (n.layout = this.options.simbut.layout), this.options.simbut.inlineCard !== void 0 && (n.inlineCard = this.options.simbut.inlineCard), this.options.simbut.imageUrl !== void 0 && (n.imageUrl = this.options.simbut.imageUrl), this.options.simbut.i18n !== void 0 && (n.i18n = this.options.simbut.i18n), this.options.simbut.onFindSimilar !== void 0 && (n.onFindSimilar = this.options.simbut.onFindSimilar), await o.init(n), this._simbut = o;
169
+ }
170
+ else
171
+ this._simbut?.destroy(), this._simbut = null, !e && !this._warnedSimButMountMissing ? (console.warn(`[gengage] SimBut mount target not found: ${s}`), this._warnedSimButMountMissing = !0) : !a && !this._warnedSimButNoChat && (console.warn("[gengage] SimBut requires chat to be enabled or simbut.onFindSimilar"), this._warnedSimButNoChat = !0);
172
+ } else
173
+ this._simbut?.destroy(), this._simbut = null;
174
+ }
175
+ _enqueue(i) {
176
+ const t = this._queue.then(i);
177
+ return this._queue = t.catch((s) => {
178
+ }), t;
179
+ }
180
+ };
181
+ async function k(i) {
182
+ const t = p(i), s = d(), e = s.instances[t];
183
+ if (e) return e;
184
+ const a = s.pending[t];
185
+ if (a) return a;
186
+ const h = new S(i, () => {
187
+ const n = d();
188
+ delete n.instances[t], delete n.pending[t];
189
+ }), o = h.init().then(() => (s.instances[t] = h, delete s.pending[t], h)).catch((n) => {
190
+ throw delete s.pending[t], _({
191
+ reason: "overlay_init_failed",
192
+ message: n instanceof Error ? n.message : String(n)
193
+ }), n;
194
+ });
195
+ return s.pending[t] = o, o;
196
+ }
197
+ function q(i) {
198
+ return d().instances[i] ?? null;
199
+ }
200
+ function M(i) {
201
+ q(i)?.destroy();
202
+ }
203
+ function U(i) {
204
+ return `${l}${i}`;
205
+ }
206
+ export {
207
+ v as a,
208
+ k as i,
209
+ M as n,
210
+ q as r,
211
+ U as t
212
+ };
@@ -0,0 +1,4 @@
1
+ export { initOverlayWidgets, getOverlayWidgets, destroyOverlayWidgets, buildOverlayIdempotencyKey, } from './common/overlay.js';
2
+ export type { OverlayWidgetsController, OverlayWidgetsOptions, OverlayChatOptions, OverlayQNAOptions, OverlaySimRelOptions, OverlaySimButOptions, } from './common/overlay.js';
3
+ export { bootstrapSession, updatePageContext } from './common/context.js';
4
+ export type { PageContext, SessionContext, WidgetTheme } from './common/types.js';
@@ -0,0 +1,10 @@
1
+ import { i as t, t as a } from "./context-DGz5F81j.js";
2
+ import { i as r, n as i, r as o, t as d } from "./overlay-DJ1ZRMfI.js";
3
+ export {
4
+ a as bootstrapSession,
5
+ d as buildOverlayIdempotencyKey,
6
+ i as destroyOverlayWidgets,
7
+ o as getOverlayWidgets,
8
+ r as initOverlayWidgets,
9
+ t as updatePageContext
10
+ };
@@ -0,0 +1,364 @@
1
+ import { n as I } from "./widget-base-2-B1Ch5I.js";
2
+ import { j as S } from "./context-DGz5F81j.js";
3
+ function E(n, e) {
4
+ if (typeof window > "u" || !S(n)) return !1;
5
+ const r = new CustomEvent("gengage:navigate", {
6
+ detail: e === void 0 ? { url: n } : {
7
+ url: n,
8
+ newTab: e
9
+ },
10
+ cancelable: !0
11
+ });
12
+ return window.dispatchEvent(r) ? (e ? window.open(n, "_blank", "noopener,noreferrer") : window.location.href = n, !0) : !1;
13
+ }
14
+ var _ = console;
15
+ function F(n, e, r = {}) {
16
+ const t = n.action, a = r.logger ?? _;
17
+ switch (I("action", `routing action: ${t.kind}`, t), t.kind) {
18
+ case "open_chat":
19
+ e.openChat?.(t.payload);
20
+ return;
21
+ case "navigate": {
22
+ if (typeof t.url != "string") {
23
+ h(t, e, r, a);
24
+ return;
25
+ }
26
+ if (!S(t.url)) {
27
+ a.warn("[gengage] Blocked navigation to unsafe URL:", t.url);
28
+ return;
29
+ }
30
+ const i = typeof t.newTab == "boolean" ? t.newTab : void 0;
31
+ if (e.navigate) {
32
+ e.navigate({
33
+ url: t.url,
34
+ ...i !== void 0 && { newTab: i }
35
+ });
36
+ return;
37
+ }
38
+ (r.defaultNavigate ?? R)(t.url, i);
39
+ return;
40
+ }
41
+ case "save_session":
42
+ if (typeof t.sessionId != "string" || typeof t.sku != "string") {
43
+ h(t, e, r, a);
44
+ return;
45
+ }
46
+ e.saveSession?.({
47
+ sessionId: t.sessionId,
48
+ sku: t.sku
49
+ });
50
+ return;
51
+ case "add_to_cart":
52
+ if (typeof t.sku != "string" || typeof t.quantity != "number" || typeof t.cartCode != "string") {
53
+ h(t, e, r, a);
54
+ return;
55
+ }
56
+ e.addToCart?.({
57
+ sku: t.sku,
58
+ quantity: t.quantity,
59
+ cartCode: t.cartCode
60
+ });
61
+ return;
62
+ case "script_call": {
63
+ if (r.allowScriptCall === !1) {
64
+ h(t, e, r, a);
65
+ return;
66
+ }
67
+ if (typeof t.name != "string") {
68
+ h(t, e, r, a);
69
+ return;
70
+ }
71
+ const i = q(t.payload) ? t.payload : void 0;
72
+ e.scriptCall?.({
73
+ name: t.name,
74
+ ...i !== void 0 && { payload: i }
75
+ });
76
+ return;
77
+ }
78
+ default:
79
+ h(t, e, r, a);
80
+ }
81
+ }
82
+ function h(n, e, r, t) {
83
+ const a = r.unknownActionPolicy ?? "log-and-ignore";
84
+ if (a === "delegate") {
85
+ e.unknown?.(n), e.unknown || t.warn("[gengage] Unknown action received without delegate handler", n);
86
+ return;
87
+ }
88
+ if (a === "throw") throw new Error(`[gengage] Unknown action kind: ${n.kind}`);
89
+ t.warn("[gengage] Unknown action ignored", n);
90
+ }
91
+ function R(n, e) {
92
+ if (!(typeof window > "u")) {
93
+ if (!S(n)) {
94
+ console.warn("[gengage] Blocked navigation to unsafe URL:", n);
95
+ return;
96
+ }
97
+ E(n, e);
98
+ }
99
+ }
100
+ function q(n) {
101
+ return typeof n == "object" && n !== null && !Array.isArray(n);
102
+ }
103
+ function P(n) {
104
+ const e = globalThis.CSS?.escape;
105
+ if (typeof e == "function") return e(n);
106
+ const r = Array.from(n);
107
+ return r.map((t, a) => {
108
+ const i = t.codePointAt(0);
109
+ return i === void 0 ? "" : i === 0 ? "�" : i >= 1 && i <= 31 || i === 127 || a === 0 && i >= 48 && i <= 57 || a === 1 && r[0] === "-" && i >= 48 && i <= 57 ? `\\${i.toString(16)} ` : a === 0 && t === "-" && r.length === 1 ? "\\-" : i >= 128 || /[A-Za-z0-9_-]/.test(t) ? t : `\\${t}`;
110
+ }).join("");
111
+ }
112
+ function M() {
113
+ return v() !== null;
114
+ }
115
+ function v() {
116
+ const n = globalThis;
117
+ return n.SpeechRecognition ?? n.webkitSpeechRecognition ?? null;
118
+ }
119
+ var z = class {
120
+ constructor(n, e) {
121
+ this.recognition = null, this._state = "idle", this.silenceTimer = null, this.accumulatedTranscript = "", this.intentionalStop = !1, this._lastRestartAt = 0, this.callbacks = n, this.lang = e?.lang ?? "tr-TR", this.silenceTimeoutMs = e?.silenceTimeoutMs ?? 1500, this.autoSubmit = e?.autoSubmit ?? !0;
122
+ }
123
+ get state() {
124
+ return this._state;
125
+ }
126
+ start() {
127
+ if (this._state === "listening") return;
128
+ const n = v();
129
+ if (!n) {
130
+ this.setState("error"), this.callbacks.onError?.("not-supported", "Web Speech API is not supported in this browser.");
131
+ return;
132
+ }
133
+ if (typeof globalThis.isSecureContext < "u" && !globalThis.isSecureContext) {
134
+ this.setState("error"), this.callbacks.onError?.("not-allowed", "Voice input requires HTTPS.");
135
+ return;
136
+ }
137
+ this.accumulatedTranscript = "", this.intentionalStop = !1;
138
+ const e = new n();
139
+ e.continuous = !0, e.interimResults = !0, e.lang = this.lang, e.maxAlternatives = 1, e.onstart = () => {
140
+ this.setState("listening");
141
+ }, e.onresult = (r) => {
142
+ this.clearSilenceTimer();
143
+ let t = "", a = "";
144
+ for (let i = r.resultIndex; i < r.results.length; i++) {
145
+ const u = r.results[i];
146
+ if (!u) continue;
147
+ const p = u[0];
148
+ p && (u.isFinal ? a += p.transcript : t += p.transcript);
149
+ }
150
+ a && (this.accumulatedTranscript += a, this.callbacks.onFinal?.(this.accumulatedTranscript)), t && this.callbacks.onInterim?.(this.accumulatedTranscript + t), this.autoSubmit && this.accumulatedTranscript && this.startSilenceTimer();
151
+ }, e.onerror = (r) => {
152
+ const t = U(r.error);
153
+ this.intentionalStop && (r.error === "no-speech" || r.error === "aborted") || (this.setState("error"), this.callbacks.onError?.(t, r.message || r.error));
154
+ }, e.onend = () => {
155
+ if (this.clearSilenceTimer(), this._state === "listening" && !this.intentionalStop) {
156
+ const r = Date.now();
157
+ if (r - this._lastRestartAt < 500) {
158
+ this.setState("idle");
159
+ return;
160
+ }
161
+ this._lastRestartAt = r;
162
+ try {
163
+ e.start();
164
+ } catch {
165
+ this.setState("idle");
166
+ }
167
+ return;
168
+ }
169
+ this.setState("idle");
170
+ }, this.recognition = e;
171
+ try {
172
+ e.start();
173
+ } catch {
174
+ this.setState("error"), this.callbacks.onError?.("unknown", "Failed to start speech recognition.");
175
+ }
176
+ }
177
+ stop() {
178
+ if (this.intentionalStop = !0, this.clearSilenceTimer(), this.recognition) {
179
+ try {
180
+ this.recognition.stop();
181
+ } catch {
182
+ }
183
+ this.recognition = null;
184
+ }
185
+ return this.setState("idle"), this.accumulatedTranscript;
186
+ }
187
+ abort() {
188
+ if (this.intentionalStop = !0, this.clearSilenceTimer(), this.accumulatedTranscript = "", this.recognition) {
189
+ try {
190
+ this.recognition.abort();
191
+ } catch {
192
+ }
193
+ this.recognition = null;
194
+ }
195
+ this.setState("idle");
196
+ }
197
+ destroy() {
198
+ this.abort();
199
+ }
200
+ setState(n) {
201
+ this._state !== n && (this._state = n, this.callbacks.onStateChange?.(n));
202
+ }
203
+ startSilenceTimer() {
204
+ this.clearSilenceTimer(), this.silenceTimer = setTimeout(() => {
205
+ const n = this.stop();
206
+ n.trim() && this.callbacks.onAutoSubmit?.(n.trim());
207
+ }, this.silenceTimeoutMs);
208
+ }
209
+ clearSilenceTimer() {
210
+ this.silenceTimer !== null && (clearTimeout(this.silenceTimer), this.silenceTimer = null);
211
+ }
212
+ };
213
+ function U(n) {
214
+ switch (n) {
215
+ case "not-allowed":
216
+ return "not-allowed";
217
+ case "no-speech":
218
+ return "no-speech";
219
+ case "audio-capture":
220
+ return "no-microphone";
221
+ case "network":
222
+ return "network";
223
+ case "aborted":
224
+ return "aborted";
225
+ default:
226
+ return "unknown";
227
+ }
228
+ }
229
+ function B(n) {
230
+ const { label: e, avatarUrl: r, primaryColor: t, secondaryColor: a = "#111827", fontFamily: i = "inherit", labelClassName: u = "gengage-pill-launcher-label", styleId: p = "gengage-pill-launcher-style", mobileBreakpoint: $ = 768, desktopWidth: g = "188px", desktopHeight: b = "60px", iconSize: d = "46px" } = n, w = `${parseInt(g, 10) - 14}px`, x = `${parseInt(b, 10) - 4}px`, y = `${parseInt(d, 10) - 4}px`, C = `
231
+ :host {
232
+ --pill-primary: ${t};
233
+ --pill-secondary: ${a};
234
+ --pill-font: ${i};
235
+ }
236
+
237
+ button[data-gengage-part="chat-launcher-button"] {
238
+ box-sizing: border-box;
239
+ width: ${g} !important;
240
+ min-width: ${g} !important;
241
+ max-width: ${g} !important;
242
+ height: ${b} !important;
243
+ min-height: ${b} !important;
244
+ padding: 6px 7px 6px 22px !important;
245
+ display: inline-flex !important;
246
+ flex-direction: row-reverse !important;
247
+ align-items: center !important;
248
+ justify-content: space-between !important;
249
+ gap: 12px !important;
250
+ border-radius: 999px !important;
251
+ border: 1px solid color-mix(in srgb, var(--pill-primary) 18%, white) !important;
252
+ background: #ffffff !important;
253
+ color: var(--pill-secondary) !important;
254
+ box-shadow:
255
+ 0 18px 46px color-mix(in srgb, var(--pill-primary) 18%, transparent),
256
+ 0 4px 14px color-mix(in srgb, var(--pill-secondary) 8%, transparent) !important;
257
+ overflow: visible !important;
258
+ }
259
+
260
+ button[data-gengage-part="chat-launcher-button"]:hover {
261
+ transform: translateY(-1px) !important;
262
+ box-shadow:
263
+ 0 22px 52px color-mix(in srgb, var(--pill-primary) 24%, transparent),
264
+ 0 6px 18px color-mix(in srgb, var(--pill-secondary) 12%, transparent) !important;
265
+ }
266
+
267
+ .${u} {
268
+ color: var(--pill-secondary);
269
+ font: 500 15px/1.05 var(--pill-font);
270
+ letter-spacing: -0.02em;
271
+ white-space: nowrap;
272
+ flex: 0 0 auto;
273
+ pointer-events: none;
274
+ }
275
+
276
+ button[data-gengage-part="chat-launcher-button"] img {
277
+ width: ${d} !important;
278
+ height: ${d} !important;
279
+ flex: 0 0 ${d} !important;
280
+ border-radius: 999px;
281
+ object-fit: cover;
282
+ object-position: center;
283
+ background: transparent;
284
+ border: 0 !important;
285
+ box-shadow: none !important;
286
+ }
287
+
288
+ @media (max-width: ${$}px) {
289
+ button[data-gengage-part="chat-launcher-button"] {
290
+ width: ${w} !important;
291
+ min-width: ${w} !important;
292
+ max-width: ${w} !important;
293
+ height: ${x} !important;
294
+ min-height: ${x} !important;
295
+ padding-left: 20px !important;
296
+ padding-right: 7px !important;
297
+ }
298
+
299
+ .${u} {
300
+ font-size: 14px;
301
+ }
302
+
303
+ button[data-gengage-part="chat-launcher-button"] img {
304
+ width: ${y} !important;
305
+ height: ${y} !important;
306
+ flex-basis: ${y} !important;
307
+ }
308
+ }
309
+ `.trim(), k = () => {
310
+ for (const o of document.querySelectorAll("[data-gengage-widget]")) {
311
+ if (!(o instanceof HTMLElement)) continue;
312
+ const s = o.shadowRoot;
313
+ if (s && (s.querySelector('[data-gengage-part="chat-launcher-button"]') || s.querySelector(".gengage-chat-root")))
314
+ return o;
315
+ }
316
+ return null;
317
+ }, m = (o) => {
318
+ if (o.getElementById(p)) return;
319
+ const s = document.createElement("style");
320
+ s.id = p, s.textContent = C, o.appendChild(s);
321
+ }, A = P(u), T = (o) => {
322
+ m(o);
323
+ const s = o.querySelector('[data-gengage-part="chat-launcher-button"]');
324
+ if (!(s instanceof HTMLButtonElement)) return !1;
325
+ const c = o.querySelector('[data-gengage-part="chat-header-avatar"]');
326
+ if (c instanceof HTMLImageElement) {
327
+ const f = o.querySelector('[data-gengage-part="chat-launcher-button"] img');
328
+ (!f || c.src === f.src) && c.classList.remove("gengage-chat-header-avatar--logo");
329
+ }
330
+ if (s.querySelector(`.${A}`)) return !0;
331
+ s.setAttribute("aria-label", e);
332
+ const l = document.createElement("span");
333
+ return l.className = u, l.textContent = e, s.appendChild(l), !0;
334
+ };
335
+ return {
336
+ launcherImageUrl: r,
337
+ apply: async (o) => {
338
+ if (o) {
339
+ m(o), await Promise.resolve();
340
+ for (let c = 0; c < 90; c++) {
341
+ if (T(o)) return;
342
+ await new Promise((l) => requestAnimationFrame(() => l()));
343
+ }
344
+ return;
345
+ }
346
+ const s = k();
347
+ s?.shadowRoot && m(s.shadowRoot), await Promise.resolve();
348
+ for (let c = 0; c < 90; c++) {
349
+ const l = k()?.shadowRoot ?? null;
350
+ if (l && (m(l), T(l)))
351
+ return;
352
+ await new Promise((f) => requestAnimationFrame(() => f()));
353
+ }
354
+ }
355
+ };
356
+ }
357
+ export {
358
+ F as a,
359
+ P as i,
360
+ z as n,
361
+ E as o,
362
+ M as r,
363
+ B as t
364
+ };
@@ -1,63 +1,3 @@
1
- import { ActionPayload, PageContext } from '../common/types.js';
2
- import { BaseWidget } from '../common/widget-base.js';
3
- import { QNAWidgetConfig } from './types.js';
4
- /**
5
- * Contextual Q&A action buttons for product pages.
6
- * Renders quick-action buttons that open the chat widget with a pre-built query.
7
- *
8
- * @example
9
- * ```ts
10
- * import { GengageQNA, wireQNAToChat, bootstrapSession } from '@gengage/assistant-fe';
11
- *
12
- * const qna = new GengageQNA();
13
- * await qna.init({
14
- * accountId: 'mystore',
15
- * middlewareUrl: '<backend service location provided for your Gengage account>',
16
- * mountTarget: '#qna-section',
17
- * pageContext: { pageType: 'pdp', sku: '12345' },
18
- * session: { sessionId: bootstrapSession() },
19
- * });
20
- * wireQNAToChat(); // Wire button clicks to chat.openWithAction()
21
- * ```
22
- */
23
- export declare class GengageQNA extends BaseWidget<QNAWidgetConfig> {
24
- private _abortController;
25
- private _debounceTimer;
26
- private _contentEl;
27
- private _lastSku;
28
- private _i18n;
29
- protected onInit(config: QNAWidgetConfig): Promise<void>;
30
- protected onUpdate(context: Partial<PageContext>): void;
31
- protected onShow(): void;
32
- protected onHide(): void;
33
- protected onDestroy(): void;
34
- private _abort;
35
- /** `headerTitle` wins over deprecated `headingTitle`. */
36
- private _resolvedQnaHeaderTitle;
37
- /** Clean up TextInput placeholder rotation timers to prevent interval leaks. */
38
- private _cleanupTextInputTimers;
39
- private _fetchAndRender;
40
- private _createLoadingIndicator;
41
- private _resolveI18n;
42
- private _resolveUISpecRegistry;
43
- private _renderUISpec;
44
- private _specIncludesType;
45
- private _buildFallbackActionsSpec;
46
- /**
47
- * Free-text field when the launcher stream has no TextInput. Must sit **above** the
48
- * quick-question pills (heading → search → chips), not below — see `render` order above.
49
- */
50
- private _insertStandaloneInputBeforePills;
51
- private _appendStandaloneInput;
52
- private _handleAction;
53
- private _handleOpenChat;
54
- private _showTransitionIndicator;
55
- _actionHandler: (action: ActionPayload) => void;
56
- _openChatHandler: () => void;
57
- }
58
- export declare function createQNAWidget(): GengageQNA;
59
- export type { QNAWidgetConfig, QNAUIComponents, QNAI18n, QNAUISpecRenderContext, QNARendererConfig } from './types.js';
60
- export { renderQnaUISpec, createDefaultQnaUISpecRegistry, defaultQnaUnknownUISpecRenderer, } from './components/renderUISpec.js';
61
- export type { QNAUISpecRegistry } from './components/renderUISpec.js';
1
+ export * from './runtime.js';
62
2
  export { qnaCatalog } from './catalog.js';
63
3
  export type { QNACatalog, QNAComponentName } from './catalog.js';