Skip to content
TypeWire

@tahanabavi/typefetch-query-core

v1.2.0

Framework-agnostic query engine for TypeFetch contracts (cache, dedup, staleness, mutations, invalidation).

Setup

The client is the whole setup surface. Declare invalidation once, here — no call site downstream ever names a cache key:

ts
import { QueryClient } from '@tahanabavi/typefetch-query-core'
import { api } from './api' // a typefetch ApiClient

const client = new QueryClient({
relations: { 'user.updateUser': ['user.getUser'] },
})

relations reads "<mutation id>": ["<query id>", …]. The id is the contract's own stable endpointId (typesocket calls it eventId) — the engine resolves either, which is exactly why the same client drives both transports.

Cross-tab seams

Two more options exist for adapters that mirror the cache across tabs or replay it offline. Both are additive — leave them off and the engine runs exactly as above.

ts
import { collectSources } from '@tahanabavi/typefetch-query-core'

const client = new QueryClient({
// Wrap every fetch and mutation. Run the request, or resolve without it to
// hand back a value another tab already broadcast.
gate: (ctx, run) => run(),
// Turn an endpoint id back into its endpoint, so an inbound mirror can write
// through the typed `setQueryData` — even for an endpoint this tab has yet to
// mount. `collectSources` builds the map from a client's `.modules` tree.
sources: collectSources(api.modules),
})

setQueryData takes a matching { updatedAt } so a mirrored value keeps the origin's timestamp rather than looking freshly fetched. Each of these is a hook a sync or offline adapter attaches to; none is needed to use the engine on its own.