Skip to content

Releases: statelyai/xstate

@xstate/[email protected]

14 Feb 12:26
08ade1a
Compare
Choose a tag to compare

Patch Changes

@xstate/[email protected]

10 Feb 14:34
a4f9ca3
Compare
Choose a tag to compare

Major Changes

  • #5175 38aa9f518ee2f9a5f481306a1dc68c0ad47d28d5 Thanks @davidkpiano! - The createStore 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! - The fromStore(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! - The createStoreWithProducer(…) function now only accepts two arguments: a producer 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 the context 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 the emits 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! - Added store.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.

[email protected]

12 Jan 18:45
3b43d84
Compare
Choose a tag to compare

Patch Changes

@xstate/[email protected]

12 Jan 18:45
3b43d84
Compare
Choose a tag to compare

@xstate/[email protected]

12 Jan 18:45
3b43d84
Compare
Choose a tag to compare

@xstate/[email protected]

12 Jan 18:45
3b43d84
Compare
Choose a tag to compare

@xstate/[email protected]

12 Jan 18:45
3b43d84
Compare
Choose a tag to compare

@xstate/[email protected]

12 Jan 18:45
3b43d84
Compare
Choose a tag to compare

[email protected]

24 Dec 19:13
e754939
Compare
Choose a tag to compare

Patch Changes

  • #5139 bf6119a7310a878afbf4f5b01f5e24288f9a0f16 Thanks @SandroMaglione! - Make spawn 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 } }
        )
      })
    });

@xstate/[email protected]

24 Dec 19:14
e754939
Compare
Choose a tag to compare