npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@xstate/solid

v1.0.0

Published

XState tools for SolidJS

Downloads

356

Readme

@xstate/solid

The @xstate/solid package contains utilities for using XState with SolidJS.

[[toc]]

Quick Start

  1. Install xstate and @xstate/solid:
npm i xstate @xstate/solid
  1. Import the useActor hook:
import { useActor } from '@xstate/solid';
import { createMachine } from 'xstate';

const toggleMachine = createMachine({
  id: 'toggle',
  initial: 'inactive',
  states: {
    inactive: {
      on: { TOGGLE: 'active' }
    },
    active: {
      on: { TOGGLE: 'inactive' }
    }
  }
});

export const Toggler = () => {
  const [snapshot, send] = useActor(toggleMachine);

  return (
    <button onclick={() => send({ type: 'TOGGLE' })}>
      {snapshot.value === 'inactive'
        ? 'Click to activate'
        : 'Active! Click to deactivate'}
    </button>
  );
};

API

useActor(logic, options?)

A SolidJS hook that interprets the given logic and starts an actor that runs for the lifetime of the component.

Arguments

  • logic

    // existing machine
    const [snapshot, send] = useMachine(machine);

Returns a tuple of [snapshot, send, actorRef]:

  • snapshot - Represents the current snapshot of the logic. This is a read-only value that is tracked by SolidJS for granular reactivity.
  • send - A function that sends events to the running service.
  • actorRef - The created service.

fromActorRef(actorRf)

A SolidJS hook that subscribes to emitted changes from an existing actor.

Arguments

  • actorRef - an actor object that contains .send(...) and .subscribe(...) methods. Allows SolidJS Signal (or function) to dynamically specify an actor.
const snapshot = fromActorRef(someSpawnedActor);

useActorRef(logic, options?)

A SolidJS hook that returns the actorRef created from the logic with the options, if specified. It starts the actor and runs it for the lifetime of the component. This is similar to useActor.

createService returns a static reference (to just the interpreted logic) which will not rerender when its snapshot changes.

Arguments

import { useActorRef } from '@xstate/solid';
import { someMachine } from '../path/to/someMachine';

const App = () => {
  const actorRef = useActorRef(someMachine);

  // ...
};

With options:

// ...

const App = () => {
  const service = useActorRef(someMachine, {
    input: {
      /* ... */
    }
  });

  // ...
};

Matching States

When using hierarchical and parallel machines, the state values will be objects, not strings. In this case, it is best to use state.matches(...).

The SolidJS Switch and Match Components are ideal for this use case:

const Loader = () => {
  const [snapshot, send] = useActor(/* ... */);

  return (
    <div>
      <Switch fallback={null}>
        <Match when={snapshot.matches('idle')}>
          <Loader.Idle />
        </Match>
        <Match when={snapshot.matches({ loading: 'user' })}>
          <Loader.LoadingUser />
        </Match>
        <Match when={snapshot.matches({ loading: 'friends' })}>
          <Loader.LoadingFriends />
        </Match>
      </Switch>
    </div>
  );
};

Persisted and Rehydrated State

You can persist and rehydrate state with useActor(...) via options.snapshot:

// ...

// Get the persisted state config object from somewhere, e.g. localStorage
const persistedSnapshot = JSON.parse(localStorage.getItem('some-persisted-state-key')) || someMachine.initialState;

const App = () => {
  const [snapshot, send] = useActor(someMachine, {
    snapshot: persistedSnapshot
  });

  // snapshot will rehydrate the provided persisted snapshot, it won't be the machine's initial snapshot

  return (/* ... */)
}

Actor refs

The actorRef created in useActor(logic) can be referenced as the third returned value:

//                  vvvvvvv
const [snapshot, send, actorRef] = useActor(someMachine);

You can subscribe to that actorRef's snapshot changes with the createEffect hook:

// ...

createEffect(() => {
  const subscription = actorRef.subscribe((snapshot) => {
    // simple snapshot logging
    console.log(snapshot);
  });

  onCleanup(() => subscription.unsubscribe());
}); // note: service should never change