@sailfish-ai/recorder 1.12.7 → 1.12.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/{canvasManager-B9uQ-PFS.js → canvasManager-3AzRUaNq.js} +1 -1
- package/dist/chunks/canvasManager-3AzRUaNq.js.br +0 -0
- package/dist/chunks/canvasManager-3AzRUaNq.js.gz +0 -0
- package/dist/chunks/{canvasManager-Ce7vazTt.js → canvasManager-CDEhVz_J.js} +1 -1
- package/dist/chunks/canvasManager-CDEhVz_J.js.br +0 -0
- package/dist/chunks/canvasManager-CDEhVz_J.js.gz +0 -0
- package/dist/chunks/{chunkSerializer-B-z7p0r-.js → chunkSerializer-B3loCr3q.js} +1 -1
- package/dist/chunks/chunkSerializer-B3loCr3q.js.br +0 -0
- package/dist/chunks/chunkSerializer-B3loCr3q.js.gz +0 -0
- package/dist/chunks/{chunkSerializer-C1knjCQ5.js → chunkSerializer-Cz0TPV-B.js} +1 -1
- package/dist/chunks/chunkSerializer-Cz0TPV-B.js.br +0 -0
- package/dist/chunks/chunkSerializer-Cz0TPV-B.js.gz +0 -0
- package/dist/chunks/hoverDetection-Bl-yKKI3.js +137 -0
- package/dist/chunks/hoverDetection-Bl-yKKI3.js.br +0 -0
- package/dist/chunks/hoverDetection-Bl-yKKI3.js.gz +0 -0
- package/dist/chunks/hoverDetection-CYsyBQjj.js +139 -0
- package/dist/chunks/hoverDetection-CYsyBQjj.js.br +0 -0
- package/dist/chunks/hoverDetection-CYsyBQjj.js.gz +0 -0
- package/dist/chunks/{index-BMHQ-0NY.js → index-BUAmLDnY.js} +109 -103
- package/dist/chunks/index-BUAmLDnY.js.br +0 -0
- package/dist/chunks/index-BUAmLDnY.js.gz +0 -0
- package/dist/chunks/{index-qgM1hFXO.js → index-CPZwt1ko.js} +59 -53
- package/dist/chunks/index-CPZwt1ko.js.br +0 -0
- package/dist/chunks/index-CPZwt1ko.js.gz +0 -0
- package/dist/hoverDetection.js +371 -0
- package/dist/hoverDetection.js.br +0 -0
- package/dist/hoverDetection.js.gz +0 -0
- package/dist/hoverDetection.test.js +187 -0
- package/dist/hoverDetection.test.js.br +0 -0
- package/dist/hoverDetection.test.js.gz +0 -0
- package/dist/index.js +8 -0
- package/dist/index.js.br +0 -0
- package/dist/index.js.gz +0 -0
- package/dist/recorder.cjs +1 -1
- package/dist/recorder.cjs.br +0 -0
- package/dist/recorder.cjs.gz +0 -0
- package/dist/recorder.js +1 -1
- package/dist/recorder.js.br +0 -0
- package/dist/recorder.js.gz +0 -0
- package/dist/recorder.umd.cjs +572 -434
- package/dist/recorder.umd.cjs.br +0 -0
- package/dist/recorder.umd.cjs.gz +0 -0
- package/dist/recording.js +27 -0
- package/dist/recording.js.br +0 -0
- package/dist/recording.js.gz +0 -0
- package/dist/types/hoverDetection.d.ts +37 -0
- package/dist/types/hoverDetection.test.d.ts +1 -0
- package/dist/types/types.d.ts +6 -0
- package/package.json +1 -1
- package/dist/chunks/canvasManager-B9uQ-PFS.js.br +0 -0
- package/dist/chunks/canvasManager-B9uQ-PFS.js.gz +0 -0
- package/dist/chunks/canvasManager-Ce7vazTt.js.br +0 -0
- package/dist/chunks/canvasManager-Ce7vazTt.js.gz +0 -0
- package/dist/chunks/chunkSerializer-B-z7p0r-.js.br +0 -0
- package/dist/chunks/chunkSerializer-B-z7p0r-.js.gz +0 -0
- package/dist/chunks/chunkSerializer-C1knjCQ5.js.br +0 -0
- package/dist/chunks/chunkSerializer-C1knjCQ5.js.gz +0 -0
- package/dist/chunks/index-BMHQ-0NY.js.br +0 -0
- package/dist/chunks/index-BMHQ-0NY.js.gz +0 -0
- package/dist/chunks/index-qgM1hFXO.js.br +0 -0
- package/dist/chunks/index-qgM1hFXO.js.gz +0 -0
|
@@ -39,12 +39,12 @@ function uuidv4() {
|
|
|
39
39
|
return ("x" === e2 ? t2 : 3 & t2 | 8).toString(16);
|
|
40
40
|
});
|
|
41
41
|
}
|
|
42
|
-
const f = "X-Sf3-Rid", g = 0, m = 1, h = 2, y = 4,
|
|
42
|
+
const f = "X-Sf3-Rid", g = 0, m = 1, h = 2, y = 4, v = "undefined" != typeof performance && "function" == typeof performance.now;
|
|
43
43
|
function monotonicNow() {
|
|
44
|
-
return
|
|
44
|
+
return v ? performance.now() : Date.now();
|
|
45
45
|
}
|
|
46
46
|
function timeOriginMs() {
|
|
47
|
-
return
|
|
47
|
+
return v ? performance.timeOrigin : 0;
|
|
48
48
|
}
|
|
49
49
|
class ClockSyncManager {
|
|
50
50
|
constructor() {
|
|
@@ -97,9 +97,9 @@ class ClockSyncManager {
|
|
|
97
97
|
this.estimatedOffsetMs = n2[Math.floor(n2.length / 2)], this.bestRttMs = t2[0].rttMs, this.lastSyncMonoMs = e2;
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
|
-
let
|
|
100
|
+
let b = null;
|
|
101
101
|
function getClockSyncManager() {
|
|
102
|
-
return
|
|
102
|
+
return b || (b = new ClockSyncManager()), b;
|
|
103
103
|
}
|
|
104
104
|
function buildEventTimeEnvelope(e2, t2) {
|
|
105
105
|
const n2 = getClockSyncManager(), i2 = n2.getSyncMetadata(), o2 = n2.estimateServerTime(e2);
|
|
@@ -279,14 +279,14 @@ function buildBatches(e2, t2, n2) {
|
|
|
279
279
|
function eventSize(e2) {
|
|
280
280
|
return JSON.stringify(e2).length;
|
|
281
281
|
}
|
|
282
|
-
let
|
|
282
|
+
let P = Date.now;
|
|
283
283
|
function withAppUrlMetadata(e2) {
|
|
284
284
|
var _a;
|
|
285
285
|
return { ...e2 ?? {}, appUrl: (e2 == null ? void 0 : e2.appUrl) ?? ((_a = window == null ? void 0 : window.location) == null ? void 0 : _a.href) };
|
|
286
286
|
}
|
|
287
|
-
/[1-9][0-9]{12}/.test(Date.now().toString()) || (
|
|
288
|
-
const
|
|
289
|
-
let O = null, j = null, U = null, N = null, q = 0,
|
|
287
|
+
/[1-9][0-9]{12}/.test(Date.now().toString()) || (P = () => (/* @__PURE__ */ new Date()).getTime());
|
|
288
|
+
const B = readDebugFlag(), _ = "per_session";
|
|
289
|
+
let O = null, j = null, U = null, N = null, q = 0, H = false, z = null, W = null;
|
|
290
290
|
const K = [];
|
|
291
291
|
let V = 0, G = 0, Q = false;
|
|
292
292
|
function pushBinaryRing(e2) {
|
|
@@ -360,7 +360,7 @@ function _wsSendBinaryNow(e2) {
|
|
|
360
360
|
}
|
|
361
361
|
}
|
|
362
362
|
function wsSendBinary(e2) {
|
|
363
|
-
return
|
|
363
|
+
return H || !isWebSocketOpen(j) ? (bufferBinaryOffline(e2), false) : !!_wsSendBinaryNow(e2) || (bufferBinaryOffline(e2), false);
|
|
364
364
|
}
|
|
365
365
|
let X = null, J = 0;
|
|
366
366
|
function requestTimeSync() {
|
|
@@ -456,21 +456,21 @@ function saveGlobalFuncSpanState(e2, t2) {
|
|
|
456
456
|
try {
|
|
457
457
|
if ("undefined" == typeof localStorage) return;
|
|
458
458
|
const n2 = { enabled: e2, expirationTimestampMs: t2, savedAt: Date.now() };
|
|
459
|
-
localStorage.setItem(ce, JSON.stringify(n2)),
|
|
459
|
+
localStorage.setItem(ce, JSON.stringify(n2)), B && console.log("[Sailfish] Saved funcSpan state to localStorage:", n2);
|
|
460
460
|
} catch (e3) {
|
|
461
|
-
|
|
461
|
+
B && console.warn("[Sailfish] Failed to save funcSpan state to localStorage:", e3);
|
|
462
462
|
}
|
|
463
463
|
}
|
|
464
464
|
function clearGlobalFuncSpanState() {
|
|
465
465
|
try {
|
|
466
466
|
if ("undefined" == typeof localStorage) return;
|
|
467
|
-
localStorage.removeItem(ce),
|
|
467
|
+
localStorage.removeItem(ce), B && console.log("[Sailfish] Cleared funcSpan state from localStorage");
|
|
468
468
|
} catch (e2) {
|
|
469
|
-
|
|
469
|
+
B && console.warn("[Sailfish] Failed to clear funcSpan state from localStorage:", e2);
|
|
470
470
|
}
|
|
471
471
|
}
|
|
472
472
|
function clearStaleFuncSpanState() {
|
|
473
|
-
oe = false, se = null, ae = false, clearGlobalFuncSpanState(),
|
|
473
|
+
oe = false, se = null, ae = false, clearGlobalFuncSpanState(), B && console.log("[Sailfish] Cleared stale function span tracking state (backend validation failed)");
|
|
474
474
|
}
|
|
475
475
|
let le = false;
|
|
476
476
|
function restoreFuncSpanState() {
|
|
@@ -482,14 +482,14 @@ function restoreFuncSpanState() {
|
|
|
482
482
|
const e3 = localStorage.getItem(ce);
|
|
483
483
|
if (!e3) return null;
|
|
484
484
|
const t2 = JSON.parse(e3);
|
|
485
|
-
return
|
|
485
|
+
return B && console.log("[Sailfish] Loaded funcSpan state from localStorage:", t2), t2;
|
|
486
486
|
} catch (e3) {
|
|
487
|
-
return
|
|
487
|
+
return B && console.warn("[Sailfish] Failed to load funcSpan state from localStorage:", e3), null;
|
|
488
488
|
}
|
|
489
489
|
})();
|
|
490
|
-
if (e2 && e2.enabled) if (oe = true, se = e2.expirationTimestampMs, ae = false,
|
|
491
|
-
Date.now() >= se ? (oe = false, se = null, clearGlobalFuncSpanState(),
|
|
492
|
-
} else
|
|
490
|
+
if (e2 && e2.enabled) if (oe = true, se = e2.expirationTimestampMs, ae = false, B && console.log("[Sailfish] Restored global function span tracking from localStorage:", { enabled: true, expirationTime: se }), null !== se) {
|
|
491
|
+
Date.now() >= se ? (oe = false, se = null, clearGlobalFuncSpanState(), B && console.log("[Sailfish] Persisted tracking already expired, cleared state")) : B && console.log("[Sailfish] Function span tracking is active and valid (temporary until WebSocket confirms)");
|
|
492
|
+
} else B && console.log("[Sailfish] Function span tracking is active (no expiration, temporary until WebSocket confirms)");
|
|
493
493
|
}
|
|
494
494
|
function isWebSocketOpen(e2) {
|
|
495
495
|
return (e2 == null ? void 0 : e2.readyState) === WebSocket.OPEN;
|
|
@@ -510,9 +510,9 @@ async function flushNotifyQueue() {
|
|
|
510
510
|
}
|
|
511
511
|
}
|
|
512
512
|
async function flushBufferedEvents() {
|
|
513
|
-
if (isWebSocketOpen(j)) if (
|
|
513
|
+
if (isWebSocketOpen(j)) if (z) await z;
|
|
514
514
|
else {
|
|
515
|
-
|
|
515
|
+
z = (async () => {
|
|
516
516
|
var _a, _b;
|
|
517
517
|
const e2 = await (async function getAllIndexedEvents() {
|
|
518
518
|
const e3 = await withStore$2("readonly", (e4) => new Promise((t4) => {
|
|
@@ -540,21 +540,21 @@ async function flushBufferedEvents() {
|
|
|
540
540
|
}
|
|
541
541
|
})();
|
|
542
542
|
try {
|
|
543
|
-
await
|
|
543
|
+
await z;
|
|
544
544
|
} finally {
|
|
545
|
-
|
|
545
|
+
z = null;
|
|
546
546
|
}
|
|
547
547
|
}
|
|
548
548
|
}
|
|
549
549
|
function sendEvent(e2) {
|
|
550
|
-
e2.app_url || (e2.app_url = getCachedHref()), enrichEventWithTimeSync(e2), !
|
|
550
|
+
e2.app_url || (e2.app_url = getCachedHref()), enrichEventWithTimeSync(e2), !H && isWebSocketOpen(j) && wsSendPayload({ type: "event", event: e2, mapUuid: window.sfMapUuid }) || queueEventForIDB(e2);
|
|
551
551
|
}
|
|
552
552
|
function handleWsOpen() {
|
|
553
|
-
|
|
553
|
+
B && (console.log("[Sailfish] WebSocket connection opened"), console.log("[Sailfish] Function span tracking state: " + (oe ? "ENABLED" : "DISABLED"))), (async () => {
|
|
554
554
|
try {
|
|
555
|
-
|
|
555
|
+
H = true, await flushNotifyQueue(), await flushBufferedEvents();
|
|
556
556
|
} finally {
|
|
557
|
-
|
|
557
|
+
H = false;
|
|
558
558
|
}
|
|
559
559
|
await flushBinaryBacklog(), null != W && clearInterval(W), W = window.setInterval(() => {
|
|
560
560
|
flushBufferedEvents(), Q && flushBinaryBacklog();
|
|
@@ -570,30 +570,30 @@ function handleWsOpen() {
|
|
|
570
570
|
function handleWsClose() {
|
|
571
571
|
null != W && (clearInterval(W), W = null), (function stopTimeSyncInterval() {
|
|
572
572
|
null != X && "undefined" != typeof window && (window.clearInterval(X), X = null);
|
|
573
|
-
})(),
|
|
573
|
+
})(), B && console.log("[Sailfish] WebSocket closed");
|
|
574
574
|
}
|
|
575
575
|
function handleWsMessage(e2) {
|
|
576
576
|
try {
|
|
577
577
|
const t2 = JSON.parse(e2);
|
|
578
578
|
if ("time-sync-response" === t2.type) return void getClockSyncManager().recordTimeSyncResponse({ requestId: t2.requestId, serverReceivedAtMs: t2.serverReceivedAtMs, serverSentAtMs: t2.serverSentAtMs });
|
|
579
|
-
if ("funcSpanTrackingControl" === t2.type) if (
|
|
579
|
+
if ("funcSpanTrackingControl" === t2.type) if (B && console.log("[Sailfish] Received funcSpanTrackingControl message:", { enabled: t2.enabled, timeoutSeconds: t2.timeoutSeconds, expirationTimestampMs: t2.expirationTimestampMs }), null !== re && (window.clearTimeout(re), re = null), oe = t2.enabled, ae = false, B && console.log("[Sailfish] Function span tracking " + (t2.enabled ? "ENABLED (GLOBAL)" : "DISABLED (GLOBAL)")), t2.enabled) {
|
|
580
580
|
if (t2.expirationTimestampMs) {
|
|
581
581
|
se = t2.expirationTimestampMs;
|
|
582
582
|
const e3 = Date.now(), n2 = se - e3;
|
|
583
|
-
|
|
584
|
-
ae || (oe = false, se = null, clearGlobalFuncSpanState(),
|
|
585
|
-
}, n2)) : (oe = false, se = null, clearGlobalFuncSpanState(),
|
|
583
|
+
B && console.log(`[Sailfish] Server expiration timestamp: ${se}, ms until expiration: ${n2}`), n2 > 0 ? (saveGlobalFuncSpanState(true, se), re = window.setTimeout(() => {
|
|
584
|
+
ae || (oe = false, se = null, clearGlobalFuncSpanState(), B && console.log("[Sailfish] GLOBAL function span tracking auto-disabled at server expiration time"), wsSendPayload({ type: "funcSpanTrackingExpired", sessionId: getOrSetSessionId(), expiredAt: Date.now() }), B && console.log("[Sailfish] Notified backend that function span tracking expired"));
|
|
585
|
+
}, n2)) : (oe = false, se = null, clearGlobalFuncSpanState(), B && console.log("[Sailfish] Tracking already expired, not enabling"));
|
|
586
586
|
} else {
|
|
587
587
|
const e3 = t2.timeoutSeconds || 3600;
|
|
588
588
|
e3 > 0 && (se = Date.now() + 1e3 * e3, saveGlobalFuncSpanState(true, se), re = window.setTimeout(() => {
|
|
589
|
-
ae || (oe = false, se = null, clearGlobalFuncSpanState(),
|
|
589
|
+
ae || (oe = false, se = null, clearGlobalFuncSpanState(), B && console.log(`[Sailfish] GLOBAL function span tracking auto-disabled after ${e3}s (legacy)`), wsSendPayload({ type: "funcSpanTrackingExpired", sessionId: getOrSetSessionId(), expiredAt: Date.now() }), B && console.log("[Sailfish] Notified backend that function span tracking expired (legacy timeout)"));
|
|
590
590
|
}, 1e3 * e3));
|
|
591
591
|
}
|
|
592
592
|
try {
|
|
593
593
|
const e3 = getOrSetSessionId();
|
|
594
|
-
wsSendPayload({ type: "funcSpanTrackingSessionReport", sessionId: e3, enabled: true, configurationType: "global" }),
|
|
594
|
+
wsSendPayload({ type: "funcSpanTrackingSessionReport", sessionId: e3, enabled: true, configurationType: "global" }), B && console.log(`[Sailfish] GLOBAL tracking session report sent for session: ${e3}`);
|
|
595
595
|
} catch (e3) {
|
|
596
|
-
|
|
596
|
+
B && console.warn("[Sailfish] Failed to send GLOBAL tracking session report:", e3);
|
|
597
597
|
}
|
|
598
598
|
} else se = null, clearGlobalFuncSpanState();
|
|
599
599
|
} catch (e3) {
|
|
@@ -605,7 +605,7 @@ function initializeWebSocket(t2, n2, i2, o2, r2 = false) {
|
|
|
605
605
|
const t3 = new URL(e2);
|
|
606
606
|
return `${t3.hostname}${t3.port ? `:${t3.port}` : ""}`;
|
|
607
607
|
})(t2);
|
|
608
|
-
let a2 = `${"https:" === new URL(t2).protocol ? "wss" : "ws"}://${s2}/ws/notify/?apiKey=${n2}&sessionId=${i2}&sender=JS%2FTS&version=1.12.
|
|
608
|
+
let a2 = `${"https:" === new URL(t2).protocol ? "wss" : "ws"}://${s2}/ws/notify/?apiKey=${n2}&sessionId=${i2}&sender=JS%2FTS&version=1.12.8`;
|
|
609
609
|
if (o2 && (a2 += `&envValue=${encodeURIComponent(o2)}`), U = null, N = null, q = 0, O = r2 ? (function tryCreateWsWorker() {
|
|
610
610
|
if ("undefined" == typeof Worker) return null;
|
|
611
611
|
try {
|
|
@@ -622,10 +622,10 @@ function initializeWebSocket(t2, n2, i2, o2, r2 = false) {
|
|
|
622
622
|
const n3 = e3.data;
|
|
623
623
|
"open" === n3.type ? (t3.readyState = WebSocket.OPEN, handleWsOpen()) : "close" === n3.type ? (t3.readyState = WebSocket.CLOSED, q = 0, handleWsClose()) : "message" === n3.type ? handleWsMessage(n3.data) : "buffered" === n3.type && (q = "number" == typeof n3.bufferedAmount ? n3.bufferedAmount : 0);
|
|
624
624
|
}, O.onerror = () => {
|
|
625
|
-
|
|
626
|
-
}, O.postMessage({ type: "init", wsUrl: a2 }),
|
|
625
|
+
B && console.warn("[Sailfish] WebSocket worker error");
|
|
626
|
+
}, O.postMessage({ type: "init", wsUrl: a2 }), B && console.log("[Sailfish] WebSocket running in Web Worker (off main thread)"), t3;
|
|
627
627
|
}
|
|
628
|
-
|
|
628
|
+
B && console.log("[Sailfish] WebSocket running on main thread (Worker unavailable)");
|
|
629
629
|
const c2 = new e(a2, [], { connectionTimeout: 3e4 });
|
|
630
630
|
c2.binaryType = "arraybuffer", U = (e2) => c2.send(e2), N = () => c2.bufferedAmount || 0;
|
|
631
631
|
const l2 = { get readyState() {
|
|
@@ -636,29 +636,29 @@ function initializeWebSocket(t2, n2, i2, o2, r2 = false) {
|
|
|
636
636
|
return j = l2, c2.addEventListener("open", () => handleWsOpen()), c2.addEventListener("close", () => handleWsClose()), c2.addEventListener("message", (e2) => handleWsMessage(e2.data)), l2;
|
|
637
637
|
}
|
|
638
638
|
function sendMessage(e2) {
|
|
639
|
-
"sessionId" in e2 || (e2.sessionId = getOrSetSessionId()), e2.app_url || (e2.app_url = getCachedHref()), enrichEventWithTimeSync(e2),
|
|
639
|
+
"sessionId" in e2 || (e2.sessionId = getOrSetSessionId()), e2.app_url || (e2.app_url = getCachedHref()), enrichEventWithTimeSync(e2), H || !isWebSocketOpen(j) ? saveNotifyMessageToIDB(JSON.stringify(e2)) : wsSendPayload(e2) || saveNotifyMessageToIDB(JSON.stringify(e2));
|
|
640
640
|
}
|
|
641
641
|
function enableFunctionSpanTracking() {
|
|
642
|
-
if (
|
|
642
|
+
if (B && console.log("[Sailfish] enableFunctionSpanTracking() called - Report Issue recording started (LOCAL MODE)"), oe = true, ae = true, se = null, null !== re && (window.clearTimeout(re), re = null), isWebSocketOpen(j)) {
|
|
643
643
|
wsSendPayload({ type: "funcSpanTrackingSessionReport", sessionId: getOrSetSessionId(), enabled: true, configurationType: _ });
|
|
644
|
-
} else
|
|
644
|
+
} else B && console.warn("[Sailfish] WebSocket not open, cannot report LOCAL tracking session");
|
|
645
645
|
}
|
|
646
646
|
function disableFunctionSpanTracking() {
|
|
647
|
-
if (
|
|
647
|
+
if (B && console.log("[Sailfish] disableFunctionSpanTracking() called - Report Issue recording stopped"), isWebSocketOpen(j)) {
|
|
648
648
|
wsSendPayload({ type: "funcSpanTrackingSessionReport", sessionId: getOrSetSessionId(), enabled: false, configurationType: _ });
|
|
649
649
|
} else console.warn("[FUNCSPAN STOP] ✗ WebSocket not open, cannot notify tracking end");
|
|
650
|
-
ae && (oe = false, ae = false, se = null,
|
|
650
|
+
ae && (oe = false, ae = false, se = null, B && console.log("[Sailfish] LOCAL tracking mode disabled")), null !== re && (window.clearTimeout(re), re = null);
|
|
651
651
|
}
|
|
652
652
|
function isFunctionSpanTrackingEnabled() {
|
|
653
653
|
return oe;
|
|
654
654
|
}
|
|
655
655
|
function initializeFunctionSpanTrackingFromApi(e2) {
|
|
656
|
-
e2 && !oe ? (oe = true, ae = false, se = null,
|
|
656
|
+
e2 && !oe ? (oe = true, ae = false, se = null, B && console.log("[Sailfish] Function span tracking initialized as ENABLED from API check")) : !e2 && oe && (oe = false, ae = false, se = null, B && console.log("[Sailfish] Function span tracking initialized as DISABLED from API check"));
|
|
657
657
|
}
|
|
658
658
|
function getFuncSpanHeader() {
|
|
659
659
|
if (!oe) return null;
|
|
660
660
|
if (null !== se) {
|
|
661
|
-
if (Date.now() >= se) return oe = false, se = null, clearGlobalFuncSpanState(),
|
|
661
|
+
if (Date.now() >= se) return oe = false, se = null, clearGlobalFuncSpanState(), B && console.log("[Sailfish] Function span tracking expired on header check - disabling now"), null;
|
|
662
662
|
}
|
|
663
663
|
return { name: "X-Sf3-FunctionSpanCaptureOverride", value: "1-1-10-10-1-1.0-1-0-0" };
|
|
664
664
|
}
|
|
@@ -676,7 +676,7 @@ function addOrUpdateMetadata(e2) {
|
|
|
676
676
|
pe && JSON.stringify(pe) === JSON.stringify(e2) || (pe = e2, sendMessage(t2));
|
|
677
677
|
}
|
|
678
678
|
function trackingEvent(e2) {
|
|
679
|
-
sendMessage({ type: "trackingEvent", trackingData: e2, timestamp:
|
|
679
|
+
sendMessage({ type: "trackingEvent", trackingData: e2, timestamp: P() });
|
|
680
680
|
}
|
|
681
681
|
let fe = null;
|
|
682
682
|
const ge = ["https://api.ipify.org?format=json", "https://api.ip.sb/jsonip", "https://api4.my-ip.io/ip.json"];
|
|
@@ -686,7 +686,7 @@ function fetchAndSendIp(e2) {
|
|
|
686
686
|
const t2 = new AbortController(), n2 = setTimeout(() => t2.abort(), 5e3), i2 = await fetch(e3, { signal: t2.signal });
|
|
687
687
|
if (clearTimeout(n2), !i2.ok) continue;
|
|
688
688
|
const o2 = await i2.json(), r2 = o2.ip || o2.origin || null;
|
|
689
|
-
if (r2 && "string" == typeof r2 && r2.length <= 45) return void sendMessage({ type: "visitorIp", ip: r2, timestamp:
|
|
689
|
+
if (r2 && "string" == typeof r2 && r2.length <= 45) return void sendMessage({ type: "visitorIp", ip: r2, timestamp: P() });
|
|
690
690
|
} catch {
|
|
691
691
|
}
|
|
692
692
|
fe = null;
|
|
@@ -762,11 +762,11 @@ async function captureError(e2, t2 = false, n2) {
|
|
|
762
762
|
})(o2), a2 = s2.filter((e3) => !e3.includes("chunk-") && !e3.includes("react-dom")), c2 = a2.length > 0 ? a2 : s2, l2 = Date.now();
|
|
763
763
|
sendMessage({ type: "event", event: { type: 6, timestamp: l2, data: { payload: { message: i2, stack: o2, trace: c2, filteredStack: a2, payload: r2, userAgent: navigator.userAgent, url: window.location.href, timestamp: l2, level: "error" } } } });
|
|
764
764
|
}
|
|
765
|
-
const be = readDebugFlag();
|
|
766
765
|
const ve = readDebugFlag();
|
|
766
|
+
const be = readDebugFlag();
|
|
767
767
|
function sendGraphQLRequest(e2, t2, n2, i2 = 5, o2 = 2e3, r2 = 2) {
|
|
768
768
|
const s2 = `${n2.backendApi}/graphql/?apiKey=${n2.apiKey}`;
|
|
769
|
-
return
|
|
769
|
+
return be && console.log(`Initial GraphQL request for ${e2} at ${s2}`), (function exponentialBackoff(e3, t3, n3 = 5, i3 = 2e3, o3 = 2) {
|
|
770
770
|
let r3 = 0;
|
|
771
771
|
const attemptRequest = async () => {
|
|
772
772
|
try {
|
|
@@ -774,12 +774,12 @@ function sendGraphQLRequest(e2, t2, n2, i2 = 5, o2 = 2e3, r2 = 2) {
|
|
|
774
774
|
} catch (e4) {
|
|
775
775
|
if (r3++, r3 > n3) throw e4;
|
|
776
776
|
const s3 = i3 * Math.pow(o3, r3 - 1);
|
|
777
|
-
return
|
|
777
|
+
return ve && console.log(`Attempt ${r3} failed: ${t3}; Retrying in ${s3}ms...`), await new Promise((e5) => setTimeout(e5, s3)), attemptRequest();
|
|
778
778
|
}
|
|
779
779
|
};
|
|
780
780
|
return attemptRequest();
|
|
781
781
|
})(() => fetch(s2, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ operationName: e2, query: t2, variables: n2 }) }).then((e3) => {
|
|
782
|
-
if (
|
|
782
|
+
if (be && console.log(`Received response with status: ${e3.status}`), !e3.ok) throw new Error(`GraphQL request failed with status ${e3.status}`);
|
|
783
783
|
return e3.json();
|
|
784
784
|
}), "Sending GraphQL request to Sailfish AI", i2, o2, r2);
|
|
785
785
|
}
|
|
@@ -971,7 +971,7 @@ async function initializeRecording(e2, o2, r2, s2, a2, c2 = true, l2 = false, d2
|
|
|
971
971
|
ke = o4, await yieldToMain();
|
|
972
972
|
const r3 = e2.unmaskSelector || void 0, a3 = e2.blockSelector || void 0, c3 = e2.maskTextSelector || void 0, l3 = e2.maskInputSelector || void 0, u3 = { ...e2.maskInputOptions ?? {} }, p2 = l3 ? { ...we } : u3, f2 = n({ baseFn: maskInputFn, unmaskSelector: r3, maskInputSelector: l3, adminMaskInputOptions: u3 }), g2 = i(r3);
|
|
973
973
|
if (d2) {
|
|
974
|
-
const { chunkedSnapshot: n2 } = await import("./chunkSerializer-
|
|
974
|
+
const { chunkedSnapshot: n2 } = await import("./chunkSerializer-B3loCr3q.js"), i2 = o4.mirror;
|
|
975
975
|
let s3 = true;
|
|
976
976
|
const d3 = [];
|
|
977
977
|
o4({ emit(e3) {
|
|
@@ -986,8 +986,14 @@ async function initializeRecording(e2, o2, r2, s2, a2, c2 = true, l2 = false, d2
|
|
|
986
986
|
} else o4({ emit(e3) {
|
|
987
987
|
emitWithContext(e3);
|
|
988
988
|
}, ...e2, maskInputOptions: p2, maskInputFn: f2, maskTextFn: g2, maskInputSelector: l3, maskTextSelector: c3, blockSelector: a3, maskTextClass: e2.maskTextClass ?? xe, recordCanvas: false });
|
|
989
|
+
if (false !== e2.recordHover) try {
|
|
990
|
+
const { installHoverDetection: t2 } = await import("./hoverDetection-CYsyBQjj.js"), num = (e3, t3) => "number" == typeof e3 ? e3 : t3, n2 = t2(o4, { dwellMs: num(e2.hoverDwellMs, 500), strictAffordance: false !== e2.hoverStrictAffordance, cooldownMs: num(e2.hoverCooldownMs, 3e3), maxPerSession: num(e2.hoverMaxPerSession, 300), maxPerSecond: num(e2.hoverMaxPerSecond, 1) });
|
|
991
|
+
window.addEventListener("pagehide", () => n2(), { once: true });
|
|
992
|
+
} catch (e3) {
|
|
993
|
+
console.warn("[Sailfish] Failed to enable hover detection:", e3);
|
|
994
|
+
}
|
|
989
995
|
if (e2.recordCanvas) try {
|
|
990
|
-
const { startCanvasRecording: n2, stopCanvasRecording: i2, flushAllCanvas: r4, isCanvasRecordingActive: a4 } = await import("./canvasManager-
|
|
996
|
+
const { startCanvasRecording: n2, stopCanvasRecording: i2, flushAllCanvas: r4, isCanvasRecordingActive: a4 } = await import("./canvasManager-3AzRUaNq.js"), c4 = { settings: { maskCanvasClass: e2.maskCanvasClass, maskTextClass: e2.maskTextClass, maskTextSelector: e2.maskTextSelector, blockSelector: e2.blockSelector, unmaskSelector: e2.unmaskSelector, maskCanvasText: e2.maskCanvasText ?? void 0, canvasRedactStyle: e2.canvasRedactStyle, recordSsn: e2.recordSsn, recordCreditCardInfo: e2.recordCreditCardInfo, recordDob: e2.recordDob, recordRealName: e2.recordRealName, recordPassword: e2.recordPassword }, mirror: o4.mirror, addSailfishEvent: (e3) => {
|
|
991
997
|
ke == null ? void 0 : ke.addSailfishEvent(t.SailfishCustom, { ...e3, tag: "sf-canvas" });
|
|
992
998
|
}, sendBinary: wsSendBinary, getContextIds: () => ({ session_id: s2, page_visit_uuid: getUrlAndStoredUuids().page_visit_uuid }), isTransportSaturated };
|
|
993
999
|
n2(c4);
|
|
@@ -1124,7 +1130,7 @@ function getInitialState() {
|
|
|
1124
1130
|
})();
|
|
1125
1131
|
return { mode: "lookback", description: "", occurredInThisTab: true, createIssue: e2.createIssue, issueName: "", issueDescription: "", createEngTicket: e2.createEngTicket, engTicketTeam: "", engTicketProject: "", engTicketPriority: 0, engTicketLabels: [], engTicketSprint: "", engTicketIssueType: "", engTicketCustomFields: {} };
|
|
1126
1132
|
}
|
|
1127
|
-
let De = getInitialState(),
|
|
1133
|
+
let De = getInitialState(), Pe = null, Be = null, _e = null, Oe = false, je = false;
|
|
1128
1134
|
function setSprintDefaulted(e2) {
|
|
1129
1135
|
je = e2;
|
|
1130
1136
|
}
|
|
@@ -1329,7 +1335,7 @@ function updateFormWithIntegrationData(e2) {
|
|
|
1329
1335
|
const a2 = document.getElementById("sf-eng-ticket-type");
|
|
1330
1336
|
return a2 && s2 && e2.engTicketProject && (updateIssueTypeOptions(a2, e2.engTicketProject), e2.engTicketIssueType ? (a2.value = e2.engTicketIssueType, a2.style.color = "#000") : a2.value && (e2.engTicketIssueType = a2.value)), e2;
|
|
1331
1337
|
}
|
|
1332
|
-
const
|
|
1338
|
+
const He = Object.freeze(Object.defineProperty({ __proto__: null, fetchIntegrationData: async function fetchIntegrationData(e2, t2) {
|
|
1333
1339
|
if (!Ne) try {
|
|
1334
1340
|
const n2 = await fetchEngineeringTicketPlatformIntegrations(e2, t2);
|
|
1335
1341
|
Ne = resolveIntegration(n2);
|
|
@@ -1370,7 +1376,7 @@ function renderCustomMultiSelect(e2, t2, n2, i2, o2 = false) {
|
|
|
1370
1376
|
</div>
|
|
1371
1377
|
`;
|
|
1372
1378
|
}
|
|
1373
|
-
const
|
|
1379
|
+
const ze = { 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 } }, We = { shortcuts: { ...ze }, resolveSessionId: null, apiKey: null, backendApi: null, triageBaseUrl: "https://app.sailfishqa.com", deactivateIsolation: () => {
|
|
1374
1380
|
}, integrationData: null, showEngTicketFieldsDefault: false };
|
|
1375
1381
|
let Ke = null, Ve = false;
|
|
1376
1382
|
function setupCustomMultiSelectListeners(e2, t2) {
|
|
@@ -1625,7 +1631,7 @@ function openReportIssueModal(e2) {
|
|
|
1625
1631
|
}
|
|
1626
1632
|
function closeModal() {
|
|
1627
1633
|
We.deactivateIsolation(), document.activeElement instanceof HTMLElement && document.activeElement.blur(), (Ke == null ? void 0 : Ke.parentNode) && Ke.parentNode.removeChild(Ke), Ke = null, Oe || (function resetState() {
|
|
1628
|
-
De = getInitialState(),
|
|
1634
|
+
De = getInitialState(), Pe = null, Be = null, je = false;
|
|
1629
1635
|
})(), _e && (clearInterval(_e), setTimerInterval(null));
|
|
1630
1636
|
}
|
|
1631
1637
|
function activateModalIsolation(e2) {
|
|
@@ -1940,7 +1946,7 @@ function injectModalHTML(e2 = "lookback") {
|
|
|
1940
1946
|
if (t4--, t4 > 0) e5.textContent = t4.toString();
|
|
1941
1947
|
else {
|
|
1942
1948
|
clearInterval(n3), document.body.removeChild(e5), (function setRecordingStartTime(e6) {
|
|
1943
|
-
|
|
1949
|
+
Pe = e6;
|
|
1944
1950
|
})(Date.now()), setIsRecording(true);
|
|
1945
1951
|
try {
|
|
1946
1952
|
const { enableFunctionSpanTracking: e6 } = await Promise.resolve().then(() => de);
|
|
@@ -1970,7 +1976,7 @@ function injectModalHTML(e2 = "lookback") {
|
|
|
1970
1976
|
const t5 = e6.querySelector("#sf-recording-timer");
|
|
1971
1977
|
if (!t5) return;
|
|
1972
1978
|
const n4 = setInterval(() => {
|
|
1973
|
-
const e7 = Date.now() - (
|
|
1979
|
+
const e7 = Date.now() - (Pe ?? Date.now()), n5 = Math.floor(e7 / 6e4).toString().padStart(2, "0"), i3 = Math.floor(e7 % 6e4 / 1e3).toString().padStart(2, "0");
|
|
1974
1980
|
t5.textContent = `${n5}:${i3}`;
|
|
1975
1981
|
}, 1e3);
|
|
1976
1982
|
setTimerInterval(n4);
|
|
@@ -1985,7 +1991,7 @@ function injectModalHTML(e2 = "lookback") {
|
|
|
1985
1991
|
const e5 = ((_a = document.getElementById("sf-issue-description")) == null ? void 0 : _a.value) || "", t4 = De.mode;
|
|
1986
1992
|
if (De.description = e5, De.createIssue && !De.issueName.trim()) return void alert("Issue title is required when creating an issue.");
|
|
1987
1993
|
let n3, i3;
|
|
1988
|
-
if ("startnow" === t4) n3 =
|
|
1994
|
+
if ("startnow" === t4) n3 = Pe ?? Date.now() - 3e5, i3 = Be ?? Date.now();
|
|
1989
1995
|
else {
|
|
1990
1996
|
const e6 = 60 * Number((o2 == null ? void 0 : o2.value) || "2") * 1e3;
|
|
1991
1997
|
i3 = Date.now(), n3 = i3 - e6;
|
|
@@ -1996,13 +2002,13 @@ function injectModalHTML(e2 = "lookback") {
|
|
|
1996
2002
|
const t5 = e6, n4 = t5.dataset.fieldId;
|
|
1997
2003
|
n4 && ("checkbox" === t5.type ? h2[n4] = t5.checked : "number" === t5.type ? h2[n4] = parseFloat(t5.value) || null : t5.classList.contains("sf-custom-multiselect") || (h2[n4] = t5.value));
|
|
1998
2004
|
});
|
|
1999
|
-
const y2 = document.getElementById("sf-eng-ticket-sprint"),
|
|
2000
|
-
if (
|
|
2005
|
+
const y2 = document.getElementById("sf-eng-ticket-sprint"), v2 = (y2 == null ? void 0 : y2.value) || De.engTicketSprint;
|
|
2006
|
+
if (v2) {
|
|
2001
2007
|
const e6 = getSprintFieldId();
|
|
2002
|
-
h2[e6] = parseInt(
|
|
2008
|
+
h2[e6] = parseInt(v2, 10);
|
|
2003
2009
|
}
|
|
2004
|
-
const isFieldEmpty = (e6) => null == e6 || ("string" == typeof e6 ? "" === e6.trim() : !!Array.isArray(e6) && 0 === e6.length),
|
|
2005
|
-
for (const e6 of
|
|
2010
|
+
const isFieldEmpty = (e6) => null == e6 || ("string" == typeof e6 ? "" === e6.trim() : !!Array.isArray(e6) && 0 === e6.length), b2 = De.createEngTicket ? (getFieldsForProject(p2, m2) || []).filter((e6) => e6 && e6.required) : [], S2 = [];
|
|
2011
|
+
for (const e6 of b2) {
|
|
2006
2012
|
const t5 = e6.fieldId || e6.key;
|
|
2007
2013
|
if ("summary" === t5 || "description" === t5 || "priority" === t5) continue;
|
|
2008
2014
|
let n4, i4;
|
|
@@ -2077,9 +2083,9 @@ function updateModeSpecificUI(e2) {
|
|
|
2077
2083
|
const t2 = document.querySelector("#sf-issue-mode-info div"), n2 = document.getElementById("sf-issue-submit-btn"), i2 = document.getElementById("sf-record-button-container"), o2 = document.getElementById("sf-recording-timer-label"), r2 = document.getElementById("sf-recording-timer-display"), s2 = document.getElementById("sf-modal-footer"), a2 = document.getElementById("sf-lookback-container");
|
|
2078
2084
|
if (t2 && n2 && i2 && o2 && r2 && s2 && a2) if ("startnow" === e2) {
|
|
2079
2085
|
i2.style.display = "block", a2.style.display = "none", s2.style.justifyContent = "space-between", t2.textContent = "I want to reproduce the issue right now.";
|
|
2080
|
-
const e3 = null !==
|
|
2081
|
-
if (n2.disabled = !e3, n2.style.opacity = e3 ? "1" : "0.4", n2.style.cursor = e3 ? "pointer" : "not-allowed",
|
|
2082
|
-
const e4 = Math.floor((
|
|
2086
|
+
const e3 = null !== Pe && null !== Be;
|
|
2087
|
+
if (n2.disabled = !e3, n2.style.opacity = e3 ? "1" : "0.4", n2.style.cursor = e3 ? "pointer" : "not-allowed", Pe && Be) {
|
|
2088
|
+
const e4 = Math.floor((Be - Pe) / 1e3), t3 = String(Math.floor(e4 / 60)).padStart(2, "0"), n3 = String(e4 % 60).padStart(2, "0");
|
|
2083
2089
|
o2.style.display = "block", r2.textContent = `${t3}:${n3}`;
|
|
2084
2090
|
} else o2.style.display = "none";
|
|
2085
2091
|
} else i2.style.display = "none", o2.style.display = "none", a2.style.display = "block", s2.style.justifyContent = "flex-end", t2.textContent = "Something already happened. Capture the past few minutes.", n2.disabled = false, n2.style.opacity = "1", n2.style.cursor = "pointer";
|
|
@@ -2143,7 +2149,7 @@ function bindEngTicketListeners() {
|
|
|
2143
2149
|
async function stopRecording() {
|
|
2144
2150
|
var _a;
|
|
2145
2151
|
!(function setRecordingEndTime(e2) {
|
|
2146
|
-
|
|
2152
|
+
Be = e2;
|
|
2147
2153
|
})(Date.now()), setIsRecording(false), _e && (clearInterval(_e), setTimerInterval(null)), (_a = document.getElementById("sf-recording-indicator")) == null ? void 0 : _a.remove();
|
|
2148
2154
|
try {
|
|
2149
2155
|
const { disableFunctionSpanTracking: e2 } = await Promise.resolve().then(() => de);
|
|
@@ -2159,8 +2165,8 @@ async function stopRecording() {
|
|
|
2159
2165
|
t3 && (t3.textContent = "Re-record");
|
|
2160
2166
|
}
|
|
2161
2167
|
const t2 = document.getElementById("sf-recording-timer-label"), n2 = document.getElementById("sf-recording-timer-display");
|
|
2162
|
-
if (t2 && n2 &&
|
|
2163
|
-
const e3 = Math.floor((
|
|
2168
|
+
if (t2 && n2 && Pe && Be) {
|
|
2169
|
+
const e3 = Math.floor((Be - Pe) / 1e3), i3 = Math.floor(e3 / 60).toString().padStart(2, "0"), o3 = (e3 % 60).toString().padStart(2, "0");
|
|
2164
2170
|
n2.textContent = `${i3}:${o3}`, t2.style.display = "block";
|
|
2165
2171
|
}
|
|
2166
2172
|
const i2 = document.getElementById("sf-issue-description");
|
|
@@ -2169,7 +2175,7 @@ async function stopRecording() {
|
|
|
2169
2175
|
o2 && (o2.checked = true);
|
|
2170
2176
|
const r2 = document.getElementById("sf-inline-record-chip"), s2 = document.getElementById("sf-inline-record-timer");
|
|
2171
2177
|
if (r2 && s2) {
|
|
2172
|
-
const e3 = Math.floor(((
|
|
2178
|
+
const e3 = Math.floor(((Be ?? 0) - (Pe ?? 0)) / 1e3), t3 = Math.floor(e3 / 60).toString().padStart(2, "0"), n3 = Math.floor(e3 % 60).toString().padStart(2, "0");
|
|
2173
2179
|
s2.textContent = `${t3}:${n3}`, s2.style.color = "black", r2.style.display = "flex";
|
|
2174
2180
|
}
|
|
2175
2181
|
const a2 = document.getElementById("sf-issue-submit-btn");
|
|
@@ -2248,7 +2254,7 @@ function fadeCardAndRemove(e2, t2, n2 = 300) {
|
|
|
2248
2254
|
}
|
|
2249
2255
|
const Ge = Object.freeze(Object.defineProperty({ __proto__: null, ReportIssueContext: We, openReportIssueModal, setupIssueReporting: function setupIssueReporting(e2) {
|
|
2250
2256
|
We.apiKey = e2.apiKey, We.backendApi = e2.backendApi, We.resolveSessionId = e2.getSessionId, We.integrationData = e2.integrationData || null, We.showEngTicketFieldsDefault = e2.showEngTicketFieldsInReportIssueModalDefault ?? false, e2.customBaseUrl && (We.triageBaseUrl = e2.customBaseUrl), We.shortcuts = (function mergeShortcutsConfig(e3) {
|
|
2251
|
-
const t3 = { ...
|
|
2257
|
+
const t3 = { ...ze };
|
|
2252
2258
|
if (!e3) return t3;
|
|
2253
2259
|
"boolean" == typeof e3.enabled && (t3.enabled = e3.enabled);
|
|
2254
2260
|
const n2 = ["openModalExistingMode", "openModalCaptureNewMode", "closeModal", "submitReport", "startRecording", "stopRecording"];
|
|
@@ -2494,7 +2500,7 @@ function getCachedRegex(e2, t2) {
|
|
|
2494
2500
|
let i2 = et.get(n2);
|
|
2495
2501
|
return i2 || (i2 = new RegExp(e2, t2), et.set(n2, i2)), i2;
|
|
2496
2502
|
}
|
|
2497
|
-
const tt = new Set([".js", ".mjs", ".cjs", ".ts", ".css", ".scss", ".sass", ".less", ".styl", ".stylus", ".png", ".jpg", ".jpeg", ".gif", ".svg", ".webp", ".avif", ".bmp", ".ico", ".tiff", ".tif", ".heic", ".woff", ".woff2", ".ttf", ".otf", ".eot", ".mp4", ".webm", ".ogv", ".mp3", ".wav", ".flac", ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".csv", ".json", ".xml", ".txt", ".zip", ".rar", ".gz", ".tar", ".7z", ".map", ".webmanifest"].map((e2) => e2.toLowerCase())), nt = ["t.co", "*.twitter.com", "*.gravatar.com", "*.googleapis.com", "*.amazonaws.com", "*.smooch.io", "*.zendesk.com", "*.zdassets.com"], it = [400, 403], ot = "CORS", rt = 1, st = "authorization", at = "Authorization", ct = { recordCanvas: false, recordCrossOriginIframes: false, collectFonts: false, inlineImages: false, recordPassword: false, recordRealName: true, recordCreditCardInfo: false, recordSsn: false, recordDob: false, sampling: {}, enableFiberTracking: false, maskInputSelector: "", maskTextSelector: "", blockSelector: "", unmaskSelector: "", maskInputOptions: { password: true } }, lt = { level: ["info", "log", "warn", "error"], lengthThreshold: 1e4, stringifyOptions: { stringLengthLimit: 1e3, numOfKeysLimit: 20, depthOfLimit: 4 }, logger: "console" };
|
|
2503
|
+
const tt = new Set([".js", ".mjs", ".cjs", ".ts", ".css", ".scss", ".sass", ".less", ".styl", ".stylus", ".png", ".jpg", ".jpeg", ".gif", ".svg", ".webp", ".avif", ".bmp", ".ico", ".tiff", ".tif", ".heic", ".woff", ".woff2", ".ttf", ".otf", ".eot", ".mp4", ".webm", ".ogv", ".mp3", ".wav", ".flac", ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".csv", ".json", ".xml", ".txt", ".zip", ".rar", ".gz", ".tar", ".7z", ".map", ".webmanifest"].map((e2) => e2.toLowerCase())), nt = ["t.co", "*.twitter.com", "*.gravatar.com", "*.googleapis.com", "*.amazonaws.com", "*.smooch.io", "*.zendesk.com", "*.zdassets.com"], it = [400, 403], ot = "CORS", rt = 1, st = "authorization", at = "Authorization", ct = { recordCanvas: false, recordCrossOriginIframes: false, collectFonts: false, inlineImages: false, recordPassword: false, recordRealName: true, recordCreditCardInfo: false, recordSsn: false, recordDob: false, sampling: {}, enableFiberTracking: false, maskInputSelector: "", maskTextSelector: "", blockSelector: "", unmaskSelector: "", maskInputOptions: { password: true }, recordHover: true, hoverDwellMs: 500, hoverStrictAffordance: true, hoverCooldownMs: 3e3, hoverMaxPerSession: 300, hoverMaxPerSecond: 1 }, lt = { level: ["info", "log", "warn", "error"], lengthThreshold: 1e4, stringifyOptions: { stringLengthLimit: 1e3, numOfKeysLimit: 20, depthOfLimit: 4 }, logger: "console" };
|
|
2498
2504
|
function maskAuthorizationHeader(e2) {
|
|
2499
2505
|
const t2 = e2[st] ? st : e2[at] ? at : null;
|
|
2500
2506
|
if (!t2) return;
|
|
@@ -2660,13 +2666,13 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
|
|
|
2660
2666
|
Ze && console.warn("[Sailfish] Failed to capture request data:", e5);
|
|
2661
2667
|
}
|
|
2662
2668
|
delete h2[f];
|
|
2663
|
-
const
|
|
2664
|
-
|
|
2665
|
-
const
|
|
2666
|
-
h2[f] =
|
|
2669
|
+
const v2 = getFuncSpanHeader();
|
|
2670
|
+
v2 && delete h2[v2.name];
|
|
2671
|
+
const b2 = `${c3}/${u2.page_visit_uuid}/${d3}`;
|
|
2672
|
+
h2[f] = b2, v2 && (h2[v2.name] = v2.value);
|
|
2667
2673
|
maskAuthorizationHeader(h2);
|
|
2668
2674
|
try {
|
|
2669
|
-
let
|
|
2675
|
+
let v3 = await (async function injectHeader(e5, t3, n5, i5, o4, r4, s3) {
|
|
2670
2676
|
const a3 = getFuncSpanHeader();
|
|
2671
2677
|
if (n5 instanceof Request) {
|
|
2672
2678
|
const c4 = n5.clone(), l4 = new Headers(c4.headers);
|
|
@@ -2678,8 +2684,8 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
|
|
|
2678
2684
|
const c4 = { ...i5 }, l4 = new Headers(i5.headers || {});
|
|
2679
2685
|
return l4.set(f, `${o4}/${r4}/${s3}`), a3 && (l4.set(a3.name, a3.value), Ze && console.log("[Sailfish] Added funcspan header to HTTP fetch:", { url: "string" == typeof n5 ? n5 : n5.href, header: a3.name })), c4.headers = l4, await e5.call(t3, n5, c4);
|
|
2680
2686
|
}
|
|
2681
|
-
})(e4, n4, o3, r3, c3, u2.page_visit_uuid, d3),
|
|
2682
|
-
it.includes(
|
|
2687
|
+
})(e4, n4, o3, r3, c3, u2.page_visit_uuid, d3), b3 = false;
|
|
2688
|
+
it.includes(v3.status) && (Ze && console.log("Perform retry as status was fail:", v3), delete h2[f], v3 = await (async function retryWithoutPropagateHeaders(e5, t3, n5, i5) {
|
|
2683
2689
|
try {
|
|
2684
2690
|
let i6 = n5[0], o4 = n5[1] || {};
|
|
2685
2691
|
if ("string" == typeof i6 || i6 instanceof URL) {
|
|
@@ -2697,19 +2703,19 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
|
|
|
2697
2703
|
} catch (e6) {
|
|
2698
2704
|
throw Ze && console.log(`Retry without ${f} for ${i5} also failed:`, e6), e6;
|
|
2699
2705
|
}
|
|
2700
|
-
})(e4, n4, i4, l3),
|
|
2706
|
+
})(e4, n4, i4, l3), b3 = true);
|
|
2701
2707
|
const S2 = Date.now(), w2 = (function captureClientTime() {
|
|
2702
2708
|
return { wallTimeMs: Date.now(), monotonicMs: monotonicNow(), timeOriginMs: timeOriginMs() };
|
|
2703
|
-
})(), k2 =
|
|
2709
|
+
})(), k2 = v3.status, x2 = v3.ok, I2 = x2 ? "" : `Request Error: ${v3.statusText}`;
|
|
2704
2710
|
let T2 = null;
|
|
2705
2711
|
try {
|
|
2706
|
-
T2 = {},
|
|
2712
|
+
T2 = {}, v3.headers.forEach((e5, t3) => {
|
|
2707
2713
|
T2[t3] = e5;
|
|
2708
2714
|
});
|
|
2709
2715
|
} catch (e5) {
|
|
2710
2716
|
Ze && console.warn("[Sailfish] Failed to capture response headers:", e5), T2 = null;
|
|
2711
2717
|
}
|
|
2712
|
-
const E2 = { type: 27, timestamp: S2, sessionId: c3, client: w2, data: { request_id: d3, session_id: c3, timestamp_start: g2, timestamp_end: S2, response_code: k2, success: x2, error: I2, method: p2, url: toAbsoluteUrl(l3), retry_without_trace_id:
|
|
2718
|
+
const E2 = { type: 27, timestamp: S2, sessionId: c3, client: w2, data: { request_id: d3, session_id: c3, timestamp_start: g2, timestamp_end: S2, response_code: k2, success: x2, error: I2, method: p2, url: toAbsoluteUrl(l3), retry_without_trace_id: b3, request_headers: h2, request_body: m2, response_headers: T2, response_body: null }, ...u2 }, sendEventWithBody = (e5) => {
|
|
2713
2719
|
E2.data.response_body = e5, y2 ? y2.text().then((e6) => {
|
|
2714
2720
|
E2.data.request_body = e6, sendEvent(E2);
|
|
2715
2721
|
}, () => {
|
|
@@ -2722,13 +2728,13 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
|
|
|
2722
2728
|
if (!t3) return false;
|
|
2723
2729
|
const n5 = t3.toLowerCase();
|
|
2724
2730
|
return a2.some((e6) => n5.includes(e6));
|
|
2725
|
-
})(
|
|
2731
|
+
})(v3)) sendEventWithBody(null);
|
|
2726
2732
|
else if ((function isStreamingResponse(e5) {
|
|
2727
2733
|
const t3 = e5.headers.get("content-type");
|
|
2728
2734
|
if (!t3) return false;
|
|
2729
2735
|
const n5 = t3.toLowerCase();
|
|
2730
2736
|
return s2.some((e6) => n5.includes(e6));
|
|
2731
|
-
})(
|
|
2737
|
+
})(v3)) if (t2.captureStreamingResponseBody) try {
|
|
2732
2738
|
(async function readStreamPrefix(e5, t3, n5) {
|
|
2733
2739
|
const i5 = e5.body;
|
|
2734
2740
|
if (!i5) return null;
|
|
@@ -2766,23 +2772,23 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
|
|
|
2766
2772
|
}
|
|
2767
2773
|
return null;
|
|
2768
2774
|
}
|
|
2769
|
-
})(
|
|
2775
|
+
})(v3.clone(), 1024 * t2.captureStreamPrefixKb, t2.captureStreamTimeoutMs).then((e5) => sendEventWithBody(e5), () => sendEventWithBody(null));
|
|
2770
2776
|
} catch {
|
|
2771
2777
|
sendEventWithBody(null);
|
|
2772
2778
|
}
|
|
2773
2779
|
else sendEventWithBody(null);
|
|
2774
2780
|
else {
|
|
2775
|
-
const e5 =
|
|
2781
|
+
const e5 = v3.headers.get("content-length"), t3 = e5 ? parseInt(e5, 10) : NaN;
|
|
2776
2782
|
if (!isNaN(t3) && t3 > C2) sendEventWithBody(null);
|
|
2777
2783
|
else try {
|
|
2778
|
-
|
|
2784
|
+
v3.clone().text().then((e6) => {
|
|
2779
2785
|
e6.length > C2 ? sendEventWithBody(null) : sendEventWithBody(e6);
|
|
2780
2786
|
}, () => sendEventWithBody(null));
|
|
2781
2787
|
} catch {
|
|
2782
2788
|
sendEventWithBody(null);
|
|
2783
2789
|
}
|
|
2784
2790
|
}
|
|
2785
|
-
return
|
|
2791
|
+
return v3;
|
|
2786
2792
|
} catch (t3) {
|
|
2787
2793
|
const o4 = Date.now(), r4 = false, s3 = ((_a = t3.response) == null ? void 0 : _a.status) || 500, a3 = t3.message || "Fetch request failed";
|
|
2788
2794
|
if (t3 instanceof TypeError && ((_b = t3 == null ? void 0 : t3.message) == null ? void 0 : _b.toLowerCase().includes(ot.toLowerCase()))) return e4.apply(n4, i4);
|
|
@@ -2797,7 +2803,7 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
|
|
|
2797
2803
|
})(e3, n3, i3, l2, d2, o2, c2);
|
|
2798
2804
|
} });
|
|
2799
2805
|
}
|
|
2800
|
-
async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-service.sailfishqa.com", domainsToPropagateHeaderTo: n2 = ["*"], domainsToNotPropagateHeaderTo: i2 = [], serviceVersion: o2, serviceIdentifier: r2, gitSha: s2, serviceAdditionalMetadata: a2, enableIpTracking: c2, captureStreamingResponseBody: l2 = true, captureResponseBodyMaxMb: d2 = 10, captureStreamPrefixKb: u2 = 64, captureStreamTimeoutMs: g2 = 1e4, enableFiberTracking: m2 = false, deferRecording: h2, deferRecordingStart: y2, chunkSnapshot:
|
|
2806
|
+
async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-service.sailfishqa.com", domainsToPropagateHeaderTo: n2 = ["*"], domainsToNotPropagateHeaderTo: i2 = [], serviceVersion: o2, serviceIdentifier: r2, gitSha: s2, serviceAdditionalMetadata: a2, enableIpTracking: c2, captureStreamingResponseBody: l2 = true, captureResponseBodyMaxMb: d2 = 10, captureStreamPrefixKb: u2 = 64, captureStreamTimeoutMs: g2 = 1e4, enableFiberTracking: m2 = false, deferRecording: h2, deferRecordingStart: y2, chunkSnapshot: v2, useWsWorker: b2 = true, capturePerformanceMetrics: S2 = true, maskTextClass: w2, maskInputSelector: k2, maskTextSelector: x2, blockSelector: I2, unmaskSelector: T2, maskInputOptions: E2, recordCanvas: C2, maskCanvasClass: M2, gitOrg: $2, gitRepo: F2, gitProvider: L2, library: R2, headlessRecording: D2 = false }) {
|
|
2801
2807
|
var _a, _b, _c, _d;
|
|
2802
2808
|
if (!D2 && (function isHeadlessOrLighthouse() {
|
|
2803
2809
|
try {
|
|
@@ -2810,8 +2816,8 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
|
|
|
2810
2816
|
return false;
|
|
2811
2817
|
}
|
|
2812
2818
|
})()) return;
|
|
2813
|
-
const
|
|
2814
|
-
if (_2.sessionId =
|
|
2819
|
+
const P2 = h2 ?? y2 ?? true, B2 = getOrSetSessionId(), _2 = window.__sailfish_recorder || (window.__sailfish_recorder = {});
|
|
2820
|
+
if (_2.sessionId = B2, _2.apiKey = e2, _2.backendApi = t2, _2.serviceAdditionalMetadata = a2, _2.initialized && _2.sessionId === B2 && _2.ws && 1 === _2.ws.readyState) return void trackDomainChangesOnce();
|
|
2815
2821
|
const O2 = { captureStreamingResponseBody: l2, captureResponseBodyMaxMb: d2, captureStreamPrefixKb: u2, captureStreamTimeoutMs: g2 };
|
|
2816
2822
|
sessionStorage.getItem("pageVisitUUID") || (sessionStorage.setItem("pageVisitUUID", uuidv4()), invalidateUrlCache()), _2.xhrPatched || (!(function setupXMLHttpRequestInterceptor(e3 = [], t3 = { captureStreamingResponseBody: true, captureResponseBodyMaxMb: 10, captureStreamPrefixKb: 64, captureStreamTimeoutMs: 1e4 }, n3 = []) {
|
|
2817
2823
|
const i3 = XMLHttpRequest.prototype.open, o3 = XMLHttpRequest.prototype.send, r3 = XMLHttpRequest.prototype.setRequestHeader, s3 = getOrSetSessionId(), a3 = createSkipHeadersPropagationChecker(e3, n3);
|
|
@@ -2887,13 +2893,13 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
|
|
|
2887
2893
|
}
|
|
2888
2894
|
_2.canvasObjLogInit = true;
|
|
2889
2895
|
}
|
|
2890
|
-
await yieldToMain(), _2.domEventsInit || (initializeDomContentEvents(
|
|
2896
|
+
await yieldToMain(), _2.domEventsInit || (initializeDomContentEvents(B2), _2.domEventsInit = true), await yieldToMain(), _2.consoleInit || (initializeConsolePlugin(lt, B2), _2.consoleInit = true), await yieldToMain(), _2.errorInit || (!(function initializeErrorInterceptor() {
|
|
2891
2897
|
window.addEventListener("error", (e3) => {
|
|
2892
2898
|
captureError(e3.error ?? e3.message, false, { filename: e3.filename, lineno: e3.lineno, colno: e3.colno });
|
|
2893
2899
|
}), window.addEventListener("unhandledrejection", (e3) => {
|
|
2894
2900
|
captureError(e3.reason, true);
|
|
2895
2901
|
});
|
|
2896
|
-
})(), _2.errorInit = true), await yieldToMain(), !_2.perfInit && S2 && (initializePerformancePlugin(
|
|
2902
|
+
})(), _2.errorInit = true), await yieldToMain(), !_2.perfInit && S2 && (initializePerformancePlugin(B2), _2.perfInit = true), await yieldToMain(), _ensureModuleSideEffects(), (function storeCredentialsAndConnection({ apiKey: e3, backendApi: t3 }) {
|
|
2897
2903
|
A && (sessionStorage.setItem("sailfishApiKey", e3), sessionStorage.setItem("sailfishBackendApi", t3));
|
|
2898
2904
|
})({ apiKey: e2, backendApi: t2 }), !isFunctionSpanTrackingEnabled() || _2.ws && 1 === _2.ws.readyState || fetchFunctionSpanTrackingEnabled(e2, t2).then((e3) => {
|
|
2899
2905
|
var _a2;
|
|
@@ -2902,7 +2908,7 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
|
|
|
2902
2908
|
Ze && console.warn("[Sailfish] Failed to validate function span tracking status with backend:", e3);
|
|
2903
2909
|
}), _2.sentDoNotPropagateOnce || (sendDomainsToNotPropagateHeaderTo(e2, [...i2, ...nt], t2).catch((e3) => console.error("Failed to send domains to not propagate header to:", e3)), _2.sentDoNotPropagateOnce = true), (async function gatherAndCacheDeviceInfo() {
|
|
2904
2910
|
sendMessage({ type: "deviceInfo", data: { deviceInfo: { language: navigator.language, userAgent: navigator.userAgent } } });
|
|
2905
|
-
})(), c2 && fetchAndSendIp(
|
|
2911
|
+
})(), c2 && fetchAndSendIp(B2);
|
|
2906
2912
|
try {
|
|
2907
2913
|
const n3 = s2 ?? (function readGitSha() {
|
|
2908
2914
|
var _a2;
|
|
@@ -2941,12 +2947,12 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
|
|
|
2941
2947
|
return { framework: i4[0] ?? null, additionalFrameworks: i4.slice(1), serviceRole: "frontend" };
|
|
2942
2948
|
})(), f2 = { ...u3, serviceRole: p2.serviceRole, ...null !== p2.framework && { framework: p2.framework }, ...p2.additionalFrameworks.length > 0 && { additionalFrameworks: p2.additionalFrameworks } };
|
|
2943
2949
|
await yieldToMain();
|
|
2944
|
-
const [g3, h3] = await Promise.all([fetchCaptureSettings(e2, t2), startRecordingSession(e2,
|
|
2950
|
+
const [g3, h3] = await Promise.all([fetchCaptureSettings(e2, t2), startRecordingSession(e2, B2, t2, i3, c3, d3, n3, l3, f2, $2, F2, L2)]), y3 = { ...ct, ...(_a = g3.data) == null ? void 0 : _a.captureSettingsFromApiKey, enableFiberTracking: m2, ...void 0 !== w2 ? { maskTextClass: w2 } : {}, ...void 0 !== k2 ? { maskInputSelector: k2 } : {}, ...void 0 !== x2 ? { maskTextSelector: x2 } : {}, ...void 0 !== I2 ? { blockSelector: I2 } : {}, ...void 0 !== T2 ? { unmaskSelector: T2 } : {}, ...void 0 !== E2 ? { maskInputOptions: E2 } : {}, recordCanvas: C2 ?? ((_c = (_b = g3.data) == null ? void 0 : _b.captureSettingsFromApiKey) == null ? void 0 : _c.recordCanvasSf) ?? ct.recordCanvas, ...void 0 !== M2 ? { maskCanvasClass: M2 } : {} };
|
|
2945
2951
|
if (_2.ws && 1 === _2.ws.readyState) return;
|
|
2946
2952
|
if ((_d = h3.data) == null ? void 0 : _d.startRecordingSession) {
|
|
2947
2953
|
const n4 = (a2 == null ? void 0 : a2.env) || (a2 == null ? void 0 : a2.environment);
|
|
2948
2954
|
await yieldToMain();
|
|
2949
|
-
const i4 = await initializeRecording(y3, t2, e2,
|
|
2955
|
+
const i4 = await initializeRecording(y3, t2, e2, B2, n4, P2, b2, v2 ?? false);
|
|
2950
2956
|
_2.ws = i4, _2.initialized = true, trackDomainChangesOnce(), _2.sentMapUuidOnce || (!(function sendMapUuidIfAvailable(e3 = "", t3 = "") {
|
|
2951
2957
|
window.sfMapUuid && sendMessage({ type: "mapUuid", data: { mapUuid: window.sfMapUuid, serviceIdentifier: e3, serviceVersion: t3 } });
|
|
2952
2958
|
})(r2, o2), _2.sentMapUuidOnce = true);
|
|
@@ -2963,7 +2969,7 @@ const initRecorder = async (e2) => {
|
|
|
2963
2969
|
return clearPageVisitDataFromSessionStorage(), t2.initialized && t2.sessionId === n2 && t2.ws && 1 === t2.ws.readyState ? void 0 : (t2.initPromise || (t2.initPromise = (async () => {
|
|
2964
2970
|
try {
|
|
2965
2971
|
if (t2.hasLoggedInitOnce || (console.log("Initializing Sailfish Recorder (first run) …"), t2.hasLoggedInitOnce = true), await startRecording(e2), !t2.issueReportingInit) {
|
|
2966
|
-
const n3 = e2.backendApi ?? "https://api-service.sailfishqa.com", [{ setupIssueReporting: i2 }, { fetchIntegrationData: o2, getIntegrationData: r2 }] = await Promise.all([Promise.resolve().then(() => Ge), Promise.resolve().then(() =>
|
|
2972
|
+
const n3 = e2.backendApi ?? "https://api-service.sailfishqa.com", [{ setupIssueReporting: i2 }, { fetchIntegrationData: o2, getIntegrationData: r2 }] = await Promise.all([Promise.resolve().then(() => Ge), Promise.resolve().then(() => He)]);
|
|
2967
2973
|
let s2 = null;
|
|
2968
2974
|
try {
|
|
2969
2975
|
await o2(e2.apiKey, n3), s2 = r2();
|
|
@@ -3026,7 +3032,7 @@ export {
|
|
|
3026
3032
|
maskCanvasDraws as N,
|
|
3027
3033
|
maskInputFn as O,
|
|
3028
3034
|
matchUrlWithWildcard as P,
|
|
3029
|
-
|
|
3035
|
+
P as Q,
|
|
3030
3036
|
onNavigationChange as R,
|
|
3031
3037
|
rt as S,
|
|
3032
3038
|
openReportIssueModal as T,
|