API reference/fetchium

fetchium

fetchium

API reference for the main fetchium package — a data-fetching and query layer built on Signalium's reactive primitives.

ts
import {
  Query,
  QueryAdapter,
  fetchQuery,
  queryKeyForClass,
  Mutation,
  getMutation,
  mutationKeyForClass,
  Entity,
  QueryClient,
  NetworkManager,
  NoOpNetworkManager,
  GcManager,
  NoOpGcManager,
  t,
  registerFormat,
  draft,
  QueryClientContext,
  NetworkManagerContext,
} from 'fetchium';

// REST adapter (JSON REST APIs)
import { RESTQuery, RESTMutation, RESTQueryAdapter } from 'fetchium/rest';

Classes

Query (abstract)

Base class for all query definitions. Extend this to define custom data-fetching logic.

Static properties

PropertyTypeDescription
cacheQueryCacheOptions | undefinedClass-level persistent cache settings (maxCount, cacheTime).

Static properties

PropertyTypeDescription
cacheQueryCacheOptions | undefinedClass-level persistent cache settings (maxCount, cacheTime).
adaptertypeof QueryAdapter(required) The adapter class responsible for sending requests. Set automatically on RESTQuery. Custom query types must set this to their own adapter class.

Instance properties

PropertyTypeDescription
paramsRecord<string, TypeDef> | undefinedShape definition for query parameters.
resultTypeDefShape(abstract) Shape definition for the query result.
configQueryConfigOptions | undefinedInstance-level configuration (gcTime, staleTime, retry, etc.).
contextQueryContextThe query context provided by the QueryClient. Available in getConfig() and other methods.

Methods

MethodSignatureDescription
getIdentityKey(): unknown(abstract) Returns a value used to compute the cache/identity key for this query class.
refetch(): voidTriggers a refetch of this query, bypassing staleTime.
getConfig(): QueryConfigOptions | undefinedOptional. Dynamically compute config at execution time. Reactive: re-runs when any signal consumed inside notifies (e.g. this.responseNotifier).

RESTQuery extends Query

Convenience base class for REST/JSON queries. Handles URL construction, search params, body serialization, and pagination.

Instance properties

PropertyTypeDefaultDescription
method'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH''GET'HTTP method.
pathstring | undefined—URL path. Use template literal interpolation with this.params references.
searchParamsRecord<string, unknown> | undefined—Query string parameters.
bodyRecord<string, unknown> | undefined—Request body (JSON-serialized).
headersHeadersInit | undefined—Custom HTTP headers.
requestOptionsQueryRequestOptions | undefined—Additional fetch options (credentials, mode, baseUrl, etc.).
fetchNextFetchNextConfig | undefined—Static pagination config. Values can be FieldRefs (e.g. this.result.nextCursor).
responseResponse | undefined—The raw HTTP Response from the last fetch. Set by RESTQueryAdapter after each request completes. Available in getConfig().
responseNotifierNotifier—Notifier fired by RESTQueryAdapter after each fetch completes. Consume inside a reactiveSignal in getConfig() to react to new responses.

getIdentityKey() default

Returns "${method}:${path}".

Optional method overrides

MethodSignatureDescription
getPath(): string | undefinedDynamically compute the URL path.
getMethod(): stringDynamically compute the HTTP method.
getSearchParams(): Record<string, unknown> | undefinedDynamically compute search params.
getBody(): Record<string, unknown> | undefinedDynamically compute the request body.
getRequestOptions(): QueryRequestOptions | undefinedDynamically compute fetch options.
getFetchNext(): FetchNextConfig | undefinedDynamically compute pagination config. Takes priority over the static fetchNext field.

Example

ts
class GetUser extends RESTQuery {
  params = { id: t.string };

  path = `/api/users/${this.params.id}`;

  result = {
    id: t.id,
    name: t.string,
    email: t.string,
  };
}

Entity

Base class for entity definitions. Entities are normalized, identity-stable proxy objects managed by the QueryClient.

Static properties

PropertyTypeDescription
cache{ gcTime?: number } | undefinedIn-memory GC time in minutes. 0 = next-tick eviction, Infinity = never GC.

