ResourceKit
API Reference

resource()

Resources, actions, relations, and named queries - the shared definitions.

import { resource, action, namedQuery, one, many } from "resourcekit";

resource(name, config)

Defines a resource and returns its typed API.

OptionTypeDefault
schemaz.ZodObjectrequiredShape of one record
identityfield name"id"The field records are addressed by
mode"collection" | "document" | "snapshot" | "blob" | "connection""collection"Local caching behavior - see Defining resources
supports("one" | "where" | "create" | "update" | "delete")[]all fiveWhich operations exist on the resource - see Supported operations. Unsupported ones are omitted from the type
versionfield name-Numeric field enabling conflict detection
actionsrecord of action(...){}Typed write operations
relationsrecord of one()/many(){}Connections for include()
queriesrecord of namedQuery(...){}Typed server-implemented reads

The resource API

issues.one(id)                      // Query<Issue | null>
issues.where(filter?)               // collection query (chainable, see below)

issues.create(record)               // fields with schema defaults are optional
issues.update(id, partial)
issues.delete(id)

issues.actions.assign(id, input)    // one per declared action
issues.queries.search(input)        // one per declared named query

Collection queries

where() returns a chainable, immutable query. Wire-level (decides what syncs):

.take(n, field?, direction?)   // window the synced set to the top n

Local (runs on the device, never crosses the network):

.filter((record) => boolean)   // any predicate
.orderBy(field, "asc" | "desc")
.orderBy((a, b) => number)     // or a comparator
.limit(n)
.include("project", ...)       // join declared relations

Filter syntax

{ status: "open" }                       // equality (shorthand)
{ status: { eq: "open" } }               // equality (explicit)
{ status: { in: ["open", "closed"] } }   // membership
{ score: { gt: 0, lte: 100 } }           // ranges: gt / gte / lt / lte
{ assigneeId: null }                     // null equality

Fields combine with AND. undefined values are dropped ("no constraint").

action(input, run, options?)

Argument
inputZod schema for the action's input
run({ input, record }) => partialRecord for declarative actions, or null for server-only actions
options.offlineReplay after an offline period - default true for declarative, false for server-only

namedQuery(input, output)

Declares a server-implemented read. input and output are Zod schemas; both are validated on both sides. Array outputs return refinable collection queries; other outputs resolve to value | null.

one(target, field) / many(target, field)

Relation declarations. target is a lazy thunk (() => projects); field is the local foreign-key field for one, the target's foreign-key field for many. See Relations.

bundle(build)

import { bundle } from "resourcekit";

Declares a group of queries to prefetch together. build maps an input to the queries to sync - anything you'd pass to useSynced (filtered, .take(n), .include(...), named queries). The input type is inferred from build; a bundle with no input is bundle(() => [...]).

export const workspaceData = bundle(({ workspaceId }: { workspaceId: string }) => [
  issues.where({ workspaceId }),
  projects.where({ workspaceId }),
  members.where(),
]);

Preload a bundle with engine.preload(bundle, input?) or the usePreload(bundle, input?) hook. See the Bundles guide.

On this page