Skip to content

@xmachines/play-svelte

API / @xmachines/play-svelte

Svelte 5 renderer for the XMachines Play architecture — connects an actor to a @json-render/svelte catalog-driven UI using Svelte 5 runes and TC39 Signals.

Part of the xmachines-js monorepo.

Installation

Terminal window
npm install @xmachines/play-svelte

Peer dependencies (must be installed separately):

Terminal window
npm install svelte@^5.0.0 xstate@^5.31.0 @xstate/store@^3.17.0 \
@json-render/core@^0.18.0 @json-render/svelte@^0.18.0 @json-render/xstate@^0.18.0

Usage

Basic setup

Define a catalog and registry once, then pass both to PlayUIProvider with your actor. PlayRenderer renders the current actor view automatically:

App.svelte
<script lang="ts">
import { defineRegistry, PlayUIProvider, PlayRenderer } from "@xmachines/play-svelte";
import { authCatalog } from "./catalog.js";
import Login from "./components/Login.svelte";
import Dashboard from "./components/Dashboard.svelte";
let { actor } = $props();
const registryResult = defineRegistry(authCatalog, {
components: { Login, Dashboard },
actions: {
login: async (params) => {
actor.send({ type: "auth.login", username: params?.username });
},
logout: async () => actor.send({ type: "auth.logout" }),
},
});
</script>
<PlayUIProvider {actor} {registryResult}>
<PlayRenderer />
</PlayUIProvider>

Lower-level: ActorProvider

Use ActorProvider directly when you need fine-grained control over rendering — for example, to wrap with a custom layout or inject the @json-render/svelte providers individually:

<script lang="ts">
import { ActorProvider } from "@xmachines/play-svelte";
let { actor, registryResult } = $props();
</script>
<ActorProvider {actor} {registryResult} fallback={loadingSnippet} onError={handleError}>
<!-- children rendered inside StateProvider tree -->
{@render children()}
</ActorProvider>

Accessing the actor from child components

import { getActorContext } from "@xmachines/play-svelte";
// Inside a Svelte component that is a descendant of ActorProvider:
const actor = getActorContext();
actor.send({ type: "some.event" });

API Summary

Components

ComponentDescription
<PlayUIProvider>Batteries-included composite — wraps ActorProvider + JsonUIProvider. Standard entry point for actor-driven UI.
<ActorProvider>Primitive provider — owns actor lifecycle, signal subscription, per-view StateStore, and onRenderError injection.
<PlayRenderer>Zero-prop leaf component — reads getPlayViewContext() and renders <Renderer> from @json-render/svelte.

Functions

FunctionDescription
defineRegistry(catalog, options)Creates a typed component registry. Wraps @json-render/svelte’s defineRegistry with catalog-typed params on action handlers. Import from @xmachines/play-svelte, not @json-render/svelte.
getActorContext()Returns the AnyPlayActor from the nearest ActorProvider ancestor. Throws if called outside the provider tree.
getPlayViewContext()Returns the ViewContextValue (spec, registry, handlers, store) from the nearest ActorProvider ancestor.
setActorContext(actor)Sets the actor context — used internally by ActorProvider.

Types

TypeDescription
ActorProviderPropsProps for <ActorProvider>: actor, registryResult, optional store, fallback snippet, onError, onRenderError, children.
PlayUIProviderPropsExtends ActorProviderProps with optional validationFunctions, navigate, and functions.
ViewContextValueThe view context shape provided by ActorProvider and consumed by PlayRenderer.
AnyPlayActorAbstractActor<AnyActorLogic> & Viewable — the actor shape accepted by ActorProvider and getActorContext.
DefineRegistryOptions<C>Options for defineRegistry: components, catalog-typed actions, and onRenderError.
ActionFn<C, K>Per-action handler type with params inferred from catalog.
Actions<C>Map of catalog-typed action handlers.
SetStateState setter function type passed as the second argument to action handlers.
RenderErrorHandlerCallback (error: unknown, elementType: string) => void invoked when a catalog component throws.

Re-exports from @json-render/svelte

Import everything from @xmachines/play-svelte — these providers are re-exported for convenience:

import {
JsonUIProvider,
StateProvider,
ActionProvider,
VisibilityProvider,
ValidationProvider,
Renderer,
getBoundProp,
getStateValue,
} from "@xmachines/play-svelte";
// Types
import type {
JSONUIProviderProps,
BaseComponentProps,
ComponentFn,
ComponentContext,
} from "@xmachines/play-svelte";

Testing

Run the test suite for this package:

Terminal window
npm test -w @xmachines/play-svelte

Or from within the package directory:

Terminal window
npm test

Tests run with Vitest in a jsdom environment using @testing-library/svelte. Browser-specific tests are in test/browser/ and use a separate Playwright-backed config:

Terminal window
# From the package directory
npx vitest --config vitest.browser.config.ts

Coverage thresholds: 80% lines, functions, branches, and statements (enforced via v8 provider).

License

MIT — see LICENSE.

@xmachines/play-svelte - Svelte renderer for XMachines Play architecture

Provides a provider/renderer split that mirrors @json-render/svelte patterns:

  • ActorProvider: primitive escape-hatch (owns actor lifecycle, signal subscription, per-view StateStore, onRenderError injection)
  • PlayUIProvider: batteries-included composite (ActorProvider + JsonUIProvider)
  • PlayRenderer: zero-prop leaf — reads getPlayViewContext() and renders Renderer

Re-exports primitives from @json-render/svelte so consumers import everything from @xmachines/play-svelte rather than @json-render/svelte directly.

Interfaces

Type Aliases

Variables

Functions

References

ActionProvider

Renames and re-exports PlayRenderer


ActorProvider

Renames and re-exports PlayRenderer


getBoundProp

Renames and re-exports RenderErrorHandler


getStateValue

Renames and re-exports RenderErrorHandler


JsonUIProvider

Renames and re-exports PlayRenderer


JSONUIProviderProps

Renames and re-exports RenderErrorHandler


PlayUIProvider

Renames and re-exports PlayRenderer


Renderer

Renames and re-exports PlayRenderer


StateProvider

Renames and re-exports PlayRenderer


ValidationProvider

Renames and re-exports PlayRenderer


VisibilityProvider

Renames and re-exports PlayRenderer