@newtalaria/browser 0.1.10 → 0.1.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.
- package/README.md +5 -2
- package/dist/client.d.ts +8 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/index.js +229 -2
- package/dist/index.js.map +4 -4
- package/dist/replay/hooks.d.ts +6 -0
- package/dist/replay/hooks.d.ts.map +1 -1
- package/dist/replay/recorder.d.ts +5 -0
- package/dist/replay/recorder.d.ts.map +1 -1
- package/dist/replay/segment_buffer.d.ts +5 -0
- package/dist/replay/segment_buffer.d.ts.map +1 -1
- package/dist/sdk_meta.d.ts +4 -0
- package/dist/sdk_meta.d.ts.map +1 -0
- package/dist/talaria.browser.iife.js +229 -2
- package/dist/talaria.browser.iife.js.map +4 -4
- package/dist/utils/browser_context.d.ts +28 -0
- package/dist/utils/browser_context.d.ts.map +1 -0
- package/dist/utils/browser_extension_noise.d.ts +11 -0
- package/dist/utils/browser_extension_noise.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/replay/hooks.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { FailedRequestStatusCode } from '../types.js';
|
|
2
2
|
export type Teardown = () => void;
|
|
3
|
+
/**
|
|
4
|
+
* Fire when the document becomes visible again (tab focus) or is restored
|
|
5
|
+
* from the back/forward cache. Used to refresh the rrweb paint base after
|
|
6
|
+
* background throttling would have skipped periodic checkouts.
|
|
7
|
+
*/
|
|
8
|
+
export declare function installVisibilityResumeHook(onResume: () => void): Teardown;
|
|
3
9
|
export interface NetworkMeta {
|
|
4
10
|
method: string;
|
|
5
11
|
url: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/replay/hooks.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAE3D,MAAM,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC;AAElC,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,EAAE,CAAC,EAAE,OAAO,CAAC;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,qDAAqD;IACrD,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IACxC;;;OAGG;IACH,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,GAAG;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACnE,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,wBAAwB,CAAC,EAAE,uBAAuB,EAAE,CAAC;IACrD,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC,qFAAqF;IACrF,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAiBD,2EAA2E;AAC3E,wBAAgB,kBAAkB,IAAI,QAAQ,CA2B7C;AAcD,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,uBAAuB,EAAE,GAC/B,OAAO,CAUT;AAED,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,WAAW,EACjB,IAAI,EAAE;IACJ,qBAAqB,EAAE,OAAO,CAAC;IAC/B,wBAAwB,EAAE,uBAAuB,EAAE,CAAC;IACpD,uBAAuB,EAAE,MAAM,EAAE,CAAC;IAClC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GACA,IAAI,IAAI,WAAW,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAoB1C;AAED,8FAA8F;AAC9F,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,kBAAuB,GAAG,QAAQ,CA+F7E"}
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/replay/hooks.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAE3D,MAAM,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC;AAElC;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,QAAQ,CA4B1E;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,EAAE,CAAC,EAAE,OAAO,CAAC;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,qDAAqD;IACrD,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IACxC;;;OAGG;IACH,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,GAAG;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACnE,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,wBAAwB,CAAC,EAAE,uBAAuB,EAAE,CAAC;IACrD,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC,qFAAqF;IACrF,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAiBD,2EAA2E;AAC3E,wBAAgB,kBAAkB,IAAI,QAAQ,CA2B7C;AAcD,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,uBAAuB,EAAE,GAC/B,OAAO,CAUT;AAED,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,WAAW,EACjB,IAAI,EAAE;IACJ,qBAAqB,EAAE,OAAO,CAAC;IAC/B,wBAAwB,EAAE,uBAAuB,EAAE,CAAC;IACpD,uBAAuB,EAAE,MAAM,EAAE,CAAC;IAClC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GACA,IAAI,IAAI,WAAW,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAoB1C;AAED,8FAA8F;AAC9F,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,kBAAuB,GAAG,QAAQ,CA+F7E"}
|
|
@@ -4,6 +4,11 @@ export interface RecorderOptions {
|
|
|
4
4
|
/** Embed accessible stylesheet rules into the snapshot. Default false at resolve time. */
|
|
5
5
|
inlineStylesheet: boolean;
|
|
6
6
|
blockSelector?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Periodic Meta+FullSnapshot while recording (rrweb `checkoutEveryNms`).
|
|
9
|
+
* Set in buffer/error-sample mode so the ring never ages out its paint base.
|
|
10
|
+
*/
|
|
11
|
+
checkoutEveryNms?: number;
|
|
7
12
|
onEvent: (event: RrwebEvent) => void;
|
|
8
13
|
}
|
|
9
14
|
export interface RecorderHandle {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../src/replay/recorder.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,OAAO,CAAC;IACvB,0FAA0F;IAC1F,gBAAgB,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,qEAAqE;IACrE,gBAAgB,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc,
|
|
1
|
+
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../src/replay/recorder.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,OAAO,CAAC;IACvB,0FAA0F;IAC1F,gBAAgB,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,qEAAqE;IACrE,gBAAgB,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc,CA6CtE"}
|
|
@@ -34,6 +34,11 @@ export declare const ERROR_CLIP_FLUSH_SLACK_MS = 5000;
|
|
|
34
34
|
export declare const SEGMENT_FLUSH_MS = 5000;
|
|
35
35
|
/** Keep ~60s of events while buffering (error-only sample path). */
|
|
36
36
|
export declare const RING_BUFFER_MS = 60000;
|
|
37
|
+
/**
|
|
38
|
+
* rrweb checkout interval in buffer mode — must be ≤ {@link RING_BUFFER_MS}
|
|
39
|
+
* so a FullSnapshot always remains inside the ring after idle/away trim.
|
|
40
|
+
*/
|
|
41
|
+
export declare const RING_BUFFER_CHECKOUT_MS = 60000;
|
|
37
42
|
/** Cap ring buffer size so one error flush stays bounded. */
|
|
38
43
|
export declare const RING_BUFFER_MAX_BYTES = 1500000;
|
|
39
44
|
/** Default post-error upload window (cheap error clip). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"segment_buffer.d.ts","sourceRoot":"","sources":["../../src/replay/segment_buffer.ts"],"names":[],"mappings":"AAEA,oDAAoD;AACpD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,SAAU,CAAC;AAC1C;;;GAGG;AACH,eAAO,MAAM,4BAA4B,QAAc,CAAC;AACxD,iFAAiF;AACjF,eAAO,MAAM,+BAA+B,QACF,CAAC;AAC3C;;;GAGG;AACH,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C;;GAEG;AACH,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,uEAAuE;AACvE,eAAO,MAAM,+BAA+B,QAAkB,CAAC;AAC/D,8DAA8D;AAC9D,eAAO,MAAM,yBAAyB,OAAQ,CAAC;AAC/C,+BAA+B;AAC/B,eAAO,MAAM,gBAAgB,OAAQ,CAAC;AACtC,oEAAoE;AACpE,eAAO,MAAM,cAAc,QAAS,CAAC;AACrC,6DAA6D;AAC7D,eAAO,MAAM,qBAAqB,UAAY,CAAC;AAC/C,2DAA2D;AAC3D,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAC5C;;;GAGG;AACH,eAAO,MAAM,sBAAsB,QAAgB,CAAC;AAEpD,mCAAmC;AACnC,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC,2BAA2B;AAC3B,eAAO,MAAM,UAAU,IAAI,CAAC;AAE5B,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,YAAY,CAAK;IAEzB,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,cAAc,IAAI,MAAM,CAE3B;IAED,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAK7B,eAAe,IAAI,OAAO;IAI1B,4DAA4D;IAC5D,gBAAgB,IAAI,UAAU,GAAG,SAAS;IAI1C;;;OAGG;IACH,kBAAkB,IAAI,OAAO;IAc7B;;;OAGG;IACH,QAAQ,CAAC,GAAG,SAAa,EAAE,QAAQ,SAAwB,GAAG,IAAI;IAiBlE,iBAAiB,IAAI,OAAO;IAI5B;;;OAGG;IACH,eAAe,IAAI,MAAM;IAczB;;;;;;;;OAQG;IACH,oBAAoB,CAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE;QAAE,qBAAqB,CAAC,EAAE,OAAO,CAAA;KAAE,GACzC,UAAU,EAAE;IAqCf,OAAO,IAAI,UAAU,EAAE;IAOvB,6EAA6E;IAC7E,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI;IAMnC,KAAK,IAAI,IAAI;IAKb,SAAS,IAAI;QAAE,SAAS,EAAE,IAAI,CAAC;QAAC,OAAO,EAAE,IAAI,CAAA;KAAE,GAAG,IAAI;IAUtD,OAAO,CAAC,cAAc;CAGvB"}
|
|
1
|
+
{"version":3,"file":"segment_buffer.d.ts","sourceRoot":"","sources":["../../src/replay/segment_buffer.ts"],"names":[],"mappings":"AAEA,oDAAoD;AACpD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,SAAU,CAAC;AAC1C;;;GAGG;AACH,eAAO,MAAM,4BAA4B,QAAc,CAAC;AACxD,iFAAiF;AACjF,eAAO,MAAM,+BAA+B,QACF,CAAC;AAC3C;;;GAGG;AACH,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C;;GAEG;AACH,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,uEAAuE;AACvE,eAAO,MAAM,+BAA+B,QAAkB,CAAC;AAC/D,8DAA8D;AAC9D,eAAO,MAAM,yBAAyB,OAAQ,CAAC;AAC/C,+BAA+B;AAC/B,eAAO,MAAM,gBAAgB,OAAQ,CAAC;AACtC,oEAAoE;AACpE,eAAO,MAAM,cAAc,QAAS,CAAC;AACrC;;;GAGG;AACH,eAAO,MAAM,uBAAuB,QAAiB,CAAC;AACtD,6DAA6D;AAC7D,eAAO,MAAM,qBAAqB,UAAY,CAAC;AAC/C,2DAA2D;AAC3D,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAC5C;;;GAGG;AACH,eAAO,MAAM,sBAAsB,QAAgB,CAAC;AAEpD,mCAAmC;AACnC,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC,2BAA2B;AAC3B,eAAO,MAAM,UAAU,IAAI,CAAC;AAE5B,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,YAAY,CAAK;IAEzB,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,cAAc,IAAI,MAAM,CAE3B;IAED,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAK7B,eAAe,IAAI,OAAO;IAI1B,4DAA4D;IAC5D,gBAAgB,IAAI,UAAU,GAAG,SAAS;IAI1C;;;OAGG;IACH,kBAAkB,IAAI,OAAO;IAc7B;;;OAGG;IACH,QAAQ,CAAC,GAAG,SAAa,EAAE,QAAQ,SAAwB,GAAG,IAAI;IAiBlE,iBAAiB,IAAI,OAAO;IAI5B;;;OAGG;IACH,eAAe,IAAI,MAAM;IAczB;;;;;;;;OAQG;IACH,oBAAoB,CAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE;QAAE,qBAAqB,CAAC,EAAE,OAAO,CAAA;KAAE,GACzC,UAAU,EAAE;IAqCf,OAAO,IAAI,UAAU,EAAE;IAOvB,6EAA6E;IAC7E,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI;IAMnC,KAAK,IAAI,IAAI;IAKb,SAAS,IAAI;QAAE,SAAS,EAAE,IAAI,CAAC;QAAC,OAAO,EAAE,IAAI,CAAA;KAAE,GAAG,IAAI;IAUtD,OAAO,CAAC,cAAc;CAGvB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk_meta.d.ts","sourceRoot":"","sources":["../src/sdk_meta.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,eAAO,MAAM,QAAQ,wBAAwB,CAAC;AAC9C,eAAO,MAAM,WAAW,WAAW,CAAC"}
|
|
@@ -17,6 +17,21 @@
|
|
|
17
17
|
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
// src/utils/browser_extension_noise.ts
|
|
21
|
+
var EXTENSION_URL = /(?:chrome|moz|safari|safari-web|ms-browser)-extension:\/\//i;
|
|
22
|
+
var WEBKIT_MASKED = /webkit-masked-url:\/\/hidden\//i;
|
|
23
|
+
function isBrowserExtensionNoise(opts) {
|
|
24
|
+
const filename = opts.filename ?? "";
|
|
25
|
+
if (EXTENSION_URL.test(filename) || WEBKIT_MASKED.test(filename)) {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
const stack = opts.stack ?? "";
|
|
29
|
+
if (EXTENSION_URL.test(stack) || WEBKIT_MASKED.test(stack)) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
|
|
20
35
|
// src/utils/opaque_script_error.ts
|
|
21
36
|
function isOpaqueCrossOriginScriptError(event) {
|
|
22
37
|
const msg = (event.message ?? "").trim();
|
|
@@ -25,6 +40,137 @@
|
|
|
25
40
|
return true;
|
|
26
41
|
}
|
|
27
42
|
|
|
43
|
+
// src/utils/browser_context.ts
|
|
44
|
+
function parseBrowserContext(ua = typeof navigator !== "undefined" ? navigator.userAgent : "", language = typeof navigator !== "undefined" ? navigator.language : "") {
|
|
45
|
+
const userAgent = ua || "";
|
|
46
|
+
const lang = language || "";
|
|
47
|
+
let name = "unknown";
|
|
48
|
+
let version = "";
|
|
49
|
+
const rules = [
|
|
50
|
+
{ name: "Edge", re: /Edg(?:e|A|iOS)?\/([\d.]+)/ },
|
|
51
|
+
{ name: "Opera", re: /OPR\/([\d.]+)/ },
|
|
52
|
+
{ name: "Samsung Internet", re: /SamsungBrowser\/([\d.]+)/ },
|
|
53
|
+
{ name: "Firefox", re: /Firefox\/([\d.]+)/ },
|
|
54
|
+
{ name: "Chrome", re: /(?:Chrome|CriOS)\/([\d.]+)/ },
|
|
55
|
+
{ name: "Safari", re: /Version\/([\d.]+).*Safari/ }
|
|
56
|
+
];
|
|
57
|
+
for (const rule2 of rules) {
|
|
58
|
+
const m = userAgent.match(rule2.re);
|
|
59
|
+
if (m) {
|
|
60
|
+
name = rule2.name;
|
|
61
|
+
version = m[1] ?? "";
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (name === "unknown" && /iPhone|iPad|iPod/.test(userAgent) && /AppleWebKit/.test(userAgent)) {
|
|
66
|
+
name = "Safari";
|
|
67
|
+
const m = userAgent.match(/OS ([\d_]+)/);
|
|
68
|
+
if (m?.[1]) version = m[1].replace(/_/g, ".");
|
|
69
|
+
}
|
|
70
|
+
let os = "unknown";
|
|
71
|
+
let osVersion = "";
|
|
72
|
+
const win = userAgent.match(/Windows NT ([\d.]+)/);
|
|
73
|
+
if (win) {
|
|
74
|
+
os = "Windows";
|
|
75
|
+
osVersion = win[1] ?? "";
|
|
76
|
+
} else {
|
|
77
|
+
const android = userAgent.match(/Android ([\d.]+)/);
|
|
78
|
+
if (android) {
|
|
79
|
+
os = "Android";
|
|
80
|
+
osVersion = android[1] ?? "";
|
|
81
|
+
} else {
|
|
82
|
+
const ios = userAgent.match(/(?:iPhone|iPad|iPod).*OS ([\d_]+)/);
|
|
83
|
+
if (ios) {
|
|
84
|
+
os = "iOS";
|
|
85
|
+
osVersion = (ios[1] ?? "").replace(/_/g, ".");
|
|
86
|
+
} else {
|
|
87
|
+
const mac = userAgent.match(/Mac OS X ([\d_]+)/);
|
|
88
|
+
if (mac) {
|
|
89
|
+
os = "macOS";
|
|
90
|
+
osVersion = (mac[1] ?? "").replace(/_/g, ".");
|
|
91
|
+
} else if (/CrOS/.test(userAgent)) {
|
|
92
|
+
os = "Chrome OS";
|
|
93
|
+
} else if (/Linux/.test(userAgent)) {
|
|
94
|
+
os = "Linux";
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
let device = "desktop";
|
|
100
|
+
if (/iPad|Tablet|Android(?!.*Mobile)/i.test(userAgent)) {
|
|
101
|
+
device = "tablet";
|
|
102
|
+
} else if (/Mobi|iPhone|iPod|Android.*Mobile/i.test(userAgent)) {
|
|
103
|
+
device = "mobile";
|
|
104
|
+
} else if (!userAgent) {
|
|
105
|
+
device = "unknown";
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
name,
|
|
109
|
+
version,
|
|
110
|
+
os,
|
|
111
|
+
osVersion,
|
|
112
|
+
device,
|
|
113
|
+
language: lang,
|
|
114
|
+
userAgent
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function browserContextTags(ctx) {
|
|
118
|
+
return {
|
|
119
|
+
"browser.name": ctx.name,
|
|
120
|
+
"browser.version": ctx.version || "unknown",
|
|
121
|
+
"os.name": ctx.os,
|
|
122
|
+
"os.version": ctx.osVersion || "unknown",
|
|
123
|
+
device: ctx.device
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
async function collectBrowserContext() {
|
|
127
|
+
const base = parseBrowserContext();
|
|
128
|
+
const nav = typeof navigator !== "undefined" ? navigator : void 0;
|
|
129
|
+
const uad = nav?.userAgentData;
|
|
130
|
+
if (!uad) return base;
|
|
131
|
+
if (uad.mobile === true) base.device = "mobile";
|
|
132
|
+
if (uad.platform) {
|
|
133
|
+
const p = uad.platform;
|
|
134
|
+
if (/Windows/i.test(p)) base.os = "Windows";
|
|
135
|
+
else if (/macOS|Mac OS/i.test(p)) base.os = "macOS";
|
|
136
|
+
else if (/Android/i.test(p)) base.os = "Android";
|
|
137
|
+
else if (/iOS|iPhone/i.test(p)) base.os = "iOS";
|
|
138
|
+
else if (/Linux/i.test(p)) base.os = "Linux";
|
|
139
|
+
else if (/Chrome OS|Chromium OS/i.test(p)) base.os = "Chrome OS";
|
|
140
|
+
else base.os = p;
|
|
141
|
+
}
|
|
142
|
+
const brands = uad.brands ?? [];
|
|
143
|
+
const interesting = brands.find(
|
|
144
|
+
(b) => !/Not.?A.?Brand/i.test(b.brand) && !/Chromium/i.test(b.brand)
|
|
145
|
+
);
|
|
146
|
+
if (interesting) {
|
|
147
|
+
base.name = interesting.brand.replace(/^Google /, "");
|
|
148
|
+
base.version = interesting.version;
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
if (typeof uad.getHighEntropyValues === "function") {
|
|
152
|
+
const hi = await uad.getHighEntropyValues([
|
|
153
|
+
"platformVersion",
|
|
154
|
+
"fullVersionList"
|
|
155
|
+
]);
|
|
156
|
+
if (hi.platformVersion) base.osVersion = hi.platformVersion;
|
|
157
|
+
const full = hi.fullVersionList?.find(
|
|
158
|
+
(b) => !/Not.?A.?Brand/i.test(b.brand) && !/Chromium/i.test(b.brand)
|
|
159
|
+
);
|
|
160
|
+
if (full) {
|
|
161
|
+
base.name = full.brand.replace(/^Google /, "");
|
|
162
|
+
base.version = full.version;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
} catch {
|
|
166
|
+
}
|
|
167
|
+
return base;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// src/sdk_meta.ts
|
|
171
|
+
var SDK_NAME = "@newtalaria/browser";
|
|
172
|
+
var SDK_VERSION = "0.1.13";
|
|
173
|
+
|
|
28
174
|
// src/transport/serverpod.ts
|
|
29
175
|
var ServerpodTransport = class {
|
|
30
176
|
constructor(options) {
|
|
@@ -140,6 +286,7 @@
|
|
|
140
286
|
var ERROR_CLIP_FLUSH_SLACK_MS = 5e3;
|
|
141
287
|
var SEGMENT_FLUSH_MS = 5e3;
|
|
142
288
|
var RING_BUFFER_MS = 6e4;
|
|
289
|
+
var RING_BUFFER_CHECKOUT_MS = RING_BUFFER_MS;
|
|
143
290
|
var RING_BUFFER_MAX_BYTES = 15e5;
|
|
144
291
|
var ERROR_REPLAY_AFTER_MS = 15e3;
|
|
145
292
|
var MAX_REPLAY_DURATION_MS = 5 * 60 * 1e3;
|
|
@@ -13282,6 +13429,7 @@
|
|
|
13282
13429
|
inlineStylesheet: options.inlineStylesheet,
|
|
13283
13430
|
// Shrink DOM snapshots on heavy sites (docs / marketing).
|
|
13284
13431
|
slimDOMOptions: "all",
|
|
13432
|
+
...options.checkoutEveryNms != null && options.checkoutEveryNms > 0 ? { checkoutEveryNms: options.checkoutEveryNms } : {},
|
|
13285
13433
|
sampling: {
|
|
13286
13434
|
mousemove: 150,
|
|
13287
13435
|
scroll: 200,
|
|
@@ -13302,6 +13450,32 @@
|
|
|
13302
13450
|
}
|
|
13303
13451
|
|
|
13304
13452
|
// src/replay/hooks.ts
|
|
13453
|
+
function installVisibilityResumeHook(onResume) {
|
|
13454
|
+
if (typeof document === "undefined") {
|
|
13455
|
+
return () => {
|
|
13456
|
+
};
|
|
13457
|
+
}
|
|
13458
|
+
const onVisibility = () => {
|
|
13459
|
+
if (document.visibilityState === "visible") {
|
|
13460
|
+
onResume();
|
|
13461
|
+
}
|
|
13462
|
+
};
|
|
13463
|
+
const onPageShow = (event) => {
|
|
13464
|
+
if (event.persisted) {
|
|
13465
|
+
onResume();
|
|
13466
|
+
}
|
|
13467
|
+
};
|
|
13468
|
+
document.addEventListener("visibilitychange", onVisibility);
|
|
13469
|
+
if (typeof window !== "undefined") {
|
|
13470
|
+
window.addEventListener("pageshow", onPageShow);
|
|
13471
|
+
}
|
|
13472
|
+
return () => {
|
|
13473
|
+
document.removeEventListener("visibilitychange", onVisibility);
|
|
13474
|
+
if (typeof window !== "undefined") {
|
|
13475
|
+
window.removeEventListener("pageshow", onPageShow);
|
|
13476
|
+
}
|
|
13477
|
+
};
|
|
13478
|
+
}
|
|
13305
13479
|
function safeSerialize(args) {
|
|
13306
13480
|
try {
|
|
13307
13481
|
return JSON.stringify(
|
|
@@ -13538,6 +13712,8 @@
|
|
|
13538
13712
|
this.linkableReplayId = null;
|
|
13539
13713
|
/** Last error-clip paint/upload failure (cleared on successful segment 0). */
|
|
13540
13714
|
this.lastReplayCaptureFailure = null;
|
|
13715
|
+
/** Cached once per init for event tags/extra. */
|
|
13716
|
+
this.browserContext = null;
|
|
13541
13717
|
}
|
|
13542
13718
|
init(options) {
|
|
13543
13719
|
if (this.options) {
|
|
@@ -13560,6 +13736,10 @@
|
|
|
13560
13736
|
this.errorClipDeadlineMs = null;
|
|
13561
13737
|
this.linkableReplayId = null;
|
|
13562
13738
|
this.lastReplayCaptureFailure = null;
|
|
13739
|
+
this.browserContext = parseBrowserContext();
|
|
13740
|
+
void collectBrowserContext().then((ctx) => {
|
|
13741
|
+
if (this.options) this.browserContext = ctx;
|
|
13742
|
+
});
|
|
13563
13743
|
this.buffer = new SegmentBuffer();
|
|
13564
13744
|
this.uploadChain = Promise.resolve();
|
|
13565
13745
|
this.sessionSampled = Math.random() < this.options.replaysSessionSampleRate;
|
|
@@ -13568,6 +13748,9 @@
|
|
|
13568
13748
|
maskAllInputs: this.options.maskAllInputs,
|
|
13569
13749
|
inlineStylesheet: this.options.inlineStylesheet,
|
|
13570
13750
|
blockSelector: this.options.blockSelector,
|
|
13751
|
+
// Buffer/error path: keep a FullSnapshot inside the ~60s ring. Session
|
|
13752
|
+
// sample uploads continuously so periodic checkouts are skipped (size).
|
|
13753
|
+
checkoutEveryNms: this.sessionSampled ? void 0 : RING_BUFFER_CHECKOUT_MS,
|
|
13571
13754
|
onEvent: (event) => this.onRrwebEvent(event)
|
|
13572
13755
|
});
|
|
13573
13756
|
this.teardowns.push(
|
|
@@ -13597,7 +13780,8 @@
|
|
|
13597
13780
|
}
|
|
13598
13781
|
);
|
|
13599
13782
|
}
|
|
13600
|
-
})
|
|
13783
|
+
}),
|
|
13784
|
+
installVisibilityResumeHook(() => this.onForegroundResume())
|
|
13601
13785
|
);
|
|
13602
13786
|
if (!this.options.disableDefaultIntegrations) {
|
|
13603
13787
|
this.installGlobalHandlers();
|
|
@@ -13629,6 +13813,14 @@
|
|
|
13629
13813
|
}
|
|
13630
13814
|
async captureException(error, context) {
|
|
13631
13815
|
const err = error instanceof Error ? error : new Error(typeof error === "string" ? error : "Unknown error");
|
|
13816
|
+
const filename = typeof context?.extra?.filename === "string" ? context.extra.filename : void 0;
|
|
13817
|
+
if (isBrowserExtensionNoise({
|
|
13818
|
+
message: err.message,
|
|
13819
|
+
stack: err.stack,
|
|
13820
|
+
filename
|
|
13821
|
+
})) {
|
|
13822
|
+
return;
|
|
13823
|
+
}
|
|
13632
13824
|
await this.capture({
|
|
13633
13825
|
message: err.message || err.name || "Error",
|
|
13634
13826
|
level: "error",
|
|
@@ -13722,6 +13914,7 @@
|
|
|
13722
13914
|
this.closed = false;
|
|
13723
13915
|
this.linkableReplayId = null;
|
|
13724
13916
|
this.lastReplayCaptureFailure = null;
|
|
13917
|
+
this.browserContext = null;
|
|
13725
13918
|
}
|
|
13726
13919
|
onRrwebEvent(event) {
|
|
13727
13920
|
if (this.closed || !this.options) return;
|
|
@@ -13805,13 +13998,28 @@
|
|
|
13805
13998
|
}
|
|
13806
13999
|
const tags = applyReplayCaptureTags(
|
|
13807
14000
|
{
|
|
14001
|
+
...this.browserContext ? browserContextTags(this.browserContext) : {},
|
|
13808
14002
|
...this.options.tags ?? {},
|
|
13809
14003
|
...args.context?.tags ?? {}
|
|
13810
14004
|
},
|
|
13811
14005
|
errorClipOutcome
|
|
13812
14006
|
);
|
|
13813
14007
|
const extra = mergeReplayCaptureExtra(
|
|
13814
|
-
|
|
14008
|
+
{
|
|
14009
|
+
...this.browserContext ? {
|
|
14010
|
+
browser: {
|
|
14011
|
+
name: this.browserContext.name,
|
|
14012
|
+
version: this.browserContext.version,
|
|
14013
|
+
os: this.browserContext.os,
|
|
14014
|
+
osVersion: this.browserContext.osVersion,
|
|
14015
|
+
device: this.browserContext.device,
|
|
14016
|
+
language: this.browserContext.language,
|
|
14017
|
+
userAgent: this.browserContext.userAgent
|
|
14018
|
+
}
|
|
14019
|
+
} : {},
|
|
14020
|
+
sdk: { name: SDK_NAME, version: SDK_VERSION },
|
|
14021
|
+
...args.context?.extra
|
|
14022
|
+
},
|
|
13815
14023
|
errorClipOutcome
|
|
13816
14024
|
);
|
|
13817
14025
|
try {
|
|
@@ -13967,6 +14175,18 @@
|
|
|
13967
14175
|
checkoutFullSnapshot() {
|
|
13968
14176
|
this.recorder?.takeFullSnapshot();
|
|
13969
14177
|
}
|
|
14178
|
+
/**
|
|
14179
|
+
* Tab focus / bfcache restore: background timers are throttled, so the
|
|
14180
|
+
* buffer-mode checkout interval may not have fired. Refresh the paint base
|
|
14181
|
+
* so an error clip still has ~60s of usable lead-up after the user returns.
|
|
14182
|
+
*/
|
|
14183
|
+
onForegroundResume() {
|
|
14184
|
+
if (this.closed || !this.options || !this.recorder) return;
|
|
14185
|
+
if (!this.uploadEnabled) {
|
|
14186
|
+
this.buffer.trimRing();
|
|
14187
|
+
}
|
|
14188
|
+
this.checkoutFullSnapshot();
|
|
14189
|
+
}
|
|
13970
14190
|
/**
|
|
13971
14191
|
* Ensure segment 0 begins at Meta+FullSnapshot. Orphan increments alone
|
|
13972
14192
|
* produce a blank rrweb player.
|
|
@@ -14035,6 +14255,13 @@
|
|
|
14035
14255
|
const onError = (event) => {
|
|
14036
14256
|
if (isOpaqueCrossOriginScriptError(event)) return;
|
|
14037
14257
|
const error = event.error instanceof Error ? event.error : new Error(event.message || "window.onerror");
|
|
14258
|
+
if (isBrowserExtensionNoise({
|
|
14259
|
+
message: event.message || error.message,
|
|
14260
|
+
stack: error.stack,
|
|
14261
|
+
filename: event.filename
|
|
14262
|
+
})) {
|
|
14263
|
+
return;
|
|
14264
|
+
}
|
|
14038
14265
|
void this.captureException(error, {
|
|
14039
14266
|
extra: {
|
|
14040
14267
|
filename: event.filename,
|