egutierrez c142b3a025 feat(uniweb): room history client (fetchHistory + BusClient.history)
NATS delivers live only, so reloading the page lost a room's history. Add the
client half of the new history endpoint:

- ControlPlane.fetchHistory(roomID, limit): signed GET /rooms/{id}/history?limit=N,
  decoding each base64-std frame to the raw bytes the live subscription delivers.
- BusClient.history(roomID, limit): opens each replayed frame (verify + decrypt)
  exactly like subscribe, dropping any that fail, oldest -> newest.
- Extract BusClient.openFrame as the shared envelope-opening core for subscribe
  and history (no duplication; subscribe behavior unchanged).
- ulidTime(id): decode the ms-epoch a ULID encodes in its first 10 Crockford
  chars (inverse of newULID), so a frame's timestamp comes from its id (the wire
  carries none). Covered by ulid.test.ts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 19:39:57 +02:00
S
Description
Synced from fn_registry
327 KiB
Languages
TypeScript 99.6%
JavaScript 0.2%
HTML 0.2%