Tørrkjøringen fanget to ting: vault manglet i PACKAGES (så @shade/server feilet på en ukjent workspace-referanse), og jeg hadde innført en syklus storage-sqlite → vault → server → storage-sqlite. Den siste er løst ved at storage-sqlite bare bruker VaultStore som TYPE — flyttet til devDependencies, så det ikke er en runtime-avhengighet. vault står ved siden av inbox-server i lista: begge er i en syklus med server (de trenger verifyPayload, standalone.ts mounter rutene deres), og lista håndterer det allerede ved å liste server først. publish:dry: 26 pakket, 0 feilet. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@shade/transport-bridge
Transport-agnostic delivery for Shade: WS → SSE → long-poll, in priority
order, behind a single IncomingMessage interface.
import {
FallbackBridgeTransport,
WsBridge,
SseBridge,
LongPollBridge,
} from '@shade/transport-bridge';
const auth = { crypto, signingPrivateKey, address: 'bob' };
const bridge = new FallbackBridgeTransport([
new WsBridge({ baseUrl, auth }),
new SseBridge({ baseUrl, auth }),
new LongPollBridge({ baseUrl, auth }),
]);
await bridge.connect({
onMessage: (msg) => {
// msg: { from: string; bytes: Uint8Array; receivedAt: number; msgId?: string }
},
});
console.log(bridge.activeKind); // "ws" | "sse" | "long-poll"
Pair with createBridgeRoutes in @shade/inbox-server to expose the
matching /v1/bridge/{stream,poll,ws} endpoints. Full design + threat
model in docs/transport.md.
What it solves
Browser extensions, strict corporate proxies, and edge runtimes routinely block long-lived WebSockets. Apps that already use the Shade inbox shouldn't have to write three custom delivery paths to handle the realistic mix of hostile networks they ship into. This package is the canonical answer.
Status
V3.7. Stable wire format, additive change to @shade/inbox-server. See
CHANGELOG.