Bundle / foldkit-bundle-surface

Reading a placement: projections and Mirrors

A placement's state is part of the parent Model, so its fields are already in the application's ref tree. Observing one needs no bundle API: App.model.search.query, App.model.search.select(projection).

For an application with search and filter placements, the following integration fragment gives each mirror its own keys. Import Mirror from foldkit-mirror; the first example above defines only search:

ts
const SearchUrl = Mirror.url(App, {
  name: 'search',
  fields: [App.model.search.query],
  keys: { query: { key: 'search.q' } },
})
const FilterUrl = Mirror.url(App, {
  name: 'filter',
  fields: [App.model.filter.query],
  keys: { query: { key: 'filter.q' } },
})

test/mirror.test.ts writes and reads both.

Why placements are not re-rooted Surfaces

A Surface names the Messages a feature may cause by their parent constructors, and an agent adapter exposes one capability per constructor. Every Message of a placement travels under one wrapper variant, GotSearchMessage({ message }), so a re-rooted Surface could only offer that single variant, not the child's individual Messages. Exposing a placement's Messages one by one needs Surface and Agent to understand wrapped variants, which is a change to those packages rather than a helper here. Until then, declare a parent Surface over the placement's fields and name the wrapper variant in its messages.

Limits

  • A Link composed with Link.andThen (or Link.compose) from a ref-built Link names the application passed to contract, not the ref's.
  • Surfaces cannot expose a placement's individual child Messages, for the reason above.