@playfast/reform-query-browser
v1.0.1
Published
Browser host layers for Reform's AsyncCalc — window focus/online auto-invalidation and localStorage persistence. Keeps reform core DOM-free: implements the optional QueryEvents and QueryStore seams.
Maintainers
Readme
@playfast/reform-query-browser
Browser host layers for Reform's AsyncCalc. Reform core stays renderer-neutral —
it declares the optional QueryEvents (lifecycle signals) and QueryStore
(persistence) seams but contains no DOM. This package implements them over the
real browser, plus the focus/reconnect auto-invalidation managers built on top.
What it gives you
QueryEventsBrowser— implementsQueryEventsoverwindowfocus /documentvisibility /online. Falls back to a no-op off the main thread (SSR, workers, tests), so the same app layer is safe everywhere.localStorageQueryStore— implementsQueryStoreoverlocalStorage(JSON, namespaced underreform-query:). Provide it to enablepersiston a calc.RefetchOnFocus/RefetchOnReconnect— managers that invalidate every live query on the matching signal (React-Query'srefetchOnWindowFocus/refetchOnReconnect). Invalidation only marks queries stale; a stale query that's actively read refetches.BrowserQueryDefaults— focus + reconnect managers pre-wired overQueryEventsBrowser, so you only needQueries(part ofEngine) in context.
Usage
import { Engine, AsyncCalc } from '@playfast/reform'
import { BrowserQueryDefaults, localStorageQueryStore } from '@playfast/reform-query-browser'
// In your app layer, alongside Engine:
const base = Layer.mergeAll(
Engine,
BrowserQueryDefaults, // refetch on focus + reconnect
localStorageQueryStore, // enables `persist`
/* your state + calc layers */
)
// Opt a query into persistence:
AsyncCalc.live(Todos, { query, persist: { key: 'todos' } })
// Imperative control anywhere you can run an Effect:
runtime.runFork(AsyncCalc.invalidate(Todos)) // mark stale (refetches if active)
runtime.runFork(AsyncCalc.refetch(Todos)) // force a run nowAll of QueryEvents/QueryStore are optional: a calc that uses persist with no
QueryStore in context (or runs where there's no window) simply behaves as if
the feature were off — no hard requirement is added to your layer.