Optional instance methods

MethodSignatureDescription
__subscribe(onEvent: (event: MutationEvent) => void) => (() => void) | undefinedSubscribe to external mutation events for this entity (e.g. WebSocket push). Return a cleanup function.

Example

ts
class User extends Entity {
  static cache = { gcTime: 10 };

  __typename = t.typename('User');
  id = t.id;

  name = t.string;
  email = t.optional(t.string);
}

Mutation (abstract)

Base class for mutation definitions.

Static properties

PropertyTypeDescription
adaptertypeof QueryAdapter(required) The adapter class that handles sending this mutation. Set automatically on RESTMutation. Custom mutation types must set this to their own adapter class.

Instance properties

PropertyTypeDescription
paramsTypeDefShape | undefinedShape definition for mutation input parameters.
resultTypeDefShape | undefinedShape definition for the mutation response.
optimisticUpdatesboolean | undefinedWhen true, applies effects optimistically before the server responds.
configMutationConfigOptions | undefinedMutation configuration (retry settings).
effectsMutationEffects | undefinedStatic entity effects (creates, updates, deletes) and query invalidation.
contextQueryContextThe query context provided by the QueryClient.

Methods

MethodSignatureDescription
getIdentityKey(): unknown(abstract) Returns a value used to compute the mutation identity key.
getEffects(): MutationEffectsOptional. Dynamically compute entity effects at execution time.

RESTMutation extends Mutation

Convenience base class for REST/JSON mutations.

Instance properties

PropertyTypeDefaultDescription
pathstring | undefined—URL path.
method'POST' | 'PUT' | 'DELETE' | 'PATCH''POST'HTTP method.
bodyRecord<string, unknown> | undefined—Request body shape. No body is sent if omitted.
headersHeadersInit | undefined—Custom HTTP headers.
requestOptionsQueryRequestOptions | undefined—Additional fetch options.

getIdentityKey() default

Returns "${method}:${path}".

Optional method overrides

MethodSignatureDescription
getPath(): string | undefinedDynamically compute the URL path.
getMethod(): stringDynamically compute the HTTP method.
getBody(): Record<string, unknown> | undefinedDynamically compute the request body.
getRequestOptions(): QueryRequestOptions | undefinedDynamically compute fetch options.

QueryClient

Central coordinator for queries, mutations, entity storage, caching, and garbage collection.

Constructor

ts
new QueryClient(config: QueryClientConfig)
FieldTypeDefaultDescription
storeQueryStoreIn-memoryPersistent storage backend. Defaults to SyncQueryStore(MemoryPersistentStore).
adaptersQueryAdapter[][]Transport adapters (e.g. new RESTQueryAdapter({ fetch, baseUrl })).
logLogContext | undefinedconsoleLogger with error, warn, info, debug methods.
evictionMultipliernumber | undefined1Scales all GC times for testing. Set to 0.001 to make timers fire in milliseconds.
networkManagerNetworkManagernew NetworkManager()Tracks network connectivity.
gcManagerGcManager | NoOpGcManagerAuto-detectedGC manager. Uses NoOpGcManager on the server.
reactivationGraceMsnumber0Milliseconds. A query that reactivates (a watcher returns, or a paused scope resumes) with data younger than this is not refetched, even if stale. Data a subscription pushed to (a subscribe stream event, or a topic event sent with its topic) counts as fresh from the last push; a running poll() counts through the fetches it makes. Network reconnects, __refetch() and invalidation still refetch. Infinity never refetches on reactivation. Per-query override: reactivationGraceMs in the query config.
reactivationStaggerMsnumber0Milliseconds. Reactivation refetches that start in the same task are spread evenly across this window, in activation order, instead of all starting at once. A value that is not a finite positive number counts as 0.
shouldRetry(error, attempt, status) => boolean—Optional. Whether a failed attempt is retried. Without it, every failed attempt is retried, whatever its status. attempt starts at 0; status is the attempt's HTTP status when known (the adapter's error response, or status / statusCode / response.status on the error). Return false to stop retrying errors you know are permanent, such as a 4xx. Per-query override: retry.shouldRetry.
activityActivitySource | undefined—{ isActive(), subscribe(listener) } foreground source. When set, poll() stops its timers while inactive and resumes them on activation. A value without isActive and subscribe functions is ignored, with a warning in development.
pollResumeJitterMsnumber0Milliseconds. A poll() tick that is overdue on resume (or whose timer fired over a second late, as after JS timers were frozen in the background) is rescheduled at a random point in this window instead of firing at once. A value that is not a finite positive number counts as 0. Per-poll override: poll({ interval, resumeJitterMs }).

