@tracelane/core 0.1.0-alpha.10 → 0.1.0-alpha.12

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 CHANGED
@@ -1,4 +1,6 @@
1
1
  export type { BrowserExecutor } from './browser-executor.js';
2
+ export { __internal, attachNetworkCapture } from './network-capture.js';
3
+ export { loadRrwebBundle } from './load-rrweb-bundle.js';
2
4
  export { createRecorder, DEFAULT_COOLDOWN_MS, DEFAULT_DRAIN_INTERVAL_MS } from './recorder.js';
3
5
  export type { FinalizeResult, Recorder, RecorderOptions, TestOutcome } from './recorder.js';
4
6
  export type { ConsolePluginOptions, NetworkPluginOptions } from './page-script.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,YAAY,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D,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"}
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;AAIxE,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 CHANGED
@@ -1,4 +1,13 @@
1
1
  // Public API surface for @tracelane/core.
2
+ // CDP network capture (Task 2.16 / P1 PRD §E.2) — framework-agnostic, shared by
3
+ // the WDIO and Playwright adapters via the BrowserExecutor surface. `__internal`
4
+ // exposes the pure page-side logger + method resolver so @tracelane/report's
5
+ // cross-package contract test can exercise core's real output (the test must
6
+ // live in report — which depends on core — to keep the dep edge one-directional).
7
+ export { __internal, attachNetworkCapture } from './network-capture.js';
8
+ // In-page rrweb bundle loader — reads the adapter's built dist/rrweb-bundle.js
9
+ // off disk (pass the adapter's import.meta.url). Shared across adapters.
10
+ export { loadRrwebBundle } from './load-rrweb-bundle.js';
2
11
  // Recorder controller — in-page buffer install + Node-polled drain (ADR-0006).
3
12
  export { createRecorder, DEFAULT_COOLDOWN_MS, DEFAULT_DRAIN_INTERVAL_MS } from './recorder.js';
