@ada-cx/messaging-sdk 1.0.0-setup.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.
Files changed (61) hide show
  1. package/README.md +211 -0
  2. package/dist/client/ada-settings-reader.d.ts +10 -0
  3. package/dist/client/client-channel-handlers.d.ts +92 -0
  4. package/dist/client/client-errors.d.ts +7 -0
  5. package/dist/client/client-frame-constants.d.ts +41 -0
  6. package/dist/client/client-frame-runtime.d.ts +54 -0
  7. package/dist/client/client-host-runtime.d.ts +73 -0
  8. package/dist/client/client-types.d.ts +231 -0
  9. package/dist/client/client.d.ts +843 -0
  10. package/dist/client/config-helpers.d.ts +157 -0
  11. package/dist/client/constants.d.ts +61 -0
  12. package/dist/client/core-channel-test-harness.d.ts +47 -0
  13. package/dist/client/embed-interface.d.ts +172 -0
  14. package/dist/client/embed-lifecycle.d.ts +12 -0
  15. package/dist/client/fallback-html.d.ts +1 -0
  16. package/dist/client/frame-manager.d.ts +64 -0
  17. package/dist/client/frame-styles.d.ts +164 -0
  18. package/dist/client/frame-visibility.d.ts +53 -0
  19. package/dist/client/integration-manager.d.ts +73 -0
  20. package/dist/client/legacy-callback-adapter.d.ts +22 -0
  21. package/dist/client/mask-element.d.ts +19 -0
  22. package/dist/client/proactive/index.d.ts +5 -0
  23. package/dist/client/proactive/proactive-channel.d.ts +33 -0
  24. package/dist/client/proactive/proactive-runtime.d.ts +65 -0
  25. package/dist/client/proactive/proactive-utils.d.ts +51 -0
  26. package/dist/client/sdk-error-reporter.d.ts +22 -0
  27. package/dist/client/sdk-event-bus.d.ts +116 -0
  28. package/dist/client/service-worker-notifications.d.ts +1 -0
  29. package/dist/client/url-business-events.d.ts +19 -0
  30. package/dist/frame-channel/frame-channel.d.ts +64 -0
  31. package/dist/frame-channel/frame-child.d.ts +45 -0
  32. package/dist/frame-channel/index.d.ts +3 -0
  33. package/dist/frame-channel/types.d.ts +736 -0
  34. package/dist/helpers/rollout.d.ts +18 -0
  35. package/dist/host-telemetry.d.ts +15 -0
  36. package/dist/index.d.ts +8 -0
  37. package/dist/logger.d.ts +59 -0
  38. package/dist/mobile-webview-runtime.d.ts +122 -0
  39. package/dist/npm/build-info.d.cts +17 -0
  40. package/dist/npm/build-info.d.ts +17 -0
  41. package/dist/npm/index.cjs +276 -0
  42. package/dist/npm/index.cjs.map +1 -0
  43. package/dist/npm/index.d.cts +15 -0
  44. package/dist/npm/index.d.ts +9 -0
  45. package/dist/npm/index.js +270 -0
  46. package/dist/npm/index.js.map +1 -0
  47. package/dist/npm/loader.d.cts +120 -0
  48. package/dist/npm/loader.d.ts +120 -0
  49. package/dist/npm/testing.cjs +155 -0
  50. package/dist/npm/testing.cjs.map +1 -0
  51. package/dist/npm/testing.d.cts +39 -0
  52. package/dist/npm/testing.d.ts +39 -0
  53. package/dist/npm/testing.js +154 -0
  54. package/dist/npm/testing.js.map +1 -0
  55. package/dist/sdk-module-loader.d.ts +1 -0
  56. package/dist/shared-utils/clusters.d.ts +5 -0
  57. package/dist/shared-utils/csat.d.ts +116 -0
  58. package/dist/shared-utils/host-telemetry.d.ts +35 -0
  59. package/dist/shared-utils/index.d.ts +3 -0
  60. package/dist/voice/voice-manager.d.ts +120 -0
  61. package/package.json +77 -0
