Lifecycle and independent-hook migration
Beta.14 and earlier exposed cleanup. Its optional early-teardown path could
reuse a stopped shared adapter after the final view disconnected. The option
is removed; shared observation now lasts until terminal core disposal.
Remove the cleanup key from source-backed configuration. This includes
cleanup: false and explicitly supplied cleanup: undefined. Dedicated source
entrypoints reject the key before acquiring the source, including JavaScript and
prebuilt configurations. There is no replacement flag.
The first fragment assumes actor is an existing application-owned XState source.
import { igniteCore } from "ignite-element/xstate";
// actor is an existing application-owned source.const counter = igniteCore({ source: actor, states: snapshot => ({ count: snapshot.context.count }), commands: ({ source }) => ({ increment: () => source.send({ type: "INCREMENT" }), }),});An independent custom element releases its private runtime on true disconnect;
a same-turn move preserves it. A shared view releases its own observation handles
on disconnect. Its core retains application-level observation and activated
effects, including while no views are connected. At final application shutdown,
call counter.dispose(), then perform any application-owned native shutdown.
Disposal is terminal; a shorter session needs a newly created source/core for
its next session. Do not reconnect a disposed singleton.
useIgnite(core) provides independent runtimes for XState machines, Redux slices
and factories returning fresh Redux stores or MobX observables. Each hook now
owns private state and releases it automatically on unmount. A genuine remount
starts fresh. Existing-source hooks remain shared and release only their view
subscription; they do not dispose the core.
This alternative fragment assumes machine is defined by your behavior module.
// With the XState machine from your behavior module:const independentCounter = igniteCore({ source: machine, states: snapshot => ({ count: snapshot.context.count }), commands: ({ source }) => ({ increment: () => source.send({ type: "INCREMENT" }), }),});// Each component calls: const ctx = useIgnite(independentCounter)Remove preparation-only core.get("states") from independent hook setup.
Preparing a machine-backed headless runtime no longer makes hooks share it.
When sharing is intended, construct an existing source outside rendering and
pass that instance, as in the first example. Explicit headless operations stay
attached to their own runtime for independent inputs.
Independent factories and initialization must be safe to repeat and discard without external work or resources requiring cleanup. This includes context and reducer initialization, Redux middleware/enhancer setup, observable construction, projections and command setup. Ignite defers its own activation, not arbitrary work performed by a factory. Return a fresh source, not the same singleton. The hook remains synchronous; no Provider, loading value or cleanup hook is added.