4
13
  // Capture mode switch (ADR-0005).
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAK1C,+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
+ {"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;AAExE,+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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Read the rrweb in-page bundle source (defines `window.rrweb`) off disk.
3
+ *
4
+ * @param moduleUrl the calling adapter's `import.meta.url`; candidate
5
+ * paths resolve relative to this module.
6
+ * @param candidatePaths optional explicit candidate paths (overrides the
7
+ * defaults). The first that exists is read.
8
+ * @returns the bundle source string.
9
+ * @throws if no candidate exists — that means the package was used without its
10
+ * build step having run.
11
+ */
12
+ export declare function loadRrwebBundle(moduleUrl: string, candidatePaths?: string[]): string;
13
+ //# sourceMappingURL=load-rrweb-bundle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-rrweb-bundle.d.ts","sourceRoot":"","sources":["../src/load-rrweb-bundle.ts"],"names":[],"mappings":"AA8BA;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAUpF"}
@@ -0,0 +1,47 @@
1
+ // Loads the in-page rrweb bundle source string (framework-agnostic).
2
+ //
3
+ // Each adapter (WDIO, Playwright) ships its own `dist/rrweb-bundle.js` — an
4
+ // esbuild IIFE that defines `window.rrweb` with `record` +
5
+ // `getRecordConsolePlugin` (+ `getRecordNetworkPlugin`). The recorder is
6
+ // bundle-source-agnostic (ADR-0006) and expects this source as a plain string,
7
+ // which it `window.eval`s in the page on every (re-)injection.
8
+ //
9
+ // This loader lives in @tracelane/core so every adapter shares one
10
+ // implementation. The adapter passes its own `import.meta.url` so the candidate
11
+ // paths resolve relative to the ADAPTER's module (where its bundle sits), not to
12
+ // core. We derive the module directory from `fileURLToPath(moduleUrl)` directly
13
+ // (not via `new URL(rel, moduleUrl)`) because under the jsdom test env the
14
+ // global `URL` resolves relative inputs against the page origin, not the file.
15
+ import { existsSync, readFileSync } from 'node:fs';
16
+ import { dirname, join } from 'node:path';
17
+ import { fileURLToPath } from 'node:url';
18
+ /**
19
+ * Default candidate locations for the built bundle relative to `moduleUrl`, in
20
+ * priority order. Mirrors the historical wdio layout:
21
+ * - Published: `dist/<loader>.js` sits next to `dist/rrweb-bundle.js`.
22
+ * - Source/test: `src/<loader>.ts` → `../dist/rrweb-bundle.js`.
23
+ */
24
+ function defaultCandidatePaths(moduleUrl) {
25
+ const moduleDir = dirname(fileURLToPath(moduleUrl));
26
+ return [join(moduleDir, 'rrweb-bundle.js'), join(moduleDir, '..', 'dist', 'rrweb-bundle.js')];
27
+ }
28
+ /**
29
+ * Read the rrweb in-page bundle source (defines `window.rrweb`) off disk.
30
+ *
31
+ * @param moduleUrl the calling adapter's `import.meta.url`; candidate
32
+ * paths resolve relative to this module.
33
+ * @param candidatePaths optional explicit candidate paths (overrides the
34
+ * defaults). The first that exists is read.
35
+ * @returns the bundle source string.
36
+ * @throws if no candidate exists — that means the package was used without its
37
+ * build step having run.
38
+ */
39
+ export function loadRrwebBundle(moduleUrl, candidatePaths) {
40
+ const candidates = candidatePaths && candidatePaths.length > 0 ? candidatePaths : defaultCandidatePaths(moduleUrl);
41
+ const found = candidates.find((p) => existsSync(p));
42
+ if (found === undefined) {
43
+ throw new Error(`tracelane: in-page rrweb bundle not found (looked in ${candidates.join(', ')}). Run the package build to generate dist/rrweb-bundle.js.`);
44
+ }
45
+ return readFileSync(found, 'utf8');
46
+ }
47
+ //# sourceMappingURL=load-rrweb-bundle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-rrweb-bundle.js","sourceRoot":"","sources":["../src/load-rrweb-bundle.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,EAAE;AACF,4EAA4E;AAC5E,2DAA2D;AAC3D,yEAAyE;AACzE,+EAA+E;AAC/E,+DAA+D;AAC/D,EAAE;AACF,mEAAmE;AACnE,gFAAgF;AAChF,iFAAiF;AACjF,gFAAgF;AAChF,2EAA2E;AAC3E,+EAA+E;AAE/E,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC;;;;;GAKG;AACH,SAAS,qBAAqB,CAAC,SAAiB;IAC9C,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC;IACpD,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC;AAChG,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAAC,SAAiB,EAAE,cAAyB;IAC1E,MAAM,UAAU,GACd,cAAc,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAClG,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,wDAAwD,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,4DAA4D,CAC1I,CAAC;IACJ,CAAC;IACD,OAAO,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AACrC,CAAC"}
@@ -0,0 +1,38 @@
1
+ import type { BrowserExecutor } from './browser-executor.js';
2
+ /**
3
+ * Page-side logger. Self-contained (no Node closures) so it can be
4
+ * `.toString()`-serialized by `execute` (PRD §A.4). The console plugin captures
5
+ * this `console.error`; the `[tracelane.net]` prefix lets the report's network
6
+ * panel scrape it back out (PRD §E.2).
7
+ *
8
+ * The status is zero-padded to 3 digits so it satisfies panels.ts's
9
+ * `parseNetConsoleLine` regex (`(\d{3})`); `Number('000')` parses back to a
10
+ * genuine `0`, which — paired with the always-present method — panels.ts treats
11
+ * as a true network failure.
12
+ */
13
+ declare function logNetworkErrorInPage(url: string, status: number, method: string): void;
14
+ /** Pull the request method out of CDP request headers, defaulting to GET. */
15
+ declare function methodOf(headers: Record<string, string> | undefined): string;
16
+ /**
17
+ * Attach CDP network capture to a BrowserExecutor (P1 PRD §E.2).
18
+ *
19
+ * Enables the Network domain and registers subscribers that forward both HTTP
20
+ * error responses (`Network.responseReceived`, `status >= 400`) and no-response
21
+ * failures (`Network.loadingFailed` — CORS/DNS/offline/abort, audit A-6) into
22
+ * `console.error`. Resolves once `Network.enable` has been sent. The
23
+ * subscribers' own `execute` calls are fire-and-forget (their failures must not
24
+ * break the test).
25
+ *
26
+ * To give the methodless `loadingFailed` events a method (required by panels.ts
27
+ * to classify the row as failed), we keep a small `requestId → { method, url }`
28
+ * map populated from `Network.requestWillBeSent`, and evict an entry once it has
29
+ * either succeeded (`responseReceived`) or failed (`loadingFailed`) so the map
30
+ * can't grow unbounded over a long session.
31
+ */
32
+ export declare function attachNetworkCapture(executor: BrowserExecutor): Promise<void>;
33
+ export declare const __internal: {
34
+ logNetworkErrorInPage: typeof logNetworkErrorInPage;
35
+ methodOf: typeof methodOf;
36
+ };
37
+ export {};
38
+ //# sourceMappingURL=network-capture.d.ts.map
@@ -0,0 +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;AAoC7D;;;;;;;;;;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,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAoDnF;AAGD,eAAO,MAAM,UAAU;;;CAAsC,CAAC"}
@@ -0,0 +1,125 @@
1
+ // CDP network capture wiring (Task 2.16 / P1 PRD §E.2).
2
+ //
3
+ // Enable the CDP Network domain and route failures into the page's
4
+ // `console.error` via `executor.execute`. Two failure classes are surfaced:
5
+ //
6
+ // 1. `Network.responseReceived` with `status >= 400` — a response arrived
7
+ // but the server reported an HTTP error (4xx/5xx).
8
+ // 2. `Network.loadingFailed` — the request produced NO response at all
9
+ // (CORS failure, DNS/connection failure, offline, abort). CDP's
10
+ // `responseReceived` never fires for these, and the in-page status-0
11
+ // wrapper is off by default, so without this branch a genuine failed
12
+ // request would be invisible (audit A-6). We surface it with an explicit
13
+ // status `000` (= a real 0 once parsed) so it reads as a true failure.
14
+ //
15
+ // The rrweb console plugin (installed by the recorder) then captures the
16
+ // console line, so failures show up in the report's network panel "for free" —
17
+ // no dedicated network transport in v1. Framework-agnostic: it talks only to a
18
+ // BrowserExecutor, so the WDIO and Playwright adapters share this one path.
19
+ //
20
+ // The console line is prefixed `[tracelane.net]` so @tracelane/report's network
21
+ // panel can scrape it back out (NETWORK_CONSOLE_PREFIX in panels.ts). The line
22
+ // ALWAYS carries a METHOD: panels.ts classifies a `status === 0` scrape row as
23
+ // a true failure only when a method is present (its "true error path" rule —
24
+ // see `isTrueErrorPath`), so a methodless `loadingFailed` line would be
25
+ // silently dropped from the panel.
26
+ /** Status sentinel for a request that produced no response (a true 0 once parsed). */
27
+ const NO_RESPONSE_STATUS = 0;
28
+ /**
29
+ * Page-side logger. Self-contained (no Node closures) so it can be
30
+ * `.toString()`-serialized by `execute` (PRD §A.4). The console plugin captures
31
+ * this `console.error`; the `[tracelane.net]` prefix lets the report's network
32
+ * panel scrape it back out (PRD §E.2).
33
+ *
34
+ * The status is zero-padded to 3 digits so it satisfies panels.ts's
35
+ * `parseNetConsoleLine` regex (`(\d{3})`); `Number('000')` parses back to a
36
+ * genuine `0`, which — paired with the always-present method — panels.ts treats
37
+ * as a true network failure.
38
+ */
39
+ function logNetworkErrorInPage(url, status, method) {
40
+ // Zero-pad to 3 digits without String.padStart so the .toString()-serialized
41
+ // form runs on older in-page engines too.
42
+ let code = String(status);
43
+ while (code.length < 3)
44
+ code = `0${code}`;
45
+ console.error(`[tracelane.net] ${method} ${code} ${url}`);
46
+ }
47
+ /** Pull the request method out of CDP request headers, defaulting to GET. */
48
+ function methodOf(headers) {
49
+ if (!headers)
50
+ return 'GET';
51
+ // CDP exposes the pseudo-header `:method` for HTTP/2/3; fall back to a plain
52
+ // `method` header, then GET.
53
+ return headers[':method'] ?? headers.method ?? 'GET';
54
+ }
55
+ /**
56
+ * Attach CDP network capture to a BrowserExecutor (P1 PRD §E.2).
57
+ *
58
+ * Enables the Network domain and registers subscribers that forward both HTTP
59
+ * error responses (`Network.responseReceived`, `status >= 400`) and no-response
60
+ * failures (`Network.loadingFailed` — CORS/DNS/offline/abort, audit A-6) into
61
+ * `console.error`. Resolves once `Network.enable` has been sent. The
62
+ * subscribers' own `execute` calls are fire-and-forget (their failures must not
63
+ * break the test).
64
+ *
65
+ * To give the methodless `loadingFailed` events a method (required by panels.ts
66
+ * to classify the row as failed), we keep a small `requestId → { method, url }`
67
+ * map populated from `Network.requestWillBeSent`, and evict an entry once it has
68
+ * either succeeded (`responseReceived`) or failed (`loadingFailed`) so the map
69
+ * can't grow unbounded over a long session.
70
+ */
71
+ export async function attachNetworkCapture(executor) {
72
+ await executor.cdp('Network', 'enable');
73
+ // Correlation map: a `loadingFailed` carries only a requestId, so remember the
74
+ // method + url from `requestWillBeSent` to reconstruct a method-bearing line.
75
+ const inflight = new Map();
76
+ const emit = (url, status, method) => {
77
+ // Fire-and-forget: a logging failure (e.g. page mid-navigation) must not
78
+ // surface as a test error.
79
+ void executor
80
+ .execute(logNetworkErrorInPage, url, status, method)
81
+ .catch(() => {
82
+ /* page may be navigating; drop this one line */
83
+ });
84
+ };
85
+ executor.on('Network.requestWillBeSent', (params) => {
86
+ const e = params;
87
+ const id = e?.requestId;
88
+ const url = e?.request?.url;
89
+ if (typeof id !== 'string' || typeof url !== 'string')
90
+ return;
91
+ const method = typeof e.request?.method === 'string' ? e.request.method : 'GET';
92
+ inflight.set(id, { method, url });
93
+ });
94
+ executor.on('Network.responseReceived', (params) => {
95
+ const e = params;
96
+ const response = e?.response;
97
+ // A response arrived — this request will not surface via loadingFailed, so
98
+ // drop it from the inflight map regardless of status.
99
+ if (typeof e?.requestId === 'string')
100
+ inflight.delete(e.requestId);
101
+ const status = response?.status;
102
+ if (typeof status !== 'number' || status < 400)
103
+ return;
104
+ const url = response?.url ?? '';
105
+ const method = methodOf(response?.requestHeaders);
106
+ emit(url, status, method);
107
+ });
108
+ executor.on('Network.loadingFailed', (params) => {
109
+ const e = params;
110
+ const id = e?.requestId;
111
+ // Correlate back to the request's method + url; CORS/DNS/offline/abort
112
+ // failures produce NO response, so this is the only place they surface.
113
+ const tracked = typeof id === 'string' ? inflight.get(id) : undefined;
114
+ if (typeof id === 'string')
115
+ inflight.delete(id);
116
+ const url = tracked?.url ?? '';
117
+ // Method is required for panels.ts to treat the status-0 row as a failure;
118
+ // default to GET if the requestWillBeSent was missed (e.g. attach mid-flight).
119
+ const method = tracked?.method ?? 'GET';
120
+ emit(url, NO_RESPONSE_STATUS, method);
121
+ });
122
+ }
123
+ // Exposed for unit tests: the page-side logger + method resolver are pure.
124
+ export const __internal = { logNetworkErrorInPage, methodOf };
125
+ //# sourceMappingURL=network-capture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"network-capture.js","sourceRoot":"","sources":["../src/network-capture.ts"],"names":[],"mappings":"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"}
@@ -30,14 +30,15 @@ export declare const DEFAULT_CONSOLE_PLUGIN_OPTIONS: ConsolePluginOptions;
30
30
  */
31
31
  export type NetworkPluginOptions = Record<string, unknown>;
32
32
  /**
33
- * The in-page init routine (PRD §D.3 + ADR-0006). Idempotent across calls via a
34
- * monotonic `__tracelane__sessionId` stamp and a cooldown guard so hash-only /
35
- * HMR navigations don't double-init the recorder (the cooldown / re-injection
36
- * semantics are exercised in Task 2.4).
33
+ * The in-page init routine (PRD §D.3 + ADR-0006). A cooldown guard suppresses
34
+ * double-init on hash-only / HMR navigations within the SAME document. Note the
35
+ * `__tracelane__sessionId` stamp is page-local: it resets to 1 in every fresh
36
+ * document (a hard navigation), so it is NOT a cross-document monotonic counter.
37
37
  *
38
38
  * Assumes `window.rrweb` is already defined (the recorder injects the rrweb
39
- * bundle string first). Returns the active session id so the Node side can
40
- * confirm whether a (re-)init actually took effect.
39
+ * bundle string first). Returns a sentinel the Node side uses to decide whether
40
+ * a fresh recording actually started: `0` when this call was cooldown-suppressed
41
+ * (no new recording), or the active (≥1) session id when recording (re-)started.
41
42
  *
42
43
  * `networkOptions === undefined` keeps the network plugin OFF (the legacy
43
44
  * CDP-based path still applies). `networkOptions === {}` opts in with the
@@ -1 +1 @@
1
- {"version":3,"file":"page-script.d.ts","sourceRoot":"","sources":["../src/page-script.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,0EAA0E;AAC1E,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE;QACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAED,6CAA6C;AAC7C,eAAO,MAAM,8BAA8B,EAAE,oBAI5C,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE3D;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,oBAAoB,EACpC,cAAc,CAAC,EAAE,oBAAoB,GACpC,MAAM,CAsDR;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,EAAE,CAKhD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAKhE"}
1
+ {"version":3,"file":"page-script.d.ts","sourceRoot":"","sources":["../src/page-script.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,0EAA0E;AAC1E,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE;QACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAED,6CAA6C;AAC7C,eAAO,MAAM,8BAA8B,EAAE,oBAI5C,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE3D;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,oBAAoB,EACpC,cAAc,CAAC,EAAE,oBAAoB,GACpC,MAAM,CAuGR;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,EAAE,CAKhD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAKhE"}
@@ -14,14 +14,15 @@ export const DEFAULT_CONSOLE_PLUGIN_OPTIONS = {
14
14
  stringifyOptions: { stringLengthLimit: 1000, numOfKeysLimit: 100, depthOfLimit: 1 },
15
15
  };
16
16
  /**
17
- * The in-page init routine (PRD §D.3 + ADR-0006). Idempotent across calls via a
18
- * monotonic `__tracelane__sessionId` stamp and a cooldown guard so hash-only /
19
- * HMR navigations don't double-init the recorder (the cooldown / re-injection
20
- * semantics are exercised in Task 2.4).
17
+ * The in-page init routine (PRD §D.3 + ADR-0006). A cooldown guard suppresses
18
+ * double-init on hash-only / HMR navigations within the SAME document. Note the
19
+ * `__tracelane__sessionId` stamp is page-local: it resets to 1 in every fresh
20
+ * document (a hard navigation), so it is NOT a cross-document monotonic counter.
21
21
  *
22
22
  * Assumes `window.rrweb` is already defined (the recorder injects the rrweb
23
- * bundle string first). Returns the active session id so the Node side can
24
- * confirm whether a (re-)init actually took effect.
23
+ * bundle string first). Returns a sentinel the Node side uses to decide whether
24
+ * a fresh recording actually started: `0` when this call was cooldown-suppressed
25
+ * (no new recording), or the active (≥1) session id when recording (re-)started.
25
26
  *
26
27
  * `networkOptions === undefined` keeps the network plugin OFF (the legacy
27
28
  * CDP-based path still applies). `networkOptions === {}` opts in with the
@@ -33,13 +34,57 @@ export function tracelaneInitScript(cooldownMs, consoleOptions, networkOptions)
33
34
  const w = window;
34
35
  const now = Date.now();
35
36
  // Cooldown: a very recent init means this is a hash/HMR re-render, not a real
36
- // navigation — skip to avoid double-recording (ADR-0006).
37
+ // navigation — skip to avoid double-recording (ADR-0006). Return the `0`
38
+ // sentinel so the Node side can tell "suppressed" apart from a fresh recording
39
+ // (the in-page session id resets to 1 on every new document, so it can't be
40
+ // used as a monotonic signal across hard navigations).
37
41
  if (w.__tracelane__inited !== undefined && now - w.__tracelane__inited < cooldownMs) {
38
- return w.__tracelane__sessionId ?? 0;
42
+ return 0;
39
43
  }
40
44
  w.__tracelane__inited = now;
41
45
  w.__tracelane__sessionId = (w.__tracelane__sessionId ?? 0) + 1;
42
46
  w.__tracelane__events = w.__tracelane__events ?? [];
47
+ // Pre-navigation rescue (Fix #2): the in-page event buffer dies on a hard
48
+ // navigation before the Node poll drains it. The OLD document stashes its
49
+ // unflushed tail into sessionStorage on `pagehide`; this fresh document merges
50
+ // it back in on init, then clears the key so it's consumed exactly once.
51
+ // Best-effort: sessionStorage may be unavailable (private mode) or the value
52
+ // may be malformed — never let that break recording.
53
+ try {
54
+ const pending = w.sessionStorage?.getItem('__tracelane__pending');
55
+ if (pending) {
56
+ const parsed = JSON.parse(pending);
57
+ if (Array.isArray(parsed) && parsed.length > 0) {
58
+ w.__tracelane__events.push(...parsed);
59
+ }
60
+ w.sessionStorage?.removeItem('__tracelane__pending');
61
+ }
62
+ }
63
+ catch {
64
+ // sessionStorage unavailable / parse failure — best-effort, ignore.
65
+ }
66
+ // Register the `pagehide` flush once per document. On teardown it stashes the
67
+ // live buffer (only post-last-drain events remain, since drain read-and-clears)
68
+ // into sessionStorage so the next document can merge it.
69
+ if (w.__tracelane__pagehideBound !== true && typeof w.addEventListener === 'function') {
70
+ w.__tracelane__pagehideBound = true;
71
+ w.addEventListener('pagehide', () => {
72
+ try {
73
+ const events = w.__tracelane__events ?? [];
74
+ if (events.length === 0)
75
+ return;
76
+ const json = JSON.stringify(events);
77
+ // Size guard: sessionStorage quota is ~5 MB; bail well under it rather
78
+ // than throw a QuotaExceededError mid-teardown.
79
+ if (json.length > 4_000_000)
80
+ return;
81
+ w.sessionStorage?.setItem('__tracelane__pending', json);
82
+ }
83
+ catch {
84
+ // private mode / quota / serialization failure — best-effort, ignore.
85
+ }
86
+ });
87
+ }
43
88
  if (w.rrweb !== undefined) {
44
89
  // Tear down any prior recorder before starting a fresh one (re-injection).
45
90
  if (typeof w.__tracelane__stop === 'function') {
@@ -1 +1 @@
1
- {"version":3,"file":"page-script.js","sourceRoot":"","sources":["../src/page-script.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH,6CAA6C;AAC7C,MAAM,CAAC,MAAM,8BAA8B,GAAyB;IAClE,KAAK,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC;IACvC,eAAe,EAAE,KAAK;IACtB,gBAAgB,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC,EAAE;CACpF,CAAC;AAaF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,mBAAmB,CACjC,UAAkB,EAClB,cAAoC,EACpC,cAAqC;IAErC,MAAM,CAAC,GAAG,MAYT,CAAC;IAEF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,8EAA8E;IAC9E,0DAA0D;IAC1D,IAAI,CAAC,CAAC,mBAAmB,KAAK,SAAS,IAAI,GAAG,GAAG,CAAC,CAAC,mBAAmB,GAAG,UAAU,EAAE,CAAC;QACpF,OAAO,CAAC,CAAC,sBAAsB,IAAI,CAAC,CAAC;IACvC,CAAC;IAED,CAAC,CAAC,mBAAmB,GAAG,GAAG,CAAC;IAC5B,CAAC,CAAC,sBAAsB,GAAG,CAAC,CAAC,CAAC,sBAAsB,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAC/D,CAAC,CAAC,mBAAmB,GAAG,CAAC,CAAC,mBAAmB,IAAI,EAAE,CAAC;IAEpD,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1B,2EAA2E;QAC3E,IAAI,OAAO,CAAC,CAAC,iBAAiB,KAAK,UAAU,EAAE,CAAC;YAC9C,IAAI,CAAC;gBACH,CAAC,CAAC,iBAAiB,EAAE,CAAC;YACxB,CAAC;YAAC,MAAM,CAAC;gBACP,uDAAuD;YACzD,CAAC;QACH,CAAC;QACD,MAAM,OAAO,GAAc,CAAC,CAAC,CAAC,KAAK,CAAC,sBAAsB,CAAC,cAAc,CAAC,CAAC,CAAC;QAC5E,IAAI,cAAc,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,KAAK,CAAC,sBAAsB,KAAK,UAAU,EAAE,CAAC;YACzF,yEAAyE;YACzE,4DAA4D;YAC5D,uCAAuC;YACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,sBAAsB,CAAC,cAAc,CAAC,CAAC,CAAC;QAC/D,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;YAC1B,IAAI,CAAC,KAAc;gBACjB,qEAAqE;gBACrE,+BAA+B;gBAC9B,CAAC,CAAC,mBAAiC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnD,CAAC;YACD,OAAO;SACR,CAAC,CAAC;QACH,CAAC,CAAC,iBAAiB,GAAG,OAAO,IAAI,KAAK,UAAU,CAAC,CAAC,CAAE,IAAmB,CAAC,CAAC,CAAC,SAAS,CAAC;IACtF,CAAC;IAED,OAAO,CAAC,CAAC,sBAAsB,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,CAAC,GAAG,MAAwD,CAAC;IACnE,MAAM,GAAG,GAAG,CAAC,CAAC,mBAAmB,IAAI,EAAE,CAAC;IACxC,CAAC,CAAC,mBAAmB,GAAG,EAAE,CAAC;IAC3B,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAW,EAAE,EAAU;IACxD,MAAM,CAAC,GAAG,MAET,CAAC;IACF,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,eAAe,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;AAClE,CAAC"}
1
+ {"version":3,"file":"page-script.js","sourceRoot":"","sources":["../src/page-script.ts"],"names":[],"mappings":"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"}
@@ -4,8 +4,14 @@ import { type Mode } from './mode.js';
4
4
  import { type ConsolePluginOptions, type NetworkPluginOptions } from './page-script.js';
5
5
  /** Default re-injection cooldown in ms (ADR-0006). */
6
6
  export declare const DEFAULT_COOLDOWN_MS = 250;
7
- /** Default Node-side poll interval in ms (ADR-0006). */
8
- export declare const DEFAULT_DRAIN_INTERVAL_MS = 5000;
7
+ /**
8
+ * Default Node-side poll interval in ms (ADR-0006). Kept short so events
9
+ * buffered on a document right before a hard navigation are drained before the
10
+ * navigation tears the page (and the in-page buffer) down. The `pagehide` flush
11
+ * in the init script is the belt-and-suspenders rescue for whatever the poll
12
+ * misses in the final window.
13
+ */
14
+ export declare const DEFAULT_DRAIN_INTERVAL_MS = 500;
9
15
  export interface RecorderOptions {
10
16
  /** The framework-agnostic driver (ADR-0004). */
11
17
  executor: BrowserExecutor;
@@ -15,7 +21,7 @@ export interface RecorderOptions {
15
21
  * is bundle-source-agnostic and never imports rrweb for in-page injection.
16
22
  */
17
23
  rrwebBundle: string;
18
- /** Node-side drain poll interval (default 5000). */
24
+ /** Node-side drain poll interval (default 500). */
19
25
  drainIntervalMs?: number;
20
26
  /** Re-injection cooldown guard (default 250). */
21
27
  cooldownMs?: number;
@@ -54,9 +60,10 @@ export interface Recorder {
54
60
  start(): Promise<void>;
55
61
  /**
56
62
  * Re-inject after a navigation (ADR-0006). The in-page cooldown guard
57
- * suppresses double-init on hash-only / HMR navigations; when a real re-init
58
- * takes effect (the monotonic session id advances) a `tracelane.nav` boundary
59
- * event is appended. Returns `true` if a re-init actually happened.
63
+ * suppresses double-init on hash-only / HMR navigations (init returns the `0`
64
+ * sentinel); when a real re-init takes effect (init returns a session id
65
+ * `>= 1`) a `tracelane.nav` boundary event is appended. Returns `true` if a
66
+ * re-init actually happened.
60
67
  */
61
68
  reinject(url: string): Promise<boolean>;
62
69
  /** Read+clear the page buffer, merge into the Node buffer, return the batch. */
@@ -1 +1 @@
1
- {"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../src/recorder.ts"],"names":[],"mappings":"AAAA,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,wDAAwD;AACxD,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAE9C,MAAM,WAAW,eAAe;IAC9B,gDAAgD;IAChD,QAAQ,EAAE,eAAe,CAAC;IAC1B;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,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;;;;;OAKG;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;CAC9B;AASD,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,QAAQ,CAiGjE"}
1
+ {"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../src/recorder.ts"],"names":[],"mappings":"AAAA,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;CAC9B;AASD,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,QAAQ,CAkGjE"}
package/dist/recorder.js CHANGED
@@ -2,8 +2,14 @@ import { resolveMode } from './mode.js';
2
2
  import { DEFAULT_CONSOLE_PLUGIN_OPTIONS, tracelaneDrainScript, tracelaneInitScript, tracelaneNavScript, } from './page-script.js';
3
3
  /** Default re-injection cooldown in ms (ADR-0006). */
4
4
  export const DEFAULT_COOLDOWN_MS = 250;
5
- /** Default Node-side poll interval in ms (ADR-0006). */
6
- export const DEFAULT_DRAIN_INTERVAL_MS = 5000;
5
+ /**
6
+ * Default Node-side poll interval in ms (ADR-0006). Kept short so events
7
+ * buffered on a document right before a hard navigation are drained before the
8
+ * navigation tears the page (and the in-page buffer) down. The `pagehide` flush
9
+ * in the init script is the belt-and-suspenders rescue for whatever the poll
10
+ * misses in the final window.
11
+ */
12
+ export const DEFAULT_DRAIN_INTERVAL_MS = 500;
7
13
  /** Inject + eval the rrweb bundle string in the page (defines `window.rrweb`). */
8
14
  function injectBundleScript(bundle) {
9
15
  // window.eval runs the bundle in global page scope (so `window.rrweb` becomes
@@ -15,28 +21,30 @@ export function createRecorder(options) {
15
21
  const buffer = [];
16
22
  let pollTimer;
17
23
  let started = false;
18
- // Last session id we've observed from the page; advances only when an init
19
- // actually takes effect (i.e. wasn't suppressed by the cooldown guard).
20
- let lastSessionId = 0;
21
- /** Run the init script in-page and return the active session id. */
24
+ /**
25
+ * Run the init script in-page. Returns the active session id: `0` means the
26
+ * in-page cooldown suppressed this init (a same-document hash/HMR re-render,
27
+ * no fresh recording started); `>= 1` means a recording actually (re)started.
28
+ * The in-page init is the authority — Node never tracks session ids itself,
29
+ * because the in-page id resets to 1 on every fresh document (a hard nav) and
30
+ * a Node-side monotonic counter would mis-classify post-first-nav loads as
31
+ * cooldown-suppressed.
32
+ */
22
33
  async function runInit() {
23
34
  return executor.execute(tracelaneInitScript, cooldownMs, consolePluginOptions, networkPluginOptions);
24
35
  }
25
36
  async function inject() {
26
37
  await executor.execute(injectBundleScript, rrwebBundle);
27
- lastSessionId = await runInit();
38
+ await runInit();
28
39
  }
29
40
  async function reinject(url) {
30
41
  // Re-eval the bundle (the page may have been torn down by navigation), then
31
- // re-run init. The cooldown guard inside the init script decides whether a
32
- // fresh recorder actually starts.
42
+ // re-run init. The init script's return value is the authority on whether a
43
+ // fresh recording started.
33
44
  await executor.execute(injectBundleScript, rrwebBundle);
34
- const sessionId = await runInit();
35
- if (sessionId <= lastSessionId) {
36
- // Suppressed by cooldown no navigation boundary to record.
37
- return false;
38
- }
39
- lastSessionId = sessionId;
45
+ const sid = await runInit();
46
+ if (sid === 0)
47
+ return false; // cooldown-suppressed (same-doc hash/HMR); no nav boundary
40
48
  await executor.execute(tracelaneNavScript, url, Date.now());
41
49
  return true;
42
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"recorder.js","sourceRoot":"","sources":["../src/recorder.ts"],"names":[],"mappings":"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"}
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.10",
3
+ "version": "0.1.0-alpha.12",
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",