@sailfish-ai/recorder 1.8.19 → 1.8.21-alpha5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,3 +9,4 @@
9
9
  ## Trigger build - 11182025 1125AM GMT+4
10
10
 
11
11
  ## Trigger build - 02122025 0330PM GMT+4
12
+ ## Trigger build - 26122025 0330PM GMT+4
package/dist/graphql.js CHANGED
@@ -38,6 +38,7 @@ export function fetchCaptureSettings(apiKey, backendApi) {
38
38
  recordSsn
39
39
  recordDob
40
40
  sampling
41
+ textEditThrottleEnabled
41
42
  }
42
43
  }
43
44
  `, { apiKey, backendApi });
package/dist/recorder.cjs CHANGED
@@ -465,7 +465,7 @@ function initializeWebSocket(e, a, u, m2) {
465
465
  const a2 = document.createElement("a");
466
466
  return a2.href = e2, `${a2.hostname}${a2.port ? `:${a2.port}` : ""}`;
467
467
  })(e);
468
- let b2 = `${"https:" === new URL(e).protocol ? "wss" : "ws"}://${w2}/ws/notify/?apiKey=${a}&sessionId=${u}&sender=JS%2FTS&version=1.8.19`;
468
+ let b2 = `${"https:" === new URL(e).protocol ? "wss" : "ws"}://${w2}/ws/notify/?apiKey=${a}&sessionId=${u}&sender=JS%2FTS&version=1.8.21-alpha5`;
469
469
  m2 && (b2 += `&envValue=${encodeURIComponent(m2)}`);
