# header _(no submodules)_ ## Purpose Defines the 32-byte fixed-width metadata header that `StorageCache` prepends to every cached value. The header carries `createdAt`, `expiresAt`, `flags`, and `hitCount` so the cache can recover TTL semantics over any byte-oriented `AbstractStorage` without a side-channel metadata API. Fixed width keeps reads single-range and avoids a second round-trip when the underlying store supports byte-range fetches. ## Features - 32 bytes, big-endian, deterministic layout — byte-identical between writers and readers across runtimes. - Two `u64` fields (`createdAt`, `expiresAt`) accommodate millisecond timestamps well past the year 10000. - One `u32` `flags` word carries codec selector bits (`FLAG_CODEC_JSON`) and a `FLAG_HAS_METADATA` presence bit reserved for downstream extensions. - One `u32` `hitCount` saturates at 2³² − 1 — informational only; not rewritten on read in this version. - 8 reserved bytes at the tail leave room for future extension without a version bump. - Bounds-checked `encodeHeader` — out-of-range fields surface as `StorageCacheError("CACHE_STORAGE.ENTRY_CORRUPT")` rather than producing a silently truncated blob. ## Usage: Basic Example ```ts import { decodeHeader, encodeHeader } from "@suaveplan/cache-storage/header"; const bytes = encodeHeader({ createdAt: Date.now(), expiresAt: 0, flags: 0, hitCount: 0, }); const meta = decodeHeader(bytes); ``` ## Usage: Advanced Example ```ts import { decodeHeader, encodeHeader, FLAG_CODEC_JSON, FLAG_HAS_METADATA, HEADER_BYTES, } from "@suaveplan/cache-storage/header"; function packEntry(value: Uint8Array, ttlMs: number): Uint8Array { const now = Date.now(); const head = encodeHeader({ createdAt: now, expiresAt: ttlMs > 0 ? now + ttlMs : 0, flags: FLAG_HAS_METADATA | FLAG_CODEC_JSON, hitCount: 0, }); const out = new Uint8Array(HEADER_BYTES + value.length); out.set(head, 0); out.set(value, HEADER_BYTES); return out; } function unpackEntry(blob: Uint8Array): { meta: ReturnType; body: Uint8Array; } { return { meta: decodeHeader(blob), body: blob.subarray(HEADER_BYTES) }; } ``` ## API Reference | Export | Kind | Purpose | | --- | --- | --- | | `HEADER_BYTES` | const number `32` | Fixed length of the metadata header. | | `HeaderMeta` | interface | `{ createdAt: number; expiresAt: number; flags: number; hitCount: number }`. | | `encodeHeader(meta)` | function | Returns a fresh 32-byte `Uint8Array`. Throws `StorageCacheError("CACHE_STORAGE.ENTRY_CORRUPT")` when any field is out of range. | | `decodeHeader(bytes)` | function | Parses the leading 32 bytes. Throws `StorageCacheError("CACHE_STORAGE.ENTRY_CORRUPT")` when the buffer is shorter. | | `FLAG_HAS_METADATA` | const number | Bit 0 — set by `StorageCache` on every encode. | | `FLAG_CODEC_JSON` | const number | Bit 1 — set when the body was produced by `JsonCodec` (for future routing). | ## Implementation Notes `u64` values are split into two `u32` big-endian writes (`high * 2³² + low`) so the encoder runs without `BigInt` overhead. `decodeHeader` is the inverse. The reserved 8 bytes at offset 24..31 are zeroed at encode time to keep on-disk parity bytewise stable; future versions may stuff version markers there without breaking forward decoders that mask the field.