@sailfish-ai/recorder 1.11.4 → 1.11.6

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.
Files changed (36) hide show
  1. package/dist/chunks/{chunkSerializer-CFHDS9Vi.js → chunkSerializer-D7_uK-dD.js} +1 -1
  2. package/dist/chunks/chunkSerializer-D7_uK-dD.js.br +0 -0
  3. package/dist/chunks/chunkSerializer-D7_uK-dD.js.gz +0 -0
  4. package/dist/chunks/{chunkSerializer-DOaGGlCg.js → chunkSerializer-DkWXHnW4.js} +1 -1
  5. package/dist/chunks/chunkSerializer-DkWXHnW4.js.br +0 -0
  6. package/dist/chunks/chunkSerializer-DkWXHnW4.js.gz +0 -0
  7. package/dist/chunks/{index-DbcegHRc.js → index-CftVmmO9.js} +37 -19
  8. package/dist/chunks/index-CftVmmO9.js.br +0 -0
  9. package/dist/chunks/index-CftVmmO9.js.gz +0 -0
  10. package/dist/chunks/{index-B8IAZfT7.js → index-QXHuV98g.js} +114 -96
  11. package/dist/chunks/index-QXHuV98g.js.br +0 -0
  12. package/dist/chunks/index-QXHuV98g.js.gz +0 -0
  13. package/dist/errorInterceptor.js +42 -4
  14. package/dist/errorInterceptor.js.br +0 -0
  15. package/dist/errorInterceptor.js.gz +0 -0
  16. package/dist/eventStore.js +25 -1
  17. package/dist/eventStore.js.br +0 -0
  18. package/dist/eventStore.js.gz +0 -0
  19. package/dist/recorder.cjs +1 -1
  20. package/dist/recorder.cjs.br +0 -0
  21. package/dist/recorder.cjs.gz +0 -0
  22. package/dist/recorder.js +22 -22
  23. package/dist/recorder.js.br +0 -0
  24. package/dist/recorder.js.gz +0 -0
  25. package/dist/recorder.umd.cjs +36 -18
  26. package/dist/recorder.umd.cjs.br +0 -0
  27. package/dist/recorder.umd.cjs.gz +0 -0
  28. package/package.json +1 -1
  29. package/dist/chunks/chunkSerializer-CFHDS9Vi.js.br +0 -0
  30. package/dist/chunks/chunkSerializer-CFHDS9Vi.js.gz +0 -0
  31. package/dist/chunks/chunkSerializer-DOaGGlCg.js.br +0 -0
  32. package/dist/chunks/chunkSerializer-DOaGGlCg.js.gz +0 -0
  33. package/dist/chunks/index-B8IAZfT7.js.br +0 -0
  34. package/dist/chunks/index-B8IAZfT7.js.gz +0 -0
  35. package/dist/chunks/index-DbcegHRc.js.br +0 -0
  36. package/dist/chunks/index-DbcegHRc.js.gz +0 -0
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const e = require("./index-DbcegHRc.js");
3
+ const e = require("./index-CftVmmO9.js");
4
4
  exports.chunkedSnapshot = async function chunkedSnapshot(t, n, o = {}) {
5
5
  const s = o.chunkSize ?? 500, r = o.maxChunkMs ?? 16, { blockClass: c, blockSelector: a, maskTextClass: i, maskTextSelector: d } = o;
6
6
  let u = 100001, l = 0, N = performance.now();
@@ -1,4 +1,4 @@
1
- import { y as e } from "./index-B8IAZfT7.js";
1
+ import { V as e } from "./index-QXHuV98g.js";
2
2
  async function chunkedSnapshot(t, n, o = {}) {
3
3
  const s = o.chunkSize ?? 500, r = o.maxChunkMs ?? 16, { blockClass: c, blockSelector: a, maskTextClass: i, maskTextSelector: d } = o;
4
4
  let u = 100001, l = 0, N = performance.now();
@@ -313,10 +313,13 @@ async function flushBufferedEvents() {
313
313
  I = (async () => {
314
314
  var _a, _b;
315
315
  const e2 = await (async function getAllIndexedEvents() {
316
- return await withStore$1("readonly", (e3) => new Promise((t3) => {
317
- const n2 = e3.getAll();
318
- n2.onsuccess = () => t3(n2.result), n2.onerror = () => t3([]);
319
- })) ?? [];
316
+ const e3 = await withStore$1("readonly", (e4) => new Promise((t4) => {
317
+ const n3 = e4.getAll();
318
+ n3.onsuccess = () => t4(n3.result), n3.onerror = () => t4([]);
319
+ })) ?? [], t3 = Date.now(), n2 = [], i2 = [];
320
+ for (const o2 of e3) "number" == typeof (o2 == null ? void 0 : o2.timestamp) && t3 - o2.timestamp >= 864e5 ? "number" == typeof o2.id && i2.push(o2.id) : n2.push(o2);
321
+ return i2.length > 0 && deleteEventsByIds(i2).catch(() => {
322
+ }), n2;
320
323
  })(), t2 = {};
321
324
  for (const n2 of e2) {
322
325
  const e3 = ((_b = (_a = n2 == null ? void 0 : n2.data) == null ? void 0 : _a.data) == null ? void 0 : _b.sessionId) ?? "unknown-session";
@@ -391,7 +394,7 @@ function initializeWebSocket(t2, n2, i2, o2, r2 = false) {
391
394
  const t3 = new URL(e2);
392
395
  return `${t3.hostname}${t3.port ? `:${t3.port}` : ""}`;
393
396
  })(t2);
394
- let a2 = `${"https:" === new URL(t2).protocol ? "wss" : "ws"}://${s2}/ws/notify/?apiKey=${n2}&sessionId=${i2}&sender=JS%2FTS&version=1.11.4`;
397
+ let a2 = `${"https:" === new URL(t2).protocol ? "wss" : "ws"}://${s2}/ws/notify/?apiKey=${n2}&sessionId=${i2}&sender=JS%2FTS&version=1.11.6`;
395
398
  if (o2 && (a2 += `&envValue=${encodeURIComponent(o2)}`), w = r2 ? (function tryCreateWsWorker() {
396
399
  if ("undefined" == typeof Worker) return null;
397
400
  try {
@@ -486,10 +489,25 @@ async function getConsumerFor(e2, t2) {
486
489
  }
487
490
  return null;
488
491
  }
489
- async function captureError(e2, t2 = false) {
490
- let n2, i2;
491
- e2 instanceof Error ? (n2 = e2.message, i2 = e2.stack || "No stack trace") : "string" == typeof e2 ? (n2 = e2, i2 = "No stack trace available") : (n2 = "Unknown error occurred", i2 = "No stack trace available");
492
- const o2 = await (async function resolveStackTrace(e3) {
492
+ async function captureError(e2, t2 = false, n2) {
493
+ let i2, o2;
494
+ const r2 = [];
495
+ e2 instanceof Error ? (i2 = e2.message || e2.name, o2 = e2.stack || "No stack trace", r2.push(`${e2.name}: ${i2}`)) : "string" == typeof e2 ? (i2 = e2, o2 = "No stack trace available", r2.push(t2 ? `Uncaught (in promise) ${e2}` : e2)) : (i2 = (function describeNonError(e3) {
496
+ if (null === e3) return "null";
497
+ if (void 0 === e3) return "undefined";
498
+ if ("string" == typeof e3) return e3;
499
+ if ("number" == typeof e3 || "boolean" == typeof e3 || "bigint" == typeof e3) return String(e3);
500
+ if (e3 instanceof Event) {
501
+ const t3 = e3.target, n3 = (t3 == null ? void 0 : t3.tagName) ? `<${t3.tagName.toLowerCase()}>` : "";
502
+ return `[${e3.type} Event${n3 ? ` on ${n3}` : ""}${e3.isTrusted ? " trusted" : ""}]`;
503
+ }
504
+ try {
505
+ return JSON.stringify(e3);
506
+ } catch {
507
+ return Object.prototype.toString.call(e3);
508
+ }
509
+ })(e2), o2 = "No stack trace available", r2.push(t2 ? `Uncaught (in promise) ${i2}` : i2)), (n2 == null ? void 0 : n2.filename) && r2.push(`at ${n2.filename}:${n2.lineno ?? 0}:${n2.colno ?? 0}`);
510
+ const s2 = await (async function resolveStackTrace(e3) {
493
511
  if (!e3) return ["No stack trace available"];
494
512
  const t3 = Array.isArray(e3) ? e3 : e3.split("\n"), n3 = [];
495
513
  for (const e4 of t3) {
@@ -498,27 +516,27 @@ async function captureError(e2, t2 = false) {
498
516
  n3.push(e4);
499
517
  continue;
500
518
  }
501
- const [, i3, o3, r3, s3] = t4, a3 = parseInt(r3, 10), l2 = Math.max(0, parseInt(s3, 10) - 1);
502
- if (!Number.isFinite(a3) || !Number.isFinite(l2)) {
519
+ const [, i3, o3, r3, s3] = t4, a3 = parseInt(r3, 10), l3 = Math.max(0, parseInt(s3, 10) - 1);
520
+ if (!Number.isFinite(a3) || !Number.isFinite(l3)) {
503
521
  n3.push(e4 + " [Invalid line/column]");
504
522
  continue;
505
523
  }
506
- const c2 = await getConsumerFor(i3, o3);
507
- if (!c2) {
524
+ const c3 = await getConsumerFor(i3, o3);
525
+ if (!c3) {
508
526
  n3.push(`${e4} [No source map found for ${o3}]`);
509
527
  continue;
510
528
  }
511
529
  const { SourceMapConsumer: d2 } = await getSourceMapModule();
512
- let u2 = c2.originalPositionFor({ line: a3, column: l2, bias: d2.GREATEST_LOWER_BOUND });
513
- if (!u2.source || null == u2.line) for (let e5 = 1; e5 <= 20 && (u2 = c2.originalPositionFor({ line: a3, column: Math.max(0, l2 - e5), bias: d2.GREATEST_LOWER_BOUND }), !u2.source || null == u2.line); e5++) ;
530
+ let u2 = c3.originalPositionFor({ line: a3, column: l3, bias: d2.GREATEST_LOWER_BOUND });
531
+ if (!u2.source || null == u2.line) for (let e5 = 1; e5 <= 20 && (u2 = c3.originalPositionFor({ line: a3, column: Math.max(0, l3 - e5), bias: d2.GREATEST_LOWER_BOUND }), !u2.source || null == u2.line); e5++) ;
514
532
  if (u2.source && null != u2.line) {
515
533
  const e5 = u2.name || "anonymous";
516
534
  n3.push(`${u2.source}:${u2.line}:${u2.column ?? 0} (${e5})`);
517
535
  } else n3.push(`${e4} [No mapping found in ${o3}]`);
518
536
  }
519
537
  return n3;
520
- })(i2), r2 = o2.filter((e3) => !e3.includes("chunk-") && !e3.includes("react-dom")), s2 = r2.length > 0 ? r2 : o2, a2 = Date.now();
521
- sendMessage({ type: "event", event: { type: 6, timestamp: a2, data: { payload: { message: n2, stack: i2, trace: s2, filteredStack: r2, userAgent: navigator.userAgent, url: window.location.href, timestamp: a2, level: "error" } } } });
538
+ })(o2), a2 = s2.filter((e3) => !e3.includes("chunk-") && !e3.includes("react-dom")), l2 = a2.length > 0 ? a2 : s2, c2 = Date.now();
539
+ sendMessage({ type: "event", event: { type: 6, timestamp: c2, data: { payload: { message: i2, stack: o2, trace: l2, filteredStack: a2, payload: r2, userAgent: navigator.userAgent, url: window.location.href, timestamp: c2, level: "error" } } } });
522
540
  }
523
541
  const K = readDebugFlag();
524
542
  const G = readDebugFlag();
@@ -728,7 +746,7 @@ async function initializeRecording(e2, n2, i2, o2, r2, s2 = true, a2 = false, l2
728
746
  }
729
747
  const { record: n4 } = await import("@sailfish-rrweb/rrweb-record-only");
730
748
  if (Q = n4, await yieldToMain(), l2) {
731
- const { chunkedSnapshot: i3 } = await Promise.resolve().then(() => require("./chunkSerializer-CFHDS9Vi.js")), o3 = n4.mirror;
749
+ const { chunkedSnapshot: i3 } = await Promise.resolve().then(() => require("./chunkSerializer-D7_uK-dD.js")), o3 = n4.mirror;
732
750
  let r3 = true;
733
751
  const s3 = [];
734
752
  n4({ emit(e3) {
@@ -2352,7 +2370,7 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
2352
2370
  };
2353
2371
  })(o2, C2, i2), E2.xhrPatched = true), E2.fetchPatched || (setupFetchInterceptor(o2, C2, i2), E2.fetchPatched = true), await yieldToMain(), E2.domEventsInit || (initializeDomContentEvents(T2), E2.domEventsInit = true), await yieldToMain(), E2.consoleInit || (initializeConsolePlugin(Le, T2), E2.consoleInit = true), await yieldToMain(), E2.errorInit || (!(function initializeErrorInterceptor() {
2354
2372
  window.addEventListener("error", (e3) => {
2355
- captureError(e3.error || e3.message);
2373
+ captureError(e3.error ?? e3.message, false, { filename: e3.filename, lineno: e3.lineno, colno: e3.colno });
2356
2374
  }), window.addEventListener("unhandledrejection", (e3) => {
2357
2375
  captureError(e3.reason, true);
2358
2376
  });
Binary file
Binary file
@@ -151,13 +151,13 @@ function buildBatches(e2, t2, n2) {
151
151
  function eventSize(e2) {
152
152
  return JSON.stringify(e2).length;
153
153
  }
154
- let w = Date.now;
154
+ let v = Date.now;
155
155
  function withAppUrlMetadata(e2) {
156
156
  var _a;
157
157
  return { ...e2 ?? {}, appUrl: (e2 == null ? void 0 : e2.appUrl) ?? ((_a = window == null ? void 0 : window.location) == null ? void 0 : _a.href) };
158
158
  }
159
- /[1-9][0-9]{12}/.test(Date.now().toString()) || (w = () => (/* @__PURE__ */ new Date()).getTime());
160
- const v = readDebugFlag(), S = "per_session";
159
+ /[1-9][0-9]{12}/.test(Date.now().toString()) || (v = () => (/* @__PURE__ */ new Date()).getTime());
160
+ const w = readDebugFlag(), S = "per_session";
161
161
  let k = null, x = null, I = false, T = null, E = null, C = "", $ = "", F = false;
162
162
  const L = [];
163
163
  function onNavigationChange(e2) {
@@ -233,21 +233,21 @@ function saveGlobalFuncSpanState(e2, t2) {
233
233
  try {
234
234
  if ("undefined" == typeof localStorage) return;
235
235
  const n2 = { enabled: e2, expirationTimestampMs: t2, savedAt: Date.now() };
236
- localStorage.setItem(B, JSON.stringify(n2)), v && console.log("[Sailfish] Saved funcSpan state to localStorage:", n2);
236
+ localStorage.setItem(B, JSON.stringify(n2)), w && console.log("[Sailfish] Saved funcSpan state to localStorage:", n2);
237
237
  } catch (e3) {
238
- v && console.warn("[Sailfish] Failed to save funcSpan state to localStorage:", e3);
238
+ w && console.warn("[Sailfish] Failed to save funcSpan state to localStorage:", e3);
239
239
  }
240
240
  }
241
241
  function clearGlobalFuncSpanState() {
242
242
  try {
243
243
  if ("undefined" == typeof localStorage) return;
244
- localStorage.removeItem(B), v && console.log("[Sailfish] Cleared funcSpan state from localStorage");
244
+ localStorage.removeItem(B), w && console.log("[Sailfish] Cleared funcSpan state from localStorage");
245
245
  } catch (e2) {
246
- v && console.warn("[Sailfish] Failed to clear funcSpan state from localStorage:", e2);
246
+ w && console.warn("[Sailfish] Failed to clear funcSpan state from localStorage:", e2);
247
247
  }
248
248
  }
249
249
  function clearStaleFuncSpanState() {
250
- R = false, _ = null, P = false, clearGlobalFuncSpanState(), v && console.log("[Sailfish] Cleared stale function span tracking state (backend validation failed)");
250
+ R = false, _ = null, P = false, clearGlobalFuncSpanState(), w && console.log("[Sailfish] Cleared stale function span tracking state (backend validation failed)");
251
251
  }
252
252
  let j = false;
253
253
  function restoreFuncSpanState() {
@@ -259,14 +259,14 @@ function restoreFuncSpanState() {
259
259
  const e3 = localStorage.getItem(B);
260
260
  if (!e3) return null;
261
261
  const t2 = JSON.parse(e3);
262
- return v && console.log("[Sailfish] Loaded funcSpan state from localStorage:", t2), t2;
262
+ return w && console.log("[Sailfish] Loaded funcSpan state from localStorage:", t2), t2;
263
263
  } catch (e3) {
264
- return v && console.warn("[Sailfish] Failed to load funcSpan state from localStorage:", e3), null;
264
+ return w && console.warn("[Sailfish] Failed to load funcSpan state from localStorage:", e3), null;
265
265
  }
266
266
  })();
267
- if (e2 && e2.enabled) if (R = true, _ = e2.expirationTimestampMs, P = false, v && console.log("[Sailfish] Restored global function span tracking from localStorage:", { enabled: true, expirationTime: _ }), null !== _) {
268
- Date.now() >= _ ? (R = false, _ = null, clearGlobalFuncSpanState(), v && console.log("[Sailfish] Persisted tracking already expired, cleared state")) : v && console.log("[Sailfish] Function span tracking is active and valid (temporary until WebSocket confirms)");
269
- } else v && console.log("[Sailfish] Function span tracking is active (no expiration, temporary until WebSocket confirms)");
267
+ if (e2 && e2.enabled) if (R = true, _ = e2.expirationTimestampMs, P = false, w && console.log("[Sailfish] Restored global function span tracking from localStorage:", { enabled: true, expirationTime: _ }), null !== _) {
268
+ Date.now() >= _ ? (R = false, _ = null, clearGlobalFuncSpanState(), w && console.log("[Sailfish] Persisted tracking already expired, cleared state")) : w && console.log("[Sailfish] Function span tracking is active and valid (temporary until WebSocket confirms)");
269
+ } else w && console.log("[Sailfish] Function span tracking is active (no expiration, temporary until WebSocket confirms)");
270
270
  }
271
271
  function isWebSocketOpen(e2) {
272
272
  return (e2 == null ? void 0 : e2.readyState) === WebSocket.OPEN;
@@ -292,10 +292,13 @@ async function flushBufferedEvents() {
292
292
  T = (async () => {
293
293
  var _a, _b;
294
294
  const e2 = await (async function getAllIndexedEvents() {
295
- return await withStore$1("readonly", (e3) => new Promise((t3) => {
296
- const n2 = e3.getAll();
297
- n2.onsuccess = () => t3(n2.result), n2.onerror = () => t3([]);
298
- })) ?? [];
295
+ const e3 = await withStore$1("readonly", (e4) => new Promise((t4) => {
296
+ const n3 = e4.getAll();
297
+ n3.onsuccess = () => t4(n3.result), n3.onerror = () => t4([]);
298
+ })) ?? [], t3 = Date.now(), n2 = [], i2 = [];
299
+ for (const o2 of e3) "number" == typeof (o2 == null ? void 0 : o2.timestamp) && t3 - o2.timestamp >= 864e5 ? "number" == typeof o2.id && i2.push(o2.id) : n2.push(o2);
300
+ return i2.length > 0 && deleteEventsByIds(i2).catch(() => {
301
+ }), n2;
299
302
  })(), t2 = {};
300
303
  for (const n2 of e2) {
301
304
  const e3 = ((_b = (_a = n2 == null ? void 0 : n2.data) == null ? void 0 : _a.data) == null ? void 0 : _b.sessionId) ?? "unknown-session";
@@ -324,7 +327,7 @@ function sendEvent(e2) {
324
327
  e2.app_url || (e2.app_url = getCachedHref()), !I && isWebSocketOpen(x) && wsSendPayload({ type: "event", event: e2, mapUuid: window.sfMapUuid }) || queueEventForIDB(e2);
325
328
  }
326
329
  function handleWsOpen() {
327
- v && (console.log("[Sailfish] WebSocket connection opened"), console.log("[Sailfish] Function span tracking state: " + (R ? "ENABLED" : "DISABLED"))), (async () => {
330
+ w && (console.log("[Sailfish] WebSocket connection opened"), console.log("[Sailfish] Function span tracking state: " + (R ? "ENABLED" : "DISABLED"))), (async () => {
328
331
  try {
329
332
  I = true, await flushNotifyQueue(), await flushBufferedEvents();
330
333
  } finally {
@@ -336,29 +339,29 @@ function handleWsOpen() {
336
339
  })();
337
340
  }
338
341
  function handleWsClose() {
339
- null != E && (clearInterval(E), E = null), v && console.log("[Sailfish] WebSocket closed");
342
+ null != E && (clearInterval(E), E = null), w && console.log("[Sailfish] WebSocket closed");
340
343
  }
341
344
  function handleWsMessage(e2) {
342
345
  try {
343
346
  const t2 = JSON.parse(e2);
344
- if ("funcSpanTrackingControl" === t2.type) if (v && console.log("[Sailfish] Received funcSpanTrackingControl message:", { enabled: t2.enabled, timeoutSeconds: t2.timeoutSeconds, expirationTimestampMs: t2.expirationTimestampMs }), null !== D && (window.clearTimeout(D), D = null), R = t2.enabled, P = false, v && console.log("[Sailfish] Function span tracking " + (t2.enabled ? "ENABLED (GLOBAL)" : "DISABLED (GLOBAL)")), t2.enabled) {
347
+ if ("funcSpanTrackingControl" === t2.type) if (w && console.log("[Sailfish] Received funcSpanTrackingControl message:", { enabled: t2.enabled, timeoutSeconds: t2.timeoutSeconds, expirationTimestampMs: t2.expirationTimestampMs }), null !== D && (window.clearTimeout(D), D = null), R = t2.enabled, P = false, w && console.log("[Sailfish] Function span tracking " + (t2.enabled ? "ENABLED (GLOBAL)" : "DISABLED (GLOBAL)")), t2.enabled) {
345
348
  if (t2.expirationTimestampMs) {
346
349
  _ = t2.expirationTimestampMs;
347
350
  const e3 = Date.now(), n2 = _ - e3;
348
- v && console.log(`[Sailfish] Server expiration timestamp: ${_}, ms until expiration: ${n2}`), n2 > 0 ? (saveGlobalFuncSpanState(true, _), D = window.setTimeout(() => {
349
- P || (R = false, _ = null, clearGlobalFuncSpanState(), v && console.log("[Sailfish] GLOBAL function span tracking auto-disabled at server expiration time"), wsSendPayload({ type: "funcSpanTrackingExpired", sessionId: getOrSetSessionId(), expiredAt: Date.now() }), v && console.log("[Sailfish] Notified backend that function span tracking expired"));
350
- }, n2)) : (R = false, _ = null, clearGlobalFuncSpanState(), v && console.log("[Sailfish] Tracking already expired, not enabling"));
351
+ w && console.log(`[Sailfish] Server expiration timestamp: ${_}, ms until expiration: ${n2}`), n2 > 0 ? (saveGlobalFuncSpanState(true, _), D = window.setTimeout(() => {
352
+ P || (R = false, _ = null, clearGlobalFuncSpanState(), w && console.log("[Sailfish] GLOBAL function span tracking auto-disabled at server expiration time"), wsSendPayload({ type: "funcSpanTrackingExpired", sessionId: getOrSetSessionId(), expiredAt: Date.now() }), w && console.log("[Sailfish] Notified backend that function span tracking expired"));
353
+ }, n2)) : (R = false, _ = null, clearGlobalFuncSpanState(), w && console.log("[Sailfish] Tracking already expired, not enabling"));
351
354
  } else {
352
355
  const e3 = t2.timeoutSeconds || 3600;
353
356
  e3 > 0 && (_ = Date.now() + 1e3 * e3, saveGlobalFuncSpanState(true, _), D = window.setTimeout(() => {
354
- P || (R = false, _ = null, clearGlobalFuncSpanState(), v && console.log(`[Sailfish] GLOBAL function span tracking auto-disabled after ${e3}s (legacy)`), wsSendPayload({ type: "funcSpanTrackingExpired", sessionId: getOrSetSessionId(), expiredAt: Date.now() }), v && console.log("[Sailfish] Notified backend that function span tracking expired (legacy timeout)"));
357
+ P || (R = false, _ = null, clearGlobalFuncSpanState(), w && console.log(`[Sailfish] GLOBAL function span tracking auto-disabled after ${e3}s (legacy)`), wsSendPayload({ type: "funcSpanTrackingExpired", sessionId: getOrSetSessionId(), expiredAt: Date.now() }), w && console.log("[Sailfish] Notified backend that function span tracking expired (legacy timeout)"));
355
358
  }, 1e3 * e3));
356
359
  }
357
360
  try {
358
361
  const e3 = getOrSetSessionId();
359
- wsSendPayload({ type: "funcSpanTrackingSessionReport", sessionId: e3, enabled: true, configurationType: "global" }), v && console.log(`[Sailfish] GLOBAL tracking session report sent for session: ${e3}`);
362
+ wsSendPayload({ type: "funcSpanTrackingSessionReport", sessionId: e3, enabled: true, configurationType: "global" }), w && console.log(`[Sailfish] GLOBAL tracking session report sent for session: ${e3}`);
360
363
  } catch (e3) {
361
- v && console.warn("[Sailfish] Failed to send GLOBAL tracking session report:", e3);
364
+ w && console.warn("[Sailfish] Failed to send GLOBAL tracking session report:", e3);
362
365
  }
363
366
  } else _ = null, clearGlobalFuncSpanState();
364
367
  } catch (e3) {
@@ -370,7 +373,7 @@ function initializeWebSocket(t2, n2, i2, o2, a2 = false) {
370
373
  const t3 = new URL(e2);
371
374
  return `${t3.hostname}${t3.port ? `:${t3.port}` : ""}`;
372
375
  })(t2);
373
- let r2 = `${"https:" === new URL(t2).protocol ? "wss" : "ws"}://${s2}/ws/notify/?apiKey=${n2}&sessionId=${i2}&sender=JS%2FTS&version=1.11.4`;
376
+ let r2 = `${"https:" === new URL(t2).protocol ? "wss" : "ws"}://${s2}/ws/notify/?apiKey=${n2}&sessionId=${i2}&sender=JS%2FTS&version=1.11.6`;
374
377
  if (o2 && (r2 += `&envValue=${encodeURIComponent(o2)}`), k = a2 ? (function tryCreateWsWorker() {
375
378
  if ("undefined" == typeof Worker) return null;
376
379
  try {
@@ -387,10 +390,10 @@ function initializeWebSocket(t2, n2, i2, o2, a2 = false) {
387
390
  const n3 = e3.data;
388
391
  "open" === n3.type ? (t3.readyState = WebSocket.OPEN, handleWsOpen()) : "close" === n3.type ? (t3.readyState = WebSocket.CLOSED, handleWsClose()) : "message" === n3.type && handleWsMessage(n3.data);
389
392
  }, k.onerror = () => {
390
- v && console.warn("[Sailfish] WebSocket worker error");
391
- }, k.postMessage({ type: "init", wsUrl: r2 }), v && console.log("[Sailfish] WebSocket running in Web Worker (off main thread)"), t3;
393
+ w && console.warn("[Sailfish] WebSocket worker error");
394
+ }, k.postMessage({ type: "init", wsUrl: r2 }), w && console.log("[Sailfish] WebSocket running in Web Worker (off main thread)"), t3;
392
395
  }
393
- v && console.log("[Sailfish] WebSocket running on main thread (Worker unavailable)");
396
+ w && console.log("[Sailfish] WebSocket running on main thread (Worker unavailable)");
394
397
  const l2 = new e(r2, [], { connectionTimeout: 3e4 }), c2 = { get readyState() {
395
398
  return l2.readyState;
396
399
  }, close: () => {
@@ -402,26 +405,26 @@ function sendMessage(e2) {
402
405
  "sessionId" in e2 || (e2.sessionId = getOrSetSessionId()), e2.app_url || (e2.app_url = getCachedHref()), I || !isWebSocketOpen(x) ? saveNotifyMessageToIDB(JSON.stringify(e2)) : wsSendPayload(e2) || saveNotifyMessageToIDB(JSON.stringify(e2));
403
406
  }
404
407
  function enableFunctionSpanTracking() {
405
- if (v && console.log("[Sailfish] enableFunctionSpanTracking() called - Report Issue recording started (LOCAL MODE)"), R = true, P = true, _ = null, null !== D && (window.clearTimeout(D), D = null), isWebSocketOpen(x)) {
408
+ if (w && console.log("[Sailfish] enableFunctionSpanTracking() called - Report Issue recording started (LOCAL MODE)"), R = true, P = true, _ = null, null !== D && (window.clearTimeout(D), D = null), isWebSocketOpen(x)) {
406
409
  wsSendPayload({ type: "funcSpanTrackingSessionReport", sessionId: getOrSetSessionId(), enabled: true, configurationType: S });
407
- } else v && console.warn("[Sailfish] WebSocket not open, cannot report LOCAL tracking session");
410
+ } else w && console.warn("[Sailfish] WebSocket not open, cannot report LOCAL tracking session");
408
411
  }
409
412
  function disableFunctionSpanTracking() {
410
- if (v && console.log("[Sailfish] disableFunctionSpanTracking() called - Report Issue recording stopped"), isWebSocketOpen(x)) {
413
+ if (w && console.log("[Sailfish] disableFunctionSpanTracking() called - Report Issue recording stopped"), isWebSocketOpen(x)) {
411
414
  wsSendPayload({ type: "funcSpanTrackingSessionReport", sessionId: getOrSetSessionId(), enabled: false, configurationType: S });
412
415
  } else console.warn("[FUNCSPAN STOP] ✗ WebSocket not open, cannot notify tracking end");
413
- P && (R = false, P = false, _ = null, v && console.log("[Sailfish] LOCAL tracking mode disabled")), null !== D && (window.clearTimeout(D), D = null);
416
+ P && (R = false, P = false, _ = null, w && console.log("[Sailfish] LOCAL tracking mode disabled")), null !== D && (window.clearTimeout(D), D = null);
414
417
  }
415
418
  function isFunctionSpanTrackingEnabled() {
416
419
  return R;
417
420
  }
418
421
  function initializeFunctionSpanTrackingFromApi(e2) {
419
- e2 && !R ? (R = true, P = false, _ = null, v && console.log("[Sailfish] Function span tracking initialized as ENABLED from API check")) : !e2 && R && (R = false, P = false, _ = null, v && console.log("[Sailfish] Function span tracking initialized as DISABLED from API check"));
422
+ e2 && !R ? (R = true, P = false, _ = null, w && console.log("[Sailfish] Function span tracking initialized as ENABLED from API check")) : !e2 && R && (R = false, P = false, _ = null, w && console.log("[Sailfish] Function span tracking initialized as DISABLED from API check"));
420
423
  }
421
424
  function getFuncSpanHeader() {
422
425
  if (!R) return null;
423
426
  if (null !== _) {
424
- if (Date.now() >= _) return R = false, _ = null, clearGlobalFuncSpanState(), v && console.log("[Sailfish] Function span tracking expired on header check - disabling now"), null;
427
+ if (Date.now() >= _) return R = false, _ = null, clearGlobalFuncSpanState(), w && console.log("[Sailfish] Function span tracking expired on header check - disabling now"), null;
425
428
  }
426
429
  return { name: "X-Sf3-FunctionSpanCaptureOverride", value: "1-1-10-10-1-1.0-1-0-0" };
427
430
  }
@@ -439,7 +442,7 @@ function addOrUpdateMetadata(e2) {
439
442
  z && JSON.stringify(z) === JSON.stringify(e2) || (z = e2, sendMessage(t2));
440
443
  }
441
444
  function trackingEvent(e2) {
442
- sendMessage({ type: "trackingEvent", trackingData: e2, timestamp: w() });
445
+ sendMessage({ type: "trackingEvent", trackingData: e2, timestamp: v() });
443
446
  }
444
447
  let N = null;
445
448
  const H = ["https://api.ipify.org?format=json", "https://api.ip.sb/jsonip", "https://api4.my-ip.io/ip.json"];
@@ -449,7 +452,7 @@ function fetchAndSendIp(e2) {
449
452
  const t2 = new AbortController(), n2 = setTimeout(() => t2.abort(), 5e3), i2 = await fetch(e3, { signal: t2.signal });
450
453
  if (clearTimeout(n2), !i2.ok) continue;
451
454
  const o2 = await i2.json(), a2 = o2.ip || o2.origin || null;
452
- if (a2 && "string" == typeof a2 && a2.length <= 45) return void sendMessage({ type: "visitorIp", ip: a2, timestamp: w() });
455
+ if (a2 && "string" == typeof a2 && a2.length <= 45) return void sendMessage({ type: "visitorIp", ip: a2, timestamp: v() });
453
456
  } catch {
454
457
  }
455
458
  N = null;
@@ -476,10 +479,25 @@ async function getConsumerFor(e2, t2) {
476
479
  }
477
480
  return null;
478
481
  }
479
- async function captureError(e2, t2 = false) {
480
- let n2, i2;
481
- e2 instanceof Error ? (n2 = e2.message, i2 = e2.stack || "No stack trace") : "string" == typeof e2 ? (n2 = e2, i2 = "No stack trace available") : (n2 = "Unknown error occurred", i2 = "No stack trace available");
482
- const o2 = await (async function resolveStackTrace(e3) {
482
+ async function captureError(e2, t2 = false, n2) {
483
+ let i2, o2;
484
+ const a2 = [];
485
+ e2 instanceof Error ? (i2 = e2.message || e2.name, o2 = e2.stack || "No stack trace", a2.push(`${e2.name}: ${i2}`)) : "string" == typeof e2 ? (i2 = e2, o2 = "No stack trace available", a2.push(t2 ? `Uncaught (in promise) ${e2}` : e2)) : (i2 = (function describeNonError(e3) {
486
+ if (null === e3) return "null";
487
+ if (void 0 === e3) return "undefined";
488
+ if ("string" == typeof e3) return e3;
489
+ if ("number" == typeof e3 || "boolean" == typeof e3 || "bigint" == typeof e3) return String(e3);
490
+ if (e3 instanceof Event) {
491
+ const t3 = e3.target, n3 = (t3 == null ? void 0 : t3.tagName) ? `<${t3.tagName.toLowerCase()}>` : "";
492
+ return `[${e3.type} Event${n3 ? ` on ${n3}` : ""}${e3.isTrusted ? " trusted" : ""}]`;
493
+ }
494
+ try {
495
+ return JSON.stringify(e3);
496
+ } catch {
497
+ return Object.prototype.toString.call(e3);
498
+ }
499
+ })(e2), o2 = "No stack trace available", a2.push(t2 ? `Uncaught (in promise) ${i2}` : i2)), (n2 == null ? void 0 : n2.filename) && a2.push(`at ${n2.filename}:${n2.lineno ?? 0}:${n2.colno ?? 0}`);
500
+ const s2 = await (async function resolveStackTrace(e3) {
483
501
  if (!e3) return ["No stack trace available"];
484
502
  const t3 = Array.isArray(e3) ? e3 : e3.split("\n"), n3 = [];
485
503
  for (const e4 of t3) {
@@ -488,27 +506,27 @@ async function captureError(e2, t2 = false) {
488
506
  n3.push(e4);
489
507
  continue;
490
508
  }
491
- const [, i3, o3, a3, s3] = t4, r3 = parseInt(a3, 10), l2 = Math.max(0, parseInt(s3, 10) - 1);
492
- if (!Number.isFinite(r3) || !Number.isFinite(l2)) {
509
+ const [, i3, o3, a3, s3] = t4, r3 = parseInt(a3, 10), l3 = Math.max(0, parseInt(s3, 10) - 1);
510
+ if (!Number.isFinite(r3) || !Number.isFinite(l3)) {
493
511
  n3.push(e4 + " [Invalid line/column]");
494
512
  continue;
495
513
  }
496
- const c2 = await getConsumerFor(i3, o3);
497
- if (!c2) {
514
+ const c3 = await getConsumerFor(i3, o3);
515
+ if (!c3) {
498
516
  n3.push(`${e4} [No source map found for ${o3}]`);
499
517
  continue;
500
518
  }
501
519
  const { SourceMapConsumer: d2 } = await getSourceMapModule();
502
- let u2 = c2.originalPositionFor({ line: r3, column: l2, bias: d2.GREATEST_LOWER_BOUND });
503
- if (!u2.source || null == u2.line) for (let e5 = 1; e5 <= 20 && (u2 = c2.originalPositionFor({ line: r3, column: Math.max(0, l2 - e5), bias: d2.GREATEST_LOWER_BOUND }), !u2.source || null == u2.line); e5++) ;
520
+ let u2 = c3.originalPositionFor({ line: r3, column: l3, bias: d2.GREATEST_LOWER_BOUND });
521
+ if (!u2.source || null == u2.line) for (let e5 = 1; e5 <= 20 && (u2 = c3.originalPositionFor({ line: r3, column: Math.max(0, l3 - e5), bias: d2.GREATEST_LOWER_BOUND }), !u2.source || null == u2.line); e5++) ;
504
522
  if (u2.source && null != u2.line) {
505
523
  const e5 = u2.name || "anonymous";
506
524
  n3.push(`${u2.source}:${u2.line}:${u2.column ?? 0} (${e5})`);
507
525
  } else n3.push(`${e4} [No mapping found in ${o3}]`);
508
526
  }
509
527
  return n3;
510
- })(i2), a2 = o2.filter((e3) => !e3.includes("chunk-") && !e3.includes("react-dom")), s2 = a2.length > 0 ? a2 : o2, r2 = Date.now();
511
- sendMessage({ type: "event", event: { type: 6, timestamp: r2, data: { payload: { message: n2, stack: i2, trace: s2, filteredStack: a2, userAgent: navigator.userAgent, url: window.location.href, timestamp: r2, level: "error" } } } });
528
+ })(o2), r2 = s2.filter((e3) => !e3.includes("chunk-") && !e3.includes("react-dom")), l2 = r2.length > 0 ? r2 : s2, c2 = Date.now();
529
+ sendMessage({ type: "event", event: { type: 6, timestamp: c2, data: { payload: { message: i2, stack: o2, trace: l2, filteredStack: r2, payload: a2, userAgent: navigator.userAgent, url: window.location.href, timestamp: c2, level: "error" } } } });
512
530
  }
513
531
  const V = readDebugFlag();
514
532
  const G = readDebugFlag();
@@ -718,7 +736,7 @@ async function initializeRecording(e2, n2, i2, o2, a2, s2 = true, r2 = false, l2
718
736
  }
719
737
  const { record: n4 } = await import("@sailfish-rrweb/rrweb-record-only");
720
738
  if (J = n4, await yieldToMain(), l2) {
721
- const { chunkedSnapshot: i3 } = await import("./chunkSerializer-DOaGGlCg.js"), o3 = n4.mirror;
739
+ const { chunkedSnapshot: i3 } = await import("./chunkSerializer-DkWXHnW4.js"), o3 = n4.mirror;
722
740
  let a3 = true;
723
741
  const s3 = [];
724
742
  n4({ emit(e3) {
@@ -1076,7 +1094,7 @@ function renderCustomMultiSelect(e2, t2, n2, i2, o2 = false) {
1076
1094
  }
1077
1095
  const ye = { enabled: false, openModalExistingMode: { key: "e", requireCmdCtrl: false }, openModalCaptureNewMode: { key: "n", requireCmdCtrl: false }, closeModal: { key: "escape", requireCmdCtrl: false }, submitReport: { key: "enter", requireCmdCtrl: true }, startRecording: { key: "r", requireCmdCtrl: false }, stopRecording: { key: "escape", requireCmdCtrl: true } }, be = { shortcuts: { ...ye }, resolveSessionId: null, apiKey: null, backendApi: null, triageBaseUrl: "https://app.sailfishqa.com", deactivateIsolation: () => {
1078
1096
  }, integrationData: null, showEngTicketFieldsDefault: false };
1079
- let we = null, ve = false;
1097
+ let ve = null, we = false;
1080
1098
  function setupCustomMultiSelectListeners(e2, t2) {
1081
1099
  const n2 = document.getElementById(`${e2}-container`), i2 = document.getElementById(`${e2}-dropdown`);
1082
1100
  if (!n2 || !i2) return;
@@ -1325,10 +1343,10 @@ function getSessionIdSafely() {
1325
1343
  return be.resolveSessionId();
1326
1344
  }
1327
1345
  function openReportIssueModal(e2) {
1328
- he ? stopRecording() : (ve = (e2 == null ? void 0 : e2.showEngTicketFields) ?? be.showEngTicketFieldsDefault, injectModalHTML(), we && document.body.appendChild(we));
1346
+ he ? stopRecording() : (we = (e2 == null ? void 0 : e2.showEngTicketFields) ?? be.showEngTicketFieldsDefault, injectModalHTML(), ve && document.body.appendChild(ve));
1329
1347
  }
1330
1348
  function closeModal() {
1331
- be.deactivateIsolation(), document.activeElement instanceof HTMLElement && document.activeElement.blur(), (we == null ? void 0 : we.parentNode) && we.parentNode.removeChild(we), we = null, he || (function resetState() {
1349
+ be.deactivateIsolation(), document.activeElement instanceof HTMLElement && document.activeElement.blur(), (ve == null ? void 0 : ve.parentNode) && ve.parentNode.removeChild(ve), ve = null, he || (function resetState() {
1332
1350
  pe = getInitialState(), fe = null, ge = null;
1333
1351
  })(), me && (clearInterval(me), setTimerInterval(null));
1334
1352
  }
@@ -1389,9 +1407,9 @@ function activateModalIsolation(e2) {
1389
1407
  };
1390
1408
  }
1391
1409
  function injectModalHTML(e2 = "lookback") {
1392
- we && (we.remove(), we = null), we = document.createElement("div"), we.id = "sf-report-issue-modal";
1410
+ ve && (ve.remove(), ve = null), ve = document.createElement("div"), ve.id = "sf-report-issue-modal";
1393
1411
  const t2 = "startnow" === e2;
1394
- we.innerHTML = `
1412
+ ve.innerHTML = `
1395
1413
  <div style="position:fixed; inset:0; background:rgba(0,0,0,0.4); z-index:9998;"></div>
1396
1414
  <div style="position:fixed; top:50%; left:50%; transform:translate(-50%, -50%);
1397
1415
  background:#fff; border-radius:12px;
@@ -1517,7 +1535,7 @@ function injectModalHTML(e2 = "lookback") {
1517
1535
  Create an Issue
1518
1536
  </label>
1519
1537
 
1520
- <label id="sf-create-eng-ticket-label" style="display:${be.integrationData && ve ? "flex" : "none"}; align-items:center; gap:8px; font-size:14px; font-weight:500; cursor:pointer;">
1538
+ <label id="sf-create-eng-ticket-label" style="display:${be.integrationData && we ? "flex" : "none"}; align-items:center; gap:8px; font-size:14px; font-weight:500; cursor:pointer;">
1521
1539
  <input type="checkbox" id="sf-create-eng-ticket-checkbox" ${pe.createEngTicket ? "checked" : ""}
1522
1540
  style="width:16px; height:16px; accent-color:#295DBF; cursor:pointer;">
1523
1541
  Create an Eng Ticket
@@ -1582,8 +1600,8 @@ function injectModalHTML(e2 = "lookback") {
1582
1600
  </div>
1583
1601
  </div>
1584
1602
  </div>
1585
- `, pe.mode = e2, document.body.appendChild(we), (function bindListeners() {
1586
- const e3 = we == null ? void 0 : we.querySelectorAll(".sf-issue-tab"), t3 = document.getElementById("sf-start-recording-btn"), n2 = document.getElementById("sf-modal-close-btn"), i2 = document.getElementById("sf-issue-submit-btn"), o2 = document.getElementById("sf-lookback-minutes");
1603
+ `, pe.mode = e2, document.body.appendChild(ve), (function bindListeners() {
1604
+ const e3 = ve == null ? void 0 : ve.querySelectorAll(".sf-issue-tab"), t3 = document.getElementById("sf-start-recording-btn"), n2 = document.getElementById("sf-modal-close-btn"), i2 = document.getElementById("sf-issue-submit-btn"), o2 = document.getElementById("sf-lookback-minutes");
1587
1605
  e3 == null ? void 0 : e3.forEach((e4) => {
1588
1606
  e4.addEventListener("click", (e5) => {
1589
1607
  const t4 = e5.currentTarget.dataset.mode;
@@ -1593,7 +1611,7 @@ function injectModalHTML(e2 = "lookback") {
1593
1611
  o2 && o2.addEventListener("change", () => {
1594
1612
  "lookback" === pe.mode && (i2.disabled = false, i2.style.opacity = "1", i2.style.cursor = "pointer");
1595
1613
  });
1596
- const a2 = we == null ? void 0 : we.querySelectorAll(".sf-collapsible-header");
1614
+ const a2 = ve == null ? void 0 : ve.querySelectorAll(".sf-collapsible-header");
1597
1615
  a2 == null ? void 0 : a2.forEach((e4) => {
1598
1616
  e4.addEventListener("click", (e5) => {
1599
1617
  const t4 = e5.currentTarget, n3 = t4.dataset.target, i3 = document.getElementById(n3), o3 = t4.querySelector(".sf-chevron");
@@ -1683,7 +1701,7 @@ function injectModalHTML(e2 = "lookback") {
1683
1701
  }, 1e3);
1684
1702
  })();
1685
1703
  });
1686
- we == null ? void 0 : we.addEventListener("click", (e4) => {
1704
+ ve == null ? void 0 : ve.addEventListener("click", (e4) => {
1687
1705
  var _a;
1688
1706
  if (e4.target.closest("#sf-issue-submit-btn")) {
1689
1707
  const e5 = ((_a = document.getElementById("sf-issue-description")) == null ? void 0 : _a.value) || "", t4 = pe.mode;
@@ -1737,7 +1755,7 @@ function injectModalHTML(e2 = "lookback") {
1737
1755
  })(`${n3}`, `${i3}`, e5, "startnow" === t4 ? "RECORDED" : "LOOKBACK");
1738
1756
  }
1739
1757
  });
1740
- })(), be.deactivateIsolation = activateModalIsolation(we), be.integrationData && pe.createEngTicket ? initializeEngTicketForm() : be.integrationData || (pe.createEngTicket = false), be.apiKey && be.backendApi && refreshIntegrationData(be.apiKey, be.backendApi).then((e3) => {
1758
+ })(), be.deactivateIsolation = activateModalIsolation(ve), be.integrationData && pe.createEngTicket ? initializeEngTicketForm() : be.integrationData || (pe.createEngTicket = false), be.apiKey && be.backendApi && refreshIntegrationData(be.apiKey, be.backendApi).then((e3) => {
1741
1759
  if (!e3 || !document.getElementById("sf-report-issue-modal")) return;
1742
1760
  be.integrationData = e3;
1743
1761
  const t3 = document.getElementById("sf-eng-ticket-fields-container");
@@ -1745,7 +1763,7 @@ function injectModalHTML(e2 = "lookback") {
1745
1763
  const e4 = generateEngTicketFieldsHTML();
1746
1764
  e4 && (t3.innerHTML = e4, initializeEngTicketForm(), bindEngTicketListeners(), updateFormWithIntegrationData(pe), renderDynamicFields(pe.engTicketProject, pe.engTicketIssueType));
1747
1765
  }
1748
- if (ve) {
1766
+ if (we) {
1749
1767
  const e4 = document.getElementById("sf-create-eng-ticket-label");
1750
1768
  e4 && (e4.style.display = "flex");
1751
1769
  }
@@ -1766,7 +1784,7 @@ function initializeEngTicketForm() {
1766
1784
  }
1767
1785
  function setActiveTab(e2) {
1768
1786
  pe.mode = e2;
1769
- const t2 = we == null ? void 0 : we.querySelector("#sf-tab-lookback"), n2 = we == null ? void 0 : we.querySelector("#sf-tab-startnow");
1787
+ const t2 = ve == null ? void 0 : ve.querySelector("#sf-tab-lookback"), n2 = ve == null ? void 0 : ve.querySelector("#sf-tab-startnow");
1770
1788
  "lookback" === e2 ? (t2.style.background = "white", t2.style.color = "#0F172A", n2.style.background = "transparent", n2.style.color = "#64748B") : (n2.style.background = "white", n2.style.color = "#0F172A", t2.style.background = "transparent", t2.style.color = "#64748B");
1771
1789
  }
1772
1790
  function updateModeSpecificUI(e2) {
@@ -2137,8 +2155,8 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
2137
2155
  delete h2[n];
2138
2156
  const b2 = getFuncSpanHeader();
2139
2157
  b2 && delete h2[b2.name];
2140
- const w2 = `${c3}/${p2.page_visit_uuid}/${u3}`;
2141
- h2[n] = w2, b2 && (h2[b2.name] = b2.value);
2158
+ const v2 = `${c3}/${p2.page_visit_uuid}/${u3}`;
2159
+ h2[n] = v2, b2 && (h2[b2.name] = b2.value);
2142
2160
  maskAuthorizationHeader(h2);
2143
2161
  try {
2144
2162
  let b3 = await (async function injectHeader(e5, t3, i5, o5, a4, s4, r3) {
@@ -2153,7 +2171,7 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
2153
2171
  const c4 = { ...o5 }, d4 = new Headers(o5.headers || {});
2154
2172
  return d4.set(n, `${a4}/${s4}/${r3}`), l3 && (d4.set(l3.name, l3.value), ke && console.log("[Sailfish] Added funcspan header to HTTP fetch:", { url: "string" == typeof i5 ? i5 : i5.href, header: l3.name })), c4.headers = d4, await e5.call(t3, i5, c4);
2155
2173
  }
2156
- })(e4, i4, a3, s3, c3, p2.page_visit_uuid, u3), w3 = false;
2174
+ })(e4, i4, a3, s3, c3, p2.page_visit_uuid, u3), v3 = false;
2157
2175
  Ee.includes(b3.status) && (ke && console.log("Perform retry as status was fail:", b3), delete h2[n], b3 = await (async function retryWithoutPropagateHeaders(e5, t3, i5, o5) {
2158
2176
  try {
2159
2177
  let o6 = i5[0], a4 = i5[1] || {};
@@ -2172,8 +2190,8 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
2172
2190
  } catch (e6) {
2173
2191
  throw ke && console.log(`Retry without ${n} for ${o5} also failed:`, e6), e6;
2174
2192
  }
2175
- })(e4, i4, o4, d3), w3 = true);
2176
- const v2 = Date.now(), S2 = b3.status, k2 = b3.ok, x2 = k2 ? "" : `Request Error: ${b3.statusText}`;
2193
+ })(e4, i4, o4, d3), v3 = true);
2194
+ const w2 = Date.now(), S2 = b3.status, k2 = b3.ok, x2 = k2 ? "" : `Request Error: ${b3.statusText}`;
2177
2195
  let I2 = null;
2178
2196
  try {
2179
2197
  I2 = {}, b3.headers.forEach((e5, t3) => {
@@ -2182,7 +2200,7 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
2182
2200
  } catch (e5) {
2183
2201
  ke && console.warn("[Sailfish] Failed to capture response headers:", e5), I2 = null;
2184
2202
  }
2185
- const T2 = { type: 27, timestamp: v2, sessionId: c3, data: { request_id: u3, session_id: c3, timestamp_start: g2, timestamp_end: v2, response_code: S2, success: k2, error: x2, method: f2, url: d3, retry_without_trace_id: w3, request_headers: h2, request_body: m2, response_headers: I2, response_body: null }, ...p2 }, sendEventWithBody = (e5) => {
2203
+ const T2 = { type: 27, timestamp: w2, sessionId: c3, data: { request_id: u3, session_id: c3, timestamp_start: g2, timestamp_end: w2, response_code: S2, success: k2, error: x2, method: f2, url: d3, retry_without_trace_id: v3, request_headers: h2, request_body: m2, response_headers: I2, response_body: null }, ...p2 }, sendEventWithBody = (e5) => {
2186
2204
  T2.data.response_body = e5, y2 ? y2.text().then((e6) => {
2187
2205
  T2.data.request_body = e6, sendEvent(T2);
2188
2206
  }, () => {
@@ -2270,7 +2288,7 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
2270
2288
  })(e3, i3, o3, d2, u2, a2, c2);
2271
2289
  } });
2272
2290
  }
2273
- async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-service.sailfishqa.com", domainsToPropagateHeaderTo: i2 = ["*"], domainsToNotPropagateHeaderTo: o2 = [], serviceVersion: a2, serviceIdentifier: s2, gitSha: r2, serviceAdditionalMetadata: l2, enableIpTracking: c2, captureStreamingResponseBody: d2 = true, captureResponseBodyMaxMb: u2 = 10, captureStreamPrefixKb: p2 = 64, captureStreamTimeoutMs: f2 = 1e4, enableFiberTracking: m2 = false, deferRecording: h2, deferRecordingStart: y2, chunkSnapshot: b2, useWsWorker: w2 = true, capturePerformanceMetrics: v2 = true, maskTextClass: S2, library: k2, headlessRecording: x2 = false }) {
2291
+ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-service.sailfishqa.com", domainsToPropagateHeaderTo: i2 = ["*"], domainsToNotPropagateHeaderTo: o2 = [], serviceVersion: a2, serviceIdentifier: s2, gitSha: r2, serviceAdditionalMetadata: l2, enableIpTracking: c2, captureStreamingResponseBody: d2 = true, captureResponseBodyMaxMb: u2 = 10, captureStreamPrefixKb: p2 = 64, captureStreamTimeoutMs: f2 = 1e4, enableFiberTracking: m2 = false, deferRecording: h2, deferRecordingStart: y2, chunkSnapshot: b2, useWsWorker: v2 = true, capturePerformanceMetrics: w2 = true, maskTextClass: S2, library: k2, headlessRecording: x2 = false }) {
2274
2292
  var _a, _b;
2275
2293
  if (!x2 && (function isHeadlessOrLighthouse() {
2276
2294
  try {
@@ -2353,11 +2371,11 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
2353
2371
  };
2354
2372
  })(o2, C2, i2), E2.xhrPatched = true), E2.fetchPatched || (setupFetchInterceptor(o2, C2, i2), E2.fetchPatched = true), await yieldToMain(), E2.domEventsInit || (initializeDomContentEvents(T2), E2.domEventsInit = true), await yieldToMain(), E2.consoleInit || (initializeConsolePlugin(Ae, T2), E2.consoleInit = true), await yieldToMain(), E2.errorInit || (!(function initializeErrorInterceptor() {
2355
2373
  window.addEventListener("error", (e3) => {
2356
- captureError(e3.error || e3.message);
2374
+ captureError(e3.error ?? e3.message, false, { filename: e3.filename, lineno: e3.lineno, colno: e3.colno });
2357
2375
  }), window.addEventListener("unhandledrejection", (e3) => {
2358
2376
  captureError(e3.reason, true);
2359
2377
  });
2360
- })(), E2.errorInit = true), await yieldToMain(), !E2.perfInit && v2 && (initializePerformancePlugin(T2), E2.perfInit = true), await yieldToMain(), _ensureModuleSideEffects(), (function storeCredentialsAndConnection({ apiKey: e3, backendApi: t3 }) {
2378
+ })(), E2.errorInit = true), await yieldToMain(), !E2.perfInit && w2 && (initializePerformancePlugin(T2), E2.perfInit = true), await yieldToMain(), _ensureModuleSideEffects(), (function storeCredentialsAndConnection({ apiKey: e3, backendApi: t3 }) {
2361
2379
  g && (sessionStorage.setItem("sailfishApiKey", e3), sessionStorage.setItem("sailfishBackendApi", t3));
2362
2380
  })({ apiKey: e2, backendApi: t2 }), !isFunctionSpanTrackingEnabled() || E2.ws && 1 === E2.ws.readyState || fetchFunctionSpanTrackingEnabled(e2, t2).then((e3) => {
2363
2381
  var _a2;
@@ -2410,7 +2428,7 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
2410
2428
  if ((_b = h3.data) == null ? void 0 : _b.startRecordingSession) {
2411
2429
  const n3 = (l2 == null ? void 0 : l2.env) || (l2 == null ? void 0 : l2.environment);
2412
2430
  await yieldToMain();
2413
- const i4 = await initializeRecording(y3, t2, e2, T2, n3, I2, w2, b2 ?? false);
2431
+ const i4 = await initializeRecording(y3, t2, e2, T2, n3, I2, v2, b2 ?? false);
2414
2432
  E2.ws = i4, E2.initialized = true, trackDomainChangesOnce(), E2.sentMapUuidOnce || (!(function sendMapUuidIfAvailable(e3 = "", t3 = "") {
2415
2433
  window.sfMapUuid && sendMessage({ type: "mapUuid", data: { mapUuid: window.sfMapUuid, serviceIdentifier: e3, serviceVersion: t3 } });
2416
2434
  })(s2, a2), E2.sentMapUuidOnce = true);
@@ -2442,28 +2460,28 @@ const initRecorder = async (e2) => {
2442
2460
  })), t2.initPromise);
2443
2461
  };
2444
2462
  export {
2445
- initializeDomContentEvents as A,
2446
- initializeFunctionSpanTrackingFromApi as B,
2447
- initializePerformancePlugin as C,
2463
+ initializeFunctionSpanTrackingFromApi as A,
2464
+ initializePerformancePlugin as B,
2465
+ initializeRecording as C,
2448
2466
  Me as D,
2449
- initializeRecording as E,
2450
- initializeWebSocket as F,
2451
- invalidateUrlCache as G,
2452
- isFunctionSpanTrackingEnabled as H,
2453
- matchUrlWithWildcard as I,
2454
- w as J,
2455
- onNavigationChange as K,
2456
- openReportIssueModal as L,
2457
- restoreFuncSpanState as M,
2458
- sendDomainsToNotPropagateHeaderTo as N,
2459
- sendEvent as O,
2460
- sendGraphQLRequest as P,
2461
- sendMessage as Q,
2462
- startRecording as R,
2467
+ initializeWebSocket as E,
2468
+ invalidateUrlCache as F,
2469
+ isFunctionSpanTrackingEnabled as G,
2470
+ matchUrlWithWildcard as H,
2471
+ v as I,
2472
+ onNavigationChange as J,
2473
+ openReportIssueModal as K,
2474
+ restoreFuncSpanState as L,
2475
+ sendDomainsToNotPropagateHeaderTo as M,
2476
+ sendEvent as N,
2477
+ sendGraphQLRequest as O,
2478
+ sendMessage as P,
2479
+ startRecording as Q,
2480
+ startRecordingSession as R,
2463
2481
  $e as S,
2464
- startRecordingSession as T,
2465
- trackingEvent as U,
2466
- withAppUrlMetadata as V,
2482
+ trackingEvent as T,
2483
+ withAppUrlMetadata as U,
2484
+ yieldToMain as V,
2467
2485
  Ae as a,
2468
2486
  addOrUpdateMetadata as b,
2469
2487
  buildBatches as c,
@@ -2488,6 +2506,6 @@ export {
2488
2506
  getUrlAndStoredUuids as v,
2489
2507
  identify as w,
2490
2508
  initRecorder as x,
2491
- yieldToMain as y,
2492
- initializeConsolePlugin as z
2509
+ initializeConsolePlugin as y,
2510
+ initializeDomContentEvents as z
2493
2511
  };
Binary file
Binary file
@@ -93,23 +93,56 @@ export async function resolveStackTrace(stackTrace) {
93
93
  }
94
94
  return out;
95
95
  }
96
+ function describeNonError(value) {
97
+ if (value === null)
98
+ return "null";
99
+ if (value === undefined)
100
+ return "undefined";
101
+ if (typeof value === "string")
102
+ return value;
103
+ if (typeof value === "number" ||
104
+ typeof value === "boolean" ||
105
+ typeof value === "bigint") {
106
+ return String(value);
107
+ }
108
+ if (value instanceof Event) {
109
+ const target = value.target;
110
+ const tag = target?.tagName ? `<${target.tagName.toLowerCase()}>` : "";
111
+ return `[${value.type} Event${tag ? ` on ${tag}` : ""}${value.isTrusted ? " trusted" : ""}]`;
112
+ }
113
+ try {
114
+ return JSON.stringify(value);
115
+ }
116
+ catch {
117
+ return Object.prototype.toString.call(value);
118
+ }
119
+ }
96
120
  /**
97
121
  * Captures full error details and resolves the stack trace.
98
122
  */
99
- async function captureError(error, isPromiseRejection = false) {
123
+ async function captureError(error, isPromiseRejection = false, location) {
100
124
  let errorMessage;
101
125
  let stack;
126
+ const payload = [];
102
127
  if (error instanceof Error) {
103
- errorMessage = error.message;
128
+ errorMessage = error.message || error.name;
104
129
  stack = error.stack || "No stack trace";
130
+ payload.push(`${error.name}: ${errorMessage}`);
105
131
  }
106
132
  else if (typeof error === "string") {
107
133
  errorMessage = error;
108
134
  stack = "No stack trace available";
135
+ payload.push(isPromiseRejection ? `Uncaught (in promise) ${error}` : error);
109
136
  }
110
137
  else {
111
- errorMessage = "Unknown error occurred";
138
+ errorMessage = describeNonError(error);
112
139
  stack = "No stack trace available";
140
+ payload.push(isPromiseRejection
141
+ ? `Uncaught (in promise) ${errorMessage}`
142
+ : errorMessage);
143
+ }
144
+ if (location?.filename) {
145
+ payload.push(`at ${location.filename}:${location.lineno ?? 0}:${location.colno ?? 0}`);
113
146
  }
114
147
  const mappedStack = await resolveStackTrace(stack);
115
148
  const filteredStack = mappedStack.filter((line) => !line.includes("chunk-") && !line.includes("react-dom"));
@@ -120,6 +153,7 @@ async function captureError(error, isPromiseRejection = false) {
120
153
  stack,
121
154
  trace,
122
155
  filteredStack,
156
+ payload,
123
157
  userAgent: navigator.userAgent,
124
158
  url: window.location.href,
125
159
  timestamp,
@@ -142,7 +176,11 @@ async function captureError(error, isPromiseRejection = false) {
142
176
  */
143
177
  export function initializeErrorInterceptor() {
144
178
  window.addEventListener("error", (event) => {
145
- captureError(event.error || event.message);
179
+ captureError(event.error ?? event.message, false, {
180
+ filename: event.filename,
181
+ lineno: event.lineno,
182
+ colno: event.colno,
183
+ });
146
184
  });
147
185
  window.addEventListener("unhandledrejection", (event) => {
148
186
  captureError(event.reason, true);
Binary file
Binary file
@@ -4,6 +4,10 @@
4
4
  const DB_NAME = "leapsEventDB";
5
5
  const STORE_NAME = "recordingEvents";
6
6
  const DB_VERSION = 1;
7
+ // HIPAA MVP: bound at-rest exposure of buffered session events. 24h chosen
8
+ // to allow long offline windows but not indefinite retention; expired
9
+ // records are filtered out at read time and deleted asynchronously.
10
+ const EVENT_TTL_MS = 24 * 60 * 60 * 1000;
7
11
  // Cached open promise; never created on SSR
8
12
  let _dbPromise = null;
9
13
  // Narrow, safe feature check (no throws in weird runtimes)
@@ -85,7 +89,27 @@ export async function getAllIndexedEvents() {
85
89
  req.onerror = () => resolve([]);
86
90
  });
87
91
  });
88
- return result ?? []; // SSR/Edge → []
92
+ const all = result ?? []; // SSR/Edge → []
93
+ // HIPAA MVP TTL filter: drop records older than EVENT_TTL_MS at read time
94
+ // and schedule background deletion of the stale IDs. Done after we
95
+ // have the full list so we don't block the read on the cleanup write.
96
+ const now = Date.now();
97
+ const fresh = [];
98
+ const staleIds = [];
99
+ for (const ev of all) {
100
+ if (typeof ev?.timestamp === "number" && now - ev.timestamp >= EVENT_TTL_MS) {
101
+ if (typeof ev.id === "number")
102
+ staleIds.push(ev.id);
103
+ }
104
+ else {
105
+ fresh.push(ev);
106
+ }
107
+ }
108
+ if (staleIds.length > 0) {
109
+ // Fire-and-forget: don't await; don't surface errors.
110
+ void deleteEventsByIds(staleIds).catch(() => { });
111
+ }
112
+ return fresh;
89
113
  }
90
114
  export async function deleteEventById(id) {
91
115
  await withStore("readwrite", (store) => {
Binary file
Binary file
package/dist/recorder.cjs CHANGED
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const e = require("./chunks/index-DbcegHRc.js");
3
+ const e = require("./chunks/index-CftVmmO9.js");
4
4
  exports.DEFAULT_CAPTURE_SETTINGS = e.DEFAULT_CAPTURE_SETTINGS, exports.DEFAULT_CONSOLE_RECORDING_SETTINGS = e.DEFAULT_CONSOLE_RECORDING_SETTINGS, exports.STORAGE_VERSION = e.STORAGE_VERSION, exports.addOrUpdateMetadata = e.addOrUpdateMetadata, exports.buildBatches = e.buildBatches, exports.clearStaleFuncSpanState = e.clearStaleFuncSpanState, exports.createSkipHeadersPropagationChecker = e.createSkipHeadersPropagationChecker, exports.createTriageAndIssueFromRecorder = e.createTriageAndIssueFromRecorder, exports.createTriageFromRecorder = e.createTriageFromRecorder, exports.disableFunctionSpanTracking = e.disableFunctionSpanTracking, exports.enableFunctionSpanTracking = e.enableFunctionSpanTracking, exports.ensureHrefCache = e.ensureHrefCache, exports.eventSize = e.eventSize, exports.fetchAndSendIp = e.fetchAndSendIp, exports.fetchCaptureSettings = e.fetchCaptureSettings, exports.fetchEngineeringTicketPlatformIntegrations = e.fetchEngineeringTicketPlatformIntegrations, exports.fetchFunctionSpanTrackingEnabled = e.fetchFunctionSpanTrackingEnabled, exports.flushBufferedEvents = e.flushBufferedEvents, exports.getCachedHref = e.getCachedHref, exports.getCachedHrefNoQuery = e.getCachedHrefNoQuery, exports.getFuncSpanHeader = e.getFuncSpanHeader, exports.getIdentifiedUser = e.getIdentifiedUser, exports.getOrSetSessionId = e.getOrSetSessionId, exports.getUrlAndStoredUuids = e.getUrlAndStoredUuids, exports.identify = e.identify, exports.initRecorder = e.initRecorder, exports.initializeConsolePlugin = e.initializeConsolePlugin, exports.initializeDomContentEvents = e.initializeDomContentEvents, exports.initializeFunctionSpanTrackingFromApi = e.initializeFunctionSpanTrackingFromApi, exports.initializePerformancePlugin = e.initializePerformancePlugin, exports.initializeRecording = e.initializeRecording, exports.initializeWebSocket = e.initializeWebSocket, exports.invalidateUrlCache = e.invalidateUrlCache, exports.isFunctionSpanTrackingEnabled = e.isFunctionSpanTrackingEnabled, exports.matchUrlWithWildcard = e.matchUrlWithWildcard, Object.defineProperty(exports, "nowTimestamp", { enumerable: true, get: () => e.nowTimestamp }), exports.onNavigationChange = e.onNavigationChange, exports.openReportIssueModal = e.openReportIssueModal, exports.restoreFuncSpanState = e.restoreFuncSpanState, exports.sendDomainsToNotPropagateHeaderTo = e.sendDomainsToNotPropagateHeaderTo, exports.sendEvent = e.sendEvent, exports.sendGraphQLRequest = e.sendGraphQLRequest, exports.sendMessage = e.sendMessage, exports.startRecording = e.startRecording, exports.startRecordingSession = e.startRecordingSession, exports.trackingEvent = e.trackingEvent, exports.withAppUrlMetadata = e.withAppUrlMetadata;
Binary file
Binary file
package/dist/recorder.js CHANGED
@@ -1,4 +1,4 @@
1
- import { D, a, S, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, z, A, B, C, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, T, U, V } from "./chunks/index-B8IAZfT7.js";
1
+ import { D, a, S, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, T, U } from "./chunks/index-QXHuV98g.js";
2
2
  export {
3
3
  D as DEFAULT_CAPTURE_SETTINGS,
4
4
  a as DEFAULT_CONSOLE_RECORDING_SETTINGS,
@@ -26,25 +26,25 @@ export {
26
26
  v as getUrlAndStoredUuids,
27
27
  w as identify,
28
28
  x as initRecorder,
29
- z as initializeConsolePlugin,
30
- A as initializeDomContentEvents,
31
- B as initializeFunctionSpanTrackingFromApi,
32
- C as initializePerformancePlugin,
33
- E as initializeRecording,
34
- F as initializeWebSocket,
35
- G as invalidateUrlCache,
36
- H as isFunctionSpanTrackingEnabled,
37
- I as matchUrlWithWildcard,
38
- J as nowTimestamp,
39
- K as onNavigationChange,
40
- L as openReportIssueModal,
41
- M as restoreFuncSpanState,
42
- N as sendDomainsToNotPropagateHeaderTo,
43
- O as sendEvent,
44
- P as sendGraphQLRequest,
45
- Q as sendMessage,
46
- R as startRecording,
47
- T as startRecordingSession,
48
- U as trackingEvent,
49
- V as withAppUrlMetadata
29
+ y as initializeConsolePlugin,
30
+ z as initializeDomContentEvents,
31
+ A as initializeFunctionSpanTrackingFromApi,
32
+ B as initializePerformancePlugin,
33
+ C as initializeRecording,
34
+ E as initializeWebSocket,
35
+ F as invalidateUrlCache,
36
+ G as isFunctionSpanTrackingEnabled,
37
+ H as matchUrlWithWildcard,
38
+ I as nowTimestamp,
39
+ J as onNavigationChange,
40
+ K as openReportIssueModal,
41
+ L as restoreFuncSpanState,
42
+ M as sendDomainsToNotPropagateHeaderTo,
43
+ N as sendEvent,
44
+ O as sendGraphQLRequest,
45
+ P as sendMessage,
46
+ Q as startRecording,
47
+ R as startRecordingSession,
48
+ T as trackingEvent,
49
+ U as withAppUrlMetadata
50
50
  };
Binary file
Binary file
@@ -515,10 +515,13 @@
515
515
  pe = (async () => {
516
516
  var _a2, _b;
517
517
  const e2 = await (async function getAllIndexedEvents() {
518
- return await withStore$1("readonly", (e3) => new Promise((w3) => {
519
- const C2 = e3.getAll();
520
- C2.onsuccess = () => w3(C2.result), C2.onerror = () => w3([]);
521
- })) ?? [];
518
+ const e3 = await withStore$1("readonly", (e4) => new Promise((w4) => {
519
+ const C3 = e4.getAll();
520
+ C3.onsuccess = () => w4(C3.result), C3.onerror = () => w4([]);
521
+ })) ?? [], w3 = Date.now(), C2 = [], x2 = [];
522
+ for (const I2 of e3) "number" == typeof (I2 == null ? void 0 : I2.timestamp) && w3 - I2.timestamp >= 864e5 ? "number" == typeof I2.id && x2.push(I2.id) : C2.push(I2);
523
+ return x2.length > 0 && deleteEventsByIds(x2).catch(() => {
524
+ }), C2;
522
525
  })(), w2 = {};
523
526
  for (const C2 of e2) {
524
527
  const e3 = ((_b = (_a2 = C2 == null ? void 0 : C2.data) == null ? void 0 : _a2.data) == null ? void 0 : _b.sessionId) ?? "unknown-session";
@@ -593,7 +596,7 @@
593
596
  const w3 = new URL(e3);
594
597
  return `${w3.hostname}${w3.port ? `:${w3.port}` : ""}`;
595
598
  })(e2);
596
- let _2 = `${"https:" === new URL(e2).protocol ? "wss" : "ws"}://${M2}/ws/notify/?apiKey=${w2}&sessionId=${C2}&sender=JS%2FTS&version=1.11.4`;
599
+ let _2 = `${"https:" === new URL(e2).protocol ? "wss" : "ws"}://${M2}/ws/notify/?apiKey=${w2}&sessionId=${C2}&sender=JS%2FTS&version=1.11.6`;
597
600
  if (x2 && (_2 += `&envValue=${encodeURIComponent(x2)}`), le = I2 ? (function tryCreateWsWorker() {
598
601
  if ("undefined" == typeof Worker) return null;
599
602
  try {
@@ -688,10 +691,25 @@
688
691
  }
689
692
  return null;
690
693
  }
691
- async function captureError(e2, w2 = false) {
692
- let C2, x2;
693
- e2 instanceof Error ? (C2 = e2.message, x2 = e2.stack || "No stack trace") : "string" == typeof e2 ? (C2 = e2, x2 = "No stack trace available") : (C2 = "Unknown error occurred", x2 = "No stack trace available");
694
- const I2 = await (async function resolveStackTrace(e3) {
694
+ async function captureError(e2, w2 = false, C2) {
695
+ let x2, I2;
696
+ const M2 = [];
697
+ e2 instanceof Error ? (x2 = e2.message || e2.name, I2 = e2.stack || "No stack trace", M2.push(`${e2.name}: ${x2}`)) : "string" == typeof e2 ? (x2 = e2, I2 = "No stack trace available", M2.push(w2 ? `Uncaught (in promise) ${e2}` : e2)) : (x2 = (function describeNonError(e3) {
698
+ if (null === e3) return "null";
699
+ if (void 0 === e3) return "undefined";
700
+ if ("string" == typeof e3) return e3;
701
+ if ("number" == typeof e3 || "boolean" == typeof e3 || "bigint" == typeof e3) return String(e3);
702
+ if (e3 instanceof Event) {
703
+ const w3 = e3.target, C3 = (w3 == null ? void 0 : w3.tagName) ? `<${w3.tagName.toLowerCase()}>` : "";
704
+ return `[${e3.type} Event${C3 ? ` on ${C3}` : ""}${e3.isTrusted ? " trusted" : ""}]`;
705
+ }
706
+ try {
707
+ return JSON.stringify(e3);
708
+ } catch {
709
+ return Object.prototype.toString.call(e3);
710
+ }
711
+ })(e2), I2 = "No stack trace available", M2.push(w2 ? `Uncaught (in promise) ${x2}` : x2)), (C2 == null ? void 0 : C2.filename) && M2.push(`at ${C2.filename}:${C2.lineno ?? 0}:${C2.colno ?? 0}`);
712
+ const _2 = await (async function resolveStackTrace(e3) {
695
713
  if (!e3) return ["No stack trace available"];
696
714
  const w3 = Array.isArray(e3) ? e3 : e3.split("\n"), C3 = [];
697
715
  for (const e4 of w3) {
@@ -700,27 +718,27 @@
700
718
  C3.push(e4);
701
719
  continue;
702
720
  }
703
- const [, x3, I3, M3, _3] = w4, U3 = parseInt(M3, 10), j2 = Math.max(0, parseInt(_3, 10) - 1);
704
- if (!Number.isFinite(U3) || !Number.isFinite(j2)) {
721
+ const [, x3, I3, M3, _3] = w4, U3 = parseInt(M3, 10), j3 = Math.max(0, parseInt(_3, 10) - 1);
722
+ if (!Number.isFinite(U3) || !Number.isFinite(j3)) {
705
723
  C3.push(e4 + " [Invalid line/column]");
706
724
  continue;
707
725
  }
708
- const z2 = await getConsumerFor(x3, I3);
709
- if (!z2) {
726
+ const z3 = await getConsumerFor(x3, I3);
727
+ if (!z3) {
710
728
  C3.push(`${e4} [No source map found for ${I3}]`);
711
729
  continue;
712
730
  }
713
731
  const { SourceMapConsumer: W2 } = await getSourceMapModule();
714
- let H2 = z2.originalPositionFor({ line: U3, column: j2, bias: W2.GREATEST_LOWER_BOUND });
715
- if (!H2.source || null == H2.line) for (let e5 = 1; e5 <= 20 && (H2 = z2.originalPositionFor({ line: U3, column: Math.max(0, j2 - e5), bias: W2.GREATEST_LOWER_BOUND }), !H2.source || null == H2.line); e5++) ;
732
+ let H2 = z3.originalPositionFor({ line: U3, column: j3, bias: W2.GREATEST_LOWER_BOUND });
733
+ if (!H2.source || null == H2.line) for (let e5 = 1; e5 <= 20 && (H2 = z3.originalPositionFor({ line: U3, column: Math.max(0, j3 - e5), bias: W2.GREATEST_LOWER_BOUND }), !H2.source || null == H2.line); e5++) ;
716
734
  if (H2.source && null != H2.line) {
717
735
  const e5 = H2.name || "anonymous";
718
736
  C3.push(`${H2.source}:${H2.line}:${H2.column ?? 0} (${e5})`);
719
737
  } else C3.push(`${e4} [No mapping found in ${I3}]`);
720
738
  }
721
739
  return C3;
722
- })(x2), M2 = I2.filter((e3) => !e3.includes("chunk-") && !e3.includes("react-dom")), _2 = M2.length > 0 ? M2 : I2, U2 = Date.now();
723
- sendMessage({ type: "event", event: { type: 6, timestamp: U2, data: { payload: { message: C2, stack: x2, trace: _2, filteredStack: M2, userAgent: navigator.userAgent, url: window.location.href, timestamp: U2, level: "error" } } } });
740
+ })(I2), U2 = _2.filter((e3) => !e3.includes("chunk-") && !e3.includes("react-dom")), j2 = U2.length > 0 ? U2 : _2, z2 = Date.now();
741
+ sendMessage({ type: "event", event: { type: 6, timestamp: z2, data: { payload: { message: x2, stack: I2, trace: j2, filteredStack: U2, payload: M2, userAgent: navigator.userAgent, url: window.location.href, timestamp: z2, level: "error" } } } });
724
742
  }
725
743
  const Ge = readDebugFlag();
726
744
  const Ve = readDebugFlag();
@@ -2558,7 +2576,7 @@
2558
2576
  };
2559
2577
  })(I2, de2, x2), ce2.xhrPatched = true), ce2.fetchPatched || (setupFetchInterceptor(I2, de2, x2), ce2.fetchPatched = true), await yieldToMain(), ce2.domEventsInit || (initializeDomContentEvents(le2), ce2.domEventsInit = true), await yieldToMain(), ce2.consoleInit || (initializeConsolePlugin(Gt, le2), ce2.consoleInit = true), await yieldToMain(), ce2.errorInit || (!(function initializeErrorInterceptor() {
2560
2578
  window.addEventListener("error", (e3) => {
2561
- captureError(e3.error || e3.message);
2579
+ captureError(e3.error ?? e3.message, false, { filename: e3.filename, lineno: e3.lineno, colno: e3.colno });
2562
2580
  }), window.addEventListener("unhandledrejection", (e3) => {
2563
2581
  captureError(e3.reason, true);
2564
2582
  });
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sailfish-ai/recorder",
3
- "version": "1.11.4",
3
+ "version": "1.11.6",
4
4
  "publishPublicly": true,
5
5
  "publishToCdn": {
6
6
  "jsdelivr": true,
Binary file
Binary file
Binary file
Binary file