Releases: statelyai/xstate
@xstate/store@3.1.0
Minor Changes
-
#5205
65784aef746b6249a9c3d71d9e4a7c9b454698c8
Thanks @davidkpiano! - AddedcreateStoreConfig
to create a store config from an object. This is an identity function that returns the config unchanged, but is useful for type inference.const storeConfig = createStoreConfig({ context: { count: 0 }, on: { inc: (ctx) => ({ ...ctx, count: ctx.count + 1 }) } }); // Reusable store config: const store = createStore(storeConfig); // ... function Comp1() { const store = useStore(storeConfig); // ... } function Comp2() { const store = useStore(storeConfig); // ... }
-
#5205
65784aef746b6249a9c3d71d9e4a7c9b454698c8
Thanks @davidkpiano! - There is now auseStore()
hook that allows you to create a local component store from a config object.import { useStore, useSelector } from '@xstate/store/react'; function Counter() { const store = useStore({ context: { name: 'David', count: 0 }, on: { inc: (ctx, { by }: { by: number }) => ({ ...ctx, count: ctx.count + by }) } }); const count = useSelector(store, (state) => state.count); return ( <div> <div>Count: {count}</div> <button onClick={() => store.trigger.inc({ by: 1 })}> Increment by 1 </button> <button onClick={() => store.trigger.inc({ by: 5 })}> Increment by 5 </button> </div> ); }
Patch Changes
- #5205
65784aef746b6249a9c3d71d9e4a7c9b454698c8
Thanks @davidkpiano! - ThecreateStoreWithProducer(config)
function now accepts anemits
object.
@xstate/store@3.0.1
Patch Changes
- #5197
5e05d5908093bfd3435dc2243e066e4e91b3ebc5
Thanks @davidkpiano! - The emitted event type can no longer be accidentally overridden in the emitted event payload. See #5196 for the issue.
@xstate/store@3.0.0
Major Changes
-
#5175
38aa9f518ee2f9a5f481306a1dc68c0ad47d28d5
Thanks @davidkpiano! - ThecreateStore
function now only accepts a single configuration object argument. This is a breaking change that simplifies the API and aligns with the configuration pattern used throughout XState.// Before // createStore( // { // count: 0 // }, // { // increment: (context) => ({ count: context.count + 1 }) // } // ); // After createStore({ context: { count: 0 }, on: { increment: (context) => ({ count: context.count + 1 }) } });
-
#5175
38aa9f518ee2f9a5f481306a1dc68c0ad47d28d5
Thanks @davidkpiano! - You can now enqueue effects in state transitions.const store = createStore({ context: { count: 0 }, on: { incrementDelayed: (context, event, enq) => { enq.effect(async () => { await new Promise((resolve) => setTimeout(resolve, 1000)); store.send({ type: 'increment' }); }); return context; }, increment: (context) => ({ count: context.count + 1 }) } });
-
#5175
38aa9f518ee2f9a5f481306a1dc68c0ad47d28d5
Thanks @davidkpiano! - ThefromStore(config)
function now only supports a single config object argument.const storeLogic = fromStore({ context: (input: { initialCount: number }) => ({ count: input.initialCount }), on: { inc: (ctx, ev: { by: number }) => ({ ...ctx, count: ctx.count + ev.by }) } });
-
#5175
38aa9f518ee2f9a5f481306a1dc68c0ad47d28d5
Thanks @davidkpiano! - ThecreateStoreWithProducer(…)
function now only accepts two arguments: aproducer
and a config ({ context, on }
) object.// Before // createStoreWithProducer( // producer, // { // count: 0 // }, // { // increment: (context) => { // context.count++; // } // } // ); // After createStoreWithProducer(producer, { context: { count: 0 }, on: { increment: (context) => { context.count++; } } });
-
#5175
38aa9f518ee2f9a5f481306a1dc68c0ad47d28d5
Thanks @davidkpiano! - Only complete assigner functions that replace thecontext
fully are supported. This is a breaking change that simplifies the API and provides more type safety.const store = createStore({ context: { items: [], count: 0 }, on: { - increment: { count: (context) => context.count + 1 } - increment: (context) => ({ count: context.count + 1 }) + increment: (context) => ({ ...context, count: context.count + 1 }) } })
-
#5175
38aa9f518ee2f9a5f481306a1dc68c0ad47d28d5
Thanks @davidkpiano! - Emitted event types are now specified in functions on theemits
property of the store definition:const store = createStore({ // … emits: { increased: (payload: { upBy: number }) => { // You can execute a side-effect here // or leave it empty } }, on: { inc: (ctx, ev: { by: number }, enq) => { enq.emit.increased({ upBy: ev.by }); // … } } });
Minor Changes
-
#5175
38aa9f518ee2f9a5f481306a1dc68c0ad47d28d5
Thanks @davidkpiano! - Addedstore.trigger
API for sending events with a fluent interface:const store = createStore({ context: { count: 0 }, on: { increment: (ctx, event: { by: number }) => ({ count: ctx.count + event.by }) } }); // Instead of manually constructing event objects: store.send({ type: 'increment', by: 5 }); // You can now use the fluent trigger API: store.trigger.increment({ by: 5 });
The
trigger
API provides full type safety for event names and payloads, making it easier and safer to send events to the store.
xstate@5.19.2
Patch Changes
- #5170
d99df1d8f4fe49145c9974465b65028bf19b365f
Thanks @Andarist! - Improved compatibility of inferred types in projects withexactOptionalPropertyTypes
enabled
@xstate/vue@4.0.2
Patch Changes
- Updated dependencies [
d99df1d8f4fe49145c9974465b65028bf19b365f
]:- xstate@5.19.2
@xstate/svelte@4.0.3
Patch Changes
- Updated dependencies [
d99df1d8f4fe49145c9974465b65028bf19b365f
]:- xstate@5.19.2
@xstate/solid@1.0.2
Patch Changes
- Updated dependencies [
d99df1d8f4fe49145c9974465b65028bf19b365f
]:- xstate@5.19.2
@xstate/react@5.0.2
Patch Changes
- Updated dependencies [
d99df1d8f4fe49145c9974465b65028bf19b365f
]:- xstate@5.19.2
@xstate/graph@3.0.2
Patch Changes
- Updated dependencies [
d99df1d8f4fe49145c9974465b65028bf19b365f
]:- xstate@5.19.2
xstate@5.19.1
Patch Changes
-
#5139
bf6119a7310a878afbf4f5b01f5e24288f9a0f16
Thanks @SandroMaglione! - Makespawn
input required when defined inside referenced actor:const childMachine = createMachine({ types: { input: {} as { value: number } } }); const machine = createMachine({ types: {} as { context: { ref: ActorRefFrom<typeof childMachine> } }, context: ({ spawn }) => ({ ref: spawn( childMachine, // Input is now required! { input: { value: 42 } } ) }) });