Files
skills/docs/foundation/bitpacker/bitpacker-streaming/src/defaults/default-clock.md
2026-05-29 08:20:56 +01:00

2.2 KiB

defaultClock

(no submodules)

Purpose

defaultClock is the single point in @suaveplan/bitpacker-streaming where the wall clock is read. Every other module that needs a time reading either accepts a Clock from the caller or imports this default. Centralising the Date.now() call this way makes the package deterministic-by-default in tests (callers inject FakeClock) while the production hot path still reads the real wall clock.

This pattern matches the convention used by @suaveplan/bitpacker-network and @suaveplan/bitpacker-compressed. Suaveplan enforces a "no module-scope Date.now()/Math.random()" rule outside allow-listed defaults — this file is one of those allow-listed defaults.

Features

  • Single named export defaultClock: Clock typed via @suaveplan/types.
  • Pure function — no side effects beyond reading the wall clock.
  • Idiomatic Suaveplan convention for clock injection.

Usage: Basic Example

import { defaultClock } from "@suaveplan/bitpacker-streaming";

const now = defaultClock();

Usage: Advanced Example

import type { Clock } from "@suaveplan/types";
import { StreamingBitPacker } from "@suaveplan/bitpacker-streaming";

// In tests, inject a deterministic clock instead of the default.
const fakeClock: Clock = (() => {
    let t = 0;
    return () => {
        t += 100;
        return t;
    };
})();

const packer = new StreamingBitPacker({ x: 255 });
await packer.packStream({ x: 1 }, { clock: fakeClock });

API Reference

defaultClock: Clock

Returns the current wall-clock time in milliseconds (Date.now()).

Implementation Notes

The Clock type is () => number. suaveplan prefers function types over class instances for monotonic primitives because they are trivially serialisable, comparable, and substitutable in tests without dependency injection frameworks.

The reason this lives in defaults/ rather than as a static class member is the suaveplan lint rule that bans module-scope Date.now() calls in production code. By scoping the call to a single named, lint-allow-listed module, we keep the rest of the package free of static analysis exceptions.