Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 28 additions & 8 deletions app/src/sim/ui/framelog.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/// The frame inspector under the canvas. It merges the frame logs of every live
/// connection into one time-ordered list — a row per frame: connection (when
/// there is more than one), direction, kind, function, round-trip time (on the
/// reply, from its own request by id), byte length — expanding to the decoded
/// envelope, the framing name, and the raw bytes as hex or text. A gap in
/// *virtual* time over `IDLE_MS` inserts an `idle` separator. Every row kind and
/// every connection is filterable from the header. A refused connection gets its
/// own row. The pane's height is drag-resizable by its top grip.
/// connection into one time-ordered list under a labelled column header — a row
/// per frame: connection (when there is more than one), direction, kind,
/// function, round-trip time (on the reply, from its own request by id), byte
/// length — expanding to the decoded envelope, the framing name, and the raw
/// bytes as hex or text. A gap in *virtual* time over `IDLE_MS` inserts an
/// `idle` separator. Every row kind and every connection is filterable from the
/// header. A refused connection gets its own row. The pane's height is
/// drag-resizable by its top grip.
///
/// The engine is the `comline-simulator` wasm now: frames are polled from the
/// `Sim`, not pushed from a `Tap`. The view calls `poll()` after it advances the
Expand Down Expand Up @@ -168,9 +169,27 @@ export function frameLog(): FrameLog {
clear.textContent = "clear";
head.append(title, kindFilters, connFilters, clockBar, clear);

// column header — same grid as each row's `<summary>` (see the CSS)
const cols = document.createElement("div");
cols.className = "sim-frames-cols";
for (const [cls, label] of [
["frame-conn", "conn"],
["frame-seq", "#"],
["frame-dir", "direction"],
["frame-kind", "kind"],
["frame-fn", "fn"],
["frame-delta", "rtt"],
["frame-len", "bytes"],
] as const) {
const s = document.createElement("span");
s.className = cls;
s.textContent = label;
cols.append(s);
}

const list = document.createElement("div");
list.className = "sim-frames-list";
el.append(grip, head, list);
el.append(grip, head, cols, list);

let sources: LogSource[] = [];
let api: FrameSource = { frames: () => [], detail: () => null };
Expand Down Expand Up @@ -321,6 +340,7 @@ export function frameLog(): FrameLog {
sources = next;
api = next_api;
multi = next.length > 1;
cols.classList.toggle("has-conn", multi);
labelByConn.clear();
for (const s of next) labelByConn.set(s.connId, s.label);
renderConnFilters();
Expand Down
39 changes: 37 additions & 2 deletions app/src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -977,21 +977,53 @@ label.clock-btn {
stroke: var(--err);
stroke-dasharray: 3 3;
}
/* one grid template shared by the column header and every row's summary */
.sim-frames {
--frame-grid: 3ch minmax(6rem, auto) 4.5rem minmax(3rem, 1fr) 4.5rem 3.5rem;
--frame-grid-conn: 7rem 3ch minmax(6rem, auto) 4.5rem minmax(3rem, 1fr) 4.5rem 3.5rem;
}

.sim-frames-cols {
display: grid;
grid-template-columns: var(--frame-grid);
gap: 0.5rem;
align-items: baseline;
padding: 0.3rem 0.4rem;
font-size: 0.6rem;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--muted);
background: var(--bg-2);
border-bottom: 1px solid var(--border);
}
.sim-frames-cols.has-conn {
grid-template-columns: var(--frame-grid-conn);
}
.sim-frames-cols:not(.has-conn) .frame-conn {
display: none;
}
.sim-frames-cols > span {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

.frame-row {
border-bottom: 1px solid var(--border);
font-size: 0.72rem;
}
details.frame-row > summary {
display: grid;
grid-template-columns: 3ch minmax(6rem, 1fr) 5.5rem 5rem 5rem 4rem;
grid-template-columns: var(--frame-grid);
gap: 0.5rem;
align-items: baseline;
padding: 0.2rem 0.4rem;
cursor: pointer;
list-style: none;
}
details.frame-row.has-conn > summary {
grid-template-columns: 7rem 3ch minmax(6rem, 1fr) 5.5rem 5rem 5rem 4rem;
grid-template-columns: var(--frame-grid-conn);
}
.frame-conn {
color: var(--accent);
Expand Down Expand Up @@ -1022,6 +1054,9 @@ details.frame-row > summary > span {
.frame-row .frame-delta,
.frame-row .frame-len {
color: var(--muted);
}
.frame-delta,
.frame-len {
text-align: right;
}
.frame-handshake .frame-kind,
Expand Down
Loading