start-sdk v2.0.4
What's Changed
Fixed
-
Daemons.dynamicnow composes withsetupMaininstead of replacing it.mainis alwayssdk.setupMain(...); what varies is theDaemonBuildableyou return from it — a staticsdk.Daemons.of(...)chain, or the reconciler for a runtime-varying daemon set. The OS ABI has always said as much (ExpectedExports.mainreturns aDaemonBuildable, and bothDaemonsandDaemonsReconcilerimplement it), but two signatures made that composition unwritable:setupMaindemanded aDaemonsrather than the ABI'sDaemonBuildable, andDaemons.dynamic(fn)returned amainexport — burying theDaemonsReconcilerit constructs inside a closure. The only shape that compiled was the wrong one: replacemainwithDaemons.dynamic(...), then nestDaemons.of()inside its builder. Packages adopting dynamic daemons were funnelled straight into it. Now:- Breaking —
Daemons.dynamictakeseffectsand returns the reconciler:sdk.Daemons.dynamic(effects, fn): DaemonsReconciler(wassdk.Daemons.dynamic(fn): main). Return it fromsetupMain. setupMain's callback is widened to the ABI: it accepts anyT.DaemonBuildable.
Migration — wrap the builder in
setupMainand passeffects:// before (2.0.0–2.0.3) export const main = sdk.Daemons.dynamic(async ({ effects }) => { return sdk.Daemons.of(effects).addDaemon(...) }) // after export const main = sdk.setupMain(async ({ effects }) => { return sdk.Daemons.dynamic(effects, async ({ effects }) => { return sdk.Daemons.of(effects).addDaemon(...) }) })
Reconcile semantics are unchanged: inside the builder,
constRetryreruns-and-reconciles rather than firingeffects.restart(), so a watched-state change touches only the daemons whoseconfigHashmoved and the service staysrunning. Reported in #3470 - Breaking —