470
470
  return oe = new U(b2, [], { connectionTimeout: 3e4 }), oe.addEventListener("open", () => {
471
471
  ne && (console.log("[Sailfish] WebSocket connection opened"), console.log("[Sailfish] Function span tracking state: " + (ce ? "ENABLED" : "DISABLED"))), (async () => {
@@ -1294,7 +1294,7 @@ function sendGraphQLRequest(e, a, u, m2 = 5, w2 = 2e3, b2 = 2) {
1294
1294
  }), "Sending GraphQL request to Sailfish AI", m2, w2, b2);
1295
1295
  }
1296
1296
  function fetchCaptureSettings(e, a) {
1297
- return sendGraphQLRequest("GetCaptureSettingsFromApiKey", "\n query GetCaptureSettingsFromApiKey($apiKey: String!) {\n captureSettingsFromApiKey(apiKey: $apiKey) {\n recordCanvas\n recordCrossOriginIframes\n collectFonts\n inlineImages\n recordPassword\n recordRealName\n recordCreditCardInfo\n recordSsn\n recordDob\n sampling\n }\n }\n ", { apiKey: e, backendApi: a });
1297
+ return sendGraphQLRequest("GetCaptureSettingsFromApiKey", "\n query GetCaptureSettingsFromApiKey($apiKey: String!) {\n captureSettingsFromApiKey(apiKey: $apiKey) {\n recordCanvas\n recordCrossOriginIframes\n collectFonts\n inlineImages\n recordPassword\n recordRealName\n recordCreditCardInfo\n recordSsn\n recordDob\n sampling\n textEditThrottleEnabled\n }\n }\n ", { apiKey: e, backendApi: a });
1298
1298
  }
1299
1299
  function fetchFunctionSpanTrackingEnabled(e, a) {
1300
1300
  return sendGraphQLRequest("GetFunctionSpanTrackingEnabledFromApiKey", "\n query GetFunctionSpanTrackingEnabledFromApiKey($apiKey: String!) {\n isFunctionSpanTrackingEnabledFromApiKey(apiKey: $apiKey)\n }\n ", { apiKey: e, backendApi: a });
@@ -2297,7 +2297,7 @@ function showStatusModal(e, a) {
2297
2297
  function fadeCardAndRemove(e, a, u = 300) {
2298
2298
  a.style.opacity = "0", a.addEventListener("transitionend", () => e.remove(), { once: true }), setTimeout(() => e.remove(), u + 100);
2299
2299
  }
2300
- var yt = Object.defineProperty, b$1 = (e, a, u) => ((e2, a2, u2) => a2 in e2 ? yt(e2, a2, { enumerable: true, configurable: true, writable: true, value: u2 }) : e2[a2] = u2)(e, "symbol" != typeof a ? a + "" : a, u), wt = Object.defineProperty, xn = (e, a, u) => ((e2, a2, u2) => a2 in e2 ? wt(e2, a2, { enumerable: true, configurable: true, writable: true, value: u2 }) : e2[a2] = u2)(e, "symbol" != typeof a ? a + "" : a, u), bt = ((e) => (e[e.Document = 0] = "Document", e[e.DocumentType = 1] = "DocumentType", e[e.Element = 2] = "Element", e[e.Text = 3] = "Text", e[e.CDATA = 4] = "CDATA", e[e.Comment = 5] = "Comment", e))(bt || {});
2300
+ var yt = Object.defineProperty, b$1 = (e, a, u) => ((e2, a2, u2) => a2 in e2 ? yt(e2, a2, { enumerable: true, configurable: true, writable: true, value: u2 }) : e2[a2] = u2)(e, "symbol" != typeof a ? a + "" : a, u), wt = Object.defineProperty, xn = (e, a, u) => ((e2, a2, u2) => a2 in e2 ? wt(e2, a2, { enumerable: true, configurable: true, writable: true, value: u2 }) : e2[a2] = u2)(e, "symbol" != typeof a ? a + "" : a, u), St = ((e) => (e[e.Document = 0] = "Document", e[e.DocumentType = 1] = "DocumentType", e[e.Element = 2] = "Element", e[e.Text = 3] = "Text", e[e.CDATA = 4] = "CDATA", e[e.Comment = 5] = "Comment", e))(St || {});
2301
2301
  function vr(e) {
2302
2302
  return e.nodeType === e.ELEMENT_NODE;
2303
2303
  }
@@ -2339,7 +2339,7 @@ function kr(e) {
2339
2339
  })(e.cssText);
2340
2340
  return a || e.cssText;
2341
2341
  }
2342
- let St = class {
2342
+ let bt = class {
2343
2343
  constructor() {
2344
2344
  xn(this, "idNodeMap", /* @__PURE__ */ new Map()), xn(this, "nodeMetaMap", /* @__PURE__ */ new WeakMap());
2345
2345
  }
@@ -2525,9 +2525,9 @@ function zi(e, a) {
2525
2525
  })(u, m2);
2526
2526
  switch (e.nodeType) {
2527
2527
  case e.DOCUMENT_NODE:
2528
- return "CSS1Compat" !== e.compatMode ? { type: bt.Document, childNodes: [], compatMode: e.compatMode } : { type: bt.Document, childNodes: [] };
2528
+ return "CSS1Compat" !== e.compatMode ? { type: St.Document, childNodes: [], compatMode: e.compatMode } : { type: St.Document, childNodes: [] };
2529
2529
  case e.DOCUMENT_TYPE_NODE:
2530
- return { type: bt.DocumentType, name: e.name, publicId: e.publicId, systemId: e.systemId, rootId: U2 };
2530
+ return { type: St.DocumentType, name: e.name, publicId: e.publicId, systemId: e.systemId, rootId: U2 };
2531
2531
  case e.ELEMENT_NODE:
2532
2532
  return (function Vi(e2, a2) {
2533
2533
  const { doc: u2, blockClass: m3, blockSelector: w3, inlineStylesheet: b3, maskInputOptions: x3 = {}, maskInputFn: C3, dataURLOptions: I3 = {}, inlineImages: E3, recordCanvas: _3, keepIframeSrcFn: O3, newlyAddedElement: F3 = false, rootId: D3 } = a2, $3 = (function Ui(e3, a3, u3) {
@@ -2613,7 +2613,7 @@ function zi(e, a) {
2613
2613
  customElements.get(B3) && (z2 = true);
2614
2614
  } catch {
2615
2615
  }
2616
- return { type: bt.Element, tagName: B3, attributes: U3, childNodes: [], isSVG: Fi(e2) || void 0, needBlock: $3, rootId: D3, isCustom: z2 };
2616
+ return { type: St.Element, tagName: B3, attributes: U3, childNodes: [], isSVG: Fi(e2) || void 0, needBlock: $3, rootId: D3, isCustom: z2 };
2617
2617
  })(e, { doc: u, blockClass: w2, blockSelector: b2, inlineStylesheet: C2, maskInputOptions: I2, maskInputFn: _2, dataURLOptions: O2, inlineImages: F2, recordCanvas: D2, keepIframeSrcFn: $2, newlyAddedElement: B2, rootId: U2 });
2618
2618
  case e.TEXT_NODE:
2619
2619
  return (function ji(e2, a2) {
@@ -2629,12 +2629,12 @@ function zi(e, a) {
2629
2629
  }
2630
2630
  C3 = Pt(C3, $t(a2.doc));
2631
2631
  }
2632
- return E3 && (C3 = "SCRIPT_PLACEHOLDER"), !I3 && !E3 && C3 && m3 && (C3 = w3 ? w3(C3, e2.parentElement) : C3.replace(/[\S]/g, "*")), { type: bt.Text, textContent: C3 || "", isStyle: I3, rootId: b3 };
2632
+ return E3 && (C3 = "SCRIPT_PLACEHOLDER"), !I3 && !E3 && C3 && m3 && (C3 = w3 ? w3(C3, e2.parentElement) : C3.replace(/[\S]/g, "*")), { type: St.Text, textContent: C3 || "", isStyle: I3, rootId: b3 };
2633
2633
  })(e, { doc: u, needsMask: x2, maskTextFn: E2, rootId: U2 });
2634
2634
  case e.CDATA_SECTION_NODE:
2635
- return { type: bt.CDATA, textContent: "", rootId: U2 };
2635
+ return { type: St.CDATA, textContent: "", rootId: U2 };
2636
2636
  case e.COMMENT_NODE:
2637
- return { type: bt.Comment, textContent: e.textContent || "", rootId: U2 };
2637
+ return { type: St.Comment, textContent: e.textContent || "", rootId: U2 };
2638
2638
  default:
2639
2639
  return false;
2640
2640
  }
@@ -2650,21 +2650,21 @@ function Se(e, a) {
2650
2650
  if (!ee2) return console.warn(e, "not serialized"), null;
2651
2651
  let te2;
2652
2652
  te2 = m2.hasNode(e) ? m2.getId(e) : (function Gi(e2, a2) {
2653
- return !!(a2.comment && e2.type === bt.Comment || e2.type === bt.Element && (a2.script && ("script" === e2.tagName || "link" === e2.tagName && ("preload" === e2.attributes.rel || "modulepreload" === e2.attributes.rel) && "script" === e2.attributes.as || "link" === e2.tagName && "prefetch" === e2.attributes.rel && "string" == typeof e2.attributes.href && "js" === xr(e2.attributes.href)) || a2.headFavicon && ("link" === e2.tagName && "shortcut icon" === e2.attributes.rel || "meta" === e2.tagName && (N(e2.attributes.name).match(/^msapplication-tile(image|color)$/) || "application-name" === N(e2.attributes.name) || "icon" === N(e2.attributes.rel) || "apple-touch-icon" === N(e2.attributes.rel) || "shortcut icon" === N(e2.attributes.rel))) || "meta" === e2.tagName && (a2.headMetaDescKeywords && N(e2.attributes.name).match(/^description|keywords$/) || a2.headMetaSocial && (N(e2.attributes.property).match(/^(og|twitter|fb):/) || N(e2.attributes.name).match(/^(og|twitter):/) || "pinterest" === N(e2.attributes.name)) || a2.headMetaRobots && ("robots" === N(e2.attributes.name) || "googlebot" === N(e2.attributes.name) || "bingbot" === N(e2.attributes.name)) || a2.headMetaHttpEquiv && void 0 !== e2.attributes["http-equiv"] || a2.headMetaAuthorship && ("author" === N(e2.attributes.name) || "generator" === N(e2.attributes.name) || "framework" === N(e2.attributes.name) || "publisher" === N(e2.attributes.name) || "progid" === N(e2.attributes.name) || N(e2.attributes.property).match(/^article:/) || N(e2.attributes.property).match(/^product:/)) || a2.headMetaVerification && ("google-site-verification" === N(e2.attributes.name) || "yandex-verification" === N(e2.attributes.name) || "csrf-token" === N(e2.attributes.name) || "p:domain_verify" === N(e2.attributes.name) || "verify-v1" === N(e2.attributes.name) || "verification" === N(e2.attributes.name) || "shopify-checkout-api-token" === N(e2.attributes.name)))));
2654
- })(ee2, D2) || !Q2 && ee2.type === bt.Text && !ee2.isStyle && !ee2.textContent.replace(/^\s+|\s+$/gm, "").length ? -2 : Ir();
2653
+ return !!(a2.comment && e2.type === St.Comment || e2.type === St.Element && (a2.script && ("script" === e2.tagName || "link" === e2.tagName && ("preload" === e2.attributes.rel || "modulepreload" === e2.attributes.rel) && "script" === e2.attributes.as || "link" === e2.tagName && "prefetch" === e2.attributes.rel && "string" == typeof e2.attributes.href && "js" === xr(e2.attributes.href)) || a2.headFavicon && ("link" === e2.tagName && "shortcut icon" === e2.attributes.rel || "meta" === e2.tagName && (N(e2.attributes.name).match(/^msapplication-tile(image|color)$/) || "application-name" === N(e2.attributes.name) || "icon" === N(e2.attributes.rel) || "apple-touch-icon" === N(e2.attributes.rel) || "shortcut icon" === N(e2.attributes.rel))) || "meta" === e2.tagName && (a2.headMetaDescKeywords && N(e2.attributes.name).match(/^description|keywords$/) || a2.headMetaSocial && (N(e2.attributes.property).match(/^(og|twitter|fb):/) || N(e2.attributes.name).match(/^(og|twitter):/) || "pinterest" === N(e2.attributes.name)) || a2.headMetaRobots && ("robots" === N(e2.attributes.name) || "googlebot" === N(e2.attributes.name) || "bingbot" === N(e2.attributes.name)) || a2.headMetaHttpEquiv && void 0 !== e2.attributes["http-equiv"] || a2.headMetaAuthorship && ("author" === N(e2.attributes.name) || "generator" === N(e2.attributes.name) || "framework" === N(e2.attributes.name) || "publisher" === N(e2.attributes.name) || "progid" === N(e2.attributes.name) || N(e2.attributes.property).match(/^article:/) || N(e2.attributes.property).match(/^product:/)) || a2.headMetaVerification && ("google-site-verification" === N(e2.attributes.name) || "yandex-verification" === N(e2.attributes.name) || "csrf-token" === N(e2.attributes.name) || "p:domain_verify" === N(e2.attributes.name) || "verify-v1" === N(e2.attributes.name) || "verification" === N(e2.attributes.name) || "shopify-checkout-api-token" === N(e2.attributes.name)))));
2654
+ })(ee2, D2) || !Q2 && ee2.type === St.Text && !ee2.isStyle && !ee2.textContent.replace(/^\s+|\s+$/gm, "").length ? -2 : Ir();
2655
2655
  const ne2 = Object.assign(ee2, { id: te2 });
2656
2656
  if (m2.add(e, ne2), -2 === te2) return null;
2657
2657
  j2 && j2(e);
2658
2658
  let re2 = !I2;
2659
- if (ne2.type === bt.Element) {
2659
+ if (ne2.type === St.Element) {
2660
2660
  re2 = re2 && !ne2.needBlock, delete ne2.needBlock;
2661
2661
  const a2 = e.shadowRoot;
2662
2662
  a2 && ze(a2) && (ne2.isShadowHost = true);
2663
2663
  }
2664
- if ((ne2.type === bt.Document || ne2.type === bt.Element) && re2) {
2665
- D2.headWhitespace && ne2.type === bt.Element && "head" === ne2.tagName && (Q2 = false);
2664
+ if ((ne2.type === St.Document || ne2.type === St.Element) && re2) {
2665
+ D2.headWhitespace && ne2.type === St.Element && "head" === ne2.tagName && (Q2 = false);
2666
2666
  const a2 = { doc: u, mirror: m2, blockClass: w2, blockSelector: b2, needsMask: X2, maskTextClass: x2, maskTextSelector: C2, skipChild: I2, inlineStylesheet: E2, maskInputOptions: _2, maskTextFn: O2, maskInputFn: F2, slimDOMOptions: D2, dataURLOptions: $2, inlineImages: B2, recordCanvas: U2, preserveWhiteSpace: Q2, onSerialize: j2, onIframeLoad: z2, iframeLoadTimeout: q2, onStylesheetLoad: V2, stylesheetLoadTimeout: H2, keepIframeSrcFn: J2 };
2667
- if (ne2.type !== bt.Element || "textarea" !== ne2.tagName || void 0 === ne2.attributes.value) for (const u2 of Array.from(e.childNodes)) {
2667
+ if (ne2.type !== St.Element || "textarea" !== ne2.tagName || void 0 === ne2.attributes.value) for (const u2 of Array.from(e.childNodes)) {
2668
2668
  const e2 = Se(u2, a2);
2669
2669
  e2 && ne2.childNodes.push(e2);
2670
2670
  }
@@ -2673,7 +2673,7 @@ function Se(e, a) {
2673
2673
  m3 && (ze(e.shadowRoot) && (m3.isShadow = true), ne2.childNodes.push(m3));
2674
2674
  }
2675
2675
  }
2676
- return e.parentNode && We(e.parentNode) && ze(e.parentNode) && (ne2.isShadow = true), ne2.type === bt.Element && "iframe" === ne2.tagName && (function _i(e2, a2, u2) {
2676
+ return e.parentNode && We(e.parentNode) && ze(e.parentNode) && (ne2.isShadow = true), ne2.type === St.Element && "iframe" === ne2.tagName && (function _i(e2, a2, u2) {
2677
2677
  const m3 = e2.contentWindow;
2678
2678
  if (!m3) return;
2679
2679
  let w3, b3 = false;
@@ -2699,7 +2699,7 @@ function Se(e, a) {
2699
2699
  const u2 = Se(a2, { doc: a2, mirror: m2, blockClass: w2, blockSelector: b2, needsMask: X2, maskTextClass: x2, maskTextSelector: C2, skipChild: false, inlineStylesheet: E2, maskInputOptions: _2, maskTextFn: O2, maskInputFn: F2, slimDOMOptions: D2, dataURLOptions: $2, inlineImages: B2, recordCanvas: U2, preserveWhiteSpace: Q2, onSerialize: j2, onIframeLoad: z2, iframeLoadTimeout: q2, onStylesheetLoad: V2, stylesheetLoadTimeout: H2, keepIframeSrcFn: J2 });
2700
2700
  u2 && z2(e, u2);
2701
2701
  }
2702
- }, q2), ne2.type === bt.Element && "link" === ne2.tagName && "string" == typeof ne2.attributes.rel && ("stylesheet" === ne2.attributes.rel || "preload" === ne2.attributes.rel && "string" == typeof ne2.attributes.href && "css" === xr(ne2.attributes.href)) && (function Wi(e2, a2, u2) {
2702
+ }, q2), ne2.type === St.Element && "link" === ne2.tagName && "string" == typeof ne2.attributes.rel && ("stylesheet" === ne2.attributes.rel || "preload" === ne2.attributes.rel && "string" == typeof ne2.attributes.href && "css" === xr(ne2.attributes.href)) && (function Wi(e2, a2, u2) {
2703
2703
  let m3, w3 = false;
2704
2704
  try {
2705
2705
  m3 = e2.sheet;
@@ -3121,7 +3121,7 @@ let gn = pn, yn = class extends gn {
3121
3121
  };
3122
3122
  var wn = yn;
3123
3123
  yn.default = yn;
3124
- let bn, Sn, In, Mn, En = mn, _n = wn, On = pn, { isClean: Tn, my: Ln } = on;
3124
+ let Sn, bn, In, Mn, En = mn, _n = wn, On = pn, { isClean: Tn, my: Ln } = on;
3125
3125
  function _r(e) {
3126
3126
  return e.map((e2) => (e2.nodes && (e2.nodes = _r(e2.nodes)), delete e2.source, e2));
3127
3127
  }
@@ -3180,7 +3180,7 @@ let Rn = class zr extends On {
3180
3180
  return this.markDirty(), this;
3181
3181
  }
3182
3182
  normalize(e, a) {
3183
- if ("string" == typeof e) e = _r(Sn(e).nodes);
3183
+ if ("string" == typeof e) e = _r(bn(e).nodes);
3184
3184
  else if (typeof e > "u") e = [];
3185
3185
  else if (Array.isArray(e)) {
3186
3186
  e = e.slice(0);
@@ -3193,7 +3193,7 @@ let Rn = class zr extends On {
3193
3193
  if (typeof e.value > "u") throw new Error("Value field is missed in node creation");
3194
3194
  "string" != typeof e.value && (e.value = String(e.value)), e = [new _n(e)];
3195
3195
  } else if (e.selector || e.selectors) e = [new Mn(e)];
3196
- else if (e.name) e = [new bn(e)];
3196
+ else if (e.name) e = [new Sn(e)];
3197
3197
  else {
3198
3198
  if (!e.text) throw new Error("Unknown node type in node creation");
3199
3199
  e = [new En(e)];
@@ -3275,17 +3275,17 @@ let Rn = class zr extends On {
3275
3275
  }
3276
3276
  };
3277
3277
  Rn.registerParse = (e) => {
3278
- Sn = e;
3278
+ bn = e;
3279
3279
  }, Rn.registerRule = (e) => {
3280
3280
  Mn = e;
3281
3281
  }, Rn.registerAtRule = (e) => {
3282
- bn = e;
3282
+ Sn = e;
3283
3283
  }, Rn.registerRoot = (e) => {
3284
3284
  In = e;
3285
3285
  };
3286
3286
  var An = Rn;
3287
3287
  Rn.default = Rn, Rn.rebuild = (e) => {
3288
- "atrule" === e.type ? Object.setPrototypeOf(e, bn.prototype) : "rule" === e.type ? Object.setPrototypeOf(e, Mn.prototype) : "decl" === e.type ? Object.setPrototypeOf(e, _n.prototype) : "comment" === e.type ? Object.setPrototypeOf(e, En.prototype) : "root" === e.type && Object.setPrototypeOf(e, In.prototype), e[Ln] = true, e.nodes && e.nodes.forEach((e2) => {
3288
+ "atrule" === e.type ? Object.setPrototypeOf(e, Sn.prototype) : "rule" === e.type ? Object.setPrototypeOf(e, Mn.prototype) : "decl" === e.type ? Object.setPrototypeOf(e, _n.prototype) : "comment" === e.type ? Object.setPrototypeOf(e, En.prototype) : "root" === e.type && Object.setPrototypeOf(e, In.prototype), e[Ln] = true, e.nodes && e.nodes.forEach((e2) => {
3289
3289
  Rn.rebuild(e2);
3290
3290
  });
3291
3291
  };
@@ -4302,8 +4302,8 @@ gs.registerPostcss = (e) => {
4302
4302
  };
4303
4303
  var ys = gs;
4304
4304
  gs.default = gs, is.registerLazyResult(gs), ns.registerLazyResult(gs);
4305
- let ws = ho, bs = Ko;
4306
- const Ss = Qo;
4305
+ let ws = ho, Ss = Ko;
4306
+ const bs = Qo;
4307
4307
  let vs = rn, xs = so, Is = class {
4308
4308
  get content() {
4309
4309
  return this.result.css;
@@ -4325,7 +4325,7 @@ let vs = rn, xs = so, Is = class {
4325
4325
  }
4326
4326
  get root() {
4327
4327
  if (this._root) return this._root;
4328
- let e, a = bs;
4328
+ let e, a = Ss;
4329
4329
  try {
4330
4330
  e = a(this._css, this._opts);
4331
4331
  } catch (e2) {
@@ -4340,7 +4340,7 @@ let vs = rn, xs = so, Is = class {
4340
4340
  constructor(e, a, u) {
4341
4341
  a = a.toString(), this.stringified = false, this._processor = e, this._css = a, this._opts = u, this._map = void 0;
4342
4342
  let m2, w2 = vs;
4343
- this.result = new Ss(this._processor, m2, this._opts), this.result.css = a;
4343
+ this.result = new bs(this._processor, m2, this._opts), this.result.css = a;
4344
4344
  let b2 = this;
4345
4345
  Object.defineProperty(this.result, "root", { get: () => b2.root });
4346
4346
  let x2 = new ws(w2, m2, this._opts, a);
@@ -4690,7 +4690,7 @@ class Vl {
4690
4690
  });
4691
4691
  }
4692
4692
  patchRootIdOnNode(e, a) {
4693
- e.type !== bt.Document && !e.rootId && (e.rootId = a), "childNodes" in e && e.childNodes.forEach((e2) => {
4693
+ e.type !== St.Document && !e.rootId && (e.rootId = a), "childNodes" in e && e.childNodes.forEach((e2) => {
4694
4694
  this.patchRootIdOnNode(e2, a);
4695
4695
  });
4696
4696
  }
@@ -5623,7 +5623,7 @@ try {
5623
5623
  console.debug("Unable to override Array.from", Ni2);
5624
5624
  }
5625
5625
  const ra = (function Ci() {
5626
- return new St();
5626
+ return new bt();
5627
5627
  })();
5628
5628
  function ae(e = {}) {
5629
5629
  const { emit: a, checkoutEveryNms: u, checkoutEveryNth: m2, blockClass: w2 = "rr-block", blockSelector: b2 = null, ignoreClass: x2 = "rr-ignore", ignoreSelector: C2 = null, maskTextClass: I2 = "rr-mask", maskTextSelector: E2 = null, inlineStylesheet: _2 = true, maskAllInputs: O2, maskInputOptions: F2, slimDOMOptions: D2, maskInputFn: $2, maskTextFn: B2, hooks: U2, packFn: j2, sampling: z2 = {}, dataURLOptions: q2 = {}, mousemoveWait: V2, recordDOM: H2 = true, recordCanvas: J2 = false, recordCrossOriginIframes: Y2 = false, recordAfter: X2 = "DOMContentLoaded" === e.recordAfter ? e.recordAfter : "load", userTriggeredOnInput: Q2 = false, collectFonts: ee2 = false, inlineImages: te2 = false, plugins: ne2, keepIframeSrcFn: re2 = () => false, ignoreCSSAttributes: oe2 = /* @__PURE__ */ new Set([]), errorHandler: se2 } = e;
@@ -5684,7 +5684,7 @@ function ae(e = {}) {
5684
5684
  if (!H2) return;
5685
5685
  Xi({ type: ci.Meta, data: { href: window.location.href, width: mo(), height: fo() } }, e2), me2.reset(), we2.init(), Mi.forEach((e3) => e3.lock());
5686
5686
  const a2 = (function Zi(e3, a3) {
5687
- const { mirror: u2 = new St(), blockClass: m3 = "rr-block", blockSelector: w3 = null, maskTextClass: b3 = "rr-mask", maskTextSelector: x3 = null, inlineStylesheet: C3 = true, inlineImages: I3 = false, recordCanvas: E3 = false, maskAllInputs: _3 = false, maskTextFn: O3, maskInputFn: F3, slimDOM: D3 = false, dataURLOptions: $3, preserveWhiteSpace: B3, onSerialize: U3, onIframeLoad: j3, iframeLoadTimeout: z3, onStylesheetLoad: q3, stylesheetLoadTimeout: V3, keepIframeSrcFn: H3 = () => false } = a3 || {};
5687
+ const { mirror: u2 = new bt(), blockClass: m3 = "rr-block", blockSelector: w3 = null, maskTextClass: b3 = "rr-mask", maskTextSelector: x3 = null, inlineStylesheet: C3 = true, inlineImages: I3 = false, recordCanvas: E3 = false, maskAllInputs: _3 = false, maskTextFn: O3, maskInputFn: F3, slimDOM: D3 = false, dataURLOptions: $3, preserveWhiteSpace: B3, onSerialize: U3, onIframeLoad: j3, iframeLoadTimeout: z3, onStylesheetLoad: q3, stylesheetLoadTimeout: V3, keepIframeSrcFn: H3 = () => false } = a3 || {};
5688
5688
  return Se(e3, { doc: e3, mirror: u2, blockClass: m3, blockSelector: w3, maskTextClass: b3, maskTextSelector: x3, skipChild: false, inlineStylesheet: C3, maskInputOptions: true === _3 ? { color: true, date: true, "datetime-local": true, email: true, month: true, number: true, range: true, search: true, tel: true, text: true, time: true, url: true, week: true, textarea: true, select: true, password: true } : false === _3 ? { password: true } : _3, maskTextFn: O3, maskInputFn: F3, slimDOMOptions: true === D3 || "all" === D3 ? { script: true, comment: true, headFavicon: true, headWhitespace: true, headMetaDescKeywords: "all" === D3, headMetaSocial: true, headMetaRobots: true, headMetaHttpEquiv: true, headMetaAuthorship: true, headMetaVerification: true } : false === D3 ? {} : D3, dataURLOptions: $3, inlineImages: I3, recordCanvas: E3, preserveWhiteSpace: B3, onSerialize: U3, onIframeLoad: j3, iframeLoadTimeout: z3, onStylesheetLoad: q3, stylesheetLoadTimeout: V3, keepIframeSrcFn: H3, newlyAddedElement: false });
5689
5689
  })(document, { mirror: ra, blockClass: w2, blockSelector: b2, maskTextClass: I2, maskTextSelector: E2, inlineStylesheet: _2, maskAllInputs: ce2, maskTextFn: B2, maskInputFn: $2, slimDOM: de2, dataURLOptions: q2, recordCanvas: J2, inlineImages: te2, onSerialize: (e3) => {
5690
5690
  wo(e3, ra) && ge2.addIframe(e3), bo(e3, ra) && me2.trackLinkElement(e3), Fs(e3) && we2.addShadowRoot(e3.shadowRoot, document);
@@ -5957,7 +5957,7 @@ var ya = zs;
5957
5957
  zs.default = zs;
5958
5958
  var wa = {};
5959
5959
  wa.isClean = Symbol("isClean"), wa.my = Symbol("my");
5960
- let ba = pa, Sa = ma, va = ya, { isClean: ka, my: xa } = wa;
5960
+ let Sa = pa, ba = ma, va = ya, { isClean: ka, my: xa } = wa;
5961
5961
  function Bs(e, a) {
5962
5962
  let u = new e.constructor();
5963
5963
  for (let m2 in e) {
@@ -6028,7 +6028,7 @@ let Ca = class {
6028
6028
  let { end: u, start: m2 } = this.rangeBy(a);
6029
6029
  return this.source.input.error(e, { column: m2.column, line: m2.line }, { column: u.column, line: u.line }, a);
6030
6030
  }
6031
- return new ba(e);
6031
+ return new Sa(e);
6032
6032
  }
6033
6033
  getProxyProcessor() {
6034
6034
  return { get: (e, a) => "proxyOf" === a ? e : "root" === a ? () => e.root().toProxy() : e[a], set: (e, a, u) => (e[a] === u || (e[a] = u, ("prop" === a || "value" === a || "name" === a || "params" === a || "important" === a || "text" === a) && e.markDirty()), true) };
@@ -6076,7 +6076,7 @@ let Ca = class {
6076
6076
  return (u.line < a.line || u.line === a.line && u.column <= a.column) && (u = { column: a.column + 1, line: a.line }), { end: u, start: a };
6077
6077
  }
6078
6078
  raw(e, a) {
6079
- return new Sa().raw(this, e, a);
6079
+ return new ba().raw(this, e, a);
6080
6080
  }
6081
6081
  remove() {
6082
6082
  return this.parent && this.parent.removeChild(this), this.parent = void 0, this;
@@ -6417,13 +6417,13 @@ let il = class {
6417
6417
  };
6418
6418
  var al = il;
6419
6419
  il.default = il;
6420
- let { nanoid: ll } = Qa, { isAbsolute: cl, resolve: ul } = aa, { SourceMapConsumer: dl, SourceMapGenerator: pl } = aa, { fileURLToPath: hl, pathToFileURL: fl } = aa, ml = pa, gl = al, yl = aa, wl = Symbol("fromOffsetCache"), bl = !(!dl || !pl), Sl = !(!ul || !cl), vl = class {
6420
+ let { nanoid: ll } = Qa, { isAbsolute: cl, resolve: ul } = aa, { SourceMapConsumer: dl, SourceMapGenerator: pl } = aa, { fileURLToPath: hl, pathToFileURL: fl } = aa, ml = pa, gl = al, yl = aa, wl = Symbol("fromOffsetCache"), Sl = !(!dl || !pl), bl = !(!ul || !cl), vl = class {
6421
6421
  get from() {
6422
6422
  return this.file || this.id;
6423
6423
  }
6424
6424
  constructor(e, a = {}) {
6425
6425
  if (null === e || typeof e > "u" || "object" == typeof e && !e.toString) throw new Error(`PostCSS received ${e} instead of CSS string`);
6426
- if (this.css = e.toString(), "\uFEFF" === this.css[0] || "￾" === this.css[0] ? (this.hasBOM = true, this.css = this.css.slice(1)) : this.hasBOM = false, this.document = this.css, a.document && (this.document = a.document.toString()), a.from && (!Sl || /^\w+:\/\//.test(a.from) || cl(a.from) ? this.file = a.from : this.file = ul(a.from)), Sl && bl) {
6426
+ if (this.css = e.toString(), "\uFEFF" === this.css[0] || "￾" === this.css[0] ? (this.hasBOM = true, this.css = this.css.slice(1)) : this.hasBOM = false, this.document = this.css, a.document && (this.document = a.document.toString()), a.from && (!bl || /^\w+:\/\//.test(a.from) || cl(a.from) ? this.file = a.from : this.file = ul(a.from)), bl && Sl) {
6427
6427
  let e2 = new gl(this.css, a);
6428
6428
  if (e2.text) {
6429
6429
  this.map = e2;
@@ -6706,8 +6706,8 @@ var mc = class {
6706
6706
  return this.memoizedURLs.set(e, u), u;
6707
6707
  }
6708
6708
  };
6709
- const gc = /[\t\n\f\r "#'()/;[\\\]{}]/g, yc = /[\t\n\f\r !"#'():;@[\\\]{}]|\/(?=\*)/g, wc = /.[\r\n"'(/\\]/, bc = /[\da-f]/i;
6710
- let Sc = qa, vc = _a, xc = La, Ic = El, Mc = Nl, kc = function(e, a = {}) {
6709
+ const gc = /[\t\n\f\r "#'()/;[\\\]{}]/g, yc = /[\t\n\f\r !"#'():;@[\\\]{}]|\/(?=\*)/g, wc = /.[\r\n"'(/\\]/, Sc = /[\da-f]/i;
6710
+ let bc = qa, vc = _a, xc = La, Ic = El, Mc = Nl, kc = function(e, a = {}) {
6711
6711
  let u, m2, w2, b2, x2, C2, I2, E2, _2, O2, F2 = e.css.valueOf(), D2 = a.ignoreErrors, $2 = F2.length, B2 = 0, U2 = [], j2 = [];
6712
6712
  function y2(a2) {
6713
6713
  throw e.error("Unclosed " + a2, B2);
@@ -6779,8 +6779,8 @@ let Sc = qa, vc = _a, xc = La, Ic = El, Mc = Nl, kc = function(e, a = {}) {
6779
6779
  break;
6780
6780
  case 92:
6781
6781
  for (b2 = B2, w2 = true; 92 === F2.charCodeAt(b2 + 1); ) b2 += 1, w2 = !w2;
6782
- if (u = F2.charCodeAt(b2 + 1), w2 && 47 !== u && 32 !== u && 10 !== u && 9 !== u && 13 !== u && 12 !== u && (b2 += 1, bc.test(F2.charAt(b2)))) {
6783
- for (; bc.test(F2.charAt(b2 + 1)); ) b2 += 1;
6782
+ if (u = F2.charCodeAt(b2 + 1), w2 && 47 !== u && 32 !== u && 10 !== u && 9 !== u && 13 !== u && 12 !== u && (b2 += 1, Sc.test(F2.charAt(b2)))) {
6783
+ for (; Sc.test(F2.charAt(b2 + 1)); ) b2 += 1;
6784
6784
  32 === F2.charCodeAt(b2 + 1) && (b2 += 1);
6785
6785
  }
6786
6786
  C2 = ["word", F2.slice(B2, b2 + 1), B2, b2], B2 = b2;
@@ -6799,7 +6799,7 @@ var _c = class {
6799
6799
  this.input = e, this.root = new Ic(), this.current = this.root, this.spaces = "", this.semicolon = false, this.createTokenizer(), this.root.source = { input: e, start: { column: 1, line: 1, offset: 0 } };
6800
6800
  }
6801
6801
  atrule(e) {
6802
- let a = new Sc();
6802
+ let a = new bc();
6803
6803
  a.name = e[1].slice(1), "" === a.name && this.unnamedAtrule(a, e), this.init(a, e[2]);
6804
6804
  let u, m2, w2, b2 = false, x2 = false, C2 = [], I2 = [];
6805
6805
  for (; !this.tokenizer.endOfFile(); ) {
@@ -7621,10 +7621,10 @@ function R(e, a, u) {
7621
7621
  };
7622
7622
  }
7623
7623
  }
7624
- var hd = ((e) => (e[e.DomContentLoaded = 0] = "DomContentLoaded", e[e.Load = 1] = "Load", e[e.FullSnapshot = 2] = "FullSnapshot", e[e.IncrementalSnapshot = 3] = "IncrementalSnapshot", e[e.Meta = 4] = "Meta", e[e.Custom = 5] = "Custom", e[e.Plugin = 6] = "Plugin", e[e.Device = 24] = "Device", e[e.SailfishCustom = 25] = "SailfishCustom", e))(hd || {});
7625
- const fd = ["/node_modules/", "/@sailfish-ai/", "/@sailfish-rrweb/", "/dist/", "/webpack/", "/vite/", "/__vite", "/react-dom/", "/react/", "/scheduler/", "/<", "/chrome-extension://", "/extensions/"];
7624
+ var hd = ((e) => (e[e.DomContentLoaded = 0] = "DomContentLoaded", e[e.Load = 1] = "Load", e[e.FullSnapshot = 2] = "FullSnapshot", e[e.IncrementalSnapshot = 3] = "IncrementalSnapshot", e[e.Meta = 4] = "Meta", e[e.Custom = 5] = "Custom", e[e.Plugin = 6] = "Plugin", e[e.Device = 24] = "Device", e[e.SailfishCustom = 25] = "SailfishCustom", e))(hd || {}), fd = ((e) => (e[e.Mutation = 0] = "Mutation", e[e.MouseMove = 1] = "MouseMove", e[e.MouseInteraction = 2] = "MouseInteraction", e[e.Scroll = 3] = "Scroll", e[e.ViewportResize = 4] = "ViewportResize", e[e.Input = 5] = "Input", e[e.TouchMove = 6] = "TouchMove", e[e.MediaInteraction = 7] = "MediaInteraction", e[e.StyleSheetRule = 8] = "StyleSheetRule", e[e.CanvasMutation = 9] = "CanvasMutation", e[e.Font = 10] = "Font", e[e.Log = 11] = "Log", e[e.Drag = 12] = "Drag", e[e.StyleDeclaration = 13] = "StyleDeclaration", e[e.Selection = 14] = "Selection", e[e.AdoptedStyleSheet = 15] = "AdoptedStyleSheet", e[e.CustomElement = 16] = "CustomElement", e[e.Typing = 17] = "Typing", e))(fd || {});
7625
+ const md = ["/node_modules/", "/@sailfish-ai/", "/@sailfish-rrweb/", "/dist/", "/webpack/", "/vite/", "/__vite", "/react-dom/", "/react/", "/scheduler/", "/<", "/chrome-extension://", "/extensions/"];
7626
7626
  function shouldSkipFrame(e) {
7627
- return fd.some((a) => e.includes(a));
7627
+ return md.some((a) => e.includes(a));
7628
7628
  }
7629
7629
  function normalizeFilePath(e) {
7630
7630
  let a = e;
@@ -7686,7 +7686,7 @@ function suppressConsoleLogsDuringCall(e) {
7686
7686
  console.log = a, console.warn = u, console.error = m2;
7687
7687
  }
7688
7688
  }
7689
- const md = "zendesk_chat", gd = "Zendesk";
7689
+ const gd = "zendesk_chat", yd = "Zendesk";
7690
7690
  function zE_safe(...e) {
7691
7691
  try {
7692
7692
  if ((function hasZendesk() {
@@ -7732,13 +7732,42 @@ function initializeConsolePlugin(e, a) {
7732
7732
  async function initializeRecording(e, a, u, m2, w2) {
7733
7733
  const b2 = initializeWebSocket(a, u, m2, w2);
7734
7734
  try {
7735
+ const a2 = (function createThrottledEmit(e2, a3 = 1e3) {
7736
+ if (!e2) return { emit: (e3) => sendEvent(e3), flush: () => {
7737
+ } };
7738
+ const u2 = /* @__PURE__ */ new Map();
7739
+ let m3 = null;
7740
+ return { emit: (e3) => {
7741
+ var _a2, _b;
7742
+ const w3 = (_a2 = e3.data) == null ? void 0 : _a2.source;
7743
+ if (3 !== e3.type || 0 !== w3 && 5 !== w3) return void sendEvent(e3);
7744
+ const b3 = `3:${w3}:${((_b = e3.data) == null ? void 0 : _b.id) || "unknown"}`;
7745
+ u2.set(b3, e3), m3 || (m3 = setInterval(() => {
7746
+ 0 !== u2.size && (u2.forEach((e4) => sendEvent(e4)), u2.clear());
7747
+ }, a3));
7748
+ }, flush: () => {
7749
+ u2.size > 0 && (u2.forEach((e3) => sendEvent(e3)), u2.clear()), m3 && (clearInterval(m3), m3 = null);
7750
+ } };
7751
+ })(e.textEditThrottleEnabled), emitWithContext = (e2) => {
7752
+ Object.assign(e2, getUrlAndStoredUuids()), e2.sessionId = m2, a2.emit(e2);
7753
+ };
7735
7754
  ae({ emit(e2) {
7736
- Object.assign(e2, getUrlAndStoredUuids()), e2.sessionId = m2, sendEvent(e2);
7737
- }, maskInputOptions: { text: true }, maskInputFn, maskTextClass: "sailfishSanitize", ...e }), (function whenZendeskReady(e2) {
7755
+ emitWithContext(e2);
7756
+ }, maskInputOptions: { text: true }, maskInputFn, maskTextClass: "sailfishSanitize", ...e });
7757
+ const textareaInputHandler = (e2) => {
7758
+ var _a2, _b;
7759
+ const a3 = e2.target;
7760
+ if (!a3 || "TEXTAREA" !== a3.tagName) return;
7761
+ const u2 = (_b = (_a2 = ae.mirror) == null ? void 0 : _a2.getId) == null ? void 0 : _b.call(_a2, a3);
7762
+ "number" != typeof u2 || u2 < 0 || emitWithContext({ type: hd.IncrementalSnapshot, data: { source: fd.Input, id: u2, text: a3.value, isChecked: false, userTriggered: true, masked: false }, timestamp: Date.now() });
7763
+ };
7764
+ document.addEventListener("input", textareaInputHandler), window.addEventListener("beforeunload", () => {
7765
+ a2.flush(), document.removeEventListener("input", textareaInputHandler);
7766
+ }), (function whenZendeskReady(e2) {
7738
7767
  if ("undefined" == typeof window) return;
7739
- const a2 = window.zE;
7740
- if ("function" == typeof a2) try {
7741
- a2(e2);
7768
+ const a3 = window.zE;
7769
+ if ("function" == typeof a3) try {
7770
+ a3(e2);
7742
7771
  } catch {
7743
7772
  }
7744
7773
  })(() => {
@@ -7746,11 +7775,11 @@ async function initializeRecording(e, a, u, m2, w2) {
7746
7775
  zE_safe("messenger:set", "conversationTags", [`sailfish-session-${m2}`]);
7747
7776
  });
7748
7777
  const handleWidgetOpen = () => {
7749
- ae.addSailfishEvent(hd.SailfishCustom, { action: "customer support chat opened", element_id: md, provider: gd });
7778
+ ae.addSailfishEvent(hd.SailfishCustom, { action: "customer support chat opened", element_id: gd, provider: yd });
7750
7779
  }, handleWidgetClose = () => {
7751
- ae.addSailfishEvent(hd.SailfishCustom, { action: "customer support chat closed", element_id: md, provider: gd });
7780
+ ae.addSailfishEvent(hd.SailfishCustom, { action: "customer support chat closed", element_id: gd, provider: yd });
7752
7781
  }, handleUnreadMessages = (e2) => {
7753
- ae.addSailfishEvent(hd.SailfishCustom, { action: "zendesk unreadmessages", element_id: md, provider: gd });
7782
+ ae.addSailfishEvent(hd.SailfishCustom, { action: "zendesk unreadmessages", element_id: gd, provider: yd });
7754
7783
  };
7755
7784
  suppressConsoleLogsDuringCall(() => {
7756
7785
  zE_safe("messenger:on", "open", handleWidgetOpen), zE_safe("messenger:on", "close", handleWidgetClose), zE_safe("messenger:on", "unreadMessages", handleUnreadMessages);
@@ -7761,8 +7790,8 @@ async function initializeRecording(e, a, u, m2, w2) {
7761
7790
  }
7762
7791
  return b2;
7763
7792
  }
7764
- let yd = null, wd = null;
7765
- const bd = readDebugFlag(), Sd = ["t.co", "*.twitter.com", "*.gravatar.com", "*.googleapis.com", "*.amazonaws.com", "*.smooch.io", "*.zendesk.com", "*.zdassets.com"], vd = [400, 403], kd = "CORS", xd = { recordCanvas: false, recordCrossOriginIframes: false, collectFonts: false, inlineImages: false, recordPassword: false, recordRealName: true, recordCreditCardInfo: false, recordSsn: false, recordDob: false, sampling: {} }, Cd = { level: ["info", "log", "warn", "error"], lengthThreshold: 1e4, stringifyOptions: { stringLengthLimit: 1e3, numOfKeysLimit: 20, depthOfLimit: 4 }, logger: "console" };
7793
+ let wd = null, Sd = null;
7794
+ const bd = readDebugFlag(), vd = ["t.co", "*.twitter.com", "*.gravatar.com", "*.googleapis.com", "*.amazonaws.com", "*.smooch.io", "*.zendesk.com", "*.zdassets.com"], kd = [400, 403], xd = "CORS", Cd = { recordCanvas: false, recordCrossOriginIframes: false, collectFonts: false, inlineImages: false, recordPassword: false, recordRealName: true, recordCreditCardInfo: false, recordSsn: false, recordDob: false, sampling: {} }, Id = { level: ["info", "log", "warn", "error"], lengthThreshold: 1e4, stringifyOptions: { stringLengthLimit: 1e3, numOfKeysLimit: 20, depthOfLimit: 4 }, logger: "console" };
7766
7795
  function trackDomainChangesOnce() {
7767
7796
  const e = window.__sailfish_recorder || (window.__sailfish_recorder = {});
7768
7797
  if (e.routeWatcherIntervalId) return;
@@ -7829,7 +7858,7 @@ function shouldSkipHeadersPropagation(e, a = []) {
7829
7858
  return true;
7830
7859
  }
7831
7860
  for (const e2 of O) if (u.pathname.toLowerCase().endsWith(e2)) return true;
7832
- return !!matchUrlWithWildcard(e, [...Sd, ...a]);
7861
+ return !!matchUrlWithWildcard(e, [...vd, ...a]);
7833
7862
  }
7834
7863
  function setupFetchInterceptor(e = []) {
7835
7864
  const a = window.fetch, u = getOrSetSessionId();
@@ -7883,7 +7912,7 @@ function setupFetchInterceptor(e = []) {
7883
7912
  return _3.set(b, `${w4}/${x4}/${C4}`), I4 && (_3.set(I4.name, I4.value), bd && console.log("[Sailfish] Added funcspan header to HTTP fetch:", { url: "string" == typeof u3 ? u3 : u3.href, header: I4.name })), E3.headers = _3, await e3.call(a4, u3, E3);
7884
7913
  }
7885
7914
  })(e2, a3, m3, w3, x3, E2.page_visit_uuid, I3), B2 = false;
7886
- vd.includes($3.status) && (bd && console.log("Perform retry as status was fail:", $3), I3 = v4(), $3 = await (async function retryWithoutPropagateHeaders(e3, a4, u3, m4) {
7915
+ kd.includes($3.status) && (bd && console.log("Perform retry as status was fail:", $3), I3 = v4(), $3 = await (async function retryWithoutPropagateHeaders(e3, a4, u3, m4) {
7887
7916
  try {
7888
7917
  let m5 = u3[0], w4 = u3[1] || {};
7889
7918
  if ("string" == typeof m5 || m5 instanceof URL) {
@@ -7921,7 +7950,7 @@ function setupFetchInterceptor(e = []) {
7921
7950
  return sendEvent({ type: 27, timestamp: U2, sessionId: x3, data: { request_id: I3, session_id: x3, timestamp_start: O2, timestamp_end: U2, response_code: j2, success: z2, error: q2, method: _2, url: C3, retry_without_trace_id: B2, request_headers: D2, request_body: F2, response_headers: H2, response_body: V2 }, ...E2 }), $3;
7922
7951
  } catch (m4) {
7923
7952
  const w4 = Date.now(), b2 = false, $3 = ((_b = m4.response) == null ? void 0 : _b.status) || 500, B2 = m4.message || "Fetch request failed";
7924
- if (m4 instanceof TypeError && ((_c2 = m4 == null ? void 0 : m4.message) == null ? void 0 : _c2.toLowerCase().includes(kd.toLowerCase()))) return e2.apply(a3, u2);
7953
+ if (m4 instanceof TypeError && ((_c2 = m4 == null ? void 0 : m4.message) == null ? void 0 : _c2.toLowerCase().includes(xd.toLowerCase()))) return e2.apply(a3, u2);
7925
7954
  throw sendEvent({ type: 27, timestamp: w4, sessionId: x3, data: { request_id: I3, session_id: x3, timestamp_start: O2, timestamp_end: w4, response_code: $3, success: b2, error: B2, method: _2, url: C3, request_headers: D2, request_body: F2, response_body: null }, ...E2 }), m4;
7926
7955
  }
7927
7956
  })(a2, m2, w2, C2, I2, u, x2);
@@ -7955,7 +7984,7 @@ async function startRecording({ apiKey: e, backendApi: a = "https://api-service.
7955
7984
  })(), D2 = getOrSetSessionId(), $2 = window.__sailfish_recorder || (window.__sailfish_recorder = {});
7956
7985
  if ($2.sessionId = D2, $2.apiKey = e, $2.backendApi = a, $2.serviceAdditionalMetadata = I2, $2.initialized && $2.sessionId === D2 && $2.ws && 1 === $2.ws.readyState) trackDomainChangesOnce();
7957
7986
  else {
7958
- $2.domEventsInit || (initializeDomContentEvents(D2), $2.domEventsInit = true), $2.consoleInit || (initializeConsolePlugin(Cd, D2), $2.consoleInit = true), $2.errorInit || (!(function initializeErrorInterceptor() {
7987
+ $2.domEventsInit || (initializeDomContentEvents(D2), $2.domEventsInit = true), $2.consoleInit || (initializeConsolePlugin(Id, D2), $2.consoleInit = true), $2.errorInit || (!(function initializeErrorInterceptor() {
7959
7988
  window.addEventListener("error", (e2) => {
7960
7989
  captureError(e2.error || e2.message);
7961
7990
  }), window.addEventListener("unhandledrejection", (e2) => {
@@ -7968,7 +7997,7 @@ async function startRecording({ apiKey: e, backendApi: a = "https://api-service.
7968
7997
  ((_a3 = e2.data) == null ? void 0 : _a3.isFunctionSpanTrackingEnabledFromApiKey) ?? false ? bd && console.log("[Sailfish] Function span tracking state validated with backend: ACTIVE") : (clearStaleFuncSpanState(), bd && console.log("[Sailfish] Cleared stale function span tracking state - backend validation shows tracking is not active"));
7969
7998
  }).catch((e2) => {
7970
7999
  bd && console.warn("[Sailfish] Failed to validate function span tracking status with backend:", e2);
7971
- }), $2.sentDoNotPropagateOnce || (sendDomainsToNotPropagateHeaderTo(e, [...m2, ...Sd], a).catch((e2) => console.error("Failed to send domains to not propagate header to:", e2)), $2.sentDoNotPropagateOnce = true), $2.xhrPatched || (!(function setupXMLHttpRequestInterceptor(e2 = []) {
8000
+ }), $2.sentDoNotPropagateOnce || (sendDomainsToNotPropagateHeaderTo(e, [...m2, ...vd], a).catch((e2) => console.error("Failed to send domains to not propagate header to:", e2)), $2.sentDoNotPropagateOnce = true), $2.xhrPatched || (!(function setupXMLHttpRequestInterceptor(e2 = []) {
7972
8001
  const a2 = XMLHttpRequest.prototype.open, u2 = XMLHttpRequest.prototype.send, m3 = XMLHttpRequest.prototype.setRequestHeader, w3 = getOrSetSessionId();
7973
8002
  XMLHttpRequest.prototype.setRequestHeader = function(e3, a3) {
7974
8003
  return this._capturedRequestHeaders || (this._capturedRequestHeaders = {}), this._capturedRequestHeaders[e3] = a3, m3.call(this, e3, a3);
@@ -8032,7 +8061,7 @@ async function startRecording({ apiKey: e, backendApi: a = "https://api-service.
8032
8061
  sendMessage({ type: "deviceInfo", data: { deviceInfo: { language: navigator.language, userAgent: navigator.userAgent } } });
8033
8062
  })();
8034
8063
  try {
8035
- const u2 = await fetchCaptureSettings(e, a), m3 = ((_a2 = u2.data) == null ? void 0 : _a2.captureSettingsFromApiKey) || xd;
8064
+ const u2 = await fetchCaptureSettings(e, a), m3 = ((_a2 = u2.data) == null ? void 0 : _a2.captureSettingsFromApiKey) || Cd;
8036
8065
  if ($2.ws && 1 === $2.ws.readyState) return;
8037
8066
  const b2 = withAppUrlMetadata(I2), C3 = await startRecordingSession(e, D2, a, _2, O2, F2, E2, "JS/TS", b2);
8038
8067
  if ((_b = C3.data) == null ? void 0 : _b.startRecordingSession) {
@@ -8076,12 +8105,12 @@ H && (!(function sendUserDeviceUuid() {
8076
8105
  }), H && window.addEventListener("beforeunload", () => {
8077
8106
  clearPageVisitDataFromSessionStorage();
8078
8107
  });
8079
- exports.DEFAULT_CAPTURE_SETTINGS = xd, exports.DEFAULT_CONSOLE_RECORDING_SETTINGS = Cd, exports.STORAGE_VERSION = 1, exports.addOrUpdateMetadata = function addOrUpdateMetadata(e) {
8108
+ exports.DEFAULT_CAPTURE_SETTINGS = Cd, exports.DEFAULT_CONSOLE_RECORDING_SETTINGS = Id, exports.STORAGE_VERSION = 1, exports.addOrUpdateMetadata = function addOrUpdateMetadata(e) {
8080
8109
  const a = { type: "addOrUpdateMetadata", metadata: e };
8081
- wd && JSON.stringify(wd) === JSON.stringify(e) || (wd = e, sendMessage(a));
8110
+ Sd && JSON.stringify(Sd) === JSON.stringify(e) || (Sd = e, sendMessage(a));
8082
8111
  }, exports.buildBatches = buildBatches, exports.clearStaleFuncSpanState = clearStaleFuncSpanState, exports.createTriageAndIssueFromRecorder = createTriageAndIssueFromRecorder, exports.createTriageFromRecorder = createTriageFromRecorder, exports.disableFunctionSpanTracking = disableFunctionSpanTracking, exports.enableFunctionSpanTracking = enableFunctionSpanTracking, exports.eventSize = eventSize, exports.fetchCaptureSettings = fetchCaptureSettings, exports.fetchEngineeringTicketPlatformIntegrations = fetchEngineeringTicketPlatformIntegrations, exports.fetchFunctionSpanTrackingEnabled = fetchFunctionSpanTrackingEnabled, exports.flushBufferedEvents = flushBufferedEvents, exports.getFuncSpanHeader = getFuncSpanHeader, exports.getOrSetSessionId = getOrSetSessionId, exports.getUrlAndStoredUuids = getUrlAndStoredUuids, exports.identify = function identify(e, a = {}, u = false) {
8083
8112
  const m2 = { type: "identify", userId: e, traits: a };
8084
- yd && yd.userId === e && JSON.stringify(yd.traits) === JSON.stringify(a) || (yd = { userId: e, traits: a, overwrite: u }, sendMessage(m2));
8113
+ wd && wd.userId === e && JSON.stringify(wd.traits) === JSON.stringify(a) || (wd = { userId: e, traits: a, overwrite: u }, sendMessage(m2));
8085
8114
  }, exports.initRecorder = async (e) => {
8086
8115
  if ("undefined" == typeof window) return;
8087
8116
  const a = window.__sailfish_recorder || (window.__sailfish_recorder = {}), u = getOrSetSessionId();
package/dist/recorder.js CHANGED
@@ -465,7 +465,7 @@ function initializeWebSocket(e, a, u, m2) {
465
465
  const a2 = document.createElement("a");
466
466
  return a2.href = e2, `${a2.hostname}${a2.port ? `:${a2.port}` : ""}`;
467
467
  })(e);
468
- let b2 = `${"https:" === new URL(e).protocol ? "wss" : "ws"}://${w2}/ws/notify/?apiKey=${a}&sessionId=${u}&sender=JS%2FTS&version=1.8.19`;
468
+ let b2 = `${"https:" === new URL(e).protocol ? "wss" : "ws"}://${w2}/ws/notify/?apiKey=${a}&sessionId=${u}&sender=JS%2FTS&version=1.8.21-alpha5`;
469
469
  m2 && (b2 += `&envValue=${encodeURIComponent(m2)}`);
470
470
  return se = new U(b2, [], { connectionTimeout: 3e4 }), se.addEventListener("open", () => {
471
471
  re && (console.log("[Sailfish] WebSocket connection opened"), console.log("[Sailfish] Function span tracking state: " + (de ? "ENABLED" : "DISABLED"))), (async () => {
@@ -1294,7 +1294,7 @@ function sendGraphQLRequest(e, a, u, m2 = 5, w2 = 2e3, b2 = 2) {
1294
1294
  }), "Sending GraphQL request to Sailfish AI", m2, w2, b2);
1295
1295
  }
1296
1296
  function fetchCaptureSettings(e, a) {
1297
- return sendGraphQLRequest("GetCaptureSettingsFromApiKey", "\n query GetCaptureSettingsFromApiKey($apiKey: String!) {\n captureSettingsFromApiKey(apiKey: $apiKey) {\n recordCanvas\n recordCrossOriginIframes\n collectFonts\n inlineImages\n recordPassword\n recordRealName\n recordCreditCardInfo\n recordSsn\n recordDob\n sampling\n }\n }\n ", { apiKey: e, backendApi: a });
1297
+ return sendGraphQLRequest("GetCaptureSettingsFromApiKey", "\n query GetCaptureSettingsFromApiKey($apiKey: String!) {\n captureSettingsFromApiKey(apiKey: $apiKey) {\n recordCanvas\n recordCrossOriginIframes\n collectFonts\n inlineImages\n recordPassword\n recordRealName\n recordCreditCardInfo\n recordSsn\n recordDob\n sampling\n textEditThrottleEnabled\n }\n }\n ", { apiKey: e, backendApi: a });
1298
1298
  }
1299
1299
  function fetchFunctionSpanTrackingEnabled(e, a) {
1300
1300
  return sendGraphQLRequest("GetFunctionSpanTrackingEnabledFromApiKey", "\n query GetFunctionSpanTrackingEnabledFromApiKey($apiKey: String!) {\n isFunctionSpanTrackingEnabledFromApiKey(apiKey: $apiKey)\n }\n ", { apiKey: e, backendApi: a });
@@ -7624,10 +7624,10 @@ function R(e, a, u) {
7624
7624
  };
7625
7625
  }
7626
7626
  }
7627
- var fd = ((e) => (e[e.DomContentLoaded = 0] = "DomContentLoaded", e[e.Load = 1] = "Load", e[e.FullSnapshot = 2] = "FullSnapshot", e[e.IncrementalSnapshot = 3] = "IncrementalSnapshot", e[e.Meta = 4] = "Meta", e[e.Custom = 5] = "Custom", e[e.Plugin = 6] = "Plugin", e[e.Device = 24] = "Device", e[e.SailfishCustom = 25] = "SailfishCustom", e))(fd || {});
7628
- const md = ["/node_modules/", "/@sailfish-ai/", "/@sailfish-rrweb/", "/dist/", "/webpack/", "/vite/", "/__vite", "/react-dom/", "/react/", "/scheduler/", "/<", "/chrome-extension://", "/extensions/"];
7627
+ var fd = ((e) => (e[e.DomContentLoaded = 0] = "DomContentLoaded", e[e.Load = 1] = "Load", e[e.FullSnapshot = 2] = "FullSnapshot", e[e.IncrementalSnapshot = 3] = "IncrementalSnapshot", e[e.Meta = 4] = "Meta", e[e.Custom = 5] = "Custom", e[e.Plugin = 6] = "Plugin", e[e.Device = 24] = "Device", e[e.SailfishCustom = 25] = "SailfishCustom", e))(fd || {}), md = ((e) => (e[e.Mutation = 0] = "Mutation", e[e.MouseMove = 1] = "MouseMove", e[e.MouseInteraction = 2] = "MouseInteraction", e[e.Scroll = 3] = "Scroll", e[e.ViewportResize = 4] = "ViewportResize", e[e.Input = 5] = "Input", e[e.TouchMove = 6] = "TouchMove", e[e.MediaInteraction = 7] = "MediaInteraction", e[e.StyleSheetRule = 8] = "StyleSheetRule", e[e.CanvasMutation = 9] = "CanvasMutation", e[e.Font = 10] = "Font", e[e.Log = 11] = "Log", e[e.Drag = 12] = "Drag", e[e.StyleDeclaration = 13] = "StyleDeclaration", e[e.Selection = 14] = "Selection", e[e.AdoptedStyleSheet = 15] = "AdoptedStyleSheet", e[e.CustomElement = 16] = "CustomElement", e[e.Typing = 17] = "Typing", e))(md || {});
7628
+ const gd = ["/node_modules/", "/@sailfish-ai/", "/@sailfish-rrweb/", "/dist/", "/webpack/", "/vite/", "/__vite", "/react-dom/", "/react/", "/scheduler/", "/<", "/chrome-extension://", "/extensions/"];
7629
7629
  function shouldSkipFrame(e) {
7630
- return md.some((a) => e.includes(a));
7630
+ return gd.some((a) => e.includes(a));
7631
7631
  }
7632
7632
  function normalizeFilePath(e) {
7633
7633
  let a = e;
@@ -7689,7 +7689,7 @@ function suppressConsoleLogsDuringCall(e) {
7689
7689
  console.log = a, console.warn = u, console.error = m2;
7690
7690
  }
7691
7691
  }
7692
- const gd = "zendesk_chat", yd = "Zendesk";
7692
+ const yd = "zendesk_chat", wd = "Zendesk";
7693
7693
  function zE_safe(...e) {
7694
7694
  try {
7695
7695
  if ((function hasZendesk() {
@@ -7735,13 +7735,42 @@ function initializeConsolePlugin(e, a) {
7735
7735
  async function initializeRecording(e, a, u, m2, w2) {
7736
7736
  const b2 = initializeWebSocket(a, u, m2, w2);
7737
7737
  try {
7738
+ const a2 = (function createThrottledEmit(e2, a3 = 1e3) {
7739
+ if (!e2) return { emit: (e3) => sendEvent(e3), flush: () => {
7740
+ } };
7741
+ const u2 = /* @__PURE__ */ new Map();
7742
+ let m3 = null;
7743
+ return { emit: (e3) => {
7744
+ var _a2, _b;
7745
+ const w3 = (_a2 = e3.data) == null ? void 0 : _a2.source;
7746
+ if (3 !== e3.type || 0 !== w3 && 5 !== w3) return void sendEvent(e3);
7747
+ const b3 = `3:${w3}:${((_b = e3.data) == null ? void 0 : _b.id) || "unknown"}`;
7748
+ u2.set(b3, e3), m3 || (m3 = setInterval(() => {
7749
+ 0 !== u2.size && (u2.forEach((e4) => sendEvent(e4)), u2.clear());
7750
+ }, a3));
7751
+ }, flush: () => {
7752
+ u2.size > 0 && (u2.forEach((e3) => sendEvent(e3)), u2.clear()), m3 && (clearInterval(m3), m3 = null);
7753
+ } };
7754
+ })(e.textEditThrottleEnabled), emitWithContext = (e2) => {
7755
+ Object.assign(e2, getUrlAndStoredUuids()), e2.sessionId = m2, a2.emit(e2);
7756
+ };
7738
7757
  ae({ emit(e2) {
7739
- Object.assign(e2, getUrlAndStoredUuids()), e2.sessionId = m2, sendEvent(e2);
7740
- }, maskInputOptions: { text: true }, maskInputFn, maskTextClass: "sailfishSanitize", ...e }), (function whenZendeskReady(e2) {
7758
+ emitWithContext(e2);
7759
+ }, maskInputOptions: { text: true }, maskInputFn, maskTextClass: "sailfishSanitize", ...e });
7760
+ const textareaInputHandler = (e2) => {
7761
+ var _a2, _b;
7762
+ const a3 = e2.target;
7763
+ if (!a3 || "TEXTAREA" !== a3.tagName) return;
7764
+ const u2 = (_b = (_a2 = ae.mirror) == null ? void 0 : _a2.getId) == null ? void 0 : _b.call(_a2, a3);
7765
+ "number" != typeof u2 || u2 < 0 || emitWithContext({ type: fd.IncrementalSnapshot, data: { source: md.Input, id: u2, text: a3.value, isChecked: false, userTriggered: true, masked: false }, timestamp: Date.now() });
7766
+ };
7767
+ document.addEventListener("input", textareaInputHandler), window.addEventListener("beforeunload", () => {
7768
+ a2.flush(), document.removeEventListener("input", textareaInputHandler);
7769
+ }), (function whenZendeskReady(e2) {
7741
7770
  if ("undefined" == typeof window) return;
7742
- const a2 = window.zE;
7743
- if ("function" == typeof a2) try {
7744
- a2(e2);
7771
+ const a3 = window.zE;
7772
+ if ("function" == typeof a3) try {
7773
+ a3(e2);
7745
7774
  } catch {
7746
7775
  }
7747
7776
  })(() => {
@@ -7749,11 +7778,11 @@ async function initializeRecording(e, a, u, m2, w2) {
7749
7778
  zE_safe("messenger:set", "conversationTags", [`sailfish-session-${m2}`]);
7750
7779
  });
7751
7780
  const handleWidgetOpen = () => {
7752
- ae.addSailfishEvent(fd.SailfishCustom, { action: "customer support chat opened", element_id: gd, provider: yd });
7781
+ ae.addSailfishEvent(fd.SailfishCustom, { action: "customer support chat opened", element_id: yd, provider: wd });
7753
7782
  }, handleWidgetClose = () => {
7754
- ae.addSailfishEvent(fd.SailfishCustom, { action: "customer support chat closed", element_id: gd, provider: yd });
7783
+ ae.addSailfishEvent(fd.SailfishCustom, { action: "customer support chat closed", element_id: yd, provider: wd });
7755
7784
  }, handleUnreadMessages = (e2) => {
7756
- ae.addSailfishEvent(fd.SailfishCustom, { action: "zendesk unreadmessages", element_id: gd, provider: yd });
7785
+ ae.addSailfishEvent(fd.SailfishCustom, { action: "zendesk unreadmessages", element_id: yd, provider: wd });
7757
7786
  };
7758
7787
  suppressConsoleLogsDuringCall(() => {
7759
7788
  zE_safe("messenger:on", "open", handleWidgetOpen), zE_safe("messenger:on", "close", handleWidgetClose), zE_safe("messenger:on", "unreadMessages", handleUnreadMessages);
@@ -7764,19 +7793,19 @@ async function initializeRecording(e, a, u, m2, w2) {
7764
7793
  }
7765
7794
  return b2;
7766
7795
  }
7767
- let wd = null, bd = null;
7796
+ let bd = null, Sd = null;
7768
7797
  function identify(e, a = {}, u = false) {
7769
7798
  const m2 = { type: "identify", userId: e, traits: a };
7770
- wd && wd.userId === e && JSON.stringify(wd.traits) === JSON.stringify(a) || (wd = { userId: e, traits: a, overwrite: u }, sendMessage(m2));
7799
+ bd && bd.userId === e && JSON.stringify(bd.traits) === JSON.stringify(a) || (bd = { userId: e, traits: a, overwrite: u }, sendMessage(m2));
7771
7800
  }
7772
7801
  function addOrUpdateMetadata(e) {
7773
7802
  const a = { type: "addOrUpdateMetadata", metadata: e };
7774
- bd && JSON.stringify(bd) === JSON.stringify(e) || (bd = e, sendMessage(a));
7803
+ Sd && JSON.stringify(Sd) === JSON.stringify(e) || (Sd = e, sendMessage(a));
7775
7804
  }
7776
7805
  function trackingEvent(e) {
7777
7806
  sendMessage({ type: "trackingEvent", trackingData: e, timestamp: ne() });
7778
7807
  }
7779
- const Sd = readDebugFlag(), vd = ["t.co", "*.twitter.com", "*.gravatar.com", "*.googleapis.com", "*.amazonaws.com", "*.smooch.io", "*.zendesk.com", "*.zdassets.com"], kd = [400, 403], Cd = "CORS", xd = 1, Id = { recordCanvas: false, recordCrossOriginIframes: false, collectFonts: false, inlineImages: false, recordPassword: false, recordRealName: true, recordCreditCardInfo: false, recordSsn: false, recordDob: false, sampling: {} }, Md = { level: ["info", "log", "warn", "error"], lengthThreshold: 1e4, stringifyOptions: { stringLengthLimit: 1e3, numOfKeysLimit: 20, depthOfLimit: 4 }, logger: "console" };
7808
+ const vd = readDebugFlag(), kd = ["t.co", "*.twitter.com", "*.gravatar.com", "*.googleapis.com", "*.amazonaws.com", "*.smooch.io", "*.zendesk.com", "*.zdassets.com"], Cd = [400, 403], xd = "CORS", Id = 1, Md = { recordCanvas: false, recordCrossOriginIframes: false, collectFonts: false, inlineImages: false, recordPassword: false, recordRealName: true, recordCreditCardInfo: false, recordSsn: false, recordDob: false, sampling: {} }, Ed = { level: ["info", "log", "warn", "error"], lengthThreshold: 1e4, stringifyOptions: { stringLengthLimit: 1e3, numOfKeysLimit: 20, depthOfLimit: 4 }, logger: "console" };
7780
7809
  function trackDomainChangesOnce() {
7781
7810
  const e = window.__sailfish_recorder || (window.__sailfish_recorder = {});
7782
7811
  if (e.routeWatcherIntervalId) return;
@@ -7843,7 +7872,7 @@ function shouldSkipHeadersPropagation(e, a = []) {
7843
7872
  return true;
7844
7873
  }
7845
7874
  for (const e2 of O) if (u.pathname.toLowerCase().endsWith(e2)) return true;
7846
- return !!matchUrlWithWildcard(e, [...vd, ...a]);
7875
+ return !!matchUrlWithWildcard(e, [...kd, ...a]);
7847
7876
  }
7848
7877
  function setupFetchInterceptor(e = []) {
7849
7878
  const a = window.fetch, u = getOrSetSessionId();
@@ -7878,7 +7907,7 @@ function setupFetchInterceptor(e = []) {
7878
7907
  D2[e3] = a4;
7879
7908
  }) : D2 = { ...w3.headers }), F2 = w3.body;
7880
7909
  } catch (e3) {
7881
- Sd && console.warn("[Sailfish] Failed to capture request data:", e3);
7910
+ vd && console.warn("[Sailfish] Failed to capture request data:", e3);
7882
7911
  }
7883
7912
  delete D2[b];
7884
7913
  const $2 = (_a2 = getFuncSpanHeader()) == null ? void 0 : _a2.name;
@@ -7888,16 +7917,16 @@ function setupFetchInterceptor(e = []) {
7888
7917
  const I4 = getFuncSpanHeader();
7889
7918
  if (u3 instanceof Request) {
7890
7919
  const E3 = u3.clone(), _3 = new Headers(E3.headers);
7891
- _3.set(b, `${w4}/${C4}/${x4}`), I4 && (_3.set(I4.name, I4.value), Sd && console.log("[Sailfish] Added funcspan header to HTTP Request:", { url: u3.url, header: I4.name }));
7920
+ _3.set(b, `${w4}/${C4}/${x4}`), I4 && (_3.set(I4.name, I4.value), vd && console.log("[Sailfish] Added funcspan header to HTTP Request:", { url: u3.url, header: I4.name }));
7892
7921
  const O3 = new Request(E3, { headers: _3 });
7893
7922
  return await e3.call(a4, O3, m4);
7894
7923
  }
7895
7924
  {
7896
7925
  const E3 = { ...m4 }, _3 = new Headers(m4.headers || {});
7897
- return _3.set(b, `${w4}/${C4}/${x4}`), I4 && (_3.set(I4.name, I4.value), Sd && console.log("[Sailfish] Added funcspan header to HTTP fetch:", { url: "string" == typeof u3 ? u3 : u3.href, header: I4.name })), E3.headers = _3, await e3.call(a4, u3, E3);
7926
+ return _3.set(b, `${w4}/${C4}/${x4}`), I4 && (_3.set(I4.name, I4.value), vd && console.log("[Sailfish] Added funcspan header to HTTP fetch:", { url: "string" == typeof u3 ? u3 : u3.href, header: I4.name })), E3.headers = _3, await e3.call(a4, u3, E3);
7898
7927
  }
7899
7928
  })(e2, a3, m3, w3, C3, E2.page_visit_uuid, I3), B2 = false;
7900
- kd.includes($3.status) && (Sd && console.log("Perform retry as status was fail:", $3), I3 = v4(), $3 = await (async function retryWithoutPropagateHeaders(e3, a4, u3, m4) {
7929
+ Cd.includes($3.status) && (vd && console.log("Perform retry as status was fail:", $3), I3 = v4(), $3 = await (async function retryWithoutPropagateHeaders(e3, a4, u3, m4) {
7901
7930
  try {
7902
7931
  let m5 = u3[0], w4 = u3[1] || {};
7903
7932
  if ("string" == typeof m5 || m5 instanceof URL) {
@@ -7913,7 +7942,7 @@ function setupFetchInterceptor(e = []) {
7913
7942
  }
7914
7943
  return e3.apply(a4, u3);
7915
7944
  } catch (e4) {
7916
- throw Sd && console.log(`Retry without ${b} for ${m4} also failed:`, e4), e4;
7945
+ throw vd && console.log(`Retry without ${b} for ${m4} also failed:`, e4), e4;
7917
7946
  }
7918
7947
  })(e2, a3, u2, x3), B2 = true);
7919
7948
  const U2 = Date.now(), j2 = $3.status, z2 = $3.ok, q2 = z2 ? "" : `Request Error: ${$3.statusText}`;
@@ -7922,7 +7951,7 @@ function setupFetchInterceptor(e = []) {
7922
7951
  const e3 = $3.clone();
7923
7952
  V2 = await e3.text();
7924
7953
  } catch (e3) {
7925
- Sd && console.warn("[Sailfish] Failed to capture response data:", e3), V2 = null;
7954
+ vd && console.warn("[Sailfish] Failed to capture response data:", e3), V2 = null;
7926
7955
  }
7927
7956
  let H2 = null;
7928
7957
  try {
@@ -7930,12 +7959,12 @@ function setupFetchInterceptor(e = []) {
7930
7959
  H2[a4] = e3;
7931
7960
  });
7932
7961
  } catch (e3) {
7933
- Sd && console.warn("[Sailfish] Failed to capture response headers:", e3), H2 = null;
7962
+ vd && console.warn("[Sailfish] Failed to capture response headers:", e3), H2 = null;
7934
7963
  }
7935
7964
  return sendEvent({ type: 27, timestamp: U2, sessionId: C3, data: { request_id: I3, session_id: C3, timestamp_start: O2, timestamp_end: U2, response_code: j2, success: z2, error: q2, method: _2, url: x3, retry_without_trace_id: B2, request_headers: D2, request_body: F2, response_headers: H2, response_body: V2 }, ...E2 }), $3;
7936
7965
  } catch (m4) {
7937
7966
  const w4 = Date.now(), b2 = false, $3 = ((_b = m4.response) == null ? void 0 : _b.status) || 500, B2 = m4.message || "Fetch request failed";
7938
- if (m4 instanceof TypeError && ((_c2 = m4 == null ? void 0 : m4.message) == null ? void 0 : _c2.toLowerCase().includes(Cd.toLowerCase()))) return e2.apply(a3, u2);
7967
+ if (m4 instanceof TypeError && ((_c2 = m4 == null ? void 0 : m4.message) == null ? void 0 : _c2.toLowerCase().includes(xd.toLowerCase()))) return e2.apply(a3, u2);
7939
7968
  throw sendEvent({ type: 27, timestamp: w4, sessionId: C3, data: { request_id: I3, session_id: C3, timestamp_start: O2, timestamp_end: w4, response_code: $3, success: b2, error: B2, method: _2, url: x3, request_headers: D2, request_body: F2, response_body: null }, ...E2 }), m4;
7940
7969
  }
7941
7970
  })(a2, m2, w2, x2, I2, u, C2);
@@ -7969,7 +7998,7 @@ async function startRecording({ apiKey: e, backendApi: a = "https://api-service.
7969
7998
  })(), D2 = getOrSetSessionId(), $2 = window.__sailfish_recorder || (window.__sailfish_recorder = {});
7970
7999
  if ($2.sessionId = D2, $2.apiKey = e, $2.backendApi = a, $2.serviceAdditionalMetadata = I2, $2.initialized && $2.sessionId === D2 && $2.ws && 1 === $2.ws.readyState) trackDomainChangesOnce();
7971
8000
  else {
7972
- $2.domEventsInit || (initializeDomContentEvents(D2), $2.domEventsInit = true), $2.consoleInit || (initializeConsolePlugin(Md, D2), $2.consoleInit = true), $2.errorInit || (!(function initializeErrorInterceptor() {
8001
+ $2.domEventsInit || (initializeDomContentEvents(D2), $2.domEventsInit = true), $2.consoleInit || (initializeConsolePlugin(Ed, D2), $2.consoleInit = true), $2.errorInit || (!(function initializeErrorInterceptor() {
7973
8002
  window.addEventListener("error", (e2) => {
7974
8003
  captureError(e2.error || e2.message);
7975
8004
  }), window.addEventListener("unhandledrejection", (e2) => {
@@ -7979,10 +8008,10 @@ async function startRecording({ apiKey: e, backendApi: a = "https://api-service.
7979
8008
  X && (sessionStorage.setItem("sailfishApiKey", e2), sessionStorage.setItem("sailfishBackendApi", a2));
7980
8009
  })({ apiKey: e, backendApi: a }), trackDomainChangesOnce(), sessionStorage.setItem("sailfishApiKey", e), sessionStorage.setItem("sailfishBackendApi", a), !isFunctionSpanTrackingEnabled() || $2.ws && 1 === $2.ws.readyState || fetchFunctionSpanTrackingEnabled(e, a).then((e2) => {
7981
8010
  var _a3;
7982
- ((_a3 = e2.data) == null ? void 0 : _a3.isFunctionSpanTrackingEnabledFromApiKey) ?? false ? Sd && console.log("[Sailfish] Function span tracking state validated with backend: ACTIVE") : (clearStaleFuncSpanState(), Sd && console.log("[Sailfish] Cleared stale function span tracking state - backend validation shows tracking is not active"));
8011
+ ((_a3 = e2.data) == null ? void 0 : _a3.isFunctionSpanTrackingEnabledFromApiKey) ?? false ? vd && console.log("[Sailfish] Function span tracking state validated with backend: ACTIVE") : (clearStaleFuncSpanState(), vd && console.log("[Sailfish] Cleared stale function span tracking state - backend validation shows tracking is not active"));
7983
8012
  }).catch((e2) => {
7984
- Sd && console.warn("[Sailfish] Failed to validate function span tracking status with backend:", e2);
7985
- }), $2.sentDoNotPropagateOnce || (sendDomainsToNotPropagateHeaderTo(e, [...m2, ...vd], a).catch((e2) => console.error("Failed to send domains to not propagate header to:", e2)), $2.sentDoNotPropagateOnce = true), $2.xhrPatched || (!(function setupXMLHttpRequestInterceptor(e2 = []) {
8013
+ vd && console.warn("[Sailfish] Failed to validate function span tracking status with backend:", e2);
8014
+ }), $2.sentDoNotPropagateOnce || (sendDomainsToNotPropagateHeaderTo(e, [...m2, ...kd], a).catch((e2) => console.error("Failed to send domains to not propagate header to:", e2)), $2.sentDoNotPropagateOnce = true), $2.xhrPatched || (!(function setupXMLHttpRequestInterceptor(e2 = []) {
7986
8015
  const a2 = XMLHttpRequest.prototype.open, u2 = XMLHttpRequest.prototype.send, m3 = XMLHttpRequest.prototype.setRequestHeader, w3 = getOrSetSessionId();
7987
8016
  XMLHttpRequest.prototype.setRequestHeader = function(e3, a3) {
7988
8017
  return this._capturedRequestHeaders || (this._capturedRequestHeaders = {}), this._capturedRequestHeaders[e3] = a3, m3.call(this, e3, a3);
@@ -8000,9 +8029,9 @@ async function startRecording({ apiKey: e, backendApi: a = "https://api-service.
8000
8029
  }
8001
8030
  const E3 = getFuncSpanHeader();
8002
8031
  if (E3) try {
8003
- this.setRequestHeader(E3.name, E3.value), Sd && console.log("[Sailfish] Added funcspan header to XMLHttpRequest:", { url: m4, header: E3.name });
8032
+ this.setRequestHeader(E3.name, E3.value), vd && console.log("[Sailfish] Added funcspan header to XMLHttpRequest:", { url: m4, header: E3.name });
8004
8033
  } catch (e3) {
8005
- Sd && console.warn(`[Sailfish] Could not set funcspan header for ${m4}`, e3);
8034
+ vd && console.warn(`[Sailfish] Could not set funcspan header for ${m4}`, e3);
8006
8035
  }
8007
8036
  const _3 = Date.now();
8008
8037
  let O3 = false;
@@ -8030,7 +8059,7 @@ async function startRecording({ apiKey: e, backendApi: a = "https://api-service.
8030
8059
  2 === a5.length && (u3[a5[0]] = a5[1]);
8031
8060
  });
8032
8061
  } catch (e4) {
8033
- Sd && console.warn("[Sailfish] Failed to capture XHR response headers:", e4), u3 = null;
8062
+ vd && console.warn("[Sailfish] Failed to capture XHR response headers:", e4), u3 = null;
8034
8063
  }
8035
8064
  if (e3 >= 200 && e3 < 300) emitFinished(true, e3, "", a4, u3);
8036
8065
  else {
@@ -8046,7 +8075,7 @@ async function startRecording({ apiKey: e, backendApi: a = "https://api-service.
8046
8075
  sendMessage({ type: "deviceInfo", data: { deviceInfo: { language: navigator.language, userAgent: navigator.userAgent } } });
8047
8076
  })();
8048
8077
  try {
8049
- const u2 = await fetchCaptureSettings(e, a), m3 = ((_a2 = u2.data) == null ? void 0 : _a2.captureSettingsFromApiKey) || Id;
8078
+ const u2 = await fetchCaptureSettings(e, a), m3 = ((_a2 = u2.data) == null ? void 0 : _a2.captureSettingsFromApiKey) || Md;
8050
8079
  if ($2.ws && 1 === $2.ws.readyState) return;
8051
8080
  const b2 = withAppUrlMetadata(I2), x3 = await startRecordingSession(e, D2, a, _2, O2, F2, E2, "JS/TS", b2);
8052
8081
  if ((_b = x3.data) == null ? void 0 : _b.startRecordingSession) {
@@ -8082,7 +8111,7 @@ H && (!(function sendUserDeviceUuid() {
8082
8111
  const e = document.visibilityState, a = Date.now();
8083
8112
  "visible" === e && getOrSetSessionId();
8084
8113
  try {
8085
- sendMessage({ type: "visibilityChange", data: { state: e, url: window.location.href.split("?")[0], timestamp: a, ...getUrlAndStoredUuids() } }), Sd && console.log(`[Sailfish] Tab became ${e}, sent visibility change event`);
8114
+ sendMessage({ type: "visibilityChange", data: { state: e, url: window.location.href.split("?")[0], timestamp: a, ...getUrlAndStoredUuids() } }), vd && console.log(`[Sailfish] Tab became ${e}, sent visibility change event`);
8086
8115
  } catch (e2) {
8087
8116
  console.warn("[Sailfish] Failed to send visibility change event:", e2);
8088
8117
  }
@@ -8109,9 +8138,9 @@ const initRecorder = async (e) => {
8109
8138
  })), a.initPromise);
8110
8139
  };
8111
8140
  export {
8112
- Id as DEFAULT_CAPTURE_SETTINGS,
8113
- Md as DEFAULT_CONSOLE_RECORDING_SETTINGS,
8114
- xd as STORAGE_VERSION,
8141
+ Md as DEFAULT_CAPTURE_SETTINGS,
8142
+ Ed as DEFAULT_CONSOLE_RECORDING_SETTINGS,
8143
+ Id as STORAGE_VERSION,
8115
8144
  addOrUpdateMetadata,
8116
8145
  buildBatches,
8117
8146
  clearStaleFuncSpanState,
Binary file
Binary file
@@ -467,7 +467,7 @@
467
467
  const a3 = document.createElement("a");
468
468
  return a3.href = e3, `${a3.hostname}${a3.port ? `:${a3.port}` : ""}`;
469
469
  })(e2);
470
- let b2 = `${"https:" === new URL(e2).protocol ? "wss" : "ws"}://${w2}/ws/notify/?apiKey=${a2}&sessionId=${u2}&sender=JS%2FTS&version=1.8.19`;
470
+ let b2 = `${"https:" === new URL(e2).protocol ? "wss" : "ws"}://${w2}/ws/notify/?apiKey=${a2}&sessionId=${u2}&sender=JS%2FTS&version=1.8.21-alpha5`;
471
471
  m2 && (b2 += `&envValue=${encodeURIComponent(m2)}`);
472
472
  return se = new j(b2, [], { connectionTimeout: 3e4 }), se.addEventListener("open", () => {
473
473
  re && (console.log("[Sailfish] WebSocket connection opened"), console.log("[Sailfish] Function span tracking state: " + (de ? "ENABLED" : "DISABLED"))), (async () => {
@@ -1296,7 +1296,7 @@
1296
1296
  }), "Sending GraphQL request to Sailfish AI", m2, w2, b2);
1297
1297
  }
1298
1298
  function fetchCaptureSettings(e2, a2) {
1299
- return sendGraphQLRequest("GetCaptureSettingsFromApiKey", "\n query GetCaptureSettingsFromApiKey($apiKey: String!) {\n captureSettingsFromApiKey(apiKey: $apiKey) {\n recordCanvas\n recordCrossOriginIframes\n collectFonts\n inlineImages\n recordPassword\n recordRealName\n recordCreditCardInfo\n recordSsn\n recordDob\n sampling\n }\n }\n ", { apiKey: e2, backendApi: a2 });
1299
+ return sendGraphQLRequest("GetCaptureSettingsFromApiKey", "\n query GetCaptureSettingsFromApiKey($apiKey: String!) {\n captureSettingsFromApiKey(apiKey: $apiKey) {\n recordCanvas\n recordCrossOriginIframes\n collectFonts\n inlineImages\n recordPassword\n recordRealName\n recordCreditCardInfo\n recordSsn\n recordDob\n sampling\n textEditThrottleEnabled\n }\n }\n ", { apiKey: e2, backendApi: a2 });
1300
1300
  }
1301
1301
  function fetchFunctionSpanTrackingEnabled(e2, a2) {
1302
1302
  return sendGraphQLRequest("GetFunctionSpanTrackingEnabledFromApiKey", "\n query GetFunctionSpanTrackingEnabledFromApiKey($apiKey: String!) {\n isFunctionSpanTrackingEnabledFromApiKey(apiKey: $apiKey)\n }\n ", { apiKey: e2, backendApi: a2 });
@@ -7623,10 +7623,10 @@
7623
7623
  };
7624
7624
  }
7625
7625
  }
7626
- var fd = ((e2) => (e2[e2.DomContentLoaded = 0] = "DomContentLoaded", e2[e2.Load = 1] = "Load", e2[e2.FullSnapshot = 2] = "FullSnapshot", e2[e2.IncrementalSnapshot = 3] = "IncrementalSnapshot", e2[e2.Meta = 4] = "Meta", e2[e2.Custom = 5] = "Custom", e2[e2.Plugin = 6] = "Plugin", e2[e2.Device = 24] = "Device", e2[e2.SailfishCustom = 25] = "SailfishCustom", e2))(fd || {});
7627
- const md = ["/node_modules/", "/@sailfish-ai/", "/@sailfish-rrweb/", "/dist/", "/webpack/", "/vite/", "/__vite", "/react-dom/", "/react/", "/scheduler/", "/<", "/chrome-extension://", "/extensions/"];
7626
+ var fd = ((e2) => (e2[e2.DomContentLoaded = 0] = "DomContentLoaded", e2[e2.Load = 1] = "Load", e2[e2.FullSnapshot = 2] = "FullSnapshot", e2[e2.IncrementalSnapshot = 3] = "IncrementalSnapshot", e2[e2.Meta = 4] = "Meta", e2[e2.Custom = 5] = "Custom", e2[e2.Plugin = 6] = "Plugin", e2[e2.Device = 24] = "Device", e2[e2.SailfishCustom = 25] = "SailfishCustom", e2))(fd || {}), md = ((e2) => (e2[e2.Mutation = 0] = "Mutation", e2[e2.MouseMove = 1] = "MouseMove", e2[e2.MouseInteraction = 2] = "MouseInteraction", e2[e2.Scroll = 3] = "Scroll", e2[e2.ViewportResize = 4] = "ViewportResize", e2[e2.Input = 5] = "Input", e2[e2.TouchMove = 6] = "TouchMove", e2[e2.MediaInteraction = 7] = "MediaInteraction", e2[e2.StyleSheetRule = 8] = "StyleSheetRule", e2[e2.CanvasMutation = 9] = "CanvasMutation", e2[e2.Font = 10] = "Font", e2[e2.Log = 11] = "Log", e2[e2.Drag = 12] = "Drag", e2[e2.StyleDeclaration = 13] = "StyleDeclaration", e2[e2.Selection = 14] = "Selection", e2[e2.AdoptedStyleSheet = 15] = "AdoptedStyleSheet", e2[e2.CustomElement = 16] = "CustomElement", e2[e2.Typing = 17] = "Typing", e2))(md || {});
7627
+ const gd = ["/node_modules/", "/@sailfish-ai/", "/@sailfish-rrweb/", "/dist/", "/webpack/", "/vite/", "/__vite", "/react-dom/", "/react/", "/scheduler/", "/<", "/chrome-extension://", "/extensions/"];
7628
7628
  function shouldSkipFrame(e2) {
7629
- return md.some((a2) => e2.includes(a2));
7629
+ return gd.some((a2) => e2.includes(a2));
7630
7630
  }
7631
7631
  function normalizeFilePath(e2) {
7632
7632
  let a2 = e2;
@@ -7688,7 +7688,7 @@
7688
7688
  console.log = a2, console.warn = u2, console.error = m2;
7689
7689
  }
7690
7690
  }
7691
- const gd = "zendesk_chat", yd = "Zendesk";
7691
+ const yd = "zendesk_chat", wd = "Zendesk";
7692
7692
  function zE_safe(...e2) {
7693
7693
  try {
7694
7694
  if ((function hasZendesk() {
@@ -7734,13 +7734,42 @@
7734
7734
  async function initializeRecording(e2, a2, u2, m2, w2) {
7735
7735
  const b2 = initializeWebSocket(a2, u2, m2, w2);
7736
7736
  try {
7737
+ const a3 = (function createThrottledEmit(e3, a4 = 1e3) {
7738
+ if (!e3) return { emit: (e4) => sendEvent(e4), flush: () => {
7739
+ } };
7740
+ const u3 = /* @__PURE__ */ new Map();
7741
+ let m3 = null;
7742
+ return { emit: (e4) => {
7743
+ var _a2, _b;
7744
+ const w3 = (_a2 = e4.data) == null ? void 0 : _a2.source;
7745
+ if (3 !== e4.type || 0 !== w3 && 5 !== w3) return void sendEvent(e4);
7746
+ const b3 = `3:${w3}:${((_b = e4.data) == null ? void 0 : _b.id) || "unknown"}`;
7747
+ u3.set(b3, e4), m3 || (m3 = setInterval(() => {
7748
+ 0 !== u3.size && (u3.forEach((e5) => sendEvent(e5)), u3.clear());
7749
+ }, a4));
7750
+ }, flush: () => {
7751
+ u3.size > 0 && (u3.forEach((e4) => sendEvent(e4)), u3.clear()), m3 && (clearInterval(m3), m3 = null);
7752
+ } };
7753
+ })(e2.textEditThrottleEnabled), emitWithContext = (e3) => {
7754
+ Object.assign(e3, getUrlAndStoredUuids()), e3.sessionId = m2, a3.emit(e3);
7755
+ };
7737
7756
  ae({ emit(e3) {
7738
- Object.assign(e3, getUrlAndStoredUuids()), e3.sessionId = m2, sendEvent(e3);
7739
- }, maskInputOptions: { text: true }, maskInputFn, maskTextClass: "sailfishSanitize", ...e2 }), (function whenZendeskReady(e3) {
7757
+ emitWithContext(e3);
7758
+ }, maskInputOptions: { text: true }, maskInputFn, maskTextClass: "sailfishSanitize", ...e2 });
7759
+ const textareaInputHandler = (e3) => {
7760
+ var _a2, _b;
7761
+ const a4 = e3.target;
7762
+ if (!a4 || "TEXTAREA" !== a4.tagName) return;
7763
+ const u3 = (_b = (_a2 = ae.mirror) == null ? void 0 : _a2.getId) == null ? void 0 : _b.call(_a2, a4);
7764
+ "number" != typeof u3 || u3 < 0 || emitWithContext({ type: fd.IncrementalSnapshot, data: { source: md.Input, id: u3, text: a4.value, isChecked: false, userTriggered: true, masked: false }, timestamp: Date.now() });
7765
+ };
7766
+ document.addEventListener("input", textareaInputHandler), window.addEventListener("beforeunload", () => {
7767
+ a3.flush(), document.removeEventListener("input", textareaInputHandler);
7768
+ }), (function whenZendeskReady(e3) {
7740
7769
  if ("undefined" == typeof window) return;
7741
- const a3 = window.zE;
7742
- if ("function" == typeof a3) try {
7743
- a3(e3);
7770
+ const a4 = window.zE;
7771
+ if ("function" == typeof a4) try {
7772
+ a4(e3);
7744
7773
  } catch {
7745
7774
  }
7746
7775
  })(() => {
@@ -7748,11 +7777,11 @@
7748
7777
  zE_safe("messenger:set", "conversationTags", [`sailfish-session-${m2}`]);
7749
7778
  });
7750
7779
  const handleWidgetOpen = () => {
7751
- ae.addSailfishEvent(fd.SailfishCustom, { action: "customer support chat opened", element_id: gd, provider: yd });
7780
+ ae.addSailfishEvent(fd.SailfishCustom, { action: "customer support chat opened", element_id: yd, provider: wd });
7752
7781
  }, handleWidgetClose = () => {
7753
- ae.addSailfishEvent(fd.SailfishCustom, { action: "customer support chat closed", element_id: gd, provider: yd });
7782
+ ae.addSailfishEvent(fd.SailfishCustom, { action: "customer support chat closed", element_id: yd, provider: wd });
7754
7783
  }, handleUnreadMessages = (e3) => {
7755
- ae.addSailfishEvent(fd.SailfishCustom, { action: "zendesk unreadmessages", element_id: gd, provider: yd });
7784
+ ae.addSailfishEvent(fd.SailfishCustom, { action: "zendesk unreadmessages", element_id: yd, provider: wd });
7756
7785
  };
7757
7786
  suppressConsoleLogsDuringCall(() => {
7758
7787
  zE_safe("messenger:on", "open", handleWidgetOpen), zE_safe("messenger:on", "close", handleWidgetClose), zE_safe("messenger:on", "unreadMessages", handleUnreadMessages);
@@ -7763,8 +7792,8 @@
7763
7792
  }
7764
7793
  return b2;
7765
7794
  }
7766
- let wd = null, bd = null;
7767
- const Sd = readDebugFlag(), vd = ["t.co", "*.twitter.com", "*.gravatar.com", "*.googleapis.com", "*.amazonaws.com", "*.smooch.io", "*.zendesk.com", "*.zdassets.com"], kd = [400, 403], Cd = "CORS", xd = { recordCanvas: false, recordCrossOriginIframes: false, collectFonts: false, inlineImages: false, recordPassword: false, recordRealName: true, recordCreditCardInfo: false, recordSsn: false, recordDob: false, sampling: {} }, Id = { level: ["info", "log", "warn", "error"], lengthThreshold: 1e4, stringifyOptions: { stringLengthLimit: 1e3, numOfKeysLimit: 20, depthOfLimit: 4 }, logger: "console" };
7795
+ let bd = null, Sd = null;
7796
+ const vd = readDebugFlag(), kd = ["t.co", "*.twitter.com", "*.gravatar.com", "*.googleapis.com", "*.amazonaws.com", "*.smooch.io", "*.zendesk.com", "*.zdassets.com"], Cd = [400, 403], xd = "CORS", Id = { recordCanvas: false, recordCrossOriginIframes: false, collectFonts: false, inlineImages: false, recordPassword: false, recordRealName: true, recordCreditCardInfo: false, recordSsn: false, recordDob: false, sampling: {} }, Md = { level: ["info", "log", "warn", "error"], lengthThreshold: 1e4, stringifyOptions: { stringLengthLimit: 1e3, numOfKeysLimit: 20, depthOfLimit: 4 }, logger: "console" };
7768
7797
  function trackDomainChangesOnce() {
7769
7798
  const e2 = window.__sailfish_recorder || (window.__sailfish_recorder = {});
7770
7799
  if (e2.routeWatcherIntervalId) return;
@@ -7831,7 +7860,7 @@
7831
7860
  return true;
7832
7861
  }
7833
7862
  for (const e3 of F) if (u2.pathname.toLowerCase().endsWith(e3)) return true;
7834
- return !!matchUrlWithWildcard(e2, [...vd, ...a2]);
7863
+ return !!matchUrlWithWildcard(e2, [...kd, ...a2]);
7835
7864
  }
7836
7865
  function setupFetchInterceptor(e2 = []) {
7837
7866
  const a2 = window.fetch, u2 = getOrSetSessionId();
@@ -7866,7 +7895,7 @@
7866
7895
  D2[e4] = a5;
7867
7896
  }) : D2 = { ...w3.headers }), F2 = w3.body;
7868
7897
  } catch (e4) {
7869
- Sd && console.warn("[Sailfish] Failed to capture request data:", e4);
7898
+ vd && console.warn("[Sailfish] Failed to capture request data:", e4);
7870
7899
  }
7871
7900
  delete D2[C];
7872
7901
  const $2 = (_a2 = getFuncSpanHeader()) == null ? void 0 : _a2.name;
@@ -7876,16 +7905,16 @@
7876
7905
  const I4 = getFuncSpanHeader();
7877
7906
  if (u4 instanceof Request) {
7878
7907
  const E3 = u4.clone(), _3 = new Headers(E3.headers);
7879
- _3.set(C, `${w4}/${b4}/${x4}`), I4 && (_3.set(I4.name, I4.value), Sd && console.log("[Sailfish] Added funcspan header to HTTP Request:", { url: u4.url, header: I4.name }));
7908
+ _3.set(C, `${w4}/${b4}/${x4}`), I4 && (_3.set(I4.name, I4.value), vd && console.log("[Sailfish] Added funcspan header to HTTP Request:", { url: u4.url, header: I4.name }));
7880
7909
  const O3 = new Request(E3, { headers: _3 });
7881
7910
  return await e4.call(a5, O3, m4);
7882
7911
  }
7883
7912
  {
7884
7913
  const E3 = { ...m4 }, _3 = new Headers(m4.headers || {});
7885
- return _3.set(C, `${w4}/${b4}/${x4}`), I4 && (_3.set(I4.name, I4.value), Sd && console.log("[Sailfish] Added funcspan header to HTTP fetch:", { url: "string" == typeof u4 ? u4 : u4.href, header: I4.name })), E3.headers = _3, await e4.call(a5, u4, E3);
7914
+ return _3.set(C, `${w4}/${b4}/${x4}`), I4 && (_3.set(I4.name, I4.value), vd && console.log("[Sailfish] Added funcspan header to HTTP fetch:", { url: "string" == typeof u4 ? u4 : u4.href, header: I4.name })), E3.headers = _3, await e4.call(a5, u4, E3);
7886
7915
  }
7887
7916
  })(e3, a4, m3, w3, b3, E2.page_visit_uuid, I3), B2 = false;
7888
- kd.includes($3.status) && (Sd && console.log("Perform retry as status was fail:", $3), I3 = v4(), $3 = await (async function retryWithoutPropagateHeaders(e4, a5, u4, m4) {
7917
+ Cd.includes($3.status) && (vd && console.log("Perform retry as status was fail:", $3), I3 = v4(), $3 = await (async function retryWithoutPropagateHeaders(e4, a5, u4, m4) {
7889
7918
  try {
7890
7919
  let m5 = u4[0], w4 = u4[1] || {};
7891
7920
  if ("string" == typeof m5 || m5 instanceof URL) {
@@ -7901,7 +7930,7 @@
7901
7930
  }
7902
7931
  return e4.apply(a5, u4);
7903
7932
  } catch (e5) {
7904
- throw Sd && console.log(`Retry without ${C} for ${m4} also failed:`, e5), e5;
7933
+ throw vd && console.log(`Retry without ${C} for ${m4} also failed:`, e5), e5;
7905
7934
  }
7906
7935
  })(e3, a4, u3, x3), B2 = true);
7907
7936
  const U2 = Date.now(), j2 = $3.status, z2 = $3.ok, q2 = z2 ? "" : `Request Error: ${$3.statusText}`;
@@ -7910,7 +7939,7 @@
7910
7939
  const e4 = $3.clone();
7911
7940
  V2 = await e4.text();
7912
7941
  } catch (e4) {
7913
- Sd && console.warn("[Sailfish] Failed to capture response data:", e4), V2 = null;
7942
+ vd && console.warn("[Sailfish] Failed to capture response data:", e4), V2 = null;
7914
7943
  }
7915
7944
  let H2 = null;
7916
7945
  try {
@@ -7918,12 +7947,12 @@
7918
7947
  H2[a5] = e4;
7919
7948
  });
7920
7949
  } catch (e4) {
7921
- Sd && console.warn("[Sailfish] Failed to capture response headers:", e4), H2 = null;
7950
+ vd && console.warn("[Sailfish] Failed to capture response headers:", e4), H2 = null;
7922
7951
  }
7923
7952
  return sendEvent({ type: 27, timestamp: U2, sessionId: b3, data: { request_id: I3, session_id: b3, timestamp_start: O2, timestamp_end: U2, response_code: j2, success: z2, error: q2, method: _2, url: x3, retry_without_trace_id: B2, request_headers: D2, request_body: F2, response_headers: H2, response_body: V2 }, ...E2 }), $3;
7924
7953
  } catch (m4) {
7925
7954
  const w4 = Date.now(), C2 = false, $3 = ((_b = m4.response) == null ? void 0 : _b.status) || 500, B2 = m4.message || "Fetch request failed";
7926
- if (m4 instanceof TypeError && ((_c2 = m4 == null ? void 0 : m4.message) == null ? void 0 : _c2.toLowerCase().includes(Cd.toLowerCase()))) return e3.apply(a4, u3);
7955
+ if (m4 instanceof TypeError && ((_c2 = m4 == null ? void 0 : m4.message) == null ? void 0 : _c2.toLowerCase().includes(xd.toLowerCase()))) return e3.apply(a4, u3);
7927
7956
  throw sendEvent({ type: 27, timestamp: w4, sessionId: b3, data: { request_id: I3, session_id: b3, timestamp_start: O2, timestamp_end: w4, response_code: $3, success: C2, error: B2, method: _2, url: x3, request_headers: D2, request_body: F2, response_body: null }, ...E2 }), m4;
7928
7957
  }
7929
7958
  })(a3, m2, w2, x2, I2, u2, b2);
@@ -7957,7 +7986,7 @@
7957
7986
  })(), D2 = getOrSetSessionId(), $2 = window.__sailfish_recorder || (window.__sailfish_recorder = {});
7958
7987
  if ($2.sessionId = D2, $2.apiKey = e2, $2.backendApi = a2, $2.serviceAdditionalMetadata = I2, $2.initialized && $2.sessionId === D2 && $2.ws && 1 === $2.ws.readyState) trackDomainChangesOnce();
7959
7988
  else {
7960
- $2.domEventsInit || (initializeDomContentEvents(D2), $2.domEventsInit = true), $2.consoleInit || (initializeConsolePlugin(Id, D2), $2.consoleInit = true), $2.errorInit || (!(function initializeErrorInterceptor() {
7989
+ $2.domEventsInit || (initializeDomContentEvents(D2), $2.domEventsInit = true), $2.consoleInit || (initializeConsolePlugin(Md, D2), $2.consoleInit = true), $2.errorInit || (!(function initializeErrorInterceptor() {
7961
7990
  window.addEventListener("error", (e3) => {
7962
7991
  captureError(e3.error || e3.message);
7963
7992
  }), window.addEventListener("unhandledrejection", (e3) => {
@@ -7967,10 +7996,10 @@
7967
7996
  Q && (sessionStorage.setItem("sailfishApiKey", e3), sessionStorage.setItem("sailfishBackendApi", a3));
7968
7997
  })({ apiKey: e2, backendApi: a2 }), trackDomainChangesOnce(), sessionStorage.setItem("sailfishApiKey", e2), sessionStorage.setItem("sailfishBackendApi", a2), !isFunctionSpanTrackingEnabled() || $2.ws && 1 === $2.ws.readyState || fetchFunctionSpanTrackingEnabled(e2, a2).then((e3) => {
7969
7998
  var _a3;
7970
- ((_a3 = e3.data) == null ? void 0 : _a3.isFunctionSpanTrackingEnabledFromApiKey) ?? false ? Sd && console.log("[Sailfish] Function span tracking state validated with backend: ACTIVE") : (clearStaleFuncSpanState(), Sd && console.log("[Sailfish] Cleared stale function span tracking state - backend validation shows tracking is not active"));
7999
+ ((_a3 = e3.data) == null ? void 0 : _a3.isFunctionSpanTrackingEnabledFromApiKey) ?? false ? vd && console.log("[Sailfish] Function span tracking state validated with backend: ACTIVE") : (clearStaleFuncSpanState(), vd && console.log("[Sailfish] Cleared stale function span tracking state - backend validation shows tracking is not active"));
7971
8000
  }).catch((e3) => {
7972
- Sd && console.warn("[Sailfish] Failed to validate function span tracking status with backend:", e3);
7973
- }), $2.sentDoNotPropagateOnce || (sendDomainsToNotPropagateHeaderTo(e2, [...m2, ...vd], a2).catch((e3) => console.error("Failed to send domains to not propagate header to:", e3)), $2.sentDoNotPropagateOnce = true), $2.xhrPatched || (!(function setupXMLHttpRequestInterceptor(e3 = []) {
8001
+ vd && console.warn("[Sailfish] Failed to validate function span tracking status with backend:", e3);
8002
+ }), $2.sentDoNotPropagateOnce || (sendDomainsToNotPropagateHeaderTo(e2, [...m2, ...kd], a2).catch((e3) => console.error("Failed to send domains to not propagate header to:", e3)), $2.sentDoNotPropagateOnce = true), $2.xhrPatched || (!(function setupXMLHttpRequestInterceptor(e3 = []) {
7974
8003
  const a3 = XMLHttpRequest.prototype.open, u3 = XMLHttpRequest.prototype.send, m3 = XMLHttpRequest.prototype.setRequestHeader, w3 = getOrSetSessionId();
7975
8004
  XMLHttpRequest.prototype.setRequestHeader = function(e4, a4) {
7976
8005
  return this._capturedRequestHeaders || (this._capturedRequestHeaders = {}), this._capturedRequestHeaders[e4] = a4, m3.call(this, e4, a4);
@@ -7988,9 +8017,9 @@
7988
8017
  }
7989
8018
  const E3 = getFuncSpanHeader();
7990
8019
  if (E3) try {
7991
- this.setRequestHeader(E3.name, E3.value), Sd && console.log("[Sailfish] Added funcspan header to XMLHttpRequest:", { url: m4, header: E3.name });
8020
+ this.setRequestHeader(E3.name, E3.value), vd && console.log("[Sailfish] Added funcspan header to XMLHttpRequest:", { url: m4, header: E3.name });
7992
8021
  } catch (e4) {
7993
- Sd && console.warn(`[Sailfish] Could not set funcspan header for ${m4}`, e4);
8022
+ vd && console.warn(`[Sailfish] Could not set funcspan header for ${m4}`, e4);
7994
8023
  }
7995
8024
  const _3 = Date.now();
7996
8025
  let O3 = false;
@@ -8018,7 +8047,7 @@
8018
8047
  2 === a6.length && (u4[a6[0]] = a6[1]);
8019
8048
  });
8020
8049
  } catch (e5) {
8021
- Sd && console.warn("[Sailfish] Failed to capture XHR response headers:", e5), u4 = null;
8050
+ vd && console.warn("[Sailfish] Failed to capture XHR response headers:", e5), u4 = null;
8022
8051
  }
8023
8052
  if (e4 >= 200 && e4 < 300) emitFinished(true, e4, "", a5, u4);
8024
8053
  else {
@@ -8034,7 +8063,7 @@
8034
8063
  sendMessage({ type: "deviceInfo", data: { deviceInfo: { language: navigator.language, userAgent: navigator.userAgent } } });
8035
8064
  })();
8036
8065
  try {
8037
- const u3 = await fetchCaptureSettings(e2, a2), m3 = ((_a2 = u3.data) == null ? void 0 : _a2.captureSettingsFromApiKey) || xd;
8066
+ const u3 = await fetchCaptureSettings(e2, a2), m3 = ((_a2 = u3.data) == null ? void 0 : _a2.captureSettingsFromApiKey) || Id;
8038
8067
  if ($2.ws && 1 === $2.ws.readyState) return;
8039
8068
  const C2 = withAppUrlMetadata(I2), x3 = await startRecordingSession(e2, D2, a2, _2, O2, F2, E2, "JS/TS", C2);
8040
8069
  if ((_b = x3.data) == null ? void 0 : _b.startRecordingSession) {
@@ -8070,7 +8099,7 @@
8070
8099
  const e2 = document.visibilityState, a2 = Date.now();
8071
8100
  "visible" === e2 && getOrSetSessionId();
8072
8101
  try {
8073
- sendMessage({ type: "visibilityChange", data: { state: e2, url: window.location.href.split("?")[0], timestamp: a2, ...getUrlAndStoredUuids() } }), Sd && console.log(`[Sailfish] Tab became ${e2}, sent visibility change event`);
8102
+ sendMessage({ type: "visibilityChange", data: { state: e2, url: window.location.href.split("?")[0], timestamp: a2, ...getUrlAndStoredUuids() } }), vd && console.log(`[Sailfish] Tab became ${e2}, sent visibility change event`);
8074
8103
  } catch (e3) {
8075
8104
  console.warn("[Sailfish] Failed to send visibility change event:", e3);
8076
8105
  }
@@ -8078,12 +8107,12 @@
8078
8107
  }), J && window.addEventListener("beforeunload", () => {
8079
8108
  clearPageVisitDataFromSessionStorage();
8080
8109
  });
8081
- e.DEFAULT_CAPTURE_SETTINGS = xd, e.DEFAULT_CONSOLE_RECORDING_SETTINGS = Id, e.STORAGE_VERSION = 1, e.addOrUpdateMetadata = function addOrUpdateMetadata(e2) {
8110
+ e.DEFAULT_CAPTURE_SETTINGS = Id, e.DEFAULT_CONSOLE_RECORDING_SETTINGS = Md, e.STORAGE_VERSION = 1, e.addOrUpdateMetadata = function addOrUpdateMetadata(e2) {
8082
8111
  const a2 = { type: "addOrUpdateMetadata", metadata: e2 };
8083
- bd && JSON.stringify(bd) === JSON.stringify(e2) || (bd = e2, sendMessage(a2));
8112
+ Sd && JSON.stringify(Sd) === JSON.stringify(e2) || (Sd = e2, sendMessage(a2));
8084
8113
  }, e.buildBatches = buildBatches, e.clearStaleFuncSpanState = clearStaleFuncSpanState, e.createTriageAndIssueFromRecorder = createTriageAndIssueFromRecorder, e.createTriageFromRecorder = createTriageFromRecorder, e.disableFunctionSpanTracking = disableFunctionSpanTracking, e.enableFunctionSpanTracking = enableFunctionSpanTracking, e.eventSize = eventSize, e.fetchCaptureSettings = fetchCaptureSettings, e.fetchEngineeringTicketPlatformIntegrations = fetchEngineeringTicketPlatformIntegrations, e.fetchFunctionSpanTrackingEnabled = fetchFunctionSpanTrackingEnabled, e.flushBufferedEvents = flushBufferedEvents, e.getFuncSpanHeader = getFuncSpanHeader, e.getOrSetSessionId = getOrSetSessionId, e.getUrlAndStoredUuids = getUrlAndStoredUuids, e.identify = function identify(e2, a2 = {}, u2 = false) {
8085
8114
  const m2 = { type: "identify", userId: e2, traits: a2 };
8086
- wd && wd.userId === e2 && JSON.stringify(wd.traits) === JSON.stringify(a2) || (wd = { userId: e2, traits: a2, overwrite: u2 }, sendMessage(m2));
8115
+ bd && bd.userId === e2 && JSON.stringify(bd.traits) === JSON.stringify(a2) || (bd = { userId: e2, traits: a2, overwrite: u2 }, sendMessage(m2));
8087
8116
  }, e.initRecorder = async (e2) => {
8088
8117
  if ("undefined" == typeof window) return;
8089
8118
  const a2 = window.__sailfish_recorder || (window.__sailfish_recorder = {}), u2 = getOrSetSessionId();
package/dist/recording.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { record } from "@sailfish-rrweb/rrweb-record-only";
2
2
  import { getRecordConsolePlugin, } from "@sailfish-rrweb/rrweb-plugin-console-record";
3
3
  // import { NetworkRecordOptions } from "@sailfish-rrweb/rrweb-plugin-network-record";
4
- import { EventType } from "@sailfish-rrweb/types";
4
+ import { EventType, IncrementalSource } from "@sailfish-rrweb/types";
5
5
  import { Complete, DomContentEventId, DomContentSource, Loading, } from "./constants";
6
6
  import { getCallerLocation, getCallerLocationFromTrace, } from "./sourceLocation";
7
7
  import suppressConsoleLogsDuringCall from "./suppressConsoleLogsDuringCall";
@@ -166,23 +166,119 @@ export function initializeConsolePlugin(consoleRecordSettings, sessionId) {
166
166
  sendEvent(eventData);
167
167
  }, window, consoleRecordSettings);
168
168
  }
169
+ /**
170
+ * Creates a throttled emit wrapper that batches text edit events (source: 0 and 5) only.
171
+ * All other events are sent immediately without throttling.
172
+ *
173
+ * Source 0 (Mutation) includes text changes in contenteditable/text nodes.
174
+ * Source 5 (Input) includes form input changes.
175
+ *
176
+ * @param enabled - Whether throttling is enabled
177
+ * @param intervalMs - Throttle interval in milliseconds (default: 1000ms)
178
+ * @returns An emit function that handles throttling for text edit events
179
+ */
180
+ function createThrottledEmit(enabled, intervalMs = 1000) {
181
+ if (!enabled) {
182
+ // No throttling - return object with emit and flush
183
+ return {
184
+ emit: (event) => sendEvent(event),
185
+ flush: () => { }, // No-op flush when throttling is disabled
186
+ };
187
+ }
188
+ // Event buffer: Map<eventKey, latestEvent> to keep only the last text input event
189
+ const eventBuffer = new Map();
190
+ let uploadInterval = null;
191
+ const emit = (event) => {
192
+ // Throttle Type 3 (IncrementalSnapshot) events with:
193
+ // - source 0 (Mutation - includes text changes in contenteditable/text nodes)
194
+ // - source 5 (Input - form input changes)
195
+ const eventSource = event.data?.source;
196
+ const isTextEditEvent = event.type === 3 && (eventSource === 0 || eventSource === 5);
197
+ if (!isTextEditEvent) {
198
+ // Send all non-text-edit events immediately (mouse, scroll, etc.)
199
+ sendEvent(event);
200
+ return;
201
+ }
202
+ // For text edit events (mutation or input), buffer and send periodically
203
+ // Create a key for this event (include source and target id for granular buffering)
204
+ const targetId = event.data?.id || 'unknown';
205
+ const eventKey = `3:${eventSource}:${targetId}`;
206
+ // Store only the LATEST text edit event for this key (overwrites previous)
207
+ eventBuffer.set(eventKey, event);
208
+ // Start upload interval if not already running
209
+ if (!uploadInterval) {
210
+ uploadInterval = setInterval(() => {
211
+ if (eventBuffer.size === 0)
212
+ return;
213
+ // Send only the FINAL text edit event for each source/target combination
214
+ eventBuffer.forEach(e => sendEvent(e));
215
+ eventBuffer.clear();
216
+ }, intervalMs);
217
+ }
218
+ };
219
+ const flush = () => {
220
+ // Immediately send any buffered events
221
+ if (eventBuffer.size > 0) {
222
+ eventBuffer.forEach(e => sendEvent(e));
223
+ eventBuffer.clear();
224
+ }
225
+ // Clear the interval
226
+ if (uploadInterval) {
227
+ clearInterval(uploadInterval);
228
+ uploadInterval = null;
229
+ }
230
+ };
231
+ return { emit, flush };
232
+ }
169
233
  export async function initializeRecording(captureSettings, // TODO - Sibyl post-launch - replace type
170
234
  // networkRecordSettings: NetworkRecordOptions,
171
235
  backendApi, apiKey, sessionId, envValue) {
172
236
  const webSocket = initializeWebSocket(backendApi, apiKey, sessionId, envValue);
173
237
  try {
238
+ // Create throttled emit wrapper (only for text edit events)
239
+ const throttledEmit = createThrottledEmit(captureSettings.textEditThrottleEnabled);
240
+ const emitWithContext = (event) => {
241
+ Object.assign(event, getUrlAndStoredUuids());
242
+ event.sessionId = sessionId;
243
+ throttledEmit.emit(event);
244
+ };
174
245
  record({
175
246
  emit(event) {
176
- Object.assign(event, getUrlAndStoredUuids());
177
- // Attach sessionId to each event
178
- event.sessionId = sessionId;
179
- sendEvent(event);
247
+ emitWithContext(event);
180
248
  },
181
- maskInputOptions: { text: true }, // Fix the incorrect property name
249
+ maskInputOptions: { text: true },
182
250
  maskInputFn,
183
251
  maskTextClass: MASK_CLASS,
184
252
  ...captureSettings,
185
253
  });
254
+ const textareaInputHandler = (event) => {
255
+ const target = event.target;
256
+ if (!target || target.tagName !== "TEXTAREA") {
257
+ return;
258
+ }
259
+ const targetId = record.mirror?.getId?.(target);
260
+ if (typeof targetId !== "number" || targetId < 0) {
261
+ return;
262
+ }
263
+ emitWithContext({
264
+ type: EventType.IncrementalSnapshot,
265
+ data: {
266
+ source: IncrementalSource.Input,
267
+ id: targetId,
268
+ text: target.value,
269
+ isChecked: false,
270
+ userTriggered: true,
271
+ masked: false,
272
+ },
273
+ timestamp: Date.now(),
274
+ });
275
+ };
276
+ document.addEventListener("input", textareaInputHandler);
277
+ // Flush buffered text edits before page unload
278
+ window.addEventListener('beforeunload', () => {
279
+ throttledEmit.flush();
280
+ document.removeEventListener("input", textareaInputHandler);
281
+ });
186
282
  // ───────────────────────────────────────────────────────────────────────
187
283
  // Zendesk (Messaging) — OPTIONAL
188
284
  // If a site uses Zendesk Messaging (and includes the snippet), wire tags
@@ -9,6 +9,7 @@ export interface CaptureSettings {
9
9
  recordSsn: boolean;
10
10
  recordDob: boolean;
11
11
  sampling: object;
12
+ textEditThrottleEnabled?: boolean;
12
13
  }
13
14
  export interface ConsoleRecordSettings {
14
15
  level: string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sailfish-ai/recorder",
3
- "version": "1.8.19",
3
+ "version": "1.8.21-alpha5",
4
4
  "publishPublicly": true,
5
5
  "type": "module",
6
6
  "main": "dist/recorder.cjs",