Writing a framework adapter
Bridge HydrationSignal into your UI framework — same shape as the shipped React, Preact, Solid, Angular, Vue, Lit, Alpine, and Svelte adapters.
The React hook is ~20 lines over HydrationSignal — every adapter is that shape. Preact, Solid, Angular, Vue, Lit, Alpine, and Svelte ship the same contract (full text on HydrationSignal’s JSDoc).
Subscribe returns an idempotent unsubscribe; each call is an independent subscription. No initial notification and no payload — pull isHydrated() after attach and on every notification. Transitions while detached aren’t replayed (re-read recovers). Render hydrated: true on the server; null signal = no persistence = hydrated.
import type { HydrationSignal } from "@stainless-code/persist";
// The shipped `./frameworks/svelte` adapter, in full — every adapter is this shape:
export function hydratedRune(signal: HydrationSignal | null) {
if (!signal)
return {
get current() {
return true;
},
};
const subscribe = createSubscriber((update) =>
signal.subscribeHydrated(update),
);
return {
get current() {
subscribe();
return signal.isHydrated();
},
};
}