@sailfish-ai/recorder 1.10.12 → 1.10.13

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.
@@ -370,7 +370,7 @@ function initializeWebSocket(t2, n2, i2, o2, s2 = false) {
370
370
  const t3 = new URL(e2);
371
371
  return `${t3.hostname}${t3.port ? `:${t3.port}` : ""}`;
372
372
  })(t2);
373
- let r2 = `${"https:" === new URL(t2).protocol ? "wss" : "ws"}://${a2}/ws/notify/?apiKey=${n2}&sessionId=${i2}&sender=JS%2FTS&version=1.10.12`;
373
+ let r2 = `${"https:" === new URL(t2).protocol ? "wss" : "ws"}://${a2}/ws/notify/?apiKey=${n2}&sessionId=${i2}&sender=JS%2FTS&version=1.10.13`;
374
374
  if (o2 && (r2 += `&envValue=${encodeURIComponent(o2)}`), k = s2 ? (function tryCreateWsWorker() {
375
375
  if ("undefined" == typeof Worker) return null;
376
376
  try {
@@ -701,7 +701,7 @@ async function initializeRecording(e2, n2, i2, o2, s2, a2 = true, r2 = false, l2
701
701
  }
702
702
  const { record: n4 } = await import("@sailfish-rrweb/rrweb-record-only");
703
703
  if (J = n4, await yieldToMain(), l2) {
704
- const { chunkedSnapshot: i3 } = await import("./chunkSerializer-kuVb759b.js"), o3 = n4.mirror;
704
+ const { chunkedSnapshot: i3 } = await import("./chunkSerializer-Dk1eF3S8.js"), o3 = n4.mirror;
705
705
  let s3 = true;
706
706
  const a3 = [];
707
707
  n4({ emit(e3) {
@@ -2002,7 +2002,7 @@ function matchUrlWithWildcard(e2, t2) {
2002
2002
  let [n3, i3] = t3.split("/", 2), o3 = "";
2003
2003
  n3.includes(":") && ([n3, o3] = n3.split(":"));
2004
2004
  const r3 = getCachedRegex(`^${n3.replace(/\./g, "\\.").replace(/\*/g, ".*")}$`, "i"), c2 = l2.startsWith("www.") ? l2.slice(4) : l2;
2005
- if (o3 && a2 !== o3) return false;
2005
+ if (o3 && "*" !== o3 && a2 !== o3) return false;
2006
2006
  if (n3.startsWith("*.")) {
2007
2007
  const e4 = n3.slice(2).toLowerCase();
2008
2008
  if (!(l2 === e4 || c2 === e4 || l2.endsWith("." + e4))) return false;
@@ -2018,34 +2018,34 @@ function matchUrlWithWildcard(e2, t2) {
2018
2018
  return true;
2019
2019
  });
2020
2020
  }
2021
- function createSkipHeadersPropagationChecker(e2 = []) {
2022
- const t2 = [...Te, ...e2];
2021
+ function createSkipHeadersPropagationChecker(e2 = [], t2 = []) {
2022
+ const n2 = [...Te, ...e2], i2 = t2.length > 0;
2023
2023
  return function shouldSkipHeadersPropagation(e3) {
2024
- let n2;
2024
+ let o2;
2025
2025
  try {
2026
- n2 = new URL("string" == typeof e3 ? e3 : String((e3 == null ? void 0 : e3.url) ?? e3), window.location.href);
2026
+ o2 = new URL("string" == typeof e3 ? e3 : String((e3 == null ? void 0 : e3.url) ?? e3), window.location.href);
2027
2027
  } catch {
2028
2028
  return true;
2029
2029
  }
2030
- const i2 = n2.pathname.toLowerCase(), o2 = i2.lastIndexOf(".");
2031
- return !(-1 === o2 || !Ie.has(i2.slice(o2))) || !!matchUrlWithWildcard(e3, t2);
2030
+ const s2 = o2.pathname.toLowerCase(), a2 = s2.lastIndexOf(".");
2031
+ return !(-1 === a2 || !Ie.has(s2.slice(a2))) || (!(!i2 || matchUrlWithWildcard(e3, t2)) || !!matchUrlWithWildcard(e3, n2));
2032
2032
  };
2033
2033
  }
2034
- function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: true, captureResponseBodyMaxMb: 10, captureStreamPrefixKb: 64, captureStreamTimeoutMs: 1e4 }) {
2035
- const i2 = window.fetch, o2 = getOrSetSessionId(), s2 = createSkipHeadersPropagationChecker(e2), a2 = ["text/event-stream", "application/x-ndjson", "application/stream+json", "application/grpc", "application/grpc-web"], r2 = ["application/octet-stream"];
2036
- window.fetch = new Proxy(i2, { apply: async (e3, i3, l2) => {
2037
- let c2, d2 = l2[0], u2 = l2[1] || {};
2034
+ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: true, captureResponseBodyMaxMb: 10, captureStreamPrefixKb: 64, captureStreamTimeoutMs: 1e4 }, i2 = []) {
2035
+ const o2 = window.fetch, s2 = getOrSetSessionId(), a2 = createSkipHeadersPropagationChecker(e2, i2), r2 = ["text/event-stream", "application/x-ndjson", "application/stream+json", "application/grpc", "application/grpc-web"], l2 = ["application/octet-stream"];
2036
+ window.fetch = new Proxy(o2, { apply: async (e3, i3, o3) => {
2037
+ let c2, d2 = o3[0], u2 = o3[1] || {};
2038
2038
  if ("string" == typeof d2) c2 = d2;
2039
2039
  else if (d2 instanceof Request) c2 = d2.url;
2040
2040
  else {
2041
- if (!(d2 instanceof URL)) return e3.apply(i3, l2);
2041
+ if (!(d2 instanceof URL)) return e3.apply(i3, o3);
2042
2042
  c2 = d2.href;
2043
2043
  }
2044
- return s2(c2) ? e3.apply(i3, l2) : (async function injectHeaderWrapper(e4, i4, o3, s3, l3, c3, d3) {
2044
+ return a2(c2) ? e3.apply(i3, o3) : (async function injectHeaderWrapper(e4, i4, o4, s3, a3, c3, d3) {
2045
2045
  var _a, _b;
2046
- if (!c3) return e4.apply(i4, o3);
2046
+ if (!c3) return e4.apply(i4, o4);
2047
2047
  let u3 = uuidv4();
2048
- const p2 = getUrlAndStoredUuids(), f2 = l3.method || "GET", g2 = Date.now();
2048
+ const p2 = getUrlAndStoredUuids(), f2 = a3.method || "GET", g2 = Date.now();
2049
2049
  let m2, h2 = {}, y2 = null;
2050
2050
  try {
2051
2051
  if (s3 instanceof Request) {
@@ -2057,11 +2057,11 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
2057
2057
  } catch (e5) {
2058
2058
  y2 = null;
2059
2059
  }
2060
- } else l3.headers && (l3.headers instanceof Headers ? l3.headers.forEach((e5, t3) => {
2060
+ } else a3.headers && (a3.headers instanceof Headers ? a3.headers.forEach((e5, t3) => {
2061
2061
  h2[t3] = e5;
2062
- }) : Array.isArray(l3.headers) ? l3.headers.forEach(([e5, t3]) => {
2062
+ }) : Array.isArray(a3.headers) ? a3.headers.forEach(([e5, t3]) => {
2063
2063
  h2[e5] = t3;
2064
- }) : h2 = { ...l3.headers }), m2 = l3.body;
2064
+ }) : h2 = { ...a3.headers }), m2 = a3.body;
2065
2065
  } catch (e5) {
2066
2066
  ke && console.warn("[Sailfish] Failed to capture request data:", e5);
2067
2067
  }
@@ -2072,38 +2072,38 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
2072
2072
  h2[n] = w2, b2 && (h2[b2.name] = b2.value);
2073
2073
  maskAuthorizationHeader(h2);
2074
2074
  try {
2075
- let b3 = await (async function injectHeader(e5, t3, i5, o4, s4, a3, r3) {
2076
- const l4 = getFuncSpanHeader();
2075
+ let b3 = await (async function injectHeader(e5, t3, i5, o5, s4, a4, r3) {
2076
+ const l3 = getFuncSpanHeader();
2077
2077
  if (i5 instanceof Request) {
2078
2078
  const c4 = i5.clone(), d4 = new Headers(c4.headers);
2079
- d4.set(n, `${s4}/${a3}/${r3}`), l4 && (d4.set(l4.name, l4.value), ke && console.log("[Sailfish] Added funcspan header to HTTP Request:", { url: i5.url, header: l4.name }));
2079
+ d4.set(n, `${s4}/${a4}/${r3}`), l3 && (d4.set(l3.name, l3.value), ke && console.log("[Sailfish] Added funcspan header to HTTP Request:", { url: i5.url, header: l3.name }));
2080
2080
  const u4 = new Request(c4, { headers: d4 });
2081
- return await e5.call(t3, u4, o4);
2081
+ return await e5.call(t3, u4, o5);
2082
2082
  }
2083
2083
  {
2084
- const c4 = { ...o4 }, d4 = new Headers(o4.headers || {});
2085
- return d4.set(n, `${s4}/${a3}/${r3}`), l4 && (d4.set(l4.name, l4.value), ke && console.log("[Sailfish] Added funcspan header to HTTP fetch:", { url: "string" == typeof i5 ? i5 : i5.href, header: l4.name })), c4.headers = d4, await e5.call(t3, i5, c4);
2084
+ const c4 = { ...o5 }, d4 = new Headers(o5.headers || {});
2085
+ return d4.set(n, `${s4}/${a4}/${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);
2086
2086
  }
2087
- })(e4, i4, s3, l3, c3, p2.page_visit_uuid, u3), w3 = false;
2088
- 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, o4) {
2087
+ })(e4, i4, s3, a3, c3, p2.page_visit_uuid, u3), w3 = false;
2088
+ 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) {
2089
2089
  try {
2090
- let o5 = i5[0], s4 = i5[1] || {};
2091
- if ("string" == typeof o5 || o5 instanceof URL) {
2092
- const i6 = { ...s4 }, a3 = new Headers(s4.headers || {});
2093
- a3.delete(n), i6.headers = a3;
2094
- return await e5.call(t3, o5, i6);
2090
+ let o6 = i5[0], s4 = i5[1] || {};
2091
+ if ("string" == typeof o6 || o6 instanceof URL) {
2092
+ const i6 = { ...s4 }, a4 = new Headers(s4.headers || {});
2093
+ a4.delete(n), i6.headers = a4;
2094
+ return await e5.call(t3, o6, i6);
2095
2095
  }
2096
- if (o5 instanceof Request) {
2097
- const i6 = o5.clone(), a3 = new Headers(i6.headers);
2098
- a3.delete(n);
2099
- const r3 = new Request(i6, { headers: a3 });
2096
+ if (o6 instanceof Request) {
2097
+ const i6 = o6.clone(), a4 = new Headers(i6.headers);
2098
+ a4.delete(n);
2099
+ const r3 = new Request(i6, { headers: a4 });
2100
2100
  return await e5.call(t3, r3, s4);
2101
2101
  }
2102
2102
  return e5.apply(t3, i5);
2103
2103
  } catch (e6) {
2104
- throw ke && console.log(`Retry without ${n} for ${o4} also failed:`, e6), e6;
2104
+ throw ke && console.log(`Retry without ${n} for ${o5} also failed:`, e6), e6;
2105
2105
  }
2106
- })(e4, i4, o3, d3), w3 = true);
2106
+ })(e4, i4, o4, d3), w3 = true);
2107
2107
  const v2 = Date.now(), S2 = b3.status, k2 = b3.ok, x2 = k2 ? "" : `Request Error: ${b3.statusText}`;
2108
2108
  let I2 = null;
2109
2109
  try {
@@ -2125,32 +2125,32 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
2125
2125
  const t3 = e5.headers.get("content-type");
2126
2126
  if (!t3) return false;
2127
2127
  const n2 = t3.toLowerCase();
2128
- return r2.some((e6) => n2.includes(e6));
2128
+ return l2.some((e6) => n2.includes(e6));
2129
2129
  })(b3)) sendEventWithBody(null);
2130
2130
  else if ((function isStreamingResponse(e5) {
2131
2131
  const t3 = e5.headers.get("content-type");
2132
2132
  if (!t3) return false;
2133
2133
  const n2 = t3.toLowerCase();
2134
- return a2.some((e6) => n2.includes(e6));
2134
+ return r2.some((e6) => n2.includes(e6));
2135
2135
  })(b3)) if (t2.captureStreamingResponseBody) try {
2136
2136
  (async function readStreamPrefix(e5, t3, n2) {
2137
2137
  const i5 = e5.body;
2138
2138
  if (!i5) return null;
2139
- const o4 = i5.getReader(), s4 = new TextDecoder(), a3 = [];
2139
+ const o5 = i5.getReader(), s4 = new TextDecoder(), a4 = [];
2140
2140
  let r3 = 0;
2141
2141
  const readWithLimit = async () => {
2142
2142
  try {
2143
2143
  for (; r3 < t3; ) {
2144
- const { done: e6, value: t4 } = await o4.read();
2144
+ const { done: e6, value: t4 } = await o5.read();
2145
2145
  if (e6) break;
2146
- r3 += t4.byteLength, a3.push(s4.decode(t4, { stream: true }));
2146
+ r3 += t4.byteLength, a4.push(s4.decode(t4, { stream: true }));
2147
2147
  }
2148
- return a3.push(s4.decode()), a3.join("");
2148
+ return a4.push(s4.decode()), a4.join("");
2149
2149
  } catch {
2150
- return a3.length > 0 ? a3.join("") : null;
2150
+ return a4.length > 0 ? a4.join("") : null;
2151
2151
  } finally {
2152
2152
  try {
2153
- o4.cancel();
2153
+ o5.cancel();
2154
2154
  } catch {
2155
2155
  }
2156
2156
  }
@@ -2158,14 +2158,14 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
2158
2158
  try {
2159
2159
  return await Promise.race([readWithLimit(), new Promise((e6) => setTimeout(() => {
2160
2160
  try {
2161
- o4.cancel();
2161
+ o5.cancel();
2162
2162
  } catch {
2163
2163
  }
2164
- e6(a3.length > 0 ? a3.join("") : null);
2164
+ e6(a4.length > 0 ? a4.join("") : null);
2165
2165
  }, n2))]);
2166
2166
  } catch {
2167
2167
  try {
2168
- o4.cancel();
2168
+ o5.cancel();
2169
2169
  } catch {
2170
2170
  }
2171
2171
  return null;
@@ -2188,17 +2188,17 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
2188
2188
  }
2189
2189
  return b3;
2190
2190
  } catch (t3) {
2191
- const n2 = Date.now(), s4 = false, a3 = ((_a = t3.response) == null ? void 0 : _a.status) || 500, r3 = t3.message || "Fetch request failed";
2192
- if (t3 instanceof TypeError && ((_b = t3 == null ? void 0 : t3.message) == null ? void 0 : _b.toLowerCase().includes(Ce.toLowerCase()))) return e4.apply(i4, o3);
2193
- let l4 = m2;
2191
+ const n2 = Date.now(), s4 = false, a4 = ((_a = t3.response) == null ? void 0 : _a.status) || 500, r3 = t3.message || "Fetch request failed";
2192
+ if (t3 instanceof TypeError && ((_b = t3 == null ? void 0 : t3.message) == null ? void 0 : _b.toLowerCase().includes(Ce.toLowerCase()))) return e4.apply(i4, o4);
2193
+ let l3 = m2;
2194
2194
  if (y2) try {
2195
- l4 = await y2.text();
2195
+ l3 = await y2.text();
2196
2196
  } catch {
2197
- l4 = null;
2197
+ l3 = null;
2198
2198
  }
2199
- throw sendEvent({ type: 27, timestamp: n2, sessionId: c3, data: { request_id: u3, session_id: c3, timestamp_start: g2, timestamp_end: n2, response_code: a3, success: s4, error: r3, method: f2, url: d3, request_headers: h2, request_body: l4, response_body: null }, ...p2 }), t3;
2199
+ throw sendEvent({ type: 27, timestamp: n2, sessionId: c3, data: { request_id: u3, session_id: c3, timestamp_start: g2, timestamp_end: n2, response_code: a4, success: s4, error: r3, method: f2, url: d3, request_headers: h2, request_body: l3, response_body: null }, ...p2 }), t3;
2200
2200
  }
2201
- })(e3, i3, l2, d2, u2, o2, c2);
2201
+ })(e3, i3, o3, d2, u2, s2, c2);
2202
2202
  } });
2203
2203
  }
2204
2204
  async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-service.sailfishqa.com", domainsToPropagateHeaderTo: i2 = [], domainsToNotPropagateHeaderTo: o2 = [], serviceVersion: s2, serviceIdentifier: a2, 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 }) {
@@ -2217,17 +2217,17 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
2217
2217
  const v2 = h2 ?? y2 ?? true, S2 = getOrSetSessionId(), k2 = window.__sailfish_recorder || (window.__sailfish_recorder = {});
2218
2218
  if (k2.sessionId = S2, k2.apiKey = e2, k2.backendApi = t2, k2.serviceAdditionalMetadata = l2, k2.initialized && k2.sessionId === S2 && k2.ws && 1 === k2.ws.readyState) return void trackDomainChangesOnce();
2219
2219
  const x2 = { captureStreamingResponseBody: d2, captureResponseBodyMaxMb: u2, captureStreamPrefixKb: p2, captureStreamTimeoutMs: f2 };
2220
- sessionStorage.getItem("pageVisitUUID") || (sessionStorage.setItem("pageVisitUUID", uuidv4()), invalidateUrlCache()), k2.xhrPatched || (!(function setupXMLHttpRequestInterceptor(e3 = [], t3 = { captureStreamingResponseBody: true, captureResponseBodyMaxMb: 10, captureStreamPrefixKb: 64, captureStreamTimeoutMs: 1e4 }) {
2221
- const i3 = XMLHttpRequest.prototype.open, o3 = XMLHttpRequest.prototype.send, s3 = XMLHttpRequest.prototype.setRequestHeader, a3 = getOrSetSessionId(), r3 = createSkipHeadersPropagationChecker(e3);
2220
+ sessionStorage.getItem("pageVisitUUID") || (sessionStorage.setItem("pageVisitUUID", uuidv4()), invalidateUrlCache()), k2.xhrPatched || (!(function setupXMLHttpRequestInterceptor(e3 = [], t3 = { captureStreamingResponseBody: true, captureResponseBodyMaxMb: 10, captureStreamPrefixKb: 64, captureStreamTimeoutMs: 1e4 }, i3 = []) {
2221
+ const o3 = XMLHttpRequest.prototype.open, s3 = XMLHttpRequest.prototype.send, a3 = XMLHttpRequest.prototype.setRequestHeader, r3 = getOrSetSessionId(), l3 = createSkipHeadersPropagationChecker(e3, i3);
2222
2222
  XMLHttpRequest.prototype.setRequestHeader = function(e4, t4) {
2223
- return this._capturedRequestHeaders || (this._capturedRequestHeaders = {}), this._capturedRequestHeaders[e4] = t4, s3.call(this, e4, t4);
2223
+ return this._capturedRequestHeaders || (this._capturedRequestHeaders = {}), this._capturedRequestHeaders[e4] = t4, a3.call(this, e4, t4);
2224
2224
  }, XMLHttpRequest.prototype.open = function(e4, t4, ...n2) {
2225
- return this._requestUrl = "string" == typeof t4 && t4.length > 0 ? t4 : null, this._requestMethod = e4, this._capturedRequestHeaders = {}, i3.apply(this, [e4, t4, ...n2]);
2225
+ return this._requestUrl = "string" == typeof t4 && t4.length > 0 ? t4 : null, this._requestMethod = e4, this._capturedRequestHeaders = {}, o3.apply(this, [e4, t4, ...n2]);
2226
2226
  }, XMLHttpRequest.prototype.send = function(...e4) {
2227
2227
  const i4 = this._requestUrl;
2228
- if (!i4) return o3.apply(this, e4);
2229
- if (r3(i4)) return o3.apply(this, e4);
2230
- const s4 = sessionStorage.getItem("pageVisitUUID"), l3 = uuidv4(), c3 = `${a3}/${s4}/${l3}`;
2228
+ if (!i4) return s3.apply(this, e4);
2229
+ if (l3(i4)) return s3.apply(this, e4);
2230
+ const o4 = sessionStorage.getItem("pageVisitUUID"), a4 = uuidv4(), c3 = `${r3}/${o4}/${a4}`;
2231
2231
  try {
2232
2232
  this.setRequestHeader(n, c3);
2233
2233
  } catch (e5) {
@@ -2243,21 +2243,21 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
2243
2243
  let p3 = false;
2244
2244
  const f3 = e4[0], g2 = { ...this._capturedRequestHeaders };
2245
2245
  maskAuthorizationHeader(g2);
2246
- const emitFinished = (e5, t4, n2, o4, s5) => {
2246
+ const emitFinished = (e5, t4, n2, o5, s4) => {
2247
2247
  if (p3) return;
2248
2248
  p3 = true;
2249
- const r4 = Date.now();
2250
- sendEvent({ type: 27, timestamp: r4, sessionId: a3, data: { request_id: l3, session_id: a3, timestamp_start: u3, timestamp_end: r4, response_code: t4, success: e5, error: n2, method: this._requestMethod, url: i4, request_headers: g2, request_body: f3, response_headers: s5, response_body: o4 }, ...getUrlAndStoredUuids() });
2249
+ const l4 = Date.now();
2250
+ sendEvent({ type: 27, timestamp: l4, sessionId: r3, data: { request_id: a4, session_id: r3, timestamp_start: u3, timestamp_end: l4, response_code: t4, success: e5, error: n2, method: this._requestMethod, url: i4, request_headers: g2, request_body: f3, response_headers: s4, response_body: o5 }, ...getUrlAndStoredUuids() });
2251
2251
  };
2252
2252
  return this.addEventListener("load", () => {
2253
2253
  const e5 = this.status || 0;
2254
2254
  let n2, i5 = null;
2255
- const o4 = 1024 * t3.captureResponseBodyMaxMb * 1024;
2255
+ const o5 = 1024 * t3.captureResponseBodyMaxMb * 1024;
2256
2256
  try {
2257
2257
  if (0 === t3.captureResponseBodyMaxMb) n2 = null;
2258
2258
  else {
2259
2259
  const e6 = this.responseText || this.response;
2260
- n2 = "string" == typeof e6 && e6.length > o4 ? null : e6;
2260
+ n2 = "string" == typeof e6 && e6.length > o5 ? null : e6;
2261
2261
  }
2262
2262
  } catch (e6) {
2263
2263
  n2 = null;
@@ -2280,9 +2280,9 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
2280
2280
  }, { once: true }), this.addEventListener("error", () => {
2281
2281
  const e5 = this.status || 0, t4 = 0 === e5 ? "Network or CORS failure" : this.statusText || `Error ${e5}`;
2282
2282
  emitFinished(false, e5, t4);
2283
- }, { once: true }), o3.apply(this, e4);
2283
+ }, { once: true }), s3.apply(this, e4);
2284
2284
  };
2285
- })(o2, x2), k2.xhrPatched = true), k2.fetchPatched || (setupFetchInterceptor(o2, x2), k2.fetchPatched = true), await yieldToMain(), k2.domEventsInit || (initializeDomContentEvents(S2), k2.domEventsInit = true), await yieldToMain(), k2.consoleInit || (initializeConsolePlugin(Ae, S2), k2.consoleInit = true), await yieldToMain(), k2.errorInit || (!(function initializeErrorInterceptor() {
2285
+ })(o2, x2, i2), k2.xhrPatched = true), k2.fetchPatched || (setupFetchInterceptor(o2, x2, i2), k2.fetchPatched = true), await yieldToMain(), k2.domEventsInit || (initializeDomContentEvents(S2), k2.domEventsInit = true), await yieldToMain(), k2.consoleInit || (initializeConsolePlugin(Ae, S2), k2.consoleInit = true), await yieldToMain(), k2.errorInit || (!(function initializeErrorInterceptor() {
2286
2286
  window.addEventListener("error", (e3) => {
2287
2287
  captureError(e3.error || e3.message);
2288
2288
  }), window.addEventListener("unhandledrejection", (e3) => {
@@ -2369,49 +2369,50 @@ const initRecorder = async (e2) => {
2369
2369
  })), t2.initPromise);
2370
2370
  };
2371
2371
  export {
2372
- initializeRecording as A,
2373
- initializeWebSocket as B,
2374
- invalidateUrlCache as C,
2372
+ initializeFunctionSpanTrackingFromApi as A,
2373
+ initializeRecording as B,
2374
+ initializeWebSocket as C,
2375
2375
  Me as D,
2376
- isFunctionSpanTrackingEnabled as E,
2377
- matchUrlWithWildcard as F,
2378
- w as G,
2379
- onNavigationChange as H,
2380
- openReportIssueModal as I,
2381
- restoreFuncSpanState as J,
2382
- sendDomainsToNotPropagateHeaderTo as K,
2383
- sendEvent as L,
2384
- sendGraphQLRequest as M,
2385
- sendMessage as N,
2386
- startRecording as O,
2387
- startRecordingSession as P,
2388
- trackingEvent as Q,
2389
- withAppUrlMetadata as R,
2376
+ invalidateUrlCache as E,
2377
+ isFunctionSpanTrackingEnabled as F,
2378
+ matchUrlWithWildcard as G,
2379
+ w as H,
2380
+ onNavigationChange as I,
2381
+ openReportIssueModal as J,
2382
+ restoreFuncSpanState as K,
2383
+ sendDomainsToNotPropagateHeaderTo as L,
2384
+ sendEvent as M,
2385
+ sendGraphQLRequest as N,
2386
+ sendMessage as O,
2387
+ startRecording as P,
2388
+ startRecordingSession as Q,
2389
+ trackingEvent as R,
2390
2390
  $e as S,
2391
+ withAppUrlMetadata as T,
2391
2392
  Ae as a,
2392
2393
  addOrUpdateMetadata as b,
2393
2394
  buildBatches as c,
2394
2395
  clearStaleFuncSpanState as d,
2395
- createTriageAndIssueFromRecorder as e,
2396
- createTriageFromRecorder as f,
2397
- disableFunctionSpanTracking as g,
2398
- enableFunctionSpanTracking as h,
2399
- ensureHrefCache as i,
2400
- eventSize as j,
2401
- fetchAndSendIp as k,
2402
- fetchCaptureSettings as l,
2403
- fetchEngineeringTicketPlatformIntegrations as m,
2404
- fetchFunctionSpanTrackingEnabled as n,
2405
- flushBufferedEvents as o,
2406
- getCachedHref as p,
2407
- getCachedHrefNoQuery as q,
2408
- getFuncSpanHeader as r,
2409
- getOrSetSessionId as s,
2410
- getUrlAndStoredUuids as t,
2411
- identify as u,
2412
- initRecorder as v,
2413
- initializeConsolePlugin as w,
2414
- initializeDomContentEvents as x,
2396
+ createSkipHeadersPropagationChecker as e,
2397
+ createTriageAndIssueFromRecorder as f,
2398
+ createTriageFromRecorder as g,
2399
+ disableFunctionSpanTracking as h,
2400
+ enableFunctionSpanTracking as i,
2401
+ ensureHrefCache as j,
2402
+ eventSize as k,
2403
+ fetchAndSendIp as l,
2404
+ fetchCaptureSettings as m,
2405
+ fetchEngineeringTicketPlatformIntegrations as n,
2406
+ fetchFunctionSpanTrackingEnabled as o,
2407
+ flushBufferedEvents as p,
2408
+ getCachedHref as q,
2409
+ getCachedHrefNoQuery as r,
2410
+ getFuncSpanHeader as s,
2411
+ getOrSetSessionId as t,
2412
+ getUrlAndStoredUuids as u,
2413
+ identify as v,
2414
+ initRecorder as w,
2415
+ initializeConsolePlugin as x,
2415
2416
  yieldToMain as y,
2416
- initializeFunctionSpanTrackingFromApi as z
2417
+ initializeDomContentEvents as z
2417
2418
  };
Binary file
Binary file
package/dist/index.js CHANGED
@@ -348,8 +348,8 @@ export function matchUrlWithWildcard(input, patterns) {
348
348
  const domainRegex = getCachedRegex(`^${normalizedPatternDomain}$`, "i");
349
349
  // Strip 'www.' from both the input domain and the pattern domain for comparison
350
350
  const strippedDomain = domain.startsWith("www.") ? domain.slice(4) : domain;
351
- // If pattern specifies a port, match the exact port
352
- if (patternPort && port !== patternPort)
351
+ // If pattern specifies a port, match the exact port (or any port if wildcard)
352
+ if (patternPort && patternPort !== "*" && port !== patternPort)
353
353
  return false;
354
354
  // handle patterns like "*.example.com"
355
355
  if (patternDomain.startsWith("*.")) {
@@ -383,12 +383,14 @@ export function matchUrlWithWildcard(input, patterns) {
383
383
  return true;
384
384
  });
385
385
  }
386
- function createSkipHeadersPropagationChecker(domainsToNotPropagateHeaderTo = []) {
386
+ export function createSkipHeadersPropagationChecker(domainsToNotPropagateHeaderTo = [], domainsToPropagateHeaderTo = []) {
387
387
  // Pre-compute the combined domain exclusion patterns once per interceptor setup
388
388
  const combinedPatterns = [
389
389
  ...DOMAINS_TO_NOT_PROPAGATE_HEADER_TO_DEFAULT,
390
390
  ...domainsToNotPropagateHeaderTo,
391
391
  ];
392
+ // Pre-compute allowlist presence once (avoids per-request .length check overhead)
393
+ const hasAllowlist = domainsToPropagateHeaderTo.length > 0;
392
394
  return function shouldSkipHeadersPropagation(url) {
393
395
  let urlObj;
394
396
  try {
@@ -404,7 +406,11 @@ function createSkipHeadersPropagationChecker(domainsToNotPropagateHeaderTo = [])
404
406
  if (lastDotIdx !== -1 && STATIC_EXTENSIONS_SET.has(lowerPathname.slice(lastDotIdx))) {
405
407
  return true;
406
408
  }
407
- // 2️⃣ WILDCARD-BASED EXCLUSION (domain + path)
409
+ // 2️⃣ ALLOWLIST CHECK if provided, URL must match at least one allowlist pattern
410
+ if (hasAllowlist && !matchUrlWithWildcard(url, domainsToPropagateHeaderTo)) {
411
+ return true;
412
+ }
413
+ // 3️⃣ WILDCARD-BASED EXCLUSION (domain + path) — blocklist still applies even if allowlisted
408
414
  if (matchUrlWithWildcard(url, combinedPatterns)) {
409
415
  return true;
410
416
  }
@@ -412,12 +418,12 @@ function createSkipHeadersPropagationChecker(domainsToNotPropagateHeaderTo = [])
412
418
  };
413
419
  }
414
420
  // Updated XMLHttpRequest interceptor with domain exclusion
415
- function setupXMLHttpRequestInterceptor(domainsToNotPropagateHeaderTo = [], bodyCaptureConfig = { captureStreamingResponseBody: true, captureResponseBodyMaxMb: 10, captureStreamPrefixKb: 64, captureStreamTimeoutMs: 10000 }) {
421
+ function setupXMLHttpRequestInterceptor(domainsToNotPropagateHeaderTo = [], bodyCaptureConfig = { captureStreamingResponseBody: true, captureResponseBodyMaxMb: 10, captureStreamPrefixKb: 64, captureStreamTimeoutMs: 10000 }, domainsToPropagateHeaderTo = []) {
416
422
  const originalOpen = XMLHttpRequest.prototype.open;
417
423
  const originalSend = XMLHttpRequest.prototype.send;
418
424
  const originalSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
419
425
  const sessionId = getOrSetSessionId();
420
- const shouldSkipHeadersPropagation = createSkipHeadersPropagationChecker(domainsToNotPropagateHeaderTo);
426
+ const shouldSkipHeadersPropagation = createSkipHeadersPropagationChecker(domainsToNotPropagateHeaderTo, domainsToPropagateHeaderTo);
421
427
  // Intercept setRequestHeader()
422
428
  XMLHttpRequest.prototype.setRequestHeader = function (name, value) {
423
429
  // initialize the buffer on first use
@@ -580,10 +586,10 @@ function setupXMLHttpRequestInterceptor(domainsToNotPropagateHeaderTo = [], body
580
586
  };
581
587
  }
582
588
  // Updated fetch interceptor with exclusion handling
583
- function setupFetchInterceptor(domainsToNotPropagateHeadersTo = [], bodyCaptureConfig = { captureStreamingResponseBody: true, captureResponseBodyMaxMb: 10, captureStreamPrefixKb: 64, captureStreamTimeoutMs: 10000 }) {
589
+ function setupFetchInterceptor(domainsToNotPropagateHeadersTo = [], bodyCaptureConfig = { captureStreamingResponseBody: true, captureResponseBodyMaxMb: 10, captureStreamPrefixKb: 64, captureStreamTimeoutMs: 10000 }, domainsToPropagateHeaderTo = []) {
584
590
  const originalFetch = window.fetch;
585
591
  const sessionId = getOrSetSessionId();
586
- const shouldSkipHeadersPropagation = createSkipHeadersPropagationChecker(domainsToNotPropagateHeadersTo);
592
+ const shouldSkipHeadersPropagation = createSkipHeadersPropagationChecker(domainsToNotPropagateHeadersTo, domainsToPropagateHeaderTo);
587
593
  // --- Streaming detection helpers ---
588
594
  // Content types that indicate a streaming response.
589
595
  // These responses should NOT have their body fully consumed — only a limited prefix is captured.
@@ -1067,11 +1073,11 @@ export async function startRecording({ apiKey, backendApi = "https://api-service
1067
1073
  // 1a. XHR + Fetch interceptors (must both run synchronously before any yield,
1068
1074
  // so fire-and-forget callers patch fetch before frameworks capture it)
1069
1075
  if (!g.xhrPatched) {
1070
- setupXMLHttpRequestInterceptor(domainsToNotPropagateHeaderTo, bodyCaptureConfig);
1076
+ setupXMLHttpRequestInterceptor(domainsToNotPropagateHeaderTo, bodyCaptureConfig, domainsToPropagateHeaderTo);
1071
1077
  g.xhrPatched = true;
1072
1078
  }
1073
1079
  if (!g.fetchPatched) {
1074
- setupFetchInterceptor(domainsToNotPropagateHeaderTo, bodyCaptureConfig);
1080
+ setupFetchInterceptor(domainsToNotPropagateHeaderTo, bodyCaptureConfig, domainsToPropagateHeaderTo);
1075
1081
  g.fetchPatched = true;
1076
1082
  }
1077
1083
  await yieldToMain();
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-OzfaZiW-.js");
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.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.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.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;
3
+ const e = require("./chunks/index-DW416eVj.js");
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.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.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;
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 } from "./chunks/index-DNOCpBMH.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, z, A, B, C, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, T } from "./chunks/index-DvLh2k6O.js";
2
2
  export {
3
3
  D as DEFAULT_CAPTURE_SETTINGS,
4
4
  a as DEFAULT_CONSOLE_RECORDING_SETTINGS,
@@ -6,42 +6,43 @@ export {
6
6
  b as addOrUpdateMetadata,
7
7
  c as buildBatches,
8
8
  d as clearStaleFuncSpanState,
9
- e as createTriageAndIssueFromRecorder,
10
- f as createTriageFromRecorder,
11
- g as disableFunctionSpanTracking,
12
- h as enableFunctionSpanTracking,
13
- i as ensureHrefCache,
14
- j as eventSize,
15
- k as fetchAndSendIp,
16
- l as fetchCaptureSettings,
17
- m as fetchEngineeringTicketPlatformIntegrations,
18
- n as fetchFunctionSpanTrackingEnabled,
19
- o as flushBufferedEvents,
20
- p as getCachedHref,
21
- q as getCachedHrefNoQuery,
22
- r as getFuncSpanHeader,
23
- s as getOrSetSessionId,
24
- t as getUrlAndStoredUuids,
25
- u as identify,
26
- v as initRecorder,
27
- w as initializeConsolePlugin,
28
- x as initializeDomContentEvents,
29
- z as initializeFunctionSpanTrackingFromApi,
30
- A as initializeRecording,
31
- B as initializeWebSocket,
32
- C as invalidateUrlCache,
33
- E as isFunctionSpanTrackingEnabled,
34
- F as matchUrlWithWildcard,
35
- G as nowTimestamp,
36
- H as onNavigationChange,
37
- I as openReportIssueModal,
38
- J as restoreFuncSpanState,
39
- K as sendDomainsToNotPropagateHeaderTo,
40
- L as sendEvent,
41
- M as sendGraphQLRequest,
42
- N as sendMessage,
43
- O as startRecording,
44
- P as startRecordingSession,
45
- Q as trackingEvent,
46
- R as withAppUrlMetadata
9
+ e as createSkipHeadersPropagationChecker,
10
+ f as createTriageAndIssueFromRecorder,
11
+ g as createTriageFromRecorder,
12
+ h as disableFunctionSpanTracking,
13
+ i as enableFunctionSpanTracking,
14
+ j as ensureHrefCache,
15
+ k as eventSize,
16
+ l as fetchAndSendIp,
17
+ m as fetchCaptureSettings,
18
+ n as fetchEngineeringTicketPlatformIntegrations,
19
+ o as fetchFunctionSpanTrackingEnabled,
20
+ p as flushBufferedEvents,
21
+ q as getCachedHref,
22
+ r as getCachedHrefNoQuery,
23
+ s as getFuncSpanHeader,
24
+ t as getOrSetSessionId,
25
+ u as getUrlAndStoredUuids,
26
+ v as identify,
27
+ w as initRecorder,
28
+ x as initializeConsolePlugin,
29
+ z as initializeDomContentEvents,
30
+ A as initializeFunctionSpanTrackingFromApi,
31
+ B as initializeRecording,
32
+ C as initializeWebSocket,
33
+ E as invalidateUrlCache,
34
+ F as isFunctionSpanTrackingEnabled,
35
+ G as matchUrlWithWildcard,
36
+ H as nowTimestamp,
37
+ I as onNavigationChange,
38
+ J as openReportIssueModal,
39
+ K as restoreFuncSpanState,
40
+ L as sendDomainsToNotPropagateHeaderTo,
41
+ M as sendEvent,
42
+ N as sendGraphQLRequest,
43
+ O as sendMessage,
44
+ P as startRecording,
45
+ Q as startRecordingSession,
46
+ R as trackingEvent,
47
+ T as withAppUrlMetadata
47
48
  };
Binary file
Binary file
@@ -5,6 +5,7 @@ export declare const STORAGE_VERSION = 1;
5
5
  export declare const DEFAULT_CAPTURE_SETTINGS: CaptureSettings;
6
6
  export declare const DEFAULT_CONSOLE_RECORDING_SETTINGS: LogRecordOptions;
7
7
  export declare function matchUrlWithWildcard(input: unknown, patterns: string[]): boolean;
8
+ export declare function createSkipHeadersPropagationChecker(domainsToNotPropagateHeaderTo?: string[], domainsToPropagateHeaderTo?: string[]): (url: string) => boolean;
8
9
  export declare function startRecording({ apiKey, backendApi, domainsToPropagateHeaderTo, domainsToNotPropagateHeaderTo, serviceVersion, serviceIdentifier, gitSha, serviceAdditionalMetadata, enableIpTracking, captureStreamingResponseBody, captureResponseBodyMaxMb, captureStreamPrefixKb, captureStreamTimeoutMs, enableFiberTracking, deferRecording, deferRecordingStart, chunkSnapshot, useWsWorker, }: {
9
10
  apiKey: string;
10
11
  backendApi?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sailfish-ai/recorder",
3
- "version": "1.10.12",
3
+ "version": "1.10.13",
4
4
  "publishPublicly": true,
5
5
  "type": "module",
6
6
  "main": "dist/recorder.cjs",
Binary file
Binary file
Binary file
Binary file