@@ -0,0 +1,843 @@
1
+ import type { AdaMessagingClientConfig, AdaMessagingStartOptions, AdaSdkEventCallback, ConversationInfo, Delegate, MetaFieldValue, PublicMessage, ResetParams, SendMessageResult, WindowInfo } from "./client-types.js";
2
+ /**
3
+ * Ada Messaging Client — thin coordinator
4
+ *
5
+ * This class is intentionally a coordinator, not a monolith. It owns the
6
+ * top-level lifecycle (init, open, close, destroy) and delegates all
7
+ * domain-specific logic to purpose-built modules:
8
+ *
9
+ * - FrameManager — iframe registry, channels, and load timers
10
+ * - SdkEventBus — pub/sub subscriber registry and getInfo() promise tracking
11
+ * - client-channel-handlers.ts — per-frame postMessage handler wiring
12
+ * - client-host-runtime.ts — config delivery, location-history patching, event routing
13
+ * - proactive/ — intro popup scheduling, URL-trigger evaluation, channel handlers
14
+ * - config-helpers.ts — pure config parsing and validation functions
15
+ * - frame-styles.ts — CSS string generators for each frame
16
+ * - integration-manager.ts — integration iframe lifecycle and command bus
17
+ * - voice/voice-manager.ts — WebSpeech recording and TTS
18
+ *
19
+ * Keep this class as a coordinator: new feature logic belongs in one of the
20
+ * modules above, not in additional private methods here.
21
+ *
22
+ * Frame hierarchy (hybrid model):
23
+ * Host Page
24
+ * ├── button.html (chat trigger)
25
+ * ├── intro.html (proactive messages)
26
+ * └── core.html (headless business logic → mounts app iframe;
27
+ * persists session/auth via the bot-domain
28
+ * /api/messaging/storage frame it mounts internally)
29
+ */
30
+ declare class AdaMessagingClient {
31
+ private _config;
32
+ private _assetRolloutCluster;
33
+ private _frameManager;
34
+ private readonly MAX_PENDING_MESSAGES;
35
+ private _pendingCoreMessages;
36
+ private _eventBus;
37
+ private _isInitialized;
38
+ private _integrationManager;
39
+ private _voiceManager;
40
+ private _startupConfig;
41
+ /** Latest host trigger waiting for the first startup config. */
42
+ private _pendingHostProactive;
43
+ private _lastOpenedViaKeyboard;
44
+ private _introTimer;
45
+ private readonly _proactiveTimers;
46
+ private _programmaticProactiveTimer;
47
+ private _activeProactiveSurfaceId;
48
+ private _proactiveClearRequestSeq;
49
+ private _pendingProactiveClearRequestId;
50
+ /** Latest intro display waiting for the intro frame channel. */
51
+ private _pendingIntroDisplay;
52
+ /** The channel exists at iframe load, before the intro runtime can receive. */
53
+ private _introChannelReady;
54
+ private _introChannelSetupStarted;
55
+ private _introChannelFailed;
56
+ private _introChannelUnlockAttempts;
57
+ private _introChannelHandshakeTimer;
58
+ private _introChannelDisplayTimer;
59
+ /** Latest emoji greeting waiting for the launcher channel. */
60
+ private _pendingEmojiDisplay;
61
+ /** Monotonic ordering for SDK-owned proactive intents. */
62
+ private _proactiveIntentSeq;
63
+ private _currentProactiveIntentId;
64
+ private _introShowing;
65
+ /** Page-local greeting dedupe; legacy resets this on a full-page reload. */
66
+ private _hasIntroShown;
67
+ /** Sticky client-lifetime parity with Embed2's card-greeting `wasIntroShown`. */
68
+ private _wasIntroShown;
69
+ /** Effective value for the current chatter; proactive removal sets only this bit. */
70
+ private _introShown;
71
+ private _runtimeMetaSyncScheduled;
72
+ private _runtimeMetaGeneration;
73
+ private _locationHistoryState;
74
+ private _lastEvaluatedUrl;
75
+ private _cachedEndpoint;
76
+ private _unreadCount;
77
+ /**
78
+ * Server-reported unread count for the current chatter, held apart from
79
+ * `_unreadCount` so a live message never renders as `seed + 1`.
80
+ */
81
+ private _seededUnread;
82
+ private _seededUnreadToken;
83
+ private _chatterToken;
84
+ /** Exact accepted chatter whose credentials live in tab-scoped identity storage. */
85
+ private _identitySessionChatterToken;
86
+ /** Consumption is emitted immediately before the matching chatter announcement. */
87
+ private _identityTokenConsumedAwaitingChatter;
88
+ /** One post-reset announcement from the just-abandoned identity lifecycle. */
89
+ private _ignoredChatterAnnouncementToken;
90
+ /** A storage credential that has not yet been restored into runtime state. */
91
+ private _persistedChatterCandidate;
92
+ /** Candidate discovery is SDK-triggered only after final startup config is known. */
93
+ private _coreReadyForCandidateDiscovery;
94
+ private _candidateDiscoveryBlockedForCore;
95
+ private _candidateDiscoveryRequestedForCore;
96
+ private _candidateDiscoveryGeneration;
97
+ private _scheduledCandidateDiscoveryGeneration;
98
+ private _candidateDiscoveryRequestSeq;
99
+ private _pendingCandidateDiscoveryRequestId;
100
+ private _candidateGeneration;
101
+ private _notificationStatusAbortController;
102
+ private _notificationStatusTimeout;
103
+ private _notificationStatusRequestSeq;
104
+ private _notificationStatusRequest;
105
+ private _notificationStatusCache;
106
+ private _sessionResumeRequestSeq;
107
+ private _pendingSessionResume;
108
+ private _pendingSessionResumeVisibility;
109
+ /** Resume succeeded, but only core.chatter.created may promote this token. */
110
+ private _resumedChatterAwaitingAnnouncement;
111
+ /** A prior tab's open marker is only actionable after live restore succeeds. */
112
+ private _pendingCrossWindowDrawerRestore;
113
+ /** Host-provided push token, retained independently of chatter-sensitive metadata. */
114
+ private _deviceToken;
115
+ /**
116
+ * Chatter whose unread count the user has already acknowledged by opening the
117
+ * chat. An in-flight seed carries a pre-clear count, so it has to lose to this
118
+ * rather than to chat visibility — the chat may already be closed again by the
119
+ * time the response lands.
120
+ */
121
+ private _acknowledgedUnreadToken;
122
+ /** An acknowledgement that landed before the chatter token existed to send it. */
123
+ private _pendingUnreadAcknowledgement;
124
+ private _isChatOpen;
125
+ /** Legacy keeps the chat frame mounted after its first open, replacing pre-chat surfaces. */
126
+ private _hasChatOpened;
127
+ /** Explicit host/user engagement, distinct from a hidden background resume. */
128
+ private _hasExplicitlyEngaged;
129
+ /** Resolved HTMLElement when parentElement config is active, null otherwise */
130
+ private _parentElement;
131
+ /** Whether init has made the configured host-layout mode authoritative. */
132
+ private _parentElementResolved;
133
+ private _maskElement;
134
+ private _hasActiveChatter;
135
+ private _hasPublishedEmbedLoaded;
136
+ private readonly _registeredInternalEventCallbacks;
137
+ private _crossWindowLiveChatActive;
138
+ private _cleanupErrorReporter;
139
+ private _cleanupCoreChannelHandlers;
140
+ private _cleanupServiceWorkerNotificationClick;
141
+ private _chatActivationEventTimer;
142
+ private _chatFallbackTimer;
143
+ /** First visible arm of the current activation's absolute fallback ceiling. */
144
+ private _chatFallbackArmedAt;
145
+ private _coreFrameReloadTimer;
146
+ private _chatHideTimer;
147
+ private _chatViewportCleanup;
148
+ private _pageScrollLocked;
149
+ /** App-requested host viewport lease, honored only by floating browser widgets. */
150
+ private _hostViewportRequested;
151
+ private _hasCompletedActivation;
152
+ /** Core has begun or advanced session activation, possibly while hidden. */
153
+ private _activationWorkObserved;
154
+ private _showingTimeoutFallback;
155
+ private readonly _handleFallbackMessage;
156
+ /**
157
+ * Durable clear intent replayed to every replacement Core until the exact
158
+ * correlated acknowledgement arrives. Config delivery is not completion: Core
159
+ * can crash after receiving these fields but before confirming the write barrier.
160
+ */
161
+ private _clearPersistenceOnNextCoreConfig;
162
+ /**
163
+ * A soft reset made from the timeout document. Its replacement core must first
164
+ * restore the existing chatter, then sync the supplied fields and reactivate.
165
+ */
166
+ private _historyPreservingResetAfterCoreReload;
167
+ private _pendingClearAckRequestId;
168
+ private _pendingClearAckResponseType;
169
+ private _pendingClearPersistenceScope;
170
+ private _resolvedPersistenceMode;
171
+ /** The current Core document has installed its router and completed public bootstrap. */
172
+ private _coreReadyForResetDelivery;
173
+ private _pendingClearPersistenceModes;
174
+ private _pendingDestructiveOps;
175
+ private _greetingResponseIdOnNextCoreConfig;
176
+ private _configuredGreetingResponseId;
177
+ private _campaignShowSeq;
178
+ private _shownCampaign;
179
+ private _openedCampaignSeq;
180
+ private _introSurfaceSeq;
181
+ private _currentIntroSurface;
182
+ private _internalHostTelemetry?;
183
+ private _onIdentityTokenConsumed?;
184
+ private _isEmbedLoadedPublicationActive?;
185
+ private _zdChatterAuthCallback;
186
+ private _delegate;
187
+ private _urlBusinessEvents;
188
+ private _urlBusinessEventsEnabled;
189
+ private _urlBusinessEventsLoaded;
190
+ private _urlBusinessEventsFailureReported;
191
+ private _urlBusinessEventsEndpoint;
192
+ private _urlBusinessEventsLoad;
193
+ private _urlBusinessEventsRefreshPending;
194
+ private _urlBusinessEventsAbortController;
195
+ /** Expose zdChatterAuthCallback to channel handlers for Zendesk Chat auth flow */
196
+ get zdChatterAuthCallback(): ((callback: (token: string) => void) => void) | null;
197
+ /**
198
+ * Proxy getters so that callers inside this class (channel setup, proactive
199
+ * runtime dependencies, open/close) can continue to use `this._channels` and
200
+ * `this._frames` without modification. They resolve through the FrameManager
201
+ * when one exists, or return empty collections before init.
202
+ */
203
+ private get _channels();
204
+ private get _frames();
205
+ constructor(config: AdaMessagingClientConfig);
206
+ private _initializeClient;
207
+ /**
208
+ * Open the chat drawer UI.
209
+ * When the chat is already open this is a no-op.
210
+ * When {@link AdaMessagingClientConfig.lazy} is true and the client has not
211
+ * been initialized yet, calling open() triggers initialization.
212
+ *
213
+ * @example
214
+ * window.adaEmbed.open();
215
+ */
216
+ open(): void;
217
+ /** Open after a proactive click without clearing the engagement attribution
218
+ * that core and the SDK have just armed for that exact displayed surface. */
219
+ private _openFromProactiveEngagement;
220
+ private _openChat;
221
+ /**
222
+ * Close the chat drawer UI and restore the launcher button.
223
+ * When the chat is already closed this is a no-op.
224
+ *
225
+ * @example
226
+ * window.adaEmbed.close();
227
+ */
228
+ close(reason?: "close" | "minimize"): void;
229
+ /**
230
+ * Reset the active conversation and optionally apply new configuration.
231
+ * Use this when the authenticated user changes or to start a fresh session.
232
+ *
233
+ * The promise resolves on core's correlated confirmation. Full resets wait for
234
+ * the persisted conversation clear to be durable, including when core reloads;
235
+ * history-preserving resets wait for reconfiguration/reactivation and do not
236
+ * clear the chatter or transcript. For compatibility with existing
237
+ * fire-and-forget call sites, a core that never confirms settles this promise
238
+ * after a bounded wait instead of rejecting; that settlement is not a claim
239
+ * that core completed the operation.
240
+ *
241
+ * @param resetParams - Optional reset options (e.g., new metaFields or greeting).
242
+ *
243
+ * @example
244
+ * window.adaEmbed.reset({ metaFields: { userId: "new-user" } });
245
+ */
246
+ reset(resetParams?: ResetParams): Promise<void>;
247
+ private _registerDestructiveAck;
248
+ private _registerDurableClearAck;
249
+ private _acknowledgeDurableClearIntent;
250
+ private _clearDurableClearIntent;
251
+ private _abandonDurableClearIntent;
252
+ private _persistenceScopeKey;
253
+ private _outgoingPersistenceMode;
254
+ /**
255
+ * A reset/delete request belongs to the bot whose storage it snapshotted.
256
+ * Rebinding this SDK instance to another bot cannot truthfully finish that
257
+ * request and must never replay it into the new bot's storage.
258
+ */
259
+ private _abandonDestructiveWorkForPersistenceScopeChange;
260
+ private _hasNoFrameToAck;
261
+ private _hasReadyCoreChannel;
262
+ /**
263
+ * Mount only the public Core frame so a never-started lazy client can perform
264
+ * and acknowledge a durable persistence clear. Core's page-load phase mounts
265
+ * storage but never restores, identifies, creates, greets, or connects a
266
+ * chatter; a later start() reuses this pre-mounted frame via the same
267
+ * reuse path in _initializeFrames().
268
+ */
269
+ private _ensurePublicCoreFrameForDestructiveClear;
270
+ private _pruneDestructiveOp;
271
+ /**
272
+ * A later durable-clear acknowledgement confirms older clears it superseded:
273
+ * its required-mode coverage must subsume each older request. Soft
274
+ * reconfiguration payloads are not cumulative, so only their exact correlated
275
+ * acknowledgement may settle them.
276
+ */
277
+ private _settleDestructiveOpFamily;
278
+ /**
279
+ * Toggle the chat drawer — open if closed, close if open.
280
+ *
281
+ * @example
282
+ * window.adaEmbed.toggle();
283
+ */
284
+ toggle(): void;
285
+ /**
286
+ * Retrieve current client state asynchronously.
287
+ *
288
+ * @returns A promise that resolves to a {@link WindowInfo} object containing
289
+ * `isChatOpen`, `hasActiveChatter`, and `hasClosedChat`.
290
+ * The promise resolves immediately with local state values if the core
291
+ * frame has not yet responded, or if the SDK is being destroyed.
292
+ *
293
+ * @example
294
+ * const info = await window.adaEmbed.getInfo();
295
+ * if (info.isChatOpen) { ... }
296
+ */
297
+ getInfo(): Promise<WindowInfo>;
298
+ /**
299
+ * Whether the chat is currently visible to the user. Derived from getInfo().
300
+ *
301
+ * @example
302
+ * if (await window.adaEmbed.isOpen()) { ... }
303
+ */
304
+ isOpen(): Promise<boolean>;
305
+ /**
306
+ * Returns the non-sensitive metaFields currently set on the session.
307
+ * Sensitive metaFields are never returned. Resolves to an empty object if
308
+ * the core frame does not respond.
309
+ *
310
+ * @example
311
+ * const fields = await window.adaEmbed.getMetaFields();
312
+ */
313
+ getMetaFields(): Promise<Record<string, MetaFieldValue>>;
314
+ /**
315
+ * Returns the active conversation id and live-agent handoff state. Requires
316
+ * `enableProgrammaticControl`; rejects when the gate is off or core does not
317
+ * respond.
318
+ *
319
+ * @example
320
+ * const { id, handoff } = await window.adaEmbed.getConversation();
321
+ */
322
+ getConversation(): Promise<ConversationInfo>;
323
+ /**
324
+ * Returns the in-memory message transcript. Requires
325
+ * `enableProgrammaticControl`; rejects when the gate is off or core does not
326
+ * respond.
327
+ *
328
+ * @example
329
+ * const messages = await window.adaEmbed.getMessages();
330
+ */
331
+ getMessages(): Promise<PublicMessage[]>;
332
+ setComposerText(text: string): Promise<void>;
333
+ setDelegate(delegate: Delegate | null | undefined): void;
334
+ private _applyBeforeSend;
335
+ /**
336
+ * Delete chatter history and reset the session.
337
+ *
338
+ * Resolves after core confirms the persisted clear is durable, including
339
+ * across a replacement core frame. A missing confirmation uses the same
340
+ * bounded compatibility settlement as {@link reset}; it does not represent a
341
+ * false success acknowledgement from core.
342
+ */
343
+ deleteHistory(): Promise<void>;
344
+ /**
345
+ * Set the display language for the chat interface.
346
+ *
347
+ * @param language - A BCP-47 language tag (e.g. `"en"`, `"fr"`, `"es-MX"`).
348
+ *
349
+ * @example
350
+ * window.adaEmbed.setLanguage("fr");
351
+ */
352
+ setLanguage(language: string): void;
353
+ /**
354
+ * Change the chat widget's color scheme at runtime.
355
+ * Takes effect immediately without reset or reload.
356
+ *
357
+ * @param theme - `"light"`, `"dark"`, or `"auto"` (follows OS preference).
358
+ *
359
+ * @example
360
+ * window.adaEmbed.setTheme("dark");
361
+ */
362
+ setTheme(theme: "light" | "dark" | "auto"): void;
363
+ /**
364
+ * Update the active chatter's metafields.
365
+ * Values are validated and sanitized before being forwarded to the core frame.
366
+ *
367
+ * @param fields - A key/value map of metadata to attach to the chatter session.
368
+ *
369
+ * @example
370
+ * window.adaEmbed.setMetaFields({ userId: "u123", plan: "pro" });
371
+ */
372
+ setMetaFields(fields: Record<string, unknown>): void;
373
+ /**
374
+ * Show or hide the Ada dashboard test-mode banner ("Testing Process: X").
375
+ * `null` (or empty) hides it. Dashboard-only — only the Ada dashboard calls this.
376
+ */
377
+ setTestModeBanner(label: string | null): void;
378
+ /**
379
+ * Pass sensitive metafields securely via chatter sensitive metadata storage.
380
+ * Unlike {@link setMetaFields}, these values are not logged or exposed in plain text.
381
+ *
382
+ * @param fields - A key/value map of sensitive metadata to send.
383
+ *
384
+ * @example
385
+ * window.adaEmbed.setSensitiveMetaFields({ authToken: "secret" });
386
+ */
387
+ setSensitiveMetaFields(fields: Record<string, unknown>): void;
388
+ /**
389
+ * Register a device push-notification token for the active chatter.
390
+ *
391
+ * @param token - The device token string from APNs or FCM.
392
+ *
393
+ * @example
394
+ * window.adaEmbed.setDeviceToken("fcm-device-token-here");
395
+ */
396
+ setDeviceToken(token: string): void;
397
+ private _replayDeviceToken;
398
+ /**
399
+ * Programmatically send a message as the user in the active conversation.
400
+ * Opens the chat drawer if not already visible. If the chat has not started,
401
+ * the auto-greeting is skipped and the message starts the conversation.
402
+ *
403
+ * @param body - The message text to send.
404
+ *
405
+ * @example
406
+ * window.adaEmbed.sendMessage("I need help with my order");
407
+ */
408
+ sendMessage(body: string): Promise<SendMessageResult>;
409
+ /**
410
+ * Handle an incoming push notification by opening the chat drawer.
411
+ * Typically called from your notification service worker or app delegate.
412
+ *
413
+ * @example
414
+ * window.adaEmbed.handleNotification();
415
+ */
416
+ handleNotification(): void;
417
+ /**
418
+ * Request browser web-notification permission. Must be called in response to
419
+ * a user gesture (e.g. a button click) per browser policy. Once granted, the
420
+ * widget shows a browser notification for new live-agent messages while the
421
+ * page is hidden or the chat is closed (legacy chat parity); clicking it
422
+ * focuses the window, opens the chat, and emits `ada:web_notification:click`.
423
+ *
424
+ * @returns The resulting permission, or null if the browser has no support.
425
+ *
426
+ * @example
427
+ * myEnableNotificationsButton.onclick = () => window.adaEmbed.requestNotifications();
428
+ */
429
+ requestNotifications(): Promise<NotificationPermission> | null;
430
+ /**
431
+ * Track a custom analytics event.
432
+ *
433
+ * @param key - The event name/key.
434
+ * @param value - Optional numeric value associated with the event.
435
+ * @param meta - Optional freeform metadata payload.
436
+ *
437
+ * @example
438
+ * window.adaEmbed.trackEvent("page_view", 1, { page: "/pricing" });
439
+ */
440
+ trackEvent(key: string, value?: number, meta?: Record<string, unknown>): void;
441
+ /**
442
+ * Subscribe to a named SDK lifecycle event.
443
+ * Namespace matching applies: subscribing to `"ada:campaigns"` also
444
+ * receives `"ada:campaigns:shown"`, `"ada:campaigns:engaged"`, etc.
445
+ *
446
+ * @param key - The event name or prefix to subscribe to (e.g. `"ada:start"`).
447
+ * @param callback - Called with the event payload whenever the event fires.
448
+ * @returns A numeric subscription ID. Pass to {@link unsubscribeEvent} to cancel.
449
+ *
450
+ * @example
451
+ * const id = window.adaEmbed.subscribeEvent("ada:start", (data) => {
452
+ * console.log("Chat started", data);
453
+ * });
454
+ */
455
+ subscribeEvent(key: string, callback: AdaSdkEventCallback): number;
456
+ /**
457
+ * Cancel a subscription previously registered with {@link subscribeEvent}.
458
+ *
459
+ * @param id - The subscription ID returned by {@link subscribeEvent}.
460
+ *
461
+ * @example
462
+ * const id = window.adaEmbed.subscribeEvent("ada:start", handler);
463
+ * // later…
464
+ * window.adaEmbed.unsubscribeEvent(id);
465
+ */
466
+ unsubscribeEvent(id: number): void;
467
+ /**
468
+ * Subscribe to published events. Transcript-bearing events
469
+ * (`ada:message:sent` and `ada:message:received`) require exact
470
+ * `subscribeEvent()` listeners and are not delivered to broad subscribers.
471
+ * Designed for bridge adapters (React Native, iOS, Android) that need to
472
+ * forward SDK events to native code.
473
+ *
474
+ * @returns A numeric subscription ID. Pass to {@link unsubscribeEvent} to cancel.
475
+ *
476
+ * @example
477
+ * const id = window.adaEmbed.subscribeAll((key, data) => {
478
+ * nativeBridge.postMessage(JSON.stringify({ type: "sdk.event", key, data }));
479
+ * });
480
+ */
481
+ subscribeAll(callback: (key: string, data: unknown) => void): number;
482
+ /**
483
+ * Trigger a proactive (scripted) conversation by its message key.
484
+ * `triggerProactiveConversation` is the deprecated alias for this method.
485
+ *
486
+ * @param messageKey - The proactive message key configured in the Ada dashboard.
487
+ * @param params - Optional placeholder substitution values.
488
+ *
489
+ * @example
490
+ * window.adaEmbed.triggerProactive("welcome_returning_user", { name: "Alex" });
491
+ */
492
+ triggerProactive(messageKeyOrOptions: string | {
493
+ messageKey: string;
494
+ params?: Record<string, string>;
495
+ }, params?: Record<string, string>): void;
496
+ /** @deprecated Use triggerProactive() instead */
497
+ triggerProactiveConversation(key: string, params?: Record<string, string>): void;
498
+ /**
499
+ * @deprecated Messaging supports only generative features; scripted/declarative proactive messages are ignored.
500
+ */
501
+ createProactive(..._args: unknown[]): void;
502
+ /**
503
+ * @deprecated Messaging supports only generative features; scripted/declarative campaigns are ignored.
504
+ */
505
+ triggerCampaign(..._args: unknown[]): void;
506
+ /**
507
+ * @deprecated Messaging supports only generative features; scripted/declarative campaigns are ignored.
508
+ */
509
+ evaluateCampaignConditions(..._args: unknown[]): void;
510
+ /** Close the currently displayed proactive or campaign bubble. */
511
+ closeCampaign(): void;
512
+ /**
513
+ * Trigger a specific Answer by id. Sends a greeting carrying `response_id` —
514
+ * the same greeting path as {@link triggerGreeting}, whose `handle` argument is
515
+ * the other arm of the same union.
516
+ *
517
+ * @param answerId - Answer id, as shown in the dashboard URL for that Answer.
518
+ *
519
+ * @example
520
+ * window.adaEmbed.triggerAnswer("627d28a9bd9ca9e5337b9763");
521
+ */
522
+ triggerAnswer(answerId: string): void;
523
+ /**
524
+ * Mount all frames and start the SDK client.
525
+ * Use with {@link AdaMessagingClientConfig.lazy} = `true` to defer initialization
526
+ * until an explicit user action, then call `start()` to mount.
527
+ * Optional settings overrides are applied before first initialization.
528
+ * Floating mode activates only when the drawer is explicitly opened. Headless
529
+ * and parentElement modes have no launcher gesture, so start activates them.
530
+ *
531
+ * @example
532
+ * // Defer loading until consent granted:
533
+ * window.adaEmbed.start({ language: "fr" });
534
+ */
535
+ start(options?: AdaMessagingStartOptions): void;
536
+ /**
537
+ * Tear down all SDK frames and listeners, removing Ada from the page.
538
+ * Equivalent to {@link destroy}. The client can be re-mounted with {@link start}.
539
+ *
540
+ * @example
541
+ * window.adaEmbed.stop();
542
+ */
543
+ stop(): void;
544
+ /**
545
+ * Programmatically trigger the bot greeting in an active conversation.
546
+ *
547
+ * @param handle - Optional bot handle override. Defaults to the configured handle.
548
+ *
549
+ * @example
550
+ * window.adaEmbed.triggerGreeting();
551
+ */
552
+ triggerGreeting(handle?: string): void;
553
+ private _triggerGreeting;
554
+ /**
555
+ * Tear down all SDK frames, channels, and event listeners.
556
+ * The SDK cannot be reused after destroy without creating a new instance.
557
+ * Prefer {@link stop} for removable-and-restartable teardown.
558
+ *
559
+ * @example
560
+ * window.adaEmbed.destroy();
561
+ */
562
+ destroy(): void;
563
+ private _destroyRuntime;
564
+ /**
565
+ * Initialize the client: create the container div,
566
+ * mount all frames, and establish channels.
567
+ */
568
+ private _init;
569
+ private _initializeFrames;
570
+ /** Wire all message handlers for the core (headless business logic) frame. */
571
+ private _setupCoreChannel;
572
+ /** Wire all message handlers for the button (chat trigger) frame. */
573
+ private _setupButtonChannel;
574
+ private _clearIntroChannelHandshakeTimer;
575
+ private _clearIntroChannelDisplayTimer;
576
+ private _stopIntroChannelReadiness;
577
+ /** Bound one queued display without treating an unready frame as delivered. */
578
+ private _armIntroChannelDisplayTimeout;
579
+ /**
580
+ * A stripped Referrer-Policy leaves the child unable to send its queued
581
+ * origin/ready reports until it receives one trusted parent message. Retry a
582
+ * harmless command to the origin derived from the iframe src; FrameChannel
583
+ * still authenticates the eventual ready by source, origin, and frame name.
584
+ */
585
+ private _attemptIntroChannelUnlock;
586
+ /** Wire handlers, but wait for the runtime's authenticated ready to deliver. */
587
+ private _setupIntroChannel;
588
+ private _openProactiveCtaUrl;
589
+ /** Send the client configuration to a frame. */
590
+ private _deliverConfig;
591
+ /** Safely invoke a window-level callback if it exists and is a function */
592
+ private _invokeWindowCallback;
593
+ /**
594
+ * Headless has no visible drawer, but start() is still an activation boundary
595
+ * and a stalled activation otherwise has no host-facing signal at all. Track it
596
+ * with the same diagnostic budget as an embedded client while retaining the
597
+ * visible-drawer requirement for fallback UI.
598
+ */
599
+ private _isEligibleForActivationTimeouts;
600
+ /** Route a published event key to all matching subscribeEvent subscribers */
601
+ private _routePublishedEvent;
602
+ private _beginProactiveDisplay;
603
+ private _acknowledgeProactiveShown;
604
+ private _beginGreetingDisplay;
605
+ /** Publish the acknowledged bubble lifecycle event once, without inventing the
606
+ * declarative-only `ada:message_opened:*` business goal for Generative Chat. */
607
+ private _publishShownCampaignOpened;
608
+ private _warnDeclarativeOnlyMethod;
609
+ private _queuePendingCoreMessage;
610
+ private _flushPendingCoreMessages;
611
+ private _acceptStartupConfig;
612
+ /**
613
+ * Deliver the latest core-owned launcher appearance when a button channel is
614
+ * available. `_startupConfig` is the durable snapshot: if core wins the sibling
615
+ * iframe load race, `_setupButtonChannel()` replays the same snapshot later.
616
+ */
617
+ private _syncButtonStartupConfig;
618
+ /**
619
+ * Render the badge from its canonical state. A live message deliberately wins
620
+ * over a server seed rather than adding to it: the seed includes live-chat
621
+ * lifecycle notices, while `_unreadCount` counts messages received this page.
622
+ */
623
+ private _syncButtonUnreadCount;
624
+ private _showOrQueueIntroDisplay;
625
+ private _ensureIntroFrame;
626
+ private _showOrQueueEmojiDisplay;
627
+ private _drainPendingEmojiDisplay;
628
+ private _drainPendingIntroDisplay;
629
+ private _clearPendingIntroDisplay;
630
+ private _dropPendingIntroDisplay;
631
+ private _clearProgrammaticProactiveTimer;
632
+ private _clearProactive;
633
+ /** Apply a core-owned conversation reset to proactive state without touching
634
+ * an independent greeting that may already occupy the shared intro frame. */
635
+ private _clearProactiveFromCore;
636
+ private _beginProactiveIntent;
637
+ /** Retire only the core surface represented by a dropped queued callback. */
638
+ private _retireDroppedProactiveSurface;
639
+ private _nextProactiveIntentId;
640
+ /** Hide and invalidate the single legacy pre-chat surface. */
641
+ private _retirePreChatSurface;
642
+ private _showProactive;
643
+ /**
644
+ * @param keepChatter - the reset preserves the chatter core-side, so keep the
645
+ * identity we already hold. Core announces a chatter only when its token
646
+ * changes, so a preserved one is never re-announced and dropping it here
647
+ * would strand us with no token for the unread routes.
648
+ */
649
+ private _prepareForSessionReset;
650
+ private _clearChatActivationTimeouts;
651
+ /**
652
+ * Holds the drawer's open geometry while it slides and fades out, then
653
+ * collapses it to 0×0.
654
+ *
655
+ * The collapse runs on a timer rather than `transitionend`: that event never
656
+ * fires when the transition is interrupted or the frame is not being
657
+ * rendered, and a missed collapse would strand a full-viewport `position:
658
+ * fixed` iframe over the customer's page (legacy embed-2 records this as
659
+ * breaking scrolling on iOS). The closing styles are already inert, so a lost
660
+ * timer degrades to a wasted paint region, not a blocked page.
661
+ */
662
+ private _startChatCloseAnimation;
663
+ private _clearChatHideTimer;
664
+ private _syncChatViewportHeight;
665
+ private _stopChatViewportHeightSync;
666
+ /**
667
+ * Lease the browser viewport to the core iframe while an in-chat surface is
668
+ * open. Only the SDK-owned floating drawer can make this promise: an inline
669
+ * embed may sit under a clipped/transformed ancestor, while headless/native
670
+ * clients own their own window geometry.
671
+ *
672
+ * The request remains recorded across a public close so reopening cannot show
673
+ * the in-app modal inside a card. The closed frame is 0x0 and inert; lifecycle
674
+ * replacement paths explicitly release the lease.
675
+ */
676
+ private _setHostViewportExpanded;
677
+ /** Mobile drawers and host-viewport surfaces share one composable lock. */
678
+ private _syncPageScrollLock;
679
+ /**
680
+ * Keeps the host page from scrolling behind an edge-to-edge SDK surface.
681
+ * The drags that escape are the ones starting on the drawer's non-scrollable
682
+ * chrome; the message list's own `overscroll-behavior-y: contain` covers
683
+ * end-of-list chaining, but only on iOS 16+ — iOS 15 is still the floor.
684
+ *
685
+ * Locks both `<html>` and `<body>`: the viewport's scroll is governed by
686
+ * whichever computes non-`visible` overflow (CSS Overflow L3 §3.3) — a host
687
+ * page with `html { overflow-x: hidden }` (a common horizontal-overflow fix)
688
+ * would make a body-only lock silently ineffective. No-op if already in the
689
+ * requested state, so a redundant unlock on close/destroy can't clobber a
690
+ * value that was never saved.
691
+ *
692
+ * Snapshots/restores the `overflow-x`/`overflow-y` longhands rather than the
693
+ * `overflow` shorthand: if a host set only one axis inline (e.g.
694
+ * `overflow-x: hidden`, a common way to suppress an unwanted horizontal
695
+ * scrollbar), reading the shorthand back returns `""` since it doesn't
696
+ * serialize from a single longhand — saving and restoring that would drop
697
+ * the host's original value entirely instead of preserving it.
698
+ */
699
+ private _setPageScrollLocked;
700
+ /**
701
+ * Whether the SDK draws its own floating-widget chrome — the launcher, the
702
+ * intro popup and the drawer scrim. `parentElement` hands window
703
+ * management to the host; `headless` mounts core alone.
704
+ */
705
+ private get _hasFloatingWidgetChrome();
706
+ private _startChatActivationTimeouts;
707
+ /** Re-arm only the inactivity fallback; the public diagnostic remains one-shot. */
708
+ private _rearmChatFallbackTimeout;
709
+ private _maybeShowChatTimeoutFallback;
710
+ private _disconnectCoreChannel;
711
+ private _showChatTimeoutFallback;
712
+ private _reloadCoreFrame;
713
+ private _invalidateStartupConfigForCoreReplacement;
714
+ private _requestActivationAfterCoreReload;
715
+ private _handleFrameTimeout;
716
+ private _setConfig;
717
+ private _clearIdentityToken;
718
+ private _clearGlobalIdentityToken;
719
+ private _applyResetOverridesToConfig;
720
+ private _sendPendingHistoryPreservingReset;
721
+ private _markCoreProtocolReady;
722
+ private _applyStartOverrides;
723
+ private _subscribeInternalEvent;
724
+ private _registerInternalEventCallbacks;
725
+ private _publishEmbedLoaded;
726
+ private _setupServiceWorkerNotificationClickHandler;
727
+ private _crossWindowDrawerStorageKey;
728
+ private _crossWindowLiveChatStorageKey;
729
+ private _safeSessionStorageGet;
730
+ private _safeSessionStorageSet;
731
+ private _safeSessionStorageRemove;
732
+ private _persistCrossWindowDrawerState;
733
+ private _setCrossWindowLiveChatActive;
734
+ private _clearCrossWindowPersistenceState;
735
+ private _armCrossWindowDrawerRestore;
736
+ private _clearUnreadCount;
737
+ private _chatterApiUrl;
738
+ /**
739
+ * Clear the chatter's server-side unread count.
740
+ *
741
+ * Deliberately not gated on the local count. api resets `unread_count` only
742
+ * from this route, and never on a new conversation, so it outlives both the
743
+ * page and the conversation. A clear that skipped the DELETE would leave a
744
+ * non-zero count for the next load to seed from — the badge would come back
745
+ * on every reload and never clear.
746
+ */
747
+ private _resetServerUnreadCount;
748
+ private _setChatterToken;
749
+ private _scheduleCandidateDiscovery;
750
+ private _setPersistedChatterCandidate;
751
+ private _beginExplicitEngagement;
752
+ private _inspectPersistedChatterCandidate;
753
+ private _handleSessionResumeResult;
754
+ private _handleSessionResumeVisibilityResult;
755
+ private _nextSessionResumeRequestId;
756
+ private _nextPositiveSafeInteger;
757
+ private _discardPersistedChatterCandidate;
758
+ private _cancelCandidateDiscoveryRequest;
759
+ private _resetCandidateDiscoveryForCoreReplacement;
760
+ private _invalidateNotificationStatusLookup;
761
+ private _getNotificationStatus;
762
+ /**
763
+ * Seed the launcher badge from the chatter's server-side unread count.
764
+ *
765
+ * api owns the scope of `unread_amount`; legacy applies a positive value without
766
+ * consulting `is_live_state`, including a count left by a handoff that has since
767
+ * ended. Keep the dot presentation because the value includes lifecycle notices as
768
+ * well as agent messages, and legacy also renders it as a dot.
769
+ */
770
+ private _seedUnreadCountFromServer;
771
+ private _applyUnreadStatus;
772
+ private _showEmbeddedChat;
773
+ private _isChatVisible;
774
+ private _getWindowInfo;
775
+ private _getProactiveRuntimeDependencies;
776
+ /**
777
+ * Schedule the intro greeting popup to display after the configured delay.
778
+ * Skipped when chat has opened, this client already showed it, or paths do not match.
779
+ */
780
+ private _scheduleIntro;
781
+ /**
782
+ * Patch history.pushState / replaceState and listen to popstate so that
783
+ * single-page-app navigation fires a synthetic "locationchange" event.
784
+ * Called once during `_init()`.
785
+ */
786
+ private _patchLocationHistory;
787
+ /** Restore original history methods and remove the locationchange listener. */
788
+ private _unpatchLocationHistory;
789
+ /** Record a delivered Text/card greeting in both legacy intro lifetimes. */
790
+ private _markGreetingIntroShown;
791
+ /** Patch only the current chatter when an accepted proactive is removed. */
792
+ private _markProactiveIntroShown;
793
+ private _currentRuntimeMeta;
794
+ /** Invalidate a queued microtask once the same latest snapshot is staged/sent. */
795
+ private _cancelScheduledRuntimeMetaSync;
796
+ /**
797
+ * Consume any staged snapshot and send current page truth on the supplied Core
798
+ * lifecycle. Callers place this immediately after a destructive protocol edge.
799
+ */
800
+ private _sendAuthoritativeRuntimeMeta;
801
+ /**
802
+ * Collapse synchronous history writes and intro commits into one latest-state
803
+ * update. A generation pin prevents a microtask queued by a destroyed client
804
+ * from reaching a later stop()/start() lifecycle.
805
+ */
806
+ private _scheduleRuntimeMetaSync;
807
+ /** Called on every SPA navigation. Re-evaluates intro and proactive conditions. */
808
+ private _onLocationChange;
809
+ /**
810
+ * Record URL-goal eligibility, then load definitions only for an active chatter.
811
+ * A dormant or provisional persisted token cannot post a business event and must
812
+ * not turn an ordinary launcher page load into another API request.
813
+ */
814
+ private _configureUrlBusinessEvents;
815
+ private _evaluateUrlBusinessEvents;
816
+ /**
817
+ * Evaluate URL-triggered proactive conversations for the current page,
818
+ * without the intro-greeting scheduling that `_onLocationChange` also does.
819
+ * Runs once on initial startup config (SPA navigation covers the rest).
820
+ */
821
+ private _evaluateProactiveConditions;
822
+ /** Normalize config align to a concrete "left" | "right" value. */
823
+ private get _align();
824
+ /** Whether the button is in text-label mode (affects frame sizing). */
825
+ private get _isTextButton();
826
+ private get _isHeadless();
827
+ private _requireProgrammaticControl;
828
+ /**
829
+ * Send a message to the core frame channel.
830
+ * Kept as a thin proxy for test spy compatibility (`vi.spyOn(client, "_sendToCore")`).
831
+ *
832
+ * Messages can be issued before the core channel exists: in lazy mode before
833
+ * `_init()`, during the initial core-frame bootstrap, or while retrying after
834
+ * a timeout fallback. A live router may receive ordinary activation before
835
+ * public config succeeds (that activation is the retry path). Only a pending
836
+ * history-preserving reset must hold later work until core.ready delivers the
837
+ * exact reset first.
838
+ */
839
+ private _sendToCore;
840
+ /** Create a FrameManager for the given container element. */
841
+ private _createFrameManager;
842
+ }
843
+ export { AdaMessagingClient };