Releases: statelyai/xstate
@xstate/store@3.12.0
Minor Changes
-
#5410
45d97deThanks @davidkpiano! - Fix go-to-definition for triggers -
#5414
524a207Thanks @davidkpiano! - Computed atoms can now access their previous value via an optional second parameter:const count = createAtom(1); const double = createAtom<number>((_, prev) => count.get() + (prev ?? 0));
xstate@5.24.0
Minor Changes
-
#5371
b8ec3b1Thanks @davidkpiano! - Addsetup.extend()method to incrementally extend machine setup configurations with additional actions, guards, and delays. This enables composable and reusable machine setups where extended actions, guards, and delays can reference base actions, guards, and delays and support chaining multiple extensions:import { setup, not, and } from 'xstate'; const baseSetup = setup({ guards: { isAuthenticated: () => true, hasPermission: () => false } }); const extendedSetup = baseSetup.extend({ guards: { // Type-safe guard references isUnauthenticated: not('isAuthenticated'), canAccess: and(['isAuthenticated', 'hasPermission']) } }); // Both base and extended guards are available extendedSetup.createMachine({ on: { LOGIN: { guard: 'isAuthenticated', target: 'authenticated' }, LOGOUT: { guard: 'isUnauthenticated', target: 'unauthenticated' } } });
@xstate/store@3.11.2
Patch Changes
- #5401
d345e1fThanks @davidkpiano! - - Fix type inference for emitted event types when usingundoRedo.
@xstate/store@3.11.1
Patch Changes
- #5395
8408430Thanks @davidkpiano! - Fix redo logic bug where redo would apply too many events when no transaction grouping is used
@xstate/store@3.11.0
Minor Changes
-
#5393
6d00d3fThanks @davidkpiano! - Addsnapshotparameter togetTransactionIdfunction.const store = createStore( undo( { // ... }, { getTransactionId: (event, snapshot) => snapshot.context.currentTransactionId } ) );
-
#5392
5854b52Thanks @davidkpiano! - Added an overload touseSelectorthat allows you to select the entire snapshot:// No selector provided, return the entire snapshot const snapshot = useSelector(store);
-
#5393
6d00d3fThanks @davidkpiano! - AddskipEventoption toundoRedo()to exclude certain events from undo/redo history.const store = createStore( undoRedo( { context: { count: 0 }, on: { inc: (ctx) => ({ count: ctx.count + 1 }), log: (ctx) => ctx // No state change } }, { skipEvent: (event, snapshot) => event.type === 'log' } ) );
xstate@5.23.0
Minor Changes
-
#5387
53dd7f1Thanks @farskid! - Addssystem.getAllthat returns a record of running actors within the system by their system idconst childMachine = createMachine({}); const machine = createMachine({ // ... invoke: [ { src: childMachine, systemId: 'test' } ] }); const system = createActor(machine); system.getAll(); // { test: ActorRefFrom<typeof childMachine> }
@xstate/store@3.10.0
Minor Changes
-
#5323
cb08332Thanks @davidkpiano! - Added support for effect-only transitions that don't trigger state updates. Now, when a transition returns the same state but includes effects, subscribers won't be notified of a state change, but the effects will still be executed. This helps prevent unnecessary re-renders while maintaining side effect functionality.it('should not trigger update if the snapshot is the same even if there are effects', () => { const store = createStore({ context: { count: 0 }, on: { doNothing: (ctx, _, enq) => { enq.effect(() => { // … }); return ctx; // Context is the same, so no update is triggered // This is the same as not returning anything (void) } } }); const spy = vi.fn(); store.subscribe(spy); store.trigger.doNothing(); store.trigger.doNothing(); expect(spy).toHaveBeenCalledTimes(0); });
@xstate/store@3.9.3
Patch Changes
- #5383
4b6a513Thanks @davidkpiano! - Fix:triggermethods now work when passed directly as event handlers, even for events with no payload. Before, the Reactevent.typewould overwrite the intended event type.
xstate@5.22.1
Patch Changes
-
#5379
98f9dddThanks @davidkpiano! - Makeactor.systemIdpublic:const actor = createActor(machine, { systemId: 'test' }); actor.systemId; // 'test'
-
#5380
e7e5e44Thanks @Nirajkashyap! - fix: remove 'eventType' from required fields in initialTransitionObject
xstate@5.22.0
Minor Changes
-
#5367
76c857eThanks @davidkpiano! - Add type-bound action helpers tosetup():createAction(fn)– create type-safe custom actionssetup().assign(...),setup().sendTo(...),setup().raise(...),setup().log(...),setup().cancel(...),setup().stopChild(...),setup().enqueueActions(...),setup().emit(...),setup().spawnChild(...)– setup-scoped helpers that are fully typed to the setup's context/events/actors/guards/delays/emitted.
These helpers return actions that are bound to the specific
setup()they were created from and can be used directly in the machine produced by that setup.const machineSetup = setup({ types: {} as { context: { count: number; }; events: { type: 'inc'; value: number } | { type: 'TEST' }; emitted: { type: 'PING' }; } }); // Custom action const action = machineSetup.createAction(({ context, event }) => { console.log(context.count, event.value); }); // Type-bound built-ins (no wrapper needed) const increment = machineSetup.assign({ count: ({ context }) => context.count + 1 }); const raiseTest = machineSetup.raise({ type: 'TEST' }); const ping = machineSetup.emit({ type: 'PING' }); const batch = machineSetup.enqueueActions(({ enqueue, check }) => { if (check(() => true)) { enqueue(increment); } }); const machine = machineSetup.createMachine({ context: { count: 0 }, entry: [action, increment, raiseTest, ping, batch] });