@gengage/assistant-fe 0.3.14 → 0.3.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assistant-fe.css +1 -1
- package/dist/chat/components/ChatDrawer.d.ts +2 -0
- package/dist/chat/components/ChatDrawer.d.ts.map +1 -1
- package/dist/chat/index.d.ts +3 -0
- package/dist/chat/index.d.ts.map +1 -1
- package/dist/chat/panel-manager.d.ts +0 -5
- package/dist/chat/panel-manager.d.ts.map +1 -1
- package/dist/chat/types.d.ts +8 -0
- package/dist/chat/types.d.ts.map +1 -1
- package/dist/chat-CRGCgvrz.cjs +94 -0
- package/dist/chat-CRGCgvrz.cjs.map +1 -0
- package/dist/{chat-D7c9emMm.js → chat-D60Ci1vQ.js} +681 -547
- package/dist/chat-D60Ci1vQ.js.map +1 -0
- package/dist/chat.cjs +1 -1
- package/dist/chat.iife.js +86 -7
- package/dist/chat.iife.js.map +1 -1
- package/dist/chat.js +2 -2
- package/dist/common/index.d.ts +2 -0
- package/dist/common/index.d.ts.map +1 -1
- package/dist/common/overlay.d.ts +10 -0
- package/dist/common/overlay.d.ts.map +1 -1
- package/dist/common/pill-launcher.d.ts +52 -0
- package/dist/common/pill-launcher.d.ts.map +1 -0
- package/dist/common/ui-theme.d.ts.map +1 -1
- package/dist/{common-Dtx5Bgu_.js → common-CjkWpalm.js} +3 -3
- package/dist/{common-Dtx5Bgu_.js.map → common-CjkWpalm.js.map} +1 -1
- package/dist/{common-C0QxGDX5.cjs → common-DX6rwrsr.cjs} +2 -2
- package/dist/{common-C0QxGDX5.cjs.map → common-DX6rwrsr.cjs.map} +1 -1
- package/dist/common.cjs +1 -1
- package/dist/common.js +7 -7
- package/dist/{connection-warning-COW6YXlM.js → connection-warning-BF8r3_5W.js} +2 -2
- package/dist/{connection-warning-COW6YXlM.js.map → connection-warning-BF8r3_5W.js.map} +1 -1
- package/dist/{connection-warning-fwHynNgu.cjs → connection-warning-Dlirb_Pi.cjs} +2 -2
- package/dist/{connection-warning-fwHynNgu.cjs.map → connection-warning-Dlirb_Pi.cjs.map} +1 -1
- package/dist/{ga-datalayer-D3upAPs9.cjs → ga-datalayer-DSVuycfp.cjs} +2 -2
- package/dist/ga-datalayer-DSVuycfp.cjs.map +1 -0
- package/dist/{ga-datalayer-DdTUkXC3.js → ga-datalayer-DygUbUWr.js} +2 -2
- package/dist/ga-datalayer-DygUbUWr.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -10
- package/dist/native-webview-Bm-pIU6O.cjs +2 -0
- package/dist/native-webview-Bm-pIU6O.cjs.map +1 -0
- package/dist/{native-webview-CRFBySOa.js → native-webview-qAXppESm.js} +11 -9
- package/dist/native-webview-qAXppESm.js.map +1 -0
- package/dist/native.cjs +1 -1
- package/dist/native.iife.js +86 -7
- package/dist/native.iife.js.map +1 -1
- package/dist/native.js +1 -1
- package/dist/qna/components/renderUISpec.d.ts.map +1 -1
- package/dist/qna/index.d.ts +7 -0
- package/dist/qna/index.d.ts.map +1 -1
- package/dist/qna/types.d.ts +12 -0
- package/dist/qna/types.d.ts.map +1 -1
- package/dist/{qna-c7t5suwI.js → qna-J0v3olA2.js} +52 -24
- package/dist/qna-J0v3olA2.js.map +1 -0
- package/dist/qna-T6ACPKRB.cjs +2 -0
- package/dist/qna-T6ACPKRB.cjs.map +1 -0
- package/dist/qna.cjs +1 -1
- package/dist/qna.css +1 -1
- package/dist/qna.iife.js +3 -3
- package/dist/qna.iife.js.map +1 -1
- package/dist/qna.js +1 -1
- package/dist/{schemas-C-giAkv4.cjs → schemas-B3zzmCPF.cjs} +2 -2
- package/dist/{schemas-C-giAkv4.cjs.map → schemas-B3zzmCPF.cjs.map} +1 -1
- package/dist/{schemas-DUid6HBM.js → schemas-DRZ9l0Z4.js} +2 -2
- package/dist/{schemas-DUid6HBM.js.map → schemas-DRZ9l0Z4.js.map} +1 -1
- package/dist/{simbut-Bk7shcTX.js → simbut-DG48EcoU.js} +2 -2
- package/dist/{simbut-Bk7shcTX.js.map → simbut-DG48EcoU.js.map} +1 -1
- package/dist/{simbut-C8KPNxO1.cjs → simbut-DHZFpGIA.cjs} +2 -2
- package/dist/{simbut-C8KPNxO1.cjs.map → simbut-DHZFpGIA.cjs.map} +1 -1
- package/dist/simbut.cjs +1 -1
- package/dist/simbut.iife.js +1 -1
- package/dist/simbut.iife.js.map +1 -1
- package/dist/simbut.js +1 -1
- package/dist/{simrel-CT26hFlJ.cjs → simrel-B3wJOMlY.cjs} +2 -2
- package/dist/{simrel-CT26hFlJ.cjs.map → simrel-B3wJOMlY.cjs.map} +1 -1
- package/dist/{simrel-1J9Ph5k5.js → simrel-CGT83sSF.js} +4 -4
- package/dist/{simrel-1J9Ph5k5.js.map → simrel-CGT83sSF.js.map} +1 -1
- package/dist/simrel.cjs +1 -1
- package/dist/simrel.iife.js +1 -1
- package/dist/simrel.iife.js.map +1 -1
- package/dist/simrel.js +1 -1
- package/package.json +2 -2
- package/dist/chat-CET9ibDo.cjs +0 -15
- package/dist/chat-CET9ibDo.cjs.map +0 -1
- package/dist/chat-D7c9emMm.js.map +0 -1
- package/dist/ga-datalayer-D3upAPs9.cjs.map +0 -1
- package/dist/ga-datalayer-DdTUkXC3.js.map +0 -1
- package/dist/native-webview-BlmrmhV_.cjs +0 -2
- package/dist/native-webview-BlmrmhV_.cjs.map +0 -1
- package/dist/native-webview-CRFBySOa.js.map +0 -1
- package/dist/qna-DvgpFom7.cjs +0 -2
- package/dist/qna-DvgpFom7.cjs.map +0 -1
- package/dist/qna-c7t5suwI.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"native-webview-BlmrmhV_.cjs","names":[],"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 { GengageSimBut } from '../simbut/index.js';\nimport type { SimButWidgetConfig } from '../simbut/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';\nconst DEFAULT_SIMBUT_MOUNT = '#gengage-simbut';\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 /** Opens merchant favorites page (passed to chat `onFavoritesClick`). */\n onFavoritesClick?: () => void;\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 /** When true, allow full product details in the assistant side panel; default is chat summary only. */\n productDetailsExtended?: boolean;\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 OverlaySimButOptions {\n enabled?: boolean;\n mountTarget?: HTMLElement | string;\n /** `findSimilar` yüküne eklenecek ürün görseli URL’si. */\n imageUrl?: string;\n i18n?: SimButWidgetConfig['i18n'];\n /** Chat kapalıyken veya özel davranış için; tanımlıysa tıklamada `chat` yerine bu çağrılır. */\n onFindSimilar?: SimButWidgetConfig['onFindSimilar'];\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 simbut?: OverlaySimButOptions;\n onAddToCart?: (params: import('./types.js').AddToCartParams) => void;\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 readonly simbut: GengageSimBut | 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 _simbut: GengageSimBut | 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 private _warnedSimButMountMissing = false;\n private _warnedSimButNoChat = 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 simbut(): GengageSimBut | null {\n return this._simbut;\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 this._simbut?.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 this._simbut?.destroy();\n\n this._chat = null;\n this._qna = null;\n this._simrel = null;\n this._simbut = 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?.onFavoritesClick !== undefined) {\n config.onFavoritesClick = this.options.chat.onFavoritesClick;\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.chat?.productDetailsExtended !== undefined) {\n config.productDetailsExtended = this.options.chat.productDetailsExtended;\n }\n if (this.options.onScriptCall !== undefined) {\n config.onScriptCall = this.options.onScriptCall;\n }\n if (this.options.onAddToCart !== undefined) {\n config.onAddToCart = this.options.onAddToCart;\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 // Hide rather than destroy — the mount target stays populated so the\n // user sees a graceful empty state instead of a blank/missing widget.\n // Widgets are re-shown and updated when navigation returns to a PDP page.\n this._qna?.hide();\n this._simrel?.hide();\n this._simbut?.hide();\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 if (this.options.simbut && this.options.simbut.enabled !== false) {\n const simButTarget = this.options.simbut.mountTarget ?? DEFAULT_SIMBUT_MOUNT;\n const mountTarget = resolveMountTarget(simButTarget);\n const chatOrHandler = this._chat ?? this.options.simbut.onFindSimilar;\n\n if (mountTarget && chatOrHandler) {\n this._warnedSimButMountMissing = false;\n this._warnedSimButNoChat = false;\n if (!this._simbut) {\n const simbut = new GengageSimBut();\n const simButConfig: SimButWidgetConfig = {\n accountId: this.options.accountId,\n middlewareUrl,\n session: this.session,\n pageContext: {\n pageType: 'pdp',\n sku,\n },\n mountTarget,\n chat: this._chat,\n };\n if (this.options.theme !== undefined) simButConfig.theme = this.options.theme;\n if (this.options.locale !== undefined) simButConfig.locale = this.options.locale;\n if (this.options.simbut.imageUrl !== undefined) simButConfig.imageUrl = this.options.simbut.imageUrl;\n if (this.options.simbut.i18n !== undefined) simButConfig.i18n = this.options.simbut.i18n;\n if (this.options.simbut.onFindSimilar !== undefined) {\n simButConfig.onFindSimilar = this.options.simbut.onFindSimilar;\n }\n await simbut.init(simButConfig);\n this._simbut = simbut;\n } else {\n this._simbut.show();\n this._simbut.setChat(this._chat);\n this._simbut.update({ pageType: 'pdp', sku });\n }\n } else {\n this._simbut?.destroy();\n this._simbut = null;\n if (!mountTarget && !this._warnedSimButMountMissing) {\n console.warn(`[gengage] SimBut mount target not found: ${simButTarget}`);\n this._warnedSimButMountMissing = true;\n } else if (!chatOrHandler && !this._warnedSimButNoChat) {\n console.warn('[gengage] SimBut requires chat to be enabled or simbut.onFindSimilar');\n this._warnedSimButNoChat = true;\n }\n }\n } else {\n this._simbut?.destroy();\n this._simbut = null;\n }\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 chat, QNA, SimRel, and optional SimBut (PDP image “find similar” pill) in one 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 * simbut: { mountTarget: '#pdp-image-wrap' },\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"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"native-webview-CRFBySOa.js","names":[],"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 { GengageSimBut } from '../simbut/index.js';\nimport type { SimButWidgetConfig } from '../simbut/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';\nconst DEFAULT_SIMBUT_MOUNT = '#gengage-simbut';\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 /** Opens merchant favorites page (passed to chat `onFavoritesClick`). */\n onFavoritesClick?: () => void;\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 /** When true, allow full product details in the assistant side panel; default is chat summary only. */\n productDetailsExtended?: boolean;\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 OverlaySimButOptions {\n enabled?: boolean;\n mountTarget?: HTMLElement | string;\n /** `findSimilar` yüküne eklenecek ürün görseli URL’si. */\n imageUrl?: string;\n i18n?: SimButWidgetConfig['i18n'];\n /** Chat kapalıyken veya özel davranış için; tanımlıysa tıklamada `chat` yerine bu çağrılır. */\n onFindSimilar?: SimButWidgetConfig['onFindSimilar'];\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 simbut?: OverlaySimButOptions;\n onAddToCart?: (params: import('./types.js').AddToCartParams) => void;\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 readonly simbut: GengageSimBut | 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 _simbut: GengageSimBut | 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 private _warnedSimButMountMissing = false;\n private _warnedSimButNoChat = 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 simbut(): GengageSimBut | null {\n return this._simbut;\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 this._simbut?.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 this._simbut?.destroy();\n\n this._chat = null;\n this._qna = null;\n this._simrel = null;\n this._simbut = 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?.onFavoritesClick !== undefined) {\n config.onFavoritesClick = this.options.chat.onFavoritesClick;\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.chat?.productDetailsExtended !== undefined) {\n config.productDetailsExtended = this.options.chat.productDetailsExtended;\n }\n if (this.options.onScriptCall !== undefined) {\n config.onScriptCall = this.options.onScriptCall;\n }\n if (this.options.onAddToCart !== undefined) {\n config.onAddToCart = this.options.onAddToCart;\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 // Hide rather than destroy — the mount target stays populated so the\n // user sees a graceful empty state instead of a blank/missing widget.\n // Widgets are re-shown and updated when navigation returns to a PDP page.\n this._qna?.hide();\n this._simrel?.hide();\n this._simbut?.hide();\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 if (this.options.simbut && this.options.simbut.enabled !== false) {\n const simButTarget = this.options.simbut.mountTarget ?? DEFAULT_SIMBUT_MOUNT;\n const mountTarget = resolveMountTarget(simButTarget);\n const chatOrHandler = this._chat ?? this.options.simbut.onFindSimilar;\n\n if (mountTarget && chatOrHandler) {\n this._warnedSimButMountMissing = false;\n this._warnedSimButNoChat = false;\n if (!this._simbut) {\n const simbut = new GengageSimBut();\n const simButConfig: SimButWidgetConfig = {\n accountId: this.options.accountId,\n middlewareUrl,\n session: this.session,\n pageContext: {\n pageType: 'pdp',\n sku,\n },\n mountTarget,\n chat: this._chat,\n };\n if (this.options.theme !== undefined) simButConfig.theme = this.options.theme;\n if (this.options.locale !== undefined) simButConfig.locale = this.options.locale;\n if (this.options.simbut.imageUrl !== undefined) simButConfig.imageUrl = this.options.simbut.imageUrl;\n if (this.options.simbut.i18n !== undefined) simButConfig.i18n = this.options.simbut.i18n;\n if (this.options.simbut.onFindSimilar !== undefined) {\n simButConfig.onFindSimilar = this.options.simbut.onFindSimilar;\n }\n await simbut.init(simButConfig);\n this._simbut = simbut;\n } else {\n this._simbut.show();\n this._simbut.setChat(this._chat);\n this._simbut.update({ pageType: 'pdp', sku });\n }\n } else {\n this._simbut?.destroy();\n this._simbut = null;\n if (!mountTarget && !this._warnedSimButMountMissing) {\n console.warn(`[gengage] SimBut mount target not found: ${simButTarget}`);\n this._warnedSimButMountMissing = true;\n } else if (!chatOrHandler && !this._warnedSimButNoChat) {\n console.warn('[gengage] SimBut requires chat to be enabled or simbut.onFindSimilar');\n this._warnedSimButNoChat = true;\n }\n }\n } else {\n this._simbut?.destroy();\n this._simbut = null;\n }\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 chat, QNA, SimRel, and optional SimBut (PDP image “find similar” pill) in one 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 * simbut: { mountTarget: '#pdp-image-wrap' },\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"],"mappings":"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"}
|
package/dist/qna-DvgpFom7.cjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const e=require(`./schemas-C-giAkv4.cjs`),t=require(`./ga-datalayer-D3upAPs9.cjs`),n=require(`./connection-warning-fwHynNgu.cjs`);async function r(t,n,r){let i=e.d(`launcher_action`,n),a={uiSpecs:[],actions:[]},o={method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)};r!==void 0&&(o.signal=r);let s=await fetch(i,o);if(!s.ok)throw Error(`HTTP ${s.status}: ${s.statusText}`);let c={onEvent:t=>{let n=e.p(t);if(n&&(n.type===`ui_spec`&&a.uiSpecs.push(n.spec),n.type===`ui_spec`&&n.spec.elements)){for(let e of Object.values(n.spec.elements))if(e.type===`ActionButton`&&e.props?.action){let t=e.props.action;a.actions.push(t)}}}};return r!==void 0&&(c.signal=r),await e.y(s,c),a}function i(e){let t=document.createElement(`div`);t.className=`gengage-qna-buttons gds-toolbar`,t.dataset.gengagePart=`qna-button-row`,t.setAttribute(`role`,`group`),t.setAttribute(`aria-label`,e.quickQuestionsAriaLabel??`Quick questions`),e.orientation===`vertical`&&(t.style.flexDirection=`column`);for(let n of e.actions){let r=document.createElement(`button`);r.className=`gengage-qna-button gds-chip`,r.dataset.gengagePart=`qna-quick-question`,r.textContent=n.title,r.type=`button`,r.addEventListener(`click`,()=>{let t={title:n.title,type:n.type};n.payload!==void 0&&(t.payload=n.payload),e.onAction(t)}),t.appendChild(r)}if(e.ctaText||e.onOpenChat){let n=document.createElement(`button`);n.className=`gengage-qna-cta gds-btn gds-btn-secondary`,n.dataset.gengagePart=`qna-cta`,n.textContent=e.ctaText??e.defaultCtaText??`Ask something else`,n.type=`button`,n.addEventListener(`click`,()=>{e.onOpenChat?.()}),t.appendChild(n)}return t}function a(e){let t=document.createElement(`div`);t.className=`gengage-qna-input-wrapper`,t.dataset.gengagePart=`qna-input-wrapper`;let n=document.createElement(`div`);n.className=`gengage-qna-input-combo`,n.dataset.gengagePart=`qna-input-combo`;let r=document.createElement(`input`);r.type=`text`,r.className=`gengage-qna-input`,r.dataset.gengagePart=`qna-input`,r.setAttribute(`aria-label`,e.askQuestionAriaLabel??`Ask a question`);let i=Array.isArray(e.placeholders)?e.placeholders:e.placeholders?[e.placeholders]:[e.defaultInputPlaceholder??`Ask a question...`],a=0,o=i[0]??``;r.placeholder=o;let s=null,c=null,l=!1,u=()=>{s&&clearInterval(s),s=null,c&&clearTimeout(c),c=null,r.classList.remove(`gengage-qna-input--fade`)},d=()=>i.length>1&&!l&&r.value.trim().length===0,f=()=>{u(),d()&&(s=setInterval(()=>{d()&&(r.classList.add(`gengage-qna-input--fade`),c=setTimeout(()=>{a=(a+1)%i.length,o=i[a]??``,r.placeholder=o,r.classList.remove(`gengage-qna-input--fade`)},180))},3e3))},p=document.createElement(`div`);p.className=`gengage-qna-input-actions`,p.dataset.gengagePart=`qna-input-actions`;let m=document.createElement(`button`);m.className=`gengage-qna-icon-btn gengage-qna-clear gengage-qna-icon-btn--hidden`,m.type=`button`,m.dataset.gengagePart=`qna-clear`,m.setAttribute(`aria-label`,`Clear question`),m.innerHTML=`<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M18 6L6 18" /><path d="M6 6L18 18" /></svg>`;let h=document.createElement(`button`);h.className=`gengage-qna-icon-btn gengage-qna-send gengage-qna-icon-btn--hidden`,h.type=`button`,h.dataset.gengagePart=`qna-send`,h.setAttribute(`aria-label`,e.sendQuestionAriaLabel??`Send question`),h.disabled=!0,h.innerHTML=`<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M22 2L11 13" /><path d="M22 2L15 22L11 13L2 9L22 2Z" /></svg><span class="gengage-qna-sr-only">${e.ctaLabel??e.sendButtonText??`Ask`}</span>`;let g=()=>{let e=r.value.trim().length>0;m.classList.toggle(`gengage-qna-icon-btn--hidden`,!e),h.classList.toggle(`gengage-qna-icon-btn--hidden`,!e),h.classList.toggle(`gengage-qna-send--active`,e),h.disabled=!e},_=()=>{let t=r.value.trim();t&&(e.onSubmit({title:t,type:`user_message`,payload:t}),r.value=``,g(),f())};return m.addEventListener(`click`,()=>{r.value=``,g(),r.focus({preventScroll:!0})}),h.addEventListener(`click`,_),r.addEventListener(`focus`,()=>{l=!0,u(),r.placeholder=``}),r.addEventListener(`blur`,()=>{l=!1,r.value.trim().length===0&&(r.placeholder=o),f()}),r.addEventListener(`input`,()=>{if(g(),r.value.trim().length>0){u();return}r.placeholder=l?``:o,f()}),r.addEventListener(`keydown`,e=>{e.key===`Enter`&&(e.preventDefault(),_()),e.key===`Escape`&&r.value.length>0&&(r.value=``,g(),f())}),p.appendChild(m),p.appendChild(h),n.appendChild(r),n.appendChild(p),t.appendChild(n),g(),f(),t._cleanup=()=>{u()},t}function o(e,t){if(!e||typeof e!=`object`)return null;let n=e,r=n.type;if(typeof r!=`string`||r.length===0)return null;let i=n.title,a=n.payload,o=typeof i==`string`&&i.length>0?i:t;if(!o)return null;let s={title:o,type:r};return a!==void 0&&(s.payload=a),s}function s(e){let t={title:e.title,type:e.type};return e.payload!==void 0&&(t.payload=e.payload),t}function c(e,t){let n=[],r=e.props?.actions;if(Array.isArray(r))for(let e of r){let t=o(e);t&&n.push(t)}let i=e.props?.buttons;if(Array.isArray(i))for(let e of i){if(!e||typeof e!=`object`)continue;let t=e,r=typeof t.label==`string`?t.label:void 0,i=o(t.action,r);i&&n.push(i)}if(e.children)for(let r of e.children){let e=t.elements[r];if(!e||e.type!==`ActionButton`)continue;let i=typeof e.props?.label==`string`?e.props.label:void 0,a=o(e.props?.action,i);a&&n.push(a)}let a=new Set;return n.filter(e=>a.has(e.title)?!1:(a.add(e.title),!0))}var l={ButtonRow:({element:e,spec:t,context:n})=>{let r=c(e,t).map(s),a=e.props?.orientation,o={actions:r,onAction:n.onAction,defaultCtaText:n.i18n.defaultCtaText,quickQuestionsAriaLabel:n.i18n.quickQuestionsAriaLabel};return n.onOpenChat!==void 0&&(o.onOpenChat=n.onOpenChat),n.ctaText!==void 0&&(o.ctaText=n.ctaText),(a===`horizontal`||a===`vertical`)&&(o.orientation=a),i(o)},ActionButtons:({element:e,spec:t,context:n})=>{let r={actions:c(e,t).map(s),onAction:n.onAction,defaultCtaText:n.i18n.defaultCtaText,quickQuestionsAriaLabel:n.i18n.quickQuestionsAriaLabel};return n.onOpenChat!==void 0&&(r.onOpenChat=n.onOpenChat),n.ctaText!==void 0&&(r.ctaText=n.ctaText),i(r)},ActionButton:({element:e,context:t})=>{let n=document.createElement(`button`);n.className=`gengage-qna-button gds-chip`,n.type=`button`,n.dataset.gengagePart=`qna-action-button`;let r=e.props?.label;typeof r==`string`?n.textContent=r:n.textContent=t.i18n.defaultCtaText;let i=o(e.props?.action,typeof r==`string`?r:void 0);return i&&n.addEventListener(`click`,()=>t.onAction(i)),n},TextInput:({element:e,context:t})=>{let n=e.props?.placeholder,r=typeof n==`string`||Array.isArray(n)?n:t.inputPlaceholder,i=typeof e.props?.ctaLabel==`string`?e.props.ctaLabel:void 0,o={onSubmit:t.onAction,askQuestionAriaLabel:t.i18n.askQuestionAriaLabel,defaultInputPlaceholder:t.i18n.defaultInputPlaceholder,sendButtonText:t.i18n.sendButton,sendQuestionAriaLabel:t.i18n.sendQuestionAriaLabel};return r!==void 0&&(o.placeholders=r),i!==void 0&&(o.ctaLabel=i),a(o)},QuestionHeading:({element:e})=>{let t=document.createElement(`h3`);t.className=`gengage-qna-heading`,t.dataset.gengagePart=`qna-heading`;let n=e.props?.text;return t.textContent=typeof n==`string`?n:``,t},ProductCard:()=>null},u=({element:e,renderElement:t})=>{if(!e.children||e.children.length===0)return null;let n=document.createElement(`div`);for(let r of e.children){let e=t(r);e&&n.appendChild(e)}return n};function d(){return{...l}}function f(t,n,r=l,i=u){return e.C({spec:t,context:n,registry:r,containerClassName:`gengage-qna-uispec`,unknownRenderer:i})}function p(e){if(!e)return;let t=e.extra;if(t&&typeof t==`object`&&!Array.isArray(t)){let e=t.visible_skus??t.visibleSkus;if(Array.isArray(e)){let t=e.filter(e=>typeof e==`string`&&e.trim().length>0).map(e=>e.trim()).slice(0,200);if(t.length>0)return t}}let n=typeof e.sku==`string`&&e.sku.trim()?e.sku.trim():void 0;return n?[n]:void 0}function m(e,t){if(!e)return null;let n=e.action;if(!n||typeof n!=`object`)return null;let r=n,i=r.type;if(typeof i!=`string`||i.length===0)return null;let a=r.title,o=typeof a==`string`&&a.length>0?a:typeof t==`string`&&t.length>0?t:``;if(!o)return null;let s=r.payload,c={title:o,type:i};return s!==void 0&&(c.payload=s),c}function h(e,t){let n=e.elements[e.root];if(!n)return!1;let r=e=>{if(e.type!==`ActionButton`)return!1;let n=e.props;if(!n||typeof n!=`object`)return!1;let r=typeof n.label==`string`?n.label:void 0;return r===t?!0:m(n,r)?.title===t};if(n.type===`ActionButton`)return r(n);if(n.children)for(let t of n.children){let n=e.elements[t];if(n&&r(n))return!0}if(n.type===`ActionButtons`&&Array.isArray(n.props?.buttons)){for(let e of n.props.buttons)if(e?.label===t||e?.action?.title===t)return!0}return!1}var g=0;function _(){return g+=1,`gengage-merge-${g}`}function v(e,t){let n=e.elements[e.root];if(!n||n.type!==`ButtonRow`)return;let r=_();e.elements[r]={type:`ActionButton`,props:{label:t.title,action:{title:t.title,type:t.type,...t.payload===void 0?{}:{payload:t.payload}}}},n.children=n.children?[r,...n.children]:[r]}function y(e,t){let n=e.elements[e.root];if(!n||n.type!==`ActionButtons`)return;let r=_();e.elements[r]={type:`ActionButton`,props:{label:t.title,action:{title:t.title,type:t.type,...t.payload===void 0?{}:{payload:t.payload}}}},n.children=n.children?[r,...n.children]:[r];let i=n.props?.buttons??[],a={label:t.title,action:{title:t.title,type:t.type,...t.payload===void 0?{}:{payload:t.payload}}};n.props={...n.props,buttons:[a,...i]}}function b(e){let t={},n=[];for(let r=0;r<e.length;r++){let i=e[r],a=`action-${r}`;n.push(a),t[a]={type:`ActionButton`,props:{label:i.title,action:{title:i.title,type:i.type,...i.payload===void 0?{}:{payload:i.payload}}}}}return t.root={type:`ButtonRow`,children:n},{root:`root`,elements:t}}function x(e){return e.find(e=>{let t=e.elements[e.root];return t?.type===`ActionButtons`||t?.type===`ButtonRow`})}function S(e,t){let n=e.productContextQuickPillLabel,r={text:n};return t&&t.length>0&&(r.sku_list=t),{title:n,type:`user_message`,payload:r}}function C(e,t,n){let r=n?.skuList,i=[],a=[];for(let n of e){let e=n.elements[n.root];if(e?.type===`ActionButton`){let n=e.props;if(m(n,typeof n?.label==`string`?n.label:void 0)?.type===`findSimilar`){i.push(S(t,r));continue}}a.push(n)}if(i.length===0)return e;let o=S(t,r),s=x(a);if(!s)return[...a,b([o])];if(!h(s,o.title)){let e=s.elements[s.root];e?.type===`ActionButtons`?y(s,o):e?.type===`ButtonRow`&&v(s,o)}return a}var w={quickQuestionsAriaLabel:`Hızlı sorular`,askQuestionAriaLabel:`Soru sorun`,defaultInputPlaceholder:`Bir soru sorun...`,sendButton:`Sor`,sendQuestionAriaLabel:`Soruyu gönder`,defaultCtaText:`Başka bir şey sor`,redirectingToChat:`Sohbete yönlendiriliyor...`,productContextQuickPillLabel:`Bu ürün hakkında ne bilmeliyim?`},T={quickQuestionsAriaLabel:`Quick questions`,askQuestionAriaLabel:`Ask a question`,defaultInputPlaceholder:`Ask a question...`,sendButton:`Ask`,sendQuestionAriaLabel:`Send question`,defaultCtaText:`Ask something else`,redirectingToChat:`Redirecting to chat...`,productContextQuickPillLabel:`What should I know about this product?`};function E(e){return e?e.toLowerCase().split(`-`)[0]??`tr`:`tr`}function D(e){switch(E(e)){case`en`:return T;default:return w}}var O=e.o({title:e.c(),type:e.c(),payload:e.u().optional()}),k=e.o({label:e.c(),action:O,variant:e.t([`primary`,`outline`,`ghost`]).optional()}),A=e.o({orientation:e.t([`horizontal`,`vertical`]).optional(),wrap:e.r().optional()}),j=e.o({placeholder:e.l([e.c(),e.n(e.c())]).optional(),ctaLabel:e.c().optional()}),M=e.o({text:e.c()}),N={components:{ActionButton:{schema:k,description:`A single clickable QNA action button.`},ButtonRow:{schema:A,description:`Container for a group of QNA action buttons.`},TextInput:{schema:j,description:`Free-text input with rotating placeholder and CTA button.`},QuestionHeading:{schema:M,description:`A heading displayed above the QNA button group.`}}},P=class extends t.y{constructor(...e){super(...e),this._abortController=null,this._debounceTimer=null,this._contentEl=null,this._i18n=w,this._actionHandler=this._handleAction.bind(this),this._openChatHandler=this._handleOpenChat.bind(this)}async onInit(e){this._i18n=this._resolveI18n(e),this._contentEl=document.createElement(`div`),this._contentEl.className=`gengage-qna-container`,this._contentEl.dataset.gengagePart=`qna-container`,this.root.appendChild(this._contentEl);let n=e.pageContext?.sku;n&&(this._lastSku=n,await this._fetchAndRender(n)),t.c(`qna`)}onUpdate(e){let t=e.sku;!t||t===this._lastSku||(this._debounceTimer&&clearTimeout(this._debounceTimer),this._debounceTimer=setTimeout(()=>{this._debounceTimer=null,this._lastSku=t,this._fetchAndRender(t)},50))}onShow(){this._contentEl&&(this._contentEl.style.opacity=`0`,this._contentEl.style.transition=`opacity 0.2s ease-in`,requestAnimationFrame(()=>{this._contentEl&&(this._contentEl.style.opacity=`1`)}))}onHide(){}onDestroy(){this._abort(),this._debounceTimer&&=(clearTimeout(this._debounceTimer),null),this._contentEl&&=(this._cleanupTextInputTimers(),this._contentEl.remove(),null)}_abort(){this._abortController?.abort(),this._abortController=null}_cleanupTextInputTimers(){if(!this._contentEl)return;let e=this._contentEl.querySelectorAll(`.gengage-qna-input-wrapper`);for(let t of e)t._cleanup?.()}async _fetchAndRender(e){if(this._abort(),this._abortController=new AbortController,!this._contentEl)return;this._cleanupTextInputTimers(),this._contentEl.innerHTML=``;let i=this._createLoadingIndicator();this._contentEl.appendChild(i);let a={middlewareUrl:this.config.middlewareUrl},o=crypto.randomUUID(),s=Date.now(),c=n.n({source:`qna`,locale:this.config.locale});this.track(t.Q(this.analyticsContext(),{endpoint:`launcher_action`,request_id:o,widget:`qna`}));try{let n={account_id:this.config.accountId,session_id:this.config.session?.sessionId??``,correlation_id:this.config.session?.sessionId??``,sku:e,locale:this.config.locale??`tr`},i=this.config.pageContext?.pageType;i!==void 0&&(n.page_type=i);let c=await r(n,a,this._abortController.signal);if(this.track(t.X(this.analyticsContext(),{request_id:o,latency_ms:Date.now()-s,chunk_count:c.actions.length,widget:`qna`})),this.track(t.et(this.analyticsContext(),{message_count:c.actions.length,history_ref:o,redaction_level:`none`,widget:`qna`})),!this._contentEl)return;this._contentEl.innerHTML=``;let l=document.createElement(`div`);if(l.className=`gengage-qna-panel gds-panel`,l.dataset.gengagePart=`qna-panel`,this._contentEl.appendChild(l),!this._specIncludesType(c.uiSpecs,`QuestionHeading`)&&this.config.showStaticQuestion&&this.config.staticQuestionText){let e=document.createElement(`h3`);e.className=`gengage-qna-heading`,e.textContent=this.config.staticQuestionText,l.appendChild(e)}let u=this.config.inputPlaceholder,d;if(u!==!0)d=u??this._i18n.defaultInputPlaceholder;else if(c.actions.length>0){let e=c.actions.filter(e=>e.type===`user_message`||e.title.includes(`?`)).map(e=>e.title);d=e.length>0?e:this._i18n.defaultInputPlaceholder}else d=this._i18n.defaultInputPlaceholder;let f={onAction:this._actionHandler,i18n:this._i18n};this.config.hideButtonRowCta||(f.onOpenChat=this._openChatHandler,this.config.ctaText!==void 0&&(f.ctaText=this.config.ctaText)),d!==void 0&&(f.inputPlaceholder=d);let m=this._buildFallbackActionsSpec(c.actions),h=p(this.config.pageContext),g=(c.uiSpecs.length>0?C(c.uiSpecs,this._i18n,{skuList:h}):[m]).filter(e=>Object.keys(e.elements).length>0);for(let e of g){let t=this._renderUISpec(e,f);l.appendChild(t)}g.length>0&&t.h(`qna`),this._specIncludesType(g,`TextInput`)||this._appendStandaloneInput(f,d,l)}catch(e){if(e instanceof DOMException&&e.name===`AbortError`)return;if(t.P(`gengage:global:error`,{source:`qna`,code:`FETCH_ERROR`,message:t.S(this.config.locale,e)}),this.track(t.Z(this.analyticsContext(),{request_id:o,error_code:`FETCH_ERROR`,error_message:e instanceof Error?e.message:String(e),widget:`qna`})),this._contentEl){this._cleanupTextInputTimers(),this._contentEl.innerHTML=``;let e=document.createElement(`div`);e.className=`gengage-qna-panel`,this._contentEl.appendChild(e);let t=this.config.inputPlaceholder===!0?this._i18n.defaultInputPlaceholder:this.config.inputPlaceholder??this._i18n.defaultInputPlaceholder,n={onAction:this._actionHandler,i18n:this._i18n,onOpenChat:this._openChatHandler};this.config.ctaText!==void 0&&(n.ctaText=this.config.ctaText),this._appendStandaloneInput(n,t,e)}}finally{c()}}_createLoadingIndicator(){let e=document.createElement(`div`);e.className=`gengage-qna-loading`;for(let t=0;t<3;t++){let t=document.createElement(`div`);t.className=`gengage-qna-loading-dot`,e.appendChild(t)}return e}_resolveI18n(e){return{...D(e.locale),...e.i18n}}_resolveUISpecRegistry(){return e.x(d(),this.config.renderer?.registry)}_renderUISpec(e,t){let n=this._resolveUISpecRegistry(),r=this.config.renderer?.unknownRenderer??u,i=(e,t)=>f(e,t,n,r),a=this.config.renderer?.renderUISpec;return a?a(e,t,{registry:n,unknownRenderer:r,defaultRender:i}):i(e,t)}_specIncludesType(e,t){for(let n of e)for(let e of Object.values(n.elements))if(e.type===t)return!0;return!1}_buildFallbackActionsSpec(e){if(e.length===0)return{root:`root`,elements:{}};let t={},n=[];for(let r=0;r<e.length;r++){let i=e[r],a=`action-${r}`;n.push(a),t[a]={type:`ActionButton`,props:{label:i.title,action:{title:i.title,type:i.type,payload:i.payload}}}}return t.root={type:`ButtonRow`,children:n},{root:`root`,elements:t}}_appendStandaloneInput(e,t,n){if(!this._contentEl)return;let r={root:`root`,elements:{root:{type:`TextInput`,props:{placeholder:t}}}},i=this._renderUISpec(r,e);(n??this._contentEl).appendChild(i)}_handleAction(e){this._showTransitionIndicator(),t.g(e.title,e.type),this.config.onActionSelected?.(e),setTimeout(()=>t.P(`gengage:qna:action`,e),350)}_handleOpenChat(){this._showTransitionIndicator(),this.config.onOpenChat?.(),setTimeout(()=>t.P(`gengage:qna:open-chat`,{}),350)}_showTransitionIndicator(){if(!this._contentEl)return;this._contentEl.querySelector(`.gengage-qna-transition-indicator`)?.remove(),this._contentEl.classList.add(`gengage-qna--transitioning`);let e=this._i18n.redirectingToChat??`Redirecting to chat...`,t=document.createElement(`div`);t.className=`gengage-qna-transition-indicator`,t.textContent=e,(this._contentEl.querySelector(`.gengage-qna-panel`)??this._contentEl).appendChild(t),setTimeout(()=>{this._contentEl?.classList.remove(`gengage-qna--transitioning`),t.remove()},600)}};function F(){return new P}Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return N}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return P}});
|
|
2
|
-
//# sourceMappingURL=qna-DvgpFom7.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"qna-DvgpFom7.cjs","names":[],"sources":["../src/qna/api.ts","../src/qna/components/ButtonRow.ts","../src/qna/components/TextInput.ts","../src/qna/components/renderUISpec.ts","../src/qna/normalize-ui-specs.ts","../src/qna/locales/tr.ts","../src/qna/locales/en.ts","../src/qna/locales/index.ts","../src/qna/catalog.ts","../src/qna/index.ts"],"sourcesContent":["import { consumeStream } from '../common/streaming.js';\nimport { buildChatEndpointUrl } from '../common/api-paths.js';\nimport { adaptBackendEvent } from '../common/protocol-adapter.js';\nimport type { StreamEvent, UISpec } from '../common/types.js';\nimport type { ChatTransportConfig } from '../common/api-paths.js';\n\nexport interface LauncherActionRequest {\n account_id: string;\n session_id: string;\n correlation_id: string;\n sku: string;\n page_type?: string;\n locale?: string;\n output_language?: string;\n mode?: string;\n}\n\nexport interface LauncherActionResult {\n uiSpecs: UISpec[];\n actions: Array<{ title: string; type: string; payload?: unknown }>;\n}\n\nexport async function fetchLauncherActions(\n request: LauncherActionRequest,\n transport: ChatTransportConfig,\n signal?: AbortSignal,\n): Promise<LauncherActionResult> {\n const url = buildChatEndpointUrl('launcher_action', transport);\n const result: LauncherActionResult = { uiSpecs: [], actions: [] };\n\n const fetchInit: RequestInit = {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(request),\n };\n if (signal !== undefined) fetchInit.signal = signal;\n const response = await fetch(url, fetchInit);\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const streamOpts: import('../common/streaming.js').StreamOptions = {\n onEvent: (event: StreamEvent) => {\n const normalized = adaptBackendEvent(event as unknown as Record<string, unknown>);\n\n if (!normalized) return;\n\n if (normalized.type === 'ui_spec') {\n result.uiSpecs.push(normalized.spec);\n }\n\n if (normalized.type === 'ui_spec' && normalized.spec.elements) {\n for (const el of Object.values(normalized.spec.elements)) {\n if (el.type === 'ActionButton' && el.props?.['action']) {\n const action = el.props['action'] as { title: string; type: string; payload?: unknown };\n result.actions.push(action);\n }\n }\n }\n },\n };\n if (signal !== undefined) streamOpts.signal = signal;\n\n await consumeStream(response, streamOpts);\n\n return result;\n}\n","import type { ActionPayload } from '../../common/types.js';\n\nexport interface ButtonRowOptions {\n actions: Array<{ title: string; type: string; payload?: unknown }>;\n onAction: (action: ActionPayload) => void;\n ctaText?: string;\n defaultCtaText?: string;\n onOpenChat?: () => void;\n orientation?: 'horizontal' | 'vertical';\n quickQuestionsAriaLabel?: string;\n}\n\nexport function renderButtonRow(options: ButtonRowOptions): HTMLElement {\n const container = document.createElement('div');\n container.className = 'gengage-qna-buttons gds-toolbar';\n container.dataset['gengagePart'] = 'qna-button-row';\n container.setAttribute('role', 'group');\n container.setAttribute('aria-label', options.quickQuestionsAriaLabel ?? 'Quick questions');\n\n if (options.orientation === 'vertical') {\n container.style.flexDirection = 'column';\n }\n\n for (const action of options.actions) {\n const button = document.createElement('button');\n button.className = 'gengage-qna-button gds-chip';\n button.dataset['gengagePart'] = 'qna-quick-question';\n button.textContent = action.title;\n button.type = 'button';\n button.addEventListener('click', () => {\n const actionPayload: ActionPayload = {\n title: action.title,\n type: action.type,\n };\n if (action.payload !== undefined) actionPayload.payload = action.payload;\n options.onAction(actionPayload);\n });\n container.appendChild(button);\n }\n\n if (options.ctaText || options.onOpenChat) {\n const cta = document.createElement('button');\n cta.className = 'gengage-qna-cta gds-btn gds-btn-secondary';\n cta.dataset['gengagePart'] = 'qna-cta';\n cta.textContent = options.ctaText ?? options.defaultCtaText ?? 'Ask something else';\n cta.type = 'button';\n cta.addEventListener('click', () => {\n options.onOpenChat?.();\n });\n container.appendChild(cta);\n }\n\n return container;\n}\n","import type { ActionPayload } from '../../common/types.js';\n\nexport interface TextInputOptions {\n placeholders?: string | string[];\n ctaLabel?: string;\n defaultInputPlaceholder?: string;\n askQuestionAriaLabel?: string;\n sendButtonText?: string;\n sendQuestionAriaLabel?: string;\n onSubmit: (action: ActionPayload) => void;\n}\n\nexport function renderTextInput(options: TextInputOptions): HTMLElement {\n const container = document.createElement('div');\n container.className = 'gengage-qna-input-wrapper';\n container.dataset['gengagePart'] = 'qna-input-wrapper';\n\n const combo = document.createElement('div');\n combo.className = 'gengage-qna-input-combo';\n combo.dataset['gengagePart'] = 'qna-input-combo';\n\n const input = document.createElement('input');\n input.type = 'text';\n input.className = 'gengage-qna-input';\n input.dataset['gengagePart'] = 'qna-input';\n input.setAttribute('aria-label', options.askQuestionAriaLabel ?? 'Ask a question');\n\n // Rotating placeholders\n const placeholders = Array.isArray(options.placeholders)\n ? options.placeholders\n : options.placeholders\n ? [options.placeholders]\n : [options.defaultInputPlaceholder ?? 'Ask a question...'];\n\n let placeholderIndex = 0;\n let activePlaceholder = placeholders[0] ?? '';\n input.placeholder = activePlaceholder;\n\n let rotateTimer: ReturnType<typeof setInterval> | null = null;\n let fadeTimer: ReturnType<typeof setTimeout> | null = null;\n let isFocused = false;\n\n const stopPlaceholderRotation = () => {\n if (rotateTimer) clearInterval(rotateTimer);\n rotateTimer = null;\n if (fadeTimer) clearTimeout(fadeTimer);\n fadeTimer = null;\n input.classList.remove('gengage-qna-input--fade');\n };\n\n const shouldRotatePlaceholders = () => placeholders.length > 1 && !isFocused && input.value.trim().length === 0;\n\n const startPlaceholderRotation = () => {\n stopPlaceholderRotation();\n if (!shouldRotatePlaceholders()) return;\n rotateTimer = setInterval(() => {\n if (!shouldRotatePlaceholders()) return;\n input.classList.add('gengage-qna-input--fade');\n fadeTimer = setTimeout(() => {\n placeholderIndex = (placeholderIndex + 1) % placeholders.length;\n activePlaceholder = placeholders[placeholderIndex] ?? '';\n input.placeholder = activePlaceholder;\n input.classList.remove('gengage-qna-input--fade');\n }, 180);\n }, 3000);\n };\n\n const actionIcons = document.createElement('div');\n actionIcons.className = 'gengage-qna-input-actions';\n actionIcons.dataset['gengagePart'] = 'qna-input-actions';\n\n const clearBtn = document.createElement('button');\n clearBtn.className = 'gengage-qna-icon-btn gengage-qna-clear gengage-qna-icon-btn--hidden';\n clearBtn.type = 'button';\n clearBtn.dataset['gengagePart'] = 'qna-clear';\n clearBtn.setAttribute('aria-label', 'Clear question');\n clearBtn.innerHTML =\n '<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M18 6L6 18\" /><path d=\"M6 6L18 18\" /></svg>';\n\n const sendBtn = document.createElement('button');\n sendBtn.className = 'gengage-qna-icon-btn gengage-qna-send gengage-qna-icon-btn--hidden';\n sendBtn.type = 'button';\n sendBtn.dataset['gengagePart'] = 'qna-send';\n sendBtn.setAttribute('aria-label', options.sendQuestionAriaLabel ?? 'Send question');\n sendBtn.disabled = true;\n sendBtn.innerHTML = `<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M22 2L11 13\" /><path d=\"M22 2L15 22L11 13L2 9L22 2Z\" /></svg><span class=\"gengage-qna-sr-only\">${options.ctaLabel ?? options.sendButtonText ?? 'Ask'}</span>`;\n\n const updateActionButtons = () => {\n const hasValue = input.value.trim().length > 0;\n clearBtn.classList.toggle('gengage-qna-icon-btn--hidden', !hasValue);\n sendBtn.classList.toggle('gengage-qna-icon-btn--hidden', !hasValue);\n sendBtn.classList.toggle('gengage-qna-send--active', hasValue);\n sendBtn.disabled = !hasValue;\n };\n\n const submit = () => {\n const text = input.value.trim();\n if (!text) return;\n options.onSubmit({\n title: text,\n type: 'user_message',\n // Align with chat composer: user_message payload is plain string.\n payload: text,\n });\n input.value = '';\n updateActionButtons();\n startPlaceholderRotation();\n };\n\n clearBtn.addEventListener('click', () => {\n input.value = '';\n updateActionButtons();\n input.focus({ preventScroll: true });\n });\n\n sendBtn.addEventListener('click', submit);\n\n input.addEventListener('focus', () => {\n isFocused = true;\n stopPlaceholderRotation();\n input.placeholder = '';\n });\n\n input.addEventListener('blur', () => {\n isFocused = false;\n if (input.value.trim().length === 0) {\n input.placeholder = activePlaceholder;\n }\n startPlaceholderRotation();\n });\n\n input.addEventListener('input', () => {\n updateActionButtons();\n if (input.value.trim().length > 0) {\n stopPlaceholderRotation();\n return;\n }\n input.placeholder = isFocused ? '' : activePlaceholder;\n startPlaceholderRotation();\n });\n\n input.addEventListener('keydown', (e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n submit();\n }\n if (e.key === 'Escape' && input.value.length > 0) {\n input.value = '';\n updateActionButtons();\n startPlaceholderRotation();\n }\n });\n\n actionIcons.appendChild(clearBtn);\n actionIcons.appendChild(sendBtn);\n combo.appendChild(input);\n combo.appendChild(actionIcons);\n container.appendChild(combo);\n\n updateActionButtons();\n startPlaceholderRotation();\n\n // Cleanup method\n (container as HTMLElement & { _cleanup?: () => void })._cleanup = () => {\n stopPlaceholderRotation();\n };\n\n return container;\n}\n","import { renderUISpecWithRegistry } from '../../common/renderer/index.js';\nimport type { UISpecDomRegistry, UISpecDomUnknownRenderer } from '../../common/renderer/index.js';\nimport type { UISpec, UIElement, ActionPayload } from '../../common/types.js';\nimport type { QNAUISpecRenderContext } from '../types.js';\nimport { renderButtonRow } from './ButtonRow.js';\nimport { renderTextInput } from './TextInput.js';\n\nexport type QNAUISpecRegistry = UISpecDomRegistry<QNAUISpecRenderContext>;\n\nfunction toActionPayload(raw: unknown, labelFallback?: string): ActionPayload | null {\n if (!raw || typeof raw !== 'object') return null;\n const obj = raw as Record<string, unknown>;\n const type = obj['type'];\n if (typeof type !== 'string' || type.length === 0) return null;\n\n const titleRaw = obj['title'];\n const payload = obj['payload'];\n const title = typeof titleRaw === 'string' && titleRaw.length > 0 ? titleRaw : labelFallback;\n if (!title) return null;\n\n const action: ActionPayload = { title, type };\n if (payload !== undefined) action.payload = payload;\n return action;\n}\n\nfunction actionPayloadToRowAction(action: ActionPayload): { title: string; type: string; payload?: unknown } {\n const rowAction: { title: string; type: string; payload?: unknown } = {\n title: action.title,\n type: action.type,\n };\n if (action.payload !== undefined) rowAction.payload = action.payload;\n return rowAction;\n}\n\nfunction collectButtonRowActions(element: UIElement, spec: UISpec): ActionPayload[] {\n const actions: ActionPayload[] = [];\n\n const directActions = element.props?.['actions'];\n if (Array.isArray(directActions)) {\n for (const rawAction of directActions) {\n const normalized = toActionPayload(rawAction);\n if (normalized) actions.push(normalized);\n }\n }\n\n const directButtons = element.props?.['buttons'];\n if (Array.isArray(directButtons)) {\n for (const rawButton of directButtons) {\n if (!rawButton || typeof rawButton !== 'object') continue;\n const obj = rawButton as Record<string, unknown>;\n const label = typeof obj['label'] === 'string' ? obj['label'] : undefined;\n const action = toActionPayload(obj['action'], label);\n if (action) actions.push(action);\n }\n }\n\n if (element.children) {\n for (const childId of element.children) {\n const child = spec.elements[childId];\n if (!child || child.type !== 'ActionButton') continue;\n const label = typeof child.props?.['label'] === 'string' ? child.props['label'] : undefined;\n const action = toActionPayload(child.props?.['action'], label);\n if (action) actions.push(action);\n }\n }\n\n // Deduplicate by title — backend may provide same actions via props and children\n const seen = new Set<string>();\n return actions.filter((a) => {\n if (seen.has(a.title)) return false;\n seen.add(a.title);\n return true;\n });\n}\n\nconst DEFAULT_QNA_UI_SPEC_REGISTRY: QNAUISpecRegistry = {\n ButtonRow: ({ element, spec, context }) => {\n const rowActions = collectButtonRowActions(element, spec).map(actionPayloadToRowAction);\n const orientation = element.props?.['orientation'];\n\n const options: import('./ButtonRow.js').ButtonRowOptions = {\n actions: rowActions,\n onAction: context.onAction,\n defaultCtaText: context.i18n.defaultCtaText,\n quickQuestionsAriaLabel: context.i18n.quickQuestionsAriaLabel,\n };\n if (context.onOpenChat !== undefined) options.onOpenChat = context.onOpenChat;\n if (context.ctaText !== undefined) options.ctaText = context.ctaText;\n if (orientation === 'horizontal' || orientation === 'vertical') options.orientation = orientation;\n return renderButtonRow(options);\n },\n\n ActionButtons: ({ element, spec, context }) => {\n const rowActions = collectButtonRowActions(element, spec).map(actionPayloadToRowAction);\n const options: import('./ButtonRow.js').ButtonRowOptions = {\n actions: rowActions,\n onAction: context.onAction,\n defaultCtaText: context.i18n.defaultCtaText,\n quickQuestionsAriaLabel: context.i18n.quickQuestionsAriaLabel,\n };\n if (context.onOpenChat !== undefined) options.onOpenChat = context.onOpenChat;\n if (context.ctaText !== undefined) options.ctaText = context.ctaText;\n return renderButtonRow(options);\n },\n\n ActionButton: ({ element, context }) => {\n const button = document.createElement('button');\n button.className = 'gengage-qna-button gds-chip';\n button.type = 'button';\n button.dataset['gengagePart'] = 'qna-action-button';\n\n const label = element.props?.['label'];\n if (typeof label === 'string') {\n button.textContent = label;\n } else {\n button.textContent = context.i18n.defaultCtaText;\n }\n\n const action = toActionPayload(element.props?.['action'], typeof label === 'string' ? label : undefined);\n if (action) {\n button.addEventListener('click', () => context.onAction(action));\n }\n return button;\n },\n\n TextInput: ({ element, context }) => {\n const placeholder = element.props?.['placeholder'];\n const placeholders =\n typeof placeholder === 'string' || Array.isArray(placeholder) ? placeholder : context.inputPlaceholder;\n // Keep input submit label independent from the quick-question CTA text.\n const ctaLabel = typeof element.props?.['ctaLabel'] === 'string' ? element.props['ctaLabel'] : undefined;\n\n const options: import('./TextInput.js').TextInputOptions = {\n onSubmit: context.onAction,\n askQuestionAriaLabel: context.i18n.askQuestionAriaLabel,\n defaultInputPlaceholder: context.i18n.defaultInputPlaceholder,\n sendButtonText: context.i18n.sendButton,\n sendQuestionAriaLabel: context.i18n.sendQuestionAriaLabel,\n };\n if (placeholders !== undefined) options.placeholders = placeholders;\n if (ctaLabel !== undefined) options.ctaLabel = ctaLabel;\n return renderTextInput(options);\n },\n\n QuestionHeading: ({ element }) => {\n const heading = document.createElement('h3');\n heading.className = 'gengage-qna-heading';\n heading.dataset['gengagePart'] = 'qna-heading';\n const text = element.props?.['text'];\n heading.textContent = typeof text === 'string' ? text : '';\n return heading;\n },\n\n // ProductCard: no-op — QNA renders only question pills + text input.\n // Backend may send ProductCard but QNA intentionally skips it;\n // the product is shown once chat opens via openWithAction().\n ProductCard: () => null,\n};\n\nexport const defaultQnaUnknownUISpecRenderer: UISpecDomUnknownRenderer<QNAUISpecRenderContext> = ({\n element,\n renderElement,\n}) => {\n if (import.meta.env?.DEV) {\n console.warn(`[gengage:qna] Unknown ui_spec component type: ${element.type}`);\n }\n if (!element.children || element.children.length === 0) {\n return null;\n }\n const wrapper = document.createElement('div');\n for (const childId of element.children) {\n const rendered = renderElement(childId);\n if (rendered) wrapper.appendChild(rendered);\n }\n return wrapper;\n};\n\nexport function createDefaultQnaUISpecRegistry(): QNAUISpecRegistry {\n return { ...DEFAULT_QNA_UI_SPEC_REGISTRY };\n}\n\nexport function renderQnaUISpec(\n spec: UISpec,\n context: QNAUISpecRenderContext,\n registry = DEFAULT_QNA_UI_SPEC_REGISTRY,\n unknownRenderer: UISpecDomUnknownRenderer<QNAUISpecRenderContext> = defaultQnaUnknownUISpecRenderer,\n): HTMLElement {\n return renderUISpecWithRegistry({\n spec,\n context,\n registry,\n containerClassName: 'gengage-qna-uispec',\n unknownRenderer,\n });\n}\n","import type { ActionPayload, PageContext, UISpec, UIElement } from '../common/types.js';\nimport type { QNAI18n } from './types.js';\n\n/** SKUs to send with the product-context quick pill (`user_message` + sku_list). */\nexport type MergeQuickPillsOptions = {\n skuList?: string[] | undefined;\n};\n\n/**\n * Resolve SKU list for QNA → chat payloads: current PDP sku, or `visible_skus` on listings.\n */\nexport function resolveQnaSkuListForPayload(pageContext: PageContext | undefined): string[] | undefined {\n if (!pageContext) return undefined;\n const extra = pageContext.extra;\n if (extra && typeof extra === 'object' && !Array.isArray(extra)) {\n const raw = extra['visible_skus'] ?? extra['visibleSkus'];\n if (Array.isArray(raw)) {\n const list = raw\n .filter((x): x is string => typeof x === 'string' && x.trim().length > 0)\n .map((s) => s.trim())\n .slice(0, 200);\n if (list.length > 0) return list;\n }\n }\n const sku = typeof pageContext.sku === 'string' && pageContext.sku.trim() ? pageContext.sku.trim() : undefined;\n return sku ? [sku] : undefined;\n}\n\nfunction actionFromProps(props: Record<string, unknown> | undefined, labelFallback?: string): ActionPayload | null {\n if (!props) return null;\n const actionRaw = props['action'];\n if (!actionRaw || typeof actionRaw !== 'object') return null;\n const obj = actionRaw as Record<string, unknown>;\n const type = obj['type'];\n if (typeof type !== 'string' || type.length === 0) return null;\n const titleRaw = obj['title'];\n const title =\n typeof titleRaw === 'string' && titleRaw.length > 0\n ? titleRaw\n : typeof labelFallback === 'string' && labelFallback.length > 0\n ? labelFallback\n : '';\n if (!title) return null;\n const payload = obj['payload'];\n const out: ActionPayload = { title, type };\n if (payload !== undefined) out.payload = payload;\n return out;\n}\n\nfunction rowHasPillWithTitle(spec: UISpec, title: string): boolean {\n const root = spec.elements[spec.root];\n if (!root) return false;\n\n const checkElement = (el: UIElement): boolean => {\n if (el.type !== 'ActionButton') return false;\n const props = el.props;\n if (!props || typeof props !== 'object') return false;\n const label = typeof props['label'] === 'string' ? props['label'] : undefined;\n if (label === title) return true;\n const a = actionFromProps(props as Record<string, unknown>, label);\n return a?.title === title;\n };\n\n if (root.type === 'ActionButton') {\n return checkElement(root);\n }\n if (root.children) {\n for (const id of root.children) {\n const child = spec.elements[id];\n if (child && checkElement(child)) return true;\n }\n }\n if (root.type === 'ActionButtons' && Array.isArray(root.props?.['buttons'])) {\n for (const btn of root.props['buttons'] as Array<{ label?: string; action?: { title?: string } }>) {\n if (btn?.label === title) return true;\n if (btn?.action?.title === title) return true;\n }\n }\n return false;\n}\n\nlet _mergeId = 0;\nfunction nextMergeId(): string {\n _mergeId += 1;\n return `gengage-merge-${_mergeId}`;\n}\n\nfunction prependToButtonRow(spec: UISpec, action: ActionPayload): void {\n const root = spec.elements[spec.root];\n if (!root || root.type !== 'ButtonRow') return;\n const id = nextMergeId();\n spec.elements[id] = {\n type: 'ActionButton',\n props: {\n label: action.title,\n action: {\n title: action.title,\n type: action.type,\n ...(action.payload !== undefined ? { payload: action.payload } : {}),\n },\n },\n };\n root.children = root.children ? [id, ...root.children] : [id];\n}\n\nfunction prependToActionButtons(spec: UISpec, action: ActionPayload): void {\n const root = spec.elements[spec.root];\n if (!root || root.type !== 'ActionButtons') return;\n const id = nextMergeId();\n spec.elements[id] = {\n type: 'ActionButton',\n props: {\n label: action.title,\n action: {\n title: action.title,\n type: action.type,\n ...(action.payload !== undefined ? { payload: action.payload } : {}),\n },\n },\n };\n root.children = root.children ? [id, ...root.children] : [id];\n const buttons = (root.props?.['buttons'] as Array<Record<string, unknown>> | undefined) ?? [];\n const btnEntry = {\n label: action.title,\n action: {\n title: action.title,\n type: action.type,\n ...(action.payload !== undefined ? { payload: action.payload } : {}),\n },\n };\n root.props = { ...root.props, buttons: [btnEntry, ...buttons] };\n}\n\nfunction buildSingleButtonRowSpec(actions: ActionPayload[]): UISpec {\n const elements: Record<string, UIElement> = {};\n const childIds: string[] = [];\n for (let i = 0; i < actions.length; i++) {\n const action = actions[i]!;\n const id = `action-${i}`;\n childIds.push(id);\n elements[id] = {\n type: 'ActionButton',\n props: {\n label: action.title,\n action: {\n title: action.title,\n type: action.type,\n ...(action.payload !== undefined ? { payload: action.payload } : {}),\n },\n },\n };\n }\n elements['root'] = {\n type: 'ButtonRow',\n children: childIds,\n };\n return { root: 'root', elements };\n}\n\nfunction findFirstPillRowSpec(specs: UISpec[]): UISpec | undefined {\n return specs.find((spec) => {\n const root = spec.elements[spec.root];\n return root?.type === 'ActionButtons' || root?.type === 'ButtonRow';\n });\n}\n\nfunction heroReplacementAction(i18n: QNAI18n, skuList?: string[]): ActionPayload {\n const text = i18n.productContextQuickPillLabel;\n const payload: Record<string, unknown> = { text };\n if (skuList && skuList.length > 0) {\n payload['sku_list'] = skuList;\n }\n return {\n title: text,\n type: 'user_message',\n payload,\n };\n}\n\n/**\n * Removes standalone hero `ActionButton` blocks for `findSimilar` (e.g. from `text_image`)\n * and merges a product-context quick question pill instead (same row as other questions).\n */\nexport function mergeStandaloneFindSimilarIntoQuickPills(\n specs: UISpec[],\n i18n: QNAI18n,\n options?: MergeQuickPillsOptions,\n): UISpec[] {\n const skuList = options?.skuList;\n const extracted: ActionPayload[] = [];\n const filtered: UISpec[] = [];\n\n for (const spec of specs) {\n const root = spec.elements[spec.root];\n if (root?.type === 'ActionButton') {\n const props = root.props as Record<string, unknown> | undefined;\n const label = typeof props?.['label'] === 'string' ? props['label'] : undefined;\n const action = actionFromProps(props, label);\n if (action?.type === 'findSimilar') {\n extracted.push(heroReplacementAction(i18n, skuList));\n continue;\n }\n }\n filtered.push(spec);\n }\n\n if (extracted.length === 0) {\n return specs;\n }\n\n const replacement = heroReplacementAction(i18n, skuList);\n const target = findFirstPillRowSpec(filtered);\n\n if (!target) {\n return [...filtered, buildSingleButtonRowSpec([replacement])];\n }\n\n if (!rowHasPillWithTitle(target, replacement.title)) {\n const root = target.elements[target.root];\n if (root?.type === 'ActionButtons') {\n prependToActionButtons(target, replacement);\n } else if (root?.type === 'ButtonRow') {\n prependToButtonRow(target, replacement);\n }\n }\n\n return filtered;\n}\n","import type { QNAI18n } from '../types.js';\n\nexport const QNA_I18N_TR: QNAI18n = {\n quickQuestionsAriaLabel: 'Hızlı sorular',\n askQuestionAriaLabel: 'Soru sorun',\n defaultInputPlaceholder: 'Bir soru sorun...',\n sendButton: 'Sor',\n sendQuestionAriaLabel: 'Soruyu gönder',\n defaultCtaText: 'Başka bir şey sor',\n redirectingToChat: 'Sohbete yönlendiriliyor...',\n productContextQuickPillLabel: 'Bu ürün hakkında ne bilmeliyim?',\n};\n","import type { QNAI18n } from '../types.js';\n\nexport const QNA_I18N_EN: QNAI18n = {\n quickQuestionsAriaLabel: 'Quick questions',\n askQuestionAriaLabel: 'Ask a question',\n defaultInputPlaceholder: 'Ask a question...',\n sendButton: 'Ask',\n sendQuestionAriaLabel: 'Send question',\n defaultCtaText: 'Ask something else',\n redirectingToChat: 'Redirecting to chat...',\n productContextQuickPillLabel: 'What should I know about this product?',\n};\n","import type { QNAI18n } from '../types.js';\nimport { QNA_I18N_TR } from './tr.js';\nimport { QNA_I18N_EN } from './en.js';\n\nfunction normalizeLocale(locale?: string): string {\n if (!locale) return 'tr';\n return locale.toLowerCase().split('-')[0] ?? 'tr';\n}\n\nexport function resolveQnaLocale(locale?: string): QNAI18n {\n switch (normalizeLocale(locale)) {\n case 'en':\n return QNA_I18N_EN;\n default:\n return QNA_I18N_TR;\n }\n}\n\nexport { QNA_I18N_TR, QNA_I18N_EN };\n","/**\n * QNA widget — json-render catalog definition.\n *\n * Backend endpoint: POST /chat/launcher_action\n * Response format: NDJSON stream, each line a StreamEvent.\n *\n * The backend returns a `ui_spec` event whose elements are typed to the\n * component names defined below. The frontend renders them via ./registry.\n *\n * Customising:\n * Fork this repo and replace ./registry implementations with your own.\n * The catalog schema (component names + prop types) is the API contract\n * with the backend — do not rename components without a backend release.\n */\n\nimport { z } from 'zod';\n\nconst ActionPayloadSchema = z.object({\n title: z.string(),\n type: z.string(),\n payload: z.unknown().optional(),\n});\n\nexport const ActionButtonSchema = z.object({\n label: z.string(),\n action: ActionPayloadSchema,\n variant: z.enum(['primary', 'outline', 'ghost']).optional(),\n});\n\nexport const ButtonRowSchema = z.object({\n orientation: z.enum(['horizontal', 'vertical']).optional(),\n wrap: z.boolean().optional(),\n});\n\nexport const TextInputSchema = z.object({\n placeholder: z.union([z.string(), z.array(z.string())]).optional(),\n ctaLabel: z.string().optional(),\n});\n\nexport const QuestionHeadingSchema = z.object({\n text: z.string(),\n});\n\nexport const qnaCatalog = {\n components: {\n ActionButton: {\n schema: ActionButtonSchema,\n description: 'A single clickable QNA action button.',\n },\n ButtonRow: {\n schema: ButtonRowSchema,\n description: 'Container for a group of QNA action buttons.',\n },\n TextInput: {\n schema: TextInputSchema,\n description: 'Free-text input with rotating placeholder and CTA button.',\n },\n QuestionHeading: {\n schema: QuestionHeadingSchema,\n description: 'A heading displayed above the QNA button group.',\n },\n },\n} as const;\n\nexport type QNACatalog = typeof qnaCatalog;\nexport type QNAComponentName = keyof QNACatalog['components'];\n","/**\n * QNA widget -- public entry point.\n *\n * Renders contextual action buttons (and an optional free-text input) on\n * product or content pages. When a user taps a button, the widget opens\n * the Chat widget with that action pre-loaded.\n *\n * Backend: POST /chat/launcher_action\n * Protocol: NDJSON stream -> json-render UISpec -> ActionButton / ButtonRow / TextInput\n */\n\nimport type { ActionPayload, PageContext, UISpec, UIElement } from '../common/types.js';\nimport type { ChatTransportConfig } from '../common/api-paths.js';\nimport type { UISpecRenderHelpers } from '../common/renderer/index.js';\nimport { mergeUISpecRegistry } from '../common/renderer/index.js';\nimport { BaseWidget } from '../common/widget-base.js';\nimport { dispatch } from '../common/events.js';\nimport { trackConnectionWarningRequest } from '../common/connection-warning.js';\nimport { getGlobalErrorMessage } from '../common/global-error-toast.js';\nimport {\n streamStartEvent,\n streamDoneEvent,\n streamErrorEvent,\n widgetHistorySnapshotEvent,\n} from '../common/analytics-events.js';\nimport { fetchLauncherActions } from './api.js';\nimport * as ga from '../common/ga-datalayer.js';\nimport {\n createDefaultQnaUISpecRegistry,\n defaultQnaUnknownUISpecRenderer,\n renderQnaUISpec,\n} from './components/renderUISpec.js';\nimport { mergeStandaloneFindSimilarIntoQuickPills, resolveQnaSkuListForPayload } from './normalize-ui-specs.js';\nimport type { QNAWidgetConfig, QNAI18n, QNAUISpecRenderContext } from './types.js';\nimport { QNA_I18N_TR, resolveQnaLocale } from './locales/index.js';\n\n// Inline CSS import marker - Vite will bundle this\nimport './components/qna.css';\n\n/**\n * Contextual Q&A action buttons for product pages.\n * Renders quick-action buttons that open the chat widget with a pre-built query.\n *\n * @example\n * ```ts\n * import { GengageQNA, wireQNAToChat, bootstrapSession } from '@gengage/assistant-fe';\n *\n * const qna = new GengageQNA();\n * await qna.init({\n * accountId: 'mystore',\n * middlewareUrl: 'https://chat.gengage.ai',\n * mountTarget: '#qna-section',\n * pageContext: { pageType: 'pdp', sku: '12345' },\n * session: { sessionId: bootstrapSession() },\n * });\n * wireQNAToChat(); // Wire button clicks to chat.openWithAction()\n * ```\n */\nexport class GengageQNA extends BaseWidget<QNAWidgetConfig> {\n private _abortController: AbortController | null = null;\n private _debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private _contentEl: HTMLElement | null = null;\n private _lastSku: string | undefined;\n private _i18n: QNAI18n = QNA_I18N_TR;\n\n protected async onInit(config: QNAWidgetConfig): Promise<void> {\n this._i18n = this._resolveI18n(config);\n\n this._contentEl = document.createElement('div');\n this._contentEl.className = 'gengage-qna-container';\n this._contentEl.dataset['gengagePart'] = 'qna-container';\n this.root.appendChild(this._contentEl);\n\n const sku = config.pageContext?.sku;\n if (sku) {\n this._lastSku = sku;\n await this._fetchAndRender(sku);\n }\n\n ga.trackInit('qna');\n }\n\n protected onUpdate(context: Partial<PageContext>): void {\n const newSku = context.sku;\n if (!newSku || newSku === this._lastSku) return;\n\n // Debounce rapid SPA navigations\n if (this._debounceTimer) clearTimeout(this._debounceTimer);\n this._debounceTimer = setTimeout(() => {\n this._debounceTimer = null;\n this._lastSku = newSku;\n void this._fetchAndRender(newSku);\n }, 50);\n }\n\n protected onShow(): void {\n if (this._contentEl) {\n this._contentEl.style.opacity = '0';\n this._contentEl.style.transition = 'opacity 0.2s ease-in';\n requestAnimationFrame(() => {\n if (this._contentEl) this._contentEl.style.opacity = '1';\n });\n }\n }\n\n protected onHide(): void {\n // Preserve fetched data for re-show\n }\n\n protected onDestroy(): void {\n this._abort();\n if (this._debounceTimer) {\n clearTimeout(this._debounceTimer);\n this._debounceTimer = null;\n }\n if (this._contentEl) {\n this._cleanupTextInputTimers();\n this._contentEl.remove();\n this._contentEl = null;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Internal\n // ---------------------------------------------------------------------------\n\n private _abort(): void {\n this._abortController?.abort();\n this._abortController = null;\n }\n\n /** Clean up TextInput placeholder rotation timers to prevent interval leaks. */\n private _cleanupTextInputTimers(): void {\n if (!this._contentEl) return;\n const wrappers = this._contentEl.querySelectorAll('.gengage-qna-input-wrapper');\n for (const wrapper of wrappers) {\n (wrapper as HTMLElement & { _cleanup?: () => void })._cleanup?.();\n }\n }\n\n private async _fetchAndRender(sku: string): Promise<void> {\n this._abort();\n this._abortController = new AbortController();\n\n if (!this._contentEl) return;\n // Clean up TextInput timers before clearing DOM to prevent interval leaks\n this._cleanupTextInputTimers();\n this._contentEl.innerHTML = '';\n\n // Show loading dots\n const loading = this._createLoadingIndicator();\n this._contentEl.appendChild(loading);\n\n const transport: ChatTransportConfig = {\n middlewareUrl: this.config.middlewareUrl,\n };\n\n const requestId = crypto.randomUUID();\n const fetchStart = Date.now();\n const releaseConnectionWarning = trackConnectionWarningRequest({\n source: 'qna',\n locale: this.config.locale,\n });\n\n this.track(\n streamStartEvent(this.analyticsContext(), {\n endpoint: 'launcher_action',\n request_id: requestId,\n widget: 'qna',\n }),\n );\n\n try {\n const launcherReq: import('./api.js').LauncherActionRequest = {\n account_id: this.config.accountId,\n session_id: this.config.session?.sessionId ?? '',\n correlation_id: this.config.session?.sessionId ?? '',\n sku,\n locale: this.config.locale ?? 'tr',\n };\n const pageType = this.config.pageContext?.pageType;\n if (pageType !== undefined) launcherReq.page_type = pageType;\n\n const result = await fetchLauncherActions(launcherReq, transport, this._abortController.signal);\n\n this.track(\n streamDoneEvent(this.analyticsContext(), {\n request_id: requestId,\n latency_ms: Date.now() - fetchStart,\n chunk_count: result.actions.length,\n widget: 'qna',\n }),\n );\n\n this.track(\n widgetHistorySnapshotEvent(this.analyticsContext(), {\n message_count: result.actions.length,\n history_ref: requestId,\n redaction_level: 'none',\n widget: 'qna',\n }),\n );\n\n if (!this._contentEl) return;\n this._contentEl.innerHTML = '';\n\n const panel = document.createElement('div');\n panel.className = 'gengage-qna-panel gds-panel';\n panel.dataset['gengagePart'] = 'qna-panel';\n this._contentEl.appendChild(panel);\n\n const hasQuestionHeading = this._specIncludesType(result.uiSpecs, 'QuestionHeading');\n\n // Render heading if configured and backend didn't provide one\n if (!hasQuestionHeading && this.config.showStaticQuestion && this.config.staticQuestionText) {\n const heading = document.createElement('h3');\n heading.className = 'gengage-qna-heading';\n heading.textContent = this.config.staticQuestionText;\n panel.appendChild(heading);\n }\n\n const cfgPlaceholders = this.config.inputPlaceholder;\n let effectivePlaceholders: string | string[];\n if (cfgPlaceholders !== true) {\n effectivePlaceholders = cfgPlaceholders ?? this._i18n.defaultInputPlaceholder;\n } else if (result.actions.length > 0) {\n // Only use question-like actions as rotating placeholders\n const filtered = result.actions\n .filter((a) => a.type === 'user_message' || a.title.includes('?'))\n .map((a) => a.title);\n effectivePlaceholders = filtered.length > 0 ? filtered : this._i18n.defaultInputPlaceholder;\n } else {\n effectivePlaceholders = this._i18n.defaultInputPlaceholder;\n }\n\n const renderContext: QNAUISpecRenderContext = {\n onAction: this._actionHandler,\n i18n: this._i18n,\n };\n if (!this.config.hideButtonRowCta) {\n renderContext.onOpenChat = this._openChatHandler;\n if (this.config.ctaText !== undefined) renderContext.ctaText = this.config.ctaText;\n }\n if (effectivePlaceholders !== undefined) renderContext.inputPlaceholder = effectivePlaceholders;\n\n const fallbackSpec = this._buildFallbackActionsSpec(result.actions);\n const quickPillSkuList = resolveQnaSkuListForPayload(this.config.pageContext);\n const specsToRender =\n result.uiSpecs.length > 0\n ? mergeStandaloneFindSimilarIntoQuickPills(result.uiSpecs, this._i18n, {\n skuList: quickPillSkuList,\n })\n : [fallbackSpec];\n const nonEmptySpecs = specsToRender.filter((spec) => Object.keys(spec.elements).length > 0);\n\n for (const spec of nonEmptySpecs) {\n const rendered = this._renderUISpec(spec, renderContext);\n panel.appendChild(rendered);\n }\n\n if (nonEmptySpecs.length > 0) {\n ga.trackShow('qna');\n }\n\n const shouldRenderStandaloneInput = !this._specIncludesType(nonEmptySpecs, 'TextInput');\n if (shouldRenderStandaloneInput) {\n this._appendStandaloneInput(renderContext, effectivePlaceholders, panel);\n }\n } catch (err) {\n if (err instanceof DOMException && err.name === 'AbortError') return;\n\n dispatch('gengage:global:error', {\n source: 'qna',\n code: 'FETCH_ERROR',\n message: getGlobalErrorMessage(this.config.locale, err),\n });\n\n this.track(\n streamErrorEvent(this.analyticsContext(), {\n request_id: requestId,\n error_code: 'FETCH_ERROR',\n error_message: err instanceof Error ? err.message : String(err),\n widget: 'qna',\n }),\n );\n\n // Keep QNA usable during backend hiccups: render at least free-text input.\n if (this._contentEl) {\n this._cleanupTextInputTimers();\n this._contentEl.innerHTML = '';\n const errPanel = document.createElement('div');\n errPanel.className = 'gengage-qna-panel';\n this._contentEl.appendChild(errPanel);\n const fallbackPlaceholders =\n this.config.inputPlaceholder === true\n ? this._i18n.defaultInputPlaceholder\n : (this.config.inputPlaceholder ?? this._i18n.defaultInputPlaceholder);\n const fallbackContext: QNAUISpecRenderContext = {\n onAction: this._actionHandler,\n i18n: this._i18n,\n onOpenChat: this._openChatHandler,\n };\n if (this.config.ctaText !== undefined) fallbackContext.ctaText = this.config.ctaText;\n this._appendStandaloneInput(fallbackContext, fallbackPlaceholders, errPanel);\n }\n\n if (import.meta.env?.DEV) {\n console.error('[gengage:qna] Failed to fetch launcher actions:', err);\n }\n } finally {\n releaseConnectionWarning();\n }\n }\n\n private _createLoadingIndicator(): HTMLElement {\n const el = document.createElement('div');\n el.className = 'gengage-qna-loading';\n for (let i = 0; i < 3; i++) {\n const dot = document.createElement('div');\n dot.className = 'gengage-qna-loading-dot';\n el.appendChild(dot);\n }\n return el;\n }\n\n private _resolveI18n(config: QNAWidgetConfig): QNAI18n {\n const base = resolveQnaLocale(config.locale);\n return { ...base, ...config.i18n };\n }\n\n private _resolveUISpecRegistry() {\n const baseRegistry = createDefaultQnaUISpecRegistry();\n return mergeUISpecRegistry(baseRegistry, this.config.renderer?.registry);\n }\n\n private _renderUISpec(spec: UISpec, context: QNAUISpecRenderContext): HTMLElement {\n const registry = this._resolveUISpecRegistry();\n const unknownRenderer = this.config.renderer?.unknownRenderer ?? defaultQnaUnknownUISpecRenderer;\n const defaultRender = (inputSpec: UISpec, inputContext: QNAUISpecRenderContext) =>\n renderQnaUISpec(inputSpec, inputContext, registry, unknownRenderer);\n\n const override = this.config.renderer?.renderUISpec;\n if (!override) return defaultRender(spec, context);\n\n const helpers: UISpecRenderHelpers<QNAUISpecRenderContext> = {\n registry,\n unknownRenderer,\n defaultRender,\n };\n return override(spec, context, helpers);\n }\n\n private _specIncludesType(specs: UISpec[], type: string): boolean {\n for (const spec of specs) {\n for (const element of Object.values(spec.elements)) {\n if (element.type === type) return true;\n }\n }\n return false;\n }\n\n private _buildFallbackActionsSpec(actions: Array<{ title: string; type: string; payload?: unknown }>): UISpec {\n if (actions.length === 0) {\n return { root: 'root', elements: {} };\n }\n\n const elements: Record<string, UIElement> = {};\n const childIds: string[] = [];\n for (let i = 0; i < actions.length; i++) {\n const action = actions[i]!;\n const id = `action-${i}`;\n childIds.push(id);\n elements[id] = {\n type: 'ActionButton',\n props: {\n label: action.title,\n action: {\n title: action.title,\n type: action.type,\n payload: action.payload,\n },\n },\n };\n }\n elements['root'] = {\n type: 'ButtonRow',\n children: childIds,\n };\n return {\n root: 'root',\n elements,\n };\n }\n\n private _appendStandaloneInput(\n context: QNAUISpecRenderContext,\n placeholder?: string | string[],\n parent?: HTMLElement,\n ): void {\n if (!this._contentEl) return;\n const inputSpec: UISpec = {\n root: 'root',\n elements: {\n root: {\n type: 'TextInput',\n props: {\n placeholder,\n },\n },\n },\n };\n const renderedInput = this._renderUISpec(inputSpec, context);\n (parent ?? this._contentEl).appendChild(renderedInput);\n }\n\n private _handleAction(action: ActionPayload): void {\n this._showTransitionIndicator();\n ga.trackSuggestedQuestion(action.title, action.type);\n this.config.onActionSelected?.(action);\n // Delay the bridge dispatch so the transition indicator is visible for a\n // moment before the chat overlay takes over — without the delay both happen\n // in the same task and the indicator is never painted.\n setTimeout(() => dispatch('gengage:qna:action', action), 350);\n }\n\n private _handleOpenChat(): void {\n this._showTransitionIndicator();\n this.config.onOpenChat?.();\n // Same 350ms delay so the indicator is perceptible before chat opens.\n setTimeout(() => dispatch('gengage:qna:open-chat', {}), 350);\n }\n\n private _showTransitionIndicator(): void {\n if (!this._contentEl) return;\n // Remove any previously appended indicator to prevent duplicates on rapid clicks\n this._contentEl.querySelector('.gengage-qna-transition-indicator')?.remove();\n this._contentEl.classList.add('gengage-qna--transitioning');\n const msg = this._i18n.redirectingToChat ?? 'Redirecting to chat...';\n const indicator = document.createElement('div');\n indicator.className = 'gengage-qna-transition-indicator';\n indicator.textContent = msg;\n const panel = this._contentEl.querySelector('.gengage-qna-panel');\n (panel ?? this._contentEl).appendChild(indicator);\n setTimeout(() => {\n this._contentEl?.classList.remove('gengage-qna--transitioning');\n indicator.remove();\n }, 600);\n }\n\n _actionHandler = this._handleAction.bind(this);\n _openChatHandler = this._handleOpenChat.bind(this);\n}\n\nexport function createQNAWidget(): GengageQNA {\n return new GengageQNA();\n}\n\nexport type { QNAWidgetConfig, QNAUIComponents, QNAI18n, QNAUISpecRenderContext, QNARendererConfig } from './types.js';\nexport {\n renderQnaUISpec,\n createDefaultQnaUISpecRegistry,\n defaultQnaUnknownUISpecRenderer,\n} from './components/renderUISpec.js';\nexport type { QNAUISpecRegistry } from './components/renderUISpec.js';\nexport { qnaCatalog } from './catalog.js';\nexport type { QNACatalog, QNAComponentName } from './catalog.js';\n"],"mappings":"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"}
|