You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 0883c25
Browse filesBrowse the repository at this point in the historyBrowse files
The planned trace query MCP server (#493) needs to parse trace zips, and
depending on backend for that would pull Fastify, the dashboard bundle and
the rerun spawner into its install. The reader imports only shared and
trace, so it moves to trace, which now owns the format in both directions.
readTraceZip moves with parseTraceZip because trace already does the
matching disk write and both backend and the MCP package read from disk.
The reader stays out of trace's index, so core and the adapters never
inline it. No behaviour change: backend imports it by subpath.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@@ -55,9 +55,9 @@ Imports from: nothing. Imported by: every other package.
55
55
56
56
### `packages/trace`
57
57
58
-
Trace-format transforms: captured events in, `trace.zip` out. Workspace-internal; inlined into each consumer at build time.
58
+
Trace-format transforms: captured events in, `trace.zip` out, and a `trace.zip` back into a player payload. Workspace-internal; inlined into each consumer at build time.
59
59
60
-
Split out of `core` because **two layers need it and only one of them may import `core`**. Adapters build their own trace through `core`; the backend builds one on behalf of an adapter that cannot run Node-side trace code (the Python adapter), and §2.2 bars the backend from `core`. Everything here is a pure transform over `shared` types — no framework API, no driver, no capture, no I/O beyond writing the zip.
60
+
Split out of `core` because **two layers need it and only one of them may import `core`**. Adapters build their own trace through `core`; the backend builds one on behalf of an adapter that cannot run Node-side trace code (the Python adapter), and §2.2 bars the backend from `core`. Everything here is a pure transform over `shared` types — no framework API, no driver, no capture, no I/O beyond writing and reading the zip.
-`parseTraceZip` / `readTraceZip` (`trace-reader.ts` and its `trace-reader-*` siblings) — the reverse direction: a `trace.zip`, ours or a foreign one, back into the `TracePlayerData` the player renders. Imported by subpath (`@wdio/devtools-trace/trace-reader`) and kept out of the package index, so adapters that reach `trace` through `core` never inline it.
70
71
71
72
Imports from: `shared`. Imported by: `core` (which re-exports it, so adapters reach it unchanged) and `backend`.
72
73
@@ -274,7 +275,7 @@ The repo has converged on a clear ownership story. When in doubt, the top-down d
274
275
275
276
- A type, constant, enum, schema, or contract used by more than one package → **`shared`**.
276
277
- Capture, parsing, normalization, sourcemap, UID, reporter, screencast, or WS-framing logic that doesn't depend on a specific framework's API → **`core`**.
277
-
- A pure transform that turns captured events into trace-zip content → **`trace`**. The test is whether the backend would ever need it: it builds traces for adapters that can't, and it may not import `core`.
278
+
- A pure transform that turns captured events into trace-zip content, or a zip back into a player payload → **`trace`**. The test is whether the backend would ever need it: it builds traces for adapters that can't, and it may not import `core`.
278
279
- A specific framework's hook, driver patch, or runner integration → the matching **adapter** package. Adapter code calls `core` for the actual work and only owns the hook registration.
279
280
- A backend HTTP route, WS handler, or rerun behavior → **`backend`**, with the contract added to `shared` first.
Copy file name to clipboardExpand all lines: CLAUDE.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -81,11 +81,11 @@ Some helpers are framework-agnostic by nature but used in only one adapter today
81
81
82
82
### Trace-format transforms live in `trace`, one layer below `core`
83
83
84
-
`packages/trace` holds the pure transforms that turn captured events into trace-zip content — the zip writer, action events, group paths, frame snapshots, mutations, HAR, sources, transcript. `core` keeps the adapter-side *orchestration and policy* that calls them: `trace-finalizer`, `spec-trace-helpers`, `trace-retention`.
84
+
`packages/trace` holds the pure transforms that turn captured events into trace-zip content — the zip writer, action events, group paths, frame snapshots, mutations, HAR, sources, transcript — and the reader that turns a zip back into a player payload (`trace-reader.ts`), so the format has one owner in both directions. `core` keeps the adapter-side *orchestration and policy* that calls them: `trace-finalizer`, `spec-trace-helpers`, `trace-retention`.
85
85
86
86
The split is not aesthetic. **`backend` may not import `core`** (it would pull framework-adapter logic into the server), but it does need to build a trace on behalf of an adapter that can't — the Python adapter ships no Node. `trace` is the layer both can reach, so it may import `shared` and nothing else; a single import of `core` from it re-creates the cycle the split exists to remove, and ESLint enforces that.
87
87
88
-
The test for a new helper: *would the backend ever need this to build a zip?* If yes, `trace`. If it needs a driver, a framework hook, or a capture session, `core`.
88
+
The test for a new helper: *would the backend ever need this to build or read a zip?* If yes, `trace`. If it needs a driver, a framework hook, or a capture session, `core`.
Copy file name to clipboardExpand all lines: packages/backend/README.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,7 +9,7 @@ The server that the three adapter packages connect to and the dashboard UI talks
9
9
-**Baseline store** (in-memory) — captures a snapshot of a failing test attempt, plus per-uid metadata, so the "Preserve & Rerun" flow can show a side-by-side diff.
10
10
-**Rerun spawner** (`runner.ts`) — spawns the user's `wdio` / `nightwatch` / `selenium` binary with rerun filters built from the dashboard's payload.
11
11
-**Worker-message handler** — dispatches messages from spawned workers (config path, session id, video path, ...).
12
-
-**Trace serving** (`show-trace.ts`, `trace-reader.ts`) — reconstructs a recorded `trace.zip` and boots the server in a read-only **trace-serve** mode that backs the DevTools UI's trace player. No worker connects in this mode.
12
+
-**Trace serving** (`show-trace.ts`, with the reader from `@wdio/devtools-trace`) — reconstructs a recorded `trace.zip` and boots the server in a read-only **trace-serve** mode that backs the DevTools UI's trace player. No worker connects in this mode.
13
13
14
14
## Framework awareness
15
15
@@ -27,7 +27,7 @@ Trace mode (see the [root README](../../README.md#-trace-mode-tracezip)) writes
27
27
28
28
The same entry is shipped as a `show-trace`**bin** by the backend (`./dist/show-trace.js`) and by each adapter (`@wdio/devtools-service`, `@wdio/selenium-devtools`, `@wdio/nightwatch-devtools` each ship a thin `bin/show-trace.mjs`), so `npx show-trace <trace.zip>` works in any project that installs an adapter — backend need only be a transitive dependency. In trace-serve mode `start({ trace })` exposes the reconstructed payload at `TRACE_API.get` and skips the worker/rerun machinery. It is one of the backend's two bins; the other, `devtools-backend` (`./dist/server.js`), starts the live dashboard server described under [Public API](#public-api).
29
29
30
-
-**Reader** (`src/trace-reader.ts`, with sibling `trace-reader-{constants,types,utils,groups}.ts`) — `parseTraceZip` / `readTraceZip` reconstruct a `TracePlayerData` payload from the archive. It accepts this repo's own exporter output **and foreign zips** written by other tools (every `.trace` entry is an action-event stream, every `.network` a HAR stream, `.stacks` sidecars carry call stacks). It rebuilds:
30
+
-**Reader** (`packages/trace/src/trace-reader.ts`, with sibling `trace-reader-{constants,types,utils,groups}.ts`) — `parseTraceZip` / `readTraceZip` reconstruct a `TracePlayerData` payload from the archive. It accepts this repo's own exporter output **and foreign zips** written by other tools (every `.trace` entry is an action-event stream, every `.network` a HAR stream, `.stacks` sidecars carry call stacks). It rebuilds:
31
31
-**commands** — from `before`/`after` action events, with call source, result, error, nearest screenshot frame, and pointer hit point;
32
32
-**DOM mutations** — from the `.mutations` NDJSON stream (drives the player's DOM time-travel);
33
33
-**network** — HAR entries from `.network` streams;
Copy file name to clipboardExpand all lines: packages/trace/package.json
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -3,7 +3,7 @@
3
3
"version": "1.0.0",
4
4
"private": true,
5
5
"author": "Vishnu Vardhan",
6
-
"description": "Trace-format transforms — turns captured events into the trace zip. Split out of core so the backend can build a trace for adapters that cannot (CLAUDE.md §2.2 bars backend from core). Workspace-internal, never published — code is inlined into each consuming package at build time.",
6
+
"description": "Trace-format transforms — turns captured events into the trace zip and reads a zip back into a player payload. Split out of core so the backend can build a trace for adapters that cannot (CLAUDE.md §2.2 bars backend from core). Workspace-internal, never published — code is inlined into each consuming package at build time.",
0 commit comments