@ada-cx/messaging-sdk

中文文档
1.10.1发布于 2026/11/06ISCTypeScriptESM + CJS零依赖近 30 天下载 1.8万

TypeScript types, test mocks, and a thin CDN loader for the Ada Messaging SDK. The runtime always resolves from Ada's CDN and is never bundled into this package.

原始使用文档
文档目录9 节
  1. Install
  2. Quick start
  3. One widget per page
  4. Module formats
  5. Types
  6. Testing your integration
  7. Bundler note
  8. Versioning and staging validation
  9. Pin the CDN build

@ada-cx/messaging-sdk

TypeScript types, test mocks, and a thin loader for the Ada Messaging SDK.

This package never contains the SDK runtime. The loader imports the runtime from Ada's CDN at page load. Ada ships runtime fixes to the CDN, and every page receives them on the next load. This is the same model as @stripe/stripe-js.

Install

npm install @ada-cx/messaging-sdk

Quick start

Call loadAdaMessaging with your bot handle. It loads the runtime, creates the messaging interface, starts the widget, and returns the interface.

import { loadAdaMessaging } from "@ada-cx/messaging-sdk";

// Module scope: your code holds the only reference.
const ada = await loadAdaMessaging({ handle: "my-bot" });

loadAdaMessaging never assigns the interface to window or any other global. Keep the returned reference in module scope, where only your own code can reach it. A global is reachable by every script on the page. The createAdaEmbedInterface export exists only as the legacy window.adaEmbed compat facade for pages migrating from the script-tag setup.

Use loadMessagingSdk when you want the runtime module without starting a widget, for example to preload it before the widget is needed:

import { loadMessagingSdk } from "@ada-cx/messaging-sdk";

const sdkModule = await loadMessagingSdk();

loadMessagingSdk memoizes the in-flight import. Concurrent calls share one load. Both loaders reject a failed load with a MessagingSdkLoadError and permit a retry:

import { MessagingSdkLoadError } from "@ada-cx/messaging-sdk";

try {
    await loadAdaMessaging({ handle: "my-bot" });
} catch (error) {
    if (error instanceof MessagingSdkLoadError) {
        console.error(error.code); // "invalid_cdn_base" | "invalid_build_sha" | "unstamped_build_sha" | "sdk_import_failed" | "sdk_module_invalid"
    }
}

If both imports fail, cause holds the default-root typed error and readonly fallbackCause holds the fallback typed error. Both errors retain their original cause chains. An invalid fallback module uses the same error properties and preserves sdk_module_invalid and the fallback error message.

One widget per page

Only one messaging interface can run on a page, and loadAdaMessaging enforces this for you. Repeated calls return the same memoized promise and resolve to the same started interface. The first call's settings win, and later calls never start a second widget. When a later call passes different settings, the loader logs a console warning and ignores the new settings. The call is therefore safe in code that runs more than once, such as React Strict Mode development effects. You do not need to cache the promise yourself.

A failed load or start clears the memo, so a later call can retry.

Control the widget lifecycle through the returned interface. ada.stop() tears the widget down, and a later ada.start(settings) on the same interface starts it again. A loadAdaMessaging call after stop() returns the same stopped interface. It does not restart the widget. The loader logs a console warning when it returns a stopped interface, so call start(settings) on that interface to run the widget again.

Module formats

The package ships ESM and CommonJS builds of both entries. Bundlers and ESM runtimes use the import condition. Jest and other CommonJS runners use the require condition. TypeScript resolves both entries under moduleResolution bundler, node16, and the legacy node10 setting.

Types

Import any public type directly. Type imports add zero runtime code.

import type {
    AdaMessagingInterface,
    AdaMessagingSettings,
    AdaMessagingStartOptions,
    PublicMessage,
    ResetParams,
} from "@ada-cx/messaging-sdk";

AdaMessagingInterface is the interface loadAdaMessaging resolves. The AdaEmbedInterface name remains available as its legacy alias.

