@ada-cx/messaging-sdk 1.4.0 → 1.6.1

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.
@@ -1,157 +1,3 @@
1
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- //#region src/npm/testing.ts
3
- var EXACT_MATCH_EVENT_KEYS = new Set(["ada:message:sent", "ada:message:received"]);
4
- function keyedSubscriptionMatches(subscriptionKey, eventKey) {
5
- if (EXACT_MATCH_EVENT_KEYS.has(eventKey)) return subscriptionKey === eventKey;
6
- return subscriptionKey === eventKey || eventKey.startsWith(subscriptionKey);
7
- }
8
- function toMetaFieldRecord(fields) {
9
- const record = {};
10
- for (const [key, value] of Object.entries(fields)) if (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === null) record[key] = value;
11
- return record;
12
- }
13
- /**
14
- * Create an in-memory messaging-interface stand-in for unit-testing an
15
- * integration without loading the SDK from the CDN.
16
- *
17
- * Every method resolves, records itself in `calls`, and keeps just enough
18
- * state to behave like the real interface: `sendMessage` appends a
19
- * programmatic user message that `getMessages` returns, `open`/`close`/
20
- * `toggle` drive `isOpen` and `getInfo`, `setMetaFields` feeds
21
- * `getMetaFields` (sensitive fields are never returned, matching the real
22
- * SDK), and `$emit` fans out to `subscribeEvent`/`subscribeAll` callbacks.
23
- *
24
- * Pass `overrides` to replace any method (e.g. with `vi.fn()`); overridden
25
- * methods are still recorded in `calls`.
26
- */
27
- function createMockAdaMessaging(overrides = {}) {
28
- const calls = [];
29
- let nextSubscriptionId = 1;
30
- let nextMessageId = 1;
31
- let chatOpen = false;
32
- let conversationId = null;
33
- const metaFields = {};
34
- const messages = [];
35
- const keyedSubscriptions = /* @__PURE__ */ new Map();
36
- const wildcardSubscriptions = /* @__PURE__ */ new Map();
37
- const emit = (key, data) => {
38
- for (const subscription of keyedSubscriptions.values()) if (keyedSubscriptionMatches(subscription.key, key)) subscription.callback(data, { eventKey: key });
39
- if (EXACT_MATCH_EVENT_KEYS.has(key)) return;
40
- for (const callback of wildcardSubscriptions.values()) callback(key, data);
41
- };
42
- const clearTranscript = () => {
43
- messages.length = 0;
44
- conversationId = null;
45
- };
46
- const base = {
47
- start: async () => void 0,
48
- stop: async () => void 0,
49
- toggle: async () => {
50
- chatOpen = !chatOpen;
51
- },
52
- deleteHistory: async () => {
53
- clearTranscript();
54
- },
55
- reset: async () => {
56
- clearTranscript();
57
- },
58
- setMetaFields: async (fields) => {
59
- Object.assign(metaFields, toMetaFieldRecord(fields));
60
- },
61
- setSensitiveMetaFields: async () => void 0,
62
- setTestModeBanner: async () => void 0,
63
- getInfo: async () => ({
64
- isChatOpen: chatOpen,
65
- isDrawerOpen: chatOpen,
66
- hasActiveChatter: messages.length > 0,
67
- hasClosedChat: false
68
- }),
69
- getMetaFields: async () => ({ ...metaFields }),
70
- isOpen: async () => chatOpen,
71
- getConversation: async () => ({
72
- id: conversationId,
73
- handoff: { inLiveChat: false }
74
- }),
75
- getMessages: async () => [...messages],
76
- setComposerText: async () => void 0,
77
- setDelegate: () => void 0,
78
- trackEvent: async () => void 0,
79
- subscribeEvent: async (key, callback) => {
80
- const id = nextSubscriptionId++;
81
- keyedSubscriptions.set(id, {
82
- key,
83
- callback
84
- });
85
- return id;
86
- },
87
- unsubscribeEvent: async (id) => {
88
- keyedSubscriptions.delete(id);
89
- wildcardSubscriptions.delete(id);
90
- },
91
- subscribeAll: async (callback) => {
92
- const id = nextSubscriptionId++;
93
- wildcardSubscriptions.set(id, callback);
94
- return id;
95
- },
96
- open: async () => {
97
- chatOpen = true;
98
- },
99
- close: async () => {
100
- chatOpen = false;
101
- },
102
- setLanguage: async () => void 0,
103
- setTheme: async () => void 0,
104
- setDeviceToken: async () => void 0,
105
- acknowledgeSessionMirrorClear: async () => void 0,
106
- deliverSessionMirrorSeed: async () => void 0,
107
- sendMessage: async (body) => {
108
- const id = `mock-message-${nextMessageId++}`;
109
- conversationId = conversationId ?? "mock-conversation";
110
- messages.push({
111
- id,
112
- role: "user",
113
- type: "text",
114
- body,
115
- createdAt: Math.floor(Date.now() / 1e3),
116
- origin: "programmatic"
117
- });
118
- return { id };
119
- },
120
- handleNotification: async () => {
121
- chatOpen = true;
122
- },
123
- requestNotifications: async () => "granted",
124
- createProactive: async () => void 0,
125
- triggerCampaign: async () => void 0,
126
- evaluateCampaignConditions: async () => void 0,
127
- closeCampaign: async () => void 0,
128
- triggerAnswer: async () => void 0,
129
- triggerProactive: async () => void 0,
130
- triggerGreeting: async () => void 0,
131
- destroy: async () => {
132
- keyedSubscriptions.clear();
133
- wildcardSubscriptions.clear();
134
- chatOpen = false;
135
- }
136
- };
137
- const definedOverrides = Object.fromEntries(Object.entries(overrides).filter(([, value]) => value !== void 0));
138
- const implementation = {
139
- ...base,
140
- ...definedOverrides
141
- };
142
- return {
143
- ...Object.fromEntries(Object.entries(implementation).map(([method, fn]) => [method, (...args) => {
144
- calls.push({
145
- method,
146
- args
147
- });
148
- return fn(...args);
149
- }])),
150
- calls,
151
- $emit: emit
152
- };
153
- }
154
- //#endregion
155
- exports.createMockAdaMessaging = createMockAdaMessaging;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var M=Object.prototype.hasOwnProperty;function g(n,e,a){Object.defineProperty(n,e,{value:a,configurable:!0,writable:!0})}Object.hasOwn||g(Object,"hasOwn",(n,e)=>{if(n==null)throw new TypeError("ada browser-polyfills: Cannot convert undefined or null to object");return M.call(Object(n),e)});function p(n){const e=Math.trunc(Number(this.length))||0;let a=Math.trunc(Number(n))||0;return a<0&&(a+=e),a<0||a>=e?void 0:this[a]}function T(n){const e=String(this),a=e.length;let r=Math.trunc(Number(n))||0;return r<0&&(r+=a),r<0||r>=a?void 0:e.charAt(r)}var O=[globalThis.Int8Array,globalThis.Uint8Array,globalThis.Uint8ClampedArray,globalThis.Int16Array,globalThis.Uint16Array,globalThis.Int32Array,globalThis.Uint32Array,globalThis.Float32Array,globalThis.Float64Array,globalThis.BigInt64Array,globalThis.BigUint64Array].filter(Boolean);Array.prototype.at||g(Array.prototype,"at",p);String.prototype.at||g(String.prototype,"at",T);for(const n of O){const e=n.prototype;e.at||g(e,"at",p)}var v=new Set(["ada:message:sent","ada:message:received"]);function C(n,e){return v.has(e)?n===e:n===e||e.startsWith(n)}function w(n){const e={};for(const[a,r]of Object.entries(n))(typeof r=="string"||typeof r=="number"||typeof r=="boolean"||r===null)&&(e[a]=r);return e}function S(n={}){const e=[];let a=1,r=1,i=!1,c=null;const u={},l=[],d=new Map,y=new Map,b=(t,s)=>{for(const o of d.values())C(o.key,t)&&o.callback(s,{eventKey:t});if(!v.has(t))for(const o of y.values())o(t,s)},f=()=>{l.length=0,c=null},h={start:async()=>{},stop:async()=>{},toggle:async()=>{i=!i},deleteHistory:async()=>{f()},reset:async()=>{f()},setMetaFields:async t=>{Object.assign(u,w(t))},setSensitiveMetaFields:async()=>{},setTestModeBanner:async()=>{},getInfo:async()=>({isChatOpen:i,isDrawerOpen:i,hasActiveChatter:l.length>0,hasClosedChat:!1}),getMetaFields:async()=>({...u}),isOpen:async()=>i,getConversation:async()=>({id:c,handoff:{inLiveChat:!1}}),getMessages:async()=>[...l],setComposerText:async()=>{},setDelegate:()=>{},trackEvent:async()=>{},subscribeEvent:async(t,s)=>{const o=a++;return d.set(o,{key:t,callback:s}),o},unsubscribeEvent:async t=>{d.delete(t),y.delete(t)},subscribeAll:async t=>{const s=a++;return y.set(s,t),s},open:async()=>{i=!0},close:async()=>{i=!1},setLanguage:async()=>{},setTheme:async()=>{},setDeviceToken:async()=>{},acknowledgeSessionMirrorClear:async()=>{},deliverSessionMirrorSeed:async()=>{},sendMessage:async t=>{const s=`mock-message-${r++}`;return c=c??"mock-conversation",l.push({id:s,role:"user",type:"text",body:t,createdAt:Math.floor(Date.now()/1e3),origin:"programmatic"}),{id:s}},handleNotification:async()=>{i=!0},requestNotifications:async()=>"granted",createProactive:async()=>{},triggerCampaign:async()=>{},evaluateCampaignConditions:async()=>{},closeCampaign:async()=>{},triggerAnswer:async()=>{},triggerProactive:async()=>{},triggerGreeting:async()=>{},destroy:async()=>{d.clear(),y.clear(),i=!1}},m=Object.fromEntries(Object.entries(n).filter(([,t])=>t!==void 0)),A={...h,...m};return{...Object.fromEntries(Object.entries(A).map(([t,s])=>[t,(...o)=>(e.push({method:t,args:o}),s(...o))])),calls:e,$emit:b}}exports.createMockAdaMessaging=S;
156
2
 
