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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ and this project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html)

## [Unreleased]

### Fixed

- **Cache sizes say they are bytes.** The Drivers tab, the engine counters, a driver's status and the
Architecture view's tooltip showed a driver's cache as a bare number, such as `465`. That reads as 465
queued events, but the engine reports the size in bytes; 465 bytes was two events. They now read
`465 bytes`. **view** beside the size still lists and counts the events.

## [0.85.0] - 2026-11-02

Needs DirXMLDev 0.62.0.
Expand Down
3 changes: 2 additions & 1 deletion web/src/components/ArchitectureView.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useEffect, useMemo, useRef, useState } from "react";
import { api } from "../api";
import { EnvPicker, useEnvironment } from "../env";
import { cacheBytes } from "../drivers";
import type { ArchApplication, Architecture, DriverState, Selection } from "../types";

/**
Expand Down Expand Up @@ -275,7 +276,7 @@ export function ArchitectureView({ revision, onSelect }: { revision: string; onS
const midX = (fromX + toX) / 2;
const vaultY = Math.min(Math.max(cy, st0.y + 24), st0.y + st0.h - 24);
const st = states?.[a.driver];
const tip = `${a.driver}${a.vaultOnly ? " (serves the vault, no external system)" : ""}\n${a.shimClass ?? "no shim class"}\n${a.counts.policies} policies · ${a.counts.entitlements} entitlements · ${a.counts.resources} resources${a.counts.forms + a.counts.prds > 0 ? ` · ${a.counts.forms} forms · ${a.counts.prds} PRDs` : ""}${st ? `\n${st.state}${st.cacheSize ? ` · cache ${st.cacheSize}` : ""}` : ""}`;
const tip = `${a.driver}${a.vaultOnly ? " (serves the vault, no external system)" : ""}\n${a.shimClass ?? "no shim class"}\n${a.counts.policies} policies · ${a.counts.entitlements} entitlements · ${a.counts.resources} resources${a.counts.forms + a.counts.prds > 0 ? ` · ${a.counts.forms} forms · ${a.counts.prds} PRDs` : ""}${st ? `\n${st.state}${st.cacheSize ? ` · cache ${cacheBytes(st.cacheSize)}` : ""}` : ""}`;
return (
<g key={a.driver}>
<path className="arch-conn" d={`M${fromX},${cy} C${midX},${cy} ${midX},${vaultY} ${toX},${vaultY}`} />
Expand Down
9 changes: 5 additions & 4 deletions web/src/components/VaultView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Fragment, useEffect, useRef, useState } from "react";
import { ApiError, GIT_CHANGED, api } from "../api";
import { EnvPicker, useEnvironment } from "../env";
import { CachePanel } from "./CachePanel";
import { cacheBytes } from "../drivers";
import { EventsView } from "./EventsView";
import { TraceViewer } from "./TraceViewer";
import { CaptureSteps, ProductionCheck } from "./ProductionCheck";
Expand Down Expand Up @@ -1134,7 +1135,7 @@ function Drivers({ env, onFix, onSelect, onSaved }: { env: string; onFix: () =>
</button>
</td>
<td className="nowrap">
{d.cacheSize ?? ""}{" "}
{cacheBytes(d.cacheSize)}{" "}
<button className="mini" onClick={() => setCacheOf(cacheOf === d.name ? null : d.name)} title="The queued events: view them, save them as a simulator case, clear the cache" data-testid={"cache-view-" + d.name}>
{cacheOf === d.name ? "hide" : "view"}
</button>
Expand Down Expand Up @@ -1228,8 +1229,8 @@ function EngineStrip({ env }: { env: string }) {
{data.stats.drivers.map((d) => (
<tr key={d.name}>
<td>{d.name}</td>
<td>{d.cacheSize}</td>
<td>{d.unprocessedSize}</td>
<td>{cacheBytes(d.cacheSize)}</td>
<td>{cacheBytes(d.unprocessedSize)}</td>
<td>{d.reportedEvents}</td>
<td>{d.commands}</td>
</tr>
Expand Down Expand Up @@ -1326,7 +1327,7 @@ function DriverManagePanel({ env, driver, armed, confirm, onSelect, onClose }: {
<tbody>
<tr><td>DN</td><td className="small"><code>{status.dn}</code></td></tr>
<tr><td>State</td><td>{status.state} · start option {status.startOption}</td></tr>
<tr><td>Cache</td><td>{status.cacheSize} · unprocessed {status.unprocessedSize}</td></tr>
<tr><td>Cache</td><td>{cacheBytes(status.cacheSize)} · unprocessed {cacheBytes(status.unprocessedSize)}</td></tr>
<tr><td>Trace</td><td>level {status.traceLevel ?? "-"} · file {status.traceFile || "-"}</td></tr>
<tr><td>Named passwords</td><td className="small">{(status.namedPasswords ?? []).length === 0 ? <span className="muted">none</span> : (status.namedPasswords ?? []).join(", ")}</td></tr>
</tbody>
Expand Down
14 changes: 14 additions & 0 deletions web/src/drivers.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { describe, expect, it } from "vitest";
import { cacheBytes } from "./drivers";

describe("cacheBytes", () => {
it("gives the engine's cache size its unit", () => {
expect(cacheBytes("465")).toBe("465 bytes");
expect(cacheBytes(0)).toBe("0 bytes");
});
it("leaves what isn't a size alone", () => {
expect(cacheBytes("?")).toBe("?");
expect(cacheBytes(undefined)).toBe("");
expect(cacheBytes("")).toBe("");
});
});
9 changes: 9 additions & 0 deletions web/src/drivers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,12 @@ export function isUserApplication(d: { shimClass?: string | null; forms?: unknow
export function userApplicationDrivers(drivers: DriverOutline[]): DriverOutline[] {
return drivers.filter(isUserApplication);
}

/**
* A driver's cache size as the engine reports it, with its unit: bytes, not a count of events (viewing the
* cache counts them). 465 bytes was two events on a test vault. Anything that isn't a number shows as it is.
*/
export function cacheBytes(size: string | number | null | undefined): string {
if (size === null || size === undefined || size === "") return "";
return /^\d+$/.test(String(size)) ? `${size} bytes` : String(size);
}
Loading