@gengage/assistant-fe 0.2.0 → 0.2.2

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 (69) hide show
  1. package/dist/chat/components/Launcher.d.ts +2 -0
  2. package/dist/chat/components/Launcher.d.ts.map +1 -1
  3. package/dist/chat/index.d.ts.map +1 -1
  4. package/dist/chat/panel-manager.d.ts +16 -0
  5. package/dist/chat/panel-manager.d.ts.map +1 -1
  6. package/dist/chat/types.d.ts +6 -0
  7. package/dist/chat/types.d.ts.map +1 -1
  8. package/dist/chat.cjs +1 -1
  9. package/dist/chat.iife.js +8 -8
  10. package/dist/chat.iife.js.map +1 -1
  11. package/dist/chat.js +2 -2
  12. package/dist/common/overlay.d.ts +11 -0
  13. package/dist/common/overlay.d.ts.map +1 -1
  14. package/dist/common/protocol-adapter.d.ts +2 -0
  15. package/dist/common/protocol-adapter.d.ts.map +1 -1
  16. package/dist/common.cjs +1 -1
  17. package/dist/common.js +5 -5
  18. package/dist/index-CB8DgwIv.cjs +13 -0
  19. package/dist/index-CB8DgwIv.cjs.map +1 -0
  20. package/dist/index-CUukV8wH.cjs +2 -0
  21. package/dist/index-CUukV8wH.cjs.map +1 -0
  22. package/dist/{index-C6KDzSjm.js → index-CpLM7vPC.js} +65 -65
  23. package/dist/index-CpLM7vPC.js.map +1 -0
  24. package/dist/{index-RmQRBt6w.js → index-EEUjXgSt.js} +245 -226
  25. package/dist/index-EEUjXgSt.js.map +1 -0
  26. package/dist/index.cjs +1 -1
  27. package/dist/index.js +3 -3
  28. package/dist/native.cjs +1 -1
  29. package/dist/native.iife.js +17 -17
  30. package/dist/native.iife.js.map +1 -1
  31. package/dist/native.js +1 -1
  32. package/dist/qna/index.d.ts.map +1 -1
  33. package/dist/qna/types.d.ts +3 -0
  34. package/dist/qna/types.d.ts.map +1 -1
  35. package/dist/qna.cjs +1 -1
  36. package/dist/qna.cjs.map +1 -1
  37. package/dist/qna.iife.js +15 -15
  38. package/dist/qna.iife.js.map +1 -1
  39. package/dist/qna.js +11 -12
  40. package/dist/qna.js.map +1 -1
  41. package/dist/{schemas-BAEbjFPE.js → schemas-D1Kd4wn8.js} +524 -499
  42. package/dist/schemas-D1Kd4wn8.js.map +1 -0
  43. package/dist/{schemas-DIyHm5pa.cjs → schemas-DOxyUYVA.cjs} +7 -7
  44. package/dist/schemas-DOxyUYVA.cjs.map +1 -0
  45. package/dist/simrel/components/GroupTabs.d.ts +1 -0
  46. package/dist/simrel/components/GroupTabs.d.ts.map +1 -1
  47. package/dist/simrel/components/ProductCard.d.ts +1 -0
  48. package/dist/simrel/components/ProductCard.d.ts.map +1 -1
  49. package/dist/simrel/components/ProductGrid.d.ts +1 -0
  50. package/dist/simrel/components/ProductGrid.d.ts.map +1 -1
  51. package/dist/simrel/components/renderUISpec.d.ts.map +1 -1
  52. package/dist/simrel/index.d.ts.map +1 -1
  53. package/dist/simrel/types.d.ts +10 -0
  54. package/dist/simrel/types.d.ts.map +1 -1
  55. package/dist/simrel.cjs +1 -1
  56. package/dist/simrel.cjs.map +1 -1
  57. package/dist/simrel.iife.js +5 -5
  58. package/dist/simrel.iife.js.map +1 -1
  59. package/dist/simrel.js +171 -165
  60. package/dist/simrel.js.map +1 -1
  61. package/package.json +1 -1
  62. package/dist/index-BA7N_XOO.cjs +0 -2
  63. package/dist/index-BA7N_XOO.cjs.map +0 -1
  64. package/dist/index-C6KDzSjm.js.map +0 -1
  65. package/dist/index-RmQRBt6w.js.map +0 -1
  66. package/dist/index-VgLdYuZV.cjs +0 -13
  67. package/dist/index-VgLdYuZV.cjs.map +0 -1
  68. package/dist/schemas-BAEbjFPE.js.map +0 -1
  69. package/dist/schemas-DIyHm5pa.cjs.map +0 -1