Every config key, including keys this table does not list, also reaches query and mutation code as this.context, so you can pass your own services through the config. The names in the table are reserved: a value under one of them is read as that option, so do not reuse them for your own context values.

Methods

MethodSignatureDescription
getContext(): QueryContextReturns the QueryContext passed at construction.
applyMutationEvent(event: MutationEvent): voidApplies an external mutation event (create/update/delete) to the entity store.
invalidateQueries(targets: ReadonlyArray<InvalidateTarget>): voidMarks matching query instances as stale. Accepts query classes and optional param subsets for filtering.
prefetch(QueryClass, params?, { ttl? }?): () => voidStarts a query now and keeps it active for ttl ms (default DEFAULT_PREFETCH_TTL, 10 s). See below.
retain(fn: () => unknown, { ttl? }?): () => voidKeeps the queries fn reads active until the returned release is called, or for ttl ms. See below.
destroy(): voidTears down the GC manager, network manager, and all caches, releases outstanding leases, and unsubscribes the store listeners it registered.

prefetch and retain

Both take a lease: the queries stay active (fetched, subscribed, exempt from GC) without a component reading them. A reader that mounts while the lease is held joins the active query, so it starts no request of its own and renders the data on its first render if it has arrived. Both return an idempotent release function. Releasing never interrupts other readers; once the last one goes, the query deactivates and its gcTime starts as usual. Calling release while a fetch is in flight, with no reader, aborts that fetch. A ttl is an upper bound: the lease goes when it runs out even if the fetch is still in flight (offline, or a topic never fulfilled), which aborts the fetch unless a reader has joined it. Call retain and prefetch from event handlers or effects, not from inside a reactive computation; called from one, they warn in development and keep only the leases from the computation's latest run.

prefetch is for the moment a user commits to a navigation, such as a tap. Call it in the handler, before navigating:

ts
function onPressToken(id: string) {
  queryClient.prefetch(GetTokenDetail, { id }, { ttl: 5_000 });
  router.push(`/token/${id}`);
}

With a synchronous store, a cached result is applied inside the call. A fresh one makes no request, and a stale one is refetched, as on any activation.

retain keeps a set of queries warm, for example the queries of a screen that is hidden but likely to come back. fn runs immediately, with the client as QueryClientContext, and again when what it reads changes. It holds a query when it reads one of the query's fields, or when it returns the query's promise or an array of them:

ts
const release = queryClient.retain(() => [
  fetchQuery(GetPortfolio),
  fetchQuery(GetPrices, { ids }),
]);
// when the surface is gone for good:
release();

Without a ttl, a retain lease lasts until release is called.


QueryAdapter (abstract)

Base class for transport adapters. An adapter handles sending queries and mutations for all query/mutation classes that declare it via static adapter. Register adapters with QueryClient at construction time.

Methods

MethodSignatureDescription
register(queryClient: IQueryClientForAdapter): voidCalled once when the adapter is registered with a QueryClient. Override to do setup (e.g. open a WebSocket connection).
send(ctx: Query, signal: AbortSignal): Promise<unknown>(abstract) Send a query and return the raw response data.
sendNext(ctx: Query, signal: AbortSignal): Promise<unknown>Optional. Send the next-page request for a paginated query.
hasNext(ctx: Query): booleanOptional. Return true if more pages are available for the current result.
sendMutation(ctx: Mutation, signal: AbortSignal): Promise<unknown>Optional. Send a mutation and return the raw response data.
onNetworkStatusChange(isOnline: boolean): voidOptional. Called when the network comes online or goes offline.
destroy(): voidOptional. Called when the QueryClient is destroyed. Clean up connections or timers.

