# `id.ts` _(no submodules)_ ## Purpose Internal cryptographically-random ID generator shared by the analytics tracker, the session manager, and any consumer that injects a default `IdGenerator`. Centralising the implementation removes the duplicate `generateId()` that lived in both `tracker.ts` and `session.ts` upstream and guarantees that anonymous IDs, event IDs, and session IDs share a single entropy source. The output is a 32-character hex string drawn from `crypto.getRandomValues`, suitable for use as a public identifier without leaking host state. ## Features - Single source of randomness — `globalThis.crypto.getRandomValues` directly, no Math.random fallback. - Pure synchronous return; no `Promise` overhead on the hot path. - Hex-encoded so the ID is URL-safe, log-safe, and 1:1 with the byte length (16 bytes → 32 chars). - Re-exported through `src/internal/id/index.ts` so the rest of the package never imports from a flat module. ## Usage: Basic ```ts import { generateId } from "@suaveplan/analytics-browser/tracker"; // ↑ generateId is internal; in tests / docs import from the barrel that // happens to re-export it. Production code typically lets the tracker // default-construct its own IDs. const anonymousId = generateId(); ``` ## Usage: Advanced ```ts import type { IdGenerator } from "@suaveplan/types"; import { generateId } from "./internal/id/id.js"; // Wrap the function-shape IdGenerator from @suaveplan/types around the // shared implementation — useful when a downstream consumer wants to // inject a deterministic counter in tests. const realIds: IdGenerator = generateId; const fakeIds: IdGenerator = (() => { let n = 0; return () => `evt-${(++n).toString().padStart(32, "0")}`; })(); ``` ## API Reference - `generateId(): string` — returns a fresh 32-character lowercase hex string. Throws synchronously only if `globalThis.crypto.getRandomValues` is missing or throws (e.g. when the host crypto API is intentionally disabled). ## Implementation Notes The 16-byte entropy budget gives 128 bits — the same size as a UUIDv4 — without the dash separators or version nibbles. Hex encoding is the simplest reversible representation and is cheap (~16 string concatenations) compared with base32 or base64. The byte length lives in `constants/index.ts` so a future opt-in to 24-byte IDs is a one-line constant change rather than a refactor across call sites.