- A dashboard follows the current result. A maintained result refreshes in the background and the UI reads whichever accepted result is selected.
- A user starts a run and follows it. A report or simulation runs when the user asks, and the UI follows that specific run.
Follow a maintained result
Declare the maintained result next to the computation.latestResultPolicy
is the common dashboard policy: refresh when the result is stale or its inputs
were invalidated, coalesce overlapping demand into one run in flight, and serve
each result as soon as it is accepted. Freshness, stale grace and retention
stay your choices.
bijection/maintained.ts
select: { by: "manual" } for a result a reviewer approves.
ctx.computations.read in an ordinary query when a calculation must be
transactionally current with native tables.
Run a calculation on demand
Declare a public computation with one access policy per control. Starting, reading, cancelling and retiring are different permissions; reuse your own policy helpers instead of assuming one implies another. An omittedcancel or
retire policy denies it. Holding a generated computation reference grants
nothing.
bijection/reports.ts
api.reports.revenue. useRun starts and recovers
runs; useOutputs(run, outputs) follows one run’s outputs. useComputation
composes both for a screen that starts and shows its own latest run.
report.start(args) resolves with the run once admission is established; rows
arrive later in report.view. Each start after a decision admits new work. To
keep showing another run, compose useRun and useOutputs directly.
report.status is one of:
An
unresolved submission keeps its identity. recover() resubmits the
original request with its original arguments and never creates a second run;
start refuses until the submission is resolved. The request journal survives
reloads, so remounting a component restores the same run.
Read run state
useOutputs, like useComputation’s view, returns idle, loading,
pending, unavailable or available. A pending run reports a summary: its phase, whether cancellation
was requested, and the first error diagnostic. A run that ended without output
reports the same summary on its absent reason, so the UI can tell a failed run
from a cancelled one:
inspect endpoint keeps the complete inspection protocol for debugging:
attempts, evidence, custody, measurements and every diagnostic.
Pages and errors
Row outputs use the same shape asusePaginatedQuery: results, status
(CanLoadMore, LoadingMore or Exhausted), isLoading and
loadMore(numItems). The first page arrives with the observation; select its
size with initialNumItems.
- Expected lifecycle conditions are typed state:
pending, orunavailablewith anabsent,unknown,withheldorunavailablereason. - A failed first read throws from the hook, like
useQuery, and reaches your error boundary. - A failed continuation keeps every row already loaded and sets that output’s
errorto the query’s own error, includingConvexErrordata. The page stays subscribed. - A changed maintained selection, revoked access or withheld result discards loaded rows; pages from different selections are never mixed.