Skip to content

@xmachines/play

Documentation / @xmachines/play

Protocol layer defining Actor ↔ Infrastructure event contracts for XMachines Play Architecture.

@xmachines/play is intentionally small. It provides the base event contract used across adapters and actor implementations while keeping framework/runtime concerns out of business logic.

Overview

This package exports protocol types only (no runtime behavior). It exists to preserve strict separation between:

  • Actors (business authority)
  • Infrastructure adapters (routers/renderers that observe and forward)

Per RFC Play v1, this package supports:

  • Actor Authority (INV-01): infrastructure proposes intents, actor decides validity
  • Strict Separation (INV-02): protocol types are framework-agnostic
  • Passive Infrastructure (INV-04): adapters reflect actor decisions

Installation

Terminal window
npm install @xmachines/play

API Surface

This package exports:

  • PlayEvent<TPayload>

PlayEvent is the minimal event shape:

type PlayEvent<TPayload extends Record<string, any> = Record<string, any>> = {
readonly type: string;
} & TPayload;

Usage

Base event usage

import type { PlayEvent } from "@xmachines/play";
type LoginEvent = PlayEvent<{ userId: string }>;
const event: LoginEvent = {
type: "auth.login",
userId: "user-123",
};

Architecture Notes

  • Keep @xmachines/play as the base protocol boundary.
  • Keep actor implementation details in adapter packages such as @xmachines/play-xstate.

License

Copyright (c) 2016 Mikael Karon. All rights reserved.

This work is licensed under the terms of the MIT license.
For a copy, see https://opensource.org/licenses/MIT.

@xmachines/play - Core Protocol Layer

Defines architectural contracts enabling Actor ↔ Infrastructure communication without direct dependencies. Per RFC section 5.2, these protocols establish the foundation for loose coupling between business logic and runtime adapters.

Exports

PlayEvent - Generic event type for Actor communication

  • Any object with a type: string property
  • Generic TPayload parameter for type-safe event shapes (optional)
  • Defaults to Record<string, unknown> for maximum flexibility
  • Framework-agnostic (not tied to XState or any specific library)

Usage:

// Flexible (default):
const event: PlayEvent = { type: "auth.login", userId: "123" };
// Type-safe (with generic):
type LoginEvent = PlayEvent<{ userId: string }>;
const event: LoginEvent = { type: "auth.login", userId: "123" };

Common Event Patterns:

  • Domain events: { type: 'auth.login', userId: '123' }
  • Custom events: { type: 'form.submit', data: {...} }

Routing Events are provided by @xmachines/play-router:

  • PlayRouteEvent: Enhanced routing with parameters and state ID targeting
  • RouterBridge: Protocol for router adapters to connect with actors

Browser Navigation: Browser back/forward buttons are handled by router adapters via the popstate event. When users press back/forward, the router detects the URL change and sends a PlayRouteEvent to the actor for validation.

import type { PlayRouteEvent, RouterBridge } from "@xmachines/play-router";

Architectural Invariants

These protocols enforce the following invariants:

  1. Actor Authority: Infrastructure proposes intents, Actor decides validity
  2. Strict Separation: No direct dependencies between layers
  3. Passive Infrastructure: Infrastructure observes Actor signals, never controls
  4. Signal-Only Reactivity: All state changes flow through TC39 Signals
  5. State-Driven Reset: Navigation follows state machine transition rules

Type Aliases