@sailfish-ai/recorder 1.0.0-beta-12 → 1.0.0-beta-2
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/recording.js +3 -2
- package/dist/sailfish-recorder.es.js +554 -36
- package/dist/sailfish-recorder.umd.js +554 -36
- package/dist/types/recording.d.ts +1 -1
- package/dist/websocket.js +1 -1
- package/package.json +1 -1
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
var byteToHex = [];
|
|
2
|
-
for (var i = 0; i < 256; ++i) {
|
|
3
|
-
byteToHex.push((i + 256).toString(16).slice(1));
|
|
1
|
+
var byteToHex$1 = [];
|
|
2
|
+
for (var i$2 = 0; i$2 < 256; ++i$2) {
|
|
3
|
+
byteToHex$1.push((i$2 + 256).toString(16).slice(1));
|
|
4
4
|
}
|
|
5
5
|
function unsafeStringify(arr, offset = 0) {
|
|
6
|
-
return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
|
|
6
|
+
return (byteToHex$1[arr[offset + 0]] + byteToHex$1[arr[offset + 1]] + byteToHex$1[arr[offset + 2]] + byteToHex$1[arr[offset + 3]] + "-" + byteToHex$1[arr[offset + 4]] + byteToHex$1[arr[offset + 5]] + "-" + byteToHex$1[arr[offset + 6]] + byteToHex$1[arr[offset + 7]] + "-" + byteToHex$1[arr[offset + 8]] + byteToHex$1[arr[offset + 9]] + "-" + byteToHex$1[arr[offset + 10]] + byteToHex$1[arr[offset + 11]] + byteToHex$1[arr[offset + 12]] + byteToHex$1[arr[offset + 13]] + byteToHex$1[arr[offset + 14]] + byteToHex$1[arr[offset + 15]]).toLowerCase();
|
|
7
7
|
}
|
|
8
|
-
var getRandomValues;
|
|
9
|
-
var rnds8 = new Uint8Array(16);
|
|
10
|
-
function rng() {
|
|
11
|
-
if (!getRandomValues) {
|
|
12
|
-
getRandomValues = typeof crypto !== "undefined" && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
|
|
13
|
-
if (!getRandomValues) {
|
|
8
|
+
var getRandomValues$1;
|
|
9
|
+
var rnds8$1 = new Uint8Array(16);
|
|
10
|
+
function rng$1() {
|
|
11
|
+
if (!getRandomValues$1) {
|
|
12
|
+
getRandomValues$1 = typeof crypto !== "undefined" && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
|
|
13
|
+
if (!getRandomValues$1) {
|
|
14
14
|
throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
-
return getRandomValues(rnds8);
|
|
17
|
+
return getRandomValues$1(rnds8$1);
|
|
18
18
|
}
|
|
19
19
|
var randomUUID = typeof crypto !== "undefined" && crypto.randomUUID && crypto.randomUUID.bind(crypto);
|
|
20
20
|
const native = {
|
|
21
21
|
randomUUID
|
|
22
22
|
};
|
|
23
|
-
function v4(options, buf, offset) {
|
|
23
|
+
function v4$1(options, buf, offset) {
|
|
24
24
|
if (native.randomUUID && !buf && !options) {
|
|
25
25
|
return native.randomUUID();
|
|
26
26
|
}
|
|
27
27
|
options = options || {};
|
|
28
|
-
var rnds = options.random || (options.rng || rng)();
|
|
28
|
+
var rnds = options.random || (options.rng || rng$1)();
|
|
29
29
|
rnds[6] = rnds[6] & 15 | 64;
|
|
30
30
|
rnds[8] = rnds[8] & 63 | 128;
|
|
31
31
|
return unsafeStringify(rnds);
|
|
@@ -4940,7 +4940,7 @@ function hookSetter$1(target, key, d, isRevoked, win = window) {
|
|
|
4940
4940
|
);
|
|
4941
4941
|
return () => hookSetter$1(target, key, original || {}, true);
|
|
4942
4942
|
}
|
|
4943
|
-
function patch$
|
|
4943
|
+
function patch$2(source, name, replacement) {
|
|
4944
4944
|
try {
|
|
4945
4945
|
if (!(name in source)) {
|
|
4946
4946
|
return () => {
|
|
@@ -6782,7 +6782,7 @@ function initFontObserver({ fontCb, doc }) {
|
|
|
6782
6782
|
});
|
|
6783
6783
|
return fontFace;
|
|
6784
6784
|
};
|
|
6785
|
-
const restoreHandler = patch$
|
|
6785
|
+
const restoreHandler = patch$2(
|
|
6786
6786
|
doc.fonts,
|
|
6787
6787
|
"add",
|
|
6788
6788
|
function(original) {
|
|
@@ -6842,7 +6842,7 @@ function initCustomElementObserver({
|
|
|
6842
6842
|
const win = doc.defaultView;
|
|
6843
6843
|
if (!win || !win.customElements) return () => {
|
|
6844
6844
|
};
|
|
6845
|
-
const restoreHandler = patch$
|
|
6845
|
+
const restoreHandler = patch$2(
|
|
6846
6846
|
win.customElements,
|
|
6847
6847
|
"define",
|
|
6848
6848
|
function(original) {
|
|
@@ -7200,7 +7200,7 @@ function initCanvas2DMutationObserver(cb, win, blockClass, blockSelector) {
|
|
|
7200
7200
|
if (typeof win.CanvasRenderingContext2D.prototype[prop] !== "function") {
|
|
7201
7201
|
continue;
|
|
7202
7202
|
}
|
|
7203
|
-
const restoreHandler = patch$
|
|
7203
|
+
const restoreHandler = patch$2(
|
|
7204
7204
|
win.CanvasRenderingContext2D.prototype,
|
|
7205
7205
|
prop,
|
|
7206
7206
|
function(original) {
|
|
@@ -7248,7 +7248,7 @@ function getNormalizedContextName(contextType) {
|
|
|
7248
7248
|
function initCanvasContextObserver(win, blockClass, blockSelector, setPreserveDrawingBufferToTrue) {
|
|
7249
7249
|
const handlers = [];
|
|
7250
7250
|
try {
|
|
7251
|
-
const restoreHandler = patch$
|
|
7251
|
+
const restoreHandler = patch$2(
|
|
7252
7252
|
win.HTMLCanvasElement.prototype,
|
|
7253
7253
|
"getContext",
|
|
7254
7254
|
function(original) {
|
|
@@ -7300,7 +7300,7 @@ function patchGLPrototype(prototype, type, cb, blockClass, blockSelector, win) {
|
|
|
7300
7300
|
if (typeof prototype[prop] !== "function") {
|
|
7301
7301
|
continue;
|
|
7302
7302
|
}
|
|
7303
|
-
const restoreHandler = patch$
|
|
7303
|
+
const restoreHandler = patch$2(
|
|
7304
7304
|
prototype,
|
|
7305
7305
|
prop,
|
|
7306
7306
|
function(original) {
|
|
@@ -7669,7 +7669,7 @@ class ShadowDomManager {
|
|
|
7669
7669
|
patchAttachShadow(element, doc) {
|
|
7670
7670
|
const manager = this;
|
|
7671
7671
|
this.restoreHandlers.push(
|
|
7672
|
-
patch$
|
|
7672
|
+
patch$2(
|
|
7673
7673
|
element.prototype,
|
|
7674
7674
|
"attachShadow",
|
|
7675
7675
|
function(original) {
|
|
@@ -11708,7 +11708,7 @@ let Declaration22$1 = declaration$2;
|
|
|
11708
11708
|
let LazyResult22$1 = lazyResult$2;
|
|
11709
11709
|
let Container22$1 = container$2;
|
|
11710
11710
|
let Processor22$1 = processor$2;
|
|
11711
|
-
let stringify$
|
|
11711
|
+
let stringify$8 = stringify_1$2;
|
|
11712
11712
|
let fromJSON$3 = fromJSON_1$2;
|
|
11713
11713
|
let Document222$1 = document$1$1;
|
|
11714
11714
|
let Warning22$1 = warning$2;
|
|
@@ -11758,7 +11758,7 @@ postcss$4.plugin = function plugin2(name, initializer) {
|
|
|
11758
11758
|
};
|
|
11759
11759
|
return creator;
|
|
11760
11760
|
};
|
|
11761
|
-
postcss$4.stringify = stringify$
|
|
11761
|
+
postcss$4.stringify = stringify$8;
|
|
11762
11762
|
postcss$4.parse = parse$6;
|
|
11763
11763
|
postcss$4.fromJSON = fromJSON$3;
|
|
11764
11764
|
postcss$4.list = list$4;
|
|
@@ -15531,7 +15531,7 @@ function hookSetter(target, key, d, isRevoked, win = window) {
|
|
|
15531
15531
|
);
|
|
15532
15532
|
return () => hookSetter(target, key, original || {}, true);
|
|
15533
15533
|
}
|
|
15534
|
-
function patch(source, name, replacement) {
|
|
15534
|
+
function patch$1(source, name, replacement) {
|
|
15535
15535
|
try {
|
|
15536
15536
|
if (!(name in source)) {
|
|
15537
15537
|
return () => {
|
|
@@ -15851,7 +15851,7 @@ const utils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
|
|
|
15851
15851
|
return nowTimestamp;
|
|
15852
15852
|
},
|
|
15853
15853
|
on,
|
|
15854
|
-
patch,
|
|
15854
|
+
patch: patch$1,
|
|
15855
15855
|
polyfill: polyfill$1,
|
|
15856
15856
|
queueToResolveTrees,
|
|
15857
15857
|
shadowHostInDom,
|
|
@@ -19657,7 +19657,7 @@ function isObjTooDeep(obj, limit) {
|
|
|
19657
19657
|
}
|
|
19658
19658
|
return false;
|
|
19659
19659
|
}
|
|
19660
|
-
function stringify(obj, stringifyOptions) {
|
|
19660
|
+
function stringify$7(obj, stringifyOptions) {
|
|
19661
19661
|
const options = {
|
|
19662
19662
|
numOfKeysLimit: 50,
|
|
19663
19663
|
depthOfLimit: 4
|
|
@@ -19781,7 +19781,7 @@ function initLogObserver(cb, win, options) {
|
|
|
19781
19781
|
const trace = ErrorStackParser.parse(error).map(
|
|
19782
19782
|
(stackFrame) => stackFrame.toString()
|
|
19783
19783
|
);
|
|
19784
|
-
const payload = [stringify(message, logOptions.stringifyOptions)];
|
|
19784
|
+
const payload = [stringify$7(message, logOptions.stringifyOptions)];
|
|
19785
19785
|
cb({
|
|
19786
19786
|
level: "error",
|
|
19787
19787
|
trace,
|
|
@@ -19798,7 +19798,7 @@ function initLogObserver(cb, win, options) {
|
|
|
19798
19798
|
if (event.reason instanceof Error) {
|
|
19799
19799
|
error = event.reason;
|
|
19800
19800
|
payload = [
|
|
19801
|
-
stringify(
|
|
19801
|
+
stringify$7(
|
|
19802
19802
|
`Uncaught (in promise) ${error.name}: ${error.message}`,
|
|
19803
19803
|
logOptions.stringifyOptions
|
|
19804
19804
|
)
|
|
@@ -19806,8 +19806,8 @@ function initLogObserver(cb, win, options) {
|
|
|
19806
19806
|
} else {
|
|
19807
19807
|
error = new Error();
|
|
19808
19808
|
payload = [
|
|
19809
|
-
stringify("Uncaught (in promise)", logOptions.stringifyOptions),
|
|
19810
|
-
stringify(event.reason, logOptions.stringifyOptions)
|
|
19809
|
+
stringify$7("Uncaught (in promise)", logOptions.stringifyOptions),
|
|
19810
|
+
stringify$7(event.reason, logOptions.stringifyOptions)
|
|
19811
19811
|
];
|
|
19812
19812
|
}
|
|
19813
19813
|
const trace = ErrorStackParser.parse(error).map(
|
|
@@ -19852,7 +19852,7 @@ function initLogObserver(cb, win, options) {
|
|
|
19852
19852
|
const trace = ErrorStackParser.parse(new Error()).map((stackFrame) => stackFrame.toString()).splice(1);
|
|
19853
19853
|
const argsForPayload = level === "assert" ? args.slice(1) : args;
|
|
19854
19854
|
const payload = argsForPayload.map(
|
|
19855
|
-
(s) => stringify(s, logOptions.stringifyOptions)
|
|
19855
|
+
(s) => stringify$7(s, logOptions.stringifyOptions)
|
|
19856
19856
|
);
|
|
19857
19857
|
logCount++;
|
|
19858
19858
|
if (logCount < logOptions.lengthThreshold) {
|
|
@@ -19866,7 +19866,7 @@ function initLogObserver(cb, win, options) {
|
|
|
19866
19866
|
level: "warn",
|
|
19867
19867
|
trace: [],
|
|
19868
19868
|
payload: [
|
|
19869
|
-
stringify("The number of log records reached the threshold.")
|
|
19869
|
+
stringify$7("The number of log records reached the threshold.")
|
|
19870
19870
|
]
|
|
19871
19871
|
});
|
|
19872
19872
|
}
|
|
@@ -19886,6 +19886,524 @@ const getRecordConsolePlugin = (options) => ({
|
|
|
19886
19886
|
observer: initLogObserver,
|
|
19887
19887
|
options
|
|
19888
19888
|
});
|
|
19889
|
+
var getRandomValues;
|
|
19890
|
+
var rnds8 = new Uint8Array(16);
|
|
19891
|
+
function rng() {
|
|
19892
|
+
if (!getRandomValues) {
|
|
19893
|
+
getRandomValues = typeof crypto !== "undefined" && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== "undefined" && typeof msCrypto.getRandomValues === "function" && msCrypto.getRandomValues.bind(msCrypto);
|
|
19894
|
+
if (!getRandomValues) {
|
|
19895
|
+
throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
|
|
19896
|
+
}
|
|
19897
|
+
}
|
|
19898
|
+
return getRandomValues(rnds8);
|
|
19899
|
+
}
|
|
19900
|
+
const REGEX = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
|
|
19901
|
+
function validate(uuid) {
|
|
19902
|
+
return typeof uuid === "string" && REGEX.test(uuid);
|
|
19903
|
+
}
|
|
19904
|
+
var byteToHex = [];
|
|
19905
|
+
for (var i = 0; i < 256; ++i) {
|
|
19906
|
+
byteToHex.push((i + 256).toString(16).substr(1));
|
|
19907
|
+
}
|
|
19908
|
+
function stringify(arr) {
|
|
19909
|
+
var offset = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 0;
|
|
19910
|
+
var uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
|
|
19911
|
+
if (!validate(uuid)) {
|
|
19912
|
+
throw TypeError("Stringified UUID is invalid");
|
|
19913
|
+
}
|
|
19914
|
+
return uuid;
|
|
19915
|
+
}
|
|
19916
|
+
function v4(options, buf, offset) {
|
|
19917
|
+
options = options || {};
|
|
19918
|
+
var rnds = options.random || (options.rng || rng)();
|
|
19919
|
+
rnds[6] = rnds[6] & 15 | 64;
|
|
19920
|
+
rnds[8] = rnds[8] & 63 | 128;
|
|
19921
|
+
return stringify(rnds);
|
|
19922
|
+
}
|
|
19923
|
+
function findLast(array, predicate) {
|
|
19924
|
+
const length = array.length;
|
|
19925
|
+
for (let i = length - 1; i >= 0; i -= 1) {
|
|
19926
|
+
if (predicate(array[i])) {
|
|
19927
|
+
return array[i];
|
|
19928
|
+
}
|
|
19929
|
+
}
|
|
19930
|
+
}
|
|
19931
|
+
function patch(source, name, replacement) {
|
|
19932
|
+
try {
|
|
19933
|
+
if (!(name in source)) {
|
|
19934
|
+
return () => {
|
|
19935
|
+
};
|
|
19936
|
+
}
|
|
19937
|
+
const original = source[name];
|
|
19938
|
+
const wrapped = replacement(original);
|
|
19939
|
+
if (typeof wrapped === "function") {
|
|
19940
|
+
wrapped.prototype = wrapped.prototype || {};
|
|
19941
|
+
Object.defineProperties(wrapped, {
|
|
19942
|
+
__rrweb_original__: {
|
|
19943
|
+
enumerable: false,
|
|
19944
|
+
value: original
|
|
19945
|
+
}
|
|
19946
|
+
});
|
|
19947
|
+
}
|
|
19948
|
+
source[name] = wrapped;
|
|
19949
|
+
return () => {
|
|
19950
|
+
source[name] = original;
|
|
19951
|
+
};
|
|
19952
|
+
} catch {
|
|
19953
|
+
return () => {
|
|
19954
|
+
};
|
|
19955
|
+
}
|
|
19956
|
+
}
|
|
19957
|
+
const defaultNetworkOptions = {
|
|
19958
|
+
initiatorTypes: [
|
|
19959
|
+
"audio",
|
|
19960
|
+
"beacon",
|
|
19961
|
+
"body",
|
|
19962
|
+
"css",
|
|
19963
|
+
"early-hint",
|
|
19964
|
+
"embed",
|
|
19965
|
+
"fetch",
|
|
19966
|
+
"frame",
|
|
19967
|
+
"iframe",
|
|
19968
|
+
"icon",
|
|
19969
|
+
"image",
|
|
19970
|
+
"img",
|
|
19971
|
+
"input",
|
|
19972
|
+
"link",
|
|
19973
|
+
"navigation",
|
|
19974
|
+
"object",
|
|
19975
|
+
"ping",
|
|
19976
|
+
"script",
|
|
19977
|
+
"track",
|
|
19978
|
+
"video",
|
|
19979
|
+
"xmlhttprequest"
|
|
19980
|
+
],
|
|
19981
|
+
ignoreRequestFn: () => false,
|
|
19982
|
+
recordHeaders: false,
|
|
19983
|
+
recordBody: false,
|
|
19984
|
+
recordInitialRequests: false
|
|
19985
|
+
};
|
|
19986
|
+
const isNavigationTiming = (entry) => entry.entryType === "navigation";
|
|
19987
|
+
const isResourceTiming = (entry) => entry.entryType === "resource";
|
|
19988
|
+
let requestId = `sfui-${v4()}`;
|
|
19989
|
+
function updateRequestId(newId) {
|
|
19990
|
+
requestId = newId;
|
|
19991
|
+
console.error(`X-SF3-RID updated to ${newId}`);
|
|
19992
|
+
}
|
|
19993
|
+
function initPerformanceObserver(cb, win, options) {
|
|
19994
|
+
if (options.recordInitialRequests) {
|
|
19995
|
+
const initialPerformanceEntries = win.performance.getEntries().filter(
|
|
19996
|
+
(entry) => isNavigationTiming(entry) || isResourceTiming(entry) && options.initiatorTypes.includes(
|
|
19997
|
+
entry.initiatorType
|
|
19998
|
+
)
|
|
19999
|
+
);
|
|
20000
|
+
cb({
|
|
20001
|
+
requests: initialPerformanceEntries.map((entry) => ({
|
|
20002
|
+
url: entry.name,
|
|
20003
|
+
initiatorType: entry.initiatorType,
|
|
20004
|
+
status: "responseStatus" in entry ? entry.responseStatus : void 0,
|
|
20005
|
+
startTime: Math.round(entry.startTime),
|
|
20006
|
+
endTime: Math.round(entry.responseEnd)
|
|
20007
|
+
})),
|
|
20008
|
+
isInitial: true
|
|
20009
|
+
});
|
|
20010
|
+
}
|
|
20011
|
+
const observer = new win.PerformanceObserver((entries) => {
|
|
20012
|
+
const performanceEntries = entries.getEntries().filter(
|
|
20013
|
+
(entry) => isNavigationTiming(entry) || isResourceTiming(entry) && options.initiatorTypes.includes(
|
|
20014
|
+
entry.initiatorType
|
|
20015
|
+
) && entry.initiatorType !== "xmlhttprequest" && entry.initiatorType !== "fetch"
|
|
20016
|
+
);
|
|
20017
|
+
cb({
|
|
20018
|
+
requests: performanceEntries.map((entry) => ({
|
|
20019
|
+
url: entry.name,
|
|
20020
|
+
initiatorType: entry.initiatorType,
|
|
20021
|
+
status: "responseStatus" in entry ? entry.responseStatus : void 0,
|
|
20022
|
+
startTime: Math.round(entry.startTime),
|
|
20023
|
+
endTime: Math.round(entry.responseEnd)
|
|
20024
|
+
}))
|
|
20025
|
+
});
|
|
20026
|
+
});
|
|
20027
|
+
observer.observe({ entryTypes: ["navigation", "resource"] });
|
|
20028
|
+
return () => {
|
|
20029
|
+
observer.disconnect();
|
|
20030
|
+
};
|
|
20031
|
+
}
|
|
20032
|
+
function shouldRecordHeaders(type, recordHeaders, headers, ignoredHeaders) {
|
|
20033
|
+
if (!recordHeaders) {
|
|
20034
|
+
return false;
|
|
20035
|
+
}
|
|
20036
|
+
if (typeof recordHeaders === "boolean") {
|
|
20037
|
+
if (!recordHeaders) return false;
|
|
20038
|
+
} else if (!recordHeaders[type]) {
|
|
20039
|
+
return false;
|
|
20040
|
+
}
|
|
20041
|
+
const typeSpecificIgnoredHeaders = ignoredHeaders ? ignoredHeaders[type] : [];
|
|
20042
|
+
const effectiveHeaders = {};
|
|
20043
|
+
Object.keys(headers).forEach((header) => {
|
|
20044
|
+
if (typeSpecificIgnoredHeaders && typeSpecificIgnoredHeaders.includes(header.toLowerCase())) {
|
|
20045
|
+
effectiveHeaders[header] = headers[header];
|
|
20046
|
+
}
|
|
20047
|
+
});
|
|
20048
|
+
return Object.keys(effectiveHeaders).length > 0;
|
|
20049
|
+
}
|
|
20050
|
+
function filterHeaders(type, headers, ignoredHeaders) {
|
|
20051
|
+
const filteredHeaders = {};
|
|
20052
|
+
const toIgnore = ignoredHeaders ? ignoredHeaders[type] : [];
|
|
20053
|
+
Object.keys(headers).forEach((header) => {
|
|
20054
|
+
if (!toIgnore.includes(header.toLowerCase())) {
|
|
20055
|
+
filteredHeaders[header] = headers[header];
|
|
20056
|
+
}
|
|
20057
|
+
});
|
|
20058
|
+
return filteredHeaders;
|
|
20059
|
+
}
|
|
20060
|
+
function shouldRecordBody(type, recordBody, headers, ignoreBodyParts) {
|
|
20061
|
+
function matchesContentType(contentTypes) {
|
|
20062
|
+
const contentTypeHeader = Object.keys(headers).find(
|
|
20063
|
+
(key) => key.toLowerCase() === "content-type"
|
|
20064
|
+
);
|
|
20065
|
+
const contentType = contentTypeHeader && headers[contentTypeHeader];
|
|
20066
|
+
return contentTypes.some((ct) => contentType == null ? void 0 : contentType.includes(ct));
|
|
20067
|
+
}
|
|
20068
|
+
if (!recordBody) return false;
|
|
20069
|
+
if (typeof recordBody === "boolean") return true;
|
|
20070
|
+
if (Array.isArray(recordBody)) return matchesContentType(recordBody);
|
|
20071
|
+
const recordBodyType = recordBody[type];
|
|
20072
|
+
if (typeof recordBodyType === "boolean") return recordBodyType;
|
|
20073
|
+
return matchesContentType(recordBodyType);
|
|
20074
|
+
}
|
|
20075
|
+
function getRecordedBody(body, type, ignoreBodyParts) {
|
|
20076
|
+
if (!body || typeof body !== "string") {
|
|
20077
|
+
return body;
|
|
20078
|
+
}
|
|
20079
|
+
try {
|
|
20080
|
+
const data = JSON.parse(body);
|
|
20081
|
+
const ignoredParts = ignoreBodyParts ? ignoreBodyParts[type] : [];
|
|
20082
|
+
const removeNestedProperty = (obj, path) => {
|
|
20083
|
+
const parts = path.split(".");
|
|
20084
|
+
const last = parts.pop();
|
|
20085
|
+
const lastObj = parts.reduce((o, key) => o[key] = o[key] || {}, obj);
|
|
20086
|
+
if (last !== void 0) {
|
|
20087
|
+
delete lastObj[last];
|
|
20088
|
+
}
|
|
20089
|
+
};
|
|
20090
|
+
ignoredParts.forEach((path) => {
|
|
20091
|
+
removeNestedProperty(data, path);
|
|
20092
|
+
});
|
|
20093
|
+
return JSON.stringify(data);
|
|
20094
|
+
} catch (error) {
|
|
20095
|
+
return body;
|
|
20096
|
+
}
|
|
20097
|
+
}
|
|
20098
|
+
async function getRequestPerformanceEntry(win, initiatorType, url, after, before, attempt = 0) {
|
|
20099
|
+
if (attempt > 10) {
|
|
20100
|
+
throw new Error("Cannot find performance entry");
|
|
20101
|
+
}
|
|
20102
|
+
const urlPerformanceEntries = win.performance.getEntriesByName(
|
|
20103
|
+
url
|
|
20104
|
+
);
|
|
20105
|
+
const performanceEntry = findLast(
|
|
20106
|
+
urlPerformanceEntries,
|
|
20107
|
+
(entry) => isResourceTiming(entry) && entry.initiatorType === initiatorType && (!after || entry.startTime >= after) && (!before || entry.startTime <= before)
|
|
20108
|
+
);
|
|
20109
|
+
if (!performanceEntry) {
|
|
20110
|
+
await new Promise((resolve2) => setTimeout(resolve2, 50 * attempt));
|
|
20111
|
+
return getRequestPerformanceEntry(
|
|
20112
|
+
win,
|
|
20113
|
+
initiatorType,
|
|
20114
|
+
url,
|
|
20115
|
+
after,
|
|
20116
|
+
before,
|
|
20117
|
+
attempt + 1
|
|
20118
|
+
);
|
|
20119
|
+
}
|
|
20120
|
+
return performanceEntry;
|
|
20121
|
+
}
|
|
20122
|
+
function initXhrObserver(cb, win, options) {
|
|
20123
|
+
if (!options.initiatorTypes.includes("xmlhttprequest")) {
|
|
20124
|
+
return () => {
|
|
20125
|
+
};
|
|
20126
|
+
}
|
|
20127
|
+
const restorePatch = patch(
|
|
20128
|
+
win.XMLHttpRequest.prototype,
|
|
20129
|
+
"open",
|
|
20130
|
+
(originalOpen) => {
|
|
20131
|
+
return function(method, url, async = true, username, password) {
|
|
20132
|
+
const xhr = this;
|
|
20133
|
+
const req = new Request(url);
|
|
20134
|
+
const networkRequest = {};
|
|
20135
|
+
let after;
|
|
20136
|
+
let before;
|
|
20137
|
+
const requestHeaders = {};
|
|
20138
|
+
const originalSetRequestHeader = xhr.setRequestHeader.bind(xhr);
|
|
20139
|
+
xhr.setRequestHeader = (header, value) => {
|
|
20140
|
+
requestHeaders[header] = value;
|
|
20141
|
+
return originalSetRequestHeader(header, value);
|
|
20142
|
+
};
|
|
20143
|
+
xhr.setRequestHeader("X-SF3-RID", requestId);
|
|
20144
|
+
const recordRequestHeaders = shouldRecordHeaders(
|
|
20145
|
+
"request",
|
|
20146
|
+
options.recordHeaders,
|
|
20147
|
+
requestHeaders,
|
|
20148
|
+
options.ignoreHeaders
|
|
20149
|
+
);
|
|
20150
|
+
if (recordRequestHeaders) {
|
|
20151
|
+
networkRequest.requestHeaders = filterHeaders(
|
|
20152
|
+
"request",
|
|
20153
|
+
requestHeaders,
|
|
20154
|
+
options.ignoreHeaders
|
|
20155
|
+
);
|
|
20156
|
+
}
|
|
20157
|
+
const originalSend = xhr.send.bind(xhr);
|
|
20158
|
+
xhr.send = (body) => {
|
|
20159
|
+
if (shouldRecordBody(
|
|
20160
|
+
"request",
|
|
20161
|
+
options.recordBody,
|
|
20162
|
+
requestHeaders,
|
|
20163
|
+
options.ignoreBodyParts
|
|
20164
|
+
)) {
|
|
20165
|
+
if (body === void 0 || body === null) {
|
|
20166
|
+
networkRequest.requestBody = null;
|
|
20167
|
+
} else {
|
|
20168
|
+
networkRequest.requestBody = getRecordedBody(
|
|
20169
|
+
body,
|
|
20170
|
+
"request",
|
|
20171
|
+
options.ignoreBodyParts
|
|
20172
|
+
);
|
|
20173
|
+
}
|
|
20174
|
+
}
|
|
20175
|
+
after = win.performance.now();
|
|
20176
|
+
return originalSend(body);
|
|
20177
|
+
};
|
|
20178
|
+
xhr.addEventListener("readystatechange", () => {
|
|
20179
|
+
if (xhr.readyState !== xhr.DONE) {
|
|
20180
|
+
return;
|
|
20181
|
+
}
|
|
20182
|
+
before = win.performance.now();
|
|
20183
|
+
const responseHeaders = {};
|
|
20184
|
+
const rawHeaders = xhr.getAllResponseHeaders();
|
|
20185
|
+
const headers = rawHeaders.trim().split(/[\r\n]+/);
|
|
20186
|
+
headers.forEach((line) => {
|
|
20187
|
+
const parts = line.split(": ");
|
|
20188
|
+
const header = parts.shift();
|
|
20189
|
+
const value = parts.join(": ");
|
|
20190
|
+
if (header) {
|
|
20191
|
+
responseHeaders[header] = value;
|
|
20192
|
+
}
|
|
20193
|
+
if (header === "X-SF3-RID" && value !== requestId) {
|
|
20194
|
+
updateRequestId(value);
|
|
20195
|
+
}
|
|
20196
|
+
});
|
|
20197
|
+
const recordResponseHeaders = shouldRecordHeaders(
|
|
20198
|
+
"response",
|
|
20199
|
+
options.recordHeaders,
|
|
20200
|
+
responseHeaders,
|
|
20201
|
+
options.ignoreHeaders
|
|
20202
|
+
);
|
|
20203
|
+
if (recordResponseHeaders) {
|
|
20204
|
+
networkRequest.responseHeaders = filterHeaders(
|
|
20205
|
+
"response",
|
|
20206
|
+
responseHeaders,
|
|
20207
|
+
options.ignoreHeaders
|
|
20208
|
+
);
|
|
20209
|
+
}
|
|
20210
|
+
if (shouldRecordBody(
|
|
20211
|
+
"response",
|
|
20212
|
+
options.recordBody,
|
|
20213
|
+
responseHeaders,
|
|
20214
|
+
options.ignoreBodyParts
|
|
20215
|
+
)) {
|
|
20216
|
+
if (xhr.response === void 0 || xhr.response === null) {
|
|
20217
|
+
networkRequest.responseBody = null;
|
|
20218
|
+
} else {
|
|
20219
|
+
networkRequest.responseBody = getRecordedBody(
|
|
20220
|
+
xhr.response,
|
|
20221
|
+
"response",
|
|
20222
|
+
options.ignoreBodyParts
|
|
20223
|
+
);
|
|
20224
|
+
}
|
|
20225
|
+
}
|
|
20226
|
+
getRequestPerformanceEntry(
|
|
20227
|
+
win,
|
|
20228
|
+
"xmlhttprequest",
|
|
20229
|
+
req.url,
|
|
20230
|
+
after,
|
|
20231
|
+
before
|
|
20232
|
+
).then((entry) => {
|
|
20233
|
+
const request = {
|
|
20234
|
+
url: entry.name,
|
|
20235
|
+
method: req.method,
|
|
20236
|
+
initiatorType: entry.initiatorType,
|
|
20237
|
+
status: xhr.status,
|
|
20238
|
+
startTime: Math.round(entry.startTime),
|
|
20239
|
+
endTime: Math.round(entry.responseEnd),
|
|
20240
|
+
requestHeaders: networkRequest.requestHeaders,
|
|
20241
|
+
requestBody: networkRequest.requestBody,
|
|
20242
|
+
responseHeaders: networkRequest.responseHeaders,
|
|
20243
|
+
responseBody: networkRequest.responseBody
|
|
20244
|
+
};
|
|
20245
|
+
cb({ requests: [request] });
|
|
20246
|
+
}).catch(() => {
|
|
20247
|
+
});
|
|
20248
|
+
});
|
|
20249
|
+
originalOpen.call(xhr, method, url, async, username, password);
|
|
20250
|
+
};
|
|
20251
|
+
}
|
|
20252
|
+
);
|
|
20253
|
+
return () => {
|
|
20254
|
+
restorePatch();
|
|
20255
|
+
};
|
|
20256
|
+
}
|
|
20257
|
+
function initFetchObserver(cb, win, options) {
|
|
20258
|
+
if (!options.initiatorTypes.includes("fetch")) {
|
|
20259
|
+
return () => {
|
|
20260
|
+
};
|
|
20261
|
+
}
|
|
20262
|
+
const restorePatch = patch(win, "fetch", (originalFetch) => {
|
|
20263
|
+
return async function(url, init) {
|
|
20264
|
+
const req = new Request(url, {
|
|
20265
|
+
...init,
|
|
20266
|
+
headers: {
|
|
20267
|
+
...init == null ? void 0 : init.headers,
|
|
20268
|
+
"X-SF3-RID": requestId
|
|
20269
|
+
}
|
|
20270
|
+
});
|
|
20271
|
+
let res;
|
|
20272
|
+
const networkRequest = {};
|
|
20273
|
+
let after;
|
|
20274
|
+
let before;
|
|
20275
|
+
try {
|
|
20276
|
+
const requestHeaders = {};
|
|
20277
|
+
req.headers.forEach((value, header) => {
|
|
20278
|
+
requestHeaders[header] = value;
|
|
20279
|
+
});
|
|
20280
|
+
const recordRequestHeaders = shouldRecordHeaders(
|
|
20281
|
+
"request",
|
|
20282
|
+
options.recordHeaders,
|
|
20283
|
+
requestHeaders,
|
|
20284
|
+
options.ignoreHeaders
|
|
20285
|
+
);
|
|
20286
|
+
if (recordRequestHeaders) {
|
|
20287
|
+
networkRequest.requestHeaders = filterHeaders(
|
|
20288
|
+
"request",
|
|
20289
|
+
requestHeaders,
|
|
20290
|
+
options.ignoreHeaders
|
|
20291
|
+
);
|
|
20292
|
+
}
|
|
20293
|
+
if (shouldRecordBody(
|
|
20294
|
+
"request",
|
|
20295
|
+
options.recordBody,
|
|
20296
|
+
requestHeaders,
|
|
20297
|
+
options.ignoreBodyParts
|
|
20298
|
+
)) {
|
|
20299
|
+
if (req.body === void 0 || req.body === null) {
|
|
20300
|
+
networkRequest.requestBody = null;
|
|
20301
|
+
} else {
|
|
20302
|
+
networkRequest.requestBody = getRecordedBody(
|
|
20303
|
+
await req.clone().text(),
|
|
20304
|
+
"request",
|
|
20305
|
+
options.ignoreBodyParts
|
|
20306
|
+
);
|
|
20307
|
+
}
|
|
20308
|
+
}
|
|
20309
|
+
after = win.performance.now();
|
|
20310
|
+
res = await originalFetch(req);
|
|
20311
|
+
before = win.performance.now();
|
|
20312
|
+
const responseHeaders = {};
|
|
20313
|
+
res.headers.forEach((value, header) => {
|
|
20314
|
+
responseHeaders[header] = value;
|
|
20315
|
+
if (header === "X-SF3-RID" && value !== requestId) {
|
|
20316
|
+
updateRequestId(value);
|
|
20317
|
+
}
|
|
20318
|
+
});
|
|
20319
|
+
const recordResponseHeaders = shouldRecordHeaders(
|
|
20320
|
+
"response",
|
|
20321
|
+
options.recordHeaders,
|
|
20322
|
+
responseHeaders,
|
|
20323
|
+
options.ignoreHeaders
|
|
20324
|
+
);
|
|
20325
|
+
if (recordResponseHeaders) {
|
|
20326
|
+
networkRequest.responseHeaders = filterHeaders(
|
|
20327
|
+
"response",
|
|
20328
|
+
responseHeaders,
|
|
20329
|
+
options.ignoreHeaders
|
|
20330
|
+
);
|
|
20331
|
+
}
|
|
20332
|
+
if (shouldRecordBody(
|
|
20333
|
+
"response",
|
|
20334
|
+
options.recordBody,
|
|
20335
|
+
responseHeaders,
|
|
20336
|
+
options.ignoreBodyParts
|
|
20337
|
+
)) {
|
|
20338
|
+
let body;
|
|
20339
|
+
try {
|
|
20340
|
+
body = await res.clone().text();
|
|
20341
|
+
} catch {
|
|
20342
|
+
}
|
|
20343
|
+
if (res.body === void 0 || res.body === null) {
|
|
20344
|
+
networkRequest.responseBody = null;
|
|
20345
|
+
} else {
|
|
20346
|
+
networkRequest.responseBody = getRecordedBody(
|
|
20347
|
+
await res.clone().text(),
|
|
20348
|
+
"response",
|
|
20349
|
+
options.ignoreBodyParts
|
|
20350
|
+
);
|
|
20351
|
+
}
|
|
20352
|
+
}
|
|
20353
|
+
return res;
|
|
20354
|
+
} finally {
|
|
20355
|
+
getRequestPerformanceEntry(win, "fetch", req.url, after, before).then((entry) => {
|
|
20356
|
+
const request = {
|
|
20357
|
+
url: entry.name,
|
|
20358
|
+
method: req.method,
|
|
20359
|
+
initiatorType: entry.initiatorType,
|
|
20360
|
+
status: res == null ? void 0 : res.status,
|
|
20361
|
+
startTime: Math.round(entry.startTime),
|
|
20362
|
+
endTime: Math.round(entry.responseEnd),
|
|
20363
|
+
requestHeaders: networkRequest.requestHeaders,
|
|
20364
|
+
requestBody: networkRequest.requestBody,
|
|
20365
|
+
responseHeaders: networkRequest.responseHeaders,
|
|
20366
|
+
responseBody: networkRequest.responseBody
|
|
20367
|
+
};
|
|
20368
|
+
cb({ requests: [request] });
|
|
20369
|
+
}).catch(() => {
|
|
20370
|
+
});
|
|
20371
|
+
}
|
|
20372
|
+
};
|
|
20373
|
+
});
|
|
20374
|
+
return () => {
|
|
20375
|
+
restorePatch();
|
|
20376
|
+
};
|
|
20377
|
+
}
|
|
20378
|
+
function initNetworkObserver(callback, win, options) {
|
|
20379
|
+
if (!("performance" in win)) {
|
|
20380
|
+
return () => {
|
|
20381
|
+
};
|
|
20382
|
+
}
|
|
20383
|
+
const networkOptions = options ? Object.assign({}, defaultNetworkOptions, options) : defaultNetworkOptions;
|
|
20384
|
+
const cb = (data) => {
|
|
20385
|
+
const requests = data.requests.filter(
|
|
20386
|
+
(request) => !networkOptions.ignoreRequestFn(request)
|
|
20387
|
+
);
|
|
20388
|
+
if (requests.length > 0 || data.isInitial) {
|
|
20389
|
+
callback({ ...data, requests });
|
|
20390
|
+
}
|
|
20391
|
+
};
|
|
20392
|
+
const performanceObserver = initPerformanceObserver(cb, win, networkOptions);
|
|
20393
|
+
const xhrObserver = initXhrObserver(cb, win, networkOptions);
|
|
20394
|
+
const fetchObserver = initFetchObserver(cb, win, networkOptions);
|
|
20395
|
+
return () => {
|
|
20396
|
+
performanceObserver();
|
|
20397
|
+
xhrObserver();
|
|
20398
|
+
fetchObserver();
|
|
20399
|
+
};
|
|
20400
|
+
}
|
|
20401
|
+
const NETWORK_PLUGIN_NAME = "@sailfish-rrweb/rrweb/network@1";
|
|
20402
|
+
const getRecordNetworkPlugin = (options) => ({
|
|
20403
|
+
name: NETWORK_PLUGIN_NAME,
|
|
20404
|
+
observer: initNetworkObserver,
|
|
20405
|
+
options
|
|
20406
|
+
});
|
|
19889
20407
|
/*! *****************************************************************************
|
|
19890
20408
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
19891
20409
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
@@ -20453,13 +20971,13 @@ var ReconnectingWebSocket = (
|
|
|
20453
20971
|
return ReconnectingWebSocket2;
|
|
20454
20972
|
}()
|
|
20455
20973
|
);
|
|
20456
|
-
const version = "1.0.0-beta-
|
|
20974
|
+
const version = "1.0.0-beta-2";
|
|
20457
20975
|
function initializeWebSocket(backendApi, apiKey, sessionId) {
|
|
20458
20976
|
const wsHost = getWebSocketHost(backendApi);
|
|
20459
20977
|
const wsScheme = window.location.protocol === "https:" ? "wss" : "ws";
|
|
20460
20978
|
const wsUrl = `${wsScheme}://${wsHost}/ws/notify/?apiKey=${apiKey}&sessionId=${sessionId}&sender=JS%2FTS&version=${version}`;
|
|
20461
20979
|
const options = {
|
|
20462
|
-
connectionTimeout:
|
|
20980
|
+
connectionTimeout: 5e3
|
|
20463
20981
|
};
|
|
20464
20982
|
const webSocket = new ReconnectingWebSocket(wsUrl, [], options);
|
|
20465
20983
|
return webSocket;
|
|
@@ -20480,8 +20998,8 @@ async function initializeRecording(captureSettings, consoleRecordSettings, netwo
|
|
|
20480
20998
|
cacheEvents(event);
|
|
20481
20999
|
},
|
|
20482
21000
|
plugins: [
|
|
20483
|
-
getRecordConsolePlugin(consoleRecordSettings)
|
|
20484
|
-
|
|
21001
|
+
getRecordConsolePlugin(consoleRecordSettings),
|
|
21002
|
+
getRecordNetworkPlugin(networkRecordSettings)
|
|
20485
21003
|
],
|
|
20486
21004
|
maskInputOptions: { text: true },
|
|
20487
21005
|
// Fix the incorrect property name
|
|
@@ -20547,7 +21065,7 @@ async function startRecording({
|
|
|
20547
21065
|
backendApi
|
|
20548
21066
|
}) {
|
|
20549
21067
|
var _a2, _b;
|
|
20550
|
-
const sessionId = v4();
|
|
21068
|
+
const sessionId = v4$1();
|
|
20551
21069
|
try {
|
|
20552
21070
|
const captureSettingsResponse = await fetchCaptureSettings(
|
|
20553
21071
|
apiKey,
|