release(v4.3.0): browser persistence via @shade/storage-indexeddb
Ship an official IndexedDB-backed StorageProvider so browser-based Shade
consumers persist identity, prekeys, sessions, retired identities,
peer-verification state and stream-resume rows across tab refresh and
browser restart. Closes the gap that forced browser apps onto
storage:"memory" (regenerated identity each load, orphaned device
records server-side).
- New package @shade/storage-indexeddb (4.3.0): full StorageProvider
conformance, schema v1, idb-backed; bumpPeerIdentityVersion is wrapped
in a single readwrite IDB transaction (atomic, vs SQLite's
read-then-upsert race).
- @shade/sdk resolveStorage() accepts { type: 'indexeddb', dbName? } via
dynamic import (lazy, optional dep — same pattern as
@shade/storage-postgres). Named StorageSpec type now reused by
ResolvedConfig.
- Tests: 16 new tests in shade-storage-indexeddb (StorageProvider
surface + peer-verifications + full E2EE conversation surviving a
simulated tab reload). Run on fake-indexeddb.
- Lockstep version bump 4.2.1 → 4.3.0 across all 25 packages.
- Publish scripts updated to include the new package.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
53
CHANGELOG.md
53
CHANGELOG.md
@@ -5,6 +5,59 @@ All notable changes to Shade are documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [4.3.0] — 2026-05-05 — Browser persistence via `@shade/storage-indexeddb`
|
||||
|
||||
Browser-based Shade consumers had no path to session persistence: the only
|
||||
storage option that worked outside Node was `"memory"`, so the identity
|
||||
keypair regenerated on every page load and `device:${registrationId}`
|
||||
churned to a fresh address each refresh. Building a `StorageProvider`
|
||||
in consumer-land meant 25+ method re-implementations per app and no
|
||||
shared conformance surface.
|
||||
|
||||
`4.3.0` ships an official IndexedDB adapter alongside SQLite and Postgres
|
||||
so any browser-based Shade SDK consumer (dashboards, contact-list apps,
|
||||
browser-extension messengers) gets persistent identity, prekeys, sessions,
|
||||
retired identities, peer-verification state and stream-resume rows for
|
||||
free, surviving tab refresh and browser restart.
|
||||
|
||||
### Added
|
||||
|
||||
#### `@shade/storage-indexeddb` (new package)
|
||||
- `IndexedDBStorage.create({ dbName? })` — async open of an IDB
|
||||
database (one object store per `StorageProvider` category) with
|
||||
schema version 1. `dbName` defaults to `"shade"`; consumers that
|
||||
run multiple Shade-backed apps on the same origin pass distinct
|
||||
names (`"my-app-shade"`) so the IDB inspector groups them sensibly.
|
||||
- Full `StorageProvider` conformance: identity, signed/one-time prekeys,
|
||||
sessions, trusted identities, retired identities (with prune by
|
||||
`retiredAt`), stream-state save/get/list/prune, peer verifications,
|
||||
and the per-peer identity-version counter.
|
||||
- `bumpPeerIdentityVersion` is wrapped in a single IDB `readwrite`
|
||||
transaction — atomic read-modify-write, closing the race window the
|
||||
SQLite adapter currently has on parallel `acceptIdentityChange`
|
||||
calls. (SQL adapters will be brought in line in a follow-up.)
|
||||
- Implementation dependency: `idb` (Jake Archibald's typed wrapper).
|
||||
Tests run against `fake-indexeddb` for parity with the SQLite test
|
||||
layout.
|
||||
|
||||
#### `@shade/sdk`
|
||||
- `resolveStorage()` accepts a fourth spec form:
|
||||
`{ type: 'indexeddb', dbName?: string }`. Resolution goes through
|
||||
a dynamic import so Node-only consumers don't pull a browser-only
|
||||
adapter into their bundle (same pattern as `@shade/storage-postgres`).
|
||||
- `ShadeConfig['storage']` now exports a named `StorageSpec` type
|
||||
reused by `ResolvedConfig`, replacing the duplicated inline union.
|
||||
|
||||
### Tests
|
||||
- `packages/shade-storage-indexeddb/tests/indexeddb-storage.test.ts` —
|
||||
full StorageProvider surface (identity, prekeys, sessions, trust,
|
||||
retired identities, persistence across close+reopen) plus an end-to-end
|
||||
`ShadeSessionManager` conversation that survives a simulated tab
|
||||
reload mid-session.
|
||||
- `packages/shade-storage-indexeddb/tests/peer-verifications.test.ts` —
|
||||
CRUD round-trip, upsert-on-duplicate, identity-version increment
|
||||
invariants, persistence across reopen.
|
||||
|
||||
## [4.2.1] — 2026-05-04 — Concurrent-ratchet desync under pull-mode drainer
|
||||
|
||||
A consumer running `shade.files.httpClient(server, { outboundQueueUrl, ... })`
|
||||
|
||||
Reference in New Issue
Block a user