@ada-cx/messaging-bridge 1.3.0 → 1.3.3

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 CHANGED
@@ -204,12 +204,47 @@ anchors.
204
204
 
205
205
  | Option | Default | Purpose |
206
206
  | --- | --- | --- |
207
- | `cdnBase` | `https://messaging-assets.ada.support` | Asset origin for immutable bridge builds. It must use HTTPS. Plain HTTP works only for loopback development. Override it only when your Ada team directs you to during a joint validation. |
207
+ | `cdnBase` | `https://messaging-assets.ada.support` | Asset root for matching bridge builds. HTTPS is required, except for loopback HTTP. An explicit value disables automatic fallback. |
208
+
209
+ The default root is preferred for production.
210
+ For production pages whose CSP already allows `static.ada.support`, use
211
+ `cdnBase: "https://static.ada.support/messaging/"`.
212
+ Both the root and `/react` entries export this supported production root as `FALLBACK_CDN_BASE`.
213
+ Ada can also provide another asset root for staging validation.
214
+
215
+ Without `cdnBase`, the loader retries once from the static root when the default import fails, including CSP and network failures.
216
+ The retry preserves the mounting core's build identifier and `bridge/bridge.js` path.
217
+ An explicit `cdnBase` disables automatic fallback.
218
+ Module-invalid and validation errors retain their original codes and messages.
219
+ The `dev` marker still requires a loopback `cdnBase`.
220
+ If both imports fail, `bridge_import_failed` names both attempted URLs.
221
+
222
+ After a successful fallback, the loader logs one warning per page, without debug logging.
223
+ The warning includes the original error as its second console argument.
224
+ A `TypeError` from the default import produces the fetch-failure warning:
225
+
226
+ ```text
227
+ [Ada] Loaded the Messaging bridge 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/".
228
+ ```
229
+
230
+ For a CSP block, update your host's policy as shown in the fetch-failure warning.
231
+
232
+ Other errors produce the evaluation-failure warning:
233
+
234
+ ```text
235
+ [Ada] Loaded the Messaging bridge from https://static.ada.support/messaging/ because the module at https://messaging-assets.ada.support/<build identifier>/bridge/bridge.js failed to evaluate (Error: boom). This is an Ada-side problem, not your host's CSP. Report it to Ada.
236
+ ```
237
+
238
+ For an evaluation-failure warning, report the original error to Ada.
239
+ Network failures also produce the fetch-failure warning.
240
+ A module that throws `TypeError` during evaluation also produces the fetch-failure warning, so the classification does not prove a CSP block.
241
+
242
+ Successful loads from the requested root produce no fallback warning.
208
243
 
209
244
  ### Frame-only asset URL resolution
210
245
 
211
- `resolveBridgeCdnUrl()` returns the bridge asset URL selected for the current custom app frame.
212
- It uses the same validation as `loadMessagingBridge()`.
246
+ `resolveBridgeCdnUrl()` reports the current frame's bridge asset URL under the default or explicitly configured root.
247
+ It uses the same validation as `loadMessagingBridge()` but does not report the root used by a fallback load.
213
248
 
214
249
  This helper is frame-only. It throws a `MessagingBridgeLoadError` outside an Ada-mounted custom app frame.
215
250
  Call it after your app starts inside that frame. Do not evaluate it at module scope in code that also runs elsewhere.
@@ -226,6 +261,10 @@ Errors: `loadMessagingBridge` rejects with a `MessagingBridgeLoadError`. Its
226
261
  | `bridge_import_failed` | The asset failed to load (network, CSP, 404). |
227
262
  | `bridge_module_invalid` | The loaded module is not an Ada bridge build. |
228
263
 
264
+ If both imports fail, `cause` holds the default-root typed error and readonly `fallbackCause` holds the fallback typed error.
265
+ Both errors retain their original cause chains.
266
+ An invalid fallback module uses the same error properties and preserves `bridge_module_invalid` and the fallback error message.
267
+
229
268
  ### Matching the core build
230
269
 
231
270
  Ada core mounts your frame with `window.name` set to `ada-custom-app:<build identifier>` before your app code runs. Your URL and its fragment mount untouched, so hash routes keep working.
