@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.
- package/README.md +211 -0
- package/dist/client/ada-settings-reader.d.ts +10 -0
- package/dist/client/client-channel-handlers.d.ts +92 -0
- package/dist/client/client-errors.d.ts +7 -0
- package/dist/client/client-frame-constants.d.ts +41 -0
- package/dist/client/client-frame-runtime.d.ts +54 -0
- package/dist/client/client-host-runtime.d.ts +73 -0
- package/dist/client/client-types.d.ts +231 -0
- package/dist/client/client.d.ts +843 -0
- package/dist/client/config-helpers.d.ts +157 -0
- package/dist/client/constants.d.ts +61 -0
- package/dist/client/core-channel-test-harness.d.ts +47 -0
- package/dist/client/embed-interface.d.ts +172 -0
- package/dist/client/embed-lifecycle.d.ts +12 -0
- package/dist/client/fallback-html.d.ts +1 -0
- package/dist/client/frame-manager.d.ts +64 -0
- package/dist/client/frame-styles.d.ts +164 -0
- package/dist/client/frame-visibility.d.ts +53 -0
- package/dist/client/integration-manager.d.ts +73 -0
- package/dist/client/legacy-callback-adapter.d.ts +22 -0
- package/dist/client/mask-element.d.ts +19 -0
- package/dist/client/proactive/index.d.ts +5 -0
- package/dist/client/proactive/proactive-channel.d.ts +33 -0
- package/dist/client/proactive/proactive-runtime.d.ts +65 -0
- package/dist/client/proactive/proactive-utils.d.ts +51 -0
- package/dist/client/sdk-error-reporter.d.ts +22 -0
- package/dist/client/sdk-event-bus.d.ts +116 -0
- package/dist/client/service-worker-notifications.d.ts +1 -0
- package/dist/client/url-business-events.d.ts +19 -0
- package/dist/frame-channel/frame-channel.d.ts +64 -0
- package/dist/frame-channel/frame-child.d.ts +45 -0
- package/dist/frame-channel/index.d.ts +3 -0
- package/dist/frame-channel/types.d.ts +736 -0
- package/dist/helpers/rollout.d.ts +18 -0
- package/dist/host-telemetry.d.ts +15 -0
- package/dist/index.d.ts +8 -0
- package/dist/logger.d.ts +59 -0
- package/dist/mobile-webview-runtime.d.ts +122 -0
- package/dist/npm/build-info.d.cts +17 -0
- package/dist/npm/build-info.d.ts +17 -0
- package/dist/npm/index.cjs +276 -0
- package/dist/npm/index.cjs.map +1 -0
- package/dist/npm/index.d.cts +15 -0
- package/dist/npm/index.d.ts +9 -0
- package/dist/npm/index.js +270 -0
- package/dist/npm/index.js.map +1 -0
- package/dist/npm/loader.d.cts +120 -0
- package/dist/npm/loader.d.ts +120 -0
- package/dist/npm/testing.cjs +155 -0
- package/dist/npm/testing.cjs.map +1 -0
- package/dist/npm/testing.d.cts +39 -0
- package/dist/npm/testing.d.ts +39 -0
- package/dist/npm/testing.js +154 -0
- package/dist/npm/testing.js.map +1 -0
- package/dist/sdk-module-loader.d.ts +1 -0
- package/dist/shared-utils/clusters.d.ts +5 -0
- package/dist/shared-utils/csat.d.ts +116 -0
- package/dist/shared-utils/host-telemetry.d.ts +35 -0
- package/dist/shared-utils/index.d.ts +3 -0
- package/dist/voice/voice-manager.d.ts +120 -0
- package/package.json +77 -0
package/README.md
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# @ada-cx/messaging-sdk
|
|
2
|
+
|
|
3
|
+
TypeScript types, test mocks, and a thin loader for the Ada Messaging SDK.
|
|
4
|
+
|
|
5
|
+
This package never contains the SDK runtime. The loader imports the runtime
|
|
6
|
+
from Ada's CDN at page load. Ada ships runtime fixes to the CDN, and every
|
|
7
|
+
page receives them on the next load. This is the same model as
|
|
8
|
+
`@stripe/stripe-js`.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
npm install @ada-cx/messaging-sdk
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Quick start
|
|
17
|
+
|
|
18
|
+
Call `loadAdaMessaging` with your bot handle. It loads the runtime, creates
|
|
19
|
+
the messaging interface, starts the widget, and returns the interface.
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { loadAdaMessaging } from "@ada-cx/messaging-sdk";
|
|
23
|
+
|
|
24
|
+
// Module scope: your code holds the only reference.
|
|
25
|
+
const ada = await loadAdaMessaging({ handle: "my-bot" });
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`loadAdaMessaging` never assigns the interface to `window` or any other
|
|
29
|
+
global. Keep the returned reference in module scope, where only your own code
|
|
30
|
+
can reach it. A global is reachable by every script on the page. The
|
|
31
|
+
`createAdaEmbedInterface` export exists only as the legacy `window.adaEmbed`
|
|
32
|
+
compat facade for pages migrating from the script-tag setup.
|
|
33
|
+
|
|
34
|
+
Use `loadMessagingSdk` when you want the runtime module without starting a
|
|
35
|
+
widget, for example to preload it before the widget is needed:
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { loadMessagingSdk } from "@ada-cx/messaging-sdk";
|
|
39
|
+
|
|
40
|
+
const sdkModule = await loadMessagingSdk();
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`loadMessagingSdk` memoizes the in-flight import. Concurrent calls share one
|
|
44
|
+
load. Both loaders reject a failed load with a `MessagingSdkLoadError` and
|
|
45
|
+
permit a retry:
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import { MessagingSdkLoadError } from "@ada-cx/messaging-sdk";
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
await loadAdaMessaging({ handle: "my-bot" });
|
|
52
|
+
} catch (error) {
|
|
53
|
+
if (error instanceof MessagingSdkLoadError) {
|
|
54
|
+
console.error(error.code); // "invalid_cdn_base" | "invalid_build_sha" | "unstamped_build_sha" | "sdk_import_failed" | "sdk_module_invalid"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## One widget per page
|
|
60
|
+
|
|
61
|
+
Only one messaging interface can run on a page, and `loadAdaMessaging`
|
|
62
|
+
enforces this for you. Repeated calls return the same memoized promise and
|
|
63
|
+
resolve to the same started interface. The first call's settings win, and
|
|
64
|
+
later calls never start a second widget. When a later call passes different
|
|
65
|
+
settings, the loader logs a console warning and ignores the new settings.
|
|
66
|
+
The call is therefore safe in code that runs more than once, such as React
|
|
67
|
+
Strict Mode development effects. You do not need to cache the promise
|
|
68
|
+
yourself.
|
|
69
|
+
|
|
70
|
+
A failed load or start clears the memo, so a later call can retry.
|
|
71
|
+
|
|
72
|
+
Control the widget lifecycle through the returned interface. `ada.stop()`
|
|
73
|
+
tears the widget down, and a later `ada.start(settings)` on the same
|
|
74
|
+
interface starts it again. A `loadAdaMessaging` call after `stop()` returns
|
|
75
|
+
the same stopped interface. It does not restart the widget. The loader logs
|
|
76
|
+
a console warning when it returns a stopped interface, so call
|
|
77
|
+
`start(settings)` on that interface to run the widget again.
|
|
78
|
+
|
|
79
|
+
## Module formats
|
|
80
|
+
|
|
81
|
+
The package ships ESM and CommonJS builds of both entries. Bundlers and
|
|
82
|
+
ESM runtimes use the `import` condition. Jest and other CommonJS runners
|
|
83
|
+
use the `require` condition. TypeScript resolves both entries under
|
|
84
|
+
`moduleResolution` `bundler`, `node16`, and the legacy `node10` setting.
|
|
85
|
+
|
|
86
|
+
## Types
|
|
87
|
+
|
|
88
|
+
Import any public type directly. Type imports add zero runtime code.
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
import type {
|
|
92
|
+
AdaMessagingInterface,
|
|
93
|
+
AdaMessagingSettings,
|
|
94
|
+
AdaMessagingStartOptions,
|
|
95
|
+
PublicMessage,
|
|
96
|
+
ResetParams,
|
|
97
|
+
} from "@ada-cx/messaging-sdk";
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
`AdaMessagingInterface` is the interface `loadAdaMessaging` resolves. The
|
|
101
|
+
`AdaEmbedInterface` name remains available as its legacy alias.
|
|
102
|
+
|
|
103
|
+
Runtime symbols such as `AdaMessagingClient` and `createAdaEmbedInterface`
|
|
104
|
+
are exported as types only. Get their implementations from
|
|
105
|
+
`loadMessagingSdk()`. `createAdaEmbedInterface` exists for migrations from
|
|
106
|
+
the legacy `window.adaEmbed` contract; new integrations use
|
|
107
|
+
`loadAdaMessaging`.
|
|
108
|
+
|
|
109
|
+
## Testing your integration
|
|
110
|
+
|
|
111
|
+
The `./testing` entry provides an in-memory mock of the messaging interface.
|
|
112
|
+
Your unit tests never touch the CDN.
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
import { createMockAdaMessaging } from "@ada-cx/messaging-sdk/testing";
|
|
116
|
+
|
|
117
|
+
const ada = createMockAdaMessaging();
|
|
118
|
+
|
|
119
|
+
await ada.sendMessage("hello");
|
|
120
|
+
expect(ada.calls).toContainEqual({
|
|
121
|
+
method: "sendMessage",
|
|
122
|
+
args: ["hello"],
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// Simulate an SDK event for your subscribers.
|
|
126
|
+
await ada.subscribeEvent("ada:conversation:message", onMessage);
|
|
127
|
+
ada.$emit("ada:conversation:message", { message_id: "m1" });
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The mock records every call in `calls`. It keeps light state: sent messages
|
|
131
|
+
appear in `getMessages()`, and `open`/`close` drive `isOpen()`. Pass
|
|
132
|
+
overrides to replace any method with your own spy:
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
const ada = createMockAdaMessaging({ getMessages: vi.fn(async () => []) });
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Bundler note
|
|
139
|
+
|
|
140
|
+
The loader imports the runtime with a fully dynamic URL. The import is
|
|
141
|
+
pre-annotated with `/* webpackIgnore: true */` and `/* @vite-ignore */`, so
|
|
142
|
+
webpack and Vite leave it for the browser to resolve. Do not copy the import
|
|
143
|
+
into your own code without those annotations. If your bundler still rewrites
|
|
144
|
+
dynamic imports, configure it to ignore imports of `https:` URLs.
|
|
145
|
+
|
|
146
|
+
## Versioning and staging validation
|
|
147
|
+
|
|
148
|
+
The npm version covers only the loader, the types, and the mocks. It never
|
|
149
|
+
pins the runtime. The runtime always resolves from Ada's CDN rollout at page
|
|
150
|
+
load.
|
|
151
|
+
|
|
152
|
+
To validate a specific runtime build on any page, add the
|
|
153
|
+
`?ada-messaging-version=<version>` query parameter to the page URL. The value
|
|
154
|
+
accepts a `pr-<N>` preview build or a git SHA from a main build. An invalid
|
|
155
|
+
or unavailable value falls back to the stable rollout.
|
|
156
|
+
|
|
157
|
+
To validate against a different asset host, pass its root to the loader. Ada
|
|
158
|
+
gives you the host value when you arrange a preproduction validation:
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
await loadAdaMessaging(
|
|
162
|
+
{ handle: "my-bot" },
|
|
163
|
+
{ cdnBase: "<ada-provided-asset-host>" },
|
|
164
|
+
);
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Use `cdnBase` for staging validation only. Production pages must keep the
|
|
168
|
+
default.
|
|
169
|
+
|
|
170
|
+
### Pin the CDN build
|
|
171
|
+
|
|
172
|
+
The package exports `CDN_BUILD_SHA`. The value is the git commit SHA of the
|
|
173
|
+
monorepo commit this npm version was published from. Ada deploys each
|
|
174
|
+
commit's runtime under an immutable SHA root on the CDN. The value therefore
|
|
175
|
+
names the CDN build associated with this npm version.
|
|
176
|
+
|
|
177
|
+
Pass the SHA as the `pinBuildSha` loader option. The loader then skips the
|
|
178
|
+
rollout bootstrap and imports that build's immutable entry,
|
|
179
|
+
`<cdnBase>/<sha>/sdk/index.js`, directly:
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
import {
|
|
183
|
+
CDN_BUILD_SHA,
|
|
184
|
+
isCdnBuildShaStamped,
|
|
185
|
+
loadAdaMessaging,
|
|
186
|
+
} from "@ada-cx/messaging-sdk";
|
|
187
|
+
|
|
188
|
+
if (isCdnBuildShaStamped()) {
|
|
189
|
+
await loadAdaMessaging({ handle: "my-bot" }, { pinBuildSha: CDN_BUILD_SHA });
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Pinning is not recommended for production.** A pinned runtime misses Ada's
|
|
194
|
+
fixes and rollouts. A pinned runtime can also predate later server contract
|
|
195
|
+
changes and stop working. Use a pin only to debug an issue, to validate a
|
|
196
|
+
staged build, or to reproduce a report against a known runtime.
|
|
197
|
+
|
|
198
|
+
The option accepts any full 40-character hex git SHA of a deployed main
|
|
199
|
+
build. The loader rejects any other value with the `invalid_build_sha` error
|
|
200
|
+
code. Only published packages carry a real SHA. In the repository, and in a
|
|
201
|
+
locally built copy, `CDN_BUILD_SHA` is a 40-zero placeholder and
|
|
202
|
+
`isCdnBuildShaStamped()` returns `false`. The loader rejects the placeholder
|
|
203
|
+
with the `unstamped_build_sha` error code.
|
|
204
|
+
|
|
205
|
+
The npm publish and the CDN deploy of the same commit run in parallel. In
|
|
206
|
+
the first minutes after a release, a pin can fail with `sdk_import_failed`
|
|
207
|
+
until the deploy completes. If the deploy of that commit failed, the pinned
|
|
208
|
+
build never exists. The unpinned default is unaffected in both cases.
|
|
209
|
+
|
|
210
|
+
`pinBuildSha` composes with `cdnBase`. The pinned entry resolves under the
|
|
211
|
+
asset host you pass.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AdaMessagingClientConfig } from "./client-types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Reads `window.adaSettings` and maps recognised fields to
|
|
4
|
+
* `AdaMessagingClientConfig`. All field access is defensive — unknown types
|
|
5
|
+
* are silently ignored so that a mal-formed host page cannot crash the SDK.
|
|
6
|
+
*
|
|
7
|
+
* Priority rule: the constructor config always wins. This module only
|
|
8
|
+
* supplies fallback values that the constructor has not explicitly set.
|
|
9
|
+
*/
|
|
10
|
+
export declare function readAdaSettings(): Partial<AdaMessagingClientConfig>;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { FrameChannel, FrameName, FrameRegistry, FrameToSdkEvents, StartupConfig } from "../frame-channel/index.js";
|
|
2
|
+
import type { AdaSdkEventCallback, WindowInfo } from "./client-types.js";
|
|
3
|
+
interface BaseChannelDependencies {
|
|
4
|
+
channels: Map<FrameName, FrameChannel>;
|
|
5
|
+
frames: FrameRegistry;
|
|
6
|
+
parentElement: HTMLElement | null;
|
|
7
|
+
getAlign: () => "left" | "right";
|
|
8
|
+
open: () => void;
|
|
9
|
+
}
|
|
10
|
+
export interface ProactiveDisplayRequest {
|
|
11
|
+
campaignKey: string | null;
|
|
12
|
+
surfaceId: number;
|
|
13
|
+
triggerMethod?: "url" | "programmatic";
|
|
14
|
+
displayDelay?: number;
|
|
15
|
+
frequency?: "always" | "session" | "user";
|
|
16
|
+
intentId?: number;
|
|
17
|
+
}
|
|
18
|
+
export interface CoreChannelDependencies extends BaseChannelDependencies {
|
|
19
|
+
channel: FrameChannel;
|
|
20
|
+
config: {
|
|
21
|
+
handle: string;
|
|
22
|
+
language?: string;
|
|
23
|
+
headless?: boolean;
|
|
24
|
+
rolloutOverride?: number;
|
|
25
|
+
sensitiveMetaFields?: Record<string, unknown>;
|
|
26
|
+
styles?: Record<string, string>;
|
|
27
|
+
eventCallbacks?: Record<string, AdaSdkEventCallback>;
|
|
28
|
+
};
|
|
29
|
+
deliverConfig: (channel: FrameChannel) => void;
|
|
30
|
+
close: (reason?: "close" | "minimize") => void;
|
|
31
|
+
destroy: () => void;
|
|
32
|
+
routePublishedEvent: (key: string, data: unknown) => void;
|
|
33
|
+
invokeWindowCallback: (name: string, ...args: unknown[]) => void;
|
|
34
|
+
dispatchIntegrationCommand: (payload: unknown) => void;
|
|
35
|
+
startVoiceRecording: () => void;
|
|
36
|
+
stopVoiceRecording: () => void;
|
|
37
|
+
setVoiceLanguage: (language: string) => void;
|
|
38
|
+
setVoiceMode: (mode: "push-to-talk" | "toggle") => void;
|
|
39
|
+
setStartupConfig: (config: StartupConfig) => void;
|
|
40
|
+
getStartupConfig: () => StartupConfig | null;
|
|
41
|
+
getIsChatOpen: () => boolean;
|
|
42
|
+
getWindowInfo: () => WindowInfo;
|
|
43
|
+
scheduleIntro: (intro: NonNullable<StartupConfig["intro"]>) => void;
|
|
44
|
+
/** Evaluate URL-triggered proactive conversations for the current page. */
|
|
45
|
+
evaluateProactive: () => void;
|
|
46
|
+
/** Schedule or immediately deliver one resolved proactive display. */
|
|
47
|
+
showProactive: (request: ProactiveDisplayRequest, display: () => void) => void;
|
|
48
|
+
beginProactiveDisplay: (campaignKey: string, surfaceId: number, intentId?: number) => void;
|
|
49
|
+
isProactiveClearPending: () => boolean;
|
|
50
|
+
acknowledgeProactiveClear: (requestId: number) => void;
|
|
51
|
+
clearProactiveFromCore: () => void;
|
|
52
|
+
incrementUnreadCount: () => number;
|
|
53
|
+
setHasActiveChatter: (value: boolean) => void;
|
|
54
|
+
setChatterToken: (chatterToken: string) => boolean | undefined;
|
|
55
|
+
setChatterCandidate: (candidate: FrameToSdkEvents["core.chatter.candidate"]) => void;
|
|
56
|
+
handleSessionResumeResult: (result: FrameToSdkEvents["core.session.resume.result"]) => void;
|
|
57
|
+
handleSessionResumeVisibilityResult: (result: FrameToSdkEvents["core.session.resume.visibility.result"]) => void;
|
|
58
|
+
clearIdentityToken: () => void;
|
|
59
|
+
markIdentityTokenConsumed?: (chatterToken?: string) => void;
|
|
60
|
+
markIdentityTokenFailed?: () => void;
|
|
61
|
+
setPersistenceMode?: (mode: "normal" | "session" | "private") => void;
|
|
62
|
+
setCrossWindowLiveChatActive: (value: boolean) => void;
|
|
63
|
+
setSensitiveMetaFields: (fields: Record<string, unknown>) => void;
|
|
64
|
+
setHostViewportExpanded: (expanded: boolean) => void;
|
|
65
|
+
/** Run host-side work that must wait until the replacement core has prepared. */
|
|
66
|
+
onCoreReady?: () => void;
|
|
67
|
+
/** Claim reset ordering as soon as Core's SDK router is installed. */
|
|
68
|
+
onCoreProtocolReady?: () => void;
|
|
69
|
+
infoRequestCallbacks: Map<string, (info: WindowInfo) => void>;
|
|
70
|
+
infoRequestTimers: Map<string, ReturnType<typeof setTimeout>>;
|
|
71
|
+
resolveDataRequest: (requestId: string, data: unknown) => void;
|
|
72
|
+
rejectDataRequest: (requestId: string, message: string) => void;
|
|
73
|
+
flushDataRequests: (options?: {
|
|
74
|
+
preserveForCoreReplacement?: boolean;
|
|
75
|
+
}) => void;
|
|
76
|
+
getZdChatterAuthCallback: () => ((callback: (token: string) => void) => void) | null;
|
|
77
|
+
}
|
|
78
|
+
export interface ButtonChannelDependencies {
|
|
79
|
+
channel: FrameChannel;
|
|
80
|
+
frames: FrameRegistry;
|
|
81
|
+
deliverConfig: (channel: FrameChannel) => void;
|
|
82
|
+
open: () => void;
|
|
83
|
+
setLastOpenedViaKeyboard: (value: boolean) => void;
|
|
84
|
+
/** Needed to re-anchor a showing proactive bubble when the launcher resizes. */
|
|
85
|
+
getAlign: () => "left" | "right";
|
|
86
|
+
getIsChatOpen: () => boolean;
|
|
87
|
+
}
|
|
88
|
+
/** Wire all message handlers for the core (headless business logic) frame. */
|
|
89
|
+
export declare function setupCoreChannelHandlers(deps: CoreChannelDependencies): () => void;
|
|
90
|
+
/** Wire all message handlers for the button (chat trigger) frame. */
|
|
91
|
+
export declare function setupButtonChannelHandlers(deps: ButtonChannelDependencies): void;
|
|
92
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
type AdaEmbedErrorCode = "start_already_active" | "start_interrupted" | "start_owner_conflict";
|
|
2
|
+
/** Legacy-compatible public error shape for host SDK lifecycle failures. */
|
|
3
|
+
export declare class AdaEmbedError extends Error {
|
|
4
|
+
readonly code?: AdaEmbedErrorCode;
|
|
5
|
+
constructor(message: string, code?: AdaEmbedErrorCode);
|
|
6
|
+
}
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { FrameName } from "../frame-channel/index.js";
|
|
2
|
+
/** Default frame HTML files relative to their package asset path */
|
|
3
|
+
export declare const FRAME_SOURCES: Record<FrameName, string>;
|
|
4
|
+
/**
|
|
5
|
+
* Which built package each frame's HTML ships from. `core`/`button` are plain
|
|
6
|
+
* vanilla-JS frames in `packages/sdk/public`. `intro` renders the Lovelace
|
|
7
|
+
* `ProactiveMessage` design-system component, so it lives in `packages/integrations`
|
|
8
|
+
* (React is banned in `sdk` — see `.claude/rules/architecture.md`).
|
|
9
|
+
*/
|
|
10
|
+
export declare const FRAME_PACKAGES: Record<FrameName, "sdk" | "integrations">;
|
|
11
|
+
/**
|
|
12
|
+
* The accessible name a screen reader reads when it reaches each frame from the
|
|
13
|
+
* host page (axe `frame-title`, WCAG 4.1.2). Applied on mount for every frame, so
|
|
14
|
+
* a new frame cannot ship unnamed.
|
|
15
|
+
*
|
|
16
|
+
* Untranslated, like the launcher's name has always been: the SDK mounts frames
|
|
17
|
+
* before any locale is resolved, and these read on the host page rather than
|
|
18
|
+
* inside the chat.
|
|
19
|
+
*/
|
|
20
|
+
export declare const FRAME_TITLES: Record<FrameName, string>;
|
|
21
|
+
/**
|
|
22
|
+
* One name for every integration runtime. They are headless and permanently 0×0, so
|
|
23
|
+
* a reader never lands in one and there is nothing to tell them apart by.
|
|
24
|
+
*/
|
|
25
|
+
export declare const INTEGRATION_FRAME_TITLE = "Ada Chat Integration";
|
|
26
|
+
/**
|
|
27
|
+
* Least-privilege sandbox policies per top-level frame.
|
|
28
|
+
*
|
|
29
|
+
* - core must permit forms/popups/downloads because it hosts the nested app
|
|
30
|
+
* iframe, which supports transcript downloads and outbound legal/support links.
|
|
31
|
+
* `allow-popups-to-escape-sandbox` is required so those popups load as normal,
|
|
32
|
+
* unsandboxed tabs — without it, a popup opened from a sandboxed frame stays
|
|
33
|
+
* sandboxed, and Chrome blocks the navigation outright when the target site
|
|
34
|
+
* sets a Cross-Origin-Opener-Policy header (EXP-268).
|
|
35
|
+
* - button/intro are utility frames and do not require forms/popups.
|
|
36
|
+
*/
|
|
37
|
+
export declare const FRAME_SANDBOX_POLICIES: Record<FrameName, string>;
|
|
38
|
+
export declare const ASSET_QUERY_HANDLE_KEY = "ada_handle";
|
|
39
|
+
export declare const ASSET_QUERY_CLUSTER_KEY = "ada_cluster";
|
|
40
|
+
/** Frame load timeout in milliseconds — see constants.ts for the canonical value */
|
|
41
|
+
export { FRAME_LOAD_TIMEOUT_MS } from "./constants.js";
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { FrameName, FrameRegistry } from "../frame-channel/index.js";
|
|
2
|
+
import { FrameChannel } from "../frame-channel/index.js";
|
|
3
|
+
export interface BuildAssetUrlRuntimeOptions {
|
|
4
|
+
packageName: "sdk" | "integrations";
|
|
5
|
+
path: string;
|
|
6
|
+
handle: string;
|
|
7
|
+
cluster: string;
|
|
8
|
+
assetsOrigin: string;
|
|
9
|
+
commitSha?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function buildAssetUrlRuntime(options: BuildAssetUrlRuntimeOptions): string;
|
|
12
|
+
/**
|
|
13
|
+
* Recover the CDN base that buildAssetUrlRuntime expects (origin + any path
|
|
14
|
+
* prefix such as "/messaging" for the static.ada.support root) from the running
|
|
15
|
+
* SDK module's own URL. Deployed assets live at `<base>/<sha>/sdk/index.js`, so
|
|
16
|
+
* the base is the path up to (and including the slash before) the `<sha>`
|
|
17
|
+
* segment. Using `new URL(metaUrl).origin` would drop a path prefix and break the
|
|
18
|
+
* static.ada.support/messaging/ root for frame URLs. Falls back to the baked
|
|
19
|
+
* origin in dev (or any case where the `<sha>` segment isn't in the path, or
|
|
20
|
+
* metaUrl can't be parsed as http(s) — e.g. an opaque blob origin).
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveAssetsOriginRuntime(metaUrl: string, commitSha: string | undefined, fallbackOrigin: string): string;
|
|
23
|
+
export interface MountFrameRuntimeOptions {
|
|
24
|
+
name: FrameName;
|
|
25
|
+
options: {
|
|
26
|
+
style: string;
|
|
27
|
+
};
|
|
28
|
+
container: HTMLElement | null;
|
|
29
|
+
frames: FrameRegistry;
|
|
30
|
+
loadTimers: Map<string, ReturnType<typeof setTimeout>>;
|
|
31
|
+
buildAssetUrl: (packageName: "sdk" | "integrations", path: string) => string;
|
|
32
|
+
onFrameTimeout: (name: FrameName, message: string) => void;
|
|
33
|
+
onFrameLoaded: (name: FrameName, iframe: HTMLIFrameElement) => void;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Create an iframe, append it to the container, and set up
|
|
37
|
+
* a FrameChannel once it loads.
|
|
38
|
+
*/
|
|
39
|
+
export declare function mountFrameRuntime(options: MountFrameRuntimeOptions): void;
|
|
40
|
+
export interface OnFrameLoadedRuntimeOptions {
|
|
41
|
+
name: FrameName;
|
|
42
|
+
iframe: HTMLIFrameElement;
|
|
43
|
+
channels: Map<FrameName, FrameChannel>;
|
|
44
|
+
getFrameOrigin: (frame: HTMLIFrameElement) => string | null;
|
|
45
|
+
setupCoreChannel: (channel: FrameChannel) => void;
|
|
46
|
+
setupButtonChannel: (channel: FrameChannel) => void;
|
|
47
|
+
setupIntroChannel: (channel: FrameChannel) => void;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Called when an iframe has loaded. Creates a FrameChannel, wires origin
|
|
51
|
+
* locking and error reporting (shared for all frames), then delegates
|
|
52
|
+
* per-frame channel setup.
|
|
53
|
+
*/
|
|
54
|
+
export declare function onFrameLoadedRuntime(options: OnFrameLoadedRuntimeOptions): void;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { FrameChannel } from "../frame-channel/index.js";
|
|
2
|
+
import type { ClearPersistenceAckResponseType } from "../frame-channel/types.js";
|
|
3
|
+
import type { HostTelemetryContext } from "../host-telemetry.js";
|
|
4
|
+
import type { AdaSdkEventCallback } from "./client-types.js";
|
|
5
|
+
export interface DeliverConfigRuntimeOptions {
|
|
6
|
+
handle: string;
|
|
7
|
+
cluster: string | null;
|
|
8
|
+
endpoint: string;
|
|
9
|
+
language?: string;
|
|
10
|
+
greeting?: string;
|
|
11
|
+
configuredGreetingResponseId?: string;
|
|
12
|
+
identityToken?: string;
|
|
13
|
+
greetingResponseId?: string | null;
|
|
14
|
+
metaFields?: Record<string, unknown>;
|
|
15
|
+
sensitiveMetaFields?: Record<string, unknown>;
|
|
16
|
+
allowMetaFieldsInReset?: boolean;
|
|
17
|
+
enableProgrammaticControl?: boolean;
|
|
18
|
+
/** Customer-hosted app frame URL (already normalized to https). */
|
|
19
|
+
appUrl?: string;
|
|
20
|
+
appUrlFallback?: boolean;
|
|
21
|
+
hostTelemetry?: HostTelemetryContext;
|
|
22
|
+
styles?: Record<string, string>;
|
|
23
|
+
theme?: "light" | "dark" | "auto";
|
|
24
|
+
testMode?: boolean;
|
|
25
|
+
privateMode?: boolean;
|
|
26
|
+
isParentElementMode?: boolean;
|
|
27
|
+
isMobileViewport?: boolean;
|
|
28
|
+
hideDefaultHeader?: boolean;
|
|
29
|
+
clearPersistenceOnPrepare?: boolean;
|
|
30
|
+
clearPersistenceAckRequestId?: string;
|
|
31
|
+
clearPersistenceAckResponseType?: ClearPersistenceAckResponseType;
|
|
32
|
+
clearPersistenceStorageModes?: Array<"normal" | "session" | "private">;
|
|
33
|
+
/** Sticky SDK-owned fact matching legacy Embed2 `wasIntroShown`. */
|
|
34
|
+
introShown?: boolean;
|
|
35
|
+
}
|
|
36
|
+
/** Send the client configuration to a frame. */
|
|
37
|
+
export declare function deliverConfigRuntime(channel: FrameChannel, config: DeliverConfigRuntimeOptions): void;
|
|
38
|
+
/** Safely invoke a window-level callback if it exists and is a function. */
|
|
39
|
+
export declare function invokeWindowCallbackRuntime(name: string, ...args: unknown[]): void;
|
|
40
|
+
export type EventSubscriber = {
|
|
41
|
+
key: string;
|
|
42
|
+
wildcard?: false;
|
|
43
|
+
callback: AdaSdkEventCallback;
|
|
44
|
+
} | {
|
|
45
|
+
key: "*";
|
|
46
|
+
wildcard: true;
|
|
47
|
+
callback: (key: string, data: unknown) => void;
|
|
48
|
+
};
|
|
49
|
+
export declare function subscriberMatchesEventKeyRuntime(subscriber: EventSubscriber, key: string): boolean;
|
|
50
|
+
/** Route a published event key to all matching subscribeEvent subscribers. */
|
|
51
|
+
export declare function routePublishedEventRuntime(subscribers: Map<number, EventSubscriber>, key: string, data: unknown): void;
|
|
52
|
+
export interface LocationHistoryRuntimeState {
|
|
53
|
+
origPushState: typeof history.pushState | null;
|
|
54
|
+
origReplaceState: typeof history.replaceState | null;
|
|
55
|
+
locationChangeHandler: (() => void) | null;
|
|
56
|
+
popstateHandler: (() => void) | null;
|
|
57
|
+
}
|
|
58
|
+
export declare const EMPTY_LOCATION_HISTORY_STATE: LocationHistoryRuntimeState;
|
|
59
|
+
/** Share the page-owned scroll lock across defensive or nested callers. */
|
|
60
|
+
export declare function acquireDocumentScrollLockRuntime(): void;
|
|
61
|
+
/** Release one caller's ownership and restore only after the final owner. */
|
|
62
|
+
export declare function releaseDocumentScrollLockRuntime(): void;
|
|
63
|
+
/**
|
|
64
|
+
* Patch history.pushState / replaceState and listen to popstate so that
|
|
65
|
+
* single-page-app navigation fires a synthetic "ada:locationchange" event.
|
|
66
|
+
*
|
|
67
|
+
* Uses module-level ref counting so defensive concurrent callers share one
|
|
68
|
+
* patch and one native popstate listener; the originals are only restored when
|
|
69
|
+
* the last caller unpatches.
|
|
70
|
+
*/
|
|
71
|
+
export declare function patchLocationHistoryRuntime(state: LocationHistoryRuntimeState, onLocationChange: () => void): LocationHistoryRuntimeState;
|
|
72
|
+
/** Restore original history methods and remove location listeners. */
|
|
73
|
+
export declare function unpatchLocationHistoryRuntime(state: LocationHistoryRuntimeState): LocationHistoryRuntimeState;
|