@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.
- package/dist/client/client-channel-handlers.d.ts +0 -1
- package/dist/client/client-host-runtime.d.ts +0 -1
- package/dist/client/client-types.d.ts +4 -1
- package/dist/client/client.d.ts +2 -16
- package/dist/client/config-helpers.d.ts +3 -13
- package/dist/frame-channel/types.d.ts +0 -1
- package/dist/index.d.ts +1 -1
- package/dist/mobile-webview-runtime.d.ts +1 -1
- package/dist/npm/index.cjs +57 -1
- package/dist/npm/index.cjs.map +1 -1
- package/dist/npm/index.d.cts +2 -2
- package/dist/npm/index.d.ts +1 -1
- package/dist/npm/index.js +57 -1
- package/dist/npm/index.js.map +1 -1
- package/dist/npm/testing.cjs +1 -155
- package/dist/npm/testing.cjs.map +1 -1
- package/dist/npm/testing.js +174 -151
- package/dist/npm/testing.js.map +1 -1
- package/dist/shared-utils/host-branding.d.ts +3 -0
- package/package.json +2 -2
- package/dist/client/url-business-events.d.ts +0 -19
package/dist/npm/testing.cjs
CHANGED
|
@@ -1,157 +1,3 @@
|
|
|
1
|
-
Object.defineProperty(exports,
|
|
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
|
package/dist/npm/testing.cjs.map
CHANGED
|
@@ -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":"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"}
|
package/dist/npm/testing.js
CHANGED
|
@@ -1,156 +1,179 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
|
|
14
|
-
|
|
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
|
-
|
|
154
|
-
|
|
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
|
package/dist/npm/testing.js.map
CHANGED
|
@@ -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.
|
|
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"
|