Svelte

Derived from:

XState Svelte Template

Starting with a svelte project (If using rollup consult install docs here):

Usage with Svelte | XState Docs

App.svelte

<script>
  import { useMachine } from "./useMachine";
  import Button from "./Button.svelte";
  import AnotherComp from "./AnotherComp.svelte";
  import { state, send } from "./toggleMachine";

  $: active = $state.matches("active");
  $: count = $state.context.count;
</script>

<style>
  main {
    font-family: sans-serif;
    text-align: center;
  }
</style>

<main>
  <h1>XState Svelte Template</h1>
  <h2>Fork this template!</h2>
  <button on:click={() => send("TOGGLE")}>
    Click me ({active ? "✅" : "❌"})
  </button>{" "}
  <code>
    Toggled <strong>{count}</strong> times
  </code>
  <AnotherComp />
</main>

Button.svelte

<script>
	let count = 0;

	function handleClick() {
	  count += 1;
	}
</script>

<style>
	button {
	  background: #ff3e00;
	  color: white;
	  border: none;
	  padding: 8px 12px;
	  border-radius: 2px;
	}
</style>

<button on:click={handleClick}>
  Clicked {count} {count === 1 ? 'time' : 'times'}
</button>

AnotherComp.svelte

<script>
  import { useMachine } from "./useMachine";
  import { state, send } from "./toggleMachine.js";

  $: count = $state.context.count;
</script>

<p>Test count: {count}</p>

toggleMachine.js

import { createMachine, assign } from "xstate";
import { useMachine } from "./useMachine";

export const toggleMachine = createMachine({
  id: "toggle",
  initial: "inactive",
  context: {
    count: 0
  },
  states: {
    inactive: {
      on: { TOGGLE: "active" }
    },
    active: {
      entry: assign({ count: (ctx) => ctx.count + 1 }),
      on: { TOGGLE: "inactive" }
    }
  }
});

export const { state, send } = useMachine(toggleMachine);

useMachine.js

import { readable } from "svelte/store";
import { interpret } from "xstate";

export function useMachine(machine, options) {
  const service = interpret(machine, options);

  const store = readable(service.initialState, set => {
    service.onTransition(state => {
      set(state);
    });

    service.start();

    return () => {
      service.stop();
    };
  });

  return {
    state: store,
    send: service.send
  };
}

Conclusion

This app shares global state between two components using a shim between stores and the xstate state machines. It's an extremely simple example that increments the toggle for every uncheck of the toggle.