# XState 6.0.0-alpha.47 - Product: XState (https://whatsnew.fyi/product/xstate) - Vendor: Stately - Date: 2026-08-23 - Version: 6.0.0-alpha.47 - Original notes: https://github.com/statelyai/xstate/releases/tag/xstate%406.0.0-alpha.47 - Permalink: https://whatsnew.fyi/product/xstate/releases/6.0.0-alpha.47 - Labels: Pre-release What's New is an index, not a publisher: every entry below links to the vendor's own release notes, which are the authoritative source. Entries are labelled where they are hand-curated sample data, pre-releases, or drawn from a secondary source such as a developer blog. Reuse: the summaries, labels and curation here are © What's New. Quote freely with attribution and a link back; wholesale republication of the corpus is not permitted — terms: https://whatsnew.fyi/terms. The vendors' own release notes remain their publishers'. --- - **changed** — Guard and delay source functions are now contextually typed from schemas in setup(), .extend(), and createMachine(), so inline functions get typed context and event without hand annotations - **changed** — enq.stop(), enq.listen(), and enq.subscribeTo() now accept any ActorRef instead of requiring the full actor instance type returned by enq.spawn() - **added** — Document durable timer semantics for event-journal hosts - **changed** — Restoring an externally migrated live snapshot now treats its machine property as a runtime association rather than persisted version metadata - **changed** — getNextTransitions(snapshot) returns an empty array for completed or errored snapshots - **changed** — Setup-created machines whose input schema accepts undefined no longer require a meaningless input property when other actor options are provided - **added** — Durable adapters can implement enqueueRootEvent when the host owns only the execution root's mailbox, without overriding delivery for co-located actors - **changed** — Implement sendEvent only when the host owns routing for every target; use deliverEvent for co-located delivery ###### Minor Changes - 72938f8: Guard and delay source functions are now contextually typed from `schemas` — in `setup({ ... })`, `.extend({ ... })`, and `createMachine({ ... })` — so inline functions get typed `context` and `event` without hand annotations: ```ts const s = setup({ schemas: { context: z.object({ count: z.number() }), events: { INC: z.object({ by: z.number() }) } }, guards: { // context: { count: number }, event: { type: 'INC'; by: number } isPositive: ({ context }) => context.count > 0, // additional params after the args object are free-form isAbove: ({ context }, threshold: number) => context.count > threshold }, delays: { backoff: ({ context }) => context.count * 100 } }); ``` Guard sources receive the transition args object first (`{ context, event, self, parent, value, children }`), followed by any caller-supplied params — matching how the runtime invokes referenced guards. Delay sources receive `{ context, event, stateNode }`. Additionally, `enq.stop(...)`, `enq.listen(...)`, and `enq.subscribeTo(...)` now accept any `ActorRef` (such as values typed with `ActorRefFrom`), instead of requiring the full actor instance type returned by `enq.spawn(...)`. ###### Patch Changes - 6ecc2df: Document durable timer semantics for event-journal hosts. - fc7454f: Restoring an externally migrated live snapshot now treats its `machine` property as a runtime association rather than persisted version metadata. Persisted snapshots continue validating their nested `{ id, version }` identity and legacy top-level `version` together. `getNextTransitions(snapshot)` returns an empty array for completed or errored snapshots. Setup-created machines whose input schema accepts `undefined` no longer require a meaningless `input` property when other actor options are provided, including after `machine.provide(...)`. Durable adapters can implement `enqueueRootEvent` when the host owns only the execution root's mailbox, without overriding delivery for co-located actors: ```ts const durable = createDurable(machine, { enqueueRootEvent: (_source, event) => host.enqueue(event), executeAction, waitForEvent }); ``` Implement `sendEvent` only when the host owns routing for every target; use `deliverEvent` for co-located delivery. Durable replay guidance now explicitly covers inline entry and exit callbacks.