Skip to content

Latest commit

 

History

History
 
 

xstate-inspect

@xstate/inspect

This package contains inspection tools for XState.

Templates

Inspector running from CodeSandbox

Check out the XState + Vue Minute Timer + Viz example on CodeSandbox

Installation

  1. Install with npm or yarn:
npm install @xstate/inspect
# or yarn add @xstate/inspect

Via CDN

<script src="https://unpkg.com/@xstate/inspect/dist/xstate-inspect.umd.min.js"></script>

By using the global variable XStateInspect

  1. Import it at the beginning of your project, before any other code is called:
import { inspect } from '@xstate/inspect';

inspect({
  // options
  // url: 'https://stately.ai/viz?inspect', // (default)
  iframe: false // open in new window
});
  1. Add { devTools: true } to any interpreted machines you want to visualize:
import { interpret } from 'xstate';
import { inspect } from '@xstate/inspect';
// ...

const service = interpret(someMachine, { devTools: true });
service.start();

Configuration

  • url (optional) - The endpoint that the Inspector sends events to. Default: https://stately.ai/viz?inspect
  • iframe (optional) - The iframe that loads the provided URL. If iframe is set to false, then a new tab is opened instead.
  • devTools (optional) - Allows custom implementation for lifecycle hooks.
  • serialize (optional) - A custom serializer for messages sent to the URL endpoint. Useful for sanitizing sensitive information, such as credentials, from leaving your application.
  • targetWindow (optional) - Provide a pre-existing window location that will be used instead of opening a new window etc. When using this option, you must still provide the url value due to security checks in browser APIs, and the iframe option is ignored in such a case.

Examples

Add a custom serializer to @xstate/inspector events and transitions messages

When is this useful?

  • Remove sensitive items, such as credentials
  • Add additional custom handling
// Remove credentials from being forwarded
inspect({
  serialize: (key: string, value: any) => {
    return key === "credentials" && typeof value === "object" ? {} : value;
  },
});

// Add a custom local log
inspect({
  serialize: (key: string, value: any) => {
    if (key === "ready") {
      console.log("Detected ready key");
    }
    return value;
  },
});

Easily log all machine events and transitions

When is this useful?

  • Allows you to quickly see all events and transitions for your machines
  • No need to add manual console.log statements to your machine definitions
// The URL and port of your local project (ex. Vite, Webpack, etc).
const url = "http://127.0.0.1:5174/"

const inspector = inspect({
  url,
  iframe: undefined,
  targetWindow: window
});

// In the same window, subsribe to messages from @xstate/inspector
createWindowReceiver({}).subscribe(console.log);

// Start your machine, and all events generated are logged to the console
interpret(machine, { devTools: true }).start({});

Send events to a separate, locally hosted tool

When is this useful?

  • Forward messages to a custom endpoint, that you can then listen to and add custom handling for messages
// In your client application
const url = "http://127.0.0.1:8443/"
const targetWindow = window.open(url);

const inspector = inspect({
  // The URL must still be provided. This is used by postMessage, as it's
  // not possible to do targetWindow.location for security reasons
  url,
  targetWindow
});


// In the second, hosted application
createWindowReceiver({}).subscribe((event) => {
  if (event.type === "service.register") {
    // Do something when a new machine is started

  } else if (event.type === "service.stop") {
    // Do something when a machine enters a terminal state

  } else if (event.type === "service.event") {
    // Do something when a machine recieves an event

  } else if (event.type === "service.state") {
    // Do something when a machine enters to a new state
    // Note: Does not handle transitional states.
  }
});