@@ -0,0 +1,2 @@
1
+ "use strict";const V=require("./index-CB8DgwIv.cjs"),K=require("./qna.cjs"),$=require("./simrel.cjs"),s=require("./schemas-DOxyUYVA.cjs"),b=s.object({enabled:s.boolean().default(!0)}),G=s.object({chat:s.string().optional(),qna:s.string().optional(),simrel:s.string().optional()}),Y=s.object({}),k=s._enum(["none","x-api-key-header","bearer-header","body-api-key"]),J=s.object({mode:k.default("none"),key:s.string().optional(),headerName:s.string().optional(),bodyField:s.string().default("api_key")}),X=s.object({enabled:s.boolean().default(!0),endpoint:s.string().default("/analytics"),auth:J.default({mode:"none",bodyField:"api_key"}),fireAndForget:s.boolean().default(!0),useBeacon:s.boolean().default(!0),keepaliveFetch:s.boolean().default(!0),timeoutMs:s.number().int().positive().default(4e3),maxRetries:s.number().int().min(0).max(5).default(1)}),E="__gengageWidgetsInit",z=s.object({idempotencyKey:s.string().default(E),requireDomReady:s.boolean().default(!0)}),R=s._enum(["log-and-ignore","throw","delegate"]),Z=s.object({unknownActionPolicy:R.default("log-and-ignore"),allowScriptCall:s.boolean().default(!1)}),q=s.object({version:s.literal("1",{error:'version must be "1"'}),accountId:s.string({error:"accountId must be a non-empty string"}).min(1,{error:"accountId must be a non-empty string"}),middlewareUrl:s.string({error:'middlewareUrl must be a valid URL (e.g. "https://your-backend.example.com")'}).url({error:'middlewareUrl must be a valid URL (e.g. "https://your-backend.example.com")'}),locale:s.string().optional(),widgets:s.object({chat:b.default({enabled:!0}),qna:b.default({enabled:!0}),simrel:b.default({enabled:!0})}),mounts:G.default({}),transport:Y.default({}),analytics:X.default({enabled:!0,endpoint:"/analytics",auth:{mode:"none",bodyField:"api_key"},fireAndForget:!0,useBeacon:!0,keepaliveFetch:!0,timeoutMs:4e3,maxRetries:1}),gtm:z.default({idempotencyKey:"__gengageWidgetsInit",requireDomReady:!0}),actionHandling:Z.default({unknownActionPolicy:"log-and-ignore",allowScriptCall:!1})});function U(n){s.debugLog("config","parsing account runtime config",n);const e=q.parse(n);return s.debugLog("config","config resolved",{accountId:e.accountId,middlewareUrl:e.middlewareUrl}),e}function ee(n){return q.safeParse(n)}function te(n){return U({version:"1",accountId:n.accountId,middlewareUrl:n.middlewareUrl,locale:n.locale,widgets:{chat:{enabled:!0},qna:{enabled:!0},simrel:{enabled:!0}}})}const x=`${E}_overlay_`,ne="#gengage-qna",ie="#gengage-simrel";function C(){const n=window;return n.__gengageOverlayRegistry||(n.__gengageOverlayRegistry={instances:{},pending:{}}),n.__gengageOverlayRegistry}function se(n){const e={pageType:n.pageContext?.pageType??(n.sku!==void 0?"pdp":"other")},t=n.pageContext;return t?.sku!==void 0&&(e.sku=t.sku),t?.price!==void 0&&(e.price=t.price),t?.categoryTree!==void 0&&(e.categoryTree=t.categoryTree),t?.url!==void 0&&(e.url=t.url),t?.extra!==void 0&&(e.extra=t.extra),n.sku!==void 0&&(e.sku=n.sku),e}function oe(n,e){const t={...n,...e,pageType:e.pageType??n.pageType};return e.sku===void 0&&n.sku!==void 0&&(t.sku=n.sku),t}function N(n){return n instanceof HTMLElement||document.querySelector(n)?n:null}function P(n){return n.idempotencyKey??`${x}${n.accountId}`}class ae{constructor(e,t){this.options=e,this.onDestroy=t,this._chat=null,this._qna=null,this._simrel=null,this._analyticsClient=null,this._offQnaWire=null,this._destroyed=!1,this._queue=Promise.resolve(),this._warnedQnaMountMissing=!1,this._warnedSimRelMountMissing=!1,this.idempotencyKey=P(e),this.session=s.resolveSession(e.session),this._pageContext=se(e)}get chat(){return this._chat}get qna(){return this._qna}get simrel(){return this._simrel}get analyticsClient(){return this._analyticsClient}async init(){window.gengage||(window.gengage={}),window.gengage.sessionId=this.session.sessionId,window.gengage.pageContext=this._pageContext,await this._initChat(),this.options.wireQnaToChat!==!1&&(this._offQnaWire=s.wireQNAToChat()),await this._syncPdpWidgets(),window.gengage.overlay=this}openChat(e){this._chat?.open(e)}closeChat(){this._chat?.close()}async updateContext(e){this._destroyed||await this._enqueue(async()=>{this._pageContext=oe(this._pageContext,e),window.gengage||(window.gengage={}),window.gengage.pageContext=this._pageContext,this._chat?.update(e),this._qna?.update(e),this._simrel?.update(e),await this._syncPdpWidgets()})}async updateSku(e,t="pdp"){await this.updateContext({sku:e,pageType:t})}destroy(){this._destroyed||(this._destroyed=!0,this._offQnaWire?.(),this._offQnaWire=null,this._chat?.destroy(),this._qna?.destroy(),this._simrel?.destroy(),this._chat=null,this._qna=null,this._simrel=null,window.gengage?.overlay===this&&delete window.gengage.overlay,this.onDestroy())}async _initChat(){if(this.options.chat?.enabled===!1)return;const e=this.options.middlewareUrl,t={accountId:this.options.accountId,middlewareUrl:e,session:this.session,pageContext:this._pageContext,variant:this.options.chat?.variant??"floating"};this.options.theme!==void 0&&(t.theme=this.options.theme),this.options.locale!==void 0&&(t.locale=this.options.locale),this.options.pricing!==void 0&&(t.pricing=this.options.pricing),this.options.chat?.mountTarget!==void 0&&(t.mountTarget=this.options.chat.mountTarget),this.options.chat?.launcherImageUrl!==void 0?t.launcherImageUrl=this.options.chat.launcherImageUrl:this.options.chat?.launcherSvg!==void 0&&(t.launcherSvg=this.options.chat.launcherSvg),this.options.chat?.headerTitle!==void 0&&(t.headerTitle=this.options.chat.headerTitle),this.options.chat?.headerAvatarUrl!==void 0&&(t.headerAvatarUrl=this.options.chat.headerAvatarUrl),this.options.chat?.headerBadge!==void 0&&(t.headerBadge=this.options.chat.headerBadge),this.options.chat?.headerCartUrl!==void 0&&(t.headerCartUrl=this.options.chat.headerCartUrl),this.options.chat?.headerFavoritesToggle!==void 0&&(t.headerFavoritesToggle=this.options.chat.headerFavoritesToggle),this.options.chat?.hideMobileLauncher!==void 0&&(t.hideMobileLauncher=this.options.chat.hideMobileLauncher),this.options.chat?.mobileBreakpoint!==void 0&&(t.mobileBreakpoint=this.options.chat.mobileBreakpoint),this.options.chat?.mobileInitialState!==void 0&&(t.mobileInitialState=this.options.chat.mobileInitialState),this.options.chat?.i18n!==void 0&&(t.i18n=this.options.chat.i18n),this.options.chat?.actionHandling!==void 0&&(t.actionHandling=this.options.chat.actionHandling),this.options.chat?.renderer!==void 0&&(t.renderer=this.options.chat.renderer),this.options.onScriptCall!==void 0&&(t.onScriptCall=this.options.onScriptCall),this._chat=new V.GengageChat,await this._chat.init(t)}async _syncPdpWidgets(){if(this._destroyed)return;const e=this._pageContext.sku;if(!(this._pageContext.pageType==="pdp"&&e!==void 0&&e.length>0)){this._destroyPdpWidgets();return}const r=this.options.middlewareUrl;if(this.options.qna?.enabled!==!1){const o=this.options.qna?.mountTarget??ne,i=N(o);if(i)if(this._warnedQnaMountMissing=!1,this._qna)this._qna.show(),this._qna.update({pageType:"pdp",sku:e});else{const h=new K.GengageQNA,a={accountId:this.options.accountId,middlewareUrl:r,session:this.session,pageContext:{pageType:"pdp",sku:e},mountTarget:i};this.options.theme!==void 0&&(a.theme=this.options.theme),this.options.qna?.ctaText!==void 0&&(a.ctaText=this.options.qna.ctaText),this.options.qna?.hideButtonRowCta!==void 0&&(a.hideButtonRowCta=this.options.qna.hideButtonRowCta),this.options.qna?.inputPlaceholder!==void 0&&(a.inputPlaceholder=this.options.qna.inputPlaceholder),this.options.qna?.i18n!==void 0&&(a.i18n=this.options.qna.i18n),this.options.qna?.renderer!==void 0&&(a.renderer=this.options.qna.renderer),await h.init(a),this._qna=h}else this._qna?.destroy(),this._qna=null,this._warnedQnaMountMissing||(console.warn(`[gengage] QNA mount target not found: ${o}`),this._warnedQnaMountMissing=!0)}else this._qna?.destroy(),this._qna=null;if(this.options.simrel?.enabled!==!1){const o=this.options.simrel?.mountTarget??ie,i=N(o);if(i)if(this._warnedSimRelMountMissing=!1,this._simrel)this._simrel.show(),this._simrel.update({pageType:"pdp",sku:e});else{const h=new $.GengageSimRel,a={accountId:this.options.accountId,middlewareUrl:r,session:this.session,sku:e,mountTarget:i};this.options.theme!==void 0&&(a.theme=this.options.theme),this.options.pricing!==void 0&&(a.pricing=this.options.pricing),this.options.simrel?.discountType!==void 0&&(a.discountType=this.options.simrel.discountType),this.options.simrel?.renderCardElement!==void 0&&(a.renderCardElement=this.options.simrel.renderCardElement),this.options.simrel?.renderer!==void 0&&(a.renderer=this.options.simrel.renderer),this.options.onAddToCart!==void 0&&(a.onAddToCart=this.options.onAddToCart),this.options.onProductNavigate!==void 0?a.onProductNavigate=this.options.onProductNavigate:a.onProductNavigate=(d,l,p)=>{s.isSafeUrl(d)&&(this._chat?.saveSession(p??this.session.sessionId,l),window.location.href=d)},await h.init(a),this._simrel=h}else this._simrel?.destroy(),this._simrel=null,this._warnedSimRelMountMissing||(console.warn(`[gengage] SimRel mount target not found: ${o}`),this._warnedSimRelMountMissing=!0)}else this._simrel?.destroy(),this._simrel=null}_destroyPdpWidgets(){this._qna?.destroy(),this._simrel?.destroy(),this._qna=null,this._simrel=null}_enqueue(e){const t=this._queue.then(e);return this._queue=t.catch(r=>{}),t}}async function W(n){const e=P(n),t=C(),r=t.instances[e];if(r)return r;const o=t.pending[e];if(o)return o;const i=new ae(n,()=>{const a=C();delete a.instances[e],delete a.pending[e]}),h=i.init().then(()=>(t.instances[e]=i,delete t.pending[e],i)).catch(a=>{throw delete t.pending[e],a});return t.pending[e]=h,h}function O(n){return C().instances[n]??null}function re(n){O(n)?.destroy()}function de(n){return`${x}${n}`}const L=["gengage:chat:open","gengage:chat:close","gengage:chat:ready","gengage:chat:add-to-cart","gengage:qna:action","gengage:qna:open-chat","gengage:similar:product-click","gengage:similar:add-to-cart","gengage:global:error","gengage:context:update"],ce=32,S="#gengage-qna",M="#gengage-simrel";function le(n){let e=n;if(typeof n=="string"){const i=n.trim();if(i.length===0)return null;if(!i.startsWith("{")&&!i.startsWith("["))return{type:i};try{e=JSON.parse(i)}catch{return null}}if(!e||typeof e!="object")return null;const t=e,r=[t.type,t.command,t.action,t.event].find(i=>typeof i=="string"&&i.length>0);if(!r)return null;let o=t.payload;if(o===void 0&&"data"in t&&(o=t.data),r==="setSession"&&o===void 0){const i={};typeof t.sessionId=="string"&&(i.sessionId=t.sessionId),typeof t.userId=="string"&&(i.userId=t.userId),(i.sessionId!==void 0||i.userId!==void 0)&&(o=i)}return o===void 0?{type:r}:{type:r,payload:o}}function ge(n){if(typeof n=="string"&&n.length>0)return{sku:n};if(n&&typeof n=="object"&&"sku"in n){const e=n.sku;if(typeof e=="string"&&e.length>0){const t=n.pageType;return t!==void 0?{sku:e,pageType:t}:{sku:e}}}return null}function T(n,e){return e instanceof HTMLElement?!0:typeof e!="string"?!1:n.document.querySelector(e)!==null}function A(n,e,t){if(e instanceof HTMLElement||T(n,e)||typeof e!="string")return e;if(e.startsWith("#")){const i=e.slice(1);if(i.length>0){const h=n.document.getElementById(i);if(h)return h;const a=n.document.createElement("div");return a.id=i,n.document.body.appendChild(a),a}}const r=n.document.getElementById(t);if(r)return r;const o=n.document.createElement("div");return o.id=t,n.document.body.appendChild(o),o}function B(n,e){const t=n.webkit?.messageHandlers?.[e];return t&&typeof t.postMessage=="function"?t.postMessage.bind(t):null}function v(n,e){const t=n[e];return t&&typeof t=="object"&&typeof t.postMessage=="function"?t:null}function D(n={}){const e=n.win??window,t=n.iosHandlerName??"gengage",r=n.androidInterfaceName??"GengageNative",o=n.reactNativeInterfaceName??"ReactNativeWebView";return B(e,t)?"ios":v(e,r)?"android":v(e,o)?"react-native":"browser"}function F(n,e={}){const t=e.win??window;if(n.sessionId!==void 0){t.__gengageSessionId=n.sessionId,t.gengage||(t.gengage={}),t.gengage.sessionId=n.sessionId;try{t.sessionStorage.setItem("gengage_session_id",n.sessionId)}catch{}}if(n.userId!==void 0){t.gengage||(t.gengage={});const r=t.gengage,o=r.session??{};o.userId=n.userId,r.session=o}}function j(n={}){const e=n.win??window,t=e;if(t.gengageNative)return t.gengageNative;const r=n.iosHandlerName??"gengage",o=n.androidInterfaceName??"GengageNative",i=n.reactNativeInterfaceName??"ReactNativeWebView",h=n.trackedEvents??[...L],a=D({win:e,iosHandlerName:r,androidInterfaceName:o,reactNativeInterfaceName:i});let d=e.gengage?.overlay??null;const l=[],p=(g,c)=>{const f=c===void 0?{type:g}:{type:g,payload:c};if(a==="ios"){B(e,r)?.(f);return}if(a==="android"){v(e,o)?.postMessage(JSON.stringify(f));return}if(a==="react-native"){v(e,i)?.postMessage(JSON.stringify(f));return}},m=g=>{const c=g.detail;!c||typeof c.namespace!="string"||typeof c.type!="string"||p("bridge_message",{namespace:c.namespace,type:c.type,payload:c.payload})};e.addEventListener("gengage:bridge:message",m);const Q=h.map(g=>{const c=f=>{const u=f.detail;p("widget_event",{event:g,detail:u})};return e.addEventListener(g,c),{event:g,handler:c}}),y=g=>{l.length>=ce&&l.shift(),l.push(g)},H=()=>{if(!d||l.length===0)return;const g=l.splice(0,l.length);for(const c of g)I(c)},I=g=>{const c=le(g);if(!c||typeof c.type!="string"){console.warn("[gengage:native-bridge] Invalid message:",g);return}const f=c.type,u=c.payload;switch(f){case"openChat":{d?d.openChat(u&&typeof u=="object"?u:u==="half"||u==="full"?{state:u}:void 0):y(c);return}case"closeChat":{d?d.closeChat():y(c);return}case"updateContext":{d&&u&&typeof u=="object"?d.updateContext(u):d?console.warn("[gengage:native-bridge] updateContext: missing payload"):y(c);return}case"updateSku":{const w=ge(u);if(d&&w){d.updateSku(w.sku,w.pageType);return}d?console.warn("[gengage:native-bridge] updateSku: missing sku"):y(c);return}case"setSession":{u&&typeof u=="object"&&F(u,{win:e});return}case"destroy":{d?.destroy();return}default:e.postMessage({gengage:"native",type:f,payload:u},e.location.origin),n.logUnhandled&&console.warn("[gengage:native-bridge] Unhandled inbound type forwarded:",f)}},_={env:a,sendToNative:p,receive:I,setController(g){d=g,H()},destroy(){e.removeEventListener("gengage:bridge:message",m);for(const g of Q)e.removeEventListener(g.event,g.handler);l.splice(0,l.length),e.gengageNative===_&&delete e.gengageNative}};return t.gengageNative=_,_}async function ue(n){const{nativeBridge:e,emitReadyEvent:t=!0,...r}=n,o=j(e),i={...r};i.onAddToCart||(i.onAddToCart=l=>{o.sendToNative("addToCart",{sku:l.sku,quantity:l.quantity,cartCode:l.cartCode})}),i.onProductNavigate||(i.onProductNavigate=(l,p,m)=>{o.sendToNative("productNavigate",{url:l,sku:p,sessionId:m})});const h=i.qna?.enabled===!0||i.qna?.mountTarget!==void 0;if(i.qna?.enabled!==!1)if(h){const l=A(window,i.qna?.mountTarget??S,"gengage-qna");i.qna={...i.qna,enabled:!0,mountTarget:l}}else T(window,S)||(i.qna={enabled:!1});const a=i.simrel?.enabled===!0||i.simrel?.mountTarget!==void 0;if(i.simrel?.enabled!==!1)if(a){const l=A(window,i.simrel?.mountTarget??M,"gengage-simrel");i.simrel={...i.simrel,enabled:!0,mountTarget:l}}else T(window,M)||(i.simrel={enabled:!1});const d=await W(i);return o.setController(d),t&&o.sendToNative("ready",{sessionId:d.session.sessionId,widgets:{chat:d.chat!==null,qna:d.qna!==null,simrel:d.simrel!==null}}),{controller:d,bridge:o,destroy(){d.destroy(),o.destroy()}}}exports.AccountRuntimeConfigSchema=q;exports.AnalyticsAuthModeSchema=k;exports.DEFAULT_NATIVE_TRACKED_EVENTS=L;exports.UnknownActionPolicySchema=R;exports.applyNativeSession=F;exports.buildOverlayIdempotencyKey=de;exports.createDefaultAccountRuntimeConfig=te;exports.createNativeWebViewBridge=j;exports.destroyOverlayWidgets=re;exports.detectNativeEnvironment=D;exports.getOverlayWidgets=O;exports.initNativeOverlayWidgets=ue;exports.initOverlayWidgets=W;exports.parseAccountRuntimeConfig=U;exports.safeParseAccountRuntimeConfig=ee;
2
+ //# sourceMappingURL=index-CUukV8wH.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-CUukV8wH.cjs","sources":["../src/common/config-schema.ts","../src/common/overlay.ts","../src/common/native-webview.ts"],"sourcesContent":["import { z } from 'zod';\nimport { debugLog } from './debug.js';\n\nconst WidgetToggleSchema = z.object({\n enabled: z.boolean().default(true),\n});\n\nconst MountSelectorsSchema = z.object({\n chat: z.string().optional(),\n qna: z.string().optional(),\n simrel: z.string().optional(),\n});\n\nconst TransportSchema = z.object({});\n\nexport const AnalyticsAuthModeSchema = z.enum(['none', 'x-api-key-header', 'bearer-header', 'body-api-key']);\n\nconst AnalyticsAuthSchema = z.object({\n mode: AnalyticsAuthModeSchema.default('none'),\n key: z.string().optional(),\n headerName: z.string().optional(),\n bodyField: z.string().default('api_key'),\n});\n\nconst AnalyticsSchema = z.object({\n enabled: z.boolean().default(true),\n endpoint: z.string().default('/analytics'),\n auth: AnalyticsAuthSchema.default({ mode: 'none', bodyField: 'api_key' }),\n fireAndForget: z.boolean().default(true),\n useBeacon: z.boolean().default(true),\n keepaliveFetch: z.boolean().default(true),\n timeoutMs: z.number().int().positive().default(4000),\n maxRetries: z.number().int().min(0).max(5).default(1),\n});\n\nexport const DEFAULT_IDEMPOTENCY_KEY = '__gengageWidgetsInit';\n\nconst GTMSchema = z.object({\n idempotencyKey: z.string().default(DEFAULT_IDEMPOTENCY_KEY),\n requireDomReady: z.boolean().default(true),\n});\n\nexport const UnknownActionPolicySchema = z.enum(['log-and-ignore', 'throw', 'delegate']);\n\nconst ActionHandlingSchema = z.object({\n unknownActionPolicy: UnknownActionPolicySchema.default('log-and-ignore'),\n allowScriptCall: z.boolean().default(false),\n});\n\nexport const AccountRuntimeConfigSchema = z.object({\n version: z.literal('1', { error: 'version must be \"1\"' }),\n accountId: z\n .string({ error: 'accountId must be a non-empty string' })\n .min(1, { error: 'accountId must be a non-empty string' }),\n middlewareUrl: z\n .string({ error: 'middlewareUrl must be a valid URL (e.g. \"https://your-backend.example.com\")' })\n .url({ error: 'middlewareUrl must be a valid URL (e.g. \"https://your-backend.example.com\")' }),\n locale: z.string().optional(),\n widgets: z.object({\n chat: WidgetToggleSchema.default({ enabled: true }),\n qna: WidgetToggleSchema.default({ enabled: true }),\n simrel: WidgetToggleSchema.default({ enabled: true }),\n }),\n mounts: MountSelectorsSchema.default({}),\n transport: TransportSchema.default({}),\n analytics: AnalyticsSchema.default({\n enabled: true,\n endpoint: '/analytics',\n auth: { mode: 'none', bodyField: 'api_key' },\n fireAndForget: true,\n useBeacon: true,\n keepaliveFetch: true,\n timeoutMs: 4000,\n maxRetries: 1,\n }),\n gtm: GTMSchema.default({\n idempotencyKey: '__gengageWidgetsInit',\n requireDomReady: true,\n }),\n actionHandling: ActionHandlingSchema.default({\n unknownActionPolicy: 'log-and-ignore',\n allowScriptCall: false,\n }),\n});\n\nexport type AccountRuntimeConfig = z.infer<typeof AccountRuntimeConfigSchema>;\nexport type AnalyticsAuthMode = z.infer<typeof AnalyticsAuthModeSchema>;\nexport type UnknownActionPolicy = z.infer<typeof UnknownActionPolicySchema>;\n\nexport function parseAccountRuntimeConfig(input: unknown): AccountRuntimeConfig {\n debugLog('config', 'parsing account runtime config', input);\n const result = AccountRuntimeConfigSchema.parse(input);\n debugLog('config', 'config resolved', { accountId: result.accountId, middlewareUrl: result.middlewareUrl });\n return result;\n}\n\nexport function safeParseAccountRuntimeConfig(input: unknown): ReturnType<typeof AccountRuntimeConfigSchema.safeParse> {\n return AccountRuntimeConfigSchema.safeParse(input);\n}\n\nexport function createDefaultAccountRuntimeConfig(params: {\n accountId: string;\n middlewareUrl: string;\n locale?: string;\n}): AccountRuntimeConfig {\n return parseAccountRuntimeConfig({\n version: '1',\n accountId: params.accountId,\n middlewareUrl: params.middlewareUrl,\n locale: params.locale,\n widgets: {\n chat: { enabled: true },\n qna: { enabled: true },\n simrel: { enabled: true },\n },\n });\n}\n","import { GengageChat } from '../chat/index.js';\nimport type { ChatI18n, ChatWidgetConfig } from '../chat/types.js';\nimport { GengageQNA } from '../qna/index.js';\nimport type { QNAWidgetConfig } from '../qna/types.js';\nimport { GengageSimRel } from '../simrel/index.js';\nimport type { SimRelWidgetConfig } from '../simrel/types.js';\nimport { DEFAULT_IDEMPOTENCY_KEY } from './config-schema.js';\nimport { resolveSession } from './context.js';\nimport { wireQNAToChat } from './events.js';\nimport { isSafeUrl } from './safe-html.js';\nimport type { PageContext, SessionContext, WidgetTheme } from './types.js';\n\nconst DEFAULT_OVERLAY_KEY_PREFIX = `${DEFAULT_IDEMPOTENCY_KEY}_overlay_`;\nconst DEFAULT_QNA_MOUNT = '#gengage-qna';\nconst DEFAULT_SIMREL_MOUNT = '#gengage-simrel';\n\ninterface OverlayRegistryState {\n instances: Record<string, OverlayWidgetsRuntime>;\n pending: Record<string, Promise<OverlayWidgetsRuntime>>;\n}\n\ninterface WindowWithOverlayRegistry extends Window {\n __gengageOverlayRegistry?: OverlayRegistryState;\n}\n\nfunction getOverlayRegistry(): OverlayRegistryState {\n const win = window as WindowWithOverlayRegistry;\n if (!win.__gengageOverlayRegistry) {\n win.__gengageOverlayRegistry = {\n instances: {},\n pending: {},\n };\n }\n return win.__gengageOverlayRegistry;\n}\n\nfunction buildInitialPageContext(options: OverlayWidgetsOptions): PageContext {\n const base: PageContext = {\n pageType: options.pageContext?.pageType ?? (options.sku !== undefined ? 'pdp' : 'other'),\n };\n\n const incoming = options.pageContext;\n if (incoming?.sku !== undefined) base.sku = incoming.sku;\n if (incoming?.price !== undefined) base.price = incoming.price;\n if (incoming?.categoryTree !== undefined) base.categoryTree = incoming.categoryTree;\n if (incoming?.url !== undefined) base.url = incoming.url;\n if (incoming?.extra !== undefined) base.extra = incoming.extra;\n\n if (options.sku !== undefined) {\n base.sku = options.sku;\n }\n\n return base;\n}\n\nfunction mergePageContext(current: PageContext, patch: Partial<PageContext>): PageContext {\n const next: PageContext = {\n ...current,\n ...patch,\n pageType: patch.pageType ?? current.pageType,\n };\n if (patch.sku === undefined && current.sku !== undefined) {\n next.sku = current.sku;\n }\n return next;\n}\n\nfunction resolveMountTarget(target: HTMLElement | string): HTMLElement | string | null {\n if (target instanceof HTMLElement) return target;\n if (document.querySelector(target)) return target;\n return null;\n}\n\nfunction buildOverlayKey(options: OverlayWidgetsOptions): string {\n return options.idempotencyKey ?? `${DEFAULT_OVERLAY_KEY_PREFIX}${options.accountId}`;\n}\n\nexport interface OverlayChatOptions {\n enabled?: boolean;\n variant?: ChatWidgetConfig['variant'];\n mountTarget?: HTMLElement | string;\n launcherSvg?: string;\n launcherImageUrl?: string;\n headerTitle?: string;\n headerAvatarUrl?: string;\n headerBadge?: string;\n headerCartUrl?: string;\n headerFavoritesToggle?: boolean;\n hideMobileLauncher?: boolean;\n mobileBreakpoint?: number;\n mobileInitialState?: 'half' | 'full';\n i18n?: Partial<ChatI18n>;\n actionHandling?: ChatWidgetConfig['actionHandling'];\n /** UISpec renderer overrides for chat components. */\n renderer?: ChatWidgetConfig['renderer'];\n}\n\nexport interface OverlayQNAOptions {\n enabled?: boolean;\n mountTarget?: HTMLElement | string;\n ctaText?: string;\n hideButtonRowCta?: boolean;\n inputPlaceholder?: QNAWidgetConfig['inputPlaceholder'];\n i18n?: QNAWidgetConfig['i18n'];\n /** UISpec renderer overrides for QNA components. */\n renderer?: QNAWidgetConfig['renderer'];\n}\n\nexport interface OverlaySimRelOptions {\n enabled?: boolean;\n mountTarget?: HTMLElement | string;\n discountType?: SimRelWidgetConfig['discountType'];\n /** Custom card element renderer for the direct rendering path (GroupTabs/ProductGrid). */\n renderCardElement?: SimRelWidgetConfig['renderCardElement'];\n /** UISpec renderer overrides for simrel components. */\n renderer?: SimRelWidgetConfig['renderer'];\n}\n\nexport interface OverlayWidgetsOptions {\n accountId: string;\n middlewareUrl: string;\n locale?: string;\n session?: Partial<SessionContext>;\n pageContext?: Partial<PageContext>;\n sku?: string;\n theme?: WidgetTheme;\n /** Price formatting options. Defaults to Turkish locale. */\n pricing?: import('./price-formatter.js').PriceFormatConfig;\n idempotencyKey?: string;\n wireQnaToChat?: boolean;\n chat?: OverlayChatOptions;\n qna?: OverlayQNAOptions;\n simrel?: OverlaySimRelOptions;\n onAddToCart?: SimRelWidgetConfig['onAddToCart'];\n onProductNavigate?: SimRelWidgetConfig['onProductNavigate'];\n onScriptCall?: ChatWidgetConfig['onScriptCall'];\n}\n\nexport interface OverlayWidgetsController {\n readonly idempotencyKey: string;\n readonly session: SessionContext;\n readonly chat: GengageChat | null;\n readonly qna: GengageQNA | null;\n readonly simrel: GengageSimRel | null;\n /** Shared analytics client for custom event tracking (null if not configured). */\n readonly analyticsClient: import('./analytics.js').AnalyticsClient | null;\n openChat(options?: { state?: 'half' | 'full' }): void;\n closeChat(): void;\n updateContext(patch: Partial<PageContext>): Promise<void>;\n updateSku(sku: string, pageType?: PageContext['pageType']): Promise<void>;\n destroy(): void;\n}\n\nclass OverlayWidgetsRuntime implements OverlayWidgetsController {\n private _chat: GengageChat | null = null;\n private _qna: GengageQNA | null = null;\n private _simrel: GengageSimRel | null = null;\n private _analyticsClient: import('./analytics.js').AnalyticsClient | null = null;\n private _offQnaWire: (() => void) | null = null;\n private _pageContext: PageContext;\n private _destroyed = false;\n private _queue: Promise<void> = Promise.resolve();\n private _warnedQnaMountMissing = false;\n private _warnedSimRelMountMissing = false;\n\n readonly idempotencyKey: string;\n readonly session: SessionContext;\n\n constructor(\n private readonly options: OverlayWidgetsOptions,\n private readonly onDestroy: () => void,\n ) {\n this.idempotencyKey = buildOverlayKey(options);\n this.session = resolveSession(options.session);\n this._pageContext = buildInitialPageContext(options);\n }\n\n get chat(): GengageChat | null {\n return this._chat;\n }\n\n get qna(): GengageQNA | null {\n return this._qna;\n }\n\n get simrel(): GengageSimRel | null {\n return this._simrel;\n }\n\n get analyticsClient(): import('./analytics.js').AnalyticsClient | null {\n return this._analyticsClient;\n }\n\n async init(): Promise<void> {\n if (!window.gengage) window.gengage = {};\n window.gengage.sessionId = this.session.sessionId;\n window.gengage.pageContext = this._pageContext;\n\n await this._initChat();\n\n if (this.options.wireQnaToChat !== false) {\n this._offQnaWire = wireQNAToChat();\n }\n\n await this._syncPdpWidgets();\n\n window.gengage.overlay = this;\n }\n\n openChat(options?: { state?: 'half' | 'full' }): void {\n this._chat?.open(options);\n }\n\n closeChat(): void {\n this._chat?.close();\n }\n\n async updateContext(patch: Partial<PageContext>): Promise<void> {\n if (this._destroyed) return;\n await this._enqueue(async () => {\n this._pageContext = mergePageContext(this._pageContext, patch);\n\n if (!window.gengage) window.gengage = {};\n window.gengage.pageContext = this._pageContext;\n\n this._chat?.update(patch);\n this._qna?.update(patch);\n this._simrel?.update(patch);\n await this._syncPdpWidgets();\n });\n }\n\n async updateSku(sku: string, pageType: PageContext['pageType'] = 'pdp'): Promise<void> {\n await this.updateContext({ sku, pageType });\n }\n\n destroy(): void {\n if (this._destroyed) return;\n this._destroyed = true;\n\n this._offQnaWire?.();\n this._offQnaWire = null;\n\n this._chat?.destroy();\n this._qna?.destroy();\n this._simrel?.destroy();\n\n this._chat = null;\n this._qna = null;\n this._simrel = null;\n\n if (window.gengage?.overlay === this) {\n delete window.gengage.overlay;\n }\n\n this.onDestroy();\n }\n\n private async _initChat(): Promise<void> {\n if (this.options.chat?.enabled === false) return;\n\n const middlewareUrl = this.options.middlewareUrl;\n\n const config: ChatWidgetConfig = {\n accountId: this.options.accountId,\n middlewareUrl,\n session: this.session,\n pageContext: this._pageContext,\n variant: this.options.chat?.variant ?? 'floating',\n };\n\n if (this.options.theme !== undefined) config.theme = this.options.theme;\n if (this.options.locale !== undefined) config.locale = this.options.locale;\n if (this.options.pricing !== undefined) config.pricing = this.options.pricing;\n if (this.options.chat?.mountTarget !== undefined) config.mountTarget = this.options.chat.mountTarget;\n if (this.options.chat?.launcherImageUrl !== undefined) config.launcherImageUrl = this.options.chat.launcherImageUrl;\n else if (this.options.chat?.launcherSvg !== undefined) config.launcherSvg = this.options.chat.launcherSvg;\n if (this.options.chat?.headerTitle !== undefined) config.headerTitle = this.options.chat.headerTitle;\n if (this.options.chat?.headerAvatarUrl !== undefined) {\n config.headerAvatarUrl = this.options.chat.headerAvatarUrl;\n }\n if (this.options.chat?.headerBadge !== undefined) config.headerBadge = this.options.chat.headerBadge;\n if (this.options.chat?.headerCartUrl !== undefined) config.headerCartUrl = this.options.chat.headerCartUrl;\n if (this.options.chat?.headerFavoritesToggle !== undefined) {\n config.headerFavoritesToggle = this.options.chat.headerFavoritesToggle;\n }\n if (this.options.chat?.hideMobileLauncher !== undefined) {\n config.hideMobileLauncher = this.options.chat.hideMobileLauncher;\n }\n if (this.options.chat?.mobileBreakpoint !== undefined) {\n config.mobileBreakpoint = this.options.chat.mobileBreakpoint;\n }\n if (this.options.chat?.mobileInitialState !== undefined) {\n config.mobileInitialState = this.options.chat.mobileInitialState;\n }\n if (this.options.chat?.i18n !== undefined) config.i18n = this.options.chat.i18n;\n if (this.options.chat?.actionHandling !== undefined) {\n config.actionHandling = this.options.chat.actionHandling;\n }\n if (this.options.chat?.renderer !== undefined) config.renderer = this.options.chat.renderer;\n if (this.options.onScriptCall !== undefined) {\n config.onScriptCall = this.options.onScriptCall;\n }\n\n this._chat = new GengageChat();\n await this._chat.init(config);\n }\n\n private async _syncPdpWidgets(): Promise<void> {\n if (this._destroyed) return;\n const sku = this._pageContext.sku;\n const isPdp = this._pageContext.pageType === 'pdp' && sku !== undefined && sku.length > 0;\n\n if (!isPdp) {\n this._destroyPdpWidgets();\n return;\n }\n\n const middlewareUrl = this.options.middlewareUrl;\n\n if (this.options.qna?.enabled !== false) {\n const qnaTarget = this.options.qna?.mountTarget ?? DEFAULT_QNA_MOUNT;\n const mountTarget = resolveMountTarget(qnaTarget);\n\n if (mountTarget) {\n this._warnedQnaMountMissing = false;\n if (!this._qna) {\n const qna = new GengageQNA();\n const qnaConfig: QNAWidgetConfig = {\n accountId: this.options.accountId,\n middlewareUrl,\n session: this.session,\n pageContext: {\n pageType: 'pdp',\n sku,\n },\n mountTarget,\n };\n if (this.options.theme !== undefined) qnaConfig.theme = this.options.theme;\n if (this.options.qna?.ctaText !== undefined) qnaConfig.ctaText = this.options.qna.ctaText;\n if (this.options.qna?.hideButtonRowCta !== undefined)\n qnaConfig.hideButtonRowCta = this.options.qna.hideButtonRowCta;\n if (this.options.qna?.inputPlaceholder !== undefined) {\n qnaConfig.inputPlaceholder = this.options.qna.inputPlaceholder;\n }\n if (this.options.qna?.i18n !== undefined) qnaConfig.i18n = this.options.qna.i18n;\n if (this.options.qna?.renderer !== undefined) qnaConfig.renderer = this.options.qna.renderer;\n await qna.init(qnaConfig);\n this._qna = qna;\n } else {\n this._qna.show();\n this._qna.update({ pageType: 'pdp', sku });\n }\n } else {\n this._qna?.destroy();\n this._qna = null;\n if (!this._warnedQnaMountMissing) {\n console.warn(`[gengage] QNA mount target not found: ${qnaTarget}`);\n this._warnedQnaMountMissing = true;\n }\n }\n } else {\n this._qna?.destroy();\n this._qna = null;\n }\n\n if (this.options.simrel?.enabled !== false) {\n const simRelTarget = this.options.simrel?.mountTarget ?? DEFAULT_SIMREL_MOUNT;\n const mountTarget = resolveMountTarget(simRelTarget);\n\n if (mountTarget) {\n this._warnedSimRelMountMissing = false;\n if (!this._simrel) {\n const simrel = new GengageSimRel();\n const simRelConfig: SimRelWidgetConfig = {\n accountId: this.options.accountId,\n middlewareUrl,\n session: this.session,\n sku,\n mountTarget,\n };\n if (this.options.theme !== undefined) simRelConfig.theme = this.options.theme;\n if (this.options.pricing !== undefined) simRelConfig.pricing = this.options.pricing;\n if (this.options.simrel?.discountType !== undefined) {\n simRelConfig.discountType = this.options.simrel.discountType;\n }\n if (this.options.simrel?.renderCardElement !== undefined) {\n simRelConfig.renderCardElement = this.options.simrel.renderCardElement;\n }\n if (this.options.simrel?.renderer !== undefined) {\n simRelConfig.renderer = this.options.simrel.renderer;\n }\n if (this.options.onAddToCart !== undefined) {\n simRelConfig.onAddToCart = this.options.onAddToCart;\n }\n if (this.options.onProductNavigate !== undefined) {\n simRelConfig.onProductNavigate = this.options.onProductNavigate;\n } else {\n simRelConfig.onProductNavigate = (url, productSku, sessionId) => {\n if (!isSafeUrl(url)) return;\n this._chat?.saveSession(sessionId ?? this.session.sessionId, productSku);\n window.location.href = url;\n };\n }\n await simrel.init(simRelConfig);\n this._simrel = simrel;\n } else {\n this._simrel.show();\n this._simrel.update({ pageType: 'pdp', sku });\n }\n } else {\n this._simrel?.destroy();\n this._simrel = null;\n if (!this._warnedSimRelMountMissing) {\n console.warn(`[gengage] SimRel mount target not found: ${simRelTarget}`);\n this._warnedSimRelMountMissing = true;\n }\n }\n } else {\n this._simrel?.destroy();\n this._simrel = null;\n }\n }\n\n private _destroyPdpWidgets(): void {\n this._qna?.destroy();\n this._simrel?.destroy();\n this._qna = null;\n this._simrel = null;\n }\n\n private _enqueue(fn: () => Promise<void>): Promise<void> {\n const next = this._queue.then(fn);\n this._queue = next.catch((err) => {\n if (import.meta.env?.DEV) {\n console.error('[gengage:overlay] Queued operation failed:', err);\n }\n });\n return next;\n }\n}\n\n/**\n * Initialize all three widgets (chat, QNA, SimRel) in a single call.\n * Idempotent — safe to call multiple times from GTM; deduplicates by account + SKU key.\n *\n * @example\n * ```ts\n * import { initOverlayWidgets } from '@gengage/assistant-fe';\n *\n * const controller = await initOverlayWidgets({\n * accountId: 'mystore',\n * middlewareUrl: 'https://chat.gengage.ai',\n * sku: window.productSku,\n * pageContext: { pageType: 'pdp' },\n * chat: { variant: 'floating' },\n * qna: { mountTarget: '#qna-section' },\n * simrel: { mountTarget: '#similar-products' },\n * });\n * ```\n */\nexport async function initOverlayWidgets(options: OverlayWidgetsOptions): Promise<OverlayWidgetsController> {\n const key = buildOverlayKey(options);\n const registry = getOverlayRegistry();\n\n const existing = registry.instances[key];\n if (existing) return existing;\n\n const pending = registry.pending[key];\n if (pending) return pending;\n\n const runtime = new OverlayWidgetsRuntime(options, () => {\n const liveRegistry = getOverlayRegistry();\n delete liveRegistry.instances[key];\n delete liveRegistry.pending[key];\n });\n\n const runtimeInit = runtime\n .init()\n .then(() => {\n registry.instances[key] = runtime;\n delete registry.pending[key];\n return runtime;\n })\n .catch((err) => {\n delete registry.pending[key];\n throw err;\n });\n\n registry.pending[key] = runtimeInit;\n return runtimeInit;\n}\n\nexport function getOverlayWidgets(idempotencyKey: string): OverlayWidgetsController | null {\n const registry = getOverlayRegistry();\n return registry.instances[idempotencyKey] ?? null;\n}\n\nexport function destroyOverlayWidgets(idempotencyKey: string): void {\n const controller = getOverlayWidgets(idempotencyKey);\n controller?.destroy();\n}\n\nexport function buildOverlayIdempotencyKey(accountId: string): string {\n return `${DEFAULT_OVERLAY_KEY_PREFIX}${accountId}`;\n}\n","import { initOverlayWidgets } from './overlay.js';\nimport type { OverlayWidgetsController, OverlayWidgetsOptions } from './overlay.js';\nimport type { PageContext } from './types.js';\n\nexport const DEFAULT_NATIVE_TRACKED_EVENTS = [\n 'gengage:chat:open',\n 'gengage:chat:close',\n 'gengage:chat:ready',\n 'gengage:chat:add-to-cart',\n 'gengage:qna:action',\n 'gengage:qna:open-chat',\n 'gengage:similar:product-click',\n 'gengage:similar:add-to-cart',\n 'gengage:global:error',\n 'gengage:context:update',\n] as const;\n\nexport type NativeTrackedEvent = (typeof DEFAULT_NATIVE_TRACKED_EVENTS)[number];\nexport type NativeInboundMessage = 'openChat' | 'closeChat' | 'updateContext' | 'updateSku' | 'setSession' | 'destroy';\n\nexport type NativeBridgeEnvironment = 'ios' | 'android' | 'react-native' | 'browser';\n\nexport interface NativeSessionPayload {\n sessionId?: string;\n userId?: string;\n}\n\nexport interface NativeBridgeMessage {\n type: string;\n payload?: unknown;\n}\n\nexport interface NativeWebViewBridgeOptions {\n iosHandlerName?: string;\n androidInterfaceName?: string;\n reactNativeInterfaceName?: string;\n trackedEvents?: NativeTrackedEvent[] | string[];\n /** Log unhandled inbound message types to console in addition to forwarding to postMessage. */\n logUnhandled?: boolean;\n /** Injected for tests; defaults to global window. */\n win?: Window;\n}\n\nexport interface NativeWebViewBridge {\n readonly env: NativeBridgeEnvironment;\n sendToNative(type: string, payload?: unknown): void;\n receive(message: NativeBridgeMessage | string): void;\n setController(controller: OverlayWidgetsController | null): void;\n destroy(): void;\n}\n\nexport interface NativeOverlayInitOptions extends OverlayWidgetsOptions {\n nativeBridge?: Omit<NativeWebViewBridgeOptions, 'win'>;\n emitReadyEvent?: boolean;\n}\n\nexport interface NativeOverlayInitResult {\n controller: OverlayWidgetsController;\n bridge: NativeWebViewBridge;\n destroy(): void;\n}\n\nconst MAX_QUEUED_NATIVE_COMMANDS = 32;\nconst DEFAULT_NATIVE_QNA_MOUNT = '#gengage-qna';\nconst DEFAULT_NATIVE_SIMREL_MOUNT = '#gengage-simrel';\n\ninterface NativeWindow extends Window {\n webkit?: {\n messageHandlers?: Record<string, { postMessage?: (message: unknown) => void }>;\n };\n GengageNative?: {\n postMessage?: (message: string) => void;\n };\n ReactNativeWebView?: {\n postMessage?: (message: string) => void;\n };\n gengageNative?: NativeWebViewBridge;\n}\n\nfunction toNativeWindow(win: Window): NativeWindow {\n return win as NativeWindow;\n}\n\nfunction parseNativeBridgeMessage(raw: NativeBridgeMessage | string): NativeBridgeMessage | null {\n let candidate: unknown = raw;\n\n if (typeof raw === 'string') {\n const trimmed = raw.trim();\n if (trimmed.length === 0) return null;\n\n // Allow plain command strings such as \"openChat\" from native evaluateJavaScript calls.\n if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) {\n return { type: trimmed };\n }\n\n try {\n candidate = JSON.parse(trimmed);\n } catch {\n return null;\n }\n }\n\n if (!candidate || typeof candidate !== 'object') return null;\n const obj = candidate as Record<string, unknown>;\n\n const typeCandidate = [obj['type'], obj['command'], obj['action'], obj['event']].find(\n (value): value is string => typeof value === 'string' && value.length > 0,\n );\n if (!typeCandidate) return null;\n\n let payload = obj['payload'];\n if (payload === undefined && 'data' in obj) payload = obj['data'];\n\n // Common native shorthand:\n // { type: \"setSession\", sessionId: \"...\", userId: \"...\" }\n if (typeCandidate === 'setSession' && payload === undefined) {\n const sessionPayload: NativeSessionPayload = {};\n if (typeof obj['sessionId'] === 'string') sessionPayload.sessionId = obj['sessionId'];\n if (typeof obj['userId'] === 'string') sessionPayload.userId = obj['userId'];\n if (sessionPayload.sessionId !== undefined || sessionPayload.userId !== undefined) {\n payload = sessionPayload;\n }\n }\n\n return payload === undefined ? { type: typeCandidate } : { type: typeCandidate, payload };\n}\n\nfunction parseUpdateSkuPayload(payload: unknown): { sku: string; pageType?: PageContext['pageType'] } | null {\n if (typeof payload === 'string' && payload.length > 0) {\n return { sku: payload };\n }\n if (payload && typeof payload === 'object' && 'sku' in payload) {\n const sku = (payload as { sku?: unknown }).sku;\n if (typeof sku === 'string' && sku.length > 0) {\n const pageType = (payload as { pageType?: PageContext['pageType'] }).pageType;\n return pageType !== undefined ? { sku, pageType } : { sku };\n }\n }\n return null;\n}\n\nfunction hasMountTarget(win: Window, target: HTMLElement | string): boolean {\n if (target instanceof HTMLElement) return true;\n if (typeof target !== 'string') return false;\n return win.document.querySelector(target) !== null;\n}\n\nfunction ensureMountTarget(\n win: Window,\n preferredTarget: HTMLElement | string,\n fallbackId: string,\n): HTMLElement | string {\n if (preferredTarget instanceof HTMLElement) return preferredTarget;\n if (hasMountTarget(win, preferredTarget)) return preferredTarget;\n if (typeof preferredTarget !== 'string') return preferredTarget;\n\n // If target is a simple #id selector, create that mount.\n if (preferredTarget.startsWith('#')) {\n const id = preferredTarget.slice(1);\n if (id.length > 0) {\n const existing = win.document.getElementById(id);\n if (existing) return existing;\n const mount = win.document.createElement('div');\n mount.id = id;\n win.document.body.appendChild(mount);\n return mount;\n }\n }\n\n const fallback = win.document.getElementById(fallbackId);\n if (fallback) return fallback;\n const mount = win.document.createElement('div');\n mount.id = fallbackId;\n win.document.body.appendChild(mount);\n return mount;\n}\n\nfunction getIosPostMessage(win: Window, handlerName: string): ((message: unknown) => void) | null {\n const handler = toNativeWindow(win).webkit?.messageHandlers?.[handlerName];\n if (handler && typeof handler.postMessage === 'function') {\n return handler.postMessage.bind(handler);\n }\n return null;\n}\n\nfunction getNamedBridge(win: Window, interfaceName: string): { postMessage: (message: string) => void } | null {\n const candidate = (win as Window & Record<string, unknown>)[interfaceName];\n if (candidate && typeof candidate === 'object') {\n const postMessage = (candidate as { postMessage?: unknown }).postMessage;\n if (typeof postMessage === 'function') {\n return candidate as { postMessage: (message: string) => void };\n }\n }\n return null;\n}\n\nexport function detectNativeEnvironment(\n options: Pick<\n NativeWebViewBridgeOptions,\n 'iosHandlerName' | 'androidInterfaceName' | 'reactNativeInterfaceName' | 'win'\n > = {},\n): NativeBridgeEnvironment {\n const win = options.win ?? window;\n const iosHandlerName = options.iosHandlerName ?? 'gengage';\n const androidInterfaceName = options.androidInterfaceName ?? 'GengageNative';\n const reactNativeInterfaceName = options.reactNativeInterfaceName ?? 'ReactNativeWebView';\n\n if (getIosPostMessage(win, iosHandlerName)) return 'ios';\n if (getNamedBridge(win, androidInterfaceName)) return 'android';\n if (getNamedBridge(win, reactNativeInterfaceName)) return 'react-native';\n return 'browser';\n}\n\n/**\n * Applies native-provided session identity so widgets can share correlation IDs\n * with the host app. Safe to call before or after widget initialization.\n */\nexport function applyNativeSession(\n payload: NativeSessionPayload,\n options: Pick<NativeWebViewBridgeOptions, 'win'> = {},\n): void {\n const win = options.win ?? window;\n\n if (payload.sessionId !== undefined) {\n win.__gengageSessionId = payload.sessionId;\n if (!win.gengage) win.gengage = {};\n win.gengage.sessionId = payload.sessionId;\n try {\n win.sessionStorage.setItem('gengage_session_id', payload.sessionId);\n } catch {\n // sessionStorage can be unavailable in restricted WebView modes.\n }\n }\n\n if (payload.userId !== undefined) {\n if (!win.gengage) win.gengage = {};\n const bag = win.gengage as unknown as Record<string, unknown>;\n const session = (bag['session'] as Record<string, unknown> | undefined) ?? {};\n session['userId'] = payload.userId;\n bag['session'] = session;\n }\n}\n\n/**\n * Installs a native WebView bridge compatible with:\n * - iOS WKWebView (`webkit.messageHandlers`)\n * - Android JavascriptInterface (`window.GengageNative`)\n * - React Native WebView (`window.ReactNativeWebView`)\n * and exposes it on `window.gengageNative`.\n */\nexport function createNativeWebViewBridge(options: NativeWebViewBridgeOptions = {}): NativeWebViewBridge {\n const win = options.win ?? window;\n const nativeWin = toNativeWindow(win);\n if (nativeWin.gengageNative) return nativeWin.gengageNative;\n\n const iosHandlerName = options.iosHandlerName ?? 'gengage';\n const androidInterfaceName = options.androidInterfaceName ?? 'GengageNative';\n const reactNativeInterfaceName = options.reactNativeInterfaceName ?? 'ReactNativeWebView';\n const trackedEvents = options.trackedEvents ?? [...DEFAULT_NATIVE_TRACKED_EVENTS];\n const env = detectNativeEnvironment({ win, iosHandlerName, androidInterfaceName, reactNativeInterfaceName });\n\n let controller: OverlayWidgetsController | null = win.gengage?.overlay ?? null;\n const queuedCommands: NativeBridgeMessage[] = [];\n\n const sendToNative = (type: string, payload?: unknown): void => {\n const message: NativeBridgeMessage = payload === undefined ? { type } : { type, payload };\n\n if (env === 'ios') {\n const postMessage = getIosPostMessage(win, iosHandlerName);\n postMessage?.(message);\n return;\n }\n\n if (env === 'android') {\n const androidBridge = getNamedBridge(win, androidInterfaceName);\n androidBridge?.postMessage(JSON.stringify(message));\n return;\n }\n\n if (env === 'react-native') {\n const reactNativeBridge = getNamedBridge(win, reactNativeInterfaceName);\n reactNativeBridge?.postMessage(JSON.stringify(message));\n return;\n }\n\n // Browser fallback: no-op. Useful when running the same integration\n // outside a native WebView (desktop QA, local dev, docs previews).\n return;\n };\n\n const bridgeMessageHandler: EventListener = (event) => {\n const detail = (event as CustomEvent<{ namespace: string; type: string; payload?: unknown }>).detail;\n if (!detail || typeof detail.namespace !== 'string' || typeof detail.type !== 'string') return;\n sendToNative('bridge_message', {\n namespace: detail.namespace,\n type: detail.type,\n payload: detail.payload,\n });\n };\n\n win.addEventListener('gengage:bridge:message', bridgeMessageHandler);\n\n const trackedEventHandlers: Array<{ event: string; handler: EventListener }> = trackedEvents.map((eventName) => {\n const handler: EventListener = (event) => {\n const detail = (event as CustomEvent<unknown>).detail;\n sendToNative('widget_event', {\n event: eventName,\n detail,\n });\n };\n win.addEventListener(eventName, handler);\n return { event: eventName, handler };\n });\n\n const queueCommand = (command: NativeBridgeMessage): void => {\n if (queuedCommands.length >= MAX_QUEUED_NATIVE_COMMANDS) {\n queuedCommands.shift();\n }\n queuedCommands.push(command);\n };\n\n const flushQueuedCommands = (): void => {\n if (!controller || queuedCommands.length === 0) return;\n const pending = queuedCommands.splice(0, queuedCommands.length);\n for (const command of pending) {\n receive(command);\n }\n };\n\n const receive = (message: NativeBridgeMessage | string): void => {\n const incoming = parseNativeBridgeMessage(message);\n if (!incoming || typeof incoming.type !== 'string') {\n console.warn('[gengage:native-bridge] Invalid message:', message);\n return;\n }\n\n const type = incoming.type as NativeInboundMessage | string;\n const payload = incoming.payload;\n\n switch (type) {\n case 'openChat': {\n if (controller) {\n controller.openChat(\n payload && typeof payload === 'object'\n ? (payload as { state?: 'half' | 'full' })\n : payload === 'half' || payload === 'full'\n ? { state: payload }\n : undefined,\n );\n } else {\n queueCommand(incoming);\n }\n return;\n }\n\n case 'closeChat': {\n if (controller) {\n controller.closeChat();\n } else {\n queueCommand(incoming);\n }\n return;\n }\n\n case 'updateContext': {\n if (controller && payload && typeof payload === 'object') {\n void controller.updateContext(payload as Partial<PageContext>);\n } else if (!controller) {\n queueCommand(incoming);\n } else {\n console.warn('[gengage:native-bridge] updateContext: missing payload');\n }\n return;\n }\n\n case 'updateSku': {\n const parsed = parseUpdateSkuPayload(payload);\n if (controller && parsed) {\n void controller.updateSku(parsed.sku, parsed.pageType);\n return;\n }\n if (!controller) {\n queueCommand(incoming);\n } else {\n console.warn('[gengage:native-bridge] updateSku: missing sku');\n }\n return;\n }\n\n case 'setSession': {\n if (payload && typeof payload === 'object') {\n applyNativeSession(payload as NativeSessionPayload, { win });\n }\n return;\n }\n\n case 'destroy': {\n controller?.destroy();\n return;\n }\n\n default: {\n win.postMessage({ gengage: 'native', type, payload }, win.location.origin);\n if (options.logUnhandled) {\n console.warn('[gengage:native-bridge] Unhandled inbound type forwarded:', type);\n }\n }\n }\n };\n\n const bridge: NativeWebViewBridge = {\n env,\n sendToNative,\n receive,\n setController(nextController) {\n controller = nextController;\n flushQueuedCommands();\n },\n destroy() {\n win.removeEventListener('gengage:bridge:message', bridgeMessageHandler);\n for (const entry of trackedEventHandlers) {\n win.removeEventListener(entry.event, entry.handler);\n }\n queuedCommands.splice(0, queuedCommands.length);\n if (toNativeWindow(win).gengageNative === bridge) {\n delete toNativeWindow(win).gengageNative;\n }\n },\n };\n\n nativeWin.gengageNative = bridge;\n return bridge;\n}\n\n/**\n * Convenience helper for mobile WebViews:\n * 1) installs native bridge\n * 2) initializes overlay widgets\n * 3) sends a `ready` message to native\n */\nexport async function initNativeOverlayWidgets(options: NativeOverlayInitOptions): Promise<NativeOverlayInitResult> {\n const { nativeBridge, emitReadyEvent = true, ...overlayOptions } = options;\n const bridge = createNativeWebViewBridge(nativeBridge);\n const resolvedOptions: OverlayWidgetsOptions = { ...overlayOptions };\n\n // Mobile-app-friendly defaults:\n // 1) translate commerce callbacks to native bridge messages by default\n // 2) avoid noisy missing-mount warnings unless PDP widgets are explicitly requested\n if (!resolvedOptions.onAddToCart) {\n resolvedOptions.onAddToCart = (params) => {\n bridge.sendToNative('addToCart', {\n sku: params.sku,\n quantity: params.quantity,\n cartCode: params.cartCode,\n });\n };\n }\n\n if (!resolvedOptions.onProductNavigate) {\n resolvedOptions.onProductNavigate = (url, sku, sessionId) => {\n bridge.sendToNative('productNavigate', {\n url,\n sku,\n sessionId,\n });\n };\n }\n\n const qnaRequested = resolvedOptions.qna?.enabled === true || resolvedOptions.qna?.mountTarget !== undefined;\n if (resolvedOptions.qna?.enabled !== false) {\n if (qnaRequested) {\n const mountTarget = ensureMountTarget(\n window,\n resolvedOptions.qna?.mountTarget ?? DEFAULT_NATIVE_QNA_MOUNT,\n 'gengage-qna',\n );\n resolvedOptions.qna = { ...resolvedOptions.qna, enabled: true, mountTarget };\n } else if (!hasMountTarget(window, DEFAULT_NATIVE_QNA_MOUNT)) {\n resolvedOptions.qna = { enabled: false };\n }\n }\n\n const simrelRequested = resolvedOptions.simrel?.enabled === true || resolvedOptions.simrel?.mountTarget !== undefined;\n if (resolvedOptions.simrel?.enabled !== false) {\n if (simrelRequested) {\n const mountTarget = ensureMountTarget(\n window,\n resolvedOptions.simrel?.mountTarget ?? DEFAULT_NATIVE_SIMREL_MOUNT,\n 'gengage-simrel',\n );\n resolvedOptions.simrel = { ...resolvedOptions.simrel, enabled: true, mountTarget };\n } else if (!hasMountTarget(window, DEFAULT_NATIVE_SIMREL_MOUNT)) {\n resolvedOptions.simrel = { enabled: false };\n }\n }\n\n const controller = await initOverlayWidgets(resolvedOptions);\n bridge.setController(controller);\n\n if (emitReadyEvent) {\n bridge.sendToNative('ready', {\n sessionId: controller.session.sessionId,\n widgets: {\n chat: controller.chat !== null,\n qna: controller.qna !== null,\n simrel: controller.simrel !== null,\n },\n });\n }\n\n return {\n controller,\n bridge,\n destroy() {\n controller.destroy();\n bridge.destroy();\n },\n };\n}\n"],"names":["WidgetToggleSchema","z.object","z.boolean","MountSelectorsSchema","z.string","TransportSchema","AnalyticsAuthModeSchema","z.enum","AnalyticsAuthSchema","AnalyticsSchema","z.number","DEFAULT_IDEMPOTENCY_KEY","GTMSchema","UnknownActionPolicySchema","ActionHandlingSchema","AccountRuntimeConfigSchema","z.literal","parseAccountRuntimeConfig","input","debugLog","result","safeParseAccountRuntimeConfig","createDefaultAccountRuntimeConfig","params","DEFAULT_OVERLAY_KEY_PREFIX","DEFAULT_QNA_MOUNT","DEFAULT_SIMREL_MOUNT","getOverlayRegistry","win","buildInitialPageContext","options","base","incoming","mergePageContext","current","patch","next","resolveMountTarget","target","buildOverlayKey","OverlayWidgetsRuntime","onDestroy","resolveSession","wireQNAToChat","sku","pageType","middlewareUrl","config","GengageChat","qnaTarget","mountTarget","qna","GengageQNA","qnaConfig","simRelTarget","simrel","GengageSimRel","simRelConfig","url","productSku","sessionId","isSafeUrl","fn","err","initOverlayWidgets","key","registry","existing","pending","runtime","liveRegistry","runtimeInit","getOverlayWidgets","idempotencyKey","destroyOverlayWidgets","buildOverlayIdempotencyKey","accountId","DEFAULT_NATIVE_TRACKED_EVENTS","MAX_QUEUED_NATIVE_COMMANDS","DEFAULT_NATIVE_QNA_MOUNT","DEFAULT_NATIVE_SIMREL_MOUNT","parseNativeBridgeMessage","raw","candidate","trimmed","obj","typeCandidate","value","payload","sessionPayload","parseUpdateSkuPayload","hasMountTarget","ensureMountTarget","preferredTarget","fallbackId","id","mount","fallback","getIosPostMessage","handlerName","handler","getNamedBridge","interfaceName","detectNativeEnvironment","iosHandlerName","androidInterfaceName","reactNativeInterfaceName","applyNativeSession","bag","session","createNativeWebViewBridge","nativeWin","trackedEvents","env","controller","queuedCommands","sendToNative","type","message","bridgeMessageHandler","event","detail","trackedEventHandlers","eventName","queueCommand","command","flushQueuedCommands","receive","parsed","bridge","nextController","entry","initNativeOverlayWidgets","nativeBridge","emitReadyEvent","overlayOptions","resolvedOptions","qnaRequested","simrelRequested"],"mappings":"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"}
@@ -1,14 +1,14 @@
1
- import { G as F } from "./index-RmQRBt6w.js";
1
+ import { G as F } from "./index-EEUjXgSt.js";
2
2
  import { GengageQNA as Q } from "./qna.js";
