@tracelane/core 0.1.0-alpha.11 → 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/page-script.d.ts +7 -6
- package/dist/page-script.d.ts.map +1 -1
- package/dist/page-script.js +53 -8
- package/dist/page-script.js.map +1 -1
- package/dist/recorder.d.ts +13 -6
- package/dist/recorder.d.ts.map +1 -1
- package/dist/recorder.js +23 -15
- package/dist/recorder.js.map +1 -1
- package/package.json +1 -1
package/dist/page-script.d.ts
CHANGED
|
@@ -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).
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
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
|
|
40
|
-
*
|
|
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
|
|
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"}
|
package/dist/page-script.js
CHANGED
|
@@ -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).
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
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
|
|
24
|
-
*
|
|
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
|
|
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') {
|
package/dist/page-script.js.map
CHANGED
|
@@ -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
|
|
1
|
+
{"version":3,"file":"page-script.js","sourceRoot":"","sources":["../src/page-script.ts"],"names":[],"mappings":"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"}
|
package/dist/recorder.d.ts
CHANGED
|
@@ -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
|
-
/**
|
|
8
|
-
|
|
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
|
|
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
|
|
58
|
-
* takes effect (
|
|
59
|
-
* event is appended. Returns `true` if a
|
|
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. */
|
package/dist/recorder.d.ts.map
CHANGED
|
@@ -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
|
|
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
|
-
/**
|
|
6
|
-
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
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
|
|
32
|
-
// fresh
|
|
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
|
|
35
|
-
if (
|
|
36
|
-
|
|
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
|
}
|
package/dist/recorder.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recorder.js","sourceRoot":"","sources":["../src/recorder.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,WAAW,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAEL,8BAA8B,EAE9B,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAE1B,sDAAsD;AACtD,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AACvC
|
|
1
|
+
{"version":3,"file":"recorder.js","sourceRoot":"","sources":["../src/recorder.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,WAAW,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAEL,8BAA8B,EAE9B,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAE1B,sDAAsD;AACtD,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AACvC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,CAAC;AA2E7C,kFAAkF;AAClF,SAAS,kBAAkB,CAAC,MAAc;IACxC,8EAA8E;IAC9E,gFAAgF;IAC/E,MAAsD,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAwB;IACrD,MAAM,EACJ,QAAQ,EACR,WAAW,EACX,eAAe,GAAG,yBAAyB,EAC3C,UAAU,GAAG,mBAAmB,EAChC,oBAAoB,GAAG,8BAA8B,EACrD,oBAAoB,EACpB,IAAI,EAAE,UAAU,GACjB,GAAG,OAAO,CAAC;IAEZ,MAAM,MAAM,GAAoB,EAAE,CAAC;IACnC,IAAI,SAAqD,CAAC;IAC1D,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB;;;;;;;;OAQG;IACH,KAAK,UAAU,OAAO;QACpB,OAAO,QAAQ,CAAC,OAAO,CACrB,mBAAqD,EACrD,UAAU,EACV,oBAAoB,EACpB,oBAAoB,CACrB,CAAC;IACJ,CAAC;IAED,KAAK,UAAU,MAAM;QACnB,MAAM,QAAQ,CAAC,OAAO,CAAC,kBAAkD,EAAE,WAAW,CAAC,CAAC;QACxF,MAAM,OAAO,EAAE,CAAC;IAClB,CAAC;IAED,KAAK,UAAU,QAAQ,CAAC,GAAW;QACjC,4EAA4E;QAC5E,4EAA4E;QAC5E,2BAA2B;QAC3B,MAAM,QAAQ,CAAC,OAAO,CAAC,kBAAkD,EAAE,WAAW,CAAC,CAAC;QACxF,MAAM,GAAG,GAAG,MAAM,OAAO,EAAE,CAAC;QAC5B,IAAI,GAAG,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC,CAAC,2DAA2D;QACxF,MAAM,QAAQ,CAAC,OAAO,CAAC,kBAAkD,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC5F,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,UAAU,KAAK;QAClB,MAAM,KAAK,GAAG,CAAC,MAAM,QAAQ,CAAC,OAAO,CACnC,oBAAyD,CAC1D,CAAuC,CAAC;QACzC,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;YACtB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,KAAK,UAAU,KAAK;QAClB,IAAI,OAAO;YAAE,OAAO;QACpB,OAAO,GAAG,IAAI,CAAC;QACf,MAAM,MAAM,EAAE,CAAC;QACf,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;YAC3B,KAAK,KAAK,EAAE,CAAC;QACf,CAAC,EAAE,eAAe,CAAC,CAAC;IACtB,CAAC;IAED,KAAK,UAAU,IAAI;QACjB,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,aAAa,CAAC,SAAS,CAAC,CAAC;YACzB,SAAS,GAAG,SAAS,CAAC;QACxB,CAAC;QACD,OAAO,GAAG,KAAK,CAAC;QAChB,MAAM,KAAK,EAAE,CAAC;IAChB,CAAC;IAED,KAAK,UAAU,QAAQ,CAAC,OAAoB;QAC1C,MAAM,IAAI,EAAE,CAAC;QACb,MAAM,IAAI,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;QACrC,MAAM,iBAAiB,GAAG,IAAI,KAAK,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QAC5D,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACvB,wEAAwE;YACxE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;YAClB,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QAClD,CAAC;QACD,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IACrD,CAAC;IAED,OAAO;QACL,KAAK;QACL,QAAQ;QACR,KAAK;QACL,IAAI;QACJ,QAAQ;QACR,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM;KACxB,CAAC;AACJ,CAAC"}
|
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.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",
|