q builder as views. A question fixes one
relation, its arguments and its bounds on the server. Asking it produces an
answer: a retained, typed result you page, count and release. Read it in React
through useAnswer. Arguments and row types flow through the generated API.
The hook retains one answer identity, follows it, and releases it when its
arguments change or the component unmounts. Refresh explicitly asks again.
Choose the answer you need
A complete answer that exceeds its bounds fails instead of returning a partial
answer. Browse does not compute a population-wide total or sort. New dataset
publications do not change either result. Current read and disclosure rules
still apply to every read.
Declare the input
An installed dataset can be exposed as a virtual table. Import its existingdefineDataset declaration; deployment administration owns catalog binding and
credentials. The dataset must have a published version and managed retention.
bijection/schema.ts
ctx.db.
Relations over datasets currently support present scalar string, integer,
finite float, boolean and byte fields, including nullable fields. Project
unsupported optional or nested fields out of the relation. Complete answers can
combine dataset inputs with bounded local inputs; combining dataset inputs with
live SQL inputs is refused.
Declare the question
ImportdefineQuestion from the generated server module so the answer’s row
type is resolved against your schema. The client supplies arguments; the
question owns the relation and its bounds. Use q.arg("name") to bind a
declared argument into the fixed relation.
bijection/analytics.ts
result: "browse" only for snapshot
traversal. limits.max_rows and limits.max_bytes bound that answer; exceeding either refuses
the answer. Answers expire rather than silently being asked again.
Use the generated workspace
For a complete question namedregionalSales, code generation exposes its
native-admitted arguments and answer columns:
question.explain(args) previews the question through the planner without
reserving an answer. execution.explain() reads the plan admitted for that
answer without replanning. status() observes existing work; cancel() requests cancellation;
release() ends custody. Losing a reply does not mean native work failed.
A question defaults to complete; browse answers have pages and exact
snapshot row references. Browse results have neither collect() nor facets().
Integers remain bigint in arguments, result rows and histogram bounds.
Facets count every row of this retained answer, including its selected
predicates. They do not count the displayed page or ask the source again. The
response names its answer, request digest, result digest and exact population
size. Null and absent values are counted separately. Integer buckets have
inclusive bounds; calendar buckets have closed-open UTC epoch-millisecond
bounds, with Monday weeks.
A request names at most eight answer columns and at most 64 values or buckets
per column. A field exceeding its distribution bound is reported as unavailable;
other fields remain exact. Unavailable fields contain no partial counts. Native
reads remain bounded by the retained result and reply limits, and recheck
current authorization, expiry and erasure before releasing the distribution.
Source-wide facets remain separate observations, explicitly labelled in Explore.
Node configures requests: fileRequestStore(privateDirectory) from
bijection/node once. The same durable journal retains answer locators and
operation requests; it stores no relation literals, result rows or credentials in
answer locators.
Recover an existing answer through the same generated question:
workspace.answers.resume(answer_id) to inspect its native state without
claiming the current question’s row type. workspace.answers.recoverable()
lists locators from the same private journal.
Without the generated workspace, AnswerClient from bijection/browser asks an
ad-hoc relation or a question reference: client.ask(relation, bounds) or
client.ask(question, args). In an action, ctx.answers offers the same
lifecycle (reserve, ask, get, page, facets, cancel, release,
keep), plus collect for one bounded answer returned at once and explain.
Read collections and relationships
Ordinary rows, declared relationships and series have separate generated readers. Their names come from the schema and their paging meaning comes from the native reader. Withheld fields stay absent; projection does not grant access.bijection query reads collections and public query functions.
bijection questions ask reserves and saves an answer identity before any
source work and prints it; after a lost reply, rerun the same command with
--answer-id to retry under that identity. bijection answers reads, pages,
counts, cancels and releases a saved answer; none of its commands submits
source work.
Read it in React
UseuseAnswerExecution(execution) to observe an existing handle.
useAnswerPage(answer) reads one bounded page when its read() method is
called, and useAnswerFacets(answer, fields) observes distributions of that
same answer. These adapters do not submit work during rendering. Their
unavailable state describes an observation failure, not an invented native
terminal state. Switching handles discards late replies. The shared subscription
connection observes changes to the answer and its read authority. During
revalidation or a lost connection, managed pages and facets are hidden; a late
reply cannot restore them. Reconnecting checks the same answer and rereads
the accepted page boundary.
useAnswer(question, args) is the managed convenience path: it asks the
question, owns the answer’s custody for the component and releases it.
page_size
can request a smaller page. Both result kinds replace the displayed page,
keeping client memory bounded. A filtered browse page can be empty while
is_next_page_available is true. Use answer.collect() explicitly to return a readonly row array within the
complete answer’s bounds. Each public page contains only rows and next_cursor;
identity, count, basis and completion metadata belong to the result handle. Changing page_size changes subsequent reads without
asking again. rerun() asks again for a new answer; reconnect()
reauthorizes the existing one. Pass "skip" instead of arguments to suspend the
hook. Integers remain bigint throughout the flow.
Open a snapshot row
Browse pages return oneSnapshotRowReference per row. result.readRow(reference)
reopens that exact row under current authorization:
reference.currentObject. This is a
separate reference to the current document. Read it through the ordinary object
API, which checks current access and can return a changed value or a deleted
object. Never pass the snapshot reference itself to a mutation or treat its key
as a current ID. Explore presents these as separate snapshot details and an
Open current object link when the object is exposed by the application.