npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ada-cx/messaging-sdk

v1.0.1

Published

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.

Readme

@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"
	}
}

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.

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>" },
);

Use cdnBase for staging validation only. Production pages must keep the default.

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.