@@ -81,6 +81,7 @@ export declare const STATE: {
81
81
  readonly CSAT_AUTO_TRIGGER: "csat.autoTrigger";
82
82
  readonly FILE_TRANSFER: "file.transfer";
83
83
  readonly FILE_UPLOAD_ERROR: "file.uploadError";
84
+ readonly FEATURE_FLAGS: "featureFlags";
84
85
  readonly LIVE_AGENT_IN_LIVE_CHAT: "liveAgent.inLiveChat";
85
86
  readonly LIVE_AGENT_LIVE_CHAT_ENDED_IN_CONVERSATION: "liveAgent.liveChatEndedInConversation";
86
87
  readonly TRANSCRIPT_DOWNLOAD_STATUS: "transcript.download.status";
@@ -314,6 +314,7 @@ export type SdkPlatform = "IOS" | "ANDROID" | "REACTNATIVE" | null;
314
314
  * - `voice.*` — Web Speech voice input/TTS state.
315
315
  * - `csat.*` / `endChat.*` — survey settings, eligibility, and End Chat gates.
316
316
  * - `security.*` — Turnstile challenge state.
317
+ * - `featureFlags` — allowlisted LaunchDarkly values exposed to the app.
317
318
  *
318
319
  * Read values by key, or use the `STATE` constants for typo-safe access. This
319
320
  * contract is shared with `packages/core` and must stay in sync with it.
@@ -527,6 +528,8 @@ export interface AppDisplayState {
527
528
  variables: Record<string, unknown> | null;
528
529
  } | null;
529
530
  "liveAgent.handoff.retryRequestedCount"?: number;
531
+ /** False only while core is resolving a restored ZDM agent assignment. */
532
+ "agent.assignmentKnown"?: boolean;
530
533
  "agent.list"?: Array<{
531
534
  id: string;
532
535
  name: string;
@@ -655,6 +658,7 @@ export interface AppDisplayState {
655
658
  "security.turnstileSiteKey"?: string | null;
656
659
  "security.challengeEnabled"?: boolean;
657
660
  "security.challengeError"?: string | null;
661
+ featureFlags?: Record<string, unknown>;
658
662
  }
659
663
  /**
660
664
  * Events the display layer sends to core through `sendEvent`. Each key maps to
@@ -1,3 +1,59 @@
1
+ //#region ../../shared/utils/src/browser-polyfills.ts
2
+ /**
3
+ * Defence in depth for engines just below the declared browser floor.
4
+ * The floor is defined in `messaging/vite.browser-targets.mjs`.
5
+ *
6
+ * Internal Ada code should prefer direct helpers, such as `hasOwn(...)` from
7
+ * `guards.ts`. Every Ada bundle includes these fallbacks, including the host-page
8
+ * SDK. These fallbacks also ship inside the customer-held npm tarballs of the SDK
9
+ * and bridge. Each fallback defines a member only when it is missing. These
10
+ * fallbacks do not extend browser support below the floor required by the shipped CSS.
11
+ */
12
+ var objectHasOwnProperty = Object.prototype.hasOwnProperty;
13
+ function defineValue(target, name, value) {
14
+ Object.defineProperty(target, name, {
15
+ value,
16
+ configurable: true,
17
+ writable: true
18
+ });
19
+ }
20
+ if (!Object.hasOwn) defineValue(Object, "hasOwn", (object, key) => {
21
+ if (object == null) throw new TypeError("ada browser-polyfills: Cannot convert undefined or null to object");
22
+ return objectHasOwnProperty.call(Object(object), key);
23
+ });
24
+ function at(index) {
25
+ const length = Math.trunc(Number(this.length)) || 0;
26
+ let relativeIndex = Math.trunc(Number(index)) || 0;
27
+ if (relativeIndex < 0) relativeIndex += length;
28
+ return relativeIndex < 0 || relativeIndex >= length ? void 0 : this[relativeIndex];
29
+ }
30
+ function stringAt(index) {
31
+ const value = String(this);
32
+ const length = value.length;
33
+ let relativeIndex = Math.trunc(Number(index)) || 0;
34
+ if (relativeIndex < 0) relativeIndex += length;
35
+ return relativeIndex < 0 || relativeIndex >= length ? void 0 : value.charAt(relativeIndex);
36
+ }
37
+ var typedArrayConstructors = [
38
+ globalThis.Int8Array,
39
+ globalThis.Uint8Array,
40
+ globalThis.Uint8ClampedArray,
41
+ globalThis.Int16Array,
42
+ globalThis.Uint16Array,
43
+ globalThis.Int32Array,
44
+ globalThis.Uint32Array,
45
+ globalThis.Float32Array,
46
+ globalThis.Float64Array,
47
+ globalThis.BigInt64Array,
48
+ globalThis.BigUint64Array
49
+ ].filter(Boolean);
50
+ if (!Array.prototype.at) defineValue(Array.prototype, "at", at);
51
+ if (!String.prototype.at) defineValue(String.prototype, "at", stringAt);
52
+ for (const TypedArrayConstructor of typedArrayConstructors) {
53
+ const prototype = TypedArrayConstructor.prototype;
54
+ if (!prototype.at) defineValue(prototype, "at", at);
55
+ }
56
+ //#endregion
1
57
  //#region \0@oxc-project+runtime@0.122.0/helpers/typeof.js
2
58
  function _typeof(o) {
3
59
  "@babel/helpers - typeof";
@@ -38,6 +94,7 @@ function _defineProperty(e, r, t) {
38
94
  //#endregion
39
95
  //#region src/npm/loader.ts
40
96
  var DEFAULT_CDN_BASE = "https://messaging-assets.ada.support";
97
+ var FALLBACK_CDN_BASE = "https://static.ada.support/messaging/";
41
98
  var CUSTOM_APP_FRAME_NAME = "ada-custom-app";
42
99
  var BRIDGE_ENTRY_PATH = "bridge/bridge.js";
43
100
  var DEV_BUILD_MARKER = "dev";
@@ -45,12 +102,16 @@ var PINNED_BUILD_SHA_PATTERN = /^[0-9a-f]{40}$/i;
45
102
  var PR_BUILD_ALIAS_PATTERN = /^pr-\d+$/;
46
103
  /** Typed failure raised by {@link loadMessagingBridge}. */
47
104
  var MessagingBridgeLoadError = class extends Error {
48
- constructor(message, code, cause) {
105
+ constructor(message, code, cause, fallbackCause) {
49
106
  super(message);
50
107
  _defineProperty(this, "code", void 0);
51
108
  this.name = "MessagingBridgeLoadError";
52
109
  this.code = code;
53
110
  if (cause !== void 0) this.cause = cause;
111
+ if (fallbackCause !== void 0) Object.defineProperty(this, "fallbackCause", {
112
+ value: fallbackCause,
113
+ enumerable: true
114
+ });
54
115
  }
55
116
  };
56
117
  var defaultImportModule = (url) => import(
@@ -58,7 +119,9 @@ var defaultImportModule = (url) => import(
58
119
  /* @vite-ignore */
59
120
  url
60
121
  );
61
- var inFlightByImporter = /* @__PURE__ */ new WeakMap();
122
+ var loadsByImporter = /* @__PURE__ */ new WeakMap();
123
+ var FALLBACK_WARNING_KEY = Symbol.for("ada.messaging.bridge.fallbackWarning");
124
+ var warningScope = globalThis;
62
125
  var LOOPBACK_HOSTS = new Set([
63
126
  "localhost",
64
127
  "127.0.0.1",
@@ -129,6 +192,7 @@ function resolveCdnBase(cdnBase) {
129
192
  * PR aliases stay under the configured CDN base. A production-base alias that
130
193
  * does not exist fails closed through the normal bridge import error.
131
194
  * Local development resolves `/bridge/bridge.js` only on a loopback base.
195
+ * This reports the configured root only, not the root a fallback load used.
132
196
  */
133
197
  function resolveBridgeCdnUrl(options) {
134
198
  const build = resolveBridgeBuildFromFrameName(currentFrameName());
@@ -154,6 +218,13 @@ function isMessagingBridgeModule(value) {
154
218
  const candidate = value;
155
219
  return candidate.STATE != null && REQUIRED_BRIDGE_FUNCTION_EXPORTS.every((key) => typeof candidate[key] === "function");
156
220
  }
221
+ function describeRejection(cause) {
222
+ try {
223
+ return cause instanceof Error ? `${cause.name}: ${cause.message}` : String(cause);
224
+ } catch {
225
+ return "unknown error";
226
+ }
227
+ }
157
228
  async function importBridgeModule(url, importModule) {
158
229
  let loaded;
159
230
  try {
@@ -164,34 +235,60 @@ async function importBridgeModule(url, importModule) {
164
235
  if (!isMessagingBridgeModule(loaded)) throw new MessagingBridgeLoadError(`The module at ${url} does not expose the full Ada bridge surface; it is not a complete Ada bridge build.`, "bridge_module_invalid");
165
236
  return loaded;
166
237
  }
238
+ function memoizeLoad(cache, url, load) {
239
+ const existing = cache.get(url);
240
+ if (existing) return existing;
241
+ const pending = load();
242
+ cache.set(url, pending);
243
+ pending.catch(() => {
244
+ if (cache.get(url) === pending) cache.delete(url);
245
+ });
246
+ return pending;
247
+ }
167
248
  /**
168
249
  * Load the bridge runtime that matches the mounting core frame. Loads are
169
250
  * memoized per resolved URL and importer. A failed load is evicted for retry.
251
+ * Without `cdnBase`, an import failure at the default root is retried once
252
+ * from {@link FALLBACK_CDN_BASE}.
170
253
  */
171
254
  function loadMessagingBridge(options = {}) {
172
255
  const importModule = options.importModule ?? defaultImportModule;
173
256
  let url;
257
+ let fallbackUrl;
174
258
  try {
175
259
  url = resolveBridgeCdnUrl(options);
260
+ if (options.cdnBase === void 0) fallbackUrl = resolveBridgeCdnUrl({ cdnBase: FALLBACK_CDN_BASE });
176
261
  } catch (error) {
177
262
  return Promise.reject(error);
178
263
  }
179
- let inFlight = inFlightByImporter.get(importModule);
180
- if (!inFlight) {
181
- inFlight = /* @__PURE__ */ new Map();
182
- inFlightByImporter.set(importModule, inFlight);
183
- }
184
- const existing = inFlight.get(url);
185
- if (existing) return existing;
186
- const cache = inFlight;
187
- const pending = importBridgeModule(url, importModule);
188
- cache.set(url, pending);
189
- pending.catch(() => {
190
- if (cache.get(url) === pending) cache.delete(url);
191
- });
192
- return pending;
264
+ const state = loadsByImporter.get(importModule) ?? {
265
+ imports: /* @__PURE__ */ new Map(),
266
+ defaultLoads: /* @__PURE__ */ new Map()
267
+ };
268
+ loadsByImporter.set(importModule, state);
269
+ const load = (entryUrl) => memoizeLoad(state.imports, entryUrl, () => importBridgeModule(entryUrl, importModule));
270
+ if (fallbackUrl === void 0) return load(url);
271
+ const retryUrl = fallbackUrl;
272
+ return memoizeLoad(state.defaultLoads, url, () => load(url).catch(async (error) => {
273
+ if (!(error instanceof MessagingBridgeLoadError) || error.code !== "bridge_import_failed") throw error;
274
+ let module;
275
+ try {
276
+ module = await load(retryUrl);
277
+ } catch (cause) {
278
+ if (!(cause instanceof MessagingBridgeLoadError)) throw cause;
279
+ throw new MessagingBridgeLoadError(cause.code === "bridge_import_failed" ? `The Ada bridge runtime failed to load from both ${url} and ${retryUrl}.` : cause.message, cause.code, error, cause);
280
+ }
281
+ if (!warningScope[FALLBACK_WARNING_KEY]) {
282
+ warningScope[FALLBACK_WARNING_KEY] = true;
283
+ const cause = error.cause;
284
+ try {
285
+ console.warn(cause instanceof TypeError ? `[Ada] Loaded the Messaging bridge from ${FALLBACK_CDN_BASE} because the default root ${DEFAULT_CDN_BASE}/ was blocked or unavailable. Add ${DEFAULT_CDN_BASE} to script-src, connect-src and frame-src, or pass cdnBase: "${FALLBACK_CDN_BASE}".` : `[Ada] Loaded the Messaging bridge from ${FALLBACK_CDN_BASE} because the module at ${url} failed to evaluate (${describeRejection(cause)}). This is an Ada-side problem, not your host's CSP. Report it to Ada.`, cause);
286
+ } catch {}
287
+ }
288
+ return module;
289
+ }));
193
290
  }
194
291
  //#endregion
195
- export { loadMessagingBridge as n, resolveBridgeCdnUrl as r, MessagingBridgeLoadError as t };
292
+ export { resolveBridgeCdnUrl as i, MessagingBridgeLoadError as n, loadMessagingBridge as r, FALLBACK_CDN_BASE as t };
196
293
 
197
- //# sourceMappingURL=loader-CfCnvaTU.js.map
294
+ //# sourceMappingURL=loader-BjjKuT42.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader-BjjKuT42.js","names":[],"sources":["../../../shared/utils/src/browser-polyfills.ts","../src/npm/loader.ts"],"sourcesContent":["/**\n * Defence in depth for engines just below the declared browser floor.\n * The floor is defined in `messaging/vite.browser-targets.mjs`.\n *\n * Internal Ada code should prefer direct helpers, such as `hasOwn(...)` from\n * `guards.ts`. Every Ada bundle includes these fallbacks, including the host-page\n * SDK. These fallbacks also ship inside the customer-held npm tarballs of the SDK\n * and bridge. Each fallback defines a member only when it is missing. These\n * fallbacks do not extend browser support below the floor required by the shipped CSS.\n */\n\nconst objectHasOwnProperty = Object.prototype.hasOwnProperty;\n\nfunction defineValue(\n\ttarget: object,\n\tname: PropertyKey,\n\tvalue: (...args: unknown[]) => unknown,\n): void {\n\tObject.defineProperty(target, name, {\n\t\tvalue,\n\t\tconfigurable: true,\n\t\twritable: true,\n\t});\n}\n\nif (!Object.hasOwn) {\n\tdefineValue(Object, \"hasOwn\", (object: unknown, key: unknown) => {\n\t\tif (object == null) {\n\t\t\tthrow new TypeError(\n\t\t\t\t\"ada browser-polyfills: Cannot convert undefined or null to object\",\n\t\t\t);\n\t\t}\n\t\treturn objectHasOwnProperty.call(Object(object), key as PropertyKey);\n\t});\n}\n\nfunction at<T>(\n\tthis: { length: number; [index: number]: T },\n\tindex: unknown,\n): T | undefined {\n\tconst length = Math.trunc(Number(this.length)) || 0;\n\tlet relativeIndex = Math.trunc(Number(index)) || 0;\n\tif (relativeIndex < 0) {\n\t\trelativeIndex += length;\n\t}\n\treturn relativeIndex < 0 || relativeIndex >= length\n\t\t? undefined\n\t\t: this[relativeIndex];\n}\n\nfunction stringAt(this: string, index: unknown): string | undefined {\n\tconst value = String(this);\n\tconst length = value.length;\n\tlet relativeIndex = Math.trunc(Number(index)) || 0;\n\tif (relativeIndex < 0) {\n\t\trelativeIndex += length;\n\t}\n\treturn relativeIndex < 0 || relativeIndex >= length\n\t\t? undefined\n\t\t: value.charAt(relativeIndex);\n}\n\nconst typedArrayConstructors = [\n\tglobalThis.Int8Array,\n\tglobalThis.Uint8Array,\n\tglobalThis.Uint8ClampedArray,\n\tglobalThis.Int16Array,\n\tglobalThis.Uint16Array,\n\tglobalThis.Int32Array,\n\tglobalThis.Uint32Array,\n\tglobalThis.Float32Array,\n\tglobalThis.Float64Array,\n\tglobalThis.BigInt64Array,\n\tglobalThis.BigUint64Array,\n].filter(Boolean);\n\nif (!Array.prototype.at) {\n\tdefineValue(Array.prototype, \"at\", at);\n}\n\nif (!String.prototype.at) {\n\tdefineValue(String.prototype, \"at\", stringAt);\n}\n\nfor (const TypedArrayConstructor of typedArrayConstructors) {\n\tconst prototype = TypedArrayConstructor.prototype;\n\tif (!prototype.at) {\n\t\tdefineValue(prototype, \"at\", at);\n\t}\n}\n","import type { createBridgeClient } from \"../contract/bridge-client\";\nimport type {\n\tfilterDisplayable,\n\tfindFirstUnread,\n\tgroupMessages,\n\tisAgentTyping,\n\tisConnectivityLost,\n\tisHistoricalRow,\n\tmessageKey,\n\tresolveBotName,\n\tresolveDisplayBotName,\n\tselectUnread,\n} from \"../contract/derive\";\nimport type { STATE } from \"../contract/state-keys\";\n\nconst DEFAULT_CDN_BASE = \"https://messaging-assets.ada.support\";\nexport const FALLBACK_CDN_BASE = \"https://static.ada.support/messaging/\";\n// Keep aligned with packages/core/src/app-bridge.ts; pinned by\n// scripts/core-html-contract.test.mjs.\nconst CUSTOM_APP_FRAME_NAME = \"ada-custom-app\";\nconst BRIDGE_ENTRY_PATH = \"bridge/bridge.js\";\nconst DEV_BUILD_MARKER = \"dev\";\n\n// Only canonical build identifiers may become part of an executable asset URL.\nconst PINNED_BUILD_SHA_PATTERN = /^[0-9a-f]{40}$/i;\n// Deliberately narrower than scripts/sdk.js parseVersionOverride (7-40 hex,\n// case-insensitive): deployed keys are always lowercase `pr-<N>`, and a short\n// SHA never names an uploaded tree, so the narrower grammar loses no reachable\n// build while keeping the executable-path grammar minimal.\nconst PR_BUILD_ALIAS_PATTERN = /^pr-\\d+$/;\n\n/** Why a {@link MessagingBridgeLoadError} was raised. */\nexport type MessagingBridgeLoadErrorCode =\n\t/** The `cdnBase` option violates the HTTPS or loopback HTTP policy. */\n\t| \"invalid_cdn_base\"\n\t/** The frame's `window.name` carries no core build marker. */\n\t| \"missing_build_sha\"\n\t/** The frame-name marker is not a supported bare build identifier. */\n\t| \"invalid_build_sha\"\n\t/** The `dev` marker was paired with a non-loopback CDN base. */\n\t| \"dev_marker_not_loopback\"\n\t/** The dynamic import of the CDN asset failed. */\n\t| \"bridge_import_failed\"\n\t/** The imported module does not expose the Ada bridge surface. */\n\t| \"bridge_module_invalid\";\n\n/** Typed failure raised by {@link loadMessagingBridge}. */\nexport class MessagingBridgeLoadError extends Error {\n\treadonly code: MessagingBridgeLoadErrorCode;\n\tdeclare readonly fallbackCause?: MessagingBridgeLoadError;\n\n\tconstructor(\n\t\tmessage: string,\n\t\tcode: MessagingBridgeLoadErrorCode,\n\t\tcause?: unknown,\n\t\tfallbackCause?: MessagingBridgeLoadError,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"MessagingBridgeLoadError\";\n\t\tthis.code = code;\n\t\tif (cause !== undefined) {\n\t\t\tthis.cause = cause;\n\t\t}\n\t\tif (fallbackCause !== undefined) {\n\t\t\tObject.defineProperty(this, \"fallbackCause\", {\n\t\t\t\tvalue: fallbackCause,\n\t\t\t\tenumerable: true,\n\t\t\t});\n\t\t}\n\t}\n}\n\n/** The module shape served by the SHA-matched bridge CDN asset. */\nexport interface MessagingBridgeModule {\n\tcreateBridgeClient: typeof createBridgeClient;\n\tSTATE: typeof STATE;\n\tmessageKey: typeof messageKey;\n\tisHistoricalRow: typeof isHistoricalRow;\n\tfindFirstUnread: typeof findFirstUnread;\n\tselectUnread: typeof selectUnread;\n\tgroupMessages: typeof groupMessages;\n\tfilterDisplayable: typeof filterDisplayable;\n\tresolveBotName: typeof resolveBotName;\n\t/**\n\t * Absent on a CDN build published before this helper existed. The npm\n\t * version does not choose the runtime, so guard before calling it.\n\t */\n\tresolveDisplayBotName?: typeof resolveDisplayBotName;\n\tisAgentTyping: typeof isAgentTyping;\n\tisConnectivityLost: typeof isConnectivityLost;\n}\n\ntype ImportBridgeModule = (url: string) => Promise<unknown>;\n\n/** Options for {@link loadMessagingBridge}. */\nexport interface LoadMessagingBridgeOptions {\n\t/**\n\t * Asset base for the bridge runtime. It must use HTTPS. Plain HTTP is\n\t * accepted only for loopback hosts. An explicit value, including\n\t * {@link FALLBACK_CDN_BASE}, disables the automatic static-root fallback.\n\t */\n\tcdnBase?: string;\n\t/** Import seam for unit tests. */\n\timportModule?: ImportBridgeModule;\n}\n\n// Both annotations are load-bearing. Customer bundlers must leave the\n// browser-resolved CDN URL untouched.\nconst defaultImportModule: ImportBridgeModule = (url) =>\n\timport(/* webpackIgnore: true */ /* @vite-ignore */ url);\n\ninterface BridgeLoaderState {\n\timports: Map<string, Promise<MessagingBridgeModule>>;\n\tdefaultLoads: Map<string, Promise<MessagingBridgeModule>>;\n}\n\nconst loadsByImporter = new WeakMap<ImportBridgeModule, BridgeLoaderState>();\n\n// Share the warning across independently bundled copies of this loader.\nconst FALLBACK_WARNING_KEY = Symbol.for(\"ada.messaging.bridge.fallbackWarning\");\nconst warningScope = globalThis as typeof globalThis & {\n\t[FALLBACK_WARNING_KEY]?: boolean;\n};\n\nconst LOOPBACK_HOSTS = new Set([\"localhost\", \"127.0.0.1\", \"[::1]\", \"::1\"]);\n\nfunction isLoopbackHostname(hostname: string): boolean {\n\tconst normalized = hostname.trim().toLowerCase();\n\treturn LOOPBACK_HOSTS.has(normalized) || normalized.endsWith(\".localhost\");\n}\n\nfunction trimTrailingSlashes(value: string): string {\n\tlet end = value.length;\n\twhile (end > 0 && value[end - 1] === \"/\") {\n\t\tend -= 1;\n\t}\n\treturn value.slice(0, end);\n}\n\ntype BridgeBuild =\n\t| { kind: \"sha\"; identifier: string }\n\t| { kind: \"alias\"; identifier: string }\n\t| { kind: \"dev\" };\n\nfunction bridgeFrameOnlyMessage(message: string): string {\n\treturn `${message} The bridge only runs inside an Ada-mounted custom-app frame.`;\n}\n\nconst FRAME_NAME_MARKER_PREFIX = `${CUSTOM_APP_FRAME_NAME}:`;\n\nfunction frameNameCarriesBuild(name: string): boolean {\n\treturn name.startsWith(FRAME_NAME_MARKER_PREFIX);\n}\n\n/**\n * Read the build marker core stamps into the frame's `window.name`\n * (`ada-custom-app:<marker>`). The name is Ada-owned for this frame, so the\n * marker never touches customer-owned URL state such as a hash route.\n */\nexport function resolveBridgeBuildFromFrameName(name: string): BridgeBuild {\n\tif (name === CUSTOM_APP_FRAME_NAME) {\n\t\tthrow new MessagingBridgeLoadError(\n\t\t\t\"The mounting Ada core predates build-marker delivery, so it cannot select a versioned bridge. The Ada core rollout must include the marker-stamping core before the npm bridge can load.\",\n\t\t\t\"missing_build_sha\",\n\t\t);\n\t}\n\tif (!frameNameCarriesBuild(name)) {\n\t\tthrow new MessagingBridgeLoadError(\n\t\t\t`${bridgeFrameOnlyMessage(\n\t\t\t\t\"This document was not mounted by an Ada core frame: window.name carries no ada-custom-app build marker.\",\n\t\t\t)} If this frame is Ada-mounted, make sure @ada-cx/messaging-bridge (or its /react entry) is imported from a module your page evaluates at startup — a lazily loaded chunk evaluates after customer code could overwrite window.name.`,\n\t\t\t\"missing_build_sha\",\n\t\t);\n\t}\n\tconst value = name.slice(FRAME_NAME_MARKER_PREFIX.length);\n\tif (value === DEV_BUILD_MARKER) {\n\t\treturn { kind: \"dev\" };\n\t}\n\tif (PR_BUILD_ALIAS_PATTERN.test(value)) {\n\t\treturn { kind: \"alias\", identifier: value };\n\t}\n\tif (!PINNED_BUILD_SHA_PATTERN.test(value)) {\n\t\tthrow new MessagingBridgeLoadError(\n\t\t\tbridgeFrameOnlyMessage(\n\t\t\t\t`The window.name build marker must be exactly a bare 40-character hex git SHA or a lowercase pr-<N> alias. URLs and paths are not allowed: \"${value}\".`,\n\t\t\t),\n\t\t\t\"invalid_build_sha\",\n\t\t);\n\t}\n\treturn { kind: \"sha\", identifier: value.toLowerCase() };\n}\n\n// Latch window.name at module evaluation: core stamps the marker on the\n// frame element before the document loads, and customer code — for example a\n// library that uses window.name as a storage channel — could overwrite it\n// after boot. The latch therefore only holds when this package is imported\n// from the page's entry module rather than a lazily loaded chunk — the\n// boundary README_NPM.md documents and the snapshot tests in loader.test.ts\n// pin.\nconst initialFrameName = typeof window === \"undefined\" ? \"\" : window.name;\nconst initialFrameNameHasBuild = frameNameCarriesBuild(initialFrameName);\n\nfunction currentFrameName(): string {\n\tif (initialFrameNameHasBuild) {\n\t\treturn initialFrameName;\n\t}\n\treturn typeof window === \"undefined\" ? \"\" : window.name;\n}\n\nfunction resolveCdnBase(cdnBase: string | undefined): {\n\tbase: string;\n\thostname: string;\n} {\n\tconst base = trimTrailingSlashes((cdnBase ?? DEFAULT_CDN_BASE).trim());\n\tlet url: URL;\n\ttry {\n\t\turl = new URL(base);\n\t} catch (cause) {\n\t\tthrow new MessagingBridgeLoadError(\n\t\t\t`The cdnBase option is not a valid URL: \"${base}\".`,\n\t\t\t\"invalid_cdn_base\",\n\t\t\tcause,\n\t\t);\n\t}\n\tconst isHttps = url.protocol === \"https:\";\n\tconst isLoopbackHttp =\n\t\turl.protocol === \"http:\" && isLoopbackHostname(url.hostname);\n\tif (!isHttps && !isLoopbackHttp) {\n\t\tthrow new MessagingBridgeLoadError(\n\t\t\t`The cdnBase option must use https (plain http is allowed only for loopback hosts): \"${base}\".`,\n\t\t\t\"invalid_cdn_base\",\n\t\t);\n\t}\n\treturn { base, hostname: url.hostname };\n}\n\n/**\n * Resolve the bridge asset URL from this frame's name marker and the CDN\n * base. Production builds always resolve the immutable SHA-rooted asset.\n * PR aliases stay under the configured CDN base. A production-base alias that\n * does not exist fails closed through the normal bridge import error.\n * Local development resolves `/bridge/bridge.js` only on a loopback base.\n * This reports the configured root only, not the root a fallback load used.\n */\nexport function resolveBridgeCdnUrl(\n\toptions?: Pick<LoadMessagingBridgeOptions, \"cdnBase\">,\n): string {\n\tconst build = resolveBridgeBuildFromFrameName(currentFrameName());\n\tconst { base, hostname } = resolveCdnBase(options?.cdnBase);\n\tif (build.kind === \"dev\" && !isLoopbackHostname(hostname)) {\n\t\tthrow new MessagingBridgeLoadError(\n\t\t\tbridgeFrameOnlyMessage(\n\t\t\t\t`The ${FRAME_NAME_MARKER_PREFIX}${DEV_BUILD_MARKER} frame-name marker requires a loopback cdnBase.`,\n\t\t\t),\n\t\t\t\"dev_marker_not_loopback\",\n\t\t);\n\t}\n\tconst assetPath =\n\t\tbuild.kind === \"dev\"\n\t\t\t? `/${BRIDGE_ENTRY_PATH}`\n\t\t\t: `/${build.identifier}/${BRIDGE_ENTRY_PATH}`;\n\treturn new URL(`${base}${assetPath}`).toString();\n}\n\n// A partial CDN module (mid-deploy, or a rolled-back build missing a newer\n// export) must fail here as a typed bridge_module_invalid error, not later as\n// a TypeError on the first missing call — so every export is checked. The\n// `satisfies` clause rejects names that are not interface members; the\n// exhaustiveness type below is what forces this list to grow with it.\n//\n// This list is the set published with 1.0.0, and adding to it is a breaking\n// change even though adding an export is not. A page's runtime build comes from\n// the core frame's `window.name`, never from the installed npm version, so a\n// 1.x consumer legitimately resolves an older bridge — during a rollout, behind\n// an `?ada-messaging-version` pin, or after a CDN revert. Requiring a newer\n// export would turn every one of those into \"no bridge at all\" for a customer\n// who never calls it. Declare a helper added after 1.0.0 optional on\n// `MessagingBridgeModule` and exempt it below instead.\nconst REQUIRED_BRIDGE_FUNCTION_EXPORTS = [\n\t\"createBridgeClient\",\n\t\"messageKey\",\n\t\"isHistoricalRow\",\n\t\"findFirstUnread\",\n\t\"selectUnread\",\n\t\"groupMessages\",\n\t\"filterDisplayable\",\n\t\"resolveBotName\",\n\t\"isAgentTyping\",\n\t\"isConnectivityLost\",\n] as const satisfies readonly (keyof MessagingBridgeModule)[];\n\ntype MissingRequiredBridgeExport = Exclude<\n\tkeyof MessagingBridgeModule,\n\t| (typeof REQUIRED_BRIDGE_FUNCTION_EXPORTS)[number]\n\t| \"STATE\"\n\t// Optional by design: added after 1.0.0, so an older runtime will not have\n\t// it. Callers get `undefined` and degrade; they do not lose the bridge.\n\t| \"resolveDisplayBotName\"\n>;\n// Compile-time exhaustiveness: adding a MessagingBridgeModule member without\n// listing it in REQUIRED_BRIDGE_FUNCTION_EXPORTS (or checking it explicitly,\n// like STATE) makes the Exclude non-`never`, so the `true` assignment below\n// stops compiling.\ntype AllBridgeExportsListed = MissingRequiredBridgeExport extends never\n\t? true\n\t: never;\nconst _allBridgeExportsListed: AllBridgeExportsListed = true;\nvoid _allBridgeExportsListed;\n\nfunction isMessagingBridgeModule(\n\tvalue: unknown,\n): value is MessagingBridgeModule {\n\tif (typeof value !== \"object\" || value === null) {\n\t\treturn false;\n\t}\n\tconst candidate = value as Record<string, unknown>;\n\t// STATE is a constant object, not a function, so it gets a presence check.\n\treturn (\n\t\tcandidate.STATE != null &&\n\t\tREQUIRED_BRIDGE_FUNCTION_EXPORTS.every(\n\t\t\t(key) => typeof candidate[key] === \"function\",\n\t\t)\n\t);\n}\n\n// A rejection can be any value, including one that throws on String(); a\n// diagnostic must never turn a successful fallback into a rejected load.\nfunction describeRejection(cause: unknown): string {\n\ttry {\n\t\treturn cause instanceof Error\n\t\t\t? `${cause.name}: ${cause.message}`\n\t\t\t: String(cause);\n\t} catch {\n\t\treturn \"unknown error\";\n\t}\n}\n\nasync function importBridgeModule(\n\turl: string,\n\timportModule: ImportBridgeModule,\n): Promise<MessagingBridgeModule> {\n\tlet loaded: unknown;\n\ttry {\n\t\tloaded = await importModule(url);\n\t} catch (cause) {\n\t\tthrow new MessagingBridgeLoadError(\n\t\t\t`The Ada bridge runtime failed to load from ${url}.`,\n\t\t\t\"bridge_import_failed\",\n\t\t\tcause,\n\t\t);\n\t}\n\tif (!isMessagingBridgeModule(loaded)) {\n\t\tthrow new MessagingBridgeLoadError(\n\t\t\t`The module at ${url} does not expose the full Ada bridge surface; it is not a complete Ada bridge build.`,\n\t\t\t\"bridge_module_invalid\",\n\t\t);\n\t}\n\treturn loaded;\n}\n\nfunction memoizeLoad(\n\tcache: Map<string, Promise<MessagingBridgeModule>>,\n\turl: string,\n\tload: () => Promise<MessagingBridgeModule>,\n): Promise<MessagingBridgeModule> {\n\tconst existing = cache.get(url);\n\tif (existing) {\n\t\treturn existing;\n\t}\n\tconst pending = load();\n\tcache.set(url, pending);\n\tpending.catch(() => {\n\t\tif (cache.get(url) === pending) {\n\t\t\tcache.delete(url);\n\t\t}\n\t});\n\treturn pending;\n}\n\n/**\n * Load the bridge runtime that matches the mounting core frame. Loads are\n * memoized per resolved URL and importer. A failed load is evicted for retry.\n * Without `cdnBase`, an import failure at the default root is retried once\n * from {@link FALLBACK_CDN_BASE}.\n */\nexport function loadMessagingBridge(\n\toptions: LoadMessagingBridgeOptions = {},\n): Promise<MessagingBridgeModule> {\n\tconst importModule = options.importModule ?? defaultImportModule;\n\tlet url: string;\n\tlet fallbackUrl: string | undefined;\n\ttry {\n\t\turl = resolveBridgeCdnUrl(options);\n\t\tif (options.cdnBase === undefined) {\n\t\t\tfallbackUrl = resolveBridgeCdnUrl({ cdnBase: FALLBACK_CDN_BASE });\n\t\t}\n\t} catch (error) {\n\t\treturn Promise.reject(error);\n\t}\n\n\tconst state = loadsByImporter.get(importModule) ?? {\n\t\timports: new Map<string, Promise<MessagingBridgeModule>>(),\n\t\tdefaultLoads: new Map<string, Promise<MessagingBridgeModule>>(),\n\t};\n\tloadsByImporter.set(importModule, state);\n\tconst load = (entryUrl: string) =>\n\t\tmemoizeLoad(state.imports, entryUrl, () =>\n\t\t\timportBridgeModule(entryUrl, importModule),\n\t\t);\n\tif (fallbackUrl === undefined) {\n\t\treturn load(url);\n\t}\n\n\tconst retryUrl = fallbackUrl;\n\treturn memoizeLoad(state.defaultLoads, url, () =>\n\t\tload(url).catch(async (error: unknown) => {\n\t\t\tif (\n\t\t\t\t!(error instanceof MessagingBridgeLoadError) ||\n\t\t\t\terror.code !== \"bridge_import_failed\"\n\t\t\t) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tlet module: MessagingBridgeModule;\n\t\t\ttry {\n\t\t\t\tmodule = await load(retryUrl);\n\t\t\t} catch (cause) {\n\t\t\t\tif (!(cause instanceof MessagingBridgeLoadError)) {\n\t\t\t\t\tthrow cause;\n\t\t\t\t}\n\t\t\t\tthrow new MessagingBridgeLoadError(\n\t\t\t\t\tcause.code === \"bridge_import_failed\"\n\t\t\t\t\t\t? `The Ada bridge runtime failed to load from both ${url} and ${retryUrl}.`\n\t\t\t\t\t\t: cause.message,\n\t\t\t\t\tcause.code,\n\t\t\t\t\terror,\n\t\t\t\t\tcause,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (!warningScope[FALLBACK_WARNING_KEY]) {\n\t\t\t\twarningScope[FALLBACK_WARNING_KEY] = true;\n\t\t\t\tconst cause = error.cause;\n\t\t\t\ttry {\n\t\t\t\t\t// Browsers reject blocked, unreachable, or missing imports with TypeError.\n\t\t\t\t\t// An evaluation-time TypeError still looks like a fetch failure, as before;\n\t\t\t\t\t// this heuristic narrows diagnostic noise but cannot prove the cause.\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\tcause instanceof TypeError\n\t\t\t\t\t\t\t? `[Ada] Loaded the Messaging bridge from ${FALLBACK_CDN_BASE} because the default root ${DEFAULT_CDN_BASE}/ was blocked or unavailable. Add ${DEFAULT_CDN_BASE} to script-src, connect-src and frame-src, or pass cdnBase: \"${FALLBACK_CDN_BASE}\".`\n\t\t\t\t\t\t\t: `[Ada] Loaded the Messaging bridge from ${FALLBACK_CDN_BASE} because the module at ${url} failed to evaluate (${describeRejection(cause)}). This is an Ada-side problem, not your host's CSP. Report it to Ada.`,\n\t\t\t\t\t\tcause,\n\t\t\t\t\t);\n\t\t\t\t} catch {\n\t\t\t\t\t// A host may replace console methods; diagnostics must not throw.\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn module;\n\t\t}),\n\t);\n}\n"],"mappings":"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"}
@@ -13,4 +13,4 @@ export type { BridgeClientDestroyedError, BridgeOperations, BridgeOperationsHost
13
13
  export type { StateKey } from "../contract/state-keys.js";
14
14
  export type { AppDisplayState, AppEvents, CaptureData, CsatMessage, CsatScaleType, DownloadableMessage, FallbackUiConfig, LinkMessage, ListSelectionData, LiveChatStateData, Message, NotificationPermissionMessage, OptionItem, OptionsMessage, PictureMessage, PresenceMessage, QueueBotBlockMessage, QuickRepliesMessage, QuickReply, SdkPlatform, SeamlessOAuthMessage, SelectableListItem, SelectableListMessage, SignInMessage, StagedAttachment, StagedAttachmentRejection, TextMessage, VideoMessage, WidgetMessage, } from "../contract/types.js";
15
15
  export type { LoadMessagingBridgeOptions, MessagingBridgeLoadErrorCode, MessagingBridgeModule, } from "./loader.js";
16
- export { loadMessagingBridge, MessagingBridgeLoadError, resolveBridgeCdnUrl, } from "./loader.js";
16
+ export { FALLBACK_CDN_BASE, loadMessagingBridge, MessagingBridgeLoadError, resolveBridgeCdnUrl, } from "./loader.js";
@@ -1,2 +1,2 @@
1
- import { n as loadMessagingBridge, r as resolveBridgeCdnUrl, t as MessagingBridgeLoadError } from "../loader-CfCnvaTU.js";
2
- export { MessagingBridgeLoadError, loadMessagingBridge, resolveBridgeCdnUrl };
1
+ import { i as resolveBridgeCdnUrl, n as MessagingBridgeLoadError, r as loadMessagingBridge, t as FALLBACK_CDN_BASE } from "../loader-BjjKuT42.js";
2
+ export { FALLBACK_CDN_BASE, MessagingBridgeLoadError, loadMessagingBridge, resolveBridgeCdnUrl };
@@ -1,6 +1,7 @@
1
1
  import type { createBridgeClient } from "../contract/bridge-client.js";
2
2
  import type { filterDisplayable, findFirstUnread, groupMessages, isAgentTyping, isConnectivityLost, isHistoricalRow, messageKey, resolveBotName, resolveDisplayBotName, selectUnread } from "../contract/derive.js";
3
3
  import type { STATE } from "../contract/state-keys.js";
4
+ export declare const FALLBACK_CDN_BASE = "https://static.ada.support/messaging/";
4
5
  /** Why a {@link MessagingBridgeLoadError} was raised. */
5
6
  export type MessagingBridgeLoadErrorCode =
6
7
  /** The `cdnBase` option violates the HTTPS or loopback HTTP policy. */
@@ -18,7 +19,8 @@ export type MessagingBridgeLoadErrorCode =
18
19
  /** Typed failure raised by {@link loadMessagingBridge}. */
19
20
  export declare class MessagingBridgeLoadError extends Error {
20
21
  readonly code: MessagingBridgeLoadErrorCode;
21
- constructor(message: string, code: MessagingBridgeLoadErrorCode, cause?: unknown);
22
+ readonly fallbackCause?: MessagingBridgeLoadError;
23
+ constructor(message: string, code: MessagingBridgeLoadErrorCode, cause?: unknown, fallbackCause?: MessagingBridgeLoadError);
22
24
  }
23
25
  /** The module shape served by the SHA-matched bridge CDN asset. */
24
26
  export interface MessagingBridgeModule {
@@ -43,8 +45,9 @@ type ImportBridgeModule = (url: string) => Promise<unknown>;
43
45
  /** Options for {@link loadMessagingBridge}. */
44
46
  export interface LoadMessagingBridgeOptions {
45
47
  /**
46
- * Asset base for staged validation. It must use HTTPS. Plain HTTP is
47
- * accepted only for loopback hosts.
48
+ * Asset base for the bridge runtime. It must use HTTPS. Plain HTTP is
49
+ * accepted only for loopback hosts. An explicit value, including
50
+ * {@link FALLBACK_CDN_BASE}, disables the automatic static-root fallback.
48
51
  */
49
52
  cdnBase?: string;
50
53
  /** Import seam for unit tests. */
@@ -71,11 +74,14 @@ export declare function resolveBridgeBuildFromFrameName(name: string): BridgeBui
71
74
  * PR aliases stay under the configured CDN base. A production-base alias that
72
75
  * does not exist fails closed through the normal bridge import error.
73
76
  * Local development resolves `/bridge/bridge.js` only on a loopback base.
77
+ * This reports the configured root only, not the root a fallback load used.
74
78
  */
75
79
  export declare function resolveBridgeCdnUrl(options?: Pick<LoadMessagingBridgeOptions, "cdnBase">): string;
76
80
  /**
77
81
  * Load the bridge runtime that matches the mounting core frame. Loads are
78
82
  * memoized per resolved URL and importer. A failed load is evicted for retry.
83
+ * Without `cdnBase`, an import failure at the default root is retried once
84
+ * from {@link FALLBACK_CDN_BASE}.
79
85
  */
80
86
  export declare function loadMessagingBridge(options?: LoadMessagingBridgeOptions): Promise<MessagingBridgeModule>;
81
87
  export {};
@@ -10,4 +10,4 @@ export type { AppDisplayState, AppEvents } from "../contract/types.js";
10
10
  export type { LoadedBridgeProviderProps } from "./bridge-react.js";
11
11
  export { BridgeProvider, createBridgeProvider, useBridgeClient, useBridgeState, useBridgeStateKey, } from "./bridge-react.js";
12
12
  export type { LoadMessagingBridgeOptions, MessagingBridgeLoadErrorCode, MessagingBridgeModule, } from "./loader.js";
13
- export { loadMessagingBridge, MessagingBridgeLoadError, resolveBridgeCdnUrl, } from "./loader.js";
13
+ export { FALLBACK_CDN_BASE, loadMessagingBridge, MessagingBridgeLoadError, resolveBridgeCdnUrl, } from "./loader.js";
@@ -1,4 +1,4 @@
1
- import { n as loadMessagingBridge, r as resolveBridgeCdnUrl, t as MessagingBridgeLoadError } from "../loader-CfCnvaTU.js";
1
+ import { i as resolveBridgeCdnUrl, n as MessagingBridgeLoadError, r as loadMessagingBridge, t as FALLBACK_CDN_BASE } from "../loader-BjjKuT42.js";
2
2
  import { createContext, useCallback, useContext, useEffect, useRef, useState, useSyncExternalStore } from "react";
3
3
  import { Fragment, jsx } from "react/jsx-runtime";
4
4
  //#region src/npm/bridge-react.tsx
@@ -108,6 +108,6 @@ function createBridgeProvider(load = loadMessagingBridge) {
108
108
  };
109
109
  }
110
110
  //#endregion
111
- export { BridgeProvider, MessagingBridgeLoadError, createBridgeProvider, loadMessagingBridge, resolveBridgeCdnUrl, useBridgeClient, useBridgeState, useBridgeStateKey };
111
+ export { BridgeProvider, FALLBACK_CDN_BASE, MessagingBridgeLoadError, createBridgeProvider, loadMessagingBridge, resolveBridgeCdnUrl, useBridgeClient, useBridgeState, useBridgeStateKey };
112
112
 
113
113
  //# sourceMappingURL=react.js.map