Properties

PropertyTypeDescription
coalescesRequestsboolean | undefinedOptional. Set when the adapter merges requests sent close together. reactivationStaggerMs then starts its queries' reactivation refetches together, unspread.

Protected properties

PropertyTypeDescription
queryClientIQueryClientForAdapter | undefinedSet by register(). Use to access the shared query context via this.queryClient.getContext().

Example

ts
import { QueryAdapter } from 'fetchium';
import type { Query } from 'fetchium';

class GraphQLAdapter extends QueryAdapter {
  async send(ctx: Query, signal: AbortSignal): Promise<unknown> {
    const q = ctx as GraphQLQuery;
    const response = await fetch('/graphql', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ query: q.query, variables: q.variables }),
      signal,
    });
    const json = await response.json();
    if (json.errors?.length) throw new Error(json.errors[0].message);
    return json.data;
  }
}

new QueryClient({
  store,
  adapters: [new GraphQLAdapter()],
});

RESTQueryAdapter extends QueryAdapter

Transport adapter for RESTQuery and RESTMutation. Handles URL construction, JSON serialization, search params, pagination, and baseUrl resolution.

Import from fetchium/rest.

Constructor

ts
new RESTQueryAdapter(options?: RESTQueryAdapterOptions)
OptionTypeDescription
fetch(url: string, init?: RequestInit) => Promise<Response>The fetch implementation to use. Defaults to globalThis.fetch.
baseUrlstring | Signal<string> | (() => string) | undefinedBase URL prepended to all request paths.

NetworkManager

Signal-based network connectivity tracker. Automatically detects browser online/offline events.

Constructor

ts
new NetworkManager(initialStatus?: boolean)
ParameterTypeDefaultDescription
initialStatusbooleanAuto-detectedInitial online status. If omitted, uses navigator.onLine.

Properties and methods

MemberType / SignatureDescription
isOnlineboolean (getter)Returns true if the network is currently online. Manual override takes precedence.
setNetworkStatus(online: boolean): voidManually set the network status.
clearManualOverride(): voidClear any manual override and return to automatic detection.
getOnlineSignal(): Signal<boolean>Returns the underlying reactive Signal for online status.
destroy(): voidRemoves event listeners and cleans up resources.

NoOpNetworkManager

SSR-safe no-op implementation of NetworkManager. Always reports isOnline = true.

MemberType / SignatureDescription
isOnlineboolean (getter)Always returns true.
setNetworkStatus(online: boolean): voidNo-op.
clearManualOverride(): voidNo-op.
getOnlineSignal(): Signal<boolean>Returns a static Signal(true).
destroy(): voidNo-op.

GcManager

Bucket-based in-memory garbage collection. Each unique gcTime gets its own interval with two rotating sets. Minimum eviction delay is approximately gcTime; maximum is approximately 2 * gcTime.

Constructor

ts
new GcManager(
  onEvict: (key: number, type: GcKeyType) => void,
  multiplier?: number,
)
ParameterTypeDefaultDescription
onEvict(key: number, type: GcKeyType) => void—Callback invoked when a key is evicted.
multipliernumber1Multiplier applied to gcTime intervals (useful for testing).

Methods

MethodSignatureDescription
schedule(key: number, gcTime: number, type: GcKeyType): voidSchedule a key for eviction. gcTime = 0 evicts on next microtask. gcTime = Infinity never evicts.
cancel(key: number, gcTime: number): voidCancel a pending eviction.
destroy(): voidClears all intervals and pending entries.

NoOpGcManager

No-op garbage collection manager. All methods are no-ops.

MethodSignature
schedule(key: number, gcTime: number, type: GcKeyType): void
cancel(key: number, gcTime: number): void
destroy(): void

Functions

fetchQuery

ts
function fetchQuery<T extends Query>(
  QueryClass: new () => T,
  params?: ExtractQueryParams<T>,
): QueryPromise<T>;

