@stainless-code/persist
Version:
Hydration-aware persistence middleware for reactive stores (storage × codec seams, TanStack Store adapters, React hydration hook)
57 lines (56 loc) • 1.77 kB
JavaScript
import { o as persistSource } from "./persist-core-BApUcOkB.mjs";
//#region src/persist-tanstack.ts
/**
* Persist a `@tanstack/store` `Store` (action-bearing stores included).
*
* @example
* ```ts
* const store = new Store({ filters: [] as string[] });
* const persist = persistStore(store, {
* name: "app:filters:v1",
* version: 1,
* skipPersist: (s) => s.filters.length === 0, // no key when default
* });
* // hydrates automatically on create; subscribe-writes on every setState
* await persist.rehydrate(); // optional manual re-read, awaitable
* ```
*/
function persistStore(store, options) {
return persistSource({
getState: () => store.state,
setState: (updater) => store.setState(updater),
subscribe: (listener) => store.subscribe(() => {
listener();
})
}, options);
}
/**
* Persist a writable `@tanstack/store` `Atom`. Default `merge` REPLACES
* instead of shallow-spreading — atoms commonly hold primitives, which a
* spread would corrupt. Pass `merge` to override.
*
* @throws Error when given a readonly (computed) atom — there is no `set` to
* hydrate into.
*
* @example
* ```ts
* const theme = createAtom<"light" | "dark">("light");
* const persist = persistAtom(theme, { name: "app:theme:v1" });
* // hydrate REPLACES the primitive; theme.set() writes through
* ```
*/
function persistAtom(atom, options) {
if (!("set" in atom) || typeof atom.set !== "function") throw new Error("[persistAtom] Cannot persist a readonly atom.");
return persistSource({
getState: () => atom.get(),
setState: (updater) => atom.set(updater),
subscribe: (listener) => atom.subscribe(() => {
listener();
})
}, {
...options,
merge: options.merge ?? ((persisted) => persisted)
});
}
//#endregion
export { persistAtom, persistStore };