3
3
  import { GengageSimRel as H } from "./simrel.js";
4
- import { o as p, s as h, Y as j, _ as U, D as M, d as y, y as S, Z as K, $ as V, E as $ } from "./schemas-BAEbjFPE.js";
5
- const C = p({
4
+ import { o as p, s as h, Y as j, _ as x, D as M, d as y, y as S, Z as K, $ as V, E as $ } from "./schemas-D1Kd4wn8.js";
5
+ const T = p({
6
6
  enabled: y().default(!0)
7
7
  }), G = p({
8
8
  chat: h().optional(),
9
9
  qna: h().optional(),
10
10
  simrel: h().optional()
11
- }), Y = p({}), J = U(["none", "x-api-key-header", "bearer-header", "body-api-key"]), X = p({
11
+ }), Y = p({}), J = x(["none", "x-api-key-header", "bearer-header", "body-api-key"]), X = p({
12
12
  mode: J.default("none"),
13
13
  key: h().optional(),
14
14
  headerName: h().optional(),
@@ -25,7 +25,7 @@ const C = p({
25
25
  }), R = "__gengageWidgetsInit", z = p({
26
26
  idempotencyKey: h().default(R),
27
27
  requireDomReady: y().default(!0)
28
- }), ee = U(["log-and-ignore", "throw", "delegate"]), te = p({
28
+ }), ee = x(["log-and-ignore", "throw", "delegate"]), te = p({
29
29
  unknownActionPolicy: ee.default("log-and-ignore"),
30
30
  allowScriptCall: y().default(!1)
31
31
  }), P = p({
@@ -34,9 +34,9 @@ const C = p({
34
34
  middlewareUrl: h({ error: 'middlewareUrl must be a valid URL (e.g. "https://your-backend.example.com")' }).url({ error: 'middlewareUrl must be a valid URL (e.g. "https://your-backend.example.com")' }),
35
35
  locale: h().optional(),
36
36
  widgets: p({
37
- chat: C.default({ enabled: !0 }),
38
- qna: C.default({ enabled: !0 }),
39
- simrel: C.default({ enabled: !0 })
37
+ chat: T.default({ enabled: !0 }),
38
+ qna: T.default({ enabled: !0 }),
39
+ simrel: T.default({ enabled: !0 })
40
40
  }),
41
41
  mounts: G.default({}),
42
42
  transport: Y.default({}),
@@ -67,7 +67,7 @@ function ne(n) {
67
67
  function be(n) {
68
68
  return P.safeParse(n);
69
69
  }
70
- function Te(n) {
70
+ function Ce(n) {
71
71
  return ne({
72
72
  version: "1",
73
73
  accountId: n.accountId,
@@ -153,7 +153,7 @@ class re {
153
153
  pageContext: this._pageContext,
154
154
  variant: this.options.chat?.variant ?? "floating"
155
155
  };
156
- this.options.theme !== void 0 && (t.theme = this.options.theme), this.options.locale !== void 0 && (t.locale = this.options.locale), this.options.pricing !== void 0 && (t.pricing = this.options.pricing), this.options.chat?.mountTarget !== void 0 && (t.mountTarget = this.options.chat.mountTarget), this.options.chat?.launcherSvg !== void 0 && (t.launcherSvg = this.options.chat.launcherSvg), this.options.chat?.headerTitle !== void 0 && (t.headerTitle = this.options.chat.headerTitle), this.options.chat?.headerAvatarUrl !== void 0 && (t.headerAvatarUrl = this.options.chat.headerAvatarUrl), this.options.chat?.headerBadge !== void 0 && (t.headerBadge = this.options.chat.headerBadge), this.options.chat?.headerCartUrl !== void 0 && (t.headerCartUrl = this.options.chat.headerCartUrl), this.options.chat?.headerFavoritesToggle !== void 0 && (t.headerFavoritesToggle = this.options.chat.headerFavoritesToggle), this.options.chat?.hideMobileLauncher !== void 0 && (t.hideMobileLauncher = this.options.chat.hideMobileLauncher), this.options.chat?.mobileBreakpoint !== void 0 && (t.mobileBreakpoint = this.options.chat.mobileBreakpoint), this.options.chat?.mobileInitialState !== void 0 && (t.mobileInitialState = this.options.chat.mobileInitialState), this.options.chat?.i18n !== void 0 && (t.i18n = this.options.chat.i18n), this.options.chat?.actionHandling !== void 0 && (t.actionHandling = this.options.chat.actionHandling), this.options.onScriptCall !== void 0 && (t.onScriptCall = this.options.onScriptCall), this._chat = new F(), await this._chat.init(t);
156
+ this.options.theme !== void 0 && (t.theme = this.options.theme), this.options.locale !== void 0 && (t.locale = this.options.locale), this.options.pricing !== void 0 && (t.pricing = this.options.pricing), this.options.chat?.mountTarget !== void 0 && (t.mountTarget = this.options.chat.mountTarget), this.options.chat?.launcherImageUrl !== void 0 ? t.launcherImageUrl = this.options.chat.launcherImageUrl : this.options.chat?.launcherSvg !== void 0 && (t.launcherSvg = this.options.chat.launcherSvg), this.options.chat?.headerTitle !== void 0 && (t.headerTitle = this.options.chat.headerTitle), this.options.chat?.headerAvatarUrl !== void 0 && (t.headerAvatarUrl = this.options.chat.headerAvatarUrl), this.options.chat?.headerBadge !== void 0 && (t.headerBadge = this.options.chat.headerBadge), this.options.chat?.headerCartUrl !== void 0 && (t.headerCartUrl = this.options.chat.headerCartUrl), this.options.chat?.headerFavoritesToggle !== void 0 && (t.headerFavoritesToggle = this.options.chat.headerFavoritesToggle), this.options.chat?.hideMobileLauncher !== void 0 && (t.hideMobileLauncher = this.options.chat.hideMobileLauncher), this.options.chat?.mobileBreakpoint !== void 0 && (t.mobileBreakpoint = this.options.chat.mobileBreakpoint), this.options.chat?.mobileInitialState !== void 0 && (t.mobileInitialState = this.options.chat.mobileInitialState), this.options.chat?.i18n !== void 0 && (t.i18n = this.options.chat.i18n), this.options.chat?.actionHandling !== void 0 && (t.actionHandling = this.options.chat.actionHandling), this.options.chat?.renderer !== void 0 && (t.renderer = this.options.chat.renderer), this.options.onScriptCall !== void 0 && (t.onScriptCall = this.options.onScriptCall), this._chat = new F(), await this._chat.init(t);
157
157
  }
158
158
  async _syncPdpWidgets() {
159
159
  if (this._destroyed) return;
@@ -179,7 +179,7 @@ class re {
179
179
  },
180
180
  mountTarget: i
181
181
  };
182
- this.options.theme !== void 0 && (o.theme = this.options.theme), this.options.qna?.ctaText !== void 0 && (o.ctaText = this.options.qna.ctaText), this.options.qna?.inputPlaceholder !== void 0 && (o.inputPlaceholder = this.options.qna.inputPlaceholder), await u.init(o), this._qna = u;
182
+ this.options.theme !== void 0 && (o.theme = this.options.theme), 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), await u.init(o), this._qna = u;
183
183
  }
184
184
  else
185
185
  this._qna?.destroy(), this._qna = null, this._warnedQnaMountMissing || (console.warn(`[gengage] QNA mount target not found: ${s}`), this._warnedQnaMountMissing = !0);
@@ -198,8 +198,8 @@ class re {
198
198
  sku: e,
199
199
  mountTarget: i
200
200
  };
201
- 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.onAddToCart !== void 0 && (o.onAddToCart = this.options.onAddToCart), this.options.onProductNavigate !== void 0 ? o.onProductNavigate = this.options.onProductNavigate : o.onProductNavigate = (r, c, m) => {
202
- $(r) && (this._chat?.saveSession(m ?? this.session.sessionId, c), window.location.href = r);
201
+ 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?.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 = (r, l, m) => {
202
+ $(r) && (this._chat?.saveSession(m ?? this.session.sessionId, l), window.location.href = r);
203
203
  }, await u.init(o), this._simrel = u;
204
204
  }
205
205
  else
@@ -229,16 +229,16 @@ async function de(n) {
229
229
  });
230
230
  return t.pending[e] = u, u;
231
231
  }
232
- function ce(n) {
232
+ function le(n) {
233
233
  return I().instances[n] ?? null;
234
234
  }
235
- function Ce(n) {
236
- ce(n)?.destroy();
235
+ function Te(n) {
236
+ le(n)?.destroy();
237
237
  }
238
238
  function Ie(n) {
239
239
  return `${W}${n}`;
240
240
  }
241
- const le = [
241
+ const ce = [
242
242
  "gengage:chat:open",
243
243
  "gengage:chat:close",
244
244
  "gengage:chat:ready",
@@ -287,11 +287,11 @@ function he(n) {
287
287
  }
288
288
  return null;
289
289
  }
290
- function N(n, e) {
290
+ function q(n, e) {
291
291
  return e instanceof HTMLElement ? !0 : typeof e != "string" ? !1 : n.document.querySelector(e) !== null;
292
292
  }
293
- function x(n, e, t) {
294
- if (e instanceof HTMLElement || N(n, e) || typeof e != "string") return e;
293
+ function U(n, e, t) {
294
+ if (e instanceof HTMLElement || q(n, e) || typeof e != "string") return e;
295
295
  if (e.startsWith("#")) {
296
296
  const i = e.slice(1);
297
297
  if (i.length > 0) {
@@ -336,10 +336,10 @@ function pe(n, e = {}) {
336
336
  function me(n = {}) {
337
337
  const e = n.win ?? window, t = e;
338
338
  if (t.gengageNative) return t.gengageNative;
339
- const a = n.iosHandlerName ?? "gengage", s = n.androidInterfaceName ?? "GengageNative", i = n.reactNativeInterfaceName ?? "ReactNativeWebView", u = n.trackedEvents ?? [...le], o = fe({ win: e, iosHandlerName: a, androidInterfaceName: s, reactNativeInterfaceName: i });
339
+ const a = n.iosHandlerName ?? "gengage", s = n.androidInterfaceName ?? "GengageNative", i = n.reactNativeInterfaceName ?? "ReactNativeWebView", u = n.trackedEvents ?? [...ce], o = fe({ win: e, iosHandlerName: a, androidInterfaceName: s, reactNativeInterfaceName: i });
340
340
  let r = e.gengage?.overlay ?? null;
341
- const c = [], m = (l, d) => {
342
- const f = d === void 0 ? { type: l } : { type: l, payload: d };
341
+ const l = [], m = (c, d) => {
342
+ const f = d === void 0 ? { type: c } : { type: c, payload: d };
343
343
  if (o === "ios") {
344
344
  O(e, a)?.(f);
345
345
  return;
@@ -352,8 +352,8 @@ function me(n = {}) {
352
352
  w(e, i)?.postMessage(JSON.stringify(f));
353
353
  return;
354
354
  }
355
- }, v = (l) => {
356
- const d = l.detail;
355
+ }, v = (c) => {
356
+ const d = c.detail;
357
357
  !d || typeof d.namespace != "string" || typeof d.type != "string" || m("bridge_message", {
358
358
  namespace: d.namespace,
359
359
  type: d.type,
@@ -361,26 +361,26 @@ function me(n = {}) {
361
361
  });
362
362
  };
363
363
  e.addEventListener("gengage:bridge:message", v);
364
- const B = u.map((l) => {
364
+ const B = u.map((c) => {
365
365
  const d = (f) => {
366
366
  const g = f.detail;
367
367
  m("widget_event", {
368
- event: l,
368
+ event: c,
369
369
  detail: g
370
370
  });
371
371
  };
372
- return e.addEventListener(l, d), { event: l, handler: d };
373
- }), _ = (l) => {
374
- c.length >= ge && c.shift(), c.push(l);
372
+ return e.addEventListener(c, d), { event: c, handler: d };
373
+ }), _ = (c) => {
374
+ l.length >= ge && l.shift(), l.push(c);
375
375
  }, D = () => {
376
- if (!r || c.length === 0) return;
377
- const l = c.splice(0, c.length);
378
- for (const d of l)
379
- q(d);
380
- }, q = (l) => {
381
- const d = ue(l);
376
+ if (!r || l.length === 0) return;
377
+ const c = l.splice(0, l.length);
378
+ for (const d of c)
379
+ N(d);
380
+ }, N = (c) => {
381
+ const d = ue(c);
382
382
  if (!d || typeof d.type != "string") {
383
- console.warn("[gengage:native-bridge] Invalid message:", l);
383
+ console.warn("[gengage:native-bridge] Invalid message:", c);
384
384
  return;
385
385
  }
386
386
  const f = d.type, g = d.payload;
@@ -400,9 +400,9 @@ function me(n = {}) {
400
400
  return;
401
401
  }
402
402
  case "updateSku": {
403
- const T = he(g);
404
- if (r && T) {
405
- r.updateSku(T.sku, T.pageType);
403
+ const C = he(g);
404
+ if (r && C) {
405
+ r.updateSku(C.sku, C.pageType);
406
406
  return;
407
407
  }
408
408
  r ? console.warn("[gengage:native-bridge] updateSku: missing sku") : _(d);
@@ -422,30 +422,30 @@ function me(n = {}) {
422
422
  }, b = {
423
423
  env: o,
424
424
  sendToNative: m,
425
- receive: q,
426
- setController(l) {
427
- r = l, D();
425
+ receive: N,
426
+ setController(c) {
427
+ r = c, D();
428
428
  },
429
429
  destroy() {
430
430
  e.removeEventListener("gengage:bridge:message", v);
431
- for (const l of B)
432
- e.removeEventListener(l.event, l.handler);
433
- c.splice(0, c.length), e.gengageNative === b && delete e.gengageNative;
431
+ for (const c of B)
432
+ e.removeEventListener(c.event, c.handler);
433
+ l.splice(0, l.length), e.gengageNative === b && delete e.gengageNative;
434
434
  }
435
435
  };
436
436
  return t.gengageNative = b, b;
437
437
  }
438
- async function Ne(n) {
438
+ async function qe(n) {
439
439
  const { nativeBridge: e, emitReadyEvent: t = !0, ...a } = n, s = me(e), i = { ...a };
440
- i.onAddToCart || (i.onAddToCart = (c) => {
440
+ i.onAddToCart || (i.onAddToCart = (l) => {
441
441
  s.sendToNative("addToCart", {
442
- sku: c.sku,
443
- quantity: c.quantity,
444
- cartCode: c.cartCode
442
+ sku: l.sku,
443
+ quantity: l.quantity,
444
+ cartCode: l.cartCode
445
445
  });
446
- }), i.onProductNavigate || (i.onProductNavigate = (c, m, v) => {
446
+ }), i.onProductNavigate || (i.onProductNavigate = (l, m, v) => {
447
447
  s.sendToNative("productNavigate", {
448
- url: c,
448
+ url: l,
449
449
  sku: m,
450
450
  sessionId: v
451
451
  });
@@ -453,23 +453,23 @@ async function Ne(n) {
453
453
  const u = i.qna?.enabled === !0 || i.qna?.mountTarget !== void 0;
454
454
  if (i.qna?.enabled !== !1)
455
455
  if (u) {
456
- const c = x(
456
+ const l = U(
457
457
  window,
458
458
  i.qna?.mountTarget ?? A,
459
459
  "gengage-qna"
460
460
  );
461
- i.qna = { ...i.qna, enabled: !0, mountTarget: c };
462
- } else N(window, A) || (i.qna = { enabled: !1 });
461
+ i.qna = { ...i.qna, enabled: !0, mountTarget: l };
462
+ } else q(window, A) || (i.qna = { enabled: !1 });
463
463
  const o = i.simrel?.enabled === !0 || i.simrel?.mountTarget !== void 0;
464
464
  if (i.simrel?.enabled !== !1)
465
465
  if (o) {
466
- const c = x(
466
+ const l = U(
467
467
  window,
468
468
  i.simrel?.mountTarget ?? E,
469
469
  "gengage-simrel"
470
470
  );
471
- i.simrel = { ...i.simrel, enabled: !0, mountTarget: c };
472
- } else N(window, E) || (i.simrel = { enabled: !1 });
471
+ i.simrel = { ...i.simrel, enabled: !0, mountTarget: l };
472
+ } else q(window, E) || (i.simrel = { enabled: !1 });
473
473
  const r = await de(i);
474
474
  return s.setController(r), t && s.sendToNative("ready", {
475
475
  sessionId: r.session.sessionId,
@@ -488,19 +488,19 @@ async function Ne(n) {
488
488
  }
489
489
  export {
490
490
  P as A,
491
- le as D,
491
+ ce as D,
492
492
  ee as U,
493
493
  J as a,
494
494
  pe as b,
495
495
  Ie as c,
496
- Te as d,
496
+ Ce as d,
497
497
  me as e,
498
- Ce as f,
498
+ Te as f,
499
499
  fe as g,
500
- ce as h,
500
+ le as h,
501
501
  de as i,
502
- Ne as j,
502
+ qe as j,
503
503
  ne as p,
504
504
  be as s
505
505
  };
506
- //# sourceMappingURL=index-C6KDzSjm.js.map
506
+ //# sourceMappingURL=index-CpLM7vPC.js.map