Files
skills/docs/networking/events/broadcast-channel/src/id/id.md
2026-05-29 08:20:56 +01:00

3.0 KiB

id/id

(no submodules)

Purpose

generateId is the shared 16-character lowercase-hex identifier generator used for tab IDs and per-message IDs throughout @suaveplan/broadcast-channel. The upstream library inlined two near-identical generate*Id helpers — pulling that into a single function with injectable Rng lets the channel core compute deterministic IDs in tests and resolves the enterprise-doc smell ("Two duplicate generateTabId / generateMsgId functions; should share via a local internal/id.ts").

The module also exports defaultRng, an Rng implementation backed by Web Crypto's getRandomValues. Browsers and modern Node / Bun all expose the global crypto object so defaultRng works in every supported runtime without any extra polyfill.

Features

  • Single helper for every ID the package produces.
  • Accepts any Rng (@suaveplan/types) — seeded RNGs make tests deterministic.
  • Honours optional rng.nextBytes when present (faster, fewer calls).
  • Pure-function fallback that derives 8 bytes from two nextUint32() calls.
  • Stable encoding: lowercase hex, fixed 16 characters, no separators.

Usage: Basic

import { defaultRng, generateId } from "@suaveplan/broadcast-channel";

const tabId = generateId(defaultRng);
// tabId === "a3f1c0...", 16 hex chars

Usage: Advanced

import { generateId } from "@suaveplan/broadcast-channel";
import type { Rng } from "@suaveplan/types";

function seededRng(values: readonly number[]): Rng {
    let i = 0;
    return {
        nextUint32: () => {
            const v = values[i % values.length] ?? 0;
            i++;
            return v >>> 0;
        },
        nextFloat() {
            return this.nextUint32() / 0x1_0000_0000;
        },
    };
}

const tabId = generateId(seededRng([0xdeadbeef, 0x01020304]));
// tabId === "deadbeef01020304"

API Reference

  • function generateId(rng: Rng): string — returns a 16-character hex string built from 8 random bytes drawn from rng. Uses rng.nextBytes(8) when available, otherwise two nextUint32() calls.
  • const defaultRng: Rng — Web-Crypto-backed RNG suitable for production browser code. Exposes nextUint32, nextFloat, and nextBytes.

Implementation Notes

When rng.nextBytes is not supplied, the helper packs two unsigned 32-bit words into an 8-byte buffer in big-endian order, then encodes each byte as a two-character zero-padded hex pair. The big-endian packing is deliberate: it makes the seeded-RNG test contract human-readable (0xdeadbeef → first 4 hex bytes deadbeef) and keeps the encoding stable if downstream code ever parses the ID back into bytes. The hex emission is the simplest two-character output that survives JSON / URL / localStorage transport without escaping. We avoid crypto.randomUUID() because the channel needs a fixed 16-hex shape for the leader-election sort to be deterministic and because randomUUID output is not available in every test sandbox.