Fetches a query reactively. Must be called within a reactive context where QueryClientContext is provided. Returns a QueryPromise (a ReactivePromise) that resolves to the query result.

ParameterTypeDescription
QueryClassnew () => TThe query class to instantiate and execute.
paramsExtractQueryParams<T>Parameters matching the query's params shape. Optional if the query has no required params. Values can be Signalium Signals for reactive parameter changes.

Returns: QueryPromise<T> — a reactive promise with .value, .isPending, .isResolved, .isRejected, .error.


getMutation

ts
function getMutation<T extends Mutation>(
  MutationClass: new () => T,
): ReactiveTask<ExtractType<T['result']>, [ExtractType<T['params']>]>;

Returns a ReactiveTask for executing a mutation. Must be called within a reactive context where QueryClientContext is provided.

ParameterTypeDescription
MutationClassnew () => TThe mutation class to instantiate.

Returns: ReactiveTask — call .run(params) to execute the mutation.


queryKeyForClass

ts
function queryKeyForClass(cls: new () => Query, params: unknown): number;

Computes the numeric cache key for a query class and params combination. Useful for cache invalidation or inspection.


mutationKeyForClass

ts
function mutationKeyForClass(cls: new () => Mutation): string;

Returns the string identity key for a mutation class. Derived from the mutation's getIdentityKey().


registerFormat

ts
function registerFormat<Input extends Mask.STRING | Mask.NUMBER, T>(
  name: string,
  type: Input,
  parse: (value: Input extends Mask.STRING ? string : number) => T,
  serialize: (value: T) => Input extends Mask.STRING ? string : number,
  options?: { eager?: boolean },
): void;

Registers a custom format for use with t.format(name). Built-in formats include 'date' and 'date-time'.

ParameterTypeDescription
namestringFormat name. Use with t.format(name).
typeMask.STRING | Mask.NUMBERThe underlying wire type (string or number).
parse(value) => TConverts the raw wire value into the formatted type.
serialize(value) => wireConverts the formatted type back to the wire value.
options.eagerbooleanIf true (default), parsing runs eagerly during entity construction. If false, parsing is lazy.

To add TypeScript types for custom formats, use module augmentation:

ts
declare global {
  namespace SignaliumQuery {
    interface FormatRegistry {
      'my-format': MyType;
    }
  }
}

draft

ts
function draft<T>(value: T): Draft<T>;

Deep clones an entity or object, returning a plain mutable copy. The draft is not an entity proxy and can be freely modified before being passed to a mutation.

ParameterTypeDescription
valueTThe entity or object to clone.

Returns: Draft<T> — a recursively mutable deep clone.


The t Type DSL

The t object provides a declarative type definition DSL for describing query parameters, results, and entity shapes.

Primitive types

PropertyTypeDescription
t.stringTypeDef<string>String type.
t.numberTypeDef<number>Number type.
t.booleanTypeDef<boolean>Boolean type.
t.nullTypeDef<null>Null literal type.
t.undefinedTypeDef<undefined>Undefined literal type.
t.idTypeDef<string | number>Identity field marker. Marks the field as the entity's unique ID. Accepts string or number.

Composite types

MethodSignatureDescription
t.array(type: TypeDef<T>) => TypeDef<T[]>Array of the given element type.
t.object(shape: Record<string, TypeDef>) => TypeDef<...>Object with the given field shapes.
t.record(type: TypeDef<T>) => TypeDef<Record<string, T>>Record (dictionary) with string keys and values of the given type.
t.union(...types: TypeDef[]) => TypeDef<...>Discriminated union. Object types must have a typename field for discrimination.
t.entity(cls: new () => Entity) => TypeDef<Entity>Reference to a normalized entity type.

Modifiers

MethodSignatureDescription
t.optional(type: TypeDef<T>) => TypeDef<T | undefined>Makes a type optional (allows undefined).
t.nullable(type: TypeDef<T>) => TypeDef<T | null>Makes a type nullable (allows null).
t.nullish(type: TypeDef<T>) => TypeDef<T | undefined | null>Makes a type nullish (allows both undefined and null).

