TandemClient, TandemServer, and useTandemQuery all accept it.12345678const tasks = client.query({ collection: "tasks", select: { id: true, title: true, priority: true }, where: { status: "pending", createdAt: { gt: yesterday } }, orderBy: { priority: "desc", id: "asc" }, limit: 10, offset: 0, })
collection is required. Every option is typed against the schema, so an unknown field, relation, or mismatched value type is a compile error.| Option | Shape | Notes |
select | { field: true } | Omit to return all fields. The result type narrows to selected fields. |
where | { field: value | { eq, gt, lt, gte, lte } } | A bare value means eq. All conditions combine with AND. |
orderBy | { field: "asc" | "desc" } | Key order sets sort precedence. Omit it and the order is unspecified. |
limit | number | Maximum number of rows. |
offset | number | Rows to skip, applied after where and orderBy. |
with | { relation: true | QueryOptions } | Includes related records. See Relations. |
OR, NOT, in, and filters on related fields are not supported.subscribe returns the current result and calls the callback whenever the result changes. Call destroy to stop.1234const { result, destroy } = client.subscribe( { collection: "users", where: { active: true } }, (users) => render(users), )
useTandemQuery(query) subscribes for the component's lifetime. It re-subscribes when the serialized query changes and returns undefined when query is undefined.defineRelations and pass them to the client alongside the schema. Relations need a runtime schema whose collections list their fields.import { collection, defineRelations, defineSchema, t, TandemClient, } from "@tanishqkancharla/tandem-core" const schema = defineSchema({ users: collection({ id: t.id(), name: t.string() }), threads: collection({ id: t.id(), ownerId: t.string(), title: t.string() }), messages: collection({ id: t.id(), threadId: t.string(), body: t.string(), createdAt: t.number(), }), }) const relations = defineRelations(schema, ({ one, many }) => ({ threads: { owner: one("users", { from: "ownerId", to: "id" }), messages: many("messages", { from: "id", to: "threadId" }), }, })) const client = new TandemClient({ schema, relations })
one defines a many-to-one relation. Its result is the related row or null.many defines a one-to-many relation. Its result is an array, which is [] when nothing matches.with. true includes all fields. An object accepts the same options as a root query, scoped to the related collection, and can nest further with clauses.1234567891011121314const threads = client.query({ collection: "threads", select: { id: true, title: true }, with: { owner: { select: { name: true } }, messages: { orderBy: { createdAt: "desc" }, limit: 1, }, }, }) threads[0].owner?.name threads[0].messages[0]?.body
limit and offset apply per parent row. Tandem reads join fields internally, so select can leave them out. Subscriptions re-emit when included child records change.