You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(wasm-sdk): composite document queries on the JS surface
- wasm-sdk: `getCompositeDocuments` and
`getCompositeDocumentsWithProofInfo`. The query is the page plus
`subQueries` (optional contract, document type, `documents` or
`counts`, fixed clauses, per-value limit, and a `bind` naming the
page or an earlier documents sub-query); the result is the page and
one discriminated sub-result per sub-query, counts keyed by the
bound value's base58 identifier. Sub-query contracts go through the
same cache as the page's.
- js-evo-sdk: `documents.composite` / `documents.compositeWithProof`
and a README section with the feed-page example.
- platform-test-suite: a composite case next to the chained one (page,
like counts from the countable index, the viewer's likes through the
byLiker terminal).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
-[Composite queries (a page plus its sub-queries)](#composite-queries-a-page-plus-its-sub-queries)
20
21
-[Contributing](#contributing)
21
22
-[License](#license)
22
23
@@ -223,6 +224,54 @@ const next = await sdk.documents.chained({
223
224
224
225
The inner query must target an indexOnly document type and resolve to an index carrying `joinProperty`, and `joinProperty` must declare a same-contract `refersTo: permanentDocument` targeting `outerDocumentType`. `innerLimit` is required — it bounds the derived outer fetch, so there is no server-default fallback. There are no outer-side clauses by design; filter `outerDocuments` locally. `sdk.documents.chainedWithProof(...)` returns the same result with the metadata and proof envelope attached.
225
226
227
+
## Composite queries (a page plus its sub-queries)
228
+
229
+
A **composite query** answers a page and everything a UI needs to render it in ONE verified round trip: the page documents, plus up to ten sub-queries whose `IN` clause the node derives from the proven page (or from an earlier `documents` sub-query). The request never names the derived values. Four sub-query shapes exist:
230
+
231
+
- a **by-id join** (`bind.field: '$id'`): the documents a page property refers to (the property must declare `refersTo: permanentDocument` targeting the sub-query's type, so a missing document fails verification);
232
+
- an **indexed lookup** (`bind.field` an indexed property or `$ownerId`): documents keyed by a page value, in this or any other contract, with a `limit` on the rows it returns in total unless the index already bounds them (a unique index, or an indexOnly terminal with every prefix fixed);
233
+
- a **count** (`kind: 'counts'`): one count per page value from a `countable` index covering the fixed clauses plus the bound field;
234
+
- a **sibling** (no `bind`): an independent documents query proven under the same root.
235
+
236
+
The node returns everything under ONE merged proof, a single quorum-signed state root by construction, and the SDK bootstraps the page from the proof, re-derives every sub-query itself and verifies the whole composition: the node cannot substitute, omit, or inject a sub-result.
237
+
238
+
```ts
239
+
// A feed page: the dash posts, their like counts, the posts they quote,
240
+
// their authors' profiles, and which of them I liked.
`limit` on the page is required and bounds every derived clause (at most 100 values reach a sub-query). A sub-query may bind the page (`bind.source: 'page'`, the default) or an earlier `documents` sub-query by index (`bind.source: 1`), so quoted posts can in turn pull their authors' profiles. Every sub-query walks in the page's direction: leave a lookup's ordering out and it inherits that direction, while an ordering that disagrees with the page is refused. Sub-results come back in request order as `{ kind: 'documents', documents }` (a join in first-appearance order of the page's ids, a lookup or sibling in query order) or `{ kind: 'counts', counts }` (a `Map` keyed by the bound value's base58 identifier; a value with no entry counts zero). There is no cursor on this surface; paginate with a range clause on the page's ordering property. `sdk.documents.compositeWithProof(...)` returns the same result with the metadata and proof envelope attached.
274
+
226
275
## Contributing
227
276
228
277
Feel free to dive in! [Open an issue](https://github.com/dashpay/platform/issues/new/choose) or submit PRs.
0 commit comments