Constants and enums

MethodSignatureDescription
t.const(value: T) => TypeDef<T>Constant literal value.
t.enum(...values: T[]) => TypeDef<T[number]>Enum of allowed values (strings, numbers, or booleans).
t.enum.caseInsensitive(...values: T[]) => TypeDef<T[number]>Case-insensitive enum. String values match case-insensitively but return canonical casing.

Formats

MethodSignatureDescription
t.format(name: string) => TypeDef<FormatRegistry[name]>A formatted value. Built-in: 'date' (YYYY-MM-DD to Date), 'date-time' (ISO 8601 to Date).

Result parsing

MethodSignatureDescription
t.result(type: TypeDef<T>) => TypeDef<ParseResult<T>>Wraps a type in a ParseResult<T> ({ success: true, value: T } | { success: false, error: Error }). Individual fields that fail validation produce an error result instead of throwing.

Live data

MethodSignatureDescription
t.liveArray(entity: EntityClass | EntityClass[], opts?: LiveArrayOptions) => TypeDef<E[]>A live array that automatically updates when matching entities are created, updated, or deleted via mutation events.
t.liveValue(type: TypeDef<V>, entity: EntityClass | EntityClass[], opts: LiveValueOptions) => TypeDef<V>A live derived value that recomputes when matching entities change. Requires onCreate, onUpdate, and onDelete callbacks.

LiveArrayOptions<E>

PropertyTypeDescription
constraintsConstraintDef<E>Filter which entities are included. Can be a Record<string, unknown> or an array of [EntityClass, constraintMap] tuples. Constraint values can be FieldRefs.
sort(a: E, b: E) => numberSort comparator for the array.

LiveValueOptions<V, E>

PropertyTypeDescription
constraintsConstraintDef<E>Filter which entities trigger recomputation.
onCreate(value: V, entity: E) => VCalled when a matching entity is created. Returns the new value.
onUpdate(value: V, entity: E) => VCalled when a matching entity is updated. Returns the new value.
onDelete(value: V, entity: E) => VCalled when a matching entity is deleted. Returns the new value.

Contexts

ContextTypeDefaultDescription
QueryClientContextContext<QueryClient | undefined>undefinedSignalium context for the QueryClient. Must be provided for fetchQuery and getMutation to work.
NetworkManagerContextContext<NetworkManager>defaultNetworkManagerSignalium context for the NetworkManager.

Types

Query types

TypeDefinitionDescription
QueryPromise<T extends Query>ReactivePromise<QueryResult<T>>The return type of fetchQuery. A reactive promise.
QueryResult<T extends Query>ExtractType<T['result']> & { __refetch(), __fetchNext(), __hasNext, __isFetchingNext }The resolved value of a query. Includes pagination helpers.
QueryCacheOptions{ maxCount?: number; cacheTime?: number }Persistent storage cache settings. cacheTime is in minutes (default: 1440 / 24 hours). maxCount is the LRU queue size.
QueryConfigOptions{ gcTime?, staleTime?, debounce?, networkMode?, retry?, refreshStaleOnReconnect?, reactivationGraceMs?, subscribe? }Instance-level query configuration. See property table below.
QueryRequestOptions{ baseUrl?, credentials?, mode?, cache?, redirect?, referrer?, referrerPolicy?, integrity?, keepalive?, signal? }Extended fetch options for individual queries.
QueryContext{ log?, evictionMultiplier? }Context object provided to the QueryClient.
QueryParamsRecord<string, string | number | boolean | undefined | null | Signal<...> | unknown[] | Record<string, unknown>>The shape of query parameters at runtime.
FetchNextConfig{ url?: unknown; searchParams?: Record<string, unknown> }Pagination configuration. Values can be FieldRefs.

QueryConfigOptions properties

