05 Plug n Play Behavior - christoph-fricke/xsystem GitHub Wiki

Plug n' Play behaviors provide common functionality that is ready-to-use and can be spawned directly without further effort.

createWebSocket

Factory that transforms a given WebSocket into a behavior. The behavior publishes events that are received as messages from the WebSocket connection. Events are published through the existing pub/sub mechanisms. Events that are send to an actor spawned from this behavior are forwarded to the open WebSocket connection. In case the socket is not open, the events are queued until the connection opens to prevent throwing an exception when the socket is still connecting.

Unlike other implementations, this behavior does not manage its own connection state explicitly. Instead, the state is derived from the WebSocket's readyState to enure that it reflects the real WebSocket connection state.

A filter function can be passed to the behavior factory as an option, which is called with every event that is received from the WebSocket before it is published. If the filter returns false, the event will be discarded and not published to subscribers.

import { spawnBehavior } from "xstate/lib/behaviors";
import { createWebSocket } from "xsystem";

type Sendable = { type: "ping" };
type Receivable = { type: "pong" };

const actor = spawnBehavior(
  createWebSocket<Sendable, Receivable>(() => new WebSocket("ws://url.local"))
);

// Use it like any other publisher actor. Subscribe etc. ... or send events on the connection
actor.send({ type: "ping" });

// With optional filter to discard non-matching events
const actor2 = spawnBehavior(
  createWebSocket<Sendable, Receivable>(() => new WebSocket("ws://url.local"), {
    filter: (e) => e.type === "pong",
  })
);

createData

Creates a behavior that stores some generic data in an actor's state. It acts a simple value store. The stored data can be updated with a set event or reset with a reset event. As with any actor state, the data can be accessed through actor.getSnapshot().

import { spawnBehavior } from "xstate/lib/behaviors";
import { createData, set, reset } from "xsystem";

// Create an actor containing the initial data as state.
const store = spawnBehavior(createData("Hello World"));
store.getSnapshot(); // => "Hello World"

// Replace the stored data
store.send(set("Hello Again"));
store.getSnapshot(); // => "Hello Again"

// Reset the stored data
store.send(reset());
store.getSnapshot(); // => "Hello World"

Furthermore, the behavior is able to process update events, which behave like set events with a small quirk. When the actor stores an object as data, the update event provides the possibility for partial updates. New partial data send with an update event are shallow merged with the current state.

import { spawnBehavior } from "xstate/lib/behaviors";
import { createData, update } from "xsystem";

// Create an actor containing the initial data as state.
const store = spawnBehavior(
  createData({ id: 42, name: "dryer", manufacturer: "A company" })
);
store.getSnapshot(); // => { id: 42, name: "dryer", manufacturer: "A company" }

// Partially update the name of the stored product
store.send(update({ name: "dishwasher" }));
store.getSnapshot(); // => { id: 42, name: "dishwasher", manufacturer: "A company" }