2.4 KiB
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.getRandomValuesdirectly, no Math.random fallback. - Pure synchronous return; no
Promiseoverhead 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.tsso the rest of the package never imports from a flat module.
Usage: Basic
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
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 ifglobalThis.crypto.getRandomValuesis 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.