PropertyTypeDefaultDescription
gcTimenumber5In-memory eviction time in minutes. 0 = next-tick, Infinity = never.
staleTimenumber0Milliseconds data is considered fresh. 0 = always stale.
debouncenumber0Milliseconds to debounce refetches. At 0, a refetch starts on a microtask (invalidation: on the next task).
networkModeNetworkModeNetworkMode.OnlineWhen to allow fetching.
retryRetryConfig | number | boolean3 (client) / 0 (server)Retry configuration.
refreshStaleOnReconnectbooleantrueWhether to refetch stale queries when network reconnects.
reactivationGraceMsnumberclient value (0)Milliseconds. Skip the reactivation refetch while data is younger than this. Overrides the client's reactivationGraceMs.
subscribe(onEvent) => () => void—Subscribe to external events that should trigger refetches.

Mutation types

TypeDefinitionDescription
MutationConfigOptions{ retry?: RetryConfig | number | false }Mutation retry configuration.
MutationEffects{ creates?, updates?, deletes?, invalidates? }Mutation side effects. Entity effects are ReadonlyArray<readonly [EntityClassOrTypename, unknown]>. invalidates is ReadonlyArray<InvalidateTarget>.
InvalidateTargetQueryClass | readonly [QueryClass, Record<string, unknown>]Target for query invalidation. Class alone matches all instances; tuple with param subset matches only instances whose params contain those values.
MutationEventCreateEvent | UpdateEvent | DeleteEventUnion of mutation event types.
CreateEvent{ type: 'create'; typename: string; data: Record<string, unknown>; id?: unknown }Entity creation event.
UpdateEvent{ type: 'update'; typename: string; data: Record<string, unknown>; id?: unknown }Entity update event.
DeleteEvent{ type: 'delete'; typename: string; data: string | number | Record<string, unknown>; id?: unknown }Entity deletion event. data can be just the ID.

Network types

TypeDefinitionDescription
NetworkModeenum { Always, Online, OfflineFirst }Controls when queries are allowed to fetch.

NetworkMode values

ValueDescription
NetworkMode.AlwaysAlways fetch regardless of network status.
NetworkMode.OnlineOnly fetch when online (default).
NetworkMode.OfflineFirstFetch if cached data exists, even when offline.

Retry types

TypeDefinitionDescription
RetryConfig{ retries?: number; retryDelay?: (attemptIndex: number) => number; shouldRetry?: (error, attempt, status) => boolean }Retry configuration. Default delay: exponential backoff (1000ms * 2^attempt). shouldRetry overrides the client's shouldRetry.

Utility types

TypeDefinitionDescription
TypeDef<T>Branded phantom typeRepresents a type definition in the public API.
TypeDefShapeRecord<string, TypeDef> | TypeDefA shape for query results or mutation params.
ExtractType<T>Conditional typeExtracts the TypeScript type from a TypeDef<T>.
ExtractQueryParams<T>Conditional typeExtracts the params type from a Query subclass.
Draft<T>Recursive mapped typeRecursively removes readonly from all properties. Return type of draft().
ParseResult<T>ParseSuccess<T> | ParseErrorResult of t.result() parsing.
ParseSuccess<T>{ success: true; value: T }Successful parse.
ParseError{ success: false; error: Error }Failed parse.

Store types

TypeDefinitionDescription
QueryStoreInterfaceStorage backend interface. See stores/sync and stores/async. Besides the required methods, a store may implement onDelete (the client then skips writing entities whose records are current, and writes one again once the store reports its record dropped), onPersisted (for a store that applies writes later), isSettled, hasEntity (lets a streamed event refresh the record of an entity that is not in memory) and mergeEntity (merges the fields streamed events supplied for an entity built from them over its record; without it, such an entity is written whole through saveEntity). A store without onDelete is written on every apply, as before 0.6; when hasEntity is missing or answers undefined, an event for an entity that is not in memory and that no live array retains is written only as a mergeEntity call with ifStored, which writes nothing when the store holds no record, and not at all without mergeEntity.
CachedQuery{ value: unknown; refIds: Set<number> | undefined; updatedAt: number; preloadedEntities?: PreloadedEntityMap }Cached query data returned by QueryStore.loadQuery().
PreloadedEntityMapMap<number, Record<string, unknown>>Pre-loaded entity data for hydration.