@ada-support/embed2 1.12.3 → 1.13.0

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.
@@ -0,0 +1,22 @@
1
+ import type { StartOptions } from "@ada-support/embed-types";
2
+ export type HostTelemetrySurface = "mobile" | "browser";
3
+ export type HostTelemetryPlatform = "ios" | "android" | "react_native" | "web" | "unknown";
4
+ export type HostTelemetryWebSdkOrigin = "legacy" | "messaging";
5
+ export interface HostTelemetryContext {
6
+ surface: HostTelemetrySurface;
7
+ hostPlatform: HostTelemetryPlatform;
8
+ webSdkOrigin: HostTelemetryWebSdkOrigin;
9
+ mobilePackage?: string;
10
+ sdkVariant?: string;
11
+ }
12
+ export declare const HOST_TELEMETRY_QUERY_PARAM = "ada_host_telemetry";
13
+ type StartOptionsWithHostTelemetry = StartOptions & {
14
+ hostTelemetry?: unknown;
15
+ };
16
+ export declare function resolveHostTelemetryFromStartOptions(adaSettings: StartOptionsWithHostTelemetry, options?: {
17
+ pathname?: string;
18
+ }): HostTelemetryContext;
19
+ export declare function serializeHostTelemetry(hostTelemetry: HostTelemetryContext): string;
20
+ export declare function shouldPropagateHostTelemetry(hostTelemetry: HostTelemetryContext): boolean;
21
+ export declare function toMonitoringContext(hostTelemetry: HostTelemetryContext): Record<string, string>;
22
+ export {};
@@ -4,15 +4,4 @@ export interface Hosts {
4
4
  export interface Ports {
5
5
  [key: string]: number;
6
6
  }
7
- export declare const ports: {
8
- readonly localhost: {
9
- readonly api: 8000;
10
- readonly chat: 8002;
11
- readonly default: 9001;
12
- };
13
- readonly e2ereference: {
14
- readonly api: 8000;
15
- readonly chat: 8002;
16
- readonly default: 9001;
17
- };
18
- };
7
+ export declare const ports: Hosts;
@@ -15919,7 +15919,7 @@ const client = new BrowserClient({
15919
15919
  return event;
15920
15920
  },
15921
15921
  environment: "production",
15922
- release: "1.12.3-84129bb",
15922
+ release: "1.13.0-a6606d6",
15923
15923
  sampleRate: 0.25,
15924
15924
  autoSessionTracking: false,
15925
15925
  // Integrations don't seem to work with Sentry: https://github.com/getsentry/sentry-javascript/issues/2541
@@ -16460,16 +16460,23 @@ function httpRequest(obj) {
16460
16460
  ;// CONCATENATED MODULE: ./src/common/helpers/config-info.ts
16461
16461
  const isProduction = "production" === "production";
16462
16462
  ;// CONCATENATED MODULE: ./src/common/helpers/url/constants.ts
16463
+ // These ports are only used in development (localhost URL construction).
16464
+ // Production code paths check `isProduction` first and never read these values.
16465
+ //
16466
+ // The values come from DefinePlugin globals (DEV_API_PORT, DEV_CHAT_PORT,
16467
+ // DEV_FRAMES_PORT) which default to 8000, 8002, 9001 respectively when the
16468
+ // env vars are not set. So running `yarn start` without any env vars produces
16469
+ // the same ports as before — this is not a behavior change for normal dev.
16463
16470
  const ports = {
16464
16471
  localhost: {
16465
- api: 8000,
16466
- chat: 8002,
16467
- default: 9001
16472
+ api: Number(DEV_API_PORT),
16473
+ chat: Number(DEV_CHAT_PORT),
16474
+ default: Number(DEV_FRAMES_PORT)
16468
16475
  },
16469
16476
  e2ereference: {
16470
- api: 8000,
16471
- chat: 8002,
16472
- default: 9001
16477
+ api: Number(DEV_API_PORT),
16478
+ chat: Number(DEV_CHAT_PORT),
16479
+ default: Number(DEV_FRAMES_PORT)
16473
16480
  }
16474
16481
  };
16475
16482
  ;// CONCATENATED MODULE: ./src/common/helpers/url/index.ts
@@ -16500,9 +16507,9 @@ function getEmbedURL(_ref) {
16500
16507
  if (isProduction) {
16501
16508
  host = `https://${handle}${clusterString}.${domainString}.support`;
16502
16509
  } else {
16503
- host = `http://${handle}.localhost:9001`;
16510
+ host = `http://${handle}.localhost:${ports.localhost.default}`;
16504
16511
  }
16505
- return `${host}/embed/${frameName}/${"84129bb"}/index.html`;
16512
+ return `${host}/embed/${frameName}/${"a6606d6"}/index.html`;
16506
16513
  }
16507
16514
  function constructQueryString(query) {
16508
16515
  return Object.keys(query).map(key => {
@@ -16566,7 +16573,7 @@ function getChatURL(_ref3) {
16566
16573
  if (domainName === "localhost") {
16567
16574
  // Chat should be on a different domain (even though the port is different).
16568
16575
  // We need this to test Embed+Chat behaviour when third-party cookies are disabled (incognito mode).
16569
- return `${window.location.protocol}//${handle}.chat:8002/${questionSym}${queryString}`;
16576
+ return `${window.location.protocol}//${handle}.chat:${ports.localhost.chat}/${questionSym}${queryString}`;
16570
16577
  }
16571
16578
  const host = `${window.location.hostname}:${ports[domainName].chat}`;
16572
16579
  return `http://${host}/${questionSym}${queryString}`;
@@ -17656,6 +17663,13 @@ function logger_objectSpread(e) { for (var r = 1; r < arguments.length; r++) { v
17656
17663
  const DEFAULT_LOG_SAMPLE_RATE = 0.01;
17657
17664
  const DD_BASE_URL = "https://browser-http-intake.logs.datadoghq.com/v1/input/";
17658
17665
  const DD_TOKEN = "pubfe23baedd2ea322bebb5ed2020fa2fa1";
17666
+ let globalLogContext = {};
17667
+ function setGlobalLogContext(context) {
17668
+ globalLogContext = logger_objectSpread({}, context);
17669
+ }
17670
+ function clearGlobalLogContext() {
17671
+ globalLogContext = {};
17672
+ }
17659
17673
 
17660
17674
  // We need memoization to ensure consistency of logs
17661
17675
  const shouldLog = lodash_memoize_default()(sampleRate => {
@@ -17675,17 +17689,17 @@ async function log(message, extra, options) {
17675
17689
  await httpRequest({
17676
17690
  url: `${DD_BASE_URL}${DD_TOKEN}?ddsource=browser&ddtags=version:1.5.0,env:${"production"}`,
17677
17691
  method: "POST",
17678
- body: JSON.stringify(logger_objectSpread(logger_objectSpread({
17692
+ body: JSON.stringify(logger_objectSpread(logger_objectSpread(logger_objectSpread({
17679
17693
  message
17680
- }, extra), {}, {
17694
+ }, extra), globalLogContext), {}, {
17681
17695
  level: (options === null || options === void 0 ? void 0 : options.level) || "info",
17682
17696
  sampleRate: (options === null || options === void 0 ? void 0 : options.sampleRate) || DEFAULT_LOG_SAMPLE_RATE,
17683
17697
  service: "embed",
17684
17698
  env: "production",
17685
17699
  embedVersion: 2,
17686
- version: "1.12.3",
17700
+ version: "1.13.0",
17687
17701
  isNpm: true,
17688
- commitHash: "84129bb"
17702
+ commitHash: "a6606d6"
17689
17703
  }))
17690
17704
  });
17691
17705
  }
@@ -19072,6 +19086,134 @@ class LightboxOverlay extends preact_module_d {
19072
19086
  const ANIMATION_DELAY = 50;
19073
19087
  const CHAT_FRAME_TIMEOUT_EVENT_MS = 5000;
19074
19088
  const CHAT_FALLBACK_DELAY_MS = 10000;
19089
+ ;// CONCATENATED MODULE: ./src/common/helpers/host-telemetry.ts
19090
+
19091
+ function host_telemetry_ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
19092
+ function host_telemetry_objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? host_telemetry_ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : host_telemetry_ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
19093
+ const HOST_TELEMETRY_QUERY_PARAM = "ada_host_telemetry";
19094
+ const TRUSTED_MOBILE_SDK_PATH = "/mobile-sdk-webview/";
19095
+ const MAX_TELEMETRY_TAG_LENGTH = 100;
19096
+ const TELEMETRY_TAG_VALUE_PATTERN = /^[a-z0-9_-]+$/;
19097
+
19098
+ // Private mobile-sdk handshake used only on the trusted /mobile-sdk-webview/ page.
19099
+
19100
+ // Keep this normalization logic in sync with
19101
+ // chat/src/shared/services/host-telemetry.ts. Both sides normalize across the
19102
+ // embed/chat iframe boundary on purpose.
19103
+ function asRecord(value) {
19104
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
19105
+ }
19106
+ function normalizeSurface(value) {
19107
+ if (value === "mobile" || value === "browser") {
19108
+ return value;
19109
+ }
19110
+ return undefined;
19111
+ }
19112
+ function normalizeHostPlatform(value) {
19113
+ if (typeof value !== "string") {
19114
+ return undefined;
19115
+ }
19116
+ switch (value.trim().toLowerCase()) {
19117
+ case "ios":
19118
+ return "ios";
19119
+ case "android":
19120
+ return "android";
19121
+ case "react_native":
19122
+ case "reactnative":
19123
+ return "react_native";
19124
+ case "web":
19125
+ return "web";
19126
+ case "unknown":
19127
+ return "unknown";
19128
+ default:
19129
+ return undefined;
19130
+ }
19131
+ }
19132
+ function normalizeOrigin(value) {
19133
+ if (value === "legacy" || value === "messaging") {
19134
+ return value;
19135
+ }
19136
+ return undefined;
19137
+ }
19138
+ function normalizeTelemetryTagValue(value) {
19139
+ if (typeof value !== "string") {
19140
+ return undefined;
19141
+ }
19142
+ const normalizedValue = value.trim().toLowerCase();
19143
+ if (!normalizedValue || normalizedValue.length > MAX_TELEMETRY_TAG_LENGTH || !TELEMETRY_TAG_VALUE_PATTERN.test(normalizedValue)) {
19144
+ return undefined;
19145
+ }
19146
+ return normalizedValue;
19147
+ }
19148
+ function deriveSdkVariant(mobilePackage, webSdkOrigin) {
19149
+ if (!mobilePackage || !webSdkOrigin) {
19150
+ return undefined;
19151
+ }
19152
+ return `${mobilePackage}-${webSdkOrigin}`;
19153
+ }
19154
+ function normalizeHostTelemetry(value) {
19155
+ const record = asRecord(value);
19156
+ if (!record) {
19157
+ return undefined;
19158
+ }
19159
+ const surface = normalizeSurface(record.surface);
19160
+ const hostPlatform = normalizeHostPlatform(record.hostPlatform);
19161
+ const webSdkOrigin = normalizeOrigin(record.webSdkOrigin);
19162
+ const mobilePackage = normalizeTelemetryTagValue(record.mobilePackage);
19163
+ if (!surface || !hostPlatform || !webSdkOrigin) {
19164
+ return undefined;
19165
+ }
19166
+ const sdkVariant = normalizeTelemetryTagValue(record.sdkVariant) ?? deriveSdkVariant(mobilePackage, webSdkOrigin);
19167
+ return host_telemetry_objectSpread(host_telemetry_objectSpread({
19168
+ surface,
19169
+ hostPlatform,
19170
+ webSdkOrigin
19171
+ }, mobilePackage ? {
19172
+ mobilePackage
19173
+ } : {}), sdkVariant ? {
19174
+ sdkVariant
19175
+ } : {});
19176
+ }
19177
+ function isTrustedMobileSdkHostPage() {
19178
+ let pathname = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window.location.pathname;
19179
+ return pathname === TRUSTED_MOBILE_SDK_PATH || pathname === TRUSTED_MOBILE_SDK_PATH.slice(0, -1);
19180
+ }
19181
+ function resolveHostTelemetryFromStartOptions(adaSettings) {
19182
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
19183
+ const trustedMobileSdkHostPage = isTrustedMobileSdkHostPage(options.pathname);
19184
+ const explicit = trustedMobileSdkHostPage ? normalizeHostTelemetry(adaSettings.hostTelemetry) : undefined;
19185
+ const webSdkOrigin = (explicit === null || explicit === void 0 ? void 0 : explicit.webSdkOrigin) ?? "legacy";
19186
+ const hostPlatform = (explicit === null || explicit === void 0 ? void 0 : explicit.hostPlatform) ?? (trustedMobileSdkHostPage ? "unknown" : "web");
19187
+ const surface = (explicit === null || explicit === void 0 ? void 0 : explicit.surface) ?? (trustedMobileSdkHostPage ? "mobile" : "browser");
19188
+ const mobilePackage = explicit === null || explicit === void 0 ? void 0 : explicit.mobilePackage;
19189
+ const sdkVariant = explicit === null || explicit === void 0 ? void 0 : explicit.sdkVariant;
19190
+ return host_telemetry_objectSpread(host_telemetry_objectSpread({
19191
+ surface,
19192
+ hostPlatform,
19193
+ webSdkOrigin
19194
+ }, mobilePackage ? {
19195
+ mobilePackage
19196
+ } : {}), sdkVariant ? {
19197
+ sdkVariant
19198
+ } : {});
19199
+ }
19200
+ function serializeHostTelemetry(hostTelemetry) {
19201
+ return JSON.stringify(hostTelemetry);
19202
+ }
19203
+ function shouldPropagateHostTelemetry(hostTelemetry) {
19204
+ return hostTelemetry.surface !== "browser" || hostTelemetry.hostPlatform !== "web" || hostTelemetry.webSdkOrigin !== "legacy" || Boolean(hostTelemetry.mobilePackage) || Boolean(hostTelemetry.sdkVariant);
19205
+ }
19206
+ function toMonitoringContext(hostTelemetry) {
19207
+ return host_telemetry_objectSpread(host_telemetry_objectSpread({
19208
+ surface: hostTelemetry.surface,
19209
+ host_platform: hostTelemetry.hostPlatform,
19210
+ web_sdk_origin: hostTelemetry.webSdkOrigin
19211
+ }, hostTelemetry.mobilePackage ? {
19212
+ mobile_package: hostTelemetry.mobilePackage
19213
+ } : {}), hostTelemetry.sdkVariant ? {
19214
+ sdk_variant: hostTelemetry.sdkVariant
19215
+ } : {});
19216
+ }
19075
19217
  ;// CONCATENATED MODULE: ./src/common/helpers/is-mobile.ts
19076
19218
  const isMobile = /(iPhone)|(iPod)|(android)|(webOS)/i.exec(navigator.userAgent) !== null;
19077
19219
  ;// CONCATENATED MODULE: ./src/client/components/ChatFrame/chatFrameEvents/chatterEvent/index.ts
@@ -19242,6 +19384,7 @@ function getFallbackDataURI() {
19242
19384
 
19243
19385
 
19244
19386
 
19387
+
19245
19388
 
19246
19389
  class ChatFrame extends preact_module_d {
19247
19390
  constructor() {
@@ -19292,7 +19435,7 @@ class ChatFrame extends preact_module_d {
19292
19435
  log("Chat frame mount", {
19293
19436
  handle,
19294
19437
  chatUrl: this.url,
19295
- embedVersion: "84129bb".slice(0, 7),
19438
+ embedVersion: "a6606d6".slice(0, 7),
19296
19439
  embedSettings: adaSettings
19297
19440
  });
19298
19441
 
@@ -19380,7 +19523,7 @@ class ChatFrame extends preact_module_d {
19380
19523
  const hostPageUrlParams = new URL(window.location.href).searchParams;
19381
19524
  const smsToken = hostPageUrlParams.get("adaSMSToken");
19382
19525
  const queryParams = {
19383
- embedVersion: "84129bb".slice(0, 7),
19526
+ embedVersion: "a6606d6".slice(0, 7),
19384
19527
  greeting,
19385
19528
  language,
19386
19529
  skipGreeting,
@@ -19390,6 +19533,10 @@ class ChatFrame extends preact_module_d {
19390
19533
  test_user: testMode ? 1 : null,
19391
19534
  align: getAlignment(adaSettings)
19392
19535
  };
19536
+ const hostTelemetry = resolveHostTelemetryFromStartOptions(adaSettings);
19537
+ if (shouldPropagateHostTelemetry(hostTelemetry)) {
19538
+ queryParams[HOST_TELEMETRY_QUERY_PARAM] = serializeHostTelemetry(hostTelemetry);
19539
+ }
19393
19540
  if (smsToken) {
19394
19541
  queryParams.adaSMSToken = smsToken;
19395
19542
  }
@@ -21688,6 +21835,7 @@ function createEmbed(adaSettings) {
21688
21835
 
21689
21836
 
21690
21837
 
21838
+
21691
21839
  const EMBED_NOT_INITIALIZED_ERROR = new AdaEmbedError("Actions cannot be called until Embed has been instantiated. Try running `adaEmbed.start({...})`.");
21692
21840
 
21693
21841
  /**
@@ -21713,17 +21861,24 @@ function createEmbedInterface() {
21713
21861
  if (embed) {
21714
21862
  throw new AdaEmbedError("Ada Embed has already been started.");
21715
21863
  }
21716
- embed = createEmbed(adaSettings);
21717
- if (window.adaEmbedLoadedCallback) {
21718
- window.adaEmbedLoadedCallback();
21864
+ setGlobalLogContext(toMonitoringContext(resolveHostTelemetryFromStartOptions(adaSettings)));
21865
+ try {
21866
+ embed = createEmbed(adaSettings);
21867
+ if (window.adaEmbedLoadedCallback) {
21868
+ window.adaEmbedLoadedCallback();
21869
+ }
21870
+ log("Embed start", {
21871
+ handle: adaSettings.handle,
21872
+ embedSettings: adaSettings,
21873
+ hostPage: window.location.href,
21874
+ adaScriptURL: (scriptElement => scriptElement ? scriptElement.src : null)(document.getElementById("__ada"))
21875
+ });
21876
+ await embed.initialized;
21877
+ } catch (error) {
21878
+ embed = null;
21879
+ clearGlobalLogContext();
21880
+ throw error;
21719
21881
  }
21720
- log("Embed start", {
21721
- handle: adaSettings.handle,
21722
- embedSettings: adaSettings,
21723
- hostPage: window.location.href,
21724
- adaScriptURL: (scriptElement => scriptElement ? scriptElement.src : null)(document.getElementById("__ada"))
21725
- });
21726
- return embed.initialized;
21727
21882
  },
21728
21883
  stop: async () => {
21729
21884
  if (!embed) {
@@ -21731,7 +21886,11 @@ function createEmbedInterface() {
21731
21886
  }
21732
21887
  const stopPromise = embed.stop();
21733
21888
  embed = null;
21734
- return stopPromise;
21889
+ try {
21890
+ await stopPromise;
21891
+ } finally {
21892
+ clearGlobalLogContext();
21893
+ }
21735
21894
  },
21736
21895
  toggle,
21737
21896
  deleteHistory: async () => {
@@ -1,4 +1,6 @@
1
1
  export declare const DEFAULT_LOG_SAMPLE_RATE = 0.01;
2
+ export declare function setGlobalLogContext(context: Record<string, unknown>): void;
3
+ export declare function clearGlobalLogContext(): void;
2
4
  export declare const shouldLog: ((sampleRate?: number) => boolean) & import("lodash").MemoizedFunction;
3
5
  /**
4
6
  * Sends log to Datadog
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ada-support/embed2",
3
- "version": "1.12.3",
3
+ "version": "1.13.0",
4
4
  "description": "",
5
5
  "main": "dist/npm-entry",
6
6
  "typings": "dist/npm-entry/index-npm.d.ts",