@guidelytech/sdk-core 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -3
- package/dist/index.cjs +393 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +41 -4
- package/dist/index.d.ts +41 -4
- package/dist/index.js +382 -6
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/client.ts","../src/authoring.ts","../src/storage.ts","../src/context.ts","../src/emitter.ts","../src/frequency.ts","../src/http.ts","../src/navigation.ts","../src/queue.ts"],"sourcesContent":["/**\n * @guidelytech/sdk-core — framework-independent Guidely browser SDK.\n *\n * SSR-safe to import: nothing touches `window` at module scope. Create a client in the browser\n * with {@link createGuidely} (or `Guidely.init` for script-tag installs).\n */\nimport { GuidelyClient, createGuidely } from \"./client\";\n\nexport { GuidelyClient, createGuidely, SDK_NAME, SDK_VERSION, DEFAULT_API_URL } from \"./client\";\nexport type { GuidelyOptions, GuidelyEvents, GuidelyEventName, GuidelyUser, GuidelyAccount, GuidelyEnvironment, ConsentState, ChecklistProgressState, PersistedState, SessionState, GuideStepInfo } from \"./types\";\nexport { isFrequencyEligible, isExclusiveGuide, areMutuallyExclusive, isWithinSchedule } from \"./frequency\";\nexport type { GuideLocalState } from \"./frequency\";\nexport { detectDevice, buildContext } from \"./context\";\nexport type { DeviceInfo, ContextInput } from \"./context\";\nexport { EventQueue } from \"./queue\";\nexport type { EventQueueOptions } from \"./queue\";\nexport { watchNavigation } from \"./navigation\";\nexport { createStorage, KEYS } from \"./storage\";\nexport type { KeyValueStore, StorageKind } from \"./storage\";\nexport { AUTHORING_PARAM, HEARTBEAT_MS } from \"./authoring\";\nexport type { AuthoringIncomingMessage, AuthoringOutgoingMessage } from \"./authoring\";\nexport type { PublishedGuide, SdkConfigResponse, SdkEvent, TargetingContext, GuideConfig, GuideStep } from \"@guidelytech/shared\";\n\n/** Global-style API used by the script-tag embed: `Guidely.init(options)` / `Guidely.get()`. */\nexport const Guidely = {\n init: (options: Parameters<typeof GuidelyClient.init>[0]) => GuidelyClient.init(options),\n get: () => GuidelyClient.get(),\n createGuidely,\n version: \"0.1.0\",\n};\n\nexport default Guidely;\n","import { evaluateRules, randomId, sanitizeProperties } from \"@guidelytech/shared/runtime\";\nimport {\n type ChecklistTask,\n type EventName,\n type IdentifyRequest,\n type IdentifyResponse,\n type PublishedGuide,\n type ResourceCenterArticle,\n type SdkConfigResponse,\n type SdkEvent,\n type TargetingContext,\n} from \"@guidelytech/shared\";\nimport {\n destroyHost,\n isChecklistComplete,\n renderChecklist,\n renderResourceCenter,\n renderSurvey,\n runGuide,\n urlMatches,\n waitForTarget,\n type ChecklistWidget,\n type GuideController,\n type ResourceCenterWidget,\n type SurveyWidget,\n} from \"@guidelytech/guide-runtime\";\nimport { createScope } from \"@guidelytech/guide-runtime\";\nimport { AuthoringBridge } from \"./authoring\";\nimport { buildContext } from \"./context\";\nimport { Emitter } from \"./emitter\";\nimport { areMutuallyExclusive, isExclusiveGuide, isFrequencyEligible, isWithinSchedule, type GuideLocalState } from \"./frequency\";\nimport { Api, postWithRetry } from \"./http\";\nimport { watchNavigation } from \"./navigation\";\nimport { EventQueue } from \"./queue\";\nimport { createStorage, KEYS, readJson, writeJson, type KeyValueStore } from \"./storage\";\nimport type { ChecklistProgressState, ConsentState, GuidelyAccount, GuidelyEvents, GuidelyOptions, GuidelyUser, PersistedState, SessionState } from \"./types\";\n\nexport const SDK_NAME = \"@guidelytech/sdk-core\";\nexport const SDK_VERSION = \"0.1.0\";\nexport const DEFAULT_API_URL = \"https://api.guidely.app\";\n\ntype EvalReason = \"ready\" | \"navigation\" | \"event\" | \"click\" | \"visible\" | \"identify\" | \"after_guide\" | \"timer\" | \"manual\";\ninterface EvalDetail {\n eventName?: string;\n target?: Element | null;\n guideId?: string;\n endedGuide?: PublishedGuide;\n newAudiences?: Set<string>;\n}\n\ninterface ActiveGuide {\n guide: PublishedGuide;\n controller?: GuideController;\n survey?: SurveyWidget;\n scope?: { destroy(): void };\n manual: boolean;\n startUrl: string;\n}\n\ninterface QueuedGuide {\n guide: PublishedGuide;\n url: string;\n pageScoped: boolean;\n}\n\nconst PAGE_SCOPED = new Set([\"page_load\", \"url_match\", \"element_click\", \"element_visible\", \"delay\"]);\n\nfunction isBrowser(): boolean {\n return typeof window !== \"undefined\" && typeof document !== \"undefined\";\n}\n\nfunction nowIso(): string {\n return new Date().toISOString();\n}\n\nfunction emptyState(): PersistedState {\n return { guides: {}, checklists: {}, surveysSubmitted: [], audienceIds: [] };\n}\n\n/**\n * Framework-independent Guidely client. Create one per page with {@link createGuidely} or\n * {@link GuidelyClient.init}; adapters (`@guidelytech/react`, `@guidelytech/svelte`) wrap it.\n */\nexport class GuidelyClient {\n readonly options: Readonly<Required<Pick<GuidelyOptions, \"projectId\" | \"environment\" | \"apiUrl\" | \"analytics\" | \"consent\" | \"storage\" | \"configRefreshMs\" | \"pollIntervalMs\" | \"debug\">>> & GuidelyOptions;\n private readonly api: Api;\n private readonly store: KeyValueStore;\n private readonly sessionStore: KeyValueStore;\n private readonly emitter: Emitter<GuidelyEvents>;\n private readonly queue: EventQueue;\n private config: SdkConfigResponse | null = null;\n private etag: string | null = null;\n private anonymousId: string;\n private user: GuidelyUser | null = null;\n private state: PersistedState;\n private session: SessionState;\n private consent: ConsentState;\n private readyPromise: Promise<void> | null = null;\n private resolveReady: (() => void) | null = null;\n private isReady = false;\n private destroyed = false;\n private active: ActiveGuide | null = null;\n private queued: QueuedGuide[] = [];\n private widgets = new Map<string, { destroy(): void; checklist?: ChecklistWidget; scope?: { destroy(): void }; controller?: GuideController }>();\n private resourceCenter: ResourceCenterWidget | null = null;\n private resourceCenterScope: { destroy(): void } | null = null;\n private cleanups: Array<() => void> = [];\n private timers = new Set<ReturnType<typeof setTimeout>>();\n private visibilityObservers = new Map<string, () => void>();\n private firedDelays = new Set<string>();\n private firstVisit: boolean;\n private lastUrl: string;\n private authoring: AuthoringBridge | null = null;\n private lastAudiences = new Set<string>();\n\n constructor(options: GuidelyOptions) {\n if (!isBrowser()) throw new Error(\"[Guidely] createGuidely() must be called in the browser. Create the client inside useEffect / onMount, or use the framework adapters.\");\n if (!options || !options.projectId) throw new Error(\"[Guidely] `projectId` (your environment public key, e.g. pk_dev_…) is required.\");\n this.options = {\n ...options,\n environment: options.environment ?? (options.projectId.startsWith(\"pk_prod\") ? \"production\" : options.projectId.startsWith(\"pk_stag\") ? \"staging\" : \"development\"),\n apiUrl: options.apiUrl ?? DEFAULT_API_URL,\n analytics: options.analytics ?? true,\n consent: options.consent ?? \"granted\",\n storage: options.storage ?? \"local\",\n configRefreshMs: options.configRefreshMs ?? 5 * 60 * 1000,\n pollIntervalMs: options.pollIntervalMs ?? 1000,\n debug: options.debug ?? false,\n };\n this.consent = this.options.consent;\n this.emitter = new Emitter<GuidelyEvents>((err) => this.reportError(err));\n this.api = new Api(this.options.apiUrl, this.options.projectId, options.fetch);\n this.store = createStorage(this.options.storage);\n this.sessionStore = this.options.storage === \"memory\" ? this.store : createStorage(\"session\");\n this.anonymousId = this.store.get(KEYS.anon) || \"\";\n if (!this.anonymousId) {\n this.anonymousId = `anon_${randomId(20)}`;\n this.store.set(KEYS.anon, this.anonymousId);\n }\n this.firstVisit = !this.store.get(KEYS.seen);\n this.store.set(KEYS.seen, nowIso());\n this.state = { ...emptyState(), ...readJson<Partial<PersistedState>>(this.store, KEYS.state(this.options.projectId), {}) };\n this.user = readJson<GuidelyUser | null>(this.store, KEYS.user(this.options.projectId), null);\n const session = readJson<SessionState | null>(this.sessionStore, KEYS.session, null);\n this.session = session && session.id ? session : { id: `s_${randomId(16)}`, startedAt: nowIso(), shownGuides: [], events: [] };\n this.persistSession();\n this.lastUrl = location.href;\n this.lastAudiences = new Set(this.state.audienceIds);\n this.queue = new EventQueue({\n store: this.store,\n storageKey: KEYS.queue(this.options.projectId),\n enabled: () => this.analyticsEnabled(),\n send: async (events) => {\n const res = await this.api.post<{ accepted: number }>(\"/events\", { events, sentAt: nowIso(), sdk: { name: SDK_NAME, version: SDK_VERSION } }, { keepalive: true });\n return { ok: res.ok, retry: !(res.status >= 400 && res.status < 500 && res.status !== 429) };\n },\n beacon: (events) => this.api.beacon(\"/events\", { events, sentAt: nowIso(), sdk: { name: SDK_NAME, version: SDK_VERSION } }),\n onError: (err) => this.reportError(err),\n });\n if (options.user) this.user = { ...options.user };\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n /** Loads config (cache first, then network), wires listeners and evaluates triggers. Idempotent. */\n init(): Promise<void> {\n if (this.readyPromise) return this.readyPromise;\n this.readyPromise = new Promise<void>((resolve) => {\n this.resolveReady = resolve;\n });\n void this.bootstrap();\n return this.readyPromise;\n }\n\n /** Resolves once the client is ready (alias of `init()`). */\n ready(): Promise<void> {\n return this.init();\n }\n\n private async bootstrap(): Promise<void> {\n try {\n const cached = readJson<SdkConfigResponse | null>(this.store, KEYS.config(this.options.projectId), null);\n this.etag = this.store.get(KEYS.etag(this.options.projectId));\n if (cached && cached.guides) this.config = cached;\n await this.fetchConfig();\n if (this.destroyed) return;\n this.wireListeners();\n if (this.options.user) await this.identify(this.options.user.id, this.options.user.traits, this.options.user.account);\n else if (this.user?.id) await this.identify(this.user.id, this.user.traits, this.user.account);\n if (this.destroyed) return;\n this.isReady = true;\n if (this.config) this.emitter.emit(\"ready\", this.config);\n this.resolveReady?.();\n this.renderPersistentWidgets();\n this.resumeActiveGuide();\n this.evaluate(\"ready\");\n if (!this.options.disableAuthoring) this.maybeStartAuthoring();\n } catch (err) {\n this.reportError(err);\n this.isReady = true;\n this.resolveReady?.();\n }\n }\n\n private async fetchConfig(): Promise<boolean> {\n try {\n const res = await this.api.get<SdkConfigResponse>(\"/config\", { etag: this.etag });\n if (res.status === 304) return true;\n if (res.ok && res.data && Array.isArray(res.data.guides)) {\n this.config = res.data;\n this.etag = res.etag;\n writeJson(this.store, KEYS.config(this.options.projectId), res.data);\n if (res.etag) this.store.set(KEYS.etag(this.options.projectId), res.etag);\n else this.store.remove(KEYS.etag(this.options.projectId));\n this.emitter.emit(\"config\", res.data);\n this.log(\"config loaded\", res.data.configVersion, `${res.data.guides.length} guides`);\n return true;\n }\n this.reportError(new Error(`[Guidely] config request failed (${res.status})${this.config ? \"; using cached config\" : \"\"}`));\n return false;\n } catch (err) {\n this.reportError(new Error(`[Guidely] config request failed: ${err instanceof Error ? err.message : String(err)}${this.config ? \"; using cached config\" : \"\"}`));\n return false;\n }\n }\n\n private wireListeners(): void {\n const doc = document;\n const win = window;\n this.cleanups.push(watchNavigation((url) => this.handleNavigation(url)));\n const onClick = (e: Event) => this.handleDocumentClick(e);\n doc.addEventListener(\"click\", onClick, true);\n this.cleanups.push(() => doc.removeEventListener(\"click\", onClick, true));\n const onHide = () => {\n if (doc.visibilityState === \"hidden\") this.queue.flushSync();\n };\n doc.addEventListener(\"visibilitychange\", onHide);\n win.addEventListener(\"pagehide\", onHide);\n this.cleanups.push(() => {\n doc.removeEventListener(\"visibilitychange\", onHide);\n win.removeEventListener(\"pagehide\", onHide);\n });\n const refresh = setInterval(() => void this.refresh(), this.options.configRefreshMs);\n this.cleanups.push(() => clearInterval(refresh));\n // Idle re-check: DOM can change without navigation (lazy content), so re-arm element-visibility\n // observers for eligible guides and drain the queue.\n const poll = setInterval(() => {\n if (!this.isReady || !this.config || this.authoring?.isActive() || doc.visibilityState === \"hidden\") return;\n const url = location.href;\n const ctx = this.getContext();\n for (const guide of this.config.guides) {\n if (guide.config.trigger.type === \"element_visible\" && guide.config.trigger.value) this.armVisibility(guide, ctx, url);\n }\n this.drainQueue(url, ctx);\n }, Math.max(250, this.options.pollIntervalMs));\n this.cleanups.push(() => clearInterval(poll));\n const onMessage = (e: MessageEvent) => this.authoring?.handleMessage(e);\n win.addEventListener(\"message\", onMessage);\n this.cleanups.push(() => win.removeEventListener(\"message\", onMessage));\n }\n\n /** Re-fetches the published config and re-evaluates triggers. */\n async refresh(): Promise<void> {\n if (this.destroyed) return;\n const before = this.config?.configVersion;\n await this.fetchConfig();\n if (this.config && this.config.configVersion !== before) {\n this.renderPersistentWidgets();\n this.evaluate(\"ready\");\n }\n }\n\n /** Tears everything down: guides, widgets, listeners, timers, host element. Re-init is allowed via a new client. */\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.active?.controller?.destroy();\n this.active?.survey?.destroy();\n this.active?.scope?.destroy();\n this.active = null;\n this.queued = [];\n this.widgets.forEach((w) => w.destroy());\n this.widgets.clear();\n this.resourceCenter?.destroy();\n this.resourceCenterScope?.destroy();\n this.resourceCenter = null;\n this.visibilityObservers.forEach((stop) => stop());\n this.visibilityObservers.clear();\n this.timers.forEach((t) => clearTimeout(t));\n this.timers.clear();\n this.cleanups.splice(0).forEach((fn) => fn());\n this.authoring?.stop();\n this.authoring = null;\n this.queue.flushSync();\n this.queue.destroy();\n this.emitter.clear();\n destroyHost();\n if (current === this) current = null;\n }\n\n // ---------------------------------------------------------------------------\n // Identity\n // ---------------------------------------------------------------------------\n\n /** Identifies the end user and loads server-held state (audiences, guide history, checklist progress). */\n async identify(userId: string, traits?: Record<string, unknown>, account?: GuidelyAccount): Promise<void> {\n if (this.destroyed) return;\n this.user = { id: String(userId), traits: { ...(this.user?.id === String(userId) ? this.user.traits : {}), ...(traits || {}) }, account: account ?? (this.user?.id === String(userId) ? this.user.account : undefined) };\n writeJson(this.store, KEYS.user(this.options.projectId), this.user);\n this.enqueue(\"identify\", { properties: { traits: sanitizeProperties(this.user.traits) } });\n await this.syncIdentify();\n this.emitter.emit(\"identify\", { userId: this.user.id, anonymousId: this.anonymousId });\n if (this.isReady) this.evaluate(\"identify\");\n }\n\n private async syncIdentify(): Promise<void> {\n const body: IdentifyRequest = { anonymousId: this.anonymousId, userId: this.user?.id ?? null, traits: this.user?.traits, account: this.user?.account ? { id: this.user.account.id, traits: this.user.account.traits } : null, sessionId: this.session.id, url: this.collectUrls() ? location.href : undefined };\n const res = await postWithRetry<IdentifyResponse>(this.api, \"/identify\", body, 2);\n if (res?.ok && res.data) this.mergeServerState(res.data);\n }\n\n private mergeServerState(data: IdentifyResponse): void {\n const guides = { ...this.state.guides };\n for (const [id, s] of Object.entries(data.guideState || {})) {\n const local = guides[id];\n guides[id] = {\n impressions: Math.max(local?.impressions ?? 0, s.impressions ?? 0),\n completedAt: local?.completedAt ?? s.completedAt ?? null,\n dismissedAt: local?.dismissedAt ?? s.dismissedAt ?? null,\n lastShownAt: local?.lastShownAt ?? s.lastShownAt ?? null,\n };\n }\n const checklists = { ...this.state.checklists };\n for (const [id, p] of Object.entries(data.checklistProgress || {})) {\n const local = checklists[id];\n checklists[id] = {\n completedTaskIds: Array.from(new Set([...(local?.completedTaskIds ?? []), ...(p.completedTaskIds ?? [])])),\n completedAt: local?.completedAt ?? p.completedAt ?? null,\n dismissedAt: local?.dismissedAt ?? p.dismissedAt ?? null,\n };\n }\n this.state = {\n guides,\n checklists,\n surveysSubmitted: Array.from(new Set([...this.state.surveysSubmitted, ...(data.surveysSubmitted || [])])),\n audienceIds: data.audienceIds || [],\n firstSeenAt: this.state.firstSeenAt ?? data.firstSeenAt,\n };\n if (data.firstSeenAt && Date.now() - Date.parse(data.firstSeenAt) > 60_000) this.firstVisit = false;\n this.persistState();\n this.widgets.forEach((w, id) => {\n const g = this.findGuide(id);\n if (w.checklist && g) w.checklist.setProgress(this.getChecklistProgress(g.id));\n });\n }\n\n /** Sets or replaces the account (company/organisation) for the current user. */\n async setAccount(account: GuidelyAccount): Promise<void> {\n if (!this.user) {\n this.user = { id: \"\", account };\n writeJson(this.store, KEYS.user(this.options.projectId), this.user);\n return;\n }\n await this.identify(this.user.id, undefined, account);\n }\n\n /** Merges additional traits into the current user. */\n async updateTraits(traits: Record<string, unknown>): Promise<void> {\n if (!this.user?.id) {\n this.user = { id: \"\", traits: { ...(this.user?.traits || {}), ...traits } };\n return;\n }\n await this.identify(this.user.id, traits, this.user.account);\n }\n\n /** Forgets the user: new anonymous id, cleared local guide/checklist state, triggers re-evaluated. */\n reset(): void {\n this.stopGuide();\n this.user = null;\n this.store.remove(KEYS.user(this.options.projectId));\n this.anonymousId = `anon_${randomId(20)}`;\n this.store.set(KEYS.anon, this.anonymousId);\n this.state = emptyState();\n this.persistState();\n this.session = { id: `s_${randomId(16)}`, startedAt: nowIso(), shownGuides: [], events: [] };\n this.persistSession();\n this.sessionStore.remove(KEYS.active);\n this.lastAudiences = new Set();\n this.firedDelays.clear();\n this.widgets.forEach((w) => w.destroy());\n this.widgets.clear();\n this.emitter.emit(\"identify\", { userId: null, anonymousId: this.anonymousId });\n if (this.isReady) {\n this.renderPersistentWidgets();\n this.evaluate(\"identify\");\n }\n }\n\n // ---------------------------------------------------------------------------\n // Events\n // ---------------------------------------------------------------------------\n\n /** Updates consent at runtime (`granted` flushes buffered events; `denied` drops them). */\n setConsent(consent: ConsentState): void {\n this.consent = consent;\n if (consent === \"denied\") this.queue.clear();\n else if (consent === \"granted\") void this.queue.flush();\n }\n\n private analyticsEnabled(): boolean {\n return this.options.analytics && this.consent === \"granted\" && (this.config?.settings?.analyticsEnabled ?? true);\n }\n\n private collectUrls(): boolean {\n return this.config?.settings?.collectUrls ?? true;\n }\n\n private enqueue(name: EventName, extra: Partial<SdkEvent> = {}): SdkEvent | null {\n if (this.consent === \"denied\" || !this.options.analytics) return null;\n const event: SdkEvent = {\n eventId: randomId(24),\n name,\n occurredAt: nowIso(),\n anonymousId: this.anonymousId,\n userId: this.user?.id || null,\n accountId: this.user?.account?.id || null,\n sessionId: this.session.id,\n url: this.collectUrls() ? location.href : undefined,\n ...extra,\n };\n if (extra.properties) event.properties = sanitizeProperties(extra.properties);\n this.queue.enqueue(event);\n this.emitter.emit(\"track\", event);\n return event;\n }\n\n /** Tracks a custom event. Events drive `event` triggers, `advanceOn: \"event\"` steps and checklist tasks. */\n track(name: string, properties?: Record<string, unknown>): void {\n if (this.destroyed || !name) return;\n if (!this.session.events.includes(name)) {\n this.session.events.push(name);\n this.persistSession();\n }\n this.enqueue(\"custom\", { customName: name.slice(0, 120), properties: properties ?? {} });\n this.customListeners.get(name)?.forEach((cb) => {\n try {\n cb();\n } catch (err) {\n this.reportError(err);\n }\n });\n this.completeChecklistTasksBy(\"event\", name);\n if (this.isReady) this.evaluate(\"event\", { eventName: name });\n }\n\n /** Records a page view and re-evaluates triggers. Called automatically on SPA navigation. */\n page(url: string = location.href): void {\n if (this.destroyed) return;\n this.enqueue(\"page_view\", { properties: { path: safePath(url) } });\n this.handleNavigation(url, true);\n }\n\n private readonly customListeners = new Map<string, Set<() => void>>();\n private readonly eventBus = {\n on: (name: string, cb: () => void) => {\n let set = this.customListeners.get(name);\n if (!set) {\n set = new Set();\n this.customListeners.set(name, set);\n }\n set.add(cb);\n return () => {\n set?.delete(cb);\n };\n },\n };\n\n private handleNavigation(url: string, explicit = false): void {\n if (this.destroyed) return;\n const changed = url !== this.lastUrl;\n this.lastUrl = url;\n if (!explicit && changed) this.enqueue(\"page_view\", { properties: { path: safePath(url) } });\n this.completeChecklistTasksBy(\"url_visited\", url);\n this.active?.controller?.resume();\n if (this.active?.controller) {\n const st = this.active.controller.getState();\n if (st.status === \"running\" && !this.active.manual) {\n const g = this.active.guide;\n if (g.config.urlPatterns.length && !g.config.urlPatterns.some((p) => urlMatches(p, url))) this.active.controller.destroy();\n }\n }\n this.firedDelays.clear();\n if (this.isReady) this.evaluate(\"navigation\");\n if (changed) void this.queue.flush();\n }\n\n private handleDocumentClick(e: Event): void {\n const target = e.target as Element | null;\n if (!target || typeof target.closest !== \"function\") return;\n this.completeChecklistTasksBy(\"click\", target);\n if (this.isReady) this.evaluate(\"click\", { target });\n }\n\n // ---------------------------------------------------------------------------\n // Targeting + triggers\n // ---------------------------------------------------------------------------\n\n /** Builds the targeting context for the current moment. */\n getContext(): TargetingContext {\n const guides = this.state.guides;\n const completedChecklists = Object.entries(this.state.checklists).filter(([, p]) => !!p.completedAt).map(([id]) => id);\n const keysOf = (ids: string[]) => ids.flatMap((id) => [id, this.findGuide(id)?.key ?? id]);\n return buildContext({\n anonymousId: this.anonymousId,\n userId: this.user?.id || null,\n userAttributes: this.user?.traits ?? {},\n accountAttributes: this.user?.account?.traits ?? {},\n url: location.href,\n firstVisit: this.firstVisit,\n eventsSeen: this.session.events,\n completedGuides: keysOf(Object.keys(guides).filter((id) => guides[id]?.completedAt)),\n dismissedGuides: keysOf(Object.keys(guides).filter((id) => guides[id]?.dismissedAt)),\n seenGuides: keysOf(Object.keys(guides).filter((id) => (guides[id]?.impressions ?? 0) > 0)),\n completedChecklists: keysOf(completedChecklists),\n audienceIds: this.state.audienceIds,\n environment: this.options.environment,\n });\n }\n\n private isTargeted(guide: PublishedGuide, ctx: TargetingContext, url: string): boolean {\n const c = guide.config;\n if (c.urlPatterns.length && !c.urlPatterns.some((p) => urlMatches(p, url))) return false;\n if (c.trigger.urlPattern && !urlMatches(c.trigger.urlPattern, url)) return false;\n if (!isWithinSchedule(guide)) return false;\n if (guide.kind === \"survey\" && (this.state.surveysSubmitted.includes(guide.id) || this.state.surveysSubmitted.includes(guide.key))) return false;\n ctx.rolloutSalt = guide.id;\n return evaluateRules(c.targeting, ctx);\n }\n\n private isEligible(guide: PublishedGuide, ctx: TargetingContext, url: string): boolean {\n if (!this.isTargeted(guide, ctx, url)) return false;\n const shownThisSession = this.session.shownGuides.includes(guide.id);\n if (guide.kind === \"checklist\") {\n const p = this.state.checklists[guide.id];\n return !p?.dismissedAt;\n }\n return isFrequencyEligible(guide.config.frequency, this.state.guides[guide.id], shownThisSession);\n }\n\n private triggerFires(guide: PublishedGuide, reason: EvalReason, detail: EvalDetail): boolean {\n const t = guide.config.trigger;\n switch (t.type) {\n case \"page_load\":\n return reason === \"ready\" || reason === \"navigation\" || reason === \"identify\";\n case \"url_match\":\n return (reason === \"ready\" || reason === \"navigation\" || reason === \"identify\") && urlMatches(t.value, location.href);\n case \"event\":\n return reason === \"event\" && !!t.value && detail.eventName === t.value;\n case \"element_click\":\n if (reason !== \"click\" || !t.value || !detail.target) return false;\n try {\n return !!detail.target.closest(t.value);\n } catch {\n return false;\n }\n case \"element_visible\":\n return reason === \"visible\" && detail.guideId === guide.id;\n case \"delay\":\n return reason === \"timer\" && detail.guideId === guide.id;\n case \"after_guide\":\n return reason === \"after_guide\" && !!detail.endedGuide && (detail.endedGuide.id === t.value || detail.endedGuide.key === t.value);\n case \"segment_enter\":\n return reason === \"identify\" && !!t.value && !!detail.newAudiences?.has(t.value);\n case \"manual\":\n default:\n return false;\n }\n }\n\n private evaluate(reason: EvalReason, detail: EvalDetail = {}): void {\n if (!this.config || this.destroyed || this.authoring?.isActive()) return;\n const url = location.href;\n const ctx = this.getContext();\n if (reason === \"identify\") {\n const current = new Set(this.state.audienceIds);\n detail.newAudiences = new Set(Array.from(current).filter((a) => !this.lastAudiences.has(a)));\n this.lastAudiences = current;\n }\n const candidates: PublishedGuide[] = [];\n for (const guide of this.config.guides) {\n const t = guide.config.trigger;\n if (detail.endedGuide && detail.endedGuide.id === guide.id) continue; // never re-show the guide that just ended\n // Arm element-visibility observers and delay timers on page-level evaluations.\n if (reason === \"ready\" || reason === \"navigation\") {\n if (t.type === \"element_visible\" && t.value) this.armVisibility(guide, ctx, url);\n if ((t.type === \"delay\" || (t.type === \"page_load\" && t.delayMs > 0)) && !this.firedDelays.has(guide.id)) {\n if (!this.isEligible(guide, ctx, url)) continue;\n this.firedDelays.add(guide.id);\n this.setTimer(() => this.evaluate(\"timer\", { guideId: guide.id }), t.delayMs);\n continue;\n }\n }\n if (t.type === \"page_load\" && t.delayMs > 0 && reason !== \"timer\") continue;\n if (t.type === \"page_load\" && t.delayMs > 0 && reason === \"timer\" && detail.guideId !== guide.id) continue;\n if (!this.triggerFires(guide, reason, detail)) continue;\n if (!this.isEligible(guide, ctx, url)) continue;\n candidates.push(guide);\n }\n if (reason === \"after_guide\" || reason === \"navigation\") this.drainQueue(url, ctx);\n if (!candidates.length) return;\n candidates.sort((a, b) => a.config.frequency.priority - b.config.frequency.priority);\n for (const guide of candidates) {\n if (this.widgets.has(guide.id) || this.active?.guide.id === guide.id) continue;\n const delay = guide.config.trigger.type !== \"delay\" && guide.config.trigger.type !== \"page_load\" ? guide.config.trigger.delayMs : 0;\n if (delay > 0) {\n this.setTimer(() => this.tryShow(guide, url, false), delay);\n continue;\n }\n this.tryShow(guide, url, false);\n }\n }\n\n private armVisibility(guide: PublishedGuide, ctx: TargetingContext, url: string): void {\n const selector = guide.config.trigger.value;\n if (!selector || this.visibilityObservers.has(guide.id)) return;\n if (!this.isEligible(guide, ctx, url)) return;\n const ac = new AbortController();\n let io: IntersectionObserver | null = null;\n const stop = () => {\n ac.abort();\n io?.disconnect();\n this.visibilityObservers.delete(guide.id);\n };\n this.visibilityObservers.set(guide.id, stop);\n waitForTarget([{ kind: \"css\", value: selector }], { timeoutMs: 0, signal: ac.signal })\n .then((el) => {\n if (ac.signal.aborted) return;\n const fire = () => {\n stop();\n this.evaluate(\"visible\", { guideId: guide.id });\n };\n if (typeof IntersectionObserver === \"undefined\") return fire();\n io = new IntersectionObserver((entries) => {\n if (entries.some((e) => e.isIntersecting)) fire();\n });\n io.observe(el);\n })\n .catch(() => stop());\n }\n\n private setTimer(fn: () => void, ms: number): void {\n const t = setTimeout(() => {\n this.timers.delete(t);\n if (!this.destroyed) fn();\n }, ms);\n this.timers.add(t);\n }\n\n /** Decides whether a guide can show now, otherwise queues it. */\n private tryShow(guide: PublishedGuide, url: string, manual: boolean): boolean {\n if (this.destroyed) return false;\n if (!isExclusiveGuide(guide)) {\n if (this.widgets.has(guide.id)) return false;\n this.show(guide, manual);\n return true;\n }\n if (this.active) {\n if (this.active.guide.id === guide.id) return false;\n if (manual) this.stopGuide();\n else {\n if (!this.queued.some((q) => q.guide.id === guide.id)) this.queued.push({ guide, url, pageScoped: PAGE_SCOPED.has(guide.config.trigger.type) });\n this.log(\"queued\", guide.key, \"behind\", this.active.guide.key);\n return false;\n }\n }\n const blocked = Array.from(this.widgets.keys()).map((id) => this.findGuide(id)).some((g) => g && areMutuallyExclusive(g, guide));\n if (blocked && !manual) {\n if (!this.queued.some((q) => q.guide.id === guide.id)) this.queued.push({ guide, url, pageScoped: true });\n return false;\n }\n this.show(guide, manual);\n return true;\n }\n\n private drainQueue(url: string, ctx: TargetingContext): void {\n if (this.active) return;\n this.queued = this.queued.filter((q) => !(q.pageScoped && q.url !== url));\n while (this.queued.length) {\n const next = this.queued.shift() as QueuedGuide;\n if (!this.isEligible(next.guide, ctx, url)) continue;\n if (this.tryShow(next.guide, url, false)) return;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Showing guides\n // ---------------------------------------------------------------------------\n\n private findGuide(idOrKey: string): PublishedGuide | undefined {\n return this.config?.guides.find((g) => g.id === idOrKey || g.key === idOrKey);\n }\n\n private guideState(id: string): GuideLocalState {\n return this.state.guides[id] ?? (this.state.guides[id] = { impressions: 0 });\n }\n\n private recordImpression(guide: PublishedGuide): void {\n const s = this.guideState(guide.id);\n s.impressions += 1;\n s.lastShownAt = nowIso();\n if (!this.session.shownGuides.includes(guide.id)) this.session.shownGuides.push(guide.id);\n this.persistState();\n this.persistSession();\n this.syncGuideState(guide.id, { impression: true });\n }\n\n private recordEnd(guide: PublishedGuide, reason: \"completed\" | \"dismissed\" | \"skipped\"): void {\n const s = this.guideState(guide.id);\n if (reason === \"completed\") s.completedAt = nowIso();\n else s.dismissedAt = nowIso();\n this.persistState();\n this.syncGuideState(guide.id, reason === \"completed\" ? { completed: true } : { dismissed: true });\n if (reason === \"completed\") this.completeChecklistTasksBy(\"guide_completed\", guide);\n }\n\n private syncGuideState(guideId: string, update: { impression?: boolean; completed?: boolean; dismissed?: boolean }): void {\n void postWithRetry(this.api, \"/guide-state\", { anonymousId: this.anonymousId, userId: this.user?.id || null, updates: [{ guideId, ...update }] });\n }\n\n private show(guide: PublishedGuide, manual: boolean, stepId?: string): void {\n try {\n if (guide.kind === \"checklist\" && guide.config.checklist) return this.showChecklist(guide);\n if (guide.kind === \"survey\" && guide.config.survey) return this.showSurvey(guide, manual);\n this.showFlow(guide, manual, stepId);\n } catch (err) {\n this.reportError(err);\n }\n }\n\n private showFlow(guide: PublishedGuide, manual: boolean, stepId?: string): void {\n if (this.authoring?.isActive()) return; // authoring mode renders previews only\n const exclusive = isExclusiveGuide(guide);\n const entry: ActiveGuide = { guide, manual, startUrl: location.href };\n const controller = runGuide(guide, {\n theme: this.theme(),\n ctx: () => this.getContext(),\n startAtStep: stepId,\n eventBus: this.eventBus,\n onError: (err) => this.reportError(err),\n onEvent: (e) => {\n const step = e.stepId ? guide.config.steps.find((s) => s.id === e.stepId) : undefined;\n this.enqueue(e.name, { guideId: guide.id, guideVersion: guide.version, stepId: e.stepId, stepIndex: e.stepIndex, properties: e.properties });\n if (e.name === \"guide_started\") {\n this.recordImpression(guide);\n this.emitter.emit(\"guide:start\", guide);\n }\n if (e.name === \"step_viewed\" && step) {\n if (exclusive) writeJson(this.sessionStore, KEYS.active, { guideId: guide.id, stepId: step.id, manual });\n this.emitter.emit(\"guide:step\", { guide, stepId: step.id, stepIndex: e.stepIndex ?? 0 });\n }\n if (e.name === \"guide_completed\") {\n this.recordEnd(guide, \"completed\");\n this.emitter.emit(\"guide:complete\", guide);\n }\n if (e.name === \"guide_dismissed\") {\n this.recordEnd(guide, \"dismissed\");\n this.emitter.emit(\"guide:dismiss\", guide);\n }\n if (e.name === \"guide_skipped\") {\n this.recordEnd(guide, \"skipped\");\n this.emitter.emit(\"guide:skip\", guide);\n }\n },\n onNavigate: (url, newTab) => this.navigate(url, newTab),\n onAction: (action, value) => {\n if (action === \"start_guide\" && value) this.setTimer(() => this.startGuide(value), 0);\n else if (action === \"event\" && value) this.track(value);\n else if (action === \"open_resource_center\") this.openResourceCenter();\n },\n onEnd: (reason) => {\n if (exclusive) {\n if (this.active?.controller === controller) this.active = null;\n this.sessionStore.remove(KEYS.active);\n } else this.widgets.delete(guide.id);\n if (reason !== \"destroyed\" && !this.destroyed) this.setTimer(() => this.evaluate(\"after_guide\", { endedGuide: guide }), 0);\n },\n });\n entry.controller = controller;\n if (exclusive) this.active = entry;\n else this.widgets.set(guide.id, { destroy: () => controller.destroy(), controller });\n controller.start();\n if (controller.getState().status === \"ended\") {\n if (exclusive && this.active === entry) this.active = null;\n this.widgets.delete(guide.id);\n }\n }\n\n private showChecklist(guide: PublishedGuide): void {\n if (this.authoring?.isActive()) return; // authoring mode renders previews only\n const config = guide.config.checklist;\n if (!config || this.widgets.has(guide.id)) return;\n const scope = createScope(this.theme(), guide.config.appearance);\n const progress = this.getChecklistProgress(guide.id);\n const first = !this.state.guides[guide.id]?.impressions;\n const widget = renderChecklist({\n scope: scope.el,\n config,\n progress,\n open: config.autoOpen && first && !progress.completedAt,\n onTaskClick: (task) => this.handleChecklistTaskClick(guide, task),\n onDismiss: () => this.dismissChecklist(guide),\n onOpen: () => this.enqueue(\"guide_viewed\", { guideId: guide.id, guideVersion: guide.version }),\n });\n this.widgets.set(guide.id, { destroy: () => { widget.destroy(); scope.destroy(); }, checklist: widget, scope });\n if (first) this.recordImpression(guide);\n }\n\n private showSurvey(guide: PublishedGuide, manual: boolean): void {\n if (this.authoring?.isActive()) return; // authoring mode renders previews only\n const config = guide.config.survey;\n if (!config) return;\n const scope = createScope(this.theme(), guide.config.appearance);\n const entry: ActiveGuide = { guide, manual, startUrl: location.href, scope };\n const finish = (reason: \"submitted\" | \"dismissed\") => {\n widget.destroy();\n scope.destroy();\n if (this.active === entry) this.active = null;\n if (reason === \"dismissed\") {\n this.enqueue(\"survey_dismissed\", { guideId: guide.id, guideVersion: guide.version });\n this.recordEnd(guide, \"dismissed\");\n this.emitter.emit(\"guide:dismiss\", guide);\n }\n this.setTimer(() => this.evaluate(\"after_guide\", { endedGuide: guide }), 0);\n };\n const widget = renderSurvey({\n scope: scope.el,\n config,\n title: guide.name,\n onDismiss: () => finish(this.state.surveysSubmitted.includes(guide.id) ? \"submitted\" : \"dismissed\"),\n onSubmit: (answers) => {\n const responseId = randomId(24);\n this.state.surveysSubmitted.push(guide.id);\n this.persistState();\n this.recordEnd(guide, \"completed\");\n this.enqueue(\"survey_submitted\", { guideId: guide.id, guideVersion: guide.version, properties: { responseId } });\n void postWithRetry(this.api, `/surveys/${encodeURIComponent(guide.id)}/responses`, { anonymousId: this.anonymousId, userId: this.user?.id || null, accountId: this.user?.account?.id || null, guideVersion: guide.version, answers, responseId });\n this.emitter.emit(\"survey:submit\", { guide, answers, responseId });\n this.emitter.emit(\"guide:complete\", guide);\n widget.showThankYou();\n },\n });\n entry.survey = widget;\n this.active = entry;\n this.recordImpression(guide);\n this.enqueue(\"survey_displayed\", { guideId: guide.id, guideVersion: guide.version });\n this.emitter.emit(\"guide:start\", guide);\n }\n\n private theme() {\n return { ...(this.config?.theme || {}), ...(this.options.theme || {}) };\n }\n\n private navigate(url: string, newTab?: boolean): void {\n try {\n if (newTab) window.open(url, \"_blank\", \"noopener\");\n else location.assign(url);\n } catch (err) {\n this.reportError(err);\n }\n }\n\n private renderPersistentWidgets(): void {\n if (!this.config) return;\n const rc = this.config.resourceCenter;\n if (rc && rc.enabled && !this.resourceCenter) {\n const scope = createScope(this.theme());\n this.resourceCenterScope = scope;\n this.resourceCenter = renderResourceCenter({\n scope: scope.el,\n config: rc,\n guides: this.config.guides.map((g) => ({ id: g.id, key: g.key, name: g.name, kind: g.kind })),\n search: (q) => this.searchResourceCenter(q),\n onStartGuide: (id) => this.startGuide(id),\n onOpenChecklist: (id) => this.openChecklist(id),\n onArticleView: (a) => this.enqueue(\"article_viewed\", { properties: { articleId: a.id, slug: a.slug } }),\n onOpen: () => {\n this.enqueue(\"resource_center_opened\");\n this.emitter.emit(\"resource-center:open\");\n },\n });\n } else if ((!rc || !rc.enabled) && this.resourceCenter) {\n this.resourceCenter.destroy();\n this.resourceCenterScope?.destroy();\n this.resourceCenter = null;\n }\n }\n\n private resumeActiveGuide(): void {\n const saved = readJson<{ guideId: string; stepId: string; manual?: boolean } | null>(this.sessionStore, KEYS.active, null);\n if (!saved) return;\n this.sessionStore.remove(KEYS.active);\n const guide = this.findGuide(saved.guideId);\n if (!guide || !guide.config.steps.some((s) => s.id === saved.stepId)) return;\n this.showFlow(guide, saved.manual ?? false, saved.stepId);\n }\n\n private async searchResourceCenter(q: string): Promise<ResourceCenterArticle[]> {\n try {\n const res = await this.api.get<{ articles: ResourceCenterArticle[] }>(\"/resource-center/search\", { params: { q } });\n return res.ok && res.data ? res.data.articles : [];\n } catch {\n return [];\n }\n }\n\n // ---------------------------------------------------------------------------\n // Checklists\n // ---------------------------------------------------------------------------\n\n /** Current progress for a checklist guide (by id or key). */\n getChecklistProgress(idOrKey: string): ChecklistProgressState {\n const guide = this.findGuide(idOrKey);\n const id = guide?.id ?? idOrKey;\n const p = this.state.checklists[id];\n return p ? { completedTaskIds: [...p.completedTaskIds], completedAt: p.completedAt ?? null, dismissedAt: p.dismissedAt ?? null } : { completedTaskIds: [], completedAt: null, dismissedAt: null };\n }\n\n /** Marks a checklist task complete (manual completion) and syncs progress. */\n completeChecklistTask(idOrKey: string, taskId: string): void {\n const guide = this.findGuide(idOrKey);\n if (!guide?.config.checklist) return;\n const task = guide.config.checklist.tasks.find((t) => t.id === taskId);\n if (task) this.markTaskDone(guide, task);\n }\n\n private markTaskDone(guide: PublishedGuide, task: ChecklistTask): void {\n const config = guide.config.checklist;\n if (!config) return;\n const progress = this.state.checklists[guide.id] ?? (this.state.checklists[guide.id] = { completedTaskIds: [] });\n if (progress.completedTaskIds.includes(task.id)) return;\n progress.completedTaskIds.push(task.id);\n this.enqueue(\"checklist_task_completed\", { guideId: guide.id, guideVersion: guide.version, properties: { taskId: task.id } });\n const complete = isChecklistComplete(config, progress) && !progress.completedAt;\n if (complete) {\n progress.completedAt = nowIso();\n this.enqueue(\"checklist_completed\", { guideId: guide.id, guideVersion: guide.version });\n }\n this.persistState();\n this.widgets.get(guide.id)?.checklist?.setProgress(this.getChecklistProgress(guide.id));\n void postWithRetry(this.api, `/checklists/${encodeURIComponent(guide.id)}/progress`, { anonymousId: this.anonymousId, userId: this.user?.id || null, guideVersion: guide.version, completedTaskIds: progress.completedTaskIds, completed: !!progress.completedAt });\n this.emitter.emit(\"checklist:task\", { guide, task, progress: this.getChecklistProgress(guide.id) });\n if (complete) {\n this.emitter.emit(\"checklist:complete\", guide);\n this.widgets.get(guide.id)?.checklist?.open();\n }\n }\n\n private completeChecklistTasksBy(kind: ChecklistTask[\"completion\"], value: string | Element | PublishedGuide): void {\n if (!this.config) return;\n for (const guide of this.config.guides) {\n const tasks = guide.config.checklist?.tasks;\n if (!tasks) continue;\n for (const task of tasks) {\n if (task.completion !== kind || !task.completionValue) continue;\n let hit = false;\n if (kind === \"event\") hit = value === task.completionValue;\n else if (kind === \"url_visited\") hit = urlMatches(task.completionValue, value as string);\n else if (kind === \"guide_completed\") hit = (value as PublishedGuide).id === task.completionValue || (value as PublishedGuide).key === task.completionValue;\n else if (kind === \"click\") {\n try {\n hit = !!(value as Element).closest(task.completionValue);\n } catch {\n hit = false;\n }\n }\n if (hit) this.markTaskDone(guide, task);\n }\n }\n }\n\n private handleChecklistTaskClick(guide: PublishedGuide, task: ChecklistTask): void {\n if (task.completion === \"manual\") this.markTaskDone(guide, task);\n if (task.action === \"start_guide\" && task.actionValue) this.startGuide(task.actionValue);\n else if (task.action === \"url\" && task.actionValue) this.navigate(task.actionValue);\n else if (task.action === \"event\" && task.actionValue) this.track(task.actionValue);\n }\n\n private dismissChecklist(guide: PublishedGuide): void {\n const progress = this.state.checklists[guide.id] ?? (this.state.checklists[guide.id] = { completedTaskIds: [] });\n progress.dismissedAt = nowIso();\n this.persistState();\n this.enqueue(\"checklist_dismissed\", { guideId: guide.id, guideVersion: guide.version });\n void postWithRetry(this.api, `/checklists/${encodeURIComponent(guide.id)}/progress`, { anonymousId: this.anonymousId, userId: this.user?.id || null, guideVersion: guide.version, completedTaskIds: progress.completedTaskIds, dismissed: true });\n this.widgets.get(guide.id)?.destroy();\n this.widgets.delete(guide.id);\n }\n\n /** Opens (rendering if needed) the checklist panel. */\n openChecklist(idOrKey: string): void {\n const guide = this.findGuide(idOrKey);\n if (!guide?.config.checklist) return;\n if (!this.widgets.has(guide.id)) {\n const p = this.state.checklists[guide.id];\n if (p?.dismissedAt) {\n delete p.dismissedAt;\n this.persistState();\n }\n this.showChecklist(guide);\n }\n this.widgets.get(guide.id)?.checklist?.open();\n }\n\n closeChecklist(idOrKey: string): void {\n const guide = this.findGuide(idOrKey);\n if (guide) this.widgets.get(guide.id)?.checklist?.close();\n }\n\n // ---------------------------------------------------------------------------\n // Public guide controls\n // ---------------------------------------------------------------------------\n\n /** Starts a guide by id or key, bypassing targeting and frequency rules. */\n startGuide(idOrKey: string, options: { stepId?: string } = {}): boolean {\n const guide = this.findGuide(idOrKey);\n if (!guide) {\n this.reportError(new Error(`[Guidely] startGuide: unknown guide \"${idOrKey}\"`));\n return false;\n }\n if (guide.kind === \"checklist\") {\n this.openChecklist(guide.id);\n return true;\n }\n if (this.active) this.stopGuide();\n this.widgets.get(guide.id)?.destroy();\n this.widgets.delete(guide.id);\n this.show(guide, true, options.stepId);\n return true;\n }\n\n /** Stops the active guide silently (no dismiss event). */\n stopGuide(): void {\n const a = this.active;\n if (!a) return;\n this.active = null;\n a.controller?.destroy();\n a.survey?.destroy();\n a.scope?.destroy();\n this.sessionStore.remove(KEYS.active);\n }\n\n /** Dismisses the active guide (records a dismissal). */\n dismissGuide(): void {\n const a = this.active;\n if (!a) return;\n if (a.controller) a.controller.dismiss();\n else {\n this.stopGuide();\n this.recordEnd(a.guide, \"dismissed\");\n this.emitter.emit(\"guide:dismiss\", a.guide);\n }\n }\n\n getActiveGuide(): PublishedGuide | null {\n return this.active?.guide ?? null;\n }\n\n /** Published guides for this environment (read-only). */\n getGuides(): ReadonlyArray<PublishedGuide> {\n return this.config?.guides ?? [];\n }\n\n isGuideCompleted(idOrKey: string): boolean {\n const guide = this.findGuide(idOrKey);\n return !!this.state.guides[guide?.id ?? idOrKey]?.completedAt;\n }\n\n openResourceCenter(): void {\n if (!this.resourceCenter) this.renderPersistentWidgets();\n this.resourceCenter?.open();\n }\n\n closeResourceCenter(): void {\n this.resourceCenter?.close();\n }\n\n on<K extends keyof GuidelyEvents>(event: K, cb: GuidelyEvents[K]): () => void {\n return this.emitter.on(event, cb);\n }\n\n off<K extends keyof GuidelyEvents>(event: K, cb: GuidelyEvents[K]): void {\n this.emitter.off(event, cb);\n }\n\n /** Snapshot for debugging / devtools. */\n getState() {\n return {\n ready: this.isReady,\n destroyed: this.destroyed,\n anonymousId: this.anonymousId,\n user: this.user,\n consent: this.consent,\n configVersion: this.config?.configVersion ?? null,\n guides: this.getGuides().map((g) => ({ id: g.id, key: g.key, kind: g.kind })),\n activeGuide: this.active ? { id: this.active.guide.id, key: this.active.guide.key, ...(this.active.controller?.getState() ?? {}) } : null,\n queued: this.queued.map((q) => q.guide.key),\n widgets: Array.from(this.widgets.keys()),\n guideState: this.state.guides,\n checklists: this.state.checklists,\n audienceIds: this.state.audienceIds,\n session: this.session,\n pendingEvents: this.queue.size,\n authoring: !!this.authoring?.isActive(),\n };\n }\n\n // ---------------------------------------------------------------------------\n // Authoring\n // ---------------------------------------------------------------------------\n\n private maybeStartAuthoring(): void {\n try {\n const bridge = new AuthoringBridge({\n api: this.api,\n sessionStore: this.sessionStore,\n theme: () => this.theme(),\n ctx: () => this.getContext(),\n maskSelectors: [...(this.options.maskSelectors || []), ...(this.config?.settings?.maskSelectors || [])],\n onError: (err) => this.reportError(err),\n onActive: (active) => {\n this.emitter.emit(\"authoring\", { active });\n if (active) {\n this.stopGuide();\n this.widgets.forEach((w) => w.destroy());\n this.widgets.clear();\n } else this.evaluate(\"ready\");\n },\n });\n if (bridge.detect()) this.authoring = bridge;\n } catch (err) {\n this.reportError(err);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Internals\n // ---------------------------------------------------------------------------\n\n private persistState(): void {\n writeJson(this.store, KEYS.state(this.options.projectId), this.state);\n }\n\n private persistSession(): void {\n writeJson(this.sessionStore, KEYS.session, this.session);\n }\n\n private reportError(err: unknown): void {\n const error = err instanceof Error ? err : new Error(String(err));\n this.log(\"error\", error.message);\n try {\n this.options.onError?.(error);\n } catch {\n /* ignore */\n }\n this.emitter.emit(\"error\", error);\n }\n\n private log(...args: unknown[]): void {\n if (this.options.debug && typeof console !== \"undefined\") console.debug(\"[Guidely]\", ...args);\n }\n\n // ---------------------------------------------------------------------------\n // Static helpers (used by the embed)\n // ---------------------------------------------------------------------------\n\n /** Creates (or returns the existing) client and starts initialisation. */\n static init(options: GuidelyOptions): GuidelyClient {\n if (current && !current.destroyed && current.options.projectId === options.projectId) return current;\n current?.destroy();\n current = new GuidelyClient(options);\n void current.init();\n return current;\n }\n\n /** The most recently created client, if any. */\n static get(): GuidelyClient | null {\n return current && !current.destroyed ? current : null;\n }\n}\n\nlet current: GuidelyClient | null = null;\n\nfunction safePath(url: string): string {\n try {\n const u = new URL(url, \"http://localhost\");\n return u.pathname + u.search;\n } catch {\n return url;\n }\n}\n\n/**\n * Creates a Guidely client and starts loading configuration. Throws a friendly error when called\n * during server-side rendering; framework adapters guard this for you.\n */\nexport function createGuidely(options: GuidelyOptions): GuidelyClient {\n const client = new GuidelyClient(options);\n current = client;\n void client.init();\n return client;\n}\n","import { type AuthoringPick, type AuthoringSessionInfo, type ProjectTheme, type SelectorStrategy, type TargetingContext } from \"@guidelytech/shared\";\nimport { highlightSelectors, previewStep, runGuide, startAuthoring, type AuthoringSession, type GuideController, type PreviewHandle, type RunnableGuide } from \"@guidelytech/guide-runtime\";\nimport type { Api } from \"./http\";\nimport { KEYS, readJson, writeJson, type KeyValueStore } from \"./storage\";\n\n/** Schemas are only needed in authoring mode; load them lazily so the normal runtime stays zod-free. */\nasync function loadSchemas() {\n const m = await import(\"@guidelytech/shared\");\n return { StepSchema: m.StepSchema, GuideConfigSchema: m.GuideConfigSchema };\n}\n\nexport const AUTHORING_PARAM = \"guidely_authoring\";\nexport const HEARTBEAT_MS = 15000;\n\n/** Messages the SDK posts to the dashboard window (`window.opener`). */\nexport type AuthoringOutgoingMessage =\n | { type: \"guidely:authoring-ready\"; sessionId: string; url: string }\n | { type: \"guidely:pick\"; sessionId: string; pick: AuthoringPick }\n | { type: \"guidely:highlight-result\"; sessionId: string; counts: number[]; resolved: boolean }\n | { type: \"guidely:preview-ended\"; sessionId: string; reason: string }\n | { type: \"guidely:exit\"; sessionId: string }\n | { type: \"guidely:pong\"; sessionId: string; url: string };\n\n/** Messages the dashboard may post to the app window (origin-checked against `dashboardOrigin`). */\nexport type AuthoringIncomingMessage =\n | { type: \"guidely:preview-step\"; step: unknown; theme?: Partial<ProjectTheme> | null; appearance?: unknown }\n | { type: \"guidely:preview-guide\"; guide: { id?: string; key?: string; name?: string; kind?: string; version?: number; config: unknown } }\n | { type: \"guidely:highlight\"; selectors: SelectorStrategy[] }\n | { type: \"guidely:stop-preview\" }\n | { type: \"guidely:ping\" }\n | { type: \"guidely:exit\" };\n\nexport interface AuthoringBridgeOptions {\n api: Api;\n sessionStore: KeyValueStore;\n theme: () => Partial<ProjectTheme>;\n ctx: () => TargetingContext;\n maskSelectors: string[];\n onError: (err: unknown) => void;\n onActive: (active: boolean) => void;\n}\n\n/**\n * Detects `?guidely_authoring=<token>`, verifies the session with the public API, runs the\n * runtime's element picker and bridges picks/previews with the dashboard via `postMessage`.\n */\nexport class AuthoringBridge {\n private token: string | null = null;\n private info: AuthoringSessionInfo | null = null;\n private session: AuthoringSession | null = null;\n private heartbeat: ReturnType<typeof setInterval> | null = null;\n private preview: PreviewHandle | null = null;\n private previewGuide: GuideController | null = null;\n private active = false;\n\n constructor(private readonly opts: AuthoringBridgeOptions) {}\n\n isActive(): boolean {\n return this.active;\n }\n\n /** Returns true when a token was found (in the URL or the session marker) and verification started. */\n detect(): boolean {\n if (typeof window === \"undefined\") return false;\n let token: string | null = null;\n try {\n const url = new URL(window.location.href);\n token = url.searchParams.get(AUTHORING_PARAM);\n if (token) {\n url.searchParams.delete(AUTHORING_PARAM);\n window.history.replaceState(window.history.state, \"\", url.toString());\n }\n } catch {\n token = null;\n }\n if (!token) {\n const marker = readJson<{ token?: string } | null>(this.opts.sessionStore, KEYS.authoring, null);\n token = marker?.token ?? null;\n }\n if (!token) return false;\n this.token = token;\n writeJson(this.opts.sessionStore, KEYS.authoring, { token });\n void this.start();\n return true;\n }\n\n private async start(): Promise<void> {\n if (!this.token) return;\n try {\n const res = await this.opts.api.get<AuthoringSessionInfo>(\"/authoring/session\", { params: { token: this.token } });\n if (!res.ok || !res.data) {\n this.opts.sessionStore.remove(KEYS.authoring);\n this.opts.onError(new Error(`[Guidely] authoring session invalid or expired (${res.status})`));\n return;\n }\n this.info = res.data;\n if (Date.parse(this.info.expiresAt) < Date.now()) {\n this.opts.sessionStore.remove(KEYS.authoring);\n this.opts.onError(new Error(\"[Guidely] authoring session expired\"));\n return;\n }\n this.active = true;\n this.opts.onActive(true);\n this.session = startAuthoring({\n dashboardOrigin: this.info.dashboardOrigin,\n onPick: (pick) => this.sendPick(pick),\n onExit: () => this.stop(),\n });\n this.heartbeat = setInterval(() => {\n void this.opts.api.post(\"/authoring/session/heartbeat\", {}, { params: { token: this.token ?? undefined } }).catch(() => {});\n }, HEARTBEAT_MS);\n this.post({ type: \"guidely:authoring-ready\", sessionId: this.info.id, url: window.location.href });\n } catch (err) {\n this.opts.onError(err);\n }\n }\n\n private masked(el: Element): boolean {\n return this.opts.maskSelectors.some((sel) => {\n try {\n return !!el.closest(sel);\n } catch {\n return false;\n }\n });\n }\n\n private sendPick(raw: AuthoringPick & { element: Element }): void {\n if (!this.info || !this.token) return;\n const { element, ...rest } = raw;\n const pick: AuthoringPick = this.masked(element) ? { ...rest, textSnapshot: \"\", selectors: rest.selectors.filter((s) => s.kind !== \"text\") } : rest;\n pick.url = window.location.href;\n this.post({ type: \"guidely:pick\", sessionId: this.info.id, pick });\n void this.opts.api.post(\"/authoring/session/picks\", pick, { params: { token: this.token } }).catch((err) => this.opts.onError(err));\n }\n\n private post(message: AuthoringOutgoingMessage): void {\n if (!this.info) return;\n try {\n window.opener?.postMessage(message, this.info.dashboardOrigin);\n } catch {\n /* opener may be gone */\n }\n }\n\n private stopPreview(): void {\n this.preview?.destroy();\n this.preview = null;\n this.previewGuide?.destroy();\n this.previewGuide = null;\n this.session?.setPicking(true);\n }\n\n /** Handles `message` events; ignores anything not from `dashboardOrigin`. */\n async handleMessage(e: MessageEvent): Promise<void> {\n if (!this.active || !this.info) return;\n if (e.origin !== this.info.dashboardOrigin) return;\n const msg = e.data as AuthoringIncomingMessage | null;\n if (!msg || typeof msg !== \"object\" || typeof msg.type !== \"string\") return;\n try {\n switch (msg.type) {\n case \"guidely:preview-step\": {\n this.stopPreview();\n const { StepSchema, GuideConfigSchema } = await loadSchemas();\n const step = StepSchema.parse(msg.step);\n const appearance = msg.appearance ? GuideConfigSchema.shape.appearance.parse(msg.appearance) : undefined;\n this.session?.setPicking(false);\n this.session?.setStatus(`Previewing step “${step.title || step.id}” — close it to continue picking`);\n this.preview = previewStep(step, { ...this.opts.theme(), ...(msg.theme || {}) }, {\n appearance,\n onEnd: () => {\n this.preview = null;\n this.session?.setPicking(true);\n this.session?.setStatus(\"Guidely authoring — hover an element and click to select · Esc to cancel\");\n this.post({ type: \"guidely:preview-ended\", sessionId: this.info!.id, reason: \"step\" });\n },\n });\n break;\n }\n case \"guidely:preview-guide\": {\n this.stopPreview();\n const g = msg.guide;\n const guide: RunnableGuide = { id: g.id || \"preview\", key: g.key || \"preview\", name: g.name || \"Preview\", kind: g.kind || \"flow\", version: g.version ?? 0, config: (await loadSchemas()).GuideConfigSchema.parse(g.config) };\n this.session?.setPicking(false);\n this.session?.setStatus(`Previewing “${guide.name}”`);\n this.previewGuide = runGuide(guide, {\n theme: this.opts.theme(),\n ctx: this.opts.ctx,\n onNavigate: (url, newTab) => (newTab ? window.open(url, \"_blank\", \"noopener\") : window.location.assign(url)),\n onEnd: (reason) => {\n this.previewGuide = null;\n this.session?.setPicking(true);\n this.post({ type: \"guidely:preview-ended\", sessionId: this.info!.id, reason });\n },\n });\n this.previewGuide.start();\n break;\n }\n case \"guidely:highlight\": {\n const result = highlightSelectors(Array.isArray(msg.selectors) ? msg.selectors : [], { durationMs: 3000 });\n this.post({ type: \"guidely:highlight-result\", sessionId: this.info.id, counts: result.counts, resolved: !!result.resolved });\n break;\n }\n case \"guidely:stop-preview\":\n this.stopPreview();\n break;\n case \"guidely:ping\":\n this.post({ type: \"guidely:pong\", sessionId: this.info.id, url: window.location.href });\n break;\n case \"guidely:exit\":\n this.stop();\n break;\n default:\n break;\n }\n } catch (err) {\n this.opts.onError(err);\n }\n }\n\n /** Leaves authoring mode and clears the session marker. */\n stop(): void {\n if (!this.active) return;\n this.active = false;\n this.stopPreview();\n if (this.heartbeat) clearInterval(this.heartbeat);\n this.heartbeat = null;\n this.session?.stop();\n this.session = null;\n this.opts.sessionStore.remove(KEYS.authoring);\n if (this.info) this.post({ type: \"guidely:exit\", sessionId: this.info.id });\n this.opts.onActive(false);\n }\n}\n","export type StorageKind = \"local\" | \"session\" | \"memory\";\n\n/** Minimal synchronous key/value store; never throws (private mode, quota, SSR). */\nexport interface KeyValueStore {\n get(key: string): string | null;\n set(key: string, value: string): void;\n remove(key: string): void;\n}\n\nexport function memoryStore(): KeyValueStore {\n const map = new Map<string, string>();\n return { get: (k) => map.get(k) ?? null, set: (k, v) => void map.set(k, v), remove: (k) => void map.delete(k) };\n}\n\nfunction webStore(area: \"localStorage\" | \"sessionStorage\"): KeyValueStore | null {\n try {\n if (typeof window === \"undefined\") return null;\n const s = window[area];\n if (!s) return null;\n const probe = \"__guidely_probe__\";\n s.setItem(probe, \"1\");\n s.removeItem(probe);\n return {\n get: (k) => {\n try {\n return s.getItem(k);\n } catch {\n return null;\n }\n },\n set: (k, v) => {\n try {\n s.setItem(k, v);\n } catch {\n /* quota / private mode */\n }\n },\n remove: (k) => {\n try {\n s.removeItem(k);\n } catch {\n /* ignore */\n }\n },\n };\n } catch {\n return null;\n }\n}\n\n/** Creates a store of the requested kind, degrading to memory when unavailable. */\nexport function createStorage(kind: StorageKind = \"local\"): KeyValueStore {\n if (kind === \"memory\") return memoryStore();\n return webStore(kind === \"local\" ? \"localStorage\" : \"sessionStorage\") ?? memoryStore();\n}\n\nexport function readJson<T>(store: KeyValueStore, key: string, fallback: T): T {\n const raw = store.get(key);\n if (raw == null) return fallback;\n try {\n return JSON.parse(raw) as T;\n } catch {\n return fallback;\n }\n}\n\nexport function writeJson(store: KeyValueStore, key: string, value: unknown): void {\n try {\n store.set(key, JSON.stringify(value));\n } catch {\n /* ignore */\n }\n}\n\n/** Storage keys used by the SDK (documented for integrators). */\nexport const KEYS = {\n anon: \"guidely:anon\",\n seen: \"guidely:seen\",\n config: (key: string) => `guidely:config:${key}`,\n etag: (key: string) => `guidely:etag:${key}`,\n state: (key: string) => `guidely:state:${key}`,\n user: (key: string) => `guidely:user:${key}`,\n queue: (key: string) => `guidely:queue:${key}`,\n session: \"guidely:session\",\n active: \"guidely:active\",\n authoring: \"guidely:authoring\",\n} as const;\n","import type { TargetingContext } from \"@guidelytech/shared\";\n\nexport interface DeviceInfo {\n type: \"desktop\" | \"tablet\" | \"mobile\";\n browser?: string;\n os?: string;\n}\n\n/** Lightweight UA sniffing (good enough for targeting; not for feature detection). */\nexport function detectDevice(ua: string, width: number): DeviceInfo {\n const u = ua || \"\";\n let type: DeviceInfo[\"type\"] = \"desktop\";\n if (/iPad|Tablet|PlayBook|Silk/i.test(u) || (/Android/i.test(u) && !/Mobile/i.test(u))) type = \"tablet\";\n else if (/Mobi|iPhone|iPod|Android.*Mobile|Windows Phone/i.test(u)) type = \"mobile\";\n else if (width > 0 && width < 768) type = \"mobile\";\n else if (width > 0 && width < 1024) type = \"tablet\";\n let browser: string | undefined;\n if (/Edg\\//i.test(u)) browser = \"edge\";\n else if (/OPR\\/|Opera/i.test(u)) browser = \"opera\";\n else if (/SamsungBrowser/i.test(u)) browser = \"samsung\";\n else if (/Chrome\\/|CriOS/i.test(u)) browser = \"chrome\";\n else if (/Firefox\\/|FxiOS/i.test(u)) browser = \"firefox\";\n else if (/Safari\\//i.test(u) && /Version\\//i.test(u)) browser = \"safari\";\n else if (/MSIE|Trident/i.test(u)) browser = \"ie\";\n let os: string | undefined;\n if (/Windows/i.test(u)) os = \"windows\";\n else if (/iPhone|iPad|iPod/i.test(u)) os = \"ios\";\n else if (/Mac OS X|Macintosh/i.test(u)) os = \"macos\";\n else if (/Android/i.test(u)) os = \"android\";\n else if (/CrOS/i.test(u)) os = \"chromeos\";\n else if (/Linux/i.test(u)) os = \"linux\";\n return { type, browser, os };\n}\n\nexport interface ContextInput {\n anonymousId: string;\n userId?: string | null;\n userAttributes: Record<string, unknown>;\n accountAttributes: Record<string, unknown>;\n url: string;\n firstVisit: boolean;\n eventsSeen: Iterable<string>;\n completedGuides: Iterable<string>;\n dismissedGuides: Iterable<string>;\n seenGuides: Iterable<string>;\n completedChecklists: Iterable<string>;\n audienceIds: Iterable<string>;\n environment: string;\n locale?: string;\n device?: DeviceInfo;\n now?: Date;\n}\n\n/** Builds the `TargetingContext` consumed by `evaluateRules`. */\nexport function buildContext(input: ContextInput): TargetingContext {\n let path = \"\";\n const query: Record<string, string> = {};\n try {\n const u = new URL(input.url, \"http://localhost\");\n path = u.pathname;\n u.searchParams.forEach((v, k) => {\n query[k] = v;\n });\n } catch {\n path = input.url;\n }\n const device = input.device ?? (typeof navigator !== \"undefined\" ? detectDevice(navigator.userAgent, typeof window !== \"undefined\" ? window.innerWidth : 0) : { type: \"desktop\" });\n return {\n anonymousId: input.anonymousId,\n userId: input.userId ?? null,\n userAttributes: input.userAttributes,\n accountAttributes: input.accountAttributes,\n url: input.url,\n path,\n query,\n device,\n firstVisit: input.firstVisit,\n eventsSeen: new Set(input.eventsSeen),\n completedGuides: new Set(input.completedGuides),\n dismissedGuides: new Set(input.dismissedGuides),\n seenGuides: new Set(input.seenGuides),\n completedChecklists: new Set(input.completedChecklists),\n audienceIds: new Set(input.audienceIds),\n now: input.now ?? new Date(),\n environment: input.environment,\n locale: input.locale ?? (typeof navigator !== \"undefined\" ? navigator.language : undefined),\n };\n}\n","type AnyFn = (...args: any[]) => void;\n\n/** Tiny typed event emitter. Listener errors are reported, never thrown into the caller. */\nexport class Emitter<Events extends { [K in keyof Events]: AnyFn }> {\n private listeners = new Map<keyof Events, Set<AnyFn>>();\n constructor(private readonly onError?: (err: unknown) => void) {}\n\n on<K extends keyof Events>(event: K, cb: Events[K]): () => void {\n let set = this.listeners.get(event);\n if (!set) {\n set = new Set();\n this.listeners.set(event, set);\n }\n set.add(cb);\n return () => this.off(event, cb);\n }\n\n off<K extends keyof Events>(event: K, cb: Events[K]): void {\n this.listeners.get(event)?.delete(cb);\n }\n\n emit<K extends keyof Events>(event: K, ...args: Parameters<Events[K]>): void {\n const set = this.listeners.get(event);\n if (!set) return;\n for (const cb of Array.from(set)) {\n try {\n cb(...args);\n } catch (err) {\n this.onError?.(err);\n }\n }\n }\n\n clear(): void {\n this.listeners.clear();\n }\n}\n","import type { FrequencyConfig, PublishedGuide } from \"@guidelytech/shared\";\n\n/** Per-guide state kept locally and merged with the server's `IdentifyResponse.guideState`. */\nexport interface GuideLocalState {\n impressions: number;\n completedAt?: string | null;\n dismissedAt?: string | null;\n lastShownAt?: string | null;\n}\n\nconst HOUR = 3600 * 1000;\n\n/**\n * Pure frequency evaluation. `shownThisSession` comes from session storage.\n * - `once`: a single impression ever (unless `reshowAfterDismiss` and it was only dismissed).\n * - `once_per_session`: at most once per browser session.\n * - `every_time`: on every trigger (still blocked by completion/dismissal rules below).\n * - `interval`: at most once every `intervalHours`.\n * `maxImpressions` caps total impressions; dismissal blocks re-showing unless `reshowAfterDismiss`\n * (then `cooldownHours` must have elapsed); completion blocks unless mode is `every_time`.\n */\nexport function isFrequencyEligible(freq: FrequencyConfig, state: GuideLocalState | undefined, shownThisSession: boolean, now: number = Date.now()): boolean {\n const s = state ?? { impressions: 0 };\n if (freq.maxImpressions != null && s.impressions >= freq.maxImpressions) return false;\n if (s.completedAt && freq.mode !== \"every_time\") return false;\n if (s.dismissedAt) {\n if (!freq.reshowAfterDismiss) return false;\n if (freq.cooldownHours > 0 && now - Date.parse(s.dismissedAt) < freq.cooldownHours * HOUR) return false;\n }\n switch (freq.mode) {\n case \"once\":\n return s.impressions === 0 || (!!s.dismissedAt && freq.reshowAfterDismiss);\n case \"once_per_session\":\n return !shownThisSession;\n case \"interval\": {\n if (!s.lastShownAt) return true;\n const hours = freq.intervalHours ?? 24;\n return now - Date.parse(s.lastShownAt) >= hours * HOUR;\n }\n case \"every_time\":\n default:\n return true;\n }\n}\n\n/**\n * Exclusive guides (flows, modals, tooltips, announcements, surveys) run one at a time.\n * Banners, checklists and hotspot-only tooltips can coexist with an active flow.\n */\nexport function isExclusiveGuide(guide: PublishedGuide): boolean {\n if (guide.kind === \"banner\" || guide.kind === \"checklist\") return false;\n const steps = guide.config.steps;\n if (steps.length > 0 && steps.every((s) => s.type === \"hotspot\" || s.type === \"banner\")) return false;\n return true;\n}\n\n/** Is `a` mutually exclusive with `b` (by id or key, in either direction)? */\nexport function areMutuallyExclusive(a: PublishedGuide, b: PublishedGuide): boolean {\n const la = a.config.frequency.mutuallyExclusiveWith;\n const lb = b.config.frequency.mutuallyExclusiveWith;\n return la.includes(b.id) || la.includes(b.key) || lb.includes(a.id) || lb.includes(a.key);\n}\n\n/** Survey scheduling window. */\nexport function isWithinSchedule(guide: PublishedGuide, now: number = Date.now()): boolean {\n const s = guide.config.survey;\n if (!s) return true;\n if (s.startAt && now < Date.parse(s.startAt)) return false;\n if (s.endAt && now > Date.parse(s.endAt)) return false;\n return true;\n}\n","export interface ApiResponse<T> {\n status: number;\n ok: boolean;\n data: T | null;\n etag: string | null;\n}\n\nexport type FetchLike = typeof fetch;\n\n/** Thin HTTP client for the public SDK API. Adds the public key as query + header. */\nexport class Api {\n constructor(\n private readonly baseUrl: string,\n private readonly key: string,\n private readonly fetchImpl?: FetchLike,\n ) {}\n\n url(path: string, params: Record<string, string | undefined> = {}): string {\n const u = new URL(`${this.baseUrl.replace(/\\/$/, \"\")}/api/v1/sdk${path}`);\n u.searchParams.set(\"key\", this.key);\n for (const [k, v] of Object.entries(params)) if (v != null) u.searchParams.set(k, v);\n return u.toString();\n }\n\n private get fetcher(): FetchLike | null {\n if (this.fetchImpl) return this.fetchImpl;\n return typeof fetch === \"function\" ? fetch.bind(globalThis) : null;\n }\n\n async request<T>(method: \"GET\" | \"POST\", path: string, options: { body?: unknown; etag?: string | null; params?: Record<string, string | undefined>; keepalive?: boolean; timeoutMs?: number } = {}): Promise<ApiResponse<T>> {\n const f = this.fetcher;\n if (!f) throw new Error(\"fetch is not available\");\n const headers: Record<string, string> = { \"X-Guidely-Key\": this.key, Accept: \"application/json\" };\n if (options.body !== undefined) headers[\"Content-Type\"] = \"application/json\";\n if (options.etag) headers[\"If-None-Match\"] = options.etag;\n const ac = typeof AbortController !== \"undefined\" ? new AbortController() : null;\n const timer = ac ? setTimeout(() => ac.abort(), options.timeoutMs ?? 10000) : null;\n try {\n const res = await f(this.url(path, options.params), {\n method,\n headers,\n body: options.body === undefined ? undefined : JSON.stringify(options.body),\n keepalive: options.keepalive,\n signal: ac?.signal,\n credentials: \"omit\",\n mode: \"cors\",\n });\n let data: T | null = null;\n if (res.status !== 304 && res.status !== 204) {\n try {\n data = (await res.json()) as T;\n } catch {\n data = null;\n }\n }\n return { status: res.status, ok: res.ok, data, etag: res.headers?.get?.(\"etag\") ?? null };\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n\n get<T>(path: string, options?: { etag?: string | null; params?: Record<string, string | undefined> }): Promise<ApiResponse<T>> {\n return this.request<T>(\"GET\", path, options);\n }\n\n post<T>(path: string, body: unknown, options?: { params?: Record<string, string | undefined>; keepalive?: boolean }): Promise<ApiResponse<T>> {\n return this.request<T>(\"POST\", path, { body, ...options });\n }\n\n /** `navigator.sendBeacon` when available (page unload); returns false when it could not be queued. */\n beacon(path: string, body: unknown): boolean {\n try {\n if (typeof navigator === \"undefined\" || typeof navigator.sendBeacon !== \"function\") return false;\n // text/plain is a CORS-safelisted type: cross-origin beacons need no preflight (which\n // browsers drop during unload). The API parses the body regardless of content type.\n const blob = new Blob([JSON.stringify(body)], { type: \"text/plain;charset=UTF-8\" });\n return navigator.sendBeacon(this.url(path), blob);\n } catch {\n return false;\n }\n }\n}\n\nexport const sleep = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));\n\n/** Exponential backoff helper: 1s → 2s → 4s … capped. */\nexport function backoffMs(attempt: number, baseMs = 1000, maxMs = 30000): number {\n return Math.min(maxMs, baseMs * 2 ** Math.max(0, attempt));\n}\n\n/** Fire-and-forget POST with bounded retries (used for state sync; never blocks UI). */\nexport async function postWithRetry<T>(api: Api, path: string, body: unknown, attempts = 3, baseMs = 500): Promise<ApiResponse<T> | null> {\n for (let i = 0; i < attempts; i++) {\n try {\n const res = await api.post<T>(path, body);\n if (res.ok || (res.status >= 400 && res.status < 500 && res.status !== 429)) return res;\n } catch {\n /* network error → retry */\n }\n if (i < attempts - 1) await sleep(backoffMs(i, baseMs, 8000));\n }\n return null;\n}\n","type Listener = (url: string) => void;\n\ninterface PatchedHistory extends History {\n __guidelyPatched?: { count: number; pushState: History[\"pushState\"]; replaceState: History[\"replaceState\"] };\n}\n\n/**\n * Detects SPA navigation: patches `history.pushState`/`replaceState` (reference counted, restored\n * on the last unwatch), listens to `popstate` and `hashchange`, and debounces into one callback.\n */\nexport function watchNavigation(listener: Listener, debounceMs = 50): () => void {\n if (typeof window === \"undefined\") return () => {};\n const win = window;\n const hist = win.history as PatchedHistory;\n let last = win.location.href;\n let timer: ReturnType<typeof setTimeout> | null = null;\n const check = () => {\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n timer = null;\n const href = win.location.href;\n if (href !== last) {\n last = href;\n listener(href);\n }\n }, debounceMs);\n };\n if (!hist.__guidelyPatched) {\n const pushState = hist.pushState;\n const replaceState = hist.replaceState;\n hist.__guidelyPatched = { count: 0, pushState, replaceState };\n hist.pushState = function (this: History, ...args: Parameters<History[\"pushState\"]>) {\n const r = pushState.apply(this, args);\n win.dispatchEvent(new Event(\"guidely:navigate\"));\n return r;\n };\n hist.replaceState = function (this: History, ...args: Parameters<History[\"replaceState\"]>) {\n const r = replaceState.apply(this, args);\n win.dispatchEvent(new Event(\"guidely:navigate\"));\n return r;\n };\n }\n hist.__guidelyPatched.count += 1;\n win.addEventListener(\"guidely:navigate\", check);\n win.addEventListener(\"popstate\", check);\n win.addEventListener(\"hashchange\", check);\n return () => {\n if (timer) clearTimeout(timer);\n win.removeEventListener(\"guidely:navigate\", check);\n win.removeEventListener(\"popstate\", check);\n win.removeEventListener(\"hashchange\", check);\n const p = hist.__guidelyPatched;\n if (p) {\n p.count -= 1;\n if (p.count <= 0) {\n hist.pushState = p.pushState;\n hist.replaceState = p.replaceState;\n delete hist.__guidelyPatched;\n }\n }\n };\n}\n","import type { SdkEvent } from \"@guidelytech/shared\";\nimport { backoffMs } from \"./http\";\nimport { readJson, writeJson, type KeyValueStore } from \"./storage\";\n\nexport interface EventQueueOptions {\n store: KeyValueStore;\n storageKey: string;\n /** Sends one batch. Resolve `{ ok: true }` on success, `{ ok: false, retry }` otherwise. */\n send: (events: SdkEvent[]) => Promise<{ ok: boolean; retry?: boolean }>;\n /** Synchronous best-effort send used on page hide. */\n beacon?: (events: SdkEvent[]) => boolean;\n /** Should events be flushed right now? (analytics enabled + consent granted). */\n enabled: () => boolean;\n flushIntervalMs?: number;\n maxQueue?: number;\n batchSize?: number;\n maxAttempts?: number;\n onError?: (err: unknown) => void;\n}\n\n/**\n * Bounded, persisted event queue. Batches ≤50 events every 2s (or on demand), dedupes by\n * `eventId`, retries with exponential backoff (1s→30s, 5 attempts) and keeps failed events for\n * the next flush. Drops the oldest events once the queue exceeds 200.\n */\nexport class EventQueue {\n private events: SdkEvent[] = [];\n private timer: ReturnType<typeof setTimeout> | null = null;\n private retryTimer: ReturnType<typeof setTimeout> | null = null;\n private inflight = false;\n private inflightIds = new Set<string>();\n private attempt = 0;\n private destroyed = false;\n private readonly flushIntervalMs: number;\n private readonly maxQueue: number;\n private readonly batchSize: number;\n private readonly maxAttempts: number;\n\n constructor(private readonly opts: EventQueueOptions) {\n this.flushIntervalMs = opts.flushIntervalMs ?? 2000;\n this.maxQueue = opts.maxQueue ?? 200;\n this.batchSize = opts.batchSize ?? 50;\n this.maxAttempts = opts.maxAttempts ?? 5;\n const persisted = readJson<SdkEvent[]>(opts.store, opts.storageKey, []);\n if (Array.isArray(persisted)) this.events = persisted.filter((e) => e && typeof e.eventId === \"string\").slice(-this.maxQueue);\n // Events left over from a previous page load are flushed on the next tick.\n if (this.events.length) this.schedule();\n }\n\n get size(): number {\n return this.events.length;\n }\n\n /** Pending events (read-only copy, for debugging). */\n peek(): SdkEvent[] {\n return this.events.slice();\n }\n\n enqueue(event: SdkEvent): void {\n if (this.destroyed) return;\n if (this.events.some((e) => e.eventId === event.eventId)) return;\n this.events.push(event);\n if (this.events.length > this.maxQueue) this.events.splice(0, this.events.length - this.maxQueue);\n this.persist();\n this.schedule();\n }\n\n private persist(): void {\n writeJson(this.opts.store, this.opts.storageKey, this.events);\n }\n\n private schedule(): void {\n if (this.timer || this.retryTimer || this.destroyed) return;\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.flush();\n }, this.flushIntervalMs);\n }\n\n /** Sends queued events now (one batch at a time). Safe to call at any time. */\n async flush(): Promise<void> {\n if (this.destroyed || this.inflight || !this.events.length || !this.opts.enabled()) return;\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n this.inflight = true;\n const batch = this.events.slice(0, this.batchSize);\n this.inflightIds = new Set(batch.map((e) => e.eventId));\n let ok = false;\n let retry = true;\n try {\n const res = await this.opts.send(batch);\n ok = res.ok;\n retry = res.retry ?? !res.ok;\n } catch (err) {\n this.opts.onError?.(err);\n }\n this.inflight = false;\n this.inflightIds.clear();\n if (this.destroyed) return;\n if (ok || !retry) {\n const ids = new Set(batch.map((e) => e.eventId));\n this.events = this.events.filter((e) => !ids.has(e.eventId));\n this.attempt = 0;\n this.persist();\n if (this.events.length) this.schedule();\n return;\n }\n this.attempt += 1;\n if (this.attempt >= this.maxAttempts) {\n // Give up for now; events stay queued until the next flush trigger (navigation, timer, unload).\n this.attempt = 0;\n return;\n }\n this.retryTimer = setTimeout(() => {\n this.retryTimer = null;\n void this.flush();\n }, backoffMs(this.attempt - 1));\n }\n\n /** Best-effort synchronous flush on unload using `sendBeacon`. */\n flushSync(): void {\n if (this.destroyed || !this.opts.enabled() || !this.opts.beacon) return;\n // Events already in flight (fetch with keepalive) survive unload; only beacon the rest to avoid duplicate batches.\n const batch = this.events.filter((e) => !this.inflightIds.has(e.eventId)).slice(0, this.batchSize);\n if (!batch.length) return;\n if (this.opts.beacon(batch)) {\n const ids = new Set(batch.map((e) => e.eventId));\n this.events = this.events.filter((e) => !ids.has(e.eventId));\n this.persist();\n }\n }\n\n clear(): void {\n this.events = [];\n this.persist();\n }\n\n destroy(): void {\n this.destroyed = true;\n if (this.timer) clearTimeout(this.timer);\n if (this.retryTimer) clearTimeout(this.retryTimer);\n this.timer = null;\n this.retryTimer = null;\n this.persist();\n }\n}\n"],"mappings":"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","names":["import_runtime","import_guide_runtime","current"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/client.ts","../src/authoring.ts","../src/snapshot.ts","../src/storage.ts","../src/context.ts","../src/emitter.ts","../src/frequency.ts","../src/http.ts","../src/messenger-api.ts","../src/navigation.ts","../src/queue.ts"],"sourcesContent":["/**\n * @guidelytech/sdk-core — framework-independent Guidely browser SDK.\n *\n * SSR-safe to import: nothing touches `window` at module scope. Create a client in the browser\n * with {@link createGuidely} (or `Guidely.init` for script-tag installs).\n */\nimport { GuidelyClient, createGuidely, SDK_VERSION } from \"./client\";\n\nexport { GuidelyClient, createGuidely, SDK_NAME, SDK_VERSION, DEFAULT_API_URL } from \"./client\";\nexport type { GuidelyOptions, GuidelyEvents, GuidelyEventName, GuidelyUser, GuidelyAccount, GuidelyEnvironment, ConsentState, ChecklistProgressState, PersistedState, SessionState, GuideStepInfo } from \"./types\";\nexport { isFrequencyEligible, isExclusiveGuide, areMutuallyExclusive, isWithinSchedule } from \"./frequency\";\nexport type { GuideLocalState } from \"./frequency\";\nexport { detectDevice, buildContext } from \"./context\";\nexport type { DeviceInfo, ContextInput } from \"./context\";\nexport { EventQueue } from \"./queue\";\nexport type { EventQueueOptions } from \"./queue\";\nexport { watchNavigation } from \"./navigation\";\nexport { createStorage, KEYS } from \"./storage\";\nexport type { KeyValueStore, StorageKind } from \"./storage\";\nexport { AUTHORING_PARAM, HEARTBEAT_MS } from \"./authoring\";\nexport { captureSnapshot } from \"./snapshot\";\nexport type { AuthoringIncomingMessage, AuthoringOutgoingMessage } from \"./authoring\";\nexport type { AppSnapshot, PublishedGuide, SdkConfigResponse, SdkEvent, TargetingContext, GuideConfig, GuideStep } from \"@guidelytech/shared\";\n\n/** Global-style API used by the script-tag embed: `Guidely.init(options)` / `Guidely.get()`. */\nexport const Guidely = {\n init: (options: Parameters<typeof GuidelyClient.init>[0]) => GuidelyClient.init(options),\n get: () => GuidelyClient.get(),\n createGuidely,\n version: SDK_VERSION,\n};\n\nexport default Guidely;\n","import { evaluateRules, randomId, sanitizeProperties } from \"@guidelytech/shared/runtime\";\nimport {\n type ChecklistTask,\n type EventName,\n type IdentifyRequest,\n type IdentifyResponse,\n type PublishedGuide,\n type ResourceCenterArticle,\n type SdkConfigResponse,\n type SdkEvent,\n type TargetingContext,\n} from \"@guidelytech/shared\";\nimport {\n destroyHost,\n isChecklistComplete,\n renderChecklist,\n renderResourceCenter,\n renderSurvey,\n runGuide,\n urlMatches,\n waitForTarget,\n type ChecklistWidget,\n type GuideController,\n type ResourceCenterWidget,\n type SurveyWidget,\n} from \"@guidelytech/guide-runtime\";\nimport { createScope } from \"@guidelytech/guide-runtime\";\nimport type { MessengerTab, MessengerWidget } from \"@guidelytech/guide-runtime/messenger\";\nimport { AuthoringBridge } from \"./authoring\";\nimport { buildContext } from \"./context\";\nimport { Emitter } from \"./emitter\";\nimport { areMutuallyExclusive, isExclusiveGuide, isFrequencyEligible, isWithinSchedule, type GuideLocalState } from \"./frequency\";\nimport { Api, postWithRetry } from \"./http\";\nimport { createMessengerTransport, forgetConversations } from \"./messenger-api\";\nimport { watchNavigation } from \"./navigation\";\nimport { EventQueue } from \"./queue\";\nimport { createStorage, KEYS, readJson, writeJson, type KeyValueStore } from \"./storage\";\nimport type { ChecklistProgressState, ConsentState, GuidelyAccount, GuidelyEvents, GuidelyOptions, GuidelyUser, PersistedState, SessionState } from \"./types\";\n\nexport const SDK_NAME = \"@guidelytech/sdk-core\";\nexport const SDK_VERSION = \"0.2.0\";\nexport const DEFAULT_API_URL = \"https://api.guidely.app\";\n\ntype EvalReason = \"ready\" | \"navigation\" | \"event\" | \"click\" | \"visible\" | \"identify\" | \"after_guide\" | \"timer\" | \"manual\";\ninterface EvalDetail {\n eventName?: string;\n target?: Element | null;\n guideId?: string;\n endedGuide?: PublishedGuide;\n newAudiences?: Set<string>;\n}\n\ninterface ActiveGuide {\n guide: PublishedGuide;\n controller?: GuideController;\n survey?: SurveyWidget;\n scope?: { destroy(): void };\n manual: boolean;\n startUrl: string;\n}\n\ninterface QueuedGuide {\n guide: PublishedGuide;\n url: string;\n pageScoped: boolean;\n}\n\nconst PAGE_SCOPED = new Set([\"page_load\", \"url_match\", \"element_click\", \"element_visible\", \"delay\"]);\n\nfunction isBrowser(): boolean {\n return typeof window !== \"undefined\" && typeof document !== \"undefined\";\n}\n\nfunction nowIso(): string {\n return new Date().toISOString();\n}\n\nfunction emptyState(): PersistedState {\n return { guides: {}, checklists: {}, surveysSubmitted: [], audienceIds: [] };\n}\n\n/**\n * Framework-independent Guidely client. Create one per page with {@link createGuidely} or\n * {@link GuidelyClient.init}; adapters (`@guidelytech/react`, `@guidelytech/svelte`) wrap it.\n */\nexport class GuidelyClient {\n readonly options: Readonly<Required<Pick<GuidelyOptions, \"projectId\" | \"environment\" | \"apiUrl\" | \"analytics\" | \"consent\" | \"storage\" | \"configRefreshMs\" | \"pollIntervalMs\" | \"debug\">>> & GuidelyOptions;\n private readonly api: Api;\n private readonly store: KeyValueStore;\n private readonly sessionStore: KeyValueStore;\n private readonly emitter: Emitter<GuidelyEvents>;\n private readonly queue: EventQueue;\n private config: SdkConfigResponse | null = null;\n private etag: string | null = null;\n private anonymousId: string;\n private user: GuidelyUser | null = null;\n private state: PersistedState;\n private session: SessionState;\n private consent: ConsentState;\n private readyPromise: Promise<void> | null = null;\n private resolveReady: (() => void) | null = null;\n private isReady = false;\n private destroyed = false;\n private active: ActiveGuide | null = null;\n private queued: QueuedGuide[] = [];\n private widgets = new Map<string, { destroy(): void; checklist?: ChecklistWidget; scope?: { destroy(): void }; controller?: GuideController }>();\n private resourceCenter: ResourceCenterWidget | null = null;\n private resourceCenterScope: { destroy(): void } | null = null;\n private messenger: MessengerWidget | null = null;\n private messengerScope: { destroy(): void } | null = null;\n private messengerLoading: Promise<MessengerWidget | null> | null = null;\n private cleanups: Array<() => void> = [];\n private timers = new Set<ReturnType<typeof setTimeout>>();\n private visibilityObservers = new Map<string, () => void>();\n private firedDelays = new Set<string>();\n private firstVisit: boolean;\n private lastUrl: string;\n private authoring: AuthoringBridge | null = null;\n private lastAudiences = new Set<string>();\n /** Set once the app calls identify()/reset(); bootstrap then leaves identity alone instead of re-identifying. */\n private identitySettled = false;\n\n constructor(options: GuidelyOptions) {\n if (!isBrowser()) throw new Error(\"[Guidely] createGuidely() must be called in the browser. Create the client inside useEffect / onMount, or use the framework adapters.\");\n if (!options || !options.projectId) throw new Error(\"[Guidely] `projectId` (your environment public key, e.g. pk_dev_…) is required.\");\n this.options = {\n ...options,\n environment: options.environment ?? (options.projectId.startsWith(\"pk_prod\") ? \"production\" : options.projectId.startsWith(\"pk_stag\") ? \"staging\" : \"development\"),\n apiUrl: options.apiUrl ?? DEFAULT_API_URL,\n analytics: options.analytics ?? true,\n consent: options.consent ?? \"granted\",\n storage: options.storage ?? \"local\",\n configRefreshMs: options.configRefreshMs ?? 5 * 60 * 1000,\n pollIntervalMs: options.pollIntervalMs ?? 1000,\n debug: options.debug ?? false,\n };\n this.consent = this.options.consent;\n this.emitter = new Emitter<GuidelyEvents>((err) => this.reportError(err));\n this.api = new Api(this.options.apiUrl, this.options.projectId, options.fetch);\n this.store = createStorage(this.options.storage);\n this.sessionStore = this.options.storage === \"memory\" ? this.store : createStorage(\"session\");\n this.anonymousId = this.store.get(KEYS.anon) || \"\";\n if (!this.anonymousId) {\n this.anonymousId = `anon_${randomId(20)}`;\n this.store.set(KEYS.anon, this.anonymousId);\n }\n this.firstVisit = !this.store.get(KEYS.seen);\n this.store.set(KEYS.seen, nowIso());\n this.state = { ...emptyState(), ...readJson<Partial<PersistedState>>(this.store, KEYS.state(this.options.projectId), {}) };\n this.user = readJson<GuidelyUser | null>(this.store, KEYS.user(this.options.projectId), null);\n const session = readJson<SessionState | null>(this.sessionStore, KEYS.session, null);\n this.session = session && session.id ? session : { id: `s_${randomId(16)}`, startedAt: nowIso(), shownGuides: [], events: [] };\n this.persistSession();\n this.lastUrl = location.href;\n this.lastAudiences = new Set(this.state.audienceIds);\n this.queue = new EventQueue({\n store: this.store,\n storageKey: KEYS.queue(this.options.projectId),\n enabled: () => this.analyticsEnabled(),\n send: async (events) => {\n const res = await this.api.post<{ accepted: number }>(\"/events\", { events, sentAt: nowIso(), sdk: { name: SDK_NAME, version: SDK_VERSION } }, { keepalive: true });\n return { ok: res.ok, retry: !(res.status >= 400 && res.status < 500 && res.status !== 429) };\n },\n beacon: (events) => this.api.beacon(\"/events\", { events, sentAt: nowIso(), sdk: { name: SDK_NAME, version: SDK_VERSION } }),\n onError: (err) => this.reportError(err),\n });\n if (options.user) this.user = { ...options.user };\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n /** Loads config (cache first, then network), wires listeners and evaluates triggers. Idempotent. */\n init(): Promise<void> {\n if (this.readyPromise) return this.readyPromise;\n this.readyPromise = new Promise<void>((resolve) => {\n this.resolveReady = resolve;\n });\n void this.bootstrap();\n return this.readyPromise;\n }\n\n /** Resolves once the client is ready (alias of `init()`). */\n ready(): Promise<void> {\n return this.init();\n }\n\n private async bootstrap(): Promise<void> {\n try {\n const cached = readJson<SdkConfigResponse | null>(this.store, KEYS.config(this.options.projectId), null);\n this.etag = this.store.get(KEYS.etag(this.options.projectId));\n if (cached && cached.guides) this.config = cached;\n await this.fetchConfig();\n if (this.destroyed) return;\n this.wireListeners();\n if (!this.identitySettled) {\n if (this.options.user) await this.identify(this.options.user.id, this.options.user.traits, this.options.user.account);\n else if (this.user?.id) await this.identify(this.user.id, this.user.traits, this.user.account);\n }\n if (this.destroyed) return;\n this.isReady = true;\n if (this.config) this.emitter.emit(\"ready\", this.config);\n this.resolveReady?.();\n this.renderPersistentWidgets();\n this.resumeActiveGuide();\n this.evaluate(\"ready\");\n if (!this.options.disableAuthoring) this.maybeStartAuthoring();\n } catch (err) {\n this.reportError(err);\n this.isReady = true;\n this.resolveReady?.();\n }\n }\n\n private async fetchConfig(): Promise<boolean> {\n try {\n const res = await this.api.get<SdkConfigResponse>(\"/config\", { etag: this.etag });\n if (res.status === 304) return true;\n if (res.ok && res.data && Array.isArray(res.data.guides)) {\n this.config = res.data;\n this.etag = res.etag;\n writeJson(this.store, KEYS.config(this.options.projectId), res.data);\n if (res.etag) this.store.set(KEYS.etag(this.options.projectId), res.etag);\n else this.store.remove(KEYS.etag(this.options.projectId));\n this.emitter.emit(\"config\", res.data);\n this.log(\"config loaded\", res.data.configVersion, `${res.data.guides.length} guides`);\n return true;\n }\n this.reportError(new Error(`[Guidely] config request failed (${res.status})${this.config ? \"; using cached config\" : \"\"}`));\n return false;\n } catch (err) {\n this.reportError(new Error(`[Guidely] config request failed: ${err instanceof Error ? err.message : String(err)}${this.config ? \"; using cached config\" : \"\"}`));\n return false;\n }\n }\n\n private wireListeners(): void {\n const doc = document;\n const win = window;\n this.cleanups.push(watchNavigation((url) => this.handleNavigation(url)));\n const onClick = (e: Event) => this.handleDocumentClick(e);\n doc.addEventListener(\"click\", onClick, true);\n this.cleanups.push(() => doc.removeEventListener(\"click\", onClick, true));\n const onHide = () => {\n if (doc.visibilityState === \"hidden\") this.queue.flushSync();\n };\n doc.addEventListener(\"visibilitychange\", onHide);\n win.addEventListener(\"pagehide\", onHide);\n this.cleanups.push(() => {\n doc.removeEventListener(\"visibilitychange\", onHide);\n win.removeEventListener(\"pagehide\", onHide);\n });\n const refresh = setInterval(() => void this.refresh(), this.options.configRefreshMs);\n this.cleanups.push(() => clearInterval(refresh));\n // Idle re-check: DOM can change without navigation (lazy content), so re-arm element-visibility\n // observers for eligible guides and drain the queue.\n const poll = setInterval(() => {\n if (!this.isReady || !this.config || this.authoring?.isActive() || doc.visibilityState === \"hidden\") return;\n const url = location.href;\n const ctx = this.getContext();\n for (const guide of this.config.guides) {\n if (guide.config.trigger.type === \"element_visible\" && guide.config.trigger.value) this.armVisibility(guide, ctx, url);\n }\n this.drainQueue(url, ctx);\n }, Math.max(250, this.options.pollIntervalMs));\n this.cleanups.push(() => clearInterval(poll));\n const onMessage = (e: MessageEvent) => this.authoring?.handleMessage(e);\n win.addEventListener(\"message\", onMessage);\n this.cleanups.push(() => win.removeEventListener(\"message\", onMessage));\n }\n\n /** Re-fetches the published config and re-evaluates triggers. */\n async refresh(): Promise<void> {\n if (this.destroyed) return;\n const before = this.config?.configVersion;\n await this.fetchConfig();\n if (this.config && this.config.configVersion !== before) {\n this.renderPersistentWidgets();\n this.evaluate(\"ready\");\n }\n }\n\n /** Tears everything down: guides, widgets, listeners, timers, host element. Re-init is allowed via a new client. */\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.active?.controller?.destroy();\n this.active?.survey?.destroy();\n this.active?.scope?.destroy();\n this.active = null;\n this.queued = [];\n this.widgets.forEach((w) => w.destroy());\n this.widgets.clear();\n this.resourceCenter?.destroy();\n this.resourceCenterScope?.destroy();\n this.resourceCenter = null;\n this.destroyMessenger();\n this.visibilityObservers.forEach((stop) => stop());\n this.visibilityObservers.clear();\n this.timers.forEach((t) => clearTimeout(t));\n this.timers.clear();\n this.cleanups.splice(0).forEach((fn) => fn());\n this.authoring?.stop();\n this.authoring = null;\n this.queue.flushSync();\n this.queue.destroy();\n this.emitter.clear();\n destroyHost();\n if (current === this) current = null;\n }\n\n // ---------------------------------------------------------------------------\n // Identity\n // ---------------------------------------------------------------------------\n\n /** Identifies the end user and loads server-held state (audiences, guide history, checklist progress). */\n async identify(userId: string, traits?: Record<string, unknown>, account?: GuidelyAccount): Promise<void> {\n if (this.destroyed) return;\n this.identitySettled = true;\n this.user = { id: String(userId), traits: { ...(this.user?.id === String(userId) ? this.user.traits : {}), ...(traits || {}) }, account: account ?? (this.user?.id === String(userId) ? this.user.account : undefined) };\n writeJson(this.store, KEYS.user(this.options.projectId), this.user);\n this.enqueue(\"identify\", { properties: { traits: sanitizeProperties(this.user.traits) } });\n await this.syncIdentify();\n this.emitter.emit(\"identify\", { userId: this.user.id, anonymousId: this.anonymousId });\n if (this.isReady) this.evaluate(\"identify\");\n }\n\n private async syncIdentify(): Promise<void> {\n const body: IdentifyRequest = { anonymousId: this.anonymousId, userId: this.user?.id ?? null, traits: this.user?.traits, account: this.user?.account ? { id: this.user.account.id, traits: this.user.account.traits } : null, sessionId: this.session.id, url: this.collectUrls() ? location.href : undefined };\n const res = await postWithRetry<IdentifyResponse>(this.api, \"/identify\", body, 2);\n if (res?.ok && res.data) this.mergeServerState(res.data);\n }\n\n private mergeServerState(data: IdentifyResponse): void {\n const guides = { ...this.state.guides };\n for (const [id, s] of Object.entries(data.guideState || {})) {\n const local = guides[id];\n guides[id] = {\n impressions: Math.max(local?.impressions ?? 0, s.impressions ?? 0),\n completedAt: local?.completedAt ?? s.completedAt ?? null,\n dismissedAt: local?.dismissedAt ?? s.dismissedAt ?? null,\n lastShownAt: local?.lastShownAt ?? s.lastShownAt ?? null,\n };\n }\n const checklists = { ...this.state.checklists };\n for (const [id, p] of Object.entries(data.checklistProgress || {})) {\n const local = checklists[id];\n checklists[id] = {\n completedTaskIds: Array.from(new Set([...(local?.completedTaskIds ?? []), ...(p.completedTaskIds ?? [])])),\n completedAt: local?.completedAt ?? p.completedAt ?? null,\n dismissedAt: local?.dismissedAt ?? p.dismissedAt ?? null,\n };\n }\n this.state = {\n guides,\n checklists,\n surveysSubmitted: Array.from(new Set([...this.state.surveysSubmitted, ...(data.surveysSubmitted || [])])),\n audienceIds: data.audienceIds || [],\n firstSeenAt: this.state.firstSeenAt ?? data.firstSeenAt,\n };\n if (data.firstSeenAt && Date.now() - Date.parse(data.firstSeenAt) > 60_000) this.firstVisit = false;\n this.persistState();\n this.widgets.forEach((w, id) => {\n const g = this.findGuide(id);\n if (w.checklist && g) w.checklist.setProgress(this.getChecklistProgress(g.id));\n });\n }\n\n /** Sets or replaces the account (company/organisation) for the current user. */\n async setAccount(account: GuidelyAccount): Promise<void> {\n if (!this.user) {\n this.user = { id: \"\", account };\n writeJson(this.store, KEYS.user(this.options.projectId), this.user);\n return;\n }\n await this.identify(this.user.id, undefined, account);\n }\n\n /** Merges additional traits into the current user. */\n async updateTraits(traits: Record<string, unknown>): Promise<void> {\n if (!this.user?.id) {\n this.user = { id: \"\", traits: { ...(this.user?.traits || {}), ...traits } };\n return;\n }\n await this.identify(this.user.id, traits, this.user.account);\n }\n\n /** Forgets the user: new anonymous id, cleared local guide/checklist state, triggers re-evaluated. */\n reset(): void {\n this.identitySettled = true;\n this.stopGuide();\n this.user = null;\n this.store.remove(KEYS.user(this.options.projectId));\n this.anonymousId = `anon_${randomId(20)}`;\n this.store.set(KEYS.anon, this.anonymousId);\n this.state = emptyState();\n this.persistState();\n this.session = { id: `s_${randomId(16)}`, startedAt: nowIso(), shownGuides: [], events: [] };\n this.persistSession();\n this.sessionStore.remove(KEYS.active);\n this.lastAudiences = new Set();\n this.firedDelays.clear();\n this.widgets.forEach((w) => w.destroy());\n this.widgets.clear();\n // Conversations belong to the previous user: forget their tokens and rebuild the messenger.\n forgetConversations(this.store, this.options.projectId);\n this.destroyMessenger();\n this.emitter.emit(\"identify\", { userId: null, anonymousId: this.anonymousId });\n if (this.isReady) {\n this.renderPersistentWidgets();\n this.evaluate(\"identify\");\n }\n }\n\n // ---------------------------------------------------------------------------\n // Events\n // ---------------------------------------------------------------------------\n\n /** Updates consent at runtime (`granted` flushes buffered events; `denied` drops them). */\n setConsent(consent: ConsentState): void {\n this.consent = consent;\n if (consent === \"denied\") this.queue.clear();\n else if (consent === \"granted\") void this.queue.flush();\n }\n\n private analyticsEnabled(): boolean {\n return this.options.analytics && this.consent === \"granted\" && (this.config?.settings?.analyticsEnabled ?? true);\n }\n\n private collectUrls(): boolean {\n return this.config?.settings?.collectUrls ?? true;\n }\n\n private enqueue(name: EventName, extra: Partial<SdkEvent> = {}): SdkEvent | null {\n if (this.consent === \"denied\" || !this.options.analytics) return null;\n const event: SdkEvent = {\n eventId: randomId(24),\n name,\n occurredAt: nowIso(),\n anonymousId: this.anonymousId,\n userId: this.user?.id || null,\n accountId: this.user?.account?.id || null,\n sessionId: this.session.id,\n url: this.collectUrls() ? location.href : undefined,\n ...extra,\n };\n if (extra.properties) event.properties = sanitizeProperties(extra.properties);\n this.queue.enqueue(event);\n this.emitter.emit(\"track\", event);\n return event;\n }\n\n /** Tracks a custom event. Events drive `event` triggers, `advanceOn: \"event\"` steps and checklist tasks. */\n track(name: string, properties?: Record<string, unknown>): void {\n if (this.destroyed || !name) return;\n if (!this.session.events.includes(name)) {\n this.session.events.push(name);\n this.persistSession();\n }\n this.enqueue(\"custom\", { customName: name.slice(0, 120), properties: properties ?? {} });\n this.customListeners.get(name)?.forEach((cb) => {\n try {\n cb();\n } catch (err) {\n this.reportError(err);\n }\n });\n this.completeChecklistTasksBy(\"event\", name);\n if (this.isReady) this.evaluate(\"event\", { eventName: name });\n }\n\n /** Records a page view and re-evaluates triggers. Called automatically on SPA navigation. */\n page(url: string = location.href): void {\n if (this.destroyed) return;\n this.enqueue(\"page_view\", { properties: { path: safePath(url) } });\n this.handleNavigation(url, true);\n }\n\n private readonly customListeners = new Map<string, Set<() => void>>();\n private readonly eventBus = {\n on: (name: string, cb: () => void) => {\n let set = this.customListeners.get(name);\n if (!set) {\n set = new Set();\n this.customListeners.set(name, set);\n }\n set.add(cb);\n return () => {\n set?.delete(cb);\n };\n },\n };\n\n private handleNavigation(url: string, explicit = false): void {\n if (this.destroyed) return;\n const changed = url !== this.lastUrl;\n this.lastUrl = url;\n if (!explicit && changed) this.enqueue(\"page_view\", { properties: { path: safePath(url) } });\n this.completeChecklistTasksBy(\"url_visited\", url);\n this.active?.controller?.resume();\n if (this.active?.controller) {\n const st = this.active.controller.getState();\n if (st.status === \"running\" && !this.active.manual) {\n const g = this.active.guide;\n if (g.config.urlPatterns.length && !g.config.urlPatterns.some((p) => urlMatches(p, url))) this.active.controller.destroy();\n }\n }\n this.firedDelays.clear();\n if (this.isReady) this.evaluate(\"navigation\");\n if (changed) void this.queue.flush();\n }\n\n private handleDocumentClick(e: Event): void {\n const target = e.target as Element | null;\n if (!target || typeof target.closest !== \"function\") return;\n this.completeChecklistTasksBy(\"click\", target);\n if (this.isReady) this.evaluate(\"click\", { target });\n }\n\n // ---------------------------------------------------------------------------\n // Targeting + triggers\n // ---------------------------------------------------------------------------\n\n /** Builds the targeting context for the current moment. */\n getContext(): TargetingContext {\n const guides = this.state.guides;\n const completedChecklists = Object.entries(this.state.checklists).filter(([, p]) => !!p.completedAt).map(([id]) => id);\n const keysOf = (ids: string[]) => ids.flatMap((id) => [id, this.findGuide(id)?.key ?? id]);\n return buildContext({\n anonymousId: this.anonymousId,\n userId: this.user?.id || null,\n userAttributes: this.user?.traits ?? {},\n accountAttributes: this.user?.account?.traits ?? {},\n url: location.href,\n firstVisit: this.firstVisit,\n eventsSeen: this.session.events,\n completedGuides: keysOf(Object.keys(guides).filter((id) => guides[id]?.completedAt)),\n dismissedGuides: keysOf(Object.keys(guides).filter((id) => guides[id]?.dismissedAt)),\n seenGuides: keysOf(Object.keys(guides).filter((id) => (guides[id]?.impressions ?? 0) > 0)),\n completedChecklists: keysOf(completedChecklists),\n audienceIds: this.state.audienceIds,\n environment: this.options.environment,\n });\n }\n\n private isTargeted(guide: PublishedGuide, ctx: TargetingContext, url: string): boolean {\n const c = guide.config;\n if (c.urlPatterns.length && !c.urlPatterns.some((p) => urlMatches(p, url))) return false;\n if (c.trigger.urlPattern && !urlMatches(c.trigger.urlPattern, url)) return false;\n if (!isWithinSchedule(guide)) return false;\n if (guide.kind === \"survey\" && (this.state.surveysSubmitted.includes(guide.id) || this.state.surveysSubmitted.includes(guide.key))) return false;\n ctx.rolloutSalt = guide.id;\n return evaluateRules(c.targeting, ctx);\n }\n\n private isEligible(guide: PublishedGuide, ctx: TargetingContext, url: string): boolean {\n if (!this.isTargeted(guide, ctx, url)) return false;\n const shownThisSession = this.session.shownGuides.includes(guide.id);\n if (guide.kind === \"checklist\") {\n const p = this.state.checklists[guide.id];\n return !p?.dismissedAt;\n }\n return isFrequencyEligible(guide.config.frequency, this.state.guides[guide.id], shownThisSession);\n }\n\n private triggerFires(guide: PublishedGuide, reason: EvalReason, detail: EvalDetail): boolean {\n const t = guide.config.trigger;\n switch (t.type) {\n case \"page_load\":\n return reason === \"ready\" || reason === \"navigation\" || reason === \"identify\";\n case \"url_match\":\n return (reason === \"ready\" || reason === \"navigation\" || reason === \"identify\") && urlMatches(t.value, location.href);\n case \"event\":\n return reason === \"event\" && !!t.value && detail.eventName === t.value;\n case \"element_click\":\n if (reason !== \"click\" || !t.value || !detail.target) return false;\n try {\n return !!detail.target.closest(t.value);\n } catch {\n return false;\n }\n case \"element_visible\":\n return reason === \"visible\" && detail.guideId === guide.id;\n case \"delay\":\n return reason === \"timer\" && detail.guideId === guide.id;\n case \"after_guide\":\n return reason === \"after_guide\" && !!detail.endedGuide && (detail.endedGuide.id === t.value || detail.endedGuide.key === t.value);\n case \"segment_enter\":\n return reason === \"identify\" && !!t.value && !!detail.newAudiences?.has(t.value);\n case \"manual\":\n default:\n return false;\n }\n }\n\n private evaluate(reason: EvalReason, detail: EvalDetail = {}): void {\n if (!this.config || this.destroyed || this.authoring?.isActive()) return;\n const url = location.href;\n const ctx = this.getContext();\n if (reason === \"identify\") {\n const current = new Set(this.state.audienceIds);\n detail.newAudiences = new Set(Array.from(current).filter((a) => !this.lastAudiences.has(a)));\n this.lastAudiences = current;\n }\n const candidates: PublishedGuide[] = [];\n for (const guide of this.config.guides) {\n const t = guide.config.trigger;\n if (detail.endedGuide && detail.endedGuide.id === guide.id) continue; // never re-show the guide that just ended\n // Arm element-visibility observers and delay timers on page-level evaluations.\n if (reason === \"ready\" || reason === \"navigation\") {\n if (t.type === \"element_visible\" && t.value) this.armVisibility(guide, ctx, url);\n if ((t.type === \"delay\" || (t.type === \"page_load\" && t.delayMs > 0)) && !this.firedDelays.has(guide.id)) {\n if (!this.isEligible(guide, ctx, url)) continue;\n this.firedDelays.add(guide.id);\n this.setTimer(() => this.evaluate(\"timer\", { guideId: guide.id }), t.delayMs);\n continue;\n }\n }\n if (t.type === \"page_load\" && t.delayMs > 0 && reason !== \"timer\") continue;\n if (t.type === \"page_load\" && t.delayMs > 0 && reason === \"timer\" && detail.guideId !== guide.id) continue;\n if (!this.triggerFires(guide, reason, detail)) continue;\n if (!this.isEligible(guide, ctx, url)) continue;\n candidates.push(guide);\n }\n if (reason === \"after_guide\" || reason === \"navigation\") this.drainQueue(url, ctx);\n if (!candidates.length) return;\n candidates.sort((a, b) => a.config.frequency.priority - b.config.frequency.priority);\n for (const guide of candidates) {\n if (this.widgets.has(guide.id) || this.active?.guide.id === guide.id) continue;\n const delay = guide.config.trigger.type !== \"delay\" && guide.config.trigger.type !== \"page_load\" ? guide.config.trigger.delayMs : 0;\n if (delay > 0) {\n this.setTimer(() => this.tryShow(guide, url, false), delay);\n continue;\n }\n this.tryShow(guide, url, false);\n }\n }\n\n private armVisibility(guide: PublishedGuide, ctx: TargetingContext, url: string): void {\n const selector = guide.config.trigger.value;\n if (!selector || this.visibilityObservers.has(guide.id)) return;\n if (!this.isEligible(guide, ctx, url)) return;\n const ac = new AbortController();\n let io: IntersectionObserver | null = null;\n const stop = () => {\n ac.abort();\n io?.disconnect();\n this.visibilityObservers.delete(guide.id);\n };\n this.visibilityObservers.set(guide.id, stop);\n waitForTarget([{ kind: \"css\", value: selector }], { timeoutMs: 0, signal: ac.signal })\n .then((el) => {\n if (ac.signal.aborted) return;\n const fire = () => {\n stop();\n this.evaluate(\"visible\", { guideId: guide.id });\n };\n if (typeof IntersectionObserver === \"undefined\") return fire();\n io = new IntersectionObserver((entries) => {\n if (entries.some((e) => e.isIntersecting)) fire();\n });\n io.observe(el);\n })\n .catch(() => stop());\n }\n\n private setTimer(fn: () => void, ms: number): void {\n const t = setTimeout(() => {\n this.timers.delete(t);\n if (!this.destroyed) fn();\n }, ms);\n this.timers.add(t);\n }\n\n /** Decides whether a guide can show now, otherwise queues it. */\n private tryShow(guide: PublishedGuide, url: string, manual: boolean): boolean {\n if (this.destroyed) return false;\n if (!isExclusiveGuide(guide)) {\n if (this.widgets.has(guide.id)) return false;\n this.show(guide, manual);\n return true;\n }\n if (this.active) {\n if (this.active.guide.id === guide.id) return false;\n if (manual) this.stopGuide();\n else {\n if (!this.queued.some((q) => q.guide.id === guide.id)) this.queued.push({ guide, url, pageScoped: PAGE_SCOPED.has(guide.config.trigger.type) });\n this.log(\"queued\", guide.key, \"behind\", this.active.guide.key);\n return false;\n }\n }\n const blocked = Array.from(this.widgets.keys()).map((id) => this.findGuide(id)).some((g) => g && areMutuallyExclusive(g, guide));\n if (blocked && !manual) {\n if (!this.queued.some((q) => q.guide.id === guide.id)) this.queued.push({ guide, url, pageScoped: true });\n return false;\n }\n this.show(guide, manual);\n return true;\n }\n\n private drainQueue(url: string, ctx: TargetingContext): void {\n if (this.active) return;\n this.queued = this.queued.filter((q) => !(q.pageScoped && q.url !== url));\n while (this.queued.length) {\n const next = this.queued.shift() as QueuedGuide;\n if (!this.isEligible(next.guide, ctx, url)) continue;\n if (this.tryShow(next.guide, url, false)) return;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Showing guides\n // ---------------------------------------------------------------------------\n\n private findGuide(idOrKey: string): PublishedGuide | undefined {\n return this.config?.guides.find((g) => g.id === idOrKey || g.key === idOrKey);\n }\n\n private guideState(id: string): GuideLocalState {\n return this.state.guides[id] ?? (this.state.guides[id] = { impressions: 0 });\n }\n\n private recordImpression(guide: PublishedGuide): void {\n const s = this.guideState(guide.id);\n s.impressions += 1;\n s.lastShownAt = nowIso();\n if (!this.session.shownGuides.includes(guide.id)) this.session.shownGuides.push(guide.id);\n this.persistState();\n this.persistSession();\n this.syncGuideState(guide.id, { impression: true });\n }\n\n private recordEnd(guide: PublishedGuide, reason: \"completed\" | \"dismissed\" | \"skipped\"): void {\n const s = this.guideState(guide.id);\n if (reason === \"completed\") s.completedAt = nowIso();\n else s.dismissedAt = nowIso();\n this.persistState();\n this.syncGuideState(guide.id, reason === \"completed\" ? { completed: true } : { dismissed: true });\n if (reason === \"completed\") this.completeChecklistTasksBy(\"guide_completed\", guide);\n }\n\n private syncGuideState(guideId: string, update: { impression?: boolean; completed?: boolean; dismissed?: boolean }): void {\n void postWithRetry(this.api, \"/guide-state\", { anonymousId: this.anonymousId, userId: this.user?.id || null, updates: [{ guideId, ...update }] });\n }\n\n private show(guide: PublishedGuide, manual: boolean, stepId?: string): void {\n try {\n if (guide.kind === \"checklist\" && guide.config.checklist) return this.showChecklist(guide);\n if (guide.kind === \"survey\" && guide.config.survey) return this.showSurvey(guide, manual);\n this.showFlow(guide, manual, stepId);\n } catch (err) {\n this.reportError(err);\n }\n }\n\n private showFlow(guide: PublishedGuide, manual: boolean, stepId?: string): void {\n if (this.authoring?.isActive()) return; // authoring mode renders previews only\n const exclusive = isExclusiveGuide(guide);\n const entry: ActiveGuide = { guide, manual, startUrl: location.href };\n const controller = runGuide(guide, {\n theme: this.theme(),\n ctx: () => this.getContext(),\n startAtStep: stepId,\n eventBus: this.eventBus,\n onError: (err) => this.reportError(err),\n onEvent: (e) => {\n const step = e.stepId ? guide.config.steps.find((s) => s.id === e.stepId) : undefined;\n this.enqueue(e.name, { guideId: guide.id, guideVersion: guide.version, stepId: e.stepId, stepIndex: e.stepIndex, properties: e.properties });\n if (e.name === \"guide_started\") {\n this.recordImpression(guide);\n this.emitter.emit(\"guide:start\", guide);\n }\n if (e.name === \"step_viewed\" && step) {\n if (exclusive) writeJson(this.sessionStore, KEYS.active, { guideId: guide.id, stepId: step.id, manual });\n this.emitter.emit(\"guide:step\", { guide, stepId: step.id, stepIndex: e.stepIndex ?? 0 });\n }\n if (e.name === \"guide_completed\") {\n this.recordEnd(guide, \"completed\");\n this.emitter.emit(\"guide:complete\", guide);\n }\n if (e.name === \"guide_dismissed\") {\n this.recordEnd(guide, \"dismissed\");\n this.emitter.emit(\"guide:dismiss\", guide);\n }\n if (e.name === \"guide_skipped\") {\n this.recordEnd(guide, \"skipped\");\n this.emitter.emit(\"guide:skip\", guide);\n }\n },\n onNavigate: (url, newTab) => this.navigate(url, newTab),\n onAction: (action, value) => {\n if (action === \"start_guide\" && value) this.setTimer(() => this.startGuide(value), 0);\n else if (action === \"event\" && value) this.track(value);\n else if (action === \"open_resource_center\") this.openResourceCenter();\n },\n onEnd: (reason) => {\n if (exclusive) {\n if (this.active?.controller === controller) this.active = null;\n this.sessionStore.remove(KEYS.active);\n } else this.widgets.delete(guide.id);\n if (reason !== \"destroyed\" && !this.destroyed) this.setTimer(() => this.evaluate(\"after_guide\", { endedGuide: guide }), 0);\n },\n });\n entry.controller = controller;\n if (exclusive) this.active = entry;\n else this.widgets.set(guide.id, { destroy: () => controller.destroy(), controller });\n controller.start();\n if (controller.getState().status === \"ended\") {\n if (exclusive && this.active === entry) this.active = null;\n this.widgets.delete(guide.id);\n }\n }\n\n private showChecklist(guide: PublishedGuide): void {\n if (this.authoring?.isActive()) return; // authoring mode renders previews only\n const config = guide.config.checklist;\n if (!config || this.widgets.has(guide.id)) return;\n const scope = createScope(this.theme(), guide.config.appearance);\n const progress = this.getChecklistProgress(guide.id);\n const first = !this.state.guides[guide.id]?.impressions;\n const widget = renderChecklist({\n scope: scope.el,\n config,\n progress,\n open: config.autoOpen && first && !progress.completedAt,\n onTaskClick: (task) => this.handleChecklistTaskClick(guide, task),\n onDismiss: () => this.dismissChecklist(guide),\n onOpen: () => this.enqueue(\"guide_viewed\", { guideId: guide.id, guideVersion: guide.version }),\n });\n this.widgets.set(guide.id, { destroy: () => { widget.destroy(); scope.destroy(); }, checklist: widget, scope });\n if (first) this.recordImpression(guide);\n }\n\n private showSurvey(guide: PublishedGuide, manual: boolean): void {\n if (this.authoring?.isActive()) return; // authoring mode renders previews only\n const config = guide.config.survey;\n if (!config) return;\n const scope = createScope(this.theme(), guide.config.appearance);\n const entry: ActiveGuide = { guide, manual, startUrl: location.href, scope };\n const finish = (reason: \"submitted\" | \"dismissed\") => {\n widget.destroy();\n scope.destroy();\n if (this.active === entry) this.active = null;\n if (reason === \"dismissed\") {\n this.enqueue(\"survey_dismissed\", { guideId: guide.id, guideVersion: guide.version });\n this.recordEnd(guide, \"dismissed\");\n this.emitter.emit(\"guide:dismiss\", guide);\n }\n this.setTimer(() => this.evaluate(\"after_guide\", { endedGuide: guide }), 0);\n };\n const widget = renderSurvey({\n scope: scope.el,\n config,\n title: guide.name,\n onDismiss: () => finish(this.state.surveysSubmitted.includes(guide.id) ? \"submitted\" : \"dismissed\"),\n onSubmit: (answers) => {\n const responseId = randomId(24);\n this.state.surveysSubmitted.push(guide.id);\n this.persistState();\n this.recordEnd(guide, \"completed\");\n this.enqueue(\"survey_submitted\", { guideId: guide.id, guideVersion: guide.version, properties: { responseId } });\n void postWithRetry(this.api, `/surveys/${encodeURIComponent(guide.id)}/responses`, { anonymousId: this.anonymousId, userId: this.user?.id || null, accountId: this.user?.account?.id || null, guideVersion: guide.version, answers, responseId });\n this.emitter.emit(\"survey:submit\", { guide, answers, responseId });\n this.emitter.emit(\"guide:complete\", guide);\n widget.showThankYou();\n },\n });\n entry.survey = widget;\n this.active = entry;\n this.recordImpression(guide);\n this.enqueue(\"survey_displayed\", { guideId: guide.id, guideVersion: guide.version });\n this.emitter.emit(\"guide:start\", guide);\n }\n\n private theme() {\n return { ...(this.config?.theme || {}), ...(this.options.theme || {}) };\n }\n\n private navigate(url: string, newTab?: boolean): void {\n try {\n if (newTab) window.open(url, \"_blank\", \"noopener\");\n else location.assign(url);\n } catch (err) {\n this.reportError(err);\n }\n }\n\n private renderPersistentWidgets(): void {\n if (!this.config) return;\n const rc = this.config.resourceCenter;\n if (this.config.messenger?.enabled) {\n // One launcher: the messenger's Help tab replaces the resource center.\n if (this.resourceCenter) {\n this.resourceCenter.destroy();\n this.resourceCenterScope?.destroy();\n this.resourceCenter = null;\n }\n if (!this.messenger) void this.loadMessenger();\n return;\n }\n this.destroyMessenger();\n if (rc && rc.enabled && !this.resourceCenter) {\n const scope = createScope(this.theme());\n this.resourceCenterScope = scope;\n this.resourceCenter = renderResourceCenter({\n scope: scope.el,\n config: rc,\n guides: this.config.guides.map((g) => ({ id: g.id, key: g.key, name: g.name, kind: g.kind })),\n search: (q) => this.searchResourceCenter(q),\n loadArticle: (id) => this.loadArticle(id),\n onStartGuide: (id) => this.startGuide(id),\n onOpenChecklist: (id) => this.openChecklist(id),\n onArticleView: (a) => this.enqueue(\"article_viewed\", { properties: { articleId: a.id, slug: a.slug } }),\n onOpen: () => {\n this.enqueue(\"resource_center_opened\");\n this.emitter.emit(\"resource-center:open\");\n },\n });\n } else if ((!rc || !rc.enabled) && this.resourceCenter) {\n this.resourceCenter.destroy();\n this.resourceCenterScope?.destroy();\n this.resourceCenter = null;\n }\n }\n\n private resumeActiveGuide(): void {\n const saved = readJson<{ guideId: string; stepId: string; manual?: boolean } | null>(this.sessionStore, KEYS.active, null);\n if (!saved) return;\n this.sessionStore.remove(KEYS.active);\n const guide = this.findGuide(saved.guideId);\n if (!guide || !guide.config.steps.some((s) => s.id === saved.stepId)) return;\n this.showFlow(guide, saved.manual ?? false, saved.stepId);\n }\n\n /** Loads the messenger widget on demand (it is a separate chunk) and renders it. */\n private loadMessenger(): Promise<MessengerWidget | null> {\n if (this.messenger) return Promise.resolve(this.messenger);\n if (this.messengerLoading) return this.messengerLoading;\n this.messengerLoading = import(\"@guidelytech/guide-runtime/messenger\")\n .then(({ renderMessenger }) => {\n const cfg = this.config?.messenger;\n if (this.destroyed || !this.config || !cfg?.enabled || this.messenger) return this.messenger;\n const scope = createScope(this.theme());\n this.messengerScope = scope;\n this.messenger = renderMessenger({\n scope: scope.el,\n config: cfg,\n api: createMessengerTransport({\n api: this.api,\n store: this.store,\n projectId: this.options.projectId,\n anonymousId: () => this.anonymousId,\n userId: () => this.user?.id || null,\n pageUrl: () => (this.collectUrls() ? location.href : undefined),\n }),\n resourceCenter: this.config.resourceCenter,\n guides: this.config.guides.map((g) => ({ id: g.id, key: g.key, name: g.name, kind: g.kind })),\n onStartGuide: (idOrKey) => this.startGuide(idOrKey),\n onOpenChecklist: (id) => this.openChecklist(id),\n onArticleView: (a) => this.enqueue(\"article_viewed\", { properties: { articleId: a.id, slug: a.slug } }),\n onOpen: () => {\n this.enqueue(\"messenger_opened\");\n this.emitter.emit(\"messenger:open\");\n },\n onMessage: (message, conversation) => this.emitter.emit(\"conversation:message\", { message, conversation }),\n });\n return this.messenger;\n })\n .catch((err) => {\n this.reportError(err);\n return null;\n })\n .finally(() => {\n this.messengerLoading = null;\n });\n return this.messengerLoading;\n }\n\n private destroyMessenger(): void {\n this.messenger?.destroy();\n this.messengerScope?.destroy();\n this.messenger = null;\n this.messengerScope = null;\n }\n\n private async loadArticle(id: string): Promise<ResourceCenterArticle | null> {\n try {\n const res = await this.api.get<{ article: ResourceCenterArticle }>(`/articles/${encodeURIComponent(id)}`);\n return res.ok && res.data ? res.data.article : null;\n } catch {\n return null;\n }\n }\n\n private async searchResourceCenter(q: string): Promise<ResourceCenterArticle[]> {\n try {\n const res = await this.api.get<{ articles: ResourceCenterArticle[] }>(\"/resource-center/search\", { params: { q } });\n return res.ok && res.data ? res.data.articles : [];\n } catch {\n return [];\n }\n }\n\n // ---------------------------------------------------------------------------\n // Checklists\n // ---------------------------------------------------------------------------\n\n /** Current progress for a checklist guide (by id or key). */\n getChecklistProgress(idOrKey: string): ChecklistProgressState {\n const guide = this.findGuide(idOrKey);\n const id = guide?.id ?? idOrKey;\n const p = this.state.checklists[id];\n return p ? { completedTaskIds: [...p.completedTaskIds], completedAt: p.completedAt ?? null, dismissedAt: p.dismissedAt ?? null } : { completedTaskIds: [], completedAt: null, dismissedAt: null };\n }\n\n /** Marks a checklist task complete (manual completion) and syncs progress. */\n completeChecklistTask(idOrKey: string, taskId: string): void {\n const guide = this.findGuide(idOrKey);\n if (!guide?.config.checklist) return;\n const task = guide.config.checklist.tasks.find((t) => t.id === taskId);\n if (task) this.markTaskDone(guide, task);\n }\n\n private markTaskDone(guide: PublishedGuide, task: ChecklistTask): void {\n const config = guide.config.checklist;\n if (!config) return;\n const progress = this.state.checklists[guide.id] ?? (this.state.checklists[guide.id] = { completedTaskIds: [] });\n if (progress.completedTaskIds.includes(task.id)) return;\n progress.completedTaskIds.push(task.id);\n this.enqueue(\"checklist_task_completed\", { guideId: guide.id, guideVersion: guide.version, properties: { taskId: task.id } });\n const complete = isChecklistComplete(config, progress) && !progress.completedAt;\n if (complete) {\n progress.completedAt = nowIso();\n this.enqueue(\"checklist_completed\", { guideId: guide.id, guideVersion: guide.version });\n }\n this.persistState();\n this.widgets.get(guide.id)?.checklist?.setProgress(this.getChecklistProgress(guide.id));\n void postWithRetry(this.api, `/checklists/${encodeURIComponent(guide.id)}/progress`, { anonymousId: this.anonymousId, userId: this.user?.id || null, guideVersion: guide.version, completedTaskIds: progress.completedTaskIds, completed: !!progress.completedAt });\n this.emitter.emit(\"checklist:task\", { guide, task, progress: this.getChecklistProgress(guide.id) });\n if (complete) {\n this.emitter.emit(\"checklist:complete\", guide);\n this.widgets.get(guide.id)?.checklist?.open();\n }\n }\n\n private completeChecklistTasksBy(kind: ChecklistTask[\"completion\"], value: string | Element | PublishedGuide): void {\n if (!this.config) return;\n for (const guide of this.config.guides) {\n const tasks = guide.config.checklist?.tasks;\n if (!tasks) continue;\n for (const task of tasks) {\n if (task.completion !== kind || !task.completionValue) continue;\n let hit = false;\n if (kind === \"event\") hit = value === task.completionValue;\n else if (kind === \"url_visited\") hit = urlMatches(task.completionValue, value as string);\n else if (kind === \"guide_completed\") hit = (value as PublishedGuide).id === task.completionValue || (value as PublishedGuide).key === task.completionValue;\n else if (kind === \"click\") {\n try {\n hit = !!(value as Element).closest(task.completionValue);\n } catch {\n hit = false;\n }\n }\n if (hit) this.markTaskDone(guide, task);\n }\n }\n }\n\n private handleChecklistTaskClick(guide: PublishedGuide, task: ChecklistTask): void {\n if (task.completion === \"manual\") this.markTaskDone(guide, task);\n if (task.action === \"start_guide\" && task.actionValue) this.startGuide(task.actionValue);\n else if (task.action === \"url\" && task.actionValue) this.navigate(task.actionValue);\n else if (task.action === \"event\" && task.actionValue) this.track(task.actionValue);\n }\n\n private dismissChecklist(guide: PublishedGuide): void {\n const progress = this.state.checklists[guide.id] ?? (this.state.checklists[guide.id] = { completedTaskIds: [] });\n progress.dismissedAt = nowIso();\n this.persistState();\n this.enqueue(\"checklist_dismissed\", { guideId: guide.id, guideVersion: guide.version });\n void postWithRetry(this.api, `/checklists/${encodeURIComponent(guide.id)}/progress`, { anonymousId: this.anonymousId, userId: this.user?.id || null, guideVersion: guide.version, completedTaskIds: progress.completedTaskIds, dismissed: true });\n this.widgets.get(guide.id)?.destroy();\n this.widgets.delete(guide.id);\n }\n\n /** Opens (rendering if needed) the checklist panel. */\n openChecklist(idOrKey: string): void {\n const guide = this.findGuide(idOrKey);\n if (!guide?.config.checklist) return;\n if (!this.widgets.has(guide.id)) {\n const p = this.state.checklists[guide.id];\n if (p?.dismissedAt) {\n delete p.dismissedAt;\n this.persistState();\n }\n this.showChecklist(guide);\n }\n this.widgets.get(guide.id)?.checklist?.open();\n }\n\n closeChecklist(idOrKey: string): void {\n const guide = this.findGuide(idOrKey);\n if (guide) this.widgets.get(guide.id)?.checklist?.close();\n }\n\n // ---------------------------------------------------------------------------\n // Public guide controls\n // ---------------------------------------------------------------------------\n\n /** Starts a guide by id or key, bypassing targeting and frequency rules. */\n startGuide(idOrKey: string, options: { stepId?: string } = {}): boolean {\n const guide = this.findGuide(idOrKey);\n if (!guide) {\n this.reportError(new Error(`[Guidely] startGuide: unknown guide \"${idOrKey}\"`));\n return false;\n }\n if (guide.kind === \"checklist\") {\n this.openChecklist(guide.id);\n return true;\n }\n if (this.active) this.stopGuide();\n this.widgets.get(guide.id)?.destroy();\n this.widgets.delete(guide.id);\n this.show(guide, true, options.stepId);\n return true;\n }\n\n /** Stops the active guide silently (no dismiss event). */\n stopGuide(): void {\n const a = this.active;\n if (!a) return;\n this.active = null;\n a.controller?.destroy();\n a.survey?.destroy();\n a.scope?.destroy();\n this.sessionStore.remove(KEYS.active);\n }\n\n /** Dismisses the active guide (records a dismissal). */\n dismissGuide(): void {\n const a = this.active;\n if (!a) return;\n if (a.controller) a.controller.dismiss();\n else {\n this.stopGuide();\n this.recordEnd(a.guide, \"dismissed\");\n this.emitter.emit(\"guide:dismiss\", a.guide);\n }\n }\n\n getActiveGuide(): PublishedGuide | null {\n return this.active?.guide ?? null;\n }\n\n /** Published guides for this environment (read-only). */\n getGuides(): ReadonlyArray<PublishedGuide> {\n return this.config?.guides ?? [];\n }\n\n isGuideCompleted(idOrKey: string): boolean {\n const guide = this.findGuide(idOrKey);\n return !!this.state.guides[guide?.id ?? idOrKey]?.completedAt;\n }\n\n openResourceCenter(): void {\n if (this.config?.messenger?.enabled) return this.openMessenger(\"help\");\n if (!this.resourceCenter) this.renderPersistentWidgets();\n this.resourceCenter?.open();\n }\n\n closeResourceCenter(): void {\n if (this.messenger) return this.closeMessenger();\n this.resourceCenter?.close();\n }\n\n /** Opens the Scout messenger (when enabled for the project), optionally on a tab. */\n openMessenger(tab?: MessengerTab): void {\n if (!this.config?.messenger?.enabled) return;\n void this.loadMessenger().then((m) => m?.open(tab));\n }\n\n closeMessenger(): void {\n this.messenger?.close();\n }\n\n /** Opens a new messenger conversation, optionally pre-filling the message. */\n showNewMessage(text?: string): void {\n if (!this.config?.messenger?.enabled) return;\n void this.loadMessenger().then((m) => m?.showNewMessage(text));\n }\n\n on<K extends keyof GuidelyEvents>(event: K, cb: GuidelyEvents[K]): () => void {\n return this.emitter.on(event, cb);\n }\n\n off<K extends keyof GuidelyEvents>(event: K, cb: GuidelyEvents[K]): void {\n this.emitter.off(event, cb);\n }\n\n /** Snapshot for debugging / devtools. */\n getState() {\n return {\n ready: this.isReady,\n destroyed: this.destroyed,\n anonymousId: this.anonymousId,\n user: this.user,\n consent: this.consent,\n configVersion: this.config?.configVersion ?? null,\n guides: this.getGuides().map((g) => ({ id: g.id, key: g.key, kind: g.kind })),\n activeGuide: this.active ? { id: this.active.guide.id, key: this.active.guide.key, ...(this.active.controller?.getState() ?? {}) } : null,\n queued: this.queued.map((q) => q.guide.key),\n widgets: Array.from(this.widgets.keys()),\n guideState: this.state.guides,\n checklists: this.state.checklists,\n audienceIds: this.state.audienceIds,\n session: this.session,\n pendingEvents: this.queue.size,\n authoring: !!this.authoring?.isActive(),\n };\n }\n\n // ---------------------------------------------------------------------------\n // Authoring\n // ---------------------------------------------------------------------------\n\n private maybeStartAuthoring(): void {\n try {\n const bridge = new AuthoringBridge({\n api: this.api,\n sessionStore: this.sessionStore,\n theme: () => this.theme(),\n ctx: () => this.getContext(),\n maskSelectors: [...(this.options.maskSelectors || []), ...(this.config?.settings?.maskSelectors || [])],\n onError: (err) => this.reportError(err),\n onActive: (active) => {\n this.emitter.emit(\"authoring\", { active });\n if (active) {\n this.stopGuide();\n this.widgets.forEach((w) => w.destroy());\n this.widgets.clear();\n } else this.evaluate(\"ready\");\n },\n });\n if (bridge.detect()) this.authoring = bridge;\n } catch (err) {\n this.reportError(err);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Internals\n // ---------------------------------------------------------------------------\n\n private persistState(): void {\n writeJson(this.store, KEYS.state(this.options.projectId), this.state);\n }\n\n private persistSession(): void {\n writeJson(this.sessionStore, KEYS.session, this.session);\n }\n\n private reportError(err: unknown): void {\n const error = err instanceof Error ? err : new Error(String(err));\n this.log(\"error\", error.message);\n try {\n this.options.onError?.(error);\n } catch {\n /* ignore */\n }\n this.emitter.emit(\"error\", error);\n }\n\n private log(...args: unknown[]): void {\n if (this.options.debug && typeof console !== \"undefined\") console.debug(\"[Guidely]\", ...args);\n }\n\n // ---------------------------------------------------------------------------\n // Static helpers (used by the embed)\n // ---------------------------------------------------------------------------\n\n /** Creates (or returns the existing) client and starts initialisation. */\n static init(options: GuidelyOptions): GuidelyClient {\n if (current && !current.destroyed && current.options.projectId === options.projectId) return current;\n current?.destroy();\n current = new GuidelyClient(options);\n void current.init();\n return current;\n }\n\n /** The most recently created client, if any. */\n static get(): GuidelyClient | null {\n return current && !current.destroyed ? current : null;\n }\n}\n\nlet current: GuidelyClient | null = null;\n\nfunction safePath(url: string): string {\n try {\n const u = new URL(url, \"http://localhost\");\n return u.pathname + u.search;\n } catch {\n return url;\n }\n}\n\n/**\n * Creates a Guidely client and starts loading configuration. Throws a friendly error when called\n * during server-side rendering; framework adapters guard this for you.\n */\nexport function createGuidely(options: GuidelyOptions): GuidelyClient {\n const client = new GuidelyClient(options);\n current = client;\n void client.init();\n return client;\n}\n","import { type AppSnapshot, type AuthoringPick, type AuthoringSessionInfo, type ProjectTheme, type SelectorStrategy, type TargetingContext } from \"@guidelytech/shared\";\nimport { highlightSelectors, previewStep, runGuide, startAuthoring, type AuthoringSession, type GuideController, type PreviewHandle, type RunnableGuide } from \"@guidelytech/guide-runtime\";\nimport type { Api } from \"./http\";\nimport { captureSnapshot } from \"./snapshot\";\nimport { KEYS, readJson, writeJson, type KeyValueStore } from \"./storage\";\n\n/** Schemas are only needed in authoring mode; load them lazily so the normal runtime stays zod-free. */\nasync function loadSchemas() {\n const m = await import(\"@guidelytech/shared\");\n return { StepSchema: m.StepSchema, GuideConfigSchema: m.GuideConfigSchema };\n}\n\nexport const AUTHORING_PARAM = \"guidely_authoring\";\nexport const HEARTBEAT_MS = 15000;\n/** Quiet period after DOM changes / navigation before a new page snapshot is sent. */\nexport const SNAPSHOT_DEBOUNCE_MS = 800;\n/** Upper bound on how long continuous DOM churn can delay a snapshot. */\nexport const SNAPSHOT_MAX_WAIT_MS = 4000;\n\n/** Messages the SDK posts to the dashboard window (`window.opener`). */\nexport type AuthoringOutgoingMessage =\n | { type: \"guidely:authoring-ready\"; sessionId: string; url: string }\n | { type: \"guidely:pick\"; sessionId: string; pick: AuthoringPick }\n | { type: \"guidely:highlight-result\"; sessionId: string; counts: number[]; resolved: boolean }\n | { type: \"guidely:preview-ended\"; sessionId: string; reason: string }\n | { type: \"guidely:exit\"; sessionId: string }\n | { type: \"guidely:pong\"; sessionId: string; url: string }\n | { type: \"guidely:snapshot\"; sessionId: string; snapshot: AppSnapshot };\n\n/** Messages the dashboard may post to the app window (origin-checked against `dashboardOrigin`). */\nexport type AuthoringIncomingMessage =\n | { type: \"guidely:preview-step\"; step: unknown; theme?: Partial<ProjectTheme> | null; appearance?: unknown }\n | { type: \"guidely:preview-guide\"; guide: { id?: string; key?: string; name?: string; kind?: string; version?: number; config: unknown } }\n | { type: \"guidely:highlight\"; selectors: SelectorStrategy[] }\n | { type: \"guidely:stop-preview\" }\n | { type: \"guidely:ping\" }\n | { type: \"guidely:request-snapshot\" }\n | { type: \"guidely:exit\" };\n\nexport interface AuthoringBridgeOptions {\n api: Api;\n sessionStore: KeyValueStore;\n theme: () => Partial<ProjectTheme>;\n ctx: () => TargetingContext;\n maskSelectors: string[];\n onError: (err: unknown) => void;\n onActive: (active: boolean) => void;\n}\n\n/**\n * Detects `?guidely_authoring=<token>`, verifies the session with the public API, runs the\n * runtime's element picker and bridges picks/previews with the dashboard via `postMessage`.\n */\nexport class AuthoringBridge {\n private token: string | null = null;\n private info: AuthoringSessionInfo | null = null;\n private session: AuthoringSession | null = null;\n private heartbeat: ReturnType<typeof setInterval> | null = null;\n private preview: PreviewHandle | null = null;\n private previewGuide: GuideController | null = null;\n private active = false;\n private observer: MutationObserver | null = null;\n private snapshotTimer: ReturnType<typeof setTimeout> | null = null;\n private snapshotDue = 0;\n private lastSnapshot = \"\";\n\n constructor(private readonly opts: AuthoringBridgeOptions) {}\n\n isActive(): boolean {\n return this.active;\n }\n\n /** Returns true when a token was found (in the URL or the session marker) and verification started. */\n detect(): boolean {\n if (typeof window === \"undefined\") return false;\n let token: string | null = null;\n try {\n const url = new URL(window.location.href);\n token = url.searchParams.get(AUTHORING_PARAM);\n if (token) {\n url.searchParams.delete(AUTHORING_PARAM);\n window.history.replaceState(window.history.state, \"\", url.toString());\n }\n } catch {\n token = null;\n }\n if (!token) {\n const marker = readJson<{ token?: string } | null>(this.opts.sessionStore, KEYS.authoring, null);\n token = marker?.token ?? null;\n }\n if (!token) return false;\n this.token = token;\n writeJson(this.opts.sessionStore, KEYS.authoring, { token });\n void this.start();\n return true;\n }\n\n private async start(): Promise<void> {\n if (!this.token) return;\n try {\n const res = await this.opts.api.get<AuthoringSessionInfo>(\"/authoring/session\", { params: { token: this.token } });\n if (!res.ok || !res.data) {\n this.opts.sessionStore.remove(KEYS.authoring);\n this.opts.onError(new Error(`[Guidely] authoring session invalid or expired (${res.status})`));\n return;\n }\n this.info = res.data;\n if (Date.parse(this.info.expiresAt) < Date.now()) {\n this.opts.sessionStore.remove(KEYS.authoring);\n this.opts.onError(new Error(\"[Guidely] authoring session expired\"));\n return;\n }\n this.active = true;\n this.opts.onActive(true);\n this.session = startAuthoring({\n dashboardOrigin: this.info.dashboardOrigin,\n onPick: (pick) => this.sendPick(pick),\n onExit: () => this.stop(),\n });\n this.heartbeat = setInterval(() => {\n void this.opts.api.post(\"/authoring/session/heartbeat\", {}, { params: { token: this.token ?? undefined } }).catch(() => {});\n }, HEARTBEAT_MS);\n this.post({ type: \"guidely:authoring-ready\", sessionId: this.info.id, url: window.location.href });\n this.watchPage();\n } catch (err) {\n this.opts.onError(err);\n }\n }\n\n private masked(el: Element): boolean {\n return this.opts.maskSelectors.some((sel) => {\n try {\n return !!el.closest(sel);\n } catch {\n return false;\n }\n });\n }\n\n private sendPick(raw: AuthoringPick & { element: Element }): void {\n if (!this.info || !this.token) return;\n const { element, ...rest } = raw;\n const pick: AuthoringPick = this.masked(element) ? { ...rest, textSnapshot: \"\", selectors: rest.selectors.filter((s) => s.kind !== \"text\") } : rest;\n pick.url = window.location.href;\n this.post({ type: \"guidely:pick\", sessionId: this.info.id, pick });\n void this.opts.api.post(\"/authoring/session/picks\", pick, { params: { token: this.token } }).catch((err) => this.opts.onError(err));\n }\n\n /** Sends a snapshot now and again whenever the page settles after DOM changes or navigation. */\n private watchPage(): void {\n this.scheduleSnapshot();\n if (typeof MutationObserver === \"undefined\") return;\n this.observer = new MutationObserver(() => this.scheduleSnapshot());\n this.observer.observe(document.documentElement, { subtree: true, childList: true, attributes: true, characterData: true });\n }\n\n private scheduleSnapshot(): void {\n const now = Date.now();\n if (!this.snapshotTimer) this.snapshotDue = now + SNAPSHOT_MAX_WAIT_MS;\n else clearTimeout(this.snapshotTimer);\n this.snapshotTimer = setTimeout(() => this.sendSnapshot(), Math.max(0, Math.min(SNAPSHOT_DEBOUNCE_MS, this.snapshotDue - now)));\n }\n\n private sendSnapshot(): void {\n if (this.snapshotTimer) clearTimeout(this.snapshotTimer);\n this.snapshotTimer = null;\n if (!this.info || !this.active) return;\n try {\n const snapshot = captureSnapshot(document, this.opts.maskSelectors);\n if (!snapshot || snapshot.html === this.lastSnapshot) return;\n this.lastSnapshot = snapshot.html;\n this.post({ type: \"guidely:snapshot\", sessionId: this.info.id, snapshot });\n } catch (err) {\n this.opts.onError(err);\n }\n }\n\n private post(message: AuthoringOutgoingMessage): void {\n if (!this.info) return;\n try {\n window.opener?.postMessage(message, this.info.dashboardOrigin);\n } catch {\n /* opener may be gone */\n }\n }\n\n private stopPreview(): void {\n this.preview?.destroy();\n this.preview = null;\n this.previewGuide?.destroy();\n this.previewGuide = null;\n this.session?.setPicking(true);\n }\n\n /** Handles `message` events; ignores anything not from `dashboardOrigin`. */\n async handleMessage(e: MessageEvent): Promise<void> {\n if (!this.active || !this.info) return;\n if (e.origin !== this.info.dashboardOrigin) return;\n const msg = e.data as AuthoringIncomingMessage | null;\n if (!msg || typeof msg !== \"object\" || typeof msg.type !== \"string\") return;\n try {\n switch (msg.type) {\n case \"guidely:preview-step\": {\n this.stopPreview();\n const { StepSchema, GuideConfigSchema } = await loadSchemas();\n const step = StepSchema.parse(msg.step);\n const appearance = msg.appearance ? GuideConfigSchema.shape.appearance.parse(msg.appearance) : undefined;\n this.session?.setPicking(false);\n this.session?.setStatus(`Previewing step “${step.title || step.id}” — close it to continue picking`);\n this.preview = previewStep(step, { ...this.opts.theme(), ...(msg.theme || {}) }, {\n appearance,\n onEnd: () => {\n this.preview = null;\n this.session?.setPicking(true);\n this.session?.setStatus(\"Guidely authoring — hover an element and click to select · Esc to cancel\");\n this.post({ type: \"guidely:preview-ended\", sessionId: this.info!.id, reason: \"step\" });\n },\n });\n break;\n }\n case \"guidely:preview-guide\": {\n this.stopPreview();\n const g = msg.guide;\n const guide: RunnableGuide = { id: g.id || \"preview\", key: g.key || \"preview\", name: g.name || \"Preview\", kind: g.kind || \"flow\", version: g.version ?? 0, config: (await loadSchemas()).GuideConfigSchema.parse(g.config) };\n this.session?.setPicking(false);\n this.session?.setStatus(`Previewing “${guide.name}”`);\n this.previewGuide = runGuide(guide, {\n theme: this.opts.theme(),\n ctx: this.opts.ctx,\n onNavigate: (url, newTab) => (newTab ? window.open(url, \"_blank\", \"noopener\") : window.location.assign(url)),\n onEnd: (reason) => {\n this.previewGuide = null;\n this.session?.setPicking(true);\n this.post({ type: \"guidely:preview-ended\", sessionId: this.info!.id, reason });\n },\n });\n this.previewGuide.start();\n break;\n }\n case \"guidely:highlight\": {\n const result = highlightSelectors(Array.isArray(msg.selectors) ? msg.selectors : [], { durationMs: 3000 });\n this.post({ type: \"guidely:highlight-result\", sessionId: this.info.id, counts: result.counts, resolved: !!result.resolved });\n break;\n }\n case \"guidely:stop-preview\":\n this.stopPreview();\n break;\n case \"guidely:request-snapshot\":\n this.lastSnapshot = \"\";\n this.sendSnapshot();\n break;\n case \"guidely:ping\":\n this.post({ type: \"guidely:pong\", sessionId: this.info.id, url: window.location.href });\n break;\n case \"guidely:exit\":\n this.stop();\n break;\n default:\n break;\n }\n } catch (err) {\n this.opts.onError(err);\n }\n }\n\n /** Leaves authoring mode and clears the session marker. */\n stop(): void {\n if (!this.active) return;\n this.active = false;\n this.stopPreview();\n this.observer?.disconnect();\n this.observer = null;\n if (this.snapshotTimer) clearTimeout(this.snapshotTimer);\n this.snapshotTimer = null;\n if (this.heartbeat) clearInterval(this.heartbeat);\n this.heartbeat = null;\n this.session?.stop();\n this.session = null;\n this.opts.sessionStore.remove(KEYS.authoring);\n if (this.info) this.post({ type: \"guidely:exit\", sessionId: this.info.id });\n this.opts.onActive(false);\n }\n}\n","import type { AppSnapshot } from \"@guidelytech/shared\";\n\n/** Snapshots larger than this are not sent (postMessage copies the string). */\nexport const MAX_SNAPSHOT_BYTES = 6 * 1024 * 1024;\n\nconst STRIP = \"script, noscript, template, #guidely-root, [data-guidely], meta[http-equiv], link[rel~='preload'], link[rel~='modulepreload'], link[rel~='prefetch'], link[rel~='manifest'], link[rel~='serviceworker']\";\n\n/** Text of a stylesheet built through the CSSOM (CSS-in-JS often leaves `<style>` empty). */\nfunction rulesText(sheet: CSSStyleSheet | null | undefined): string | null {\n if (!sheet) return null;\n try {\n return Array.from(sheet.cssRules, (r) => r.cssText).join(\"\\n\");\n } catch {\n return null; // cross-origin sheet\n }\n}\n\n/** Replaces text inside masked elements with bullets of the same length, keeping the layout. */\nfunction maskText(root: Element): void {\n const walker = root.ownerDocument.createTreeWalker(root, NodeFilter.SHOW_TEXT);\n for (let n = walker.nextNode(); n; n = walker.nextNode()) {\n n.textContent = (n.textContent ?? \"\").replace(/\\S/g, \"•\");\n }\n}\n\n/**\n * Serializes the current page into a static HTML document for the dashboard's editor canvas.\n * Scripts, event handlers, Guidely's own UI and form values are dropped; `maskSelectors` text is\n * replaced with bullets. Same-origin CSSOM rules are inlined; everything else resolves through a\n * `<base href>` so stylesheets and images load from the app.\n */\nexport function captureSnapshot(doc: Document, maskSelectors: string[], maxBytes = MAX_SNAPSHOT_BYTES): AppSnapshot | null {\n const win = doc.defaultView;\n if (!win || !doc.documentElement) return null;\n const clone = doc.documentElement.cloneNode(true) as HTMLElement;\n\n // Elements whose state lives outside their markup are matched to the clone by document order,\n // so do this before anything is removed from the clone.\n const origStyles = doc.documentElement.querySelectorAll(\"style\");\n clone.querySelectorAll(\"style\").forEach((el, i) => {\n const css = rulesText(origStyles[i]?.sheet as CSSStyleSheet | null);\n if (css !== null && css.length > (el.textContent ?? \"\").length) el.textContent = css;\n });\n const origFrames = doc.documentElement.querySelectorAll(\"iframe, canvas, video, embed, object\");\n clone.querySelectorAll(\"iframe, canvas, video, embed, object\").forEach((el, i) => {\n const r = origFrames[i]?.getBoundingClientRect();\n const box = doc.createElement(\"div\");\n box.setAttribute(\"style\", `${el.getAttribute(\"style\") ?? \"\"};width:${r?.width ?? 0}px;height:${r?.height ?? 0}px;background:#e2e8f0;border-radius:4px`);\n if (el.getAttribute(\"class\")) box.setAttribute(\"class\", el.getAttribute(\"class\")!);\n el.replaceWith(box);\n });\n\n clone.querySelectorAll(STRIP).forEach((el) => el.remove());\n for (const sel of maskSelectors) {\n try {\n clone.querySelectorAll(sel).forEach(maskText);\n } catch {\n /* invalid selector */\n }\n }\n clone.querySelectorAll(\"*\").forEach((el) => {\n for (const attr of Array.from(el.attributes)) {\n const name = attr.name.toLowerCase();\n if (name.startsWith(\"on\") || ((name === \"href\" || name === \"src\" || name === \"action\") && /^\\s*javascript:/i.test(attr.value))) el.removeAttribute(attr.name);\n }\n if (el instanceof HTMLInputElement) {\n el.removeAttribute(\"value\");\n el.removeAttribute(\"checked\");\n } else if (el instanceof HTMLTextAreaElement) {\n el.textContent = \"\";\n }\n el.removeAttribute(\"autofocus\");\n });\n\n const adopted = Array.from((doc as Document & { adoptedStyleSheets?: CSSStyleSheet[] }).adoptedStyleSheets ?? [])\n .map(rulesText)\n .filter(Boolean)\n .join(\"\\n\");\n let head = clone.querySelector(\"head\");\n if (!head) {\n head = doc.createElement(\"head\");\n clone.prepend(head);\n }\n if (adopted) {\n const style = doc.createElement(\"style\");\n style.textContent = adopted;\n head.append(style);\n }\n clone.querySelectorAll(\"base\").forEach((el) => el.remove());\n const base = doc.createElement(\"base\");\n base.setAttribute(\"href\", doc.baseURI || win.location.href);\n base.setAttribute(\"target\", \"_blank\");\n head.prepend(base);\n\n const html = `<!DOCTYPE html>\\n${clone.outerHTML}`;\n if (html.length > maxBytes) return null;\n return { html, url: win.location.href, title: doc.title, width: win.innerWidth, height: win.innerHeight, capturedAt: new Date().toISOString() };\n}\n","export type StorageKind = \"local\" | \"session\" | \"memory\";\n\n/** Minimal synchronous key/value store; never throws (private mode, quota, SSR). */\nexport interface KeyValueStore {\n get(key: string): string | null;\n set(key: string, value: string): void;\n remove(key: string): void;\n}\n\nexport function memoryStore(): KeyValueStore {\n const map = new Map<string, string>();\n return { get: (k) => map.get(k) ?? null, set: (k, v) => void map.set(k, v), remove: (k) => void map.delete(k) };\n}\n\nfunction webStore(area: \"localStorage\" | \"sessionStorage\"): KeyValueStore | null {\n try {\n if (typeof window === \"undefined\") return null;\n const s = window[area];\n if (!s) return null;\n const probe = \"__guidely_probe__\";\n s.setItem(probe, \"1\");\n s.removeItem(probe);\n return {\n get: (k) => {\n try {\n return s.getItem(k);\n } catch {\n return null;\n }\n },\n set: (k, v) => {\n try {\n s.setItem(k, v);\n } catch {\n /* quota / private mode */\n }\n },\n remove: (k) => {\n try {\n s.removeItem(k);\n } catch {\n /* ignore */\n }\n },\n };\n } catch {\n return null;\n }\n}\n\n/** Creates a store of the requested kind, degrading to memory when unavailable. */\nexport function createStorage(kind: StorageKind = \"local\"): KeyValueStore {\n if (kind === \"memory\") return memoryStore();\n return webStore(kind === \"local\" ? \"localStorage\" : \"sessionStorage\") ?? memoryStore();\n}\n\nexport function readJson<T>(store: KeyValueStore, key: string, fallback: T): T {\n const raw = store.get(key);\n if (raw == null) return fallback;\n try {\n return JSON.parse(raw) as T;\n } catch {\n return fallback;\n }\n}\n\nexport function writeJson(store: KeyValueStore, key: string, value: unknown): void {\n try {\n store.set(key, JSON.stringify(value));\n } catch {\n /* ignore */\n }\n}\n\n/** Storage keys used by the SDK (documented for integrators). */\nexport const KEYS = {\n anon: \"guidely:anon\",\n seen: \"guidely:seen\",\n config: (key: string) => `guidely:config:${key}`,\n etag: (key: string) => `guidely:etag:${key}`,\n state: (key: string) => `guidely:state:${key}`,\n user: (key: string) => `guidely:user:${key}`,\n queue: (key: string) => `guidely:queue:${key}`,\n session: \"guidely:session\",\n active: \"guidely:active\",\n authoring: \"guidely:authoring\",\n /** Messenger conversations this browser can read: [{ id, token }]. */\n conversations: (key: string) => `guidely:conversations:${key}`,\n} as const;\n","import type { TargetingContext } from \"@guidelytech/shared\";\n\nexport interface DeviceInfo {\n type: \"desktop\" | \"tablet\" | \"mobile\";\n browser?: string;\n os?: string;\n}\n\n/** Lightweight UA sniffing (good enough for targeting; not for feature detection). */\nexport function detectDevice(ua: string, width: number): DeviceInfo {\n const u = ua || \"\";\n let type: DeviceInfo[\"type\"] = \"desktop\";\n if (/iPad|Tablet|PlayBook|Silk/i.test(u) || (/Android/i.test(u) && !/Mobile/i.test(u))) type = \"tablet\";\n else if (/Mobi|iPhone|iPod|Android.*Mobile|Windows Phone/i.test(u)) type = \"mobile\";\n else if (width > 0 && width < 768) type = \"mobile\";\n else if (width > 0 && width < 1024) type = \"tablet\";\n let browser: string | undefined;\n if (/Edg\\//i.test(u)) browser = \"edge\";\n else if (/OPR\\/|Opera/i.test(u)) browser = \"opera\";\n else if (/SamsungBrowser/i.test(u)) browser = \"samsung\";\n else if (/Chrome\\/|CriOS/i.test(u)) browser = \"chrome\";\n else if (/Firefox\\/|FxiOS/i.test(u)) browser = \"firefox\";\n else if (/Safari\\//i.test(u) && /Version\\//i.test(u)) browser = \"safari\";\n else if (/MSIE|Trident/i.test(u)) browser = \"ie\";\n let os: string | undefined;\n if (/Windows/i.test(u)) os = \"windows\";\n else if (/iPhone|iPad|iPod/i.test(u)) os = \"ios\";\n else if (/Mac OS X|Macintosh/i.test(u)) os = \"macos\";\n else if (/Android/i.test(u)) os = \"android\";\n else if (/CrOS/i.test(u)) os = \"chromeos\";\n else if (/Linux/i.test(u)) os = \"linux\";\n return { type, browser, os };\n}\n\nexport interface ContextInput {\n anonymousId: string;\n userId?: string | null;\n userAttributes: Record<string, unknown>;\n accountAttributes: Record<string, unknown>;\n url: string;\n firstVisit: boolean;\n eventsSeen: Iterable<string>;\n completedGuides: Iterable<string>;\n dismissedGuides: Iterable<string>;\n seenGuides: Iterable<string>;\n completedChecklists: Iterable<string>;\n audienceIds: Iterable<string>;\n environment: string;\n locale?: string;\n device?: DeviceInfo;\n now?: Date;\n}\n\n/** Builds the `TargetingContext` consumed by `evaluateRules`. */\nexport function buildContext(input: ContextInput): TargetingContext {\n let path = \"\";\n const query: Record<string, string> = {};\n try {\n const u = new URL(input.url, \"http://localhost\");\n path = u.pathname;\n u.searchParams.forEach((v, k) => {\n query[k] = v;\n });\n } catch {\n path = input.url;\n }\n const device = input.device ?? (typeof navigator !== \"undefined\" ? detectDevice(navigator.userAgent, typeof window !== \"undefined\" ? window.innerWidth : 0) : { type: \"desktop\" });\n return {\n anonymousId: input.anonymousId,\n userId: input.userId ?? null,\n userAttributes: input.userAttributes,\n accountAttributes: input.accountAttributes,\n url: input.url,\n path,\n query,\n device,\n firstVisit: input.firstVisit,\n eventsSeen: new Set(input.eventsSeen),\n completedGuides: new Set(input.completedGuides),\n dismissedGuides: new Set(input.dismissedGuides),\n seenGuides: new Set(input.seenGuides),\n completedChecklists: new Set(input.completedChecklists),\n audienceIds: new Set(input.audienceIds),\n now: input.now ?? new Date(),\n environment: input.environment,\n locale: input.locale ?? (typeof navigator !== \"undefined\" ? navigator.language : undefined),\n };\n}\n","type AnyFn = (...args: any[]) => void;\n\n/** Tiny typed event emitter. Listener errors are reported, never thrown into the caller. */\nexport class Emitter<Events extends { [K in keyof Events]: AnyFn }> {\n private listeners = new Map<keyof Events, Set<AnyFn>>();\n constructor(private readonly onError?: (err: unknown) => void) {}\n\n on<K extends keyof Events>(event: K, cb: Events[K]): () => void {\n let set = this.listeners.get(event);\n if (!set) {\n set = new Set();\n this.listeners.set(event, set);\n }\n set.add(cb);\n return () => this.off(event, cb);\n }\n\n off<K extends keyof Events>(event: K, cb: Events[K]): void {\n this.listeners.get(event)?.delete(cb);\n }\n\n emit<K extends keyof Events>(event: K, ...args: Parameters<Events[K]>): void {\n const set = this.listeners.get(event);\n if (!set) return;\n for (const cb of Array.from(set)) {\n try {\n cb(...args);\n } catch (err) {\n this.onError?.(err);\n }\n }\n }\n\n clear(): void {\n this.listeners.clear();\n }\n}\n","import type { FrequencyConfig, PublishedGuide } from \"@guidelytech/shared\";\n\n/** Per-guide state kept locally and merged with the server's `IdentifyResponse.guideState`. */\nexport interface GuideLocalState {\n impressions: number;\n completedAt?: string | null;\n dismissedAt?: string | null;\n lastShownAt?: string | null;\n}\n\nconst HOUR = 3600 * 1000;\n\n/**\n * Pure frequency evaluation. `shownThisSession` comes from session storage.\n * - `once`: a single impression ever (unless `reshowAfterDismiss` and it was only dismissed).\n * - `once_per_session`: at most once per browser session.\n * - `every_time`: on every trigger (still blocked by completion/dismissal rules below).\n * - `interval`: at most once every `intervalHours`.\n * `maxImpressions` caps total impressions; dismissal blocks re-showing unless `reshowAfterDismiss`\n * (then `cooldownHours` must have elapsed); completion blocks unless mode is `every_time`.\n */\nexport function isFrequencyEligible(freq: FrequencyConfig, state: GuideLocalState | undefined, shownThisSession: boolean, now: number = Date.now()): boolean {\n const s = state ?? { impressions: 0 };\n if (freq.maxImpressions != null && s.impressions >= freq.maxImpressions) return false;\n if (s.completedAt && freq.mode !== \"every_time\") return false;\n if (s.dismissedAt) {\n if (!freq.reshowAfterDismiss) return false;\n if (freq.cooldownHours > 0 && now - Date.parse(s.dismissedAt) < freq.cooldownHours * HOUR) return false;\n }\n switch (freq.mode) {\n case \"once\":\n return s.impressions === 0 || (!!s.dismissedAt && freq.reshowAfterDismiss);\n case \"once_per_session\":\n return !shownThisSession;\n case \"interval\": {\n if (!s.lastShownAt) return true;\n const hours = freq.intervalHours ?? 24;\n return now - Date.parse(s.lastShownAt) >= hours * HOUR;\n }\n case \"every_time\":\n default:\n return true;\n }\n}\n\n/**\n * Exclusive guides (flows, modals, tooltips, announcements, surveys) run one at a time.\n * Banners, checklists and hotspot-only tooltips can coexist with an active flow.\n */\nexport function isExclusiveGuide(guide: PublishedGuide): boolean {\n if (guide.kind === \"banner\" || guide.kind === \"checklist\") return false;\n const steps = guide.config.steps;\n if (steps.length > 0 && steps.every((s) => s.type === \"hotspot\" || s.type === \"banner\")) return false;\n return true;\n}\n\n/** Is `a` mutually exclusive with `b` (by id or key, in either direction)? */\nexport function areMutuallyExclusive(a: PublishedGuide, b: PublishedGuide): boolean {\n const la = a.config.frequency.mutuallyExclusiveWith;\n const lb = b.config.frequency.mutuallyExclusiveWith;\n return la.includes(b.id) || la.includes(b.key) || lb.includes(a.id) || lb.includes(a.key);\n}\n\n/** Survey scheduling window. */\nexport function isWithinSchedule(guide: PublishedGuide, now: number = Date.now()): boolean {\n const s = guide.config.survey;\n if (!s) return true;\n if (s.startAt && now < Date.parse(s.startAt)) return false;\n if (s.endAt && now > Date.parse(s.endAt)) return false;\n return true;\n}\n","export interface ApiResponse<T> {\n status: number;\n ok: boolean;\n data: T | null;\n etag: string | null;\n}\n\nexport type FetchLike = typeof fetch;\n\n/** Thin HTTP client for the public SDK API. Adds the public key as query + header. */\nexport class Api {\n constructor(\n private readonly baseUrl: string,\n private readonly key: string,\n private readonly fetchImpl?: FetchLike,\n ) {}\n\n url(path: string, params: Record<string, string | undefined> = {}): string {\n const u = new URL(`${this.baseUrl.replace(/\\/$/, \"\")}/api/v1/sdk${path}`);\n u.searchParams.set(\"key\", this.key);\n for (const [k, v] of Object.entries(params)) if (v != null) u.searchParams.set(k, v);\n return u.toString();\n }\n\n private get fetcher(): FetchLike | null {\n if (this.fetchImpl) return this.fetchImpl;\n return typeof fetch === \"function\" ? fetch.bind(globalThis) : null;\n }\n\n async request<T>(method: \"GET\" | \"POST\", path: string, options: { body?: unknown; etag?: string | null; params?: Record<string, string | undefined>; keepalive?: boolean; timeoutMs?: number; headers?: Record<string, string> } = {}): Promise<ApiResponse<T>> {\n const f = this.fetcher;\n if (!f) throw new Error(\"fetch is not available\");\n const headers: Record<string, string> = { ...options.headers, \"X-Guidely-Key\": this.key, Accept: \"application/json\" };\n if (options.body !== undefined) headers[\"Content-Type\"] = \"application/json\";\n if (options.etag) headers[\"If-None-Match\"] = options.etag;\n const ac = typeof AbortController !== \"undefined\" ? new AbortController() : null;\n const timer = ac ? setTimeout(() => ac.abort(), options.timeoutMs ?? 10000) : null;\n try {\n const res = await f(this.url(path, options.params), {\n method,\n headers,\n body: options.body === undefined ? undefined : JSON.stringify(options.body),\n keepalive: options.keepalive,\n signal: ac?.signal,\n credentials: \"omit\",\n mode: \"cors\",\n });\n let data: T | null = null;\n if (res.status !== 304 && res.status !== 204) {\n try {\n data = (await res.json()) as T;\n } catch {\n data = null;\n }\n }\n return { status: res.status, ok: res.ok, data, etag: res.headers?.get?.(\"etag\") ?? null };\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n\n get<T>(path: string, options?: { etag?: string | null; params?: Record<string, string | undefined>; headers?: Record<string, string> }): Promise<ApiResponse<T>> {\n return this.request<T>(\"GET\", path, options);\n }\n\n post<T>(path: string, body: unknown, options?: { params?: Record<string, string | undefined>; keepalive?: boolean; headers?: Record<string, string> }): Promise<ApiResponse<T>> {\n return this.request<T>(\"POST\", path, { body, ...options });\n }\n\n /**\n * POST that may answer with server-sent events. Each event is passed to `onEvent`; a JSON answer is\n * returned instead. No timeout: Scout replies can take a while and the server keeps the stream alive.\n */\n async stream<T>(path: string, body: unknown, onEvent: (event: string, data: unknown) => void, headers: Record<string, string> = {}): Promise<ApiResponse<T>> {\n const f = this.fetcher;\n if (!f) throw new Error(\"fetch is not available\");\n const res = await f(this.url(path), {\n method: \"POST\",\n headers: { ...headers, \"X-Guidely-Key\": this.key, Accept: \"text/event-stream, application/json\", \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n credentials: \"omit\",\n mode: \"cors\",\n });\n const type = res.headers?.get?.(\"content-type\") ?? \"\";\n if (!type.includes(\"text/event-stream\") || !res.body) {\n let data: T | null = null;\n try {\n data = (await res.json()) as T;\n } catch {\n data = null;\n }\n return { status: res.status, ok: res.ok, data, etag: null };\n }\n await readEventStream(res.body, onEvent);\n return { status: res.status, ok: res.ok, data: null, etag: null };\n }\n\n /** `navigator.sendBeacon` when available (page unload); returns false when it could not be queued. */\n beacon(path: string, body: unknown): boolean {\n try {\n if (typeof navigator === \"undefined\" || typeof navigator.sendBeacon !== \"function\") return false;\n // text/plain is a CORS-safelisted type: cross-origin beacons need no preflight (which\n // browsers drop during unload). The API parses the body regardless of content type.\n const blob = new Blob([JSON.stringify(body)], { type: \"text/plain;charset=UTF-8\" });\n return navigator.sendBeacon(this.url(path), blob);\n } catch {\n return false;\n }\n }\n}\n\nexport const sleep = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));\n\n/** Exponential backoff helper: 1s → 2s → 4s … capped. */\nexport function backoffMs(attempt: number, baseMs = 1000, maxMs = 30000): number {\n return Math.min(maxMs, baseMs * 2 ** Math.max(0, attempt));\n}\n\n/** Fire-and-forget POST with bounded retries (used for state sync; never blocks UI). */\nexport async function postWithRetry<T>(api: Api, path: string, body: unknown, attempts = 3, baseMs = 500): Promise<ApiResponse<T> | null> {\n for (let i = 0; i < attempts; i++) {\n try {\n const res = await api.post<T>(path, body);\n if (res.ok || (res.status >= 400 && res.status < 500 && res.status !== 429)) return res;\n } catch {\n /* network error → retry */\n }\n if (i < attempts - 1) await sleep(backoffMs(i, baseMs, 8000));\n }\n return null;\n}\n\n/** Parses a `text/event-stream` body (`event:` + single-line JSON `data:`; comment lines ignored). */\nexport async function readEventStream(body: ReadableStream<Uint8Array>, onEvent: (event: string, data: unknown) => void): Promise<void> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n const dispatch = (raw: string) => {\n let event = \"message\";\n const data: string[] = [];\n for (const line of raw.split(\"\\n\")) {\n if (!line || line.startsWith(\":\")) continue;\n const i = line.indexOf(\":\");\n const field = i < 0 ? line : line.slice(0, i);\n const value = i < 0 ? \"\" : line.slice(i + 1).replace(/^ /, \"\");\n if (field === \"event\") event = value;\n else if (field === \"data\") data.push(value);\n }\n if (!data.length) return;\n try {\n onEvent(event, JSON.parse(data.join(\"\\n\")));\n } catch {\n /* ignore malformed events */\n }\n };\n for (;;) {\n const { done, value } = await reader.read();\n if (value) buffer += decoder.decode(value, { stream: true }).replace(/\\r\\n?/g, \"\\n\");\n let sep: number;\n while ((sep = buffer.indexOf(\"\\n\\n\")) >= 0) {\n dispatch(buffer.slice(0, sep));\n buffer = buffer.slice(sep + 2);\n }\n if (done) break;\n }\n if (buffer.trim()) dispatch(buffer);\n}\n","import type {\n ConversationLookupResponse,\n ConversationMessagesResponse,\n MessengerConversation,\n MessengerMessage,\n ResourceCenterArticle,\n SdkArticlesResponse,\n StartConversationResponse,\n} from \"@guidelytech/shared\";\nimport type { MessengerApi, MessengerStreamHandlers } from \"@guidelytech/guide-runtime/messenger\";\nimport type { Api } from \"./http\";\nimport { KEYS, readJson, writeJson, type KeyValueStore } from \"./storage\";\n\ninterface StoredConversation {\n id: string;\n token: string;\n}\n\nconst MAX_STORED = 50;\nconst TOKEN_HEADER = \"X-Guidely-Conversation\";\n\nexport interface MessengerTransportOptions {\n api: Api;\n store: KeyValueStore;\n projectId: string;\n anonymousId: () => string;\n userId: () => string | null;\n /** Page URL to attach to new conversations (omitted when URL collection is off). */\n pageUrl: () => string | undefined;\n}\n\n/** Conversation tokens this browser holds (the only way to read a conversation). */\nexport function storedConversations(store: KeyValueStore, projectId: string): StoredConversation[] {\n const list = readJson<StoredConversation[]>(store, KEYS.conversations(projectId), []);\n return Array.isArray(list) ? list.filter((c) => c && typeof c.id === \"string\" && typeof c.token === \"string\") : [];\n}\n\nexport function forgetConversations(store: KeyValueStore, projectId: string) {\n store.remove(KEYS.conversations(projectId));\n}\n\nclass HttpError extends Error {\n constructor(readonly status: number) {\n super(`Request failed (${status})`);\n }\n}\n\n/** The messenger's server access over the public SDK API. */\nexport function createMessengerTransport(opts: MessengerTransportOptions): MessengerApi {\n const { api, store, projectId } = opts;\n const tokenFor = (id: string) => storedConversations(store, projectId).find((c) => c.id === id)?.token ?? \"\";\n const remember = (id: string, token: string) => {\n const rest = storedConversations(store, projectId).filter((c) => c.id !== id);\n writeJson(store, KEYS.conversations(projectId), [{ id, token }, ...rest].slice(0, MAX_STORED));\n };\n const forget = (id: string) => writeJson(store, KEYS.conversations(projectId), storedConversations(store, projectId).filter((c) => c.id !== id));\n\n /** Dispatches either SSE events or a JSON answer to the stream handlers. */\n async function exchange(path: string, body: unknown, headers: Record<string, string>, h: MessengerStreamHandlers, onStarted?: (r: StartConversationResponse) => void) {\n let finished = false;\n const res = await api.stream<StartConversationResponse | ConversationMessagesResponse>(\n path,\n body,\n (event, data) => {\n if (event === \"conversation\") {\n const d = data as StartConversationResponse;\n onStarted?.(d);\n h.onConversation?.(d.conversation);\n d.messages.forEach((m) => h.onMessage(m));\n } else if (event === \"message\") h.onMessage(data as MessengerMessage);\n else if (event === \"delta\") {\n const d = data as { messageId: string; text: string };\n h.onDelta(d.messageId, d.text);\n } else if (event === \"done\") {\n const d = data as { message: MessengerMessage | null; conversation: MessengerConversation };\n finished = true;\n h.onDone(d.message, d.conversation);\n } else if (event === \"error\") h.onError((data as { message?: string })?.message ?? \"Something went wrong\");\n },\n headers,\n );\n if (!res.ok) throw new HttpError(res.status);\n if (res.data) {\n // JSON answer (no Scout reply): the stored messages and the conversation.\n const d = res.data;\n if (\"token\" in d) {\n onStarted?.(d);\n h.onConversation?.(d.conversation);\n }\n d.messages.forEach((m) => h.onMessage(m));\n h.onDone(d.messages.at(-1) ?? null, d.conversation);\n } else if (!finished) h.onError(\"The reply was interrupted\");\n }\n\n return {\n async listConversations() {\n const tokens = storedConversations(store, projectId).map((c) => c.token);\n if (!tokens.length) return [];\n const res = await api.post<ConversationLookupResponse>(\"/conversations/lookup\", { tokens });\n if (!res.ok || !res.data) throw new HttpError(res.status);\n // Drop tokens the server no longer knows (deleted by retention).\n const known = new Set(res.data.conversations.map((c) => c.id));\n for (const c of storedConversations(store, projectId)) if (!known.has(c.id)) forget(c.id);\n return res.data.conversations.map(({ token: _token, ...c }) => c);\n },\n async loadMessages(id, since) {\n const res = await api.get<ConversationMessagesResponse>(`/conversations/${encodeURIComponent(id)}/messages`, { params: { since: since ?? undefined }, headers: { [TOKEN_HEADER]: tokenFor(id) } });\n if (!res.ok || !res.data) throw new HttpError(res.status);\n return res.data;\n },\n start(text, h) {\n return exchange(\"/conversations\", { anonymousId: opts.anonymousId(), userId: opts.userId(), message: text, pageUrl: opts.pageUrl() }, {}, h, (r) => remember(r.conversation.id, r.token));\n },\n send(id, text, h) {\n return exchange(`/conversations/${encodeURIComponent(id)}/messages`, { message: text }, { [TOKEN_HEADER]: tokenFor(id) }, h);\n },\n async handoff(id) {\n const res = await api.post<ConversationMessagesResponse>(`/conversations/${encodeURIComponent(id)}/handoff`, {}, { headers: { [TOKEN_HEADER]: tokenFor(id) } });\n if (!res.ok || !res.data) throw new HttpError(res.status);\n return res.data;\n },\n async rate(id, rating) {\n const res = await api.post(`/conversations/${encodeURIComponent(id)}/rating`, { rating }, { headers: { [TOKEN_HEADER]: tokenFor(id) } });\n if (!res.ok) throw new HttpError(res.status);\n },\n async listArticles() {\n const res = await api.get<SdkArticlesResponse>(\"/articles\");\n if (!res.ok || !res.data) throw new HttpError(res.status);\n return res.data;\n },\n async getArticle(id) {\n const res = await api.get<{ article: ResourceCenterArticle }>(`/articles/${encodeURIComponent(id)}`);\n return res.ok && res.data ? res.data.article : null;\n },\n async searchArticles(q) {\n const res = await api.get<{ articles: ResourceCenterArticle[] }>(\"/resource-center/search\", { params: { q } });\n return res.ok && res.data ? res.data.articles : [];\n },\n };\n}\n","type Listener = (url: string) => void;\n\ninterface PatchedHistory extends History {\n __guidelyPatched?: { count: number; pushState: History[\"pushState\"]; replaceState: History[\"replaceState\"] };\n}\n\n/**\n * Detects SPA navigation: patches `history.pushState`/`replaceState` (reference counted, restored\n * on the last unwatch), listens to `popstate` and `hashchange`, and debounces into one callback.\n */\nexport function watchNavigation(listener: Listener, debounceMs = 50): () => void {\n if (typeof window === \"undefined\") return () => {};\n const win = window;\n const hist = win.history as PatchedHistory;\n let last = win.location.href;\n let timer: ReturnType<typeof setTimeout> | null = null;\n const check = () => {\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n timer = null;\n const href = win.location.href;\n if (href !== last) {\n last = href;\n listener(href);\n }\n }, debounceMs);\n };\n if (!hist.__guidelyPatched) {\n const pushState = hist.pushState;\n const replaceState = hist.replaceState;\n hist.__guidelyPatched = { count: 0, pushState, replaceState };\n hist.pushState = function (this: History, ...args: Parameters<History[\"pushState\"]>) {\n const r = pushState.apply(this, args);\n win.dispatchEvent(new Event(\"guidely:navigate\"));\n return r;\n };\n hist.replaceState = function (this: History, ...args: Parameters<History[\"replaceState\"]>) {\n const r = replaceState.apply(this, args);\n win.dispatchEvent(new Event(\"guidely:navigate\"));\n return r;\n };\n }\n hist.__guidelyPatched.count += 1;\n win.addEventListener(\"guidely:navigate\", check);\n win.addEventListener(\"popstate\", check);\n win.addEventListener(\"hashchange\", check);\n return () => {\n if (timer) clearTimeout(timer);\n win.removeEventListener(\"guidely:navigate\", check);\n win.removeEventListener(\"popstate\", check);\n win.removeEventListener(\"hashchange\", check);\n const p = hist.__guidelyPatched;\n if (p) {\n p.count -= 1;\n if (p.count <= 0) {\n hist.pushState = p.pushState;\n hist.replaceState = p.replaceState;\n delete hist.__guidelyPatched;\n }\n }\n };\n}\n","import type { SdkEvent } from \"@guidelytech/shared\";\nimport { backoffMs } from \"./http\";\nimport { readJson, writeJson, type KeyValueStore } from \"./storage\";\n\nexport interface EventQueueOptions {\n store: KeyValueStore;\n storageKey: string;\n /** Sends one batch. Resolve `{ ok: true }` on success, `{ ok: false, retry }` otherwise. */\n send: (events: SdkEvent[]) => Promise<{ ok: boolean; retry?: boolean }>;\n /** Synchronous best-effort send used on page hide. */\n beacon?: (events: SdkEvent[]) => boolean;\n /** Should events be flushed right now? (analytics enabled + consent granted). */\n enabled: () => boolean;\n flushIntervalMs?: number;\n maxQueue?: number;\n batchSize?: number;\n maxAttempts?: number;\n onError?: (err: unknown) => void;\n}\n\n/**\n * Bounded, persisted event queue. Batches ≤50 events every 2s (or on demand), dedupes by\n * `eventId`, retries with exponential backoff (1s→30s, 5 attempts) and keeps failed events for\n * the next flush. Drops the oldest events once the queue exceeds 200.\n */\nexport class EventQueue {\n private events: SdkEvent[] = [];\n private timer: ReturnType<typeof setTimeout> | null = null;\n private retryTimer: ReturnType<typeof setTimeout> | null = null;\n private inflight = false;\n private inflightIds = new Set<string>();\n private attempt = 0;\n private destroyed = false;\n private readonly flushIntervalMs: number;\n private readonly maxQueue: number;\n private readonly batchSize: number;\n private readonly maxAttempts: number;\n\n constructor(private readonly opts: EventQueueOptions) {\n this.flushIntervalMs = opts.flushIntervalMs ?? 2000;\n this.maxQueue = opts.maxQueue ?? 200;\n this.batchSize = opts.batchSize ?? 50;\n this.maxAttempts = opts.maxAttempts ?? 5;\n const persisted = readJson<SdkEvent[]>(opts.store, opts.storageKey, []);\n if (Array.isArray(persisted)) this.events = persisted.filter((e) => e && typeof e.eventId === \"string\").slice(-this.maxQueue);\n // Events left over from a previous page load are flushed on the next tick.\n if (this.events.length) this.schedule();\n }\n\n get size(): number {\n return this.events.length;\n }\n\n /** Pending events (read-only copy, for debugging). */\n peek(): SdkEvent[] {\n return this.events.slice();\n }\n\n enqueue(event: SdkEvent): void {\n if (this.destroyed) return;\n if (this.events.some((e) => e.eventId === event.eventId)) return;\n this.events.push(event);\n if (this.events.length > this.maxQueue) this.events.splice(0, this.events.length - this.maxQueue);\n this.persist();\n this.schedule();\n }\n\n private persist(): void {\n writeJson(this.opts.store, this.opts.storageKey, this.events);\n }\n\n private schedule(): void {\n if (this.timer || this.retryTimer || this.destroyed) return;\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.flush();\n }, this.flushIntervalMs);\n }\n\n /** Sends queued events now (one batch at a time). Safe to call at any time. */\n async flush(): Promise<void> {\n if (this.destroyed || this.inflight || !this.events.length || !this.opts.enabled()) return;\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n this.inflight = true;\n const batch = this.events.slice(0, this.batchSize);\n this.inflightIds = new Set(batch.map((e) => e.eventId));\n let ok = false;\n let retry = true;\n try {\n const res = await this.opts.send(batch);\n ok = res.ok;\n retry = res.retry ?? !res.ok;\n } catch (err) {\n this.opts.onError?.(err);\n }\n this.inflight = false;\n this.inflightIds.clear();\n if (this.destroyed) return;\n if (ok || !retry) {\n const ids = new Set(batch.map((e) => e.eventId));\n this.events = this.events.filter((e) => !ids.has(e.eventId));\n this.attempt = 0;\n this.persist();\n if (this.events.length) this.schedule();\n return;\n }\n this.attempt += 1;\n if (this.attempt >= this.maxAttempts) {\n // Give up for now; events stay queued until the next flush trigger (navigation, timer, unload).\n this.attempt = 0;\n return;\n }\n this.retryTimer = setTimeout(() => {\n this.retryTimer = null;\n void this.flush();\n }, backoffMs(this.attempt - 1));\n }\n\n /** Best-effort synchronous flush on unload using `sendBeacon`. */\n flushSync(): void {\n if (this.destroyed || !this.opts.enabled() || !this.opts.beacon) return;\n // Events already in flight (fetch with keepalive) survive unload; only beacon the rest to avoid duplicate batches.\n const batch = this.events.filter((e) => !this.inflightIds.has(e.eventId)).slice(0, this.batchSize);\n if (!batch.length) return;\n if (this.opts.beacon(batch)) {\n const ids = new Set(batch.map((e) => e.eventId));\n this.events = this.events.filter((e) => !ids.has(e.eventId));\n this.persist();\n }\n }\n\n clear(): void {\n this.events = [];\n this.persist();\n }\n\n destroy(): void {\n this.destroyed = true;\n if (this.timer) clearTimeout(this.timer);\n if (this.retryTimer) clearTimeout(this.retryTimer);\n this.timer = null;\n this.retryTimer = null;\n this.persist();\n }\n}\n"],"mappings":"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","names":["import_runtime","import_guide_runtime","current"]}
|