host: each-source = graph query — the data-driven each (composition roadmap step 3)
An object's `each` source can now be a GRAPH QUERY: `(query is-a TYPE)` resolves to
whatever is-a TYPE *right now* — the list isn't baked into the body, it's the live graph.
The object's `each` IS the query; the render is the run over current data (the unifying
property, now over real data).
compose.sx stays self-contained: the `query` source delegates to a resolver bound in the
render context under "query" — it asks the context for data, never reaching into the graph
itself. The host supplies graph access via host/blog--comp-query (`(query is-a TYPE)` ->
host/blog-instances-of -> full records) injected by host/blog--comp-ctx (auth + resolver);
the post handler renders :body against that context.
Added a `val` leaf — the raw field value with no markup wrapper, for use inside attributes
(href/src). `field` stays span-wrapped for display; `(val :slug)` makes a real link in the
each template. /compose-demo's each is now a live (query is-a compose-item) over two seeded
instances instead of a baked literal list.
Verified end-to-end via a focused harness eval over the full relations+persist+blog stack
(query iterates real instances; clean href via val; empty query -> empty, not an error).
Blog suite 151/153 — the 2 fails ("relate-options load-more sentinel", "related picker
offers all posts") are PRE-EXISTING (clean HEAD is 149/151 with the identical 2 fails, a
relate-picker pagination-boundary issue) and unrelated to composition; my 2 new tests pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -100,7 +100,12 @@ Transclusion = a `ref` leaf. Sort/filter/limit/group = the *source query* langua
|
||||
2. Wire it to objects: a document's `:body` is a composition node; `contains` forks carry order;
|
||||
`host/blog-render` dispatches to the render-fold when `:body` is present (else the legacy
|
||||
`sx_content` path). Card leaves render via the existing card-type `:template`.
|
||||
3. `each` source = a graph query (`(query is-a Event)` → `host/blog-instances-of`) — data-driven.
|
||||
3. **(done)** `each` source = a graph query: `(query is-a TYPE)` resolves via a `query`
|
||||
resolver injected into the render context (`host/blog--comp-ctx` binds
|
||||
`host/blog--comp-query` → `host/blog-instances-of` → records). compose.sx stays
|
||||
self-contained — it asks the context for the data; the host supplies graph access. The
|
||||
list isn't baked into the body; it's whatever is-a TYPE *right now*. (`/compose-demo`
|
||||
each is now a live query over seeded `compose-item` instances.)
|
||||
4. Live context: route auth/device/locale into the context; reactive values later.
|
||||
5. The typed importer decomposes Ghost Lexical into card objects + a `contains` body (cards-as-
|
||||
objects), instead of one `sx_content` string.
|
||||
|
||||
Reference in New Issue
Block a user