157
3
  //# sourceMappingURL=testing.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"testing.cjs","names":[],"sources":["../../src/npm/testing.ts"],"sourcesContent":["import type {\n\tAdaSdkEventCallback,\n\tMetaFieldValue,\n\tPublicMessage,\n} from \"../client/client-types\";\nimport type { AdaMessagingInterface } from \"./loader\";\n\n/** One recorded method invocation on a {@link MockAdaMessaging}. */\nexport interface RecordedAdaMessagingCall {\n\tmethod: string;\n\targs: unknown[];\n}\n\n/**\n * The mock returned by {@link createMockAdaMessaging}: the full\n * {@link AdaMessagingInterface} plus test hooks for inspecting calls and\n * simulating SDK events.\n */\nexport interface MockAdaMessaging extends AdaMessagingInterface {\n\t/** Every method invocation, in call order. */\n\tcalls: RecordedAdaMessagingCall[];\n\t/**\n\t * Deliver an event to `subscribeEvent` and `subscribeAll` callbacks, as if\n\t * the SDK emitted it (e.g. `$emit(\"ada:ready\", { isRolledOut: true })`).\n\t * Routing matches the real SDK: keyed subscriptions match by prefix\n\t * (`\"ada:campaigns\"` catches `\"ada:campaigns:shown\"`), except the\n\t * transcript events `ada:message:sent`/`ada:message:received`, which reach\n\t * exact-key subscribers only and never `subscribeAll`.\n\t */\n\t$emit: (key: string, data?: unknown) => void;\n}\n\ninterface KeyedSubscription {\n\tkey: string;\n\tcallback: AdaSdkEventCallback;\n}\n\n// Mirrors EXACT_MATCH_EVENT_KEYS in client/client-host-runtime.ts: transcript\n// events reach exact-key subscribers only, never prefix or subscribeAll\n// subscribers. Duplicated (not imported) so the published testing entry stays\n// free of runtime modules; a drift test pins the mock against the real matcher.\nconst EXACT_MATCH_EVENT_KEYS = new Set([\n\t\"ada:message:sent\",\n\t\"ada:message:received\",\n]);\n\nfunction keyedSubscriptionMatches(\n\tsubscriptionKey: string,\n\teventKey: string,\n): boolean {\n\tif (EXACT_MATCH_EVENT_KEYS.has(eventKey)) {\n\t\treturn subscriptionKey === eventKey;\n\t}\n\t// Raw prefix match, same as the real SDK: \"ada:campaigns\" also catches\n\t// \"ada:campaigns:shown\" and underscore-suffixed keys.\n\treturn subscriptionKey === eventKey || eventKey.startsWith(subscriptionKey);\n}\n\nfunction toMetaFieldRecord(\n\tfields: Record<string, unknown>,\n): Record<string, MetaFieldValue> {\n\tconst record: Record<string, MetaFieldValue> = {};\n\tfor (const [key, value] of Object.entries(fields)) {\n\t\tif (\n\t\t\ttypeof value === \"string\" ||\n\t\t\ttypeof value === \"number\" ||\n\t\t\ttypeof value === \"boolean\" ||\n\t\t\tvalue === null\n\t\t) {\n\t\t\trecord[key] = value;\n\t\t}\n\t}\n\treturn record;\n}\n\n/**\n * Create an in-memory messaging-interface stand-in for unit-testing an\n * integration without loading the SDK from the CDN.\n *\n * Every method resolves, records itself in `calls`, and keeps just enough\n * state to behave like the real interface: `sendMessage` appends a\n * programmatic user message that `getMessages` returns, `open`/`close`/\n * `toggle` drive `isOpen` and `getInfo`, `setMetaFields` feeds\n * `getMetaFields` (sensitive fields are never returned, matching the real\n * SDK), and `$emit` fans out to `subscribeEvent`/`subscribeAll` callbacks.\n *\n * Pass `overrides` to replace any method (e.g. with `vi.fn()`); overridden\n * methods are still recorded in `calls`.\n */\nexport function createMockAdaMessaging(\n\toverrides: Partial<AdaMessagingInterface> = {},\n): MockAdaMessaging {\n\tconst calls: RecordedAdaMessagingCall[] = [];\n\tlet nextSubscriptionId = 1;\n\tlet nextMessageId = 1;\n\tlet chatOpen = false;\n\tlet conversationId: string | null = null;\n\tconst metaFields: Record<string, MetaFieldValue> = {};\n\tconst messages: PublicMessage[] = [];\n\tconst keyedSubscriptions = new Map<number, KeyedSubscription>();\n\tconst wildcardSubscriptions = new Map<\n\t\tnumber,\n\t\t(key: string, data: unknown) => void\n\t>();\n\n\tconst emit = (key: string, data?: unknown): void => {\n\t\tfor (const subscription of keyedSubscriptions.values()) {\n\t\t\tif (keyedSubscriptionMatches(subscription.key, key)) {\n\t\t\t\tsubscription.callback(data, { eventKey: key });\n\t\t\t}\n\t\t}\n\t\tif (EXACT_MATCH_EVENT_KEYS.has(key)) {\n\t\t\treturn;\n\t\t}\n\t\tfor (const callback of wildcardSubscriptions.values()) {\n\t\t\tcallback(key, data);\n\t\t}\n\t};\n\n\tconst clearTranscript = (): void => {\n\t\tmessages.length = 0;\n\t\tconversationId = null;\n\t};\n\n\tconst base: AdaMessagingInterface = {\n\t\tstart: async () => undefined,\n\t\tstop: async () => undefined,\n\t\ttoggle: async () => {\n\t\t\tchatOpen = !chatOpen;\n\t\t},\n\t\tdeleteHistory: async () => {\n\t\t\tclearTranscript();\n\t\t},\n\t\treset: async () => {\n\t\t\tclearTranscript();\n\t\t},\n\t\tsetMetaFields: async (fields) => {\n\t\t\tObject.assign(metaFields, toMetaFieldRecord(fields));\n\t\t},\n\t\t// Sensitive fields are accepted but never readable back, matching the\n\t\t// real SDK's getMetaFields contract.\n\t\tsetSensitiveMetaFields: async () => undefined,\n\t\tsetTestModeBanner: async () => undefined,\n\t\tgetInfo: async () => ({\n\t\t\tisChatOpen: chatOpen,\n\t\t\tisDrawerOpen: chatOpen,\n\t\t\thasActiveChatter: messages.length > 0,\n\t\t\thasClosedChat: false,\n\t\t}),\n\t\tgetMetaFields: async () => ({ ...metaFields }),\n\t\tisOpen: async () => chatOpen,\n\t\tgetConversation: async () => ({\n\t\t\tid: conversationId,\n\t\t\thandoff: { inLiveChat: false },\n\t\t}),\n\t\tgetMessages: async () => [...messages],\n\t\tsetComposerText: async () => undefined,\n\t\tsetDelegate: () => undefined,\n\t\ttrackEvent: async () => undefined,\n\t\tsubscribeEvent: async (key, callback) => {\n\t\t\tconst id = nextSubscriptionId++;\n\t\t\tkeyedSubscriptions.set(id, { key, callback });\n\t\t\treturn id;\n\t\t},\n\t\tunsubscribeEvent: async (id) => {\n\t\t\tkeyedSubscriptions.delete(id);\n\t\t\twildcardSubscriptions.delete(id);\n\t\t},\n\t\tsubscribeAll: async (callback) => {\n\t\t\tconst id = nextSubscriptionId++;\n\t\t\twildcardSubscriptions.set(id, callback);\n\t\t\treturn id;\n\t\t},\n\t\topen: async () => {\n\t\t\tchatOpen = true;\n\t\t},\n\t\tclose: async () => {\n\t\t\tchatOpen = false;\n\t\t},\n\t\tsetLanguage: async () => undefined,\n\t\tsetTheme: async () => undefined,\n\t\tsetDeviceToken: async () => undefined,\n\t\t// Optional on AdaEmbedInterface (internal mobile-webview plumbing), but\n\t\t// Ada's own maintained test double still implements the full surface — the\n\t\t// types-drift guard requires the shipped mock to cover every interface\n\t\t// member so a customer's double never lags it.\n\t\tacknowledgeSessionMirrorClear: async () => undefined,\n\t\tdeliverSessionMirrorSeed: async () => undefined,\n\t\tsendMessage: async (body) => {\n\t\t\tconst id = `mock-message-${nextMessageId++}`;\n\t\t\tconversationId = conversationId ?? \"mock-conversation\";\n\t\t\tmessages.push({\n\t\t\t\tid,\n\t\t\t\trole: \"user\",\n\t\t\t\ttype: \"text\",\n\t\t\t\tbody,\n\t\t\t\tcreatedAt: Math.floor(Date.now() / 1000),\n\t\t\t\torigin: \"programmatic\",\n\t\t\t});\n\t\t\treturn { id };\n\t\t},\n\t\thandleNotification: async () => {\n\t\t\tchatOpen = true;\n\t\t},\n\t\trequestNotifications: async () => \"granted\",\n\t\tcreateProactive: async () => undefined,\n\t\ttriggerCampaign: async () => undefined,\n\t\tevaluateCampaignConditions: async () => undefined,\n\t\tcloseCampaign: async () => undefined,\n\t\ttriggerAnswer: async () => undefined,\n\t\ttriggerProactive: async () => undefined,\n\t\ttriggerGreeting: async () => undefined,\n\t\tdestroy: async () => {\n\t\t\tkeyedSubscriptions.clear();\n\t\t\twildcardSubscriptions.clear();\n\t\t\tchatOpen = false;\n\t\t},\n\t};\n\n\tconst definedOverrides = Object.fromEntries(\n\t\tObject.entries(overrides).filter(([, value]) => value !== undefined),\n\t);\n\tconst implementation = { ...base, ...definedOverrides };\n\tconst recorded = Object.fromEntries(\n\t\tObject.entries(implementation).map(([method, fn]) => [\n\t\t\tmethod,\n\t\t\t(...args: unknown[]) => {\n\t\t\t\tcalls.push({ method, args });\n\t\t\t\treturn (fn as (...callArgs: unknown[]) => unknown)(...args);\n\t\t\t},\n\t\t]),\n\t) as unknown as AdaMessagingInterface;\n\n\treturn { ...recorded, calls, $emit: emit };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"testing.cjs","names":[],"sources":["../../../../shared/utils/src/browser-polyfills.ts","../../src/npm/testing.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 {\n\tAdaSdkEventCallback,\n\tMetaFieldValue,\n\tPublicMessage,\n} from \"../client/client-types\";\nimport type { AdaMessagingInterface } from \"./loader\";\n\n/** One recorded method invocation on a {@link MockAdaMessaging}. */\nexport interface RecordedAdaMessagingCall {\n\tmethod: string;\n\targs: unknown[];\n}\n\n/**\n * The mock returned by {@link createMockAdaMessaging}: the full\n * {@link AdaMessagingInterface} plus test hooks for inspecting calls and\n * simulating SDK events.\n */\nexport interface MockAdaMessaging extends AdaMessagingInterface {\n\t/** Every method invocation, in call order. */\n\tcalls: RecordedAdaMessagingCall[];\n\t/**\n\t * Deliver an event to `subscribeEvent` and `subscribeAll` callbacks, as if\n\t * the SDK emitted it (e.g. `$emit(\"ada:ready\", { isRolledOut: true })`).\n\t * Routing matches the real SDK: keyed subscriptions match by prefix\n\t * (`\"ada:campaigns\"` catches `\"ada:campaigns:shown\"`), except the\n\t * transcript events `ada:message:sent`/`ada:message:received`, which reach\n\t * exact-key subscribers only and never `subscribeAll`.\n\t */\n\t$emit: (key: string, data?: unknown) => void;\n}\n\ninterface KeyedSubscription {\n\tkey: string;\n\tcallback: AdaSdkEventCallback;\n}\n\n// Mirrors EXACT_MATCH_EVENT_KEYS in client/client-host-runtime.ts: transcript\n// events reach exact-key subscribers only, never prefix or subscribeAll\n// subscribers. Duplicated (not imported) so the published testing entry stays\n// free of runtime modules; a drift test pins the mock against the real matcher.\nconst EXACT_MATCH_EVENT_KEYS = new Set([\n\t\"ada:message:sent\",\n\t\"ada:message:received\",\n]);\n\nfunction keyedSubscriptionMatches(\n\tsubscriptionKey: string,\n\teventKey: string,\n): boolean {\n\tif (EXACT_MATCH_EVENT_KEYS.has(eventKey)) {\n\t\treturn subscriptionKey === eventKey;\n\t}\n\t// Raw prefix match, same as the real SDK: \"ada:campaigns\" also catches\n\t// \"ada:campaigns:shown\" and underscore-suffixed keys.\n\treturn subscriptionKey === eventKey || eventKey.startsWith(subscriptionKey);\n}\n\nfunction toMetaFieldRecord(\n\tfields: Record<string, unknown>,\n): Record<string, MetaFieldValue> {\n\tconst record: Record<string, MetaFieldValue> = {};\n\tfor (const [key, value] of Object.entries(fields)) {\n\t\tif (\n\t\t\ttypeof value === \"string\" ||\n\t\t\ttypeof value === \"number\" ||\n\t\t\ttypeof value === \"boolean\" ||\n\t\t\tvalue === null\n\t\t) {\n\t\t\trecord[key] = value;\n\t\t}\n\t}\n\treturn record;\n}\n\n/**\n * Create an in-memory messaging-interface stand-in for unit-testing an\n * integration without loading the SDK from the CDN.\n *\n * Every method resolves, records itself in `calls`, and keeps just enough\n * state to behave like the real interface: `sendMessage` appends a\n * programmatic user message that `getMessages` returns, `open`/`close`/\n * `toggle` drive `isOpen` and `getInfo`, `setMetaFields` feeds\n * `getMetaFields` (sensitive fields are never returned, matching the real\n * SDK), and `$emit` fans out to `subscribeEvent`/`subscribeAll` callbacks.\n *\n * Pass `overrides` to replace any method (e.g. with `vi.fn()`); overridden\n * methods are still recorded in `calls`.\n */\nexport function createMockAdaMessaging(\n\toverrides: Partial<AdaMessagingInterface> = {},\n): MockAdaMessaging {\n\tconst calls: RecordedAdaMessagingCall[] = [];\n\tlet nextSubscriptionId = 1;\n\tlet nextMessageId = 1;\n\tlet chatOpen = false;\n\tlet conversationId: string | null = null;\n\tconst metaFields: Record<string, MetaFieldValue> = {};\n\tconst messages: PublicMessage[] = [];\n\tconst keyedSubscriptions = new Map<number, KeyedSubscription>();\n\tconst wildcardSubscriptions = new Map<\n\t\tnumber,\n\t\t(key: string, data: unknown) => void\n\t>();\n\n\tconst emit = (key: string, data?: unknown): void => {\n\t\tfor (const subscription of keyedSubscriptions.values()) {\n\t\t\tif (keyedSubscriptionMatches(subscription.key, key)) {\n\t\t\t\tsubscription.callback(data, { eventKey: key });\n\t\t\t}\n\t\t}\n\t\tif (EXACT_MATCH_EVENT_KEYS.has(key)) {\n\t\t\treturn;\n\t\t}\n\t\tfor (const callback of wildcardSubscriptions.values()) {\n\t\t\tcallback(key, data);\n\t\t}\n\t};\n\n\tconst clearTranscript = (): void => {\n\t\tmessages.length = 0;\n\t\tconversationId = null;\n\t};\n\n\tconst base: AdaMessagingInterface = {\n\t\tstart: async () => undefined,\n\t\tstop: async () => undefined,\n\t\ttoggle: async () => {\n\t\t\tchatOpen = !chatOpen;\n\t\t},\n\t\tdeleteHistory: async () => {\n\t\t\tclearTranscript();\n\t\t},\n\t\treset: async () => {\n\t\t\tclearTranscript();\n\t\t},\n\t\tsetMetaFields: async (fields) => {\n\t\t\tObject.assign(metaFields, toMetaFieldRecord(fields));\n\t\t},\n\t\t// Sensitive fields are accepted but never readable back, matching the\n\t\t// real SDK's getMetaFields contract.\n\t\tsetSensitiveMetaFields: async () => undefined,\n\t\tsetTestModeBanner: async () => undefined,\n\t\tgetInfo: async () => ({\n\t\t\tisChatOpen: chatOpen,\n\t\t\tisDrawerOpen: chatOpen,\n\t\t\thasActiveChatter: messages.length > 0,\n\t\t\thasClosedChat: false,\n\t\t}),\n\t\tgetMetaFields: async () => ({ ...metaFields }),\n\t\tisOpen: async () => chatOpen,\n\t\tgetConversation: async () => ({\n\t\t\tid: conversationId,\n\t\t\thandoff: { inLiveChat: false },\n\t\t}),\n\t\tgetMessages: async () => [...messages],\n\t\tsetComposerText: async () => undefined,\n\t\tsetDelegate: () => undefined,\n\t\ttrackEvent: async () => undefined,\n\t\tsubscribeEvent: async (key, callback) => {\n\t\t\tconst id = nextSubscriptionId++;\n\t\t\tkeyedSubscriptions.set(id, { key, callback });\n\t\t\treturn id;\n\t\t},\n\t\tunsubscribeEvent: async (id) => {\n\t\t\tkeyedSubscriptions.delete(id);\n\t\t\twildcardSubscriptions.delete(id);\n\t\t},\n\t\tsubscribeAll: async (callback) => {\n\t\t\tconst id = nextSubscriptionId++;\n\t\t\twildcardSubscriptions.set(id, callback);\n\t\t\treturn id;\n\t\t},\n\t\topen: async () => {\n\t\t\tchatOpen = true;\n\t\t},\n\t\tclose: async () => {\n\t\t\tchatOpen = false;\n\t\t},\n\t\tsetLanguage: async () => undefined,\n\t\tsetTheme: async () => undefined,\n\t\tsetDeviceToken: async () => undefined,\n\t\t// Optional on AdaEmbedInterface (internal mobile-webview plumbing), but\n\t\t// Ada's own maintained test double still implements the full surface — the\n\t\t// types-drift guard requires the shipped mock to cover every interface\n\t\t// member so a customer's double never lags it.\n\t\tacknowledgeSessionMirrorClear: async () => undefined,\n\t\tdeliverSessionMirrorSeed: async () => undefined,\n\t\tsendMessage: async (body) => {\n\t\t\tconst id = `mock-message-${nextMessageId++}`;\n\t\t\tconversationId = conversationId ?? \"mock-conversation\";\n\t\t\tmessages.push({\n\t\t\t\tid,\n\t\t\t\trole: \"user\",\n\t\t\t\ttype: \"text\",\n\t\t\t\tbody,\n\t\t\t\tcreatedAt: Math.floor(Date.now() / 1000),\n\t\t\t\torigin: \"programmatic\",\n\t\t\t});\n\t\t\treturn { id };\n\t\t},\n\t\thandleNotification: async () => {\n\t\t\tchatOpen = true;\n\t\t},\n\t\trequestNotifications: async () => \"granted\",\n\t\tcreateProactive: async () => undefined,\n\t\ttriggerCampaign: async () => undefined,\n\t\tevaluateCampaignConditions: async () => undefined,\n\t\tcloseCampaign: async () => undefined,\n\t\ttriggerAnswer: async () => undefined,\n\t\ttriggerProactive: async () => undefined,\n\t\ttriggerGreeting: async () => undefined,\n\t\tdestroy: async () => {\n\t\t\tkeyedSubscriptions.clear();\n\t\t\twildcardSubscriptions.clear();\n\t\t\tchatOpen = false;\n\t\t},\n\t};\n\n\tconst definedOverrides = Object.fromEntries(\n\t\tObject.entries(overrides).filter(([, value]) => value !== undefined),\n\t);\n\tconst implementation = { ...base, ...definedOverrides };\n\tconst recorded = Object.fromEntries(\n\t\tObject.entries(implementation).map(([method, fn]) => [\n\t\t\tmethod,\n\t\t\t(...args: unknown[]) => {\n\t\t\t\tcalls.push({ method, args });\n\t\t\t\treturn (fn as (...callArgs: unknown[]) => unknown)(...args);\n\t\t\t},\n\t\t]),\n\t) as unknown as AdaMessagingInterface;\n\n\treturn { ...recorded, calls, $emit: emit };\n}\n"],"mappings":"mEAWA,IAAM,EAAuB,OAAO,UAAU,eAE9C,SAAS,EACR,EACA,EACA,EACO,CACP,OAAO,eAAe,EAAQ,EAAM,CACnC,MAAA,EACA,aAAc,GACd,SAAU,GACV,EAGG,OAAO,QACX,EAAY,OAAQ,SAAA,CAAW,EAAiB,IAAiB,CAChE,GAAI,GAAU,KACb,MAAM,IAAI,UACT,mEAAA,EAGF,OAAO,EAAqB,KAAK,OAAO,CAAA,EAAS,CAAA,IAInD,SAAS,EAER,EACgB,CAChB,MAAM,EAAS,KAAK,MAAM,OAAO,KAAK,MAAA,CAAO,GAAK,EAClD,IAAI,EAAgB,KAAK,MAAM,OAAO,CAAA,CAAM,GAAK,EACjD,OAAI,EAAgB,IACnB,GAAiB,GAEX,EAAgB,GAAK,GAAiB,EAC1C,OACA,KAAK,CAAA,EAGT,SAAS,EAAuB,EAAoC,CACnE,MAAM,EAAQ,OAAO,IAAA,EACf,EAAS,EAAM,OACrB,IAAI,EAAgB,KAAK,MAAM,OAAO,CAAA,CAAM,GAAK,EACjD,OAAI,EAAgB,IACnB,GAAiB,GAEX,EAAgB,GAAK,GAAiB,EAC1C,OACA,EAAM,OAAO,CAAA,EAGjB,IAAM,EAAyB,CAC9B,WAAW,UACX,WAAW,WACX,WAAW,kBACX,WAAW,WACX,WAAW,YACX,WAAW,WACX,WAAW,YACX,WAAW,aACX,WAAW,aACX,WAAW,cACX,WAAW,gBACV,OAAO,OAAA,EAEJ,MAAM,UAAU,IACpB,EAAY,MAAM,UAAW,KAAM,CAAA,EAG/B,OAAO,UAAU,IACrB,EAAY,OAAO,UAAW,KAAM,CAAA,EAGrC,UAAW,KAAyB,EAAwB,CAC3D,MAAM,EAAY,EAAsB,UACnC,EAAU,IACd,EAAY,EAAW,KAAM,CAAA,EC9C/B,IAAM,EAAyB,IAAI,IAAI,CACtC,mBACA,sBAAA,CACA,EAED,SAAS,EACR,EACA,EACU,CACV,OAAI,EAAuB,IAAI,CAAA,EACvB,IAAoB,EAIrB,IAAoB,GAAY,EAAS,WAAW,CAAA,EAG5D,SAAS,EACR,EACiC,CACjC,MAAM,EAAyC,CAAA,EAC/C,SAAW,CAAC,EAAK,CAAA,IAAU,OAAO,QAAQ,CAAA,GAExC,OAAO,GAAU,UACjB,OAAO,GAAU,UACjB,OAAO,GAAU,WACjB,IAAU,QAEV,EAAO,CAAA,EAAO,GAGhB,OAAO,EAiBR,SAAgB,EACf,EAA4C,CAAA,EACzB,CACnB,MAAM,EAAoC,CAAA,EAC1C,IAAI,EAAqB,EACrB,EAAgB,EAChB,EAAW,GACX,EAAgC,KACpC,MAAM,EAA6C,CAAA,EAC7C,EAA4B,CAAA,EAC5B,EAAqB,IAAI,IACzB,EAAwB,IAAI,IAK5B,EAAA,CAAQ,EAAa,IAAyB,CACnD,UAAW,KAAgB,EAAmB,OAAA,EACzC,EAAyB,EAAa,IAAK,CAAA,GAC9C,EAAa,SAAS,EAAM,CAAE,SAAU,CAAA,CAAK,EAG/C,GAAI,CAAA,EAAuB,IAAI,CAAA,EAG/B,UAAW,KAAY,EAAsB,OAAA,EAC5C,EAAS,EAAK,CAAA,GAIV,EAAA,IAA8B,CACnC,EAAS,OAAS,EAClB,EAAiB,MAGZ,EAA8B,CACnC,MAAO,SAAA,GACP,KAAM,SAAA,GACN,OAAQ,SAAY,CACnB,EAAW,CAAC,GAEb,cAAe,SAAY,CAC1B,EAAA,GAED,MAAO,SAAY,CAClB,EAAA,GAED,cAAe,MAAO,GAAW,CAChC,OAAO,OAAO,EAAY,EAAkB,CAAA,CAAO,GAIpD,uBAAwB,SAAA,GACxB,kBAAmB,SAAA,GACnB,QAAS,UAAa,CACrB,WAAY,EACZ,aAAc,EACd,iBAAkB,EAAS,OAAS,EACpC,cAAe,KAEhB,cAAe,UAAa,CAAE,GAAG,CAAA,GACjC,OAAQ,SAAY,EACpB,gBAAiB,UAAa,CAC7B,GAAI,EACJ,QAAS,CAAE,WAAY,EAAA,IAExB,YAAa,SAAY,CAAC,GAAG,CAAA,EAC7B,gBAAiB,SAAA,GACjB,YAAA,IAAA,GACA,WAAY,SAAA,GACZ,eAAgB,MAAO,EAAK,IAAa,CACxC,MAAM,EAAK,IACX,OAAA,EAAmB,IAAI,EAAI,CAAE,IAAA,EAAK,SAAA,EAAU,EACrC,GAER,iBAAkB,MAAO,GAAO,CAC/B,EAAmB,OAAO,CAAA,EAC1B,EAAsB,OAAO,CAAA,GAE9B,aAAc,MAAO,GAAa,CACjC,MAAM,EAAK,IACX,OAAA,EAAsB,IAAI,EAAI,CAAA,EACvB,GAER,KAAM,SAAY,CACjB,EAAW,IAEZ,MAAO,SAAY,CAClB,EAAW,IAEZ,YAAa,SAAA,GACb,SAAU,SAAA,GACV,eAAgB,SAAA,GAKhB,8BAA+B,SAAA,GAC/B,yBAA0B,SAAA,GAC1B,YAAa,MAAO,GAAS,CAC5B,MAAM,EAAK,gBAAgB,GAAA,GAC3B,OAAA,EAAiB,GAAkB,oBACnC,EAAS,KAAK,CACb,GAAA,EACA,KAAM,OACN,KAAM,OACN,KAAA,EACA,UAAW,KAAK,MAAM,KAAK,IAAA,EAAQ,GAAA,EACnC,OAAQ,eACR,EACM,CAAE,GAAA,CAAA,GAEV,mBAAoB,SAAY,CAC/B,EAAW,IAEZ,qBAAsB,SAAY,UAClC,gBAAiB,SAAA,GACjB,gBAAiB,SAAA,GACjB,2BAA4B,SAAA,GAC5B,cAAe,SAAA,GACf,cAAe,SAAA,GACf,iBAAkB,SAAA,GAClB,gBAAiB,SAAA,GACjB,QAAS,SAAY,CACpB,EAAmB,MAAA,EACnB,EAAsB,MAAA,EACtB,EAAW,KAIP,EAAmB,OAAO,YAC/B,OAAO,QAAQ,CAAA,EAAW,OAAA,CAAQ,CAAA,CAAG,CAAA,IAAW,IAAU,MAAA,CAAU,EAE/D,EAAiB,CAAE,GAAG,EAAM,GAAG,GAWrC,MAAO,CAAE,GAVQ,OAAO,YACvB,OAAO,QAAQ,CAAA,EAAgB,IAAA,CAAK,CAAC,EAAQ,CAAA,IAAQ,CACpD,EAAA,IACI,KACH,EAAM,KAAK,CAAE,OAAA,EAAQ,KAAA,EAAM,EACnB,EAA2C,GAAG,CAAA,GAEvD,CAAC,EAGmB,MAAA,EAAO,MAAO"}
