2.9 KiB
runtime
(no submodules)
Purpose
runtime.ts centralises the three injectable platform primitives
(Clock, MonotonicClock, Rng) that every production path in
@suaveplan/packer-browser reads time and randomness through. Direct
Date.now(), Math.random(), and performance.now() calls are banned
outside this file so seeded-deterministic tests can pin every
observable behaviour. The shape mirrors @suaveplan/packer/runtime, so
adopters that already inject runtime into the packer get the same
contract here.
Features
defaultClock/defaultMonotonicClock/defaultRng— wall-clock and CSPRNG defaults wired to the platform globals.resolveRuntime(opts?)— merges caller-suppliedRuntimeOptionsagainst the platform defaults to produce a fully-populatedPackerBrowserRuntimebundle.elapsedMs(monotonicClock, startNanos)— convenience for the histogram observation sites that previously didperformance.now() - startdirectly.- Adapter that upgrades a seeded
RnglackingnextBytesinto the runtime-shape RNG by deriving bytes fromnextUint32, so tests can inject@suaveplan/testing'sseededRng()unchanged.
Usage: Basic
import { resolveRuntime } from "@suaveplan/packer-browser";
const runtime = resolveRuntime();
const now = runtime.clock(); // ms since epoch
const seed = runtime.rng.nextBytes(16); // CSPRNG bytes
Usage: Advanced
import { FakeClock, seededRng } from "@suaveplan/testing";
import { resolveRuntime } from "@suaveplan/packer-browser";
const clock = new FakeClock({ now: 1_700_000_000_000 });
const runtime = resolveRuntime({
clock: () => clock.now(),
rng: seededRng(42),
});
// runtime.clock() returns 1_700_000_000_000 until FakeClock is advanced
API Reference
defaultClock: Clock—() => Date.now().defaultMonotonicClock: MonotonicClock— wrapsperformance.now(), returns nanoseconds asbigint.defaultRng: Required<Pick<Rng, "nextBytes">> & Rng— CSPRNG bound toglobalThis.crypto.resolveRuntime(opts?: RuntimeOptions): PackerBrowserRuntime— fills in defaults for absent fields.elapsedMs(monotonicClock, startNanos: bigint): number— returns elapsed milliseconds as a float.RuntimeOptions/PackerBrowserRuntime— option / resolved bundles.
Implementation Notes
Monotonic time is exposed as bigint nanoseconds even though most
consumers ultimately reduce to millisecond floats. The bigint
discipline prevents accidental rounding when sampling the clock at
nanosecond precision; the elapsedMs helper exists so call sites that
need the float form never reach for performance.now() directly.
nextBytes is part of the resolved RNG shape because the upcoming
Cluster B encrypted-archive keyring needs CSPRNG bytes and the manager
will forward the resolved RNG to it.