@tracelane/core 0.1.0-alpha.13 → 0.1.0-alpha.15
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/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/network-capture.d.ts +46 -1
- package/dist/network-capture.d.ts.map +1 -1
- package/dist/network-capture.js +125 -3
- package/dist/network-capture.js.map +1 -1
- package/dist/recorder.d.ts +2 -0
- package/dist/recorder.d.ts.map +1 -1
- package/dist/recorder.js +61 -8
- package/dist/recorder.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export type { BrowserExecutor } from './browser-executor.js';
|
|
2
2
|
export { __internal, attachNetworkCapture } from './network-capture.js';
|
|
3
|
+
export type { AttachNetworkCaptureOptions, ResponseMeta } from './network-capture.js';
|
|
3
4
|
export { loadRrwebBundle } from './load-rrweb-bundle.js';
|
|
4
5
|
export { createRecorder, DEFAULT_COOLDOWN_MS, DEFAULT_DRAIN_INTERVAL_MS } from './recorder.js';
|
|
5
6
|
export type { FinalizeResult, Recorder, RecorderOptions, TestOutcome } from './recorder.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,YAAY,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAO7D,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,YAAY,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAO7D,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACxE,YAAY,EAAE,2BAA2B,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAItF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAC/F,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5F,YAAY,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAGnF,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACtD,YAAY,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGtC,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,cAAc,GACf,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAK1C,gFAAgF;AAChF,iFAAiF;AACjF,6EAA6E;AAC7E,6EAA6E;AAC7E,kFAAkF;AAClF,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAK1C,gFAAgF;AAChF,iFAAiF;AACjF,6EAA6E;AAC7E,6EAA6E;AAC7E,kFAAkF;AAClF,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAGxE,+EAA+E;AAC/E,yEAAyE;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,+EAA+E;AAC/E,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAI/F,kCAAkC;AAClC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAGtD,yEAAyE;AACzE,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,cAAc,GACf,MAAM,iBAAiB,CAAC"}
|
|
@@ -1,4 +1,46 @@
|
|
|
1
1
|
import type { BrowserExecutor } from './browser-executor.js';
|
|
2
|
+
/** Options for {@link attachNetworkCapture}. */
|
|
3
|
+
export interface AttachNetworkCaptureOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Capture privacy-safe MAIN-DOCUMENT response metadata (security-header
|
|
6
|
+
* PRESENCE + cookie FLAGS only) on a `[tracelane.sec]` console line. Default
|
|
7
|
+
* `true`; set `false` to fully disable — the `[tracelane.net]` behavior is
|
|
8
|
+
* unaffected either way.
|
|
9
|
+
*/
|
|
10
|
+
security?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Node-side sink for the privacy-safe main-document response metadata. When
|
|
13
|
+
* set, the meta is delivered here (e.g. recorder.addCustomEvent) instead of a
|
|
14
|
+
* page console.error — reliable across navigation. Receives names + flags only.
|
|
15
|
+
*/
|
|
16
|
+
onSecurityMeta?: (meta: ResponseMeta) => void;
|
|
17
|
+
}
|
|
18
|
+
/** A privacy-safe per-cookie record: NAME + flag presence booleans only. */
|
|
19
|
+
interface CookieFlags {
|
|
20
|
+
name: string;
|
|
21
|
+
secure: boolean;
|
|
22
|
+
httpOnly: boolean;
|
|
23
|
+
sameSite: boolean;
|
|
24
|
+
}
|
|
25
|
+
/** The privacy-safe main-document response metadata carried on `[tracelane.sec]`. */
|
|
26
|
+
export interface ResponseMeta {
|
|
27
|
+
url: string;
|
|
28
|
+
status: number;
|
|
29
|
+
isMainDocument: true;
|
|
30
|
+
presentSecurityHeaders: string[];
|
|
31
|
+
setCookies: CookieFlags[];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Return the allowlisted security-header NAMES present in `headers` (lowercased).
|
|
35
|
+
* Pure; never reads or returns any header VALUE.
|
|
36
|
+
*/
|
|
37
|
+
declare function presentSecurityHeaders(headers: Record<string, string> | undefined, allow: readonly string[]): string[];
|
|
38
|
+
/**
|
|
39
|
+
* Parse a CDP `set-cookie` header into per-cookie FLAG PRESENCE records. CDP
|
|
40
|
+
* joins multiple Set-Cookie headers with newlines. Captures only the cookie
|
|
41
|
+
* NAME (left of the first `=`) and three flag booleans — NEVER the value.
|
|
42
|
+
*/
|
|
43
|
+
declare function parseSetCookies(setCookieHeader: string | undefined): CookieFlags[];
|
|
2
44
|
/**
|
|
3
45
|
* Page-side logger. Self-contained (no Node closures) so it can be
|
|
4
46
|
* `.toString()`-serialized by `execute` (PRD §A.4). The console plugin captures
|
|
@@ -29,10 +71,13 @@ declare function methodOf(headers: Record<string, string> | undefined): string;
|
|
|
29
71
|
* either succeeded (`responseReceived`) or failed (`loadingFailed`) so the map
|
|
30
72
|
* can't grow unbounded over a long session.
|
|
31
73
|
*/
|
|
32
|
-
export declare function attachNetworkCapture(executor: BrowserExecutor): Promise<void>;
|
|
74
|
+
export declare function attachNetworkCapture(executor: BrowserExecutor, options?: AttachNetworkCaptureOptions): Promise<void>;
|
|
33
75
|
export declare const __internal: {
|
|
34
76
|
logNetworkErrorInPage: typeof logNetworkErrorInPage;
|
|
35
77
|
methodOf: typeof methodOf;
|
|
78
|
+
presentSecurityHeaders: typeof presentSecurityHeaders;
|
|
79
|
+
parseSetCookies: typeof parseSetCookies;
|
|
80
|
+
SEC_HEADER_ALLOWLIST: readonly ["content-security-policy", "strict-transport-security", "x-frame-options", "x-content-type-options", "referrer-policy"];
|
|
36
81
|
};
|
|
37
82
|
export {};
|
|
38
83
|
//# sourceMappingURL=network-capture.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network-capture.d.ts","sourceRoot":"","sources":["../src/network-capture.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"network-capture.d.ts","sourceRoot":"","sources":["../src/network-capture.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAkD7D,gDAAgD;AAChD,MAAM,WAAW,2BAA2B;IAC1C;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;CAC/C;AAeD,4EAA4E;AAC5E,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,qFAAqF;AACrF,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,IAAI,CAAC;IACrB,sBAAsB,EAAE,MAAM,EAAE,CAAC;IACjC,UAAU,EAAE,WAAW,EAAE,CAAC;CAC3B;AAED;;;GAGG;AACH,iBAAS,sBAAsB,CAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAC3C,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,MAAM,EAAE,CAIV;AAED;;;;GAIG;AACH,iBAAS,eAAe,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,EAAE,CAgB3E;AAKD;;;;;;;;;;GAUG;AACH,iBAAS,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAMhF;AAED,6EAA6E;AAC7E,iBAAS,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GAAG,MAAM,CAKrE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,eAAe,EACzB,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,IAAI,CAAC,CAkIf;AAGD,eAAO,MAAM,UAAU;;;;;;CAMtB,CAAC"}
|
package/dist/network-capture.js
CHANGED
|
@@ -23,6 +23,51 @@
|
|
|
23
23
|
// a true failure only when a method is present (its "true error path" rule —
|
|
24
24
|
// see `isTrueErrorPath`), so a methodless `loadingFailed` line would be
|
|
25
25
|
// silently dropped from the panel.
|
|
26
|
+
/**
|
|
27
|
+
* The fixed allowlist of security-relevant response-header names whose PRESENCE
|
|
28
|
+
* (never value) we surface. Lowercased; CDP header keys are case-preserving so
|
|
29
|
+
* presence checks compare case-insensitively.
|
|
30
|
+
*/
|
|
31
|
+
const SEC_HEADER_ALLOWLIST = [
|
|
32
|
+
'content-security-policy',
|
|
33
|
+
'strict-transport-security',
|
|
34
|
+
'x-frame-options',
|
|
35
|
+
'x-content-type-options',
|
|
36
|
+
'referrer-policy',
|
|
37
|
+
];
|
|
38
|
+
/**
|
|
39
|
+
* Return the allowlisted security-header NAMES present in `headers` (lowercased).
|
|
40
|
+
* Pure; never reads or returns any header VALUE.
|
|
41
|
+
*/
|
|
42
|
+
function presentSecurityHeaders(headers, allow) {
|
|
43
|
+
if (!headers)
|
|
44
|
+
return [];
|
|
45
|
+
const lower = new Set(Object.keys(headers).map((k) => k.toLowerCase()));
|
|
46
|
+
return allow.filter((h) => lower.has(h));
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Parse a CDP `set-cookie` header into per-cookie FLAG PRESENCE records. CDP
|
|
50
|
+
* joins multiple Set-Cookie headers with newlines. Captures only the cookie
|
|
51
|
+
* NAME (left of the first `=`) and three flag booleans — NEVER the value.
|
|
52
|
+
*/
|
|
53
|
+
function parseSetCookies(setCookieHeader) {
|
|
54
|
+
if (!setCookieHeader)
|
|
55
|
+
return [];
|
|
56
|
+
return setCookieHeader
|
|
57
|
+
.split('\n')
|
|
58
|
+
.map((l) => l.trim())
|
|
59
|
+
.filter(Boolean)
|
|
60
|
+
.map((line) => {
|
|
61
|
+
const name = (line.split('=', 1)[0] ?? '').trim();
|
|
62
|
+
const low = line.toLowerCase();
|
|
63
|
+
return {
|
|
64
|
+
name,
|
|
65
|
+
secure: /(?:^|;)\s*secure(?:\s*;|\s*$)/.test(low),
|
|
66
|
+
httpOnly: /(?:^|;)\s*httponly(?:\s*;|\s*$)/.test(low),
|
|
67
|
+
sameSite: /(?:^|;)\s*samesite\s*=/.test(low),
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
}
|
|
26
71
|
/** Status sentinel for a request that produced no response (a true 0 once parsed). */
|
|
27
72
|
const NO_RESPONSE_STATUS = 0;
|
|
28
73
|
/**
|
|
@@ -68,7 +113,8 @@ function methodOf(headers) {
|
|
|
68
113
|
* either succeeded (`responseReceived`) or failed (`loadingFailed`) so the map
|
|
69
114
|
* can't grow unbounded over a long session.
|
|
70
115
|
*/
|
|
71
|
-
export async function attachNetworkCapture(executor) {
|
|
116
|
+
export async function attachNetworkCapture(executor, options = {}) {
|
|
117
|
+
const security = options.security !== false;
|
|
72
118
|
await executor.cdp('Network', 'enable');
|
|
73
119
|
// Correlation map: a `loadingFailed` carries only a requestId, so remember the
|
|
74
120
|
// method + url from `requestWillBeSent` to reconstruct a method-bearing line.
|
|
@@ -82,6 +128,32 @@ export async function attachNetworkCapture(executor) {
|
|
|
82
128
|
/* page may be navigating; drop this one line */
|
|
83
129
|
});
|
|
84
130
|
};
|
|
131
|
+
// --- Privacy-safe main-document security metadata ([tracelane.sec]) ---------
|
|
132
|
+
// We track the top-level document's requestId, then assemble a ResponseMeta
|
|
133
|
+
// from `responseReceived` (header presence) + `responseReceivedExtraInfo`
|
|
134
|
+
// (cookie flags). Both CDP events for the main-document response are delivered
|
|
135
|
+
// in the same task batch; we defer the single emit to a microtask (scheduled
|
|
136
|
+
// from `responseReceived`) so cookie flags from `responseReceivedExtraInfo`
|
|
137
|
+
// are folded in regardless of arrival order — whichever event arrives second
|
|
138
|
+
// has landed in the same task before the microtask runs. The
|
|
139
|
+
// `responseReceivedExtraInfo` handler only STASHES cookies; it never emits.
|
|
140
|
+
// `mainDocEmitted` guarantees exactly-once (so a missing/late extraInfo still
|
|
141
|
+
// emits with whatever cookies were stashed, possibly `[]`).
|
|
142
|
+
let mainDocId;
|
|
143
|
+
let mainDocMeta;
|
|
144
|
+
let mainDocCookies;
|
|
145
|
+
let mainDocEmitted = false;
|
|
146
|
+
// Emit exactly once, folding in any stashed cookies. Called from the deferred
|
|
147
|
+
// microtask scheduled by `responseReceived`; the guard makes a second call
|
|
148
|
+
// (e.g. if ever scheduled twice) a no-op. Fire-and-forget.
|
|
149
|
+
const tryEmitSec = () => {
|
|
150
|
+
if (mainDocEmitted || !mainDocMeta)
|
|
151
|
+
return;
|
|
152
|
+
mainDocEmitted = true;
|
|
153
|
+
if (mainDocCookies)
|
|
154
|
+
mainDocMeta.setCookies = mainDocCookies;
|
|
155
|
+
options.onSecurityMeta?.(mainDocMeta);
|
|
156
|
+
};
|
|
85
157
|
executor.on('Network.requestWillBeSent', (params) => {
|
|
86
158
|
const e = params;
|
|
87
159
|
const id = e?.requestId;
|
|
@@ -90,7 +162,31 @@ export async function attachNetworkCapture(executor) {
|
|
|
90
162
|
return;
|
|
91
163
|
const method = typeof e.request?.method === 'string' ? e.request.method : 'GET';
|
|
92
164
|
inflight.set(id, { method, url });
|
|
165
|
+
// Remember the top-level document's requestId so we can attach security meta
|
|
166
|
+
// to its response. Only the first Document wins (the main navigation).
|
|
167
|
+
if (security && e.type === 'Document' && mainDocId === undefined) {
|
|
168
|
+
mainDocId = id;
|
|
169
|
+
}
|
|
93
170
|
});
|
|
171
|
+
if (security) {
|
|
172
|
+
executor.on('Network.responseReceivedExtraInfo', (params) => {
|
|
173
|
+
const e = params;
|
|
174
|
+
if (typeof e?.requestId !== 'string' || e.requestId !== mainDocId)
|
|
175
|
+
return;
|
|
176
|
+
// CDP exposes Set-Cookie here (header keys are typically lowercased in
|
|
177
|
+
// extra-info), not on responseReceived.response.headers.
|
|
178
|
+
const headers = e.headers ?? {};
|
|
179
|
+
const setCookieKey = Object.keys(headers).find((k) => k.toLowerCase() === 'set-cookie');
|
|
180
|
+
const cookies = parseSetCookies(setCookieKey ? headers[setCookieKey] : undefined);
|
|
181
|
+
// STASH ONLY — never emit here. The deferred microtask scheduled by
|
|
182
|
+
// `responseReceived` folds these in. If meta already exists, also write
|
|
183
|
+
// through so it's covered even if this handler runs after the microtask
|
|
184
|
+
// was scheduled (the microtask reads mainDocMeta.setCookies / mainDocCookies).
|
|
185
|
+
mainDocCookies = cookies;
|
|
186
|
+
if (mainDocMeta)
|
|
187
|
+
mainDocMeta.setCookies = cookies;
|
|
188
|
+
});
|
|
189
|
+
}
|
|
94
190
|
executor.on('Network.responseReceived', (params) => {
|
|
95
191
|
const e = params;
|
|
96
192
|
const response = e?.response;
|
|
@@ -104,6 +200,26 @@ export async function attachNetworkCapture(executor) {
|
|
|
104
200
|
const tracked = typeof id === 'string' ? inflight.get(id) : undefined;
|
|
105
201
|
if (typeof id === 'string')
|
|
106
202
|
inflight.delete(id);
|
|
203
|
+
// Main-document security metadata. Per CDP, responseReceivedExtraInfo fires
|
|
204
|
+
// BEFORE responseReceived, so any cookies have usually already been stashed;
|
|
205
|
+
// we fold them in and emit ONCE here. If extraInfo never comes, we still emit
|
|
206
|
+
// with `setCookies: []`. The emit guard prevents a double emit if a stray
|
|
207
|
+
// extraInfo arrives afterwards.
|
|
208
|
+
if (security && typeof id === 'string' && id === mainDocId && !mainDocEmitted) {
|
|
209
|
+
const status = response?.status;
|
|
210
|
+
const meta = {
|
|
211
|
+
url: response?.url ?? '',
|
|
212
|
+
status: typeof status === 'number' ? status : 0,
|
|
213
|
+
isMainDocument: true,
|
|
214
|
+
presentSecurityHeaders: presentSecurityHeaders(response?.headers, SEC_HEADER_ALLOWLIST),
|
|
215
|
+
setCookies: mainDocCookies ?? [],
|
|
216
|
+
};
|
|
217
|
+
mainDocMeta = meta;
|
|
218
|
+
// Defer the single emit so a same-task-batch responseReceivedExtraInfo
|
|
219
|
+
// (which may arrive before OR after this event) lands its cookie flags
|
|
220
|
+
// first. The mainDocEmitted guard keeps it exactly-once.
|
|
221
|
+
queueMicrotask(() => tryEmitSec());
|
|
222
|
+
}
|
|
107
223
|
const status = response?.status;
|
|
108
224
|
if (typeof status !== 'number' || status < 400)
|
|
109
225
|
return;
|
|
@@ -126,6 +242,12 @@ export async function attachNetworkCapture(executor) {
|
|
|
126
242
|
emit(url, NO_RESPONSE_STATUS, method);
|
|
127
243
|
});
|
|
128
244
|
}
|
|
129
|
-
// Exposed for unit tests: the page-side
|
|
130
|
-
export const __internal = {
|
|
245
|
+
// Exposed for unit tests: the page-side loggers + pure resolvers/parsers.
|
|
246
|
+
export const __internal = {
|
|
247
|
+
logNetworkErrorInPage,
|
|
248
|
+
methodOf,
|
|
249
|
+
presentSecurityHeaders,
|
|
250
|
+
parseSetCookies,
|
|
251
|
+
SEC_HEADER_ALLOWLIST,
|
|
252
|
+
};
|
|
131
253
|
//# sourceMappingURL=network-capture.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network-capture.js","sourceRoot":"","sources":["../src/network-capture.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,EAAE;AACF,mEAAmE;AACnE,4EAA4E;AAC5E,EAAE;AACF,4EAA4E;AAC5E,wDAAwD;AACxD,yEAAyE;AACzE,qEAAqE;AACrE,0EAA0E;AAC1E,0EAA0E;AAC1E,8EAA8E;AAC9E,4EAA4E;AAC5E,EAAE;AACF,yEAAyE;AACzE,+EAA+E;AAC/E,+EAA+E;AAC/E,4EAA4E;AAC5E,EAAE;AACF,gFAAgF;AAChF,+EAA+E;AAC/E,+EAA+E;AAC/E,6EAA6E;AAC7E,wEAAwE;AACxE,mCAAmC;
|
|
1
|
+
{"version":3,"file":"network-capture.js","sourceRoot":"","sources":["../src/network-capture.ts"],"names":[],"mappings":"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"}
|
package/dist/recorder.d.ts
CHANGED
|
@@ -80,6 +80,8 @@ export interface Recorder {
|
|
|
80
80
|
finalize(outcome: TestOutcome): Promise<FinalizeResult>;
|
|
81
81
|
/** The merged Node-side event buffer (live reference). */
|
|
82
82
|
getBuffer(): eventWithTime[];
|
|
83
|
+
/** Append a Node-side rrweb Custom event directly to the buffer — immune to page navigation timing (unlike a page console.error). */
|
|
84
|
+
addCustomEvent(tag: string, payload: unknown): void;
|
|
83
85
|
}
|
|
84
86
|
export declare function createRecorder(options: RecorderOptions): Recorder;
|
|
85
87
|
//# sourceMappingURL=recorder.d.ts.map
|
package/dist/recorder.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../src/recorder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../src/recorder.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,KAAK,IAAI,EAAe,MAAM,WAAW,CAAC;AACnD,OAAO,EACL,KAAK,oBAAoB,EAEzB,KAAK,oBAAoB,EAI1B,MAAM,kBAAkB,CAAC;AAE1B,sDAAsD;AACtD,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAE7C,MAAM,WAAW,eAAe;IAC9B,gDAAgD;IAChD,QAAQ,EAAE,eAAe,CAAC;IAC1B;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C;;;;;;;;OAQG;IACH,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C;;;OAGG;IACH,IAAI,CAAC,EAAE,IAAI,CAAC;CACb;AAED,mDAAmD;AACnD,MAAM,WAAW,WAAW;IAC1B,+BAA+B;IAC/B,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,sDAAsD;AACtD,MAAM,WAAW,cAAc;IAC7B,iEAAiE;IACjE,iBAAiB,EAAE,OAAO,CAAC;IAC3B,kEAAkE;IAClE,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,QAAQ;IACvB,8EAA8E;IAC9E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB;;;;;;OAMG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACxC,gFAAgF;IAChF,KAAK,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IAClC,8CAA8C;IAC9C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACxD,0DAA0D;IAC1D,SAAS,IAAI,aAAa,EAAE,CAAC;IAC7B,qIAAqI;IACrI,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CACrD;AAiCD,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,QAAQ,CAgIjE"}
|
package/dist/recorder.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { EventType } from '@cubenest/rrweb-core';
|
|
1
2
|
import { resolveMode } from './mode.js';
|
|
2
3
|
import { DEFAULT_CONSOLE_PLUGIN_OPTIONS, tracelaneDrainScript, tracelaneInitScript, tracelaneNavScript, } from './page-script.js';
|
|
3
4
|
/** Default re-injection cooldown in ms (ADR-0006). */
|
|
@@ -16,6 +17,25 @@ function injectBundleScript(bundle) {
|
|
|
16
17
|
// a real global), which is the intended injection behavior in the page context.
|
|
17
18
|
window.eval(bundle);
|
|
18
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Bounded retry for page-side re-injection. `framenavigated` can fire while the
|
|
22
|
+
* new document's execution context is still being (re)created, so the first
|
|
23
|
+
* page-evaluate races the navigation and throws "Execution context was
|
|
24
|
+
* destroyed". On a real (latency-bearing) navigation that single failure would
|
|
25
|
+
* otherwise be swallowed by the caller and silently lose ALL DOM capture on the
|
|
26
|
+
* new page. The context stabilizes within a few ms of navigation, so a short
|
|
27
|
+
* bounded retry reliably recovers recording.
|
|
28
|
+
*/
|
|
29
|
+
const REINJECT_MAX_ATTEMPTS = 6;
|
|
30
|
+
const REINJECT_RETRY_MS = 100;
|
|
31
|
+
/** True for the transient errors a page op throws when it races a navigation. */
|
|
32
|
+
function isNavigationRace(err) {
|
|
33
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
34
|
+
return /execution context was destroyed|context was destroyed|frame (was )?detached|target closed|because of a navigation/i.test(msg);
|
|
35
|
+
}
|
|
36
|
+
function sleep(ms) {
|
|
37
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
38
|
+
}
|
|
19
39
|
export function createRecorder(options) {
|
|
20
40
|
const { executor, rrwebBundle, drainIntervalMs = DEFAULT_DRAIN_INTERVAL_MS, cooldownMs = DEFAULT_COOLDOWN_MS, consolePluginOptions = DEFAULT_CONSOLE_PLUGIN_OPTIONS, networkPluginOptions, mode: configMode, } = options;
|
|
21
41
|
const buffer = [];
|
|
@@ -40,16 +60,48 @@ export function createRecorder(options) {
|
|
|
40
60
|
async function reinject(url) {
|
|
41
61
|
// Re-eval the bundle (the page may have been torn down by navigation), then
|
|
42
62
|
// re-run init. The init script's return value is the authority on whether a
|
|
43
|
-
// fresh recording started.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
63
|
+
// fresh recording started. Retry on navigation-race errors so a single
|
|
64
|
+
// page-evaluate that races the in-flight nav doesn't silently lose all DOM
|
|
65
|
+
// capture on the new page (the failure mode on real, latency-bearing sites).
|
|
66
|
+
let lastErr;
|
|
67
|
+
for (let attempt = 0; attempt < REINJECT_MAX_ATTEMPTS; attempt++) {
|
|
68
|
+
try {
|
|
69
|
+
await executor.execute(injectBundleScript, rrwebBundle);
|
|
70
|
+
const sid = await runInit();
|
|
71
|
+
if (sid === 0)
|
|
72
|
+
return false; // cooldown-suppressed (same-doc hash/HMR); no nav boundary
|
|
73
|
+
await executor.execute(tracelaneNavScript, url, Date.now());
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
lastErr = err;
|
|
78
|
+
if (!isNavigationRace(err))
|
|
79
|
+
throw err; // a real failure, not a transient nav race
|
|
80
|
+
if (attempt < REINJECT_MAX_ATTEMPTS - 1)
|
|
81
|
+
await sleep(REINJECT_RETRY_MS);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
throw lastErr; // retries exhausted; the caller treats reinject as best-effort
|
|
85
|
+
}
|
|
86
|
+
function addCustomEvent(tag, payload) {
|
|
87
|
+
buffer.push({
|
|
88
|
+
type: EventType.Custom,
|
|
89
|
+
timestamp: Date.now(),
|
|
90
|
+
data: { tag, payload },
|
|
91
|
+
});
|
|
50
92
|
}
|
|
51
93
|
async function drain() {
|
|
52
|
-
|
|
94
|
+
let batch;
|
|
95
|
+
try {
|
|
96
|
+
batch = (await executor.execute(tracelaneDrainScript));
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
// A poll firing mid-navigation hits "context destroyed"; skip this cycle.
|
|
100
|
+
// The next poll (or the init script's pagehide flush) recovers the events.
|
|
101
|
+
if (isNavigationRace(err))
|
|
102
|
+
return [];
|
|
103
|
+
throw err;
|
|
104
|
+
}
|
|
53
105
|
if (batch && batch.length > 0) {
|
|
54
106
|
buffer.push(...batch);
|
|
55
107
|
return batch;
|
|
@@ -91,6 +143,7 @@ export function createRecorder(options) {
|
|
|
91
143
|
stop,
|
|
92
144
|
finalize,
|
|
93
145
|
getBuffer: () => buffer,
|
|
146
|
+
addCustomEvent,
|
|
94
147
|
};
|
|
95
148
|
}
|
|
96
149
|
//# sourceMappingURL=recorder.js.map
|
package/dist/recorder.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recorder.js","sourceRoot":"","sources":["../src/recorder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"recorder.js","sourceRoot":"","sources":["../src/recorder.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tracelane/core",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.15",
|
|
4
4
|
"description": "Framework-agnostic rrweb recording engine for tracelane. Wraps a per-framework browser object behind a common BrowserExecutor interface.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"tracelane",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"README.md"
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@cubenest/rrweb-core": "0.1.0-alpha.
|
|
34
|
+
"@cubenest/rrweb-core": "0.1.0-alpha.6"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"jsdom": "^25.0.1"
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
},
|
|
51
51
|
"homepage": "https://github.com/Cubenest/rrweb-stack/tree/main/packages/tracelane-core#readme",
|
|
52
52
|
"engines": {
|
|
53
|
-
"node": ">=
|
|
53
|
+
"node": ">=22"
|
|
54
54
|
},
|
|
55
55
|
"scripts": {
|
|
56
56
|
"build": "tsc -p tsconfig.json",
|