first commit
This commit is contained in:
81
docs/persistence/cache/cache-storage/src/header/header.md
vendored
Normal file
81
docs/persistence/cache/cache-storage/src/header/header.md
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
# header
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## 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<typeof decodeHeader>;
|
||||
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.
|
||||
Reference in New Issue
Block a user