@@ -1,156 +1,179 @@
1
- //#region src/npm/testing.ts
2
- var EXACT_MATCH_EVENT_KEYS = new Set(["ada:message:sent", "ada:message:received"]);
3
- function keyedSubscriptionMatches(subscriptionKey, eventKey) {
4
- if (EXACT_MATCH_EVENT_KEYS.has(eventKey)) return subscriptionKey === eventKey;
5
- return subscriptionKey === eventKey || eventKey.startsWith(subscriptionKey);
1
+ var T = Object.prototype.hasOwnProperty;
2
+ function g(n, e, a) {
3
+ Object.defineProperty(n, e, {
4
+ value: a,
5
+ configurable: !0,
6
+ writable: !0
7
+ });
6
8
  }
7
- function toMetaFieldRecord(fields) {
8
- const record = {};
9
- for (const [key, value] of Object.entries(fields)) if (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === null) record[key] = value;
10
- return record;
9
+ Object.hasOwn || g(Object, "hasOwn", (n, e) => {
10
+ if (n == null) throw new TypeError("ada browser-polyfills: Cannot convert undefined or null to object");
11
+ return T.call(Object(n), e);
12
+ });
13
+ function p(n) {
14
+ const e = Math.trunc(Number(this.length)) || 0;
15
+ let a = Math.trunc(Number(n)) || 0;
16
+ return a < 0 && (a += e), a < 0 || a >= e ? void 0 : this[a];
11
17
  }
12
- /**
13
- * Create an in-memory messaging-interface stand-in for unit-testing an
14
- * integration without loading the SDK from the CDN.
15
- *
16
- * Every method resolves, records itself in `calls`, and keeps just enough
17
- * state to behave like the real interface: `sendMessage` appends a
18
- * programmatic user message that `getMessages` returns, `open`/`close`/
19
- * `toggle` drive `isOpen` and `getInfo`, `setMetaFields` feeds
20
- * `getMetaFields` (sensitive fields are never returned, matching the real
21
- * SDK), and `$emit` fans out to `subscribeEvent`/`subscribeAll` callbacks.
22
- *
23
- * Pass `overrides` to replace any method (e.g. with `vi.fn()`); overridden
24
- * methods are still recorded in `calls`.
25
- */
26
- function createMockAdaMessaging(overrides = {}) {
27
- const calls = [];
28
- let nextSubscriptionId = 1;
29
- let nextMessageId = 1;
30
- let chatOpen = false;
31
- let conversationId = null;
32
- const metaFields = {};
33
- const messages = [];
34
- const keyedSubscriptions = /* @__PURE__ */ new Map();
35
- const wildcardSubscriptions = /* @__PURE__ */ new Map();
36
- const emit = (key, data) => {
37
- for (const subscription of keyedSubscriptions.values()) if (keyedSubscriptionMatches(subscription.key, key)) subscription.callback(data, { eventKey: key });
38
- if (EXACT_MATCH_EVENT_KEYS.has(key)) return;
39
- for (const callback of wildcardSubscriptions.values()) callback(key, data);
40
- };
41
- const clearTranscript = () => {
42
- messages.length = 0;
43
- conversationId = null;
44
- };
45
- const base = {
46
- start: async () => void 0,
47
- stop: async () => void 0,
48
- toggle: async () => {
49
- chatOpen = !chatOpen;
50
- },
51
- deleteHistory: async () => {
52
- clearTranscript();
53
- },
54
- reset: async () => {
55
- clearTranscript();
56
- },
57
- setMetaFields: async (fields) => {
58
- Object.assign(metaFields, toMetaFieldRecord(fields));
59
- },
60
- setSensitiveMetaFields: async () => void 0,
61
- setTestModeBanner: async () => void 0,
62
- getInfo: async () => ({
63
- isChatOpen: chatOpen,
64
- isDrawerOpen: chatOpen,
65
- hasActiveChatter: messages.length > 0,
66
- hasClosedChat: false
67
- }),
68
- getMetaFields: async () => ({ ...metaFields }),
69
- isOpen: async () => chatOpen,
70
- getConversation: async () => ({
71
- id: conversationId,
72
- handoff: { inLiveChat: false }
73
- }),
74
- getMessages: async () => [...messages],
75
- setComposerText: async () => void 0,
76
- setDelegate: () => void 0,
77
- trackEvent: async () => void 0,
78
- subscribeEvent: async (key, callback) => {
79
- const id = nextSubscriptionId++;
80
- keyedSubscriptions.set(id, {
81
- key,
82
- callback
83
- });
84
- return id;
85
- },
86
- unsubscribeEvent: async (id) => {
87
- keyedSubscriptions.delete(id);
88
- wildcardSubscriptions.delete(id);
89
- },
90
- subscribeAll: async (callback) => {
91
- const id = nextSubscriptionId++;
92
- wildcardSubscriptions.set(id, callback);
93
- return id;
94
- },
95
- open: async () => {
96
- chatOpen = true;
97
- },
98
- close: async () => {
99
- chatOpen = false;
100
- },
101
- setLanguage: async () => void 0,
102
- setTheme: async () => void 0,
103
- setDeviceToken: async () => void 0,
104
- acknowledgeSessionMirrorClear: async () => void 0,
105
- deliverSessionMirrorSeed: async () => void 0,
106
- sendMessage: async (body) => {
107
- const id = `mock-message-${nextMessageId++}`;
108
- conversationId = conversationId ?? "mock-conversation";
109
- messages.push({
110
- id,
111
- role: "user",
112
- type: "text",
113
- body,
114
- createdAt: Math.floor(Date.now() / 1e3),
115
- origin: "programmatic"
116
- });
117
- return { id };
118
- },
119
- handleNotification: async () => {
120
- chatOpen = true;
121
- },
122
- requestNotifications: async () => "granted",
123
- createProactive: async () => void 0,
124
- triggerCampaign: async () => void 0,
125
- evaluateCampaignConditions: async () => void 0,
126
- closeCampaign: async () => void 0,
127
- triggerAnswer: async () => void 0,
128
- triggerProactive: async () => void 0,
129
- triggerGreeting: async () => void 0,
130
- destroy: async () => {
131
- keyedSubscriptions.clear();
132
- wildcardSubscriptions.clear();
133
- chatOpen = false;
134
- }
135
- };
136
- const definedOverrides = Object.fromEntries(Object.entries(overrides).filter(([, value]) => value !== void 0));
137
- const implementation = {
138
- ...base,
139
- ...definedOverrides
140
- };
141
- return {
142
- ...Object.fromEntries(Object.entries(implementation).map(([method, fn]) => [method, (...args) => {
143
- calls.push({
144
- method,
145
- args
146
- });
147
- return fn(...args);
148
- }])),
149
- calls,
150
- $emit: emit
151
- };
18
+ function M(n) {
19
+ const e = String(this), a = e.length;
20
+ let r = Math.trunc(Number(n)) || 0;
21
+ return r < 0 && (r += a), r < 0 || r >= a ? void 0 : e.charAt(r);
152
22
  }
153
- //#endregion
154
- export { createMockAdaMessaging };
23
+ var O = [
24
+ globalThis.Int8Array,
25
+ globalThis.Uint8Array,
26
+ globalThis.Uint8ClampedArray,
27
+ globalThis.Int16Array,
28
+ globalThis.Uint16Array,
29
+ globalThis.Int32Array,
30
+ globalThis.Uint32Array,
31
+ globalThis.Float32Array,
32
+ globalThis.Float64Array,
33
+ globalThis.BigInt64Array,
34
+ globalThis.BigUint64Array
35
+ ].filter(Boolean);
36
+ Array.prototype.at || g(Array.prototype, "at", p);
37
+ String.prototype.at || g(String.prototype, "at", M);
38
+ for (const n of O) {
39
+ const e = n.prototype;
40
+ e.at || g(e, "at", p);
41
+ }
42
+ var v = /* @__PURE__ */ new Set(["ada:message:sent", "ada:message:received"]);
43
+ function C(n, e) {
44
+ return v.has(e) ? n === e : n === e || e.startsWith(n);
45
+ }
46
+ function w(n) {
47
+ const e = {};
48
+ for (const [a, r] of Object.entries(n)) (typeof r == "string" || typeof r == "number" || typeof r == "boolean" || r === null) && (e[a] = r);
49
+ return e;
50
+ }
51
+ function S(n = {}) {
52
+ const e = [];
53
+ let a = 1, r = 1, i = !1, c = null;
54
+ const u = {}, l = [], d = /* @__PURE__ */ new Map(), y = /* @__PURE__ */ new Map(), h = (t, s) => {
55
+ for (const o of d.values()) C(o.key, t) && o.callback(s, { eventKey: t });
56
+ if (!v.has(t))
57
+ for (const o of y.values()) o(t, s);
58
+ }, f = () => {
59
+ l.length = 0, c = null;
60
+ }, b = {
61
+ start: async () => {
62
+ },
63
+ stop: async () => {
64
+ },
65
+ toggle: async () => {
66
+ i = !i;
67
+ },
68
+ deleteHistory: async () => {
69
+ f();
70
+ },
71
+ reset: async () => {
72
+ f();
73
+ },
74
+ setMetaFields: async (t) => {
75
+ Object.assign(u, w(t));
76
+ },
77
+ setSensitiveMetaFields: async () => {
78
+ },
79
+ setTestModeBanner: async () => {
80
+ },
81
+ getInfo: async () => ({
82
+ isChatOpen: i,
83
+ isDrawerOpen: i,
84
+ hasActiveChatter: l.length > 0,
85
+ hasClosedChat: !1
86
+ }),
87
+ getMetaFields: async () => ({ ...u }),
88
+ isOpen: async () => i,
89
+ getConversation: async () => ({
90
+ id: c,
91
+ handoff: { inLiveChat: !1 }
92
+ }),
93
+ getMessages: async () => [...l],
94
+ setComposerText: async () => {
95
+ },
96
+ setDelegate: () => {
97
+ },
98
+ trackEvent: async () => {
99
+ },
100
+ subscribeEvent: async (t, s) => {
101
+ const o = a++;
102
+ return d.set(o, {
103
+ key: t,
104
+ callback: s
105
+ }), o;
106
+ },
107
+ unsubscribeEvent: async (t) => {
108
+ d.delete(t), y.delete(t);
109
+ },
110
+ subscribeAll: async (t) => {
111
+ const s = a++;
112
+ return y.set(s, t), s;
113
+ },
114
+ open: async () => {
115
+ i = !0;
116
+ },
117
+ close: async () => {
118
+ i = !1;
119
+ },
120
+ setLanguage: async () => {
121
+ },
122
+ setTheme: async () => {
123
+ },
124
+ setDeviceToken: async () => {
125
+ },
126
+ acknowledgeSessionMirrorClear: async () => {
127
+ },
128
+ deliverSessionMirrorSeed: async () => {
129
+ },
130
+ sendMessage: async (t) => {
131
+ const s = `mock-message-${r++}`;
132
+ return c = c ?? "mock-conversation", l.push({
133
+ id: s,
134
+ role: "user",
135
+ type: "text",
136
+ body: t,
137
+ createdAt: Math.floor(Date.now() / 1e3),
138
+ origin: "programmatic"
139
+ }), { id: s };
140
+ },
141
+ handleNotification: async () => {
142
+ i = !0;
143
+ },
144
+ requestNotifications: async () => "granted",
145
+ createProactive: async () => {
146
+ },
147
+ triggerCampaign: async () => {
148
+ },
149
+ evaluateCampaignConditions: async () => {
150
+ },
151
+ closeCampaign: async () => {
152
+ },
153
+ triggerAnswer: async () => {
154
+ },
155
+ triggerProactive: async () => {
156
+ },
157
+ triggerGreeting: async () => {
158
+ },
159
+ destroy: async () => {
160
+ d.clear(), y.clear(), i = !1;
161
+ }
162
+ }, m = Object.fromEntries(Object.entries(n).filter(([, t]) => t !== void 0)), A = {
163
+ ...b,
164
+ ...m
165
+ };
166
+ return {
167
+ ...Object.fromEntries(Object.entries(A).map(([t, s]) => [t, (...o) => (e.push({
168
+ method: t,
169
+ args: o
170
+ }), s(...o))])),
171
+ calls: e,
172
+ $emit: h
173
+ };
174
+ }
175
+ export {
176
+ S as createMockAdaMessaging
177
+ };
155
178
 
156
179
  //# sourceMappingURL=testing.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"testing.js","names":[],"sources":["../../src/npm/testing.ts"],"sourcesContent":["import type {\n\tAdaSdkEventCallback,\n\tMetaFieldValue,\n\tPublicMessage,\n} from \"../client/client-types\";\nimport type { AdaMessagingInterface } from \"./loader\";\n\n/** One recorded method invocation on a {@link MockAdaMessaging}. */\nexport interface RecordedAdaMessagingCall {\n\tmethod: string;\n\targs: unknown[];\n}\n\n/**\n * The mock returned by {@link createMockAdaMessaging}: the full\n * {@link AdaMessagingInterface} plus test hooks for inspecting calls and\n * simulating SDK events.\n */\nexport interface MockAdaMessaging extends AdaMessagingInterface {\n\t/** Every method invocation, in call order. */\n\tcalls: RecordedAdaMessagingCall[];\n\t/**\n\t * Deliver an event to `subscribeEvent` and `subscribeAll` callbacks, as if\n\t * the SDK emitted it (e.g. `$emit(\"ada:ready\", { isRolledOut: true })`).\n\t * Routing matches the real SDK: keyed subscriptions match by prefix\n\t * (`\"ada:campaigns\"` catches `\"ada:campaigns:shown\"`), except the\n\t * transcript events `ada:message:sent`/`ada:message:received`, which reach\n\t * exact-key subscribers only and never `subscribeAll`.\n\t */\n\t$emit: (key: string, data?: unknown) => void;\n}\n\ninterface KeyedSubscription {\n\tkey: string;\n\tcallback: AdaSdkEventCallback;\n}\n\n// Mirrors EXACT_MATCH_EVENT_KEYS in client/client-host-runtime.ts: transcript\n// events reach exact-key subscribers only, never prefix or subscribeAll\n// subscribers. Duplicated (not imported) so the published testing entry stays\n// free of runtime modules; a drift test pins the mock against the real matcher.\nconst EXACT_MATCH_EVENT_KEYS = new Set([\n\t\"ada:message:sent\",\n\t\"ada:message:received\",\n]);\n\nfunction keyedSubscriptionMatches(\n\tsubscriptionKey: string,\n\teventKey: string,\n): boolean {\n\tif (EXACT_MATCH_EVENT_KEYS.has(eventKey)) {\n\t\treturn subscriptionKey === eventKey;\n\t}\n\t// Raw prefix match, same as the real SDK: \"ada:campaigns\" also catches\n\t// \"ada:campaigns:shown\" and underscore-suffixed keys.\n\treturn subscriptionKey === eventKey || eventKey.startsWith(subscriptionKey);\n}\n\nfunction toMetaFieldRecord(\n\tfields: Record<string, unknown>,\n): Record<string, MetaFieldValue> {\n\tconst record: Record<string, MetaFieldValue> = {};\n\tfor (const [key, value] of Object.entries(fields)) {\n\t\tif (\n\t\t\ttypeof value === \"string\" ||\n\t\t\ttypeof value === \"number\" ||\n\t\t\ttypeof value === \"boolean\" ||\n\t\t\tvalue === null\n\t\t) {\n\t\t\trecord[key] = value;\n\t\t}\n\t}\n\treturn record;\n}\n\n/**\n * Create an in-memory messaging-interface stand-in for unit-testing an\n * integration without loading the SDK from the CDN.\n *\n * Every method resolves, records itself in `calls`, and keeps just enough\n * state to behave like the real interface: `sendMessage` appends a\n * programmatic user message that `getMessages` returns, `open`/`close`/\n * `toggle` drive `isOpen` and `getInfo`, `setMetaFields` feeds\n * `getMetaFields` (sensitive fields are never returned, matching the real\n * SDK), and `$emit` fans out to `subscribeEvent`/`subscribeAll` callbacks.\n *\n * Pass `overrides` to replace any method (e.g. with `vi.fn()`); overridden\n * methods are still recorded in `calls`.\n */\nexport function createMockAdaMessaging(\n\toverrides: Partial<AdaMessagingInterface> = {},\n): MockAdaMessaging {\n\tconst calls: RecordedAdaMessagingCall[] = [];\n\tlet nextSubscriptionId = 1;\n\tlet nextMessageId = 1;\n\tlet chatOpen = false;\n\tlet conversationId: string | null = null;\n\tconst metaFields: Record<string, MetaFieldValue> = {};\n\tconst messages: PublicMessage[] = [];\n\tconst keyedSubscriptions = new Map<number, KeyedSubscription>();\n\tconst wildcardSubscriptions = new Map<\n\t\tnumber,\n\t\t(key: string, data: unknown) => void\n\t>();\n\n\tconst emit = (key: string, data?: unknown): void => {\n\t\tfor (const subscription of keyedSubscriptions.values()) {\n\t\t\tif (keyedSubscriptionMatches(subscription.key, key)) {\n\t\t\t\tsubscription.callback(data, { eventKey: key });\n\t\t\t}\n\t\t}\n\t\tif (EXACT_MATCH_EVENT_KEYS.has(key)) {\n\t\t\treturn;\n\t\t}\n\t\tfor (const callback of wildcardSubscriptions.values()) {\n\t\t\tcallback(key, data);\n\t\t}\n\t};\n\n\tconst clearTranscript = (): void => {\n\t\tmessages.length = 0;\n\t\tconversationId = null;\n\t};\n\n\tconst base: AdaMessagingInterface = {\n\t\tstart: async () => undefined,\n\t\tstop: async () => undefined,\n\t\ttoggle: async () => {\n\t\t\tchatOpen = !chatOpen;\n\t\t},\n\t\tdeleteHistory: async () => {\n\t\t\tclearTranscript();\n\t\t},\n\t\treset: async () => {\n\t\t\tclearTranscript();\n\t\t},\n\t\tsetMetaFields: async (fields) => {\n\t\t\tObject.assign(metaFields, toMetaFieldRecord(fields));\n\t\t},\n\t\t// Sensitive fields are accepted but never readable back, matching the\n\t\t// real SDK's getMetaFields contract.\n\t\tsetSensitiveMetaFields: async () => undefined,\n\t\tsetTestModeBanner: async () => undefined,\n\t\tgetInfo: async () => ({\n\t\t\tisChatOpen: chatOpen,\n\t\t\tisDrawerOpen: chatOpen,\n\t\t\thasActiveChatter: messages.length > 0,\n\t\t\thasClosedChat: false,\n\t\t}),\n\t\tgetMetaFields: async () => ({ ...metaFields }),\n\t\tisOpen: async () => chatOpen,\n\t\tgetConversation: async () => ({\n\t\t\tid: conversationId,\n\t\t\thandoff: { inLiveChat: false },\n\t\t}),\n\t\tgetMessages: async () => [...messages],\n\t\tsetComposerText: async () => undefined,\n\t\tsetDelegate: () => undefined,\n\t\ttrackEvent: async () => undefined,\n\t\tsubscribeEvent: async (key, callback) => {\n\t\t\tconst id = nextSubscriptionId++;\n\t\t\tkeyedSubscriptions.set(id, { key, callback });\n\t\t\treturn id;\n\t\t},\n\t\tunsubscribeEvent: async (id) => {\n\t\t\tkeyedSubscriptions.delete(id);\n\t\t\twildcardSubscriptions.delete(id);\n\t\t},\n\t\tsubscribeAll: async (callback) => {\n\t\t\tconst id = nextSubscriptionId++;\n\t\t\twildcardSubscriptions.set(id, callback);\n\t\t\treturn id;\n\t\t},\n\t\topen: async () => {\n\t\t\tchatOpen = true;\n\t\t},\n\t\tclose: async () => {\n\t\t\tchatOpen = false;\n\t\t},\n\t\tsetLanguage: async () => undefined,\n\t\tsetTheme: async () => undefined,\n\t\tsetDeviceToken: async () => undefined,\n\t\t// Optional on AdaEmbedInterface (internal mobile-webview plumbing), but\n\t\t// Ada's own maintained test double still implements the full surface — the\n\t\t// types-drift guard requires the shipped mock to cover every interface\n\t\t// member so a customer's double never lags it.\n\t\tacknowledgeSessionMirrorClear: async () => undefined,\n\t\tdeliverSessionMirrorSeed: async () => undefined,\n\t\tsendMessage: async (body) => {\n\t\t\tconst id = `mock-message-${nextMessageId++}`;\n\t\t\tconversationId = conversationId ?? \"mock-conversation\";\n\t\t\tmessages.push({\n\t\t\t\tid,\n\t\t\t\trole: \"user\",\n\t\t\t\ttype: \"text\",\n\t\t\t\tbody,\n\t\t\t\tcreatedAt: Math.floor(Date.now() / 1000),\n\t\t\t\torigin: \"programmatic\",\n\t\t\t});\n\t\t\treturn { id };\n\t\t},\n\t\thandleNotification: async () => {\n\t\t\tchatOpen = true;\n\t\t},\n\t\trequestNotifications: async () => \"granted\",\n\t\tcreateProactive: async () => undefined,\n\t\ttriggerCampaign: async () => undefined,\n\t\tevaluateCampaignConditions: async () => undefined,\n\t\tcloseCampaign: async () => undefined,\n\t\ttriggerAnswer: async () => undefined,\n\t\ttriggerProactive: async () => undefined,\n\t\ttriggerGreeting: async () => undefined,\n\t\tdestroy: async () => {\n\t\t\tkeyedSubscriptions.clear();\n\t\t\twildcardSubscriptions.clear();\n\t\t\tchatOpen = false;\n\t\t},\n\t};\n\n\tconst definedOverrides = Object.fromEntries(\n\t\tObject.entries(overrides).filter(([, value]) => value !== undefined),\n\t);\n\tconst implementation = { ...base, ...definedOverrides };\n\tconst recorded = Object.fromEntries(\n\t\tObject.entries(implementation).map(([method, fn]) => [\n\t\t\tmethod,\n\t\t\t(...args: unknown[]) => {\n\t\t\t\tcalls.push({ method, args });\n\t\t\t\treturn (fn as (...callArgs: unknown[]) => unknown)(...args);\n\t\t\t},\n\t\t]),\n\t) as unknown as AdaMessagingInterface;\n\n\treturn { ...recorded, calls, $emit: emit };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"testing.js","names":[],"sources":["../../../../shared/utils/src/browser-polyfills.ts","../../src/npm/testing.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 {\n\tAdaSdkEventCallback,\n\tMetaFieldValue,\n\tPublicMessage,\n} from \"../client/client-types\";\nimport type { AdaMessagingInterface } from \"./loader\";\n\n/** One recorded method invocation on a {@link MockAdaMessaging}. */\nexport interface RecordedAdaMessagingCall {\n\tmethod: string;\n\targs: unknown[];\n}\n\n/**\n * The mock returned by {@link createMockAdaMessaging}: the full\n * {@link AdaMessagingInterface} plus test hooks for inspecting calls and\n * simulating SDK events.\n */\nexport interface MockAdaMessaging extends AdaMessagingInterface {\n\t/** Every method invocation, in call order. */\n\tcalls: RecordedAdaMessagingCall[];\n\t/**\n\t * Deliver an event to `subscribeEvent` and `subscribeAll` callbacks, as if\n\t * the SDK emitted it (e.g. `$emit(\"ada:ready\", { isRolledOut: true })`).\n\t * Routing matches the real SDK: keyed subscriptions match by prefix\n\t * (`\"ada:campaigns\"` catches `\"ada:campaigns:shown\"`), except the\n\t * transcript events `ada:message:sent`/`ada:message:received`, which reach\n\t * exact-key subscribers only and never `subscribeAll`.\n\t */\n\t$emit: (key: string, data?: unknown) => void;\n}\n\ninterface KeyedSubscription {\n\tkey: string;\n\tcallback: AdaSdkEventCallback;\n}\n\n// Mirrors EXACT_MATCH_EVENT_KEYS in client/client-host-runtime.ts: transcript\n// events reach exact-key subscribers only, never prefix or subscribeAll\n// subscribers. Duplicated (not imported) so the published testing entry stays\n// free of runtime modules; a drift test pins the mock against the real matcher.\nconst EXACT_MATCH_EVENT_KEYS = new Set([\n\t\"ada:message:sent\",\n\t\"ada:message:received\",\n]);\n\nfunction keyedSubscriptionMatches(\n\tsubscriptionKey: string,\n\teventKey: string,\n): boolean {\n\tif (EXACT_MATCH_EVENT_KEYS.has(eventKey)) {\n\t\treturn subscriptionKey === eventKey;\n\t}\n\t// Raw prefix match, same as the real SDK: \"ada:campaigns\" also catches\n\t// \"ada:campaigns:shown\" and underscore-suffixed keys.\n\treturn subscriptionKey === eventKey || eventKey.startsWith(subscriptionKey);\n}\n\nfunction toMetaFieldRecord(\n\tfields: Record<string, unknown>,\n): Record<string, MetaFieldValue> {\n\tconst record: Record<string, MetaFieldValue> = {};\n\tfor (const [key, value] of Object.entries(fields)) {\n\t\tif (\n\t\t\ttypeof value === \"string\" ||\n\t\t\ttypeof value === \"number\" ||\n\t\t\ttypeof value === \"boolean\" ||\n\t\t\tvalue === null\n\t\t) {\n\t\t\trecord[key] = value;\n\t\t}\n\t}\n\treturn record;\n}\n\n/**\n * Create an in-memory messaging-interface stand-in for unit-testing an\n * integration without loading the SDK from the CDN.\n *\n * Every method resolves, records itself in `calls`, and keeps just enough\n * state to behave like the real interface: `sendMessage` appends a\n * programmatic user message that `getMessages` returns, `open`/`close`/\n * `toggle` drive `isOpen` and `getInfo`, `setMetaFields` feeds\n * `getMetaFields` (sensitive fields are never returned, matching the real\n * SDK), and `$emit` fans out to `subscribeEvent`/`subscribeAll` callbacks.\n *\n * Pass `overrides` to replace any method (e.g. with `vi.fn()`); overridden\n * methods are still recorded in `calls`.\n */\nexport function createMockAdaMessaging(\n\toverrides: Partial<AdaMessagingInterface> = {},\n): MockAdaMessaging {\n\tconst calls: RecordedAdaMessagingCall[] = [];\n\tlet nextSubscriptionId = 1;\n\tlet nextMessageId = 1;\n\tlet chatOpen = false;\n\tlet conversationId: string | null = null;\n\tconst metaFields: Record<string, MetaFieldValue> = {};\n\tconst messages: PublicMessage[] = [];\n\tconst keyedSubscriptions = new Map<number, KeyedSubscription>();\n\tconst wildcardSubscriptions = new Map<\n\t\tnumber,\n\t\t(key: string, data: unknown) => void\n\t>();\n\n\tconst emit = (key: string, data?: unknown): void => {\n\t\tfor (const subscription of keyedSubscriptions.values()) {\n\t\t\tif (keyedSubscriptionMatches(subscription.key, key)) {\n\t\t\t\tsubscription.callback(data, { eventKey: key });\n\t\t\t}\n\t\t}\n\t\tif (EXACT_MATCH_EVENT_KEYS.has(key)) {\n\t\t\treturn;\n\t\t}\n\t\tfor (const callback of wildcardSubscriptions.values()) {\n\t\t\tcallback(key, data);\n\t\t}\n\t};\n\n\tconst clearTranscript = (): void => {\n\t\tmessages.length = 0;\n\t\tconversationId = null;\n\t};\n\n\tconst base: AdaMessagingInterface = {\n\t\tstart: async () => undefined,\n\t\tstop: async () => undefined,\n\t\ttoggle: async () => {\n\t\t\tchatOpen = !chatOpen;\n\t\t},\n\t\tdeleteHistory: async () => {\n\t\t\tclearTranscript();\n\t\t},\n\t\treset: async () => {\n\t\t\tclearTranscript();\n\t\t},\n\t\tsetMetaFields: async (fields) => {\n\t\t\tObject.assign(metaFields, toMetaFieldRecord(fields));\n\t\t},\n\t\t// Sensitive fields are accepted but never readable back, matching the\n\t\t// real SDK's getMetaFields contract.\n\t\tsetSensitiveMetaFields: async () => undefined,\n\t\tsetTestModeBanner: async () => undefined,\n\t\tgetInfo: async () => ({\n\t\t\tisChatOpen: chatOpen,\n\t\t\tisDrawerOpen: chatOpen,\n\t\t\thasActiveChatter: messages.length > 0,\n\t\t\thasClosedChat: false,\n\t\t}),\n\t\tgetMetaFields: async () => ({ ...metaFields }),\n\t\tisOpen: async () => chatOpen,\n\t\tgetConversation: async () => ({\n\t\t\tid: conversationId,\n\t\t\thandoff: { inLiveChat: false },\n\t\t}),\n\t\tgetMessages: async () => [...messages],\n\t\tsetComposerText: async () => undefined,\n\t\tsetDelegate: () => undefined,\n\t\ttrackEvent: async () => undefined,\n\t\tsubscribeEvent: async (key, callback) => {\n\t\t\tconst id = nextSubscriptionId++;\n\t\t\tkeyedSubscriptions.set(id, { key, callback });\n\t\t\treturn id;\n\t\t},\n\t\tunsubscribeEvent: async (id) => {\n\t\t\tkeyedSubscriptions.delete(id);\n\t\t\twildcardSubscriptions.delete(id);\n\t\t},\n\t\tsubscribeAll: async (callback) => {\n\t\t\tconst id = nextSubscriptionId++;\n\t\t\twildcardSubscriptions.set(id, callback);\n\t\t\treturn id;\n\t\t},\n\t\topen: async () => {\n\t\t\tchatOpen = true;\n\t\t},\n\t\tclose: async () => {\n\t\t\tchatOpen = false;\n\t\t},\n\t\tsetLanguage: async () => undefined,\n\t\tsetTheme: async () => undefined,\n\t\tsetDeviceToken: async () => undefined,\n\t\t// Optional on AdaEmbedInterface (internal mobile-webview plumbing), but\n\t\t// Ada's own maintained test double still implements the full surface — the\n\t\t// types-drift guard requires the shipped mock to cover every interface\n\t\t// member so a customer's double never lags it.\n\t\tacknowledgeSessionMirrorClear: async () => undefined,\n\t\tdeliverSessionMirrorSeed: async () => undefined,\n\t\tsendMessage: async (body) => {\n\t\t\tconst id = `mock-message-${nextMessageId++}`;\n\t\t\tconversationId = conversationId ?? \"mock-conversation\";\n\t\t\tmessages.push({\n\t\t\t\tid,\n\t\t\t\trole: \"user\",\n\t\t\t\ttype: \"text\",\n\t\t\t\tbody,\n\t\t\t\tcreatedAt: Math.floor(Date.now() / 1000),\n\t\t\t\torigin: \"programmatic\",\n\t\t\t});\n\t\t\treturn { id };\n\t\t},\n\t\thandleNotification: async () => {\n\t\t\tchatOpen = true;\n\t\t},\n\t\trequestNotifications: async () => \"granted\",\n\t\tcreateProactive: async () => undefined,\n\t\ttriggerCampaign: async () => undefined,\n\t\tevaluateCampaignConditions: async () => undefined,\n\t\tcloseCampaign: async () => undefined,\n\t\ttriggerAnswer: async () => undefined,\n\t\ttriggerProactive: async () => undefined,\n\t\ttriggerGreeting: async () => undefined,\n\t\tdestroy: async () => {\n\t\t\tkeyedSubscriptions.clear();\n\t\t\twildcardSubscriptions.clear();\n\t\t\tchatOpen = false;\n\t\t},\n\t};\n\n\tconst definedOverrides = Object.fromEntries(\n\t\tObject.entries(overrides).filter(([, value]) => value !== undefined),\n\t);\n\tconst implementation = { ...base, ...definedOverrides };\n\tconst recorded = Object.fromEntries(\n\t\tObject.entries(implementation).map(([method, fn]) => [\n\t\t\tmethod,\n\t\t\t(...args: unknown[]) => {\n\t\t\t\tcalls.push({ method, args });\n\t\t\t\treturn (fn as (...callArgs: unknown[]) => unknown)(...args);\n\t\t\t},\n\t\t]),\n\t) as unknown as AdaMessagingInterface;\n\n\treturn { ...recorded, calls, $emit: emit };\n}\n"],"mappings":"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"}
@@ -32,6 +32,8 @@ export interface HostBranding {
32
32
  botDescription?: HostLocalizedText;
33
33
  /** Absolute `https:` URL of the bot avatar image. Switches the avatar to image mode. */
34
34
  avatarUrl?: string;
35
+ /** Accent colour of the chat window, 3 or 6 digit hex. The launcher keeps its own colour. */
36
+ tintColor?: string;
35
37
  /** Header background colour, 3 or 6 digit hex. Turns header colouring on. */
36
38
  headerColor?: string;
37
39
  /**
@@ -50,6 +52,7 @@ export type HostBrandingField =
50
52
  | "botName"
51
53
  | "botDescription"
52
54
  | "avatarUrl"
55
+ | "tintColor"
53
56
  | "headerColor"
54
57
  | "headerTextColor"
55
58
  | "cornerStyle"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ada-cx/messaging-sdk",
3
- "version": "1.4.0",
3
+ "version": "1.6.1",
4
4
  "description": "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.",
5
5
  "homepage": "https://docs.ada.cx",
6
6
  "keywords": [
@@ -56,7 +56,7 @@
56
56
  "access": "public"
57
57
  },
58
58
  "scripts": {
59
- "build": "vite build && vite build --mode npm && tsc -b && node scripts/finish-npm-package.mjs",
59
+ "build": "vite build && vite build --mode npm && vite build --mode npm-testing && tsc -b && node scripts/finish-npm-package.mjs",
60
60
  "dev": "vite",
61
61
  "lint": "npx biome check",
62
62
  "prepack": "node scripts/finish-npm-package.mjs --verify"