Home - christoph-fricke/xsystem GitHub Wiki

Welcome to the documentation for XSystem.

The library contains building blocks for XState-based actor systems and utilities for composing behavior and simplifying the creation of behavior. Explore this wiki to learn more about the available features:

Installation

XSystem has a peer dependency to XState, which has to be installed as well. Currently, this library is bundled and distributed as an ES module.

npm i xstate xsystem

This package assumes that you already know how to use XState and you know your way around XState.

Quick Start

XSystem provides various components around actor communication and helpers. Explore the docs for more. This example highlights the usage of the provided event bus, which is probably the most used part of XSystem - at least for now.

import { createMachine, interpret } from "xstate";
import { spawnBehavior } from "xstate/lib/behaviors";
import { createEventBus, EventBus, fromActor } from "xsystem";

// Example events that might exist in an application
type SignupEvent =
  | { type: "signup.change_name"; name: string }
  | { type: "signup.change_password"; password: string };

type DashboardEvent =
  | { type: "dashboard.toggle_advanced" }
  | { type: "dashboard.usage.open" };

// Example event bus for events dispatched by a user.
// An application can contain multiple busses for different topics.
const userEventBus = spawnBehavior(
  createEventBus<SignupEvent | DashboardEvent>()
);

// Use the event bus in the codebase
function createSignupMachine(bus: EventBus<SignupEvent>) {
  return createMachine<{}, SignupEvent | { type: "abort" }>({
    id: "signup",
    // subscribe the machine to all signup events published by the bus
    invoke: { src: fromActor(bus, ["signup.*"]) },
    states: {
      SomeState: {
        on: {
          "signup.change_name": { target: "SomeState" },
          "signup.change_password": { target: "SomeState" },
          abort: { target: "SomeState" }, // Non bus events work just fine
        },
      },
    },
  });
}

// It is just XState after all. Use it like you would normally do.
const machine = interpret(createSignupMachine(userEventBus)).start();

// Publish events on the bus for example in the UI components
userEventBus.send({ type: "signup.change_name", name: "Mustermann" });

Future Work

  • Actor Registries: Better exchange references between actors to improve the actor-to-actor communication.
  • Cross Boundary Communication: Explore mechanisms to blur the line between actors running in a web worker and the main thread.
  • Community Feedback: The API is not final in any form. It will evolve with more feedback and suggestions.
  • Building Blocks: Behavior for actors that are commonly found in applications.
  • More Higher-Order Behavior: Common behavior that wraps other behavior. An existing example is withHistory.
  • Factories: Simplify the creation of behavior and possibly machine definitions with a functional builder pattern.