$ rezi
Guides

Record and Replay

Repro bundles provide a stable schema for capturing deterministic replay inputs. In @rezi-ui/core, the current schema is rezi-repro-v1.

Repro bundles provide a stable schema for capturing deterministic replay inputs. In @rezi-ui/core, the current schema is rezi-repro-v1.

Record/replay helpers now include:

  • Versioned schema identifier
  • Capture configuration snapshot
  • Terminal capability snapshot
  • Deterministic timing model metadata
  • Deterministic event-capture batch payloads
  • Headless replay driver + assertion harness APIs

No API in this layer writes files.

Schema: rezi-repro-v1

Top-level required fields:

FieldTypeNotes
schema"rezi-repro-v1"Versioned schema id
captureConfigobjectCapture flags and bounds
capsSnapshotobjectTerminal + backend caps captured with the run
timingModelobjectDeterministic replay timing metadata
eventCaptureobjectCaptured backend event batches (bytesHex) and truncation metadata

captureConfig

FieldType
captureRawEventsboolean
captureDrawlistBytesboolean
maxEventBytesnumber (non-negative integer)
maxDrawlistBytesnumber (non-negative integer)
maxFramesnumber (non-negative integer)
fpsCapnumber (positive integer)
cursorProtocolVersion1 | 2

capsSnapshot

FieldType
terminalCapsTerminalCaps | null
backendCaps.maxEventBytesnumber (non-negative integer)
backendCaps.fpsCapnumber (positive integer)
backendCaps.cursorProtocolVersion1 | 2

timingModel

FieldTypeFixed value in v1
kindstring"deterministic"
clockstring"monotonic-ms"
replayStrategystring"recorded-delta"
timeUnitstring"ms"
baseTimeMsnumbernon-negative integer

Parse and Validate

Use the schema helpers before replay or transport:

import { parseReproBundleBytes, validateReproBundle } from "@rezi-ui/core";

const parsedFromBytes = parseReproBundleBytes(bundleBytes);
if (!parsedFromBytes.ok) {
  throw new Error(`${parsedFromBytes.error.code} at ${parsedFromBytes.error.path}`);
}

const validated = validateReproBundle(parsedFromBytes.value);
if (!validated.ok) {
  throw new Error(`${validated.error.code} at ${validated.error.path}`);
}

Errors include:

  • code: stable machine-readable code
  • path: JSON path for the failing field
  • detail: short deterministic message

Deterministic Serialization

Stable export helpers guarantee deterministic bytes for equivalent bundle content:

import {
  exportReproBundleBytes,
  serializeReproBundleStable,
  validateReproBundle,
} from "@rezi-ui/core";

const parsed = validateReproBundle(candidateBundle);
if (!parsed.ok) throw new Error(parsed.error.code);

const stableJson = serializeReproBundleStable(parsed.value);
const stableBytes = exportReproBundleBytes(parsed.value);

Ordering rules:

  • Object keys are serialized in lexicographic order.
  • Array element order is preserved.
  • undefined object fields are omitted.
  • undefined array items serialize as null.

Deterministic Headless Replay

Use the step-based replay driver to replay captured batches without a real terminal:

import { createReproReplayDriver, parseReproBundleBytes, ui } from "@rezi-ui/core";

const parsed = parseReproBundleBytes(bundleBytes);
if (!parsed.ok) throw new Error(parsed.error.code);

const driver = createReproReplayDriver({
  bundle: parsed.value,
  view: () => ui.input({ id: "name", value: "" }),
});

for (;;) {
  const step = driver.step();
  if (step.kind === "done") break;
  if (step.fatal) throw new Error(`${step.fatal.code}: ${step.fatal.detail}`);
}

const replay = driver.runToEnd();
console.log(replay.actions);

Run replay + assertions in one call with mismatch diagnostics:

import { runReproReplayHarness, ui } from "@rezi-ui/core";

const result = await runReproReplayHarness({
  bundle,
  view: () => ui.input({ id: "name", value: "" }),
  expectedActions: [{ id: "name", action: "input", value: "A", cursor: 1 }],
  invariants: { noFatal: true, noOverrun: true },
});

if (!result.pass) {
  for (const m of result.mismatches) {
    console.error(`${m.code} at ${m.path}: ${m.detail}`);
  }
}

Harness result fields:

  • status: "PASS" or "FAIL"
  • replay: actions, overruns, fatal (if any), and deterministic recorded elapsed time
  • mismatches: stable codes + JSON paths + expected/actual payloads

Versioning Behavior

  • rezi-repro-v1 is accepted by current helpers.
  • rezi-repro-vN (where N is not 1) fails with ZR_REPRO_UNSUPPORTED_VERSION.
  • Unknown fields fail with ZR_REPRO_UNKNOWN_FIELD for strict schema handling.

On this page