Learn / Wiring

Why it exists, and whether you need it

Each integration used to ask the application to wire it by hand, in several places, each phrased differently — spread ...Remote.messages, add the Data.reduce branch, derive Data.subscriptions(active), provide the client layer, reduce the URL at startup, dispatch Prefs.restore after mounting. Every one of those steps compiles when missed and then silently does nothing: server results dropped, nothing fetched, shared links opening on defaults, drafts never restored.

The assembly turns the missed derivation into an error: complete() only accepts a config whose update takes the whole parent Message, whose subscriptions came from the assembly, and whose managedResources, init, and url came from the assembly wherever an item needs them (a placement with resources, a wiring with startup Commands, a wiring that reads the URL). Two items claiming one Message tag fail assemble at startup naming both (unless every claimant declares the tag shared: each folds it in turn, like per-name MirrorRestored and the URL Message).

Where the update already routes every placement, assembly.runtime({ initial, update, … }) builds the config instead of checking it: initial rest becomes init (or an init function returning assembly.initial(...) is used as init), and the own Subscriptions and Managed Resources default to the items'. The mistakes it can still make — a narrowed update, an unbranded init function, a missing url — are type errors at the property, as with complete.

Whether you need it depends on the size of the list:

  • One integration, hand-wired once, with a test that dispatches its Messages: the assembly buys little. Hand-wiring stays supported; every lower-level API remains.
  • Two or more integrations, or an application where the wiring author and the runtime author are different people: the list earns its keep, because a silently dropped step costs a debugging session and the assembly turns it into a named error.

Deleting a wiring line is caught where the wiring claims tags of its own. A wiring whose handles are typed as literals (Remote's are every RemoteMessage tag) takes those tags out of the Message assembly.update(own) hands own; an own that matches every tag it gets (Match.valueTags, a Message union's match) then fails to compile once the wiring is gone, since the tags come back unmatched. Two cases stay quiet: a wiring whose tags are all shared (a URL mirror's, a key-value mirror's MirrorRestored), since own sees those anyway, and an own written as a switch with no exhaustiveness check. There the loss shows up in behavior, which pinned transcripts and Message-level tests catch.