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.