@xmachines/play-solid
API / @xmachines/play-solid
Solid renderer for XMachines Play architecture
SolidJS rendering layer that passively observes actor signals and renders UI components via @json-render/solid. SolidJS reactivity is used solely to trigger re-renders — TC39 Signals are the source of truth.
Part of the xmachines-js monorepo.
Installation
npm install @xmachines/play-solidPeer dependencies — install alongside the package:
npm install solid-js xstate @xstate/store @json-render/solid @json-render/core @json-render/xstateQuick Start
import { PlayUIProvider, PlayRenderer, defineRegistry } from "@xmachines/play-solid";import { definePlayer } from "@xmachines/play-xstate";import { defineCatalog } from "@json-render/core";import { schema } from "@json-render/solid/schema";
// 1. Define a catalog (authCatalogDef is a plain object describing components/actions)const catalog = defineCatalog(schema, authCatalogDef);
// 2. Build a component registryconst registryResult = defineRegistry(catalog, { components: { Home: () => <div>Welcome home!</div>, Login: (ctx) => <div>Login {ctx.props.error && <span>{ctx.props.error}</span>}</div>, }, actions: { login: async (args) => actor.send({ type: "auth.login", username: args.username }), logout: async () => actor.send({ type: "auth.logout" }), },});
// 3. Create and start an actorconst createPlayer = definePlayer({ machine: myMachine });const actor = createPlayer();actor.start();
// 4. Renderfunction App() { return ( <PlayUIProvider actor={actor} registryResult={registryResult}> <PlayRenderer /> </PlayUIProvider> );}Usage
PlayUIProvider + PlayRenderer (recommended)
PlayUIProvider is the batteries-included entry point. It wraps ActorProvider and JSONUIProvider into a single composite provider. PlayRenderer is a zero-prop leaf component that reads view context and renders the current spec.
import { PlayUIProvider, PlayRenderer, defineRegistry } from "@xmachines/play-solid";
<PlayUIProvider actor={actor} registryResult={registryResult} fallback={<div>Loading…</div>} onError={(err) => console.error(err)} navigate={navigateFn} // optional: passed to JSONUIProvider validationFunctions={valFns} // optional: form validation helpers> <PlayRenderer /></PlayUIProvider>;ActorProvider (escape hatch)
For library authors who need direct control over provider composition:
import { ActorProvider, PlayRenderer } from "@xmachines/play-solid";
<ActorProvider actor={actor} registryResult={registryResult}> <PlayRenderer /></ActorProvider>;useActor hook
Access the raw actor instance anywhere inside an ActorProvider or PlayUIProvider tree:
import { useActor } from "@xmachines/play-solid";
function SubmitButton() { const actor = useActor(); return <button onClick={() => actor.send({ type: "SUBMIT" })}>Submit</button>;}usePlayView hook
Access the resolved view context (spec, handlers, registry, store) from within the provider tree:
import { usePlayView } from "@xmachines/play-solid";import { Renderer } from "@json-render/solid";
const MyRenderer = () => { const view = usePlayView(); return <Renderer spec={view.spec} registry={view.registry} />;};API Summary
Components
| Export | Description |
|---|---|
PlayUIProvider | Batteries-included composite provider (recommended entry point) |
PlayRenderer | Zero-prop leaf component; renders the current view spec inside a provider tree |
ActorProvider | Lower-level smart provider for escape-hatch composition |
Hooks
| Export | Description |
|---|---|
useActor() | Returns the raw AnyPlayActor instance from context; throws outside a provider tree |
usePlayView() | Returns the current ViewContextValue (spec, handlers, registry, store); throws outside tree |
Context
| Export | Description |
|---|---|
ActorContext | SolidJS context for the actor; use ActorContext.Provider directly as an escape hatch |
Re-exports from @json-render/solid
This package re-exports the full @json-render/solid public API so consumers do not need a direct dependency:
import { // Providers JSONUIProvider, StateProvider, ActionProvider, VisibilityProvider, ValidationProvider, // Renderer Renderer, // Registry factory + hooks defineRegistry, useBoundProp, useStateBinding, useStateValue, useStateStore, useActions, useAction, useIsVisible, useFieldValidation, useOptionalValidation, useVisibility,} from "@xmachines/play-solid";Key Types
| Type | Description |
|---|---|
PlayUIProviderProps | Props for PlayUIProvider |
ActorProviderProps | Props for ActorProvider |
ViewContextValue | Shape of the context value from usePlayView() |
AnyPlayActor | AbstractActor<AnyActorLogic> — bare actor type accepted by context providers |
Testing
Run tests for this package in isolation:
npm test -w packages/play-solidOr from within the package directory:
npm test # single run (jsdom environment)npm run test:watch # watch modenpm run test:ui # interactive Vitest UICoverage is collected with v8 (80% threshold for lines, functions, branches, and statements). Browser-specific tests live in test/browser/ and are excluded from the default jsdom run.
License
MIT
@xmachines/play-solid - SolidJS renderer for XMachines Play architecture
Provides a SolidJS rendering layer that passively observes actor signals and renders UI components via @json-render/solid. SolidJS reactivity is only used to trigger re-renders — signals are the source of truth.
Primary entry point:
import { PlayUIProvider, PlayRenderer, defineRegistry } from "@xmachines/play-solid";For escape-hatch provider composition:
import { ActorProvider, ActorContext, usePlayView } from "@xmachines/play-solid";Interfaces
- ActionProviderProps
- ActorProviderProps
- ComponentContext
- DefineRegistryResult
- JSONUIProviderProps
- PlayUIProviderProps
- RendererProps
- StateProviderProps
- ValidationProviderProps
- ViewContextValue
Type Aliases
Variables
Functions
- ActionProvider
- defineRegistry
- JSONUIProvider
- Renderer
- StateProvider
- useAction
- useActions
- useActor
- useBoundProp
- useFieldValidation
- useIsVisible
- useOptionalValidation
- usePlayView
- useStateBinding
- useStateStore
- useStateValue
- useVisibility
- ValidationProvider
- VisibilityProvider
References
RenderErrorHandler
Re-exports RenderErrorHandler