Upgrade owned lifetimes
For @arki/[email protected] · source docs/upgrade-ownership.md
This is a breaking minor release while Arki is pre-1.0. Upgrade @arki/async and @arki/dot together, rebuild packages that emit their types, and typecheck all reverse dependencies.
- Replace
scoped(async scope => ...)withscoped(plan, body). Useresource(open, close),cleanup(close)andchild(run)in the plan. The body receives successful resources and an owned signal. For dependent acquisition, nest a second scope inside the first body's closure. - Use
dynamicScope([YourRefusal, ...]).run(body)only when work is selected at runtime. Supply original canonical definitions; each admitted callback is checked against their inferred failure union. Validate unknown external output before admission. An explicitly unknown body result stays unknown and cannot promise an exact failure union. - Move partial provider cleanup into
resourcedescriptors. Return private resource/child plans fromboot. Remove the corresponding manual cleanup from legacy disposal hooks to avoid double release. A failed provider never publishes a value. - Check
isFailureafter synchronous configure and awaited boot/start/stop/get/dispose calls. Propagate a refusal unchanged inside the app. At HTTP or process boundaries, translate it into the protocol's safe failure response or unsuccessful exit. Test assertions may useorThrow; a library compatibility wrapper that throws every returned failure defeats the new contract. - Derive success shapes with
SuccessOf<typeof operation>. Do not annotate an inferred plugin with a two-parameterPlugintype that drops its ownership metadata. Generic wrappers preserve the original plugin type or its inferred ownership parameters. - Treat lazy failures as failed attempts.
initializedremains false andpeek()stays empty. A subsequent explicit get can retry. Disposal closes admission, joins initialization and returns its cached cleanup outcome.lazyOfborrows an existing value and never closes it. - Replace assumptions that a timeout ends work. Owned deadlines request cancellation and join admitted work before finalization. Await the original work; an early-returning timeout helper does not own a still-running callback. Test late settlement with
MockClockand an explicit completion gate. - Read local aggregate members from the inferred
ScopeFailed.cause. Public counts survive serialization; private causes do not. Revive with the canonicalScopeFaileddefinition and handle a summary, without casting it into a local generic aggregate. - Let
createAppRuntimewait for HMR disposal. A failed release blocks replacement ownership. HandleRuntimeReleaseFailedandRuntimeReplacedat the hosting boundary instead of creating another pool alongside uncertain resources. ProvidesFactories<Needs, Returns>and an explicitdefineFeature(...).provides<Returns>(...)type argument now describe raw callback returns, includingPromise<T>for an async factory. Service handles and boot callbacks still receive resolved values. Prefer inferring the factory record and deriving wrapper types withtypeof factories; a manual annotation using only resolved values must be updated. This keeps contextual provider inference and failure validation on the same source.
The shared lifetime engine applies to app tasks, requests, jobs and workflow attempts. Their transport and durable execution adapters adopt it in their own migration steps. This release does not claim those integrations are already complete. Dot’s managed phases now return inferred failures; see Upgrade typed phases. Request, job and workflow adapters remain separate migration work.