Skip to main content
The generated workspace client exposes collection.query() for public collections. Query construction is synchronous and performs no network requests. Each terminal call resolves the current public contracts and executes under your business session. Standalone consumer SDK packages expose the same query builders for their selected public collections and relationships. Their locked contract includes composition capabilities and remote identity assertions.
This example assumes a declared integer outstandingMinorUnits property. Integer sums and counts remain bigint. Decimal sums use m.decimalSum(field, scale) and return fixed-scale text. Measures also include distinct count, minimum, maximum, average and exact discrete percentile, subject to native type and execution admission. Missing values and explicit null retain the engine’s existing meanings. Presence predicates use the existing collection meanings: is_empty matches a missing property, while an explicit null remains present. Open lower range bounds exclude both null and missing values. related() follows a public relationship alias and returns each reached target object once, including across multiple starting objects. An invoice reached through two customers contributes once to this total. Totals attributed separately to each customer require an explicitly declared attribution rule. Traversal queries current target objects; an unavailable source identity is not a current object contribution. Point and relationship readers retain their separate retained-identity contracts. The generated relationship map supports repeated typed traversal. Set methods accept sets from the same session and public collection:
Builders are immutable. Filters, projections, grouping keys and measures come from the admitted contract. Projection and grouping produce result queries without business-object navigation or identity. Use orderBy({ field, order: "asc" }) on the final result when its fields have an admitted exact ordering.

Bounded native reads

read() returns { rows, complete: true, basis, binding }. It establishes the whole composed result or refuses. The initial native contract allows 64 expression nodes, 16 expression levels, 1,000 shared native row steps, at most 1,000 output rows and 1 MiB of processed/output data. A smaller page does not reduce the work needed to establish a total. Each filter step allows 16 predicates, and a group allows eight keys and 16 measures. page() continues this complete bounded result. Its next_cursor binds the exact query, contract and native basis; end is page or complete. Continue on the same query object with { cursor, page_size }. Pages re-execute at the pinned basis; they do not retain a separate dataset. An expired basis requires a new first page and reports continuation_expired with restart_query recovery. Object continuations append identity keys to the selected order. Projected and aggregate continuations use the shared complete-row order; ordering must be admitted for every field the native sort needs. The initial union lowering uses identity-based existence joins over the collection’s complete population. Its work and authorization requirements can therefore exceed those of either filtered operand. The server refuses a composition whose complete population, authority or work bounds cannot be established. Denied evidence never becomes a zero aggregate or an empty subtraction operand.

Observation and diagnostics

Observation uses ordinary native dependencies, including relationship and permission changes. It represents the latest checked state. Reconnection marks the previous answer as noncurrent, and terminal refusal clears it. Ending observation does not start or cancel retained work. Discovery descriptions expose composition: admitted operators, predicates, measures, limits, identity semantics and execution availability. A generated type establishes field-level compatibility; describe, explain and execution still admit the complete expression against the current schema. ReadError distinguishes invalid selection, changed contracts, incompatible sets and unsupported execution. Native engine refusals retain their native diagnostic details. Public-expression errors also carry a step such as expression.right.input and a recovery action. Native work-bound refusals report query_budget_exceeded; a partial aggregate is never returned.

Explicit retained and external execution

Remote collections expose query bindings without local point readers. Set algebra over a remote collection requires an admitted key, whose uniqueness is checked by the existing join assertion machinery. Unkeyed remote rows support filtering, projection and aggregation. read() and watch() refuse remote execution; start it explicitly through the existing retained answer owner:
admittedExecutor is a public executor binding already configured for the application. It contains no credentials. The existing planner determines whether the inputs, operators, source contexts and requested consistency can execute together. Fixed input requirements must be supported by those sources; an observed answer does not assert a coordinated snapshot across providers. Unsupported combinations refuse. Bijection continues to use external compute providers. The returned request owns observation, cancellation, recovery, result paging and release through the existing retained lifecycle. Retained access still checks current source authority and erasure. run() captures its options before preparing the query, so later edits do not retarget accepted work. The native input digest from preparation is included in the retained request and its recovery journal. Admission and execution independently compare it with the current logical inputs, including native collection identities, view membership and authorization definitions. A schema change between preparation and execution refuses the run instead of silently changing its meaning. For a Node service or CLI, configure the existing file-backed request journal so accepted work can be recovered after a process restart:
Use the same directory and namespace when recovering that client’s requests. Native caller scope and current authorization still decide access.