@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
npm install @xmachines/playAPI 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/playas the base protocol boundary. - Keep actor implementation details in adapter packages such as
@xmachines/play-xstate.
Related Packages
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
- Any object with a
type: stringproperty - Generic
TPayloadparameter 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:
- Actor Authority: Infrastructure proposes intents, Actor decides validity
- Strict Separation: No direct dependencies between layers
- Passive Infrastructure: Infrastructure observes Actor signals, never controls
- Signal-Only Reactivity: All state changes flow through TC39 Signals
- State-Driven Reset: Navigation follows state machine transition rules