Runtime symbols such as AdaMessagingClient and createAdaEmbedInterface are exported as types only. Get their implementations from loadMessagingSdk(). createAdaEmbedInterface exists for migrations from the legacy window.adaEmbed contract; new integrations use loadAdaMessaging.

window.adaSettings, new AdaMessagingClient(config), createAdaEmbedInterface(initialSettings), and adaEmbed.start(settings) accept crossWindowPersistence as a boolean or { enabled: boolean }. The SDK uses the boolean value of enabled, so { enabled: false } disables persistence. For invalid values, the SDK logs a console warning once per page load.

Invalid overrides preserve the retained host setting or the window.adaSettings fallback. Invalid constructor values preserve the window.adaSettings fallback. Without either setting, persistence defaults to on. The TypeScript setting remains boolean.

Testing your integration

The ./testing entry provides an in-memory mock of the messaging interface. Your unit tests never touch the CDN.

import { createMockAdaMessaging } from "@ada-cx/messaging-sdk/testing";

const ada = createMockAdaMessaging();

await ada.sendMessage("hello");
expect(ada.calls).toContainEqual({
    method: "sendMessage",
    args: ["hello"],
});

// Simulate an SDK event for your subscribers.
await ada.subscribeEvent("ada:conversation:message", onMessage);
ada.$emit("ada:conversation:message", { message_id: "m1" });

The mock records every call in calls. It keeps light state: sent messages appear in getMessages(), and open/close drive isOpen(). Pass overrides to replace any method with your own spy:

const ada = createMockAdaMessaging({ getMessages: vi.fn(async () => []) });

Bundler note

The loader imports the runtime with a fully dynamic URL. The import is pre-annotated with /* webpackIgnore: true */ and /* @vite-ignore */, so webpack and Vite leave it for the browser to resolve. Do not copy the import into your own code without those annotations. If your bundler still rewrites dynamic imports, configure it to ignore imports of https: URLs.

Versioning and staging validation

The npm version covers only the loader, the types, and the mocks. It never pins the runtime. The runtime always resolves from Ada's CDN rollout at page load.

To validate a specific runtime build on any page, add the ?ada-messaging-version=<version> query parameter to the page URL. The value accepts a pr-<N> preview build or a git SHA from a main build. An invalid or unavailable value falls back to the stable rollout.

To validate against a different asset host, pass its root to the loader. Ada gives you the host value when you arrange a preproduction validation:

await loadAdaMessaging(
    { handle: "my-bot" },
    { cdnBase: "<ada-provided-asset-host>" },
);

The preferred production root is https://messaging-assets.ada.support/. For production pages whose CSP already allows static.ada.support, use cdnBase: "https://static.ada.support/messaging/". The package exports this supported production root as FALLBACK_MESSAGING_CDN_BASE.

Without cdnBase, the loader automatically retries once from the static root when the default import fails, including CSP and network failures. If the default bootstrap rejects after manifest or runtime failures, it evicts its shared window.__AdaMessagingSdkBootstrap promise. The static bootstrap can then resolve independently. If resolution is pending or successful, bootstrap copies share the promise. The retry preserves pinBuildSha and its <sha>/sdk/index.js path. Successful unpinned fallback uses the static root for the manifest and frames. An explicit cdnBase disables automatic fallback. Module-invalid and validation errors retain their original codes and messages. If both imports fail, sdk_import_failed names both attempted URLs.

After a successful fallback, the loader logs one warning per page, without debug logging. The warning includes the original error as its second console argument. A TypeError from the default import produces the fetch-failure warning:

[Ada] Loaded the Messaging SDK from https://static.ada.support/messaging/ because the default root https://messaging-assets.ada.support/ was blocked or unavailable. Add https://messaging-assets.ada.support to script-src, connect-src and frame-src, or pass cdnBase: "https://static.ada.support/messaging/".

For a CSP block, update your host's policy as shown in the fetch-failure warning.

Other errors produce the evaluation-failure warning:

[Ada] Loaded the Messaging SDK from https://static.ada.support/messaging/ because the module at https://messaging-assets.ada.support/sdk.js failed to evaluate (Error: boom). This is an Ada-side problem, not your host's CSP. Report it to Ada.

For an evaluation-failure warning, report the original error to Ada. Network failures also produce the fetch-failure warning. A module that throws TypeError during evaluation also produces the fetch-failure warning, so the classification does not prove a CSP block.

Successful loads from the requested root produce no fallback warning.

Pin the CDN build

The package exports CDN_BUILD_SHA. The value is the git commit SHA of the monorepo commit this npm version was published from. Ada deploys each commit's runtime under an immutable SHA root on the CDN. The value therefore names the CDN build associated with this npm version.

Pass the SHA as the pinBuildSha loader option. The loader then skips the rollout bootstrap and imports that build's immutable entry, <cdnBase>/<sha>/sdk/index.js, directly:

import {
    CDN_BUILD_SHA,
    isCdnBuildShaStamped,
    loadAdaMessaging,
} from "@ada-cx/messaging-sdk";

if (isCdnBuildShaStamped()) {
    await loadAdaMessaging({ handle: "my-bot" }, { pinBuildSha: CDN_BUILD_SHA });
}

Pinning is not recommended for production. A pinned runtime misses Ada's fixes and rollouts. A pinned runtime can also predate later server contract changes and stop working. Use a pin only to debug an issue, to validate a staged build, or to reproduce a report against a known runtime.

The option accepts any full 40-character hex git SHA of a deployed main build. The loader rejects any other value with the invalid_build_sha error code. Only published packages carry a real SHA. In the repository, and in a locally built copy, CDN_BUILD_SHA is a 40-zero placeholder and isCdnBuildShaStamped() returns false. The loader rejects the placeholder with the unstamped_build_sha error code.

The npm publish and the CDN deploy of the same commit run in parallel. In the first minutes after a release, a pin can fail with sdk_import_failed until the deploy completes. If the deploy of that commit failed, the pinned build never exists. The unpinned default is unaffected in both cases.

pinBuildSha composes with cdnBase. The pinned entry resolves under the asset host you pass.

版本与发布记录

@ada-cx/messaging-sdk 共发布 49 个版本,首次发布于 2026/08/24;过去 12 个月发布了 49 个版本。

版本发布日期距今
1.10.1latest2026/11/06今天
1.10.02026/11/051 天前
1.9.52026/11/033 天前
1.9.42026/10/316 天前
1.9.32026/10/298 天前
1.9.22026/10/279 天前

其他发布通道:setup → 1.0.0-setup.0。

关于 @ada-cx/messaging-sdk 的常见问题

@ada-cx/messaging-sdk 是什么?

TypeScript types, test mocks, and a thin CDN loader for the Ada Messaging SDK. The runtime always resolves from Ada's CDN and is never bundled into this package.

如何安装 @ada-cx/messaging-sdk?

在项目目录运行 npm install @ada-cx/messaging-sdk,或使用 pnpm add / yarn add / bun add。

@ada-cx/messaging-sdk 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@ada-cx/messaging-sdk 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@ada-cx/messaging-sdk 可以商用吗?

@ada-cx/messaging-sdk 使用 ISC 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@ada-cx/messaging-sdk 的下载量有多少?

根据 npm 官方下载统计,@ada-cx/messaging-sdk 在 2026/10/05 – 2026/11/03 这 30 天内被下载 18,388 次,日均约 613 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@ada-cx/messaging-sdk 还在维护吗?

最新版本 1.10.1 发布于 2026/11/06(今天);至今共发布 49 个版本,其中过去 12 个月发布了 49 个;首次发布于 2026/08/24。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。