block / block/trailblaze

WASM hosted reports: embed network.ndjson into the bundle so the Network tab appears

Open
#125 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Kotlin
Stars
310
Forks
28
Avg merge
7h 45m
Merged PRs (30d)
8

Description

## Context

The Compose Multiplatform desktop app surfaces a "Network" tab in the bottom log panel for sessions that have a `/network.ndjson` artifact (captured by Playwright via `--capture-network`). The wiring lives in [`SessionLogsPanel`](https://github.com/block/trailblaze/blob/main/opensource/trailblaze-ui/src/commonMain/kotlin/xyz/block/trailblaze/ui/tabs/session/SessionLogsPanel.kt) + [`NetworkLogSource`](https://github.com/block/trailblaze/blob/main/opensource/trailblaze-ui/src/commonMain/kotlin/xyz/block/trailblaze/ui/tabs/session/NetworkLogSource.kt) and works on the JVM target — `loadNetworkLogs` reads the file from disk.

On the WASM target (hosted HTML reports generated by [`WasmReport`](https://github.com/block/trailblaze/blob/main/opensource/trailblaze-report/src/main/java/xyz/block/trailblaze/report/WasmReport.kt)) the `loadNetworkLogs` actual returns null today because the report bundle doesn't embed a `network_logs/` entry. The Network tab therefore never appears on hosted reports — it works only on the local desktop app.

The parallel `device_logs` codepath shows what the wiring should look like — see `WasmReport.kt` (the `device_logs:` block in `createCompressedDataBlock`) and the `index.html` dispatcher branch under `key.startsWith("device_logs/")`.

## Scope

Three small pieces, no new logic.

### 1. `WasmReport.kt` — accept and emit network logs

Add a `compressedNetworkLogs: Map = emptyMap()` parameter to `createCompressedDataBlock` and `writeCompressedDataBlock`, mirroring the existing `compressedDeviceLogs`. Emit a `network_logs: { … }` JSON block alongside the existing `device_logs` block in both functions.

### 2. `index.html` dispatcher — recognize the `network_logs/` key prefix

Add a branch alongside the existing device-logs lookup:

```js
else if (key.startsWith("network_logs/")) {
const sessionId = key.substring("network_logs/".length);
if (window.trailblaze_report_compressed.network_logs) {
compressedData = window.trailblaze_report_compressed.network_logs[sessionId];
}
}
```

### 3. Populate `compressedNetworkLogs` at the report-generation call site

Wherever `createCompressedDataBlock` / `writeCompressedDataBlock` is invoked with `compressedDeviceLogs` populated, do the same for `network.ndjson` files. Read `/network.ndjson` per session, JSON-encode the raw text the same way device logs are, and pass through the existing compression pipeline.

## Out of scope

- No changes to the JVM `loadNetworkLogs` actual — already works.
- No changes to the parser, panel, or schema.
- Body-file embedding (`bodies/req_.bin` and future `bodies/res_.bin`) is a separate decision — they're referenced from NDJSON via relative paths but aren't part of the NDJSON itself. Likely deferred until response-body capture lands.

## Why a separate issue

This is referenced from a TODO comment in `ActualsWasm.kt`'s `loadNetworkLogs` so a future maintainer hitting "no Network tab on the hosted report" can find it.

## Estimated diff

~30 LOC in `WasmReport.kt` + ~5 lines of JS in `index.html` + ~10 LOC in the call site that reads ndjson per session. Single PR.

Contributor guide

Open the contributing guide

Research direction

Start by comparing the device_logs handling in WasmReport.kt and the index.html dispatcher, then trace the loadNetworkLogs TODO in ActualsWasm.kt to the report-generation call site. Add network log embedding and dispatch for each session, and verify that a hosted WASM report with network.ndjson displays its Network tab while the JVM path remains unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, kotlin, wasm
Domain
frontend, web-dev
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.