@xmachines/play-vue 1.0.0-beta.32 → 1.0.0-beta.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/README.md +99 -37
  2. package/dist/ActorProvider.js +8 -0
  3. package/dist/ActorProvider.js.map +1 -0
  4. package/dist/ActorProvider.vue.d.ts +51 -0
  5. package/dist/ActorProvider.vue.d.ts.map +1 -0
  6. package/dist/ActorProvider.vue_vue_type_script_lang.js +102 -0
  7. package/dist/ActorProvider.vue_vue_type_script_lang.js.map +1 -0
  8. package/dist/PlayRenderer.js.map +1 -1
  9. package/dist/PlayRenderer.vue.d.ts +2 -37
  10. package/dist/PlayRenderer.vue.d.ts.map +1 -1
  11. package/dist/PlayRenderer.vue_vue_type_script_lang.js +11 -65
  12. package/dist/PlayRenderer.vue_vue_type_script_lang.js.map +1 -1
  13. package/dist/PlayUIProvider.js +7 -0
  14. package/dist/PlayUIProvider.js.map +1 -0
  15. package/dist/PlayUIProvider.vue.d.ts +76 -0
  16. package/dist/PlayUIProvider.vue.d.ts.map +1 -0
  17. package/dist/PlayUIProvider.vue_vue_type_script_lang.js +86 -0
  18. package/dist/PlayUIProvider.vue_vue_type_script_lang.js.map +1 -0
  19. package/dist/actor-provider-context.d.ts +40 -0
  20. package/dist/actor-provider-context.d.ts.map +1 -0
  21. package/dist/actor-provider-context.js +11 -0
  22. package/dist/actor-provider-context.js.map +1 -0
  23. package/dist/index.d.ts +11 -6
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +8 -5
  26. package/dist/node_modules/@json-render/vue/dist/index.js +79 -60
  27. package/dist/node_modules/@json-render/vue/dist/index.js.map +1 -1
  28. package/dist/types.d.ts +16 -29
  29. package/dist/types.d.ts.map +1 -1
  30. package/dist/useActor.d.ts.map +1 -1
  31. package/dist/useActor.js +1 -1
  32. package/dist/useActor.js.map +1 -1
  33. package/package.json +6 -6
package/README.md CHANGED
@@ -39,7 +39,12 @@ without muting console output.
39
39
  - `useBoundProp` — re-exported from `@json-render/vue`
40
40
  - `ComponentFn` (type) — re-exported from `@json-render/vue`
41
41
  - `ComponentContext` (type) — re-exported from `@json-render/vue`
42
- - `PlayRendererProps` (type)
42
+ - `ActorProvider` — escape hatch primitive (owns actor bridging, signal bridge, store lifecycle)
43
+ - `PlayUIProvider` — batteries-included composite (wraps `ActorProvider` + `JSONUIProvider`)
44
+ - `getPlayViewContext` — composable for accessing the current view spec inside a provider tree
45
+ - `RenderErrorHandler` (type) — inner per-element error callback signature
46
+ - `ActorProviderProps` (type)
47
+ - `ViewContextValue` (type)
43
48
  - `PlayActor` (type)
44
49
 
45
50
  ## Quick Start
@@ -131,12 +136,9 @@ export const machine = setup({
131
136
  meta: {
132
137
  route: "/login",
133
138
  view: {
134
- component: "Login",
135
- spec: {
136
- root: "root",
137
- elements: {
138
- root: { type: "Login", props: { title: "Sign In" }, children: [] },
139
- },
139
+ root: "root",
140
+ elements: {
141
+ root: { type: "Login", props: { title: "Sign In" }, children: [] },
140
142
  },
141
143
  },
142
144
  },
@@ -146,12 +148,9 @@ export const machine = setup({
146
148
  meta: {
147
149
  route: "/dashboard",
148
150
  view: {
149
- component: "Dashboard",
150
- spec: {
151
- root: "root",
152
- elements: {
153
- root: { type: "Dashboard", props: { username: "" }, children: [] },
154
- },
151
+ root: "root",
152
+ elements: {
153
+ root: { type: "Dashboard", props: { username: "" }, children: [] },
155
154
  },
156
155
  },
157
156
  },
@@ -177,7 +176,7 @@ export const machine = setup({
177
176
  <!-- App.vue -->
178
177
  <script setup lang="ts">
179
178
  import { definePlayer } from "@xmachines/play-xstate";
180
- import { PlayRenderer } from "@xmachines/play-vue";
179
+ import { PlayUIProvider, PlayRenderer } from "@xmachines/play-vue";
181
180
  import { machine } from "./machine.js";
182
181
  import { registryResult } from "./registry.js";
183
182
 
@@ -187,27 +186,34 @@ actor.start();
187
186
  </script>
188
187
 
189
188
  <template>
190
- <PlayRenderer :actor="actor" :registryResult="registryResult" />
189
+ <PlayUIProvider :actor="actor" :registryResult="registryResult">
190
+ <PlayRenderer />
191
+ </PlayUIProvider>
191
192
  </template>
192
193
  ```
193
194
 
194
195
  ## API Reference
195
196
 
196
- ### `PlayRenderer`
197
+ ### `PlayUIProvider`
197
198
 
198
- Main Vue component. Subscribes to `actor.currentView` and renders the spec.
199
+ Batteries-included composite provider. Wraps `ActorProvider` + `JSONUIProvider`. Pass `actor` and `registryResult` here, then place `<PlayRenderer />` inside as a zero-prop child.
199
200
 
200
201
  ```vue
201
- <PlayRenderer :actor="actor" :registryResult="registryResult" :store="myStore" />
202
+ <PlayUIProvider
203
+ :actor="actor"
204
+ :registryResult="registryResult"
205
+ :store="myStore"
206
+ :onRenderError="(error, elementType) => console.warn(`<${elementType}> crashed:`, error)"
207
+ >
208
+ <template #fallback><p>Something went wrong.</p></template>
209
+ <PlayRenderer />
210
+ </PlayUIProvider>
202
211
  ```
203
212
 
204
213
  **`actor`** — A `PlayerActor` (or any `AbstractActor & Viewable`). Provides the `currentView` signal.
205
214
 
206
215
  **`registryResult`** — The full `DefineRegistryResult` returned by `defineRegistry(catalog, { components, actions })` from `@xmachines/play-vue`. Pass `.vue` SFCs directly — they are auto-wrapped via `h(SFC, ctx)` so `useBoundProp` and other composables work inside `<script setup>`.
207
216
 
208
- `defineRegistry` also accepts `onRenderError(error, elementType)`, which receives errors
209
- caught by `@json-render/vue`'s inner element boundary before the default logger is used.
210
-
211
217
  **`store`** (optional) — Controls per-view UI state (`$state` bindings, form values):
212
218
 
213
219
  - **Omitted (uncontrolled, default):** A fresh `@xstate/store` atom is created per view transition, seeded from `view.spec.state`.
@@ -221,30 +227,86 @@ import type { StateStore } from "@json-render/core";
221
227
  const store: StateStore = xstateStoreStateStore({ atom: createAtom({ username: "" }) });
222
228
  ```
223
229
 
224
- **Inner render errors** — You can intercept catalog component render failures without
225
- overriding the outer Vue error boundary:
230
+ ```vue
231
+ <PlayUIProvider :actor="actor" :registryResult="registryResult" :store="store">
232
+ <PlayRenderer />
233
+ </PlayUIProvider>
234
+ ```
235
+
236
+ **`onRenderError`** — Called when an individual catalog component throws during render. Caught by `@json-render/vue`'s inner per-element error boundary — the failed component is silently removed while the rest of the spec continues rendering. When both `onRenderError` on `PlayUIProvider` and on `defineRegistry` are set, the prop wins.
237
+
238
+ ---
239
+
240
+ ### `ActorProvider`
241
+
242
+ Escape hatch primitive. Owns actor bridging, signal bridge, and store lifecycle. Use this when you need direct control over the provider layer.
243
+
244
+ ```vue
245
+ <ActorProvider :actor="actor" :registryResult="registryResult" :onRenderError="handleError">
246
+ <!-- your own JSONUIProvider + PlayRenderer tree -->
247
+ </ActorProvider>
248
+ ```
249
+
250
+ ---
251
+
252
+ ### `PlayRenderer`
253
+
254
+ Zero-prop leaf component. Must be rendered inside a `PlayUIProvider` (or `ActorProvider`) tree. Subscribes to `actor.currentView` via context and renders the current spec.
255
+
256
+ ```vue
257
+ <PlayUIProvider :actor="actor" :registryResult="registryResult">
258
+ <PlayRenderer />
259
+ </PlayUIProvider>
260
+ ```
261
+
262
+ `PlayRenderer` accepts no props — all configuration (`actor`, `registryResult`, `store`, `fallback`, `onRenderError`) is provided by the enclosing `PlayUIProvider` or `ActorProvider`.
263
+
264
+ ## Error handling
265
+
266
+ The provider tree has two layers of error boundaries:
267
+
268
+ ### Outer boundary — `fallback` slot
269
+
270
+ Vue's `onErrorCaptured` wraps the entire renderer. Triggered when the spec or store setup throws, or when the inner boundary is not present. Use Vue's built-in `onErrorCaptured` in a parent component for observability.
271
+
272
+ ```vue
273
+ <PlayUIProvider :actor="actor" :registryResult="registryResult">
274
+ <template #fallback>
275
+ <p>Something went wrong.</p>
276
+ </template>
277
+ <PlayRenderer />
278
+ </PlayUIProvider>
279
+ ```
280
+
281
+ ### Inner boundary — `onRenderError`
282
+
283
+ Each catalog element is individually wrapped in an error boundary by `@json-render/vue`. When a component throws, it is silently removed while the rest of the spec continues rendering. The outer boundary is **not** triggered.
284
+
285
+ Pass `onRenderError` to `PlayUIProvider` (or `ActorProvider`) — overrides any registry-level handler — or bake it into `defineRegistry`:
286
+
287
+ ```vue
288
+ <!-- via PlayUIProvider prop -->
289
+ <PlayUIProvider
290
+ :actor="actor"
291
+ :registryResult="registryResult"
292
+ :onRenderError="(error, elementType) => console.warn(`<${elementType}> crashed:`, error)"
293
+ >
294
+ <PlayRenderer />
295
+ </PlayUIProvider>
296
+ ```
226
297
 
227
298
  ```ts
228
- export const registryResult = defineRegistry(catalog, {
299
+ // via defineRegistry bakes the handler into the registry
300
+ const registryResult = defineRegistry(catalog, {
229
301
  components: { Login: LoginSFC, Dashboard: DashboardSFC },
230
- actions: {
231
- login: async (params) => {
232
- if (!params) return;
233
- actor.send({ type: "auth.login", username: params.username });
234
- },
235
- logout: async (params) => {
236
- actor.send({ type: "auth.logout" });
237
- },
238
- },
302
+ actions: { login: async (params) => { ... }, logout: async () => { ... } },
239
303
  onRenderError(error, elementType) {
240
304
  reportExpectedRenderError(error, elementType);
241
305
  },
242
306
  });
243
307
  ```
244
308
 
245
- ```vue
246
- <PlayRenderer :actor="actor" :registryResult="registryResult" :store="store" />
247
- ```
309
+ `onRenderError` is typed as `RenderErrorHandler` and exported from `@xmachines/play-vue`.
248
310
 
249
311
  ---
250
312
 
@@ -260,7 +322,7 @@ const actor = useActor();
260
322
  actor.send({ type: "auth.logout" });
261
323
  ```
262
324
 
263
- Throws `"useActor() must be called inside <PlayRenderer>"` if called outside the tree.
325
+ Throws `NonNullableError: "useActor() must be called inside <ActorProvider> (or <PlayUIProvider>)"` if called outside the tree.
264
326
 
265
327
  ---
266
328
 
@@ -0,0 +1,8 @@
1
+ import "./actor-provider-context.js";
2
+ import e from "./ActorProvider.vue_vue_type_script_lang.js";
3
+ //#region src/ActorProvider.vue
4
+ var t = e;
5
+ //#endregion
6
+ export { t as default };
7
+
8
+ //# sourceMappingURL=ActorProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActorProvider.js","names":[],"sources":["../src/ActorProvider.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * ActorProvider — escape-hatch primitive for the XMachines Vue render architecture.\n *\n * Owns the full actor lifecycle:\n * - Signal subscription (watchSignal) bridging TC39 Signals to Vue reactivity\n * - Per-view StateStore lifecycle (controlled/uncontrolled)\n * - Handler resolution via ActorProviderInner (must be inside StateProvider)\n * - ViewContextValue provision via ViewKey injection key\n * - ActionProvider + VisibilityProvider wrapping for downstream Renderer\n * - onRenderError injection into registry\n *\n * Library authors who need fine-grained control use this directly.\n * End users should use <PlayUIProvider> instead.\n *\n * @invariant Actor Authority - Actor decides all state transitions via guards\n * @invariant Passive Infrastructure - Component observes signals, sends events\n * @invariant Signal-Only Reactivity - Business logic state lives in actor signals\n */\n\nimport { defineComponent, ref, toRaw, markRaw, onUnmounted, h, provide, shallowRef } from \"vue\";\nimport type { PropType } from \"vue\";\nimport { watchSignal } from \"@xmachines/play-signals\";\nimport type { AbstractActor, Viewable, PlaySpec } from \"@xmachines/play-actor\";\nimport type { AnyActorLogic } from \"xstate\";\nimport type { DefineRegistryResult, SetState, RenderErrorHandler } from \"@json-render/vue\";\n\nimport { StateProvider, useStateStore, ActionProvider, VisibilityProvider } from \"@json-render/vue\";\nimport type { StateStore } from \"@json-render/core\";\nimport { createAtom } from \"@xstate/store\";\nimport { xstateStoreStateStore } from \"@json-render/xstate\";\nimport { provideActor, type PlayActor } from \"./useActor.js\";\nimport { ViewKey, type ViewContextValue } from \"./actor-provider-context.js\";\nimport type { ActorProviderProps } from \"./types.js\";\n\n// Re-export props type and context accessors for consumers who import from this file\nexport type { ActorProviderProps } from \"./types.js\";\nexport { getPlayViewContext } from \"./actor-provider-context.js\";\nexport type { ViewContextValue } from \"./actor-provider-context.js\";\n\n// ---------------------------------------------------------------------------\n// ActorProviderInner — renders inside StateProvider to call useStateStore()\n// Provides ViewContextValue + ActionProvider + VisibilityProvider for downstream Renderer.\n// ---------------------------------------------------------------------------\n\nconst ActorProviderInner = defineComponent({\n\tname: \"ActorProviderInner\",\n\tprops: {\n\t\tregistryResult: {\n\t\t\ttype: Object as PropType<DefineRegistryResult>,\n\t\t\trequired: true,\n\t\t},\n\t\tspec: {\n\t\t\ttype: Object as PropType<PlaySpec | null>,\n\t\t\tdefault: null,\n\t\t},\n\t\tstore: {\n\t\t\ttype: Object as PropType<StateStore>,\n\t\t\trequired: true,\n\t\t},\n\t},\n\tsetup(props, { slots }) {\n\t\t// Use shallowRef for the view context value to avoid deep reactivity overhead.\n\t\t// The Proxy below allows inject() to always read the latest value.\n\t\tconst viewRef = shallowRef<ViewContextValue | null>(null);\n\n\t\t// Provide the ViewContextValue via Vue's inject/provide system.\n\t\t// Called synchronously in setup() so Vue registers it on the component instance.\n\t\t// Uses Proxy so descendants always receive the latest viewRef.value.\n\t\tprovide(\n\t\t\tViewKey,\n\t\t\tnew Proxy({} as ViewContextValue, {\n\t\t\t\tget(_target, prop: string) {\n\t\t\t\t\treturn viewRef.value?.[prop as keyof ViewContextValue];\n\t\t\t\t},\n\t\t\t}),\n\t\t);\n\n\t\treturn () => {\n\t\t\tif (!props.spec) {\n\t\t\t\tviewRef.value = null;\n\t\t\t\treturn slots.default?.() ?? null;\n\t\t\t}\n\n\t\t\tconst { update, getSnapshot } = useStateStore();\n\t\t\t// Build a SetState adapter: handlers factory expects updater-function pattern\n\t\t\tconst setStateAdapter: SetState = (updater) => {\n\t\t\t\tconst prev = getSnapshot();\n\t\t\t\tupdate(updater(prev));\n\t\t\t};\n\t\t\tconst handlers = props.registryResult.handlers(\n\t\t\t\t() => setStateAdapter,\n\t\t\t\t() => getSnapshot(),\n\t\t\t);\n\n\t\t\tviewRef.value = {\n\t\t\t\tspec: props.spec,\n\t\t\t\thandlers,\n\t\t\t\tregistry: props.registryResult.registry,\n\t\t\t\tstore: props.store,\n\t\t\t};\n\n\t\t\t// Wrap with ActionProvider + VisibilityProvider so PlayRenderer's Renderer works\n\t\t\t// even when ActorProvider is used directly (without PlayUIProvider / JSONUIProvider)\n\t\t\treturn h(ActionProvider, { handlers }, () =>\n\t\t\t\th(VisibilityProvider, {}, () => slots.default?.() ?? null),\n\t\t\t);\n\t\t};\n\t},\n});\n\n// ---------------------------------------------------------------------------\n// ActorProvider — main export\n// ---------------------------------------------------------------------------\n\nexport default defineComponent({\n\tname: \"ActorProvider\",\n\tprops: {\n\t\tactor: {\n\t\t\ttype: Object as PropType<ActorProviderProps[\"actor\"]>,\n\t\t\trequired: true,\n\t\t},\n\t\tregistryResult: {\n\t\t\ttype: Object as PropType<DefineRegistryResult>,\n\t\t\trequired: true,\n\t\t},\n\t\tstore: {\n\t\t\ttype: Object as PropType<StateStore>,\n\t\t\tdefault: undefined,\n\t\t},\n\t\tonRenderError: {\n\t\t\ttype: Function as PropType<RenderErrorHandler>,\n\t\t\tdefault: undefined,\n\t\t},\n\t},\n\tsetup(props, { slots }) {\n\t\t// Unwrap actor from Vue's reactive proxy to access raw Signal objects\n\t\tconst actor = toRaw(props.actor as AbstractActor<AnyActorLogic> & Viewable);\n\n\t\t// Unwrap the registryResult and mark components as raw to avoid Vue reactivity overhead\n\t\tconst rawRegistryResult: DefineRegistryResult = {\n\t\t\t...toRaw(props.registryResult),\n\t\t\tregistry: markRaw(\n\t\t\t\tObject.fromEntries(\n\t\t\t\t\tObject.entries(toRaw(props.registryResult).registry).map(([k, v]) => [\n\t\t\t\t\t\tk,\n\t\t\t\t\t\tmarkRaw(v as object),\n\t\t\t\t\t]),\n\t\t\t\t) as DefineRegistryResult[\"registry\"],\n\t\t\t),\n\t\t};\n\n\t\t// Inject onRenderError prop into registry (non-enumerable, overrides defineRegistry-level handler)\n\t\tif (props.onRenderError) {\n\t\t\tObject.defineProperty(rawRegistryResult.registry, \"onRenderError\", {\n\t\t\t\tvalue: props.onRenderError,\n\t\t\t\tenumerable: false,\n\t\t\t\tconfigurable: true,\n\t\t\t});\n\t\t}\n\n\t\t// Provide the raw actor to all descendants via Vue's provide/inject mechanism\n\t\tprovideActor(actor as PlayActor);\n\n\t\t// Get initial value from unwrapped signal\n\t\tconst initialView = actor.currentView.get();\n\n\t\t// Vue ref for triggering re-renders (NOT business logic state)\n\t\tconst view = ref<PlaySpec | null>(initialView);\n\n\t\t// Internal per-view store — recreated on each view transition when no external store\n\t\tlet internalStore: StateStore | null = null;\n\t\tlet lastView: PlaySpec | null = null;\n\t\tlet storeKey = 0;\n\n\t\t// Signal watcher for bridging TC39 Signals to Vue reactivity\n\t\tconst unwatch = watchSignal(actor.currentView, (nextView) => {\n\t\t\tview.value = nextView;\n\t\t});\n\n\t\tonUnmounted(() => {\n\t\t\tunwatch();\n\t\t});\n\n\t\treturn () => {\n\t\t\t// No view — show fallback slot or nothing\n\t\t\tif (!view.value) {\n\t\t\t\treturn slots.fallback ? slots.fallback() : null;\n\t\t\t}\n\n\t\t\tconst spec = view.value;\n\n\t\t\t// Resolve the store: external (controlled) or internal per-view atom\n\t\t\tlet store: StateStore;\n\t\t\tif (props.store) {\n\t\t\t\tstore = props.store;\n\t\t\t} else {\n\t\t\t\tif (internalStore === null || lastView !== view.value) {\n\t\t\t\t\t// T-37-04-02: Proper proto-safe guard for spec.state\n\t\t\t\t\tconst rawState = spec.state;\n\t\t\t\t\tconst initialState: Record<string, unknown> =\n\t\t\t\t\t\trawState !== null &&\n\t\t\t\t\t\ttypeof rawState === \"object\" &&\n\t\t\t\t\t\t!Array.isArray(rawState) &&\n\t\t\t\t\t\tObject.getPrototypeOf(rawState) === Object.prototype\n\t\t\t\t\t\t\t? (rawState as Record<string, unknown>)\n\t\t\t\t\t\t\t: {};\n\t\t\t\t\tinternalStore = xstateStoreStateStore({ atom: createAtom(initialState) });\n\t\t\t\t\tlastView = view.value;\n\t\t\t\t\tstoreKey++;\n\t\t\t\t}\n\t\t\t\tstore = internalStore;\n\t\t\t}\n\n\t\t\t// ActorProviderInner renders inside StateProvider so useStateStore() works\n\t\t\treturn h(StateProvider, { store, key: storeKey }, () =>\n\t\t\t\th(ActorProviderInner, { registryResult: rawRegistryResult, spec, store }, slots),\n\t\t\t);\n\t\t};\n\t},\n});\n</script>\n"],"mappings":""}
@@ -0,0 +1,51 @@
1
+ import { PropType } from 'vue';
2
+ import { DefineRegistryResult, RenderErrorHandler } from '@json-render/vue';
3
+ import { StateStore } from '@json-render/core';
4
+ import { ActorProviderProps } from './types.js';
5
+ export type { ActorProviderProps } from './types.js';
6
+ export { getPlayViewContext } from './actor-provider-context.js';
7
+ export type { ViewContextValue } from './actor-provider-context.js';
8
+ declare const _default: import('vue', { with: { "resolution-mode": "import" } }).DefineComponent<import('vue', { with: { "resolution-mode": "import" } }).ExtractPropTypes<{
9
+ actor: {
10
+ type: PropType<ActorProviderProps["actor"]>;
11
+ required: true;
12
+ };
13
+ registryResult: {
14
+ type: PropType<DefineRegistryResult>;
15
+ required: true;
16
+ };
17
+ store: {
18
+ type: PropType<StateStore>;
19
+ default: undefined;
20
+ };
21
+ onRenderError: {
22
+ type: PropType<RenderErrorHandler>;
23
+ default: undefined;
24
+ };
25
+ }>, () => import('vue', { with: { "resolution-mode": "import" } }).VNode<import('vue', { with: { "resolution-mode": "import" } }).RendererNode, import('vue', { with: { "resolution-mode": "import" } }).RendererElement, {
26
+ [key: string]: any;
27
+ }> | import('vue', { with: { "resolution-mode": "import" } }).VNode<import('vue', { with: { "resolution-mode": "import" } }).RendererNode, import('vue', { with: { "resolution-mode": "import" } }).RendererElement, {
28
+ [key: string]: any;
29
+ }>[] | null, {}, {}, {}, import('vue', { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import('vue', { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {}, string, import('vue', { with: { "resolution-mode": "import" } }).PublicProps, Readonly<import('vue', { with: { "resolution-mode": "import" } }).ExtractPropTypes<{
30
+ actor: {
31
+ type: PropType<ActorProviderProps["actor"]>;
32
+ required: true;
33
+ };
34
+ registryResult: {
35
+ type: PropType<DefineRegistryResult>;
36
+ required: true;
37
+ };
38
+ store: {
39
+ type: PropType<StateStore>;
40
+ default: undefined;
41
+ };
42
+ onRenderError: {
43
+ type: PropType<RenderErrorHandler>;
44
+ default: undefined;
45
+ };
46
+ }>> & Readonly<{}>, {
47
+ store: StateStore;
48
+ onRenderError: RenderErrorHandler;
49
+ }, {}, {}, {}, string, import('vue', { with: { "resolution-mode": "import" } }).ComponentProvideOptions, true, {}, any>;
50
+ export default _default;
51
+ //# sourceMappingURL=ActorProvider.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActorProvider.vue.d.ts","sourceRoot":"","sources":["../src/ActorProvider.vue"],"names":[],"mappings":"AAoPA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAIpC,OAAO,KAAK,EAAE,oBAAoB,EAAY,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAG3F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAKpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGrD,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,YAAY,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;;;cAiFjD,QAAQ,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;;;;cAIrC,QAAQ,CAAC,oBAAoB,CAAC;;;;cAI9B,QAAQ,CAAC,UAAU,CAAC;;;;cAIlB,QAAQ,CAAC,kBAAkB,CAAC;;;;;;;;;cAZ9B,QAAQ,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;;;;cAIrC,QAAQ,CAAC,oBAAoB,CAAC;;;;cAI9B,QAAQ,CAAC,UAAU,CAAC;;;;cAIlB,QAAQ,CAAC,kBAAkB,CAAC;;;;;;;AAhBjD,wBAyGG"}
@@ -0,0 +1,102 @@
1
+ import { ActionProvider as e, StateProvider as t, VisibilityProvider as n, useStateStore as r } from "./node_modules/@json-render/vue/dist/index.js";
2
+ import { ViewKey as i } from "./actor-provider-context.js";
3
+ import { createAtom as a } from "./node_modules/@xstate/store/dist/store-69e7e2d5.esm.js";
4
+ import { xstateStoreStateStore as o } from "./node_modules/@json-render/xstate/dist/index.js";
5
+ import { provideActor as s } from "./useActor.js";
6
+ import { defineComponent as c, h as l, markRaw as u, onUnmounted as d, provide as f, ref as p, shallowRef as m, toRaw as h } from "vue";
7
+ import { watchSignal as g } from "@xmachines/play-signals";
8
+ //#region src/ActorProvider.vue?vue&type=script&lang.ts
9
+ var _ = c({
10
+ name: "ActorProviderInner",
11
+ props: {
12
+ registryResult: {
13
+ type: Object,
14
+ required: !0
15
+ },
16
+ spec: {
17
+ type: Object,
18
+ default: null
19
+ },
20
+ store: {
21
+ type: Object,
22
+ required: !0
23
+ }
24
+ },
25
+ setup(t, { slots: a }) {
26
+ let o = m(null);
27
+ return f(i, new Proxy({}, { get(e, t) {
28
+ return o.value?.[t];
29
+ } })), () => {
30
+ if (!t.spec) return o.value = null, a.default?.() ?? null;
31
+ let { update: i, getSnapshot: s } = r(), c = (e) => {
32
+ i(e(s()));
33
+ }, u = t.registryResult.handlers(() => c, () => s());
34
+ return o.value = {
35
+ spec: t.spec,
36
+ handlers: u,
37
+ registry: t.registryResult.registry,
38
+ store: t.store
39
+ }, l(e, { handlers: u }, () => l(n, {}, () => a.default?.() ?? null));
40
+ };
41
+ }
42
+ }), v = c({
43
+ name: "ActorProvider",
44
+ props: {
45
+ actor: {
46
+ type: Object,
47
+ required: !0
48
+ },
49
+ registryResult: {
50
+ type: Object,
51
+ required: !0
52
+ },
53
+ store: {
54
+ type: Object,
55
+ default: void 0
56
+ },
57
+ onRenderError: {
58
+ type: Function,
59
+ default: void 0
60
+ }
61
+ },
62
+ setup(e, { slots: n }) {
63
+ let r = h(e.actor), i = {
64
+ ...h(e.registryResult),
65
+ registry: u(Object.fromEntries(Object.entries(h(e.registryResult).registry).map(([e, t]) => [e, u(t)])))
66
+ };
67
+ e.onRenderError && Object.defineProperty(i.registry, "onRenderError", {
68
+ value: e.onRenderError,
69
+ enumerable: !1,
70
+ configurable: !0
71
+ }), s(r);
72
+ let c = p(r.currentView.get()), f = null, m = null, v = 0, y = g(r.currentView, (e) => {
73
+ c.value = e;
74
+ });
75
+ return d(() => {
76
+ y();
77
+ }), () => {
78
+ if (!c.value) return n.fallback ? n.fallback() : null;
79
+ let r = c.value, s;
80
+ if (e.store) s = e.store;
81
+ else {
82
+ if (f === null || m !== c.value) {
83
+ let e = r.state;
84
+ f = o({ atom: a(typeof e == "object" && e && !Array.isArray(e) && Object.getPrototypeOf(e) === Object.prototype ? e : {}) }), m = c.value, v++;
85
+ }
86
+ s = f;
87
+ }
88
+ return l(t, {
89
+ store: s,
90
+ key: v
91
+ }, () => l(_, {
92
+ registryResult: i,
93
+ spec: r,
94
+ store: s
95
+ }, n));
96
+ };
97
+ }
98
+ });
99
+ //#endregion
100
+ export { v as default };
101
+
102
+ //# sourceMappingURL=ActorProvider.vue_vue_type_script_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActorProvider.vue_vue_type_script_lang.js","names":[],"sources":["../src/ActorProvider.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * ActorProvider — escape-hatch primitive for the XMachines Vue render architecture.\n *\n * Owns the full actor lifecycle:\n * - Signal subscription (watchSignal) bridging TC39 Signals to Vue reactivity\n * - Per-view StateStore lifecycle (controlled/uncontrolled)\n * - Handler resolution via ActorProviderInner (must be inside StateProvider)\n * - ViewContextValue provision via ViewKey injection key\n * - ActionProvider + VisibilityProvider wrapping for downstream Renderer\n * - onRenderError injection into registry\n *\n * Library authors who need fine-grained control use this directly.\n * End users should use <PlayUIProvider> instead.\n *\n * @invariant Actor Authority - Actor decides all state transitions via guards\n * @invariant Passive Infrastructure - Component observes signals, sends events\n * @invariant Signal-Only Reactivity - Business logic state lives in actor signals\n */\n\nimport { defineComponent, ref, toRaw, markRaw, onUnmounted, h, provide, shallowRef } from \"vue\";\nimport type { PropType } from \"vue\";\nimport { watchSignal } from \"@xmachines/play-signals\";\nimport type { AbstractActor, Viewable, PlaySpec } from \"@xmachines/play-actor\";\nimport type { AnyActorLogic } from \"xstate\";\nimport type { DefineRegistryResult, SetState, RenderErrorHandler } from \"@json-render/vue\";\n\nimport { StateProvider, useStateStore, ActionProvider, VisibilityProvider } from \"@json-render/vue\";\nimport type { StateStore } from \"@json-render/core\";\nimport { createAtom } from \"@xstate/store\";\nimport { xstateStoreStateStore } from \"@json-render/xstate\";\nimport { provideActor, type PlayActor } from \"./useActor.js\";\nimport { ViewKey, type ViewContextValue } from \"./actor-provider-context.js\";\nimport type { ActorProviderProps } from \"./types.js\";\n\n// Re-export props type and context accessors for consumers who import from this file\nexport type { ActorProviderProps } from \"./types.js\";\nexport { getPlayViewContext } from \"./actor-provider-context.js\";\nexport type { ViewContextValue } from \"./actor-provider-context.js\";\n\n// ---------------------------------------------------------------------------\n// ActorProviderInner — renders inside StateProvider to call useStateStore()\n// Provides ViewContextValue + ActionProvider + VisibilityProvider for downstream Renderer.\n// ---------------------------------------------------------------------------\n\nconst ActorProviderInner = defineComponent({\n\tname: \"ActorProviderInner\",\n\tprops: {\n\t\tregistryResult: {\n\t\t\ttype: Object as PropType<DefineRegistryResult>,\n\t\t\trequired: true,\n\t\t},\n\t\tspec: {\n\t\t\ttype: Object as PropType<PlaySpec | null>,\n\t\t\tdefault: null,\n\t\t},\n\t\tstore: {\n\t\t\ttype: Object as PropType<StateStore>,\n\t\t\trequired: true,\n\t\t},\n\t},\n\tsetup(props, { slots }) {\n\t\t// Use shallowRef for the view context value to avoid deep reactivity overhead.\n\t\t// The Proxy below allows inject() to always read the latest value.\n\t\tconst viewRef = shallowRef<ViewContextValue | null>(null);\n\n\t\t// Provide the ViewContextValue via Vue's inject/provide system.\n\t\t// Called synchronously in setup() so Vue registers it on the component instance.\n\t\t// Uses Proxy so descendants always receive the latest viewRef.value.\n\t\tprovide(\n\t\t\tViewKey,\n\t\t\tnew Proxy({} as ViewContextValue, {\n\t\t\t\tget(_target, prop: string) {\n\t\t\t\t\treturn viewRef.value?.[prop as keyof ViewContextValue];\n\t\t\t\t},\n\t\t\t}),\n\t\t);\n\n\t\treturn () => {\n\t\t\tif (!props.spec) {\n\t\t\t\tviewRef.value = null;\n\t\t\t\treturn slots.default?.() ?? null;\n\t\t\t}\n\n\t\t\tconst { update, getSnapshot } = useStateStore();\n\t\t\t// Build a SetState adapter: handlers factory expects updater-function pattern\n\t\t\tconst setStateAdapter: SetState = (updater) => {\n\t\t\t\tconst prev = getSnapshot();\n\t\t\t\tupdate(updater(prev));\n\t\t\t};\n\t\t\tconst handlers = props.registryResult.handlers(\n\t\t\t\t() => setStateAdapter,\n\t\t\t\t() => getSnapshot(),\n\t\t\t);\n\n\t\t\tviewRef.value = {\n\t\t\t\tspec: props.spec,\n\t\t\t\thandlers,\n\t\t\t\tregistry: props.registryResult.registry,\n\t\t\t\tstore: props.store,\n\t\t\t};\n\n\t\t\t// Wrap with ActionProvider + VisibilityProvider so PlayRenderer's Renderer works\n\t\t\t// even when ActorProvider is used directly (without PlayUIProvider / JSONUIProvider)\n\t\t\treturn h(ActionProvider, { handlers }, () =>\n\t\t\t\th(VisibilityProvider, {}, () => slots.default?.() ?? null),\n\t\t\t);\n\t\t};\n\t},\n});\n\n// ---------------------------------------------------------------------------\n// ActorProvider — main export\n// ---------------------------------------------------------------------------\n\nexport default defineComponent({\n\tname: \"ActorProvider\",\n\tprops: {\n\t\tactor: {\n\t\t\ttype: Object as PropType<ActorProviderProps[\"actor\"]>,\n\t\t\trequired: true,\n\t\t},\n\t\tregistryResult: {\n\t\t\ttype: Object as PropType<DefineRegistryResult>,\n\t\t\trequired: true,\n\t\t},\n\t\tstore: {\n\t\t\ttype: Object as PropType<StateStore>,\n\t\t\tdefault: undefined,\n\t\t},\n\t\tonRenderError: {\n\t\t\ttype: Function as PropType<RenderErrorHandler>,\n\t\t\tdefault: undefined,\n\t\t},\n\t},\n\tsetup(props, { slots }) {\n\t\t// Unwrap actor from Vue's reactive proxy to access raw Signal objects\n\t\tconst actor = toRaw(props.actor as AbstractActor<AnyActorLogic> & Viewable);\n\n\t\t// Unwrap the registryResult and mark components as raw to avoid Vue reactivity overhead\n\t\tconst rawRegistryResult: DefineRegistryResult = {\n\t\t\t...toRaw(props.registryResult),\n\t\t\tregistry: markRaw(\n\t\t\t\tObject.fromEntries(\n\t\t\t\t\tObject.entries(toRaw(props.registryResult).registry).map(([k, v]) => [\n\t\t\t\t\t\tk,\n\t\t\t\t\t\tmarkRaw(v as object),\n\t\t\t\t\t]),\n\t\t\t\t) as DefineRegistryResult[\"registry\"],\n\t\t\t),\n\t\t};\n\n\t\t// Inject onRenderError prop into registry (non-enumerable, overrides defineRegistry-level handler)\n\t\tif (props.onRenderError) {\n\t\t\tObject.defineProperty(rawRegistryResult.registry, \"onRenderError\", {\n\t\t\t\tvalue: props.onRenderError,\n\t\t\t\tenumerable: false,\n\t\t\t\tconfigurable: true,\n\t\t\t});\n\t\t}\n\n\t\t// Provide the raw actor to all descendants via Vue's provide/inject mechanism\n\t\tprovideActor(actor as PlayActor);\n\n\t\t// Get initial value from unwrapped signal\n\t\tconst initialView = actor.currentView.get();\n\n\t\t// Vue ref for triggering re-renders (NOT business logic state)\n\t\tconst view = ref<PlaySpec | null>(initialView);\n\n\t\t// Internal per-view store — recreated on each view transition when no external store\n\t\tlet internalStore: StateStore | null = null;\n\t\tlet lastView: PlaySpec | null = null;\n\t\tlet storeKey = 0;\n\n\t\t// Signal watcher for bridging TC39 Signals to Vue reactivity\n\t\tconst unwatch = watchSignal(actor.currentView, (nextView) => {\n\t\t\tview.value = nextView;\n\t\t});\n\n\t\tonUnmounted(() => {\n\t\t\tunwatch();\n\t\t});\n\n\t\treturn () => {\n\t\t\t// No view — show fallback slot or nothing\n\t\t\tif (!view.value) {\n\t\t\t\treturn slots.fallback ? slots.fallback() : null;\n\t\t\t}\n\n\t\t\tconst spec = view.value;\n\n\t\t\t// Resolve the store: external (controlled) or internal per-view atom\n\t\t\tlet store: StateStore;\n\t\t\tif (props.store) {\n\t\t\t\tstore = props.store;\n\t\t\t} else {\n\t\t\t\tif (internalStore === null || lastView !== view.value) {\n\t\t\t\t\t// T-37-04-02: Proper proto-safe guard for spec.state\n\t\t\t\t\tconst rawState = spec.state;\n\t\t\t\t\tconst initialState: Record<string, unknown> =\n\t\t\t\t\t\trawState !== null &&\n\t\t\t\t\t\ttypeof rawState === \"object\" &&\n\t\t\t\t\t\t!Array.isArray(rawState) &&\n\t\t\t\t\t\tObject.getPrototypeOf(rawState) === Object.prototype\n\t\t\t\t\t\t\t? (rawState as Record<string, unknown>)\n\t\t\t\t\t\t\t: {};\n\t\t\t\t\tinternalStore = xstateStoreStateStore({ atom: createAtom(initialState) });\n\t\t\t\t\tlastView = view.value;\n\t\t\t\t\tstoreKey++;\n\t\t\t\t}\n\t\t\t\tstore = internalStore;\n\t\t\t}\n\n\t\t\t// ActorProviderInner renders inside StateProvider so useStateStore() works\n\t\t\treturn h(StateProvider, { store, key: storeKey }, () =>\n\t\t\t\th(ActorProviderInner, { registryResult: rawRegistryResult, spec, store }, slots),\n\t\t\t);\n\t\t};\n\t},\n});\n</script>\n"],"mappings":";;;;;;;;AA6CA,IAAM,IAAqB,EAAgB;CAC1C,MAAM;CACN,OAAO;EACN,gBAAgB;GACf,MAAM;GACN,UAAU;GACV;EACD,MAAM;GACL,MAAM;GACN,SAAS;GACT;EACD,OAAO;GACN,MAAM;GACN,UAAU;GACV;EACD;CACD,MAAM,GAAO,EAAE,YAAS;EAGvB,IAAM,IAAU,EAAoC,KAAK;AAczD,SATA,EACC,GACA,IAAI,MAAM,EAAC,EAAuB,EACjC,IAAI,GAAS,GAAc;AAC1B,UAAO,EAAQ,QAAQ;KAExB,CAAC,CACF,QAEY;AACZ,OAAI,CAAC,EAAM,KAEV,QADA,EAAQ,QAAQ,MACT,EAAM,WAAU,IAAK;GAG7B,IAAM,EAAE,WAAQ,mBAAgB,GAAe,EAEzC,KAA6B,MAAY;AAE9C,MAAO,EADM,GAAa,CACN,CAAC;MAEhB,IAAW,EAAM,eAAe,eAC/B,SACA,GAAa,CACnB;AAWD,UATA,EAAQ,QAAQ;IACf,MAAM,EAAM;IACZ;IACA,UAAU,EAAM,eAAe;IAC/B,OAAO,EAAM;IACb,EAIM,EAAE,GAAgB,EAAE,aAAU,QACpC,EAAE,GAAoB,EAAE,QAAQ,EAAM,WAAU,IAAK,KAAK,CAC1D;;;CAGH,CAAC,EAMF,IAAe,EAAgB;CAC9B,MAAM;CACN,OAAO;EACN,OAAO;GACN,MAAM;GACN,UAAU;GACV;EACD,gBAAgB;GACf,MAAM;GACN,UAAU;GACV;EACD,OAAO;GACN,MAAM;GACN,SAAS,KAAA;GACT;EACD,eAAe;GACd,MAAM;GACN,SAAS,KAAA;GACT;EACD;CACD,MAAM,GAAO,EAAE,YAAS;EAEvB,IAAM,IAAQ,EAAM,EAAM,MAAiD,EAGrE,IAA0C;GAC/C,GAAG,EAAM,EAAM,eAAe;GAC9B,UAAU,EACT,OAAO,YACN,OAAO,QAAQ,EAAM,EAAM,eAAe,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,OAAO,CACpE,GACA,EAAQ,EAAY,CACpB,CAAC,CACH,CACA;GACD;AAYD,EATI,EAAM,iBACT,OAAO,eAAe,EAAkB,UAAU,iBAAiB;GAClE,OAAO,EAAM;GACb,YAAY;GACZ,cAAc;GACd,CAAC,EAIH,EAAa,EAAmB;EAMhC,IAAM,IAAO,EAHO,EAAM,YAAY,KAAK,CAGG,EAG1C,IAAmC,MACnC,IAA4B,MAC5B,IAAW,GAGT,IAAU,EAAY,EAAM,cAAc,MAAa;AAC5D,KAAK,QAAQ;IACZ;AAMF,SAJA,QAAkB;AACjB,MAAS;IACR,QAEW;AAEZ,OAAI,CAAC,EAAK,MACT,QAAO,EAAM,WAAW,EAAM,UAAS,GAAI;GAG5C,IAAM,IAAO,EAAK,OAGd;AACJ,OAAI,EAAM,MACT,KAAQ,EAAM;QACR;AACN,QAAI,MAAkB,QAAQ,MAAa,EAAK,OAAO;KAEtD,IAAM,IAAW,EAAK;AAUtB,KAFA,IAAgB,EAAsB,EAAE,MAAM,EAL7C,OAAO,KAAa,YADpB,KAEA,CAAC,MAAM,QAAQ,EAAQ,IACvB,OAAO,eAAe,EAAQ,KAAM,OAAO,YACvC,IACD,EAAE,CAC+D,EAAG,CAAC,EACzE,IAAW,EAAK,OAChB;;AAED,QAAQ;;AAIT,UAAO,EAAE,GAAe;IAAE;IAAO,KAAK;IAAU,QAC/C,EAAE,GAAoB;IAAE,gBAAgB;IAAmB;IAAM;IAAO,EAAE,EAAM,CAChF;;;CAGH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"PlayRenderer.js","names":[],"sources":["../src/PlayRenderer.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * PlayRenderer - Main Vue renderer component for XMachines Play architecture\n *\n * Architecture:\n * - Subscribes to actor.currentView signal via TC39 Signal watcher\n * - Renders view.spec via StateProvider → ActionProvider → VisibilityProvider → Renderer\n * - Routes actor actions via registryResult.handlers() real async dispatch functions\n * - Vue ref only for triggering renders, NOT business logic\n *\n * State store: uses external `store` prop if provided (controlled mode); otherwise\n * creates a fresh @xstate/store atom per view transition seeded from spec.state.\n *\n * @invariant Actor Authority - Actor decides all state transitions via guards\n * @invariant Passive Infrastructure - Component observes signals, sends events\n * @invariant Signal-Only Reactivity - Business logic state lives in actor signals\n */\n\nimport { defineComponent, ref, toRaw, markRaw, onUnmounted, h } from \"vue\";\nimport type { PropType } from \"vue\";\nimport { watchSignal } from \"@xmachines/play-signals\";\nimport type { PlayRendererProps } from \"./types.js\";\nimport type { AbstractActor, Viewable, ViewMetadata } from \"@xmachines/play-actor\";\nimport type { AnyActorLogic } from \"xstate\";\nimport type { DefineRegistryResult } from \"@json-render/vue\";\nimport type { StateStore } from \"@json-render/core\";\nimport {\n\tRenderer,\n\tStateProvider,\n\tActionProvider,\n\tVisibilityProvider,\n\tuseStateStore,\n} from \"@json-render/vue\";\nimport type { SetState } from \"@json-render/vue\";\nimport { createAtom } from \"@xstate/store\";\nimport { xstateStoreStateStore } from \"@json-render/xstate\";\nimport { provideActor, type PlayActor } from \"./useActor.js\";\n\n/**\n * Inner component that renders inside StateProvider so it can call useStateStore()\n * to get the live set/getSnapshot functions needed by registryResult.handlers().\n */\nconst PlayRendererInner = defineComponent({\n\tname: \"PlayRendererInner\",\n\tprops: {\n\t\tregistryResult: {\n\t\t\ttype: Object as PropType<DefineRegistryResult>,\n\t\t\trequired: true,\n\t\t},\n\t\tspec: {\n\t\t\ttype: Object as PropType<import(\"@json-render/core\").Spec | null>,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\tsetup(props) {\n\t\treturn () => {\n\t\t\tconst { update, getSnapshot } = useStateStore();\n\t\t\t// Build a SetState adapter: handlers factory expects updater-function pattern\n\t\t\tconst setStateAdapter: SetState = (updater) => {\n\t\t\t\tconst prev = getSnapshot();\n\t\t\t\tupdate(updater(prev));\n\t\t\t};\n\t\t\tconst handlers = props.registryResult.handlers(\n\t\t\t\t() => setStateAdapter,\n\t\t\t\t() => getSnapshot(),\n\t\t\t);\n\t\t\tconst rawRegistry = props.registryResult.registry;\n\n\t\t\treturn h(ActionProvider, { handlers }, () =>\n\t\t\t\th(VisibilityProvider, {}, () =>\n\t\t\t\t\th(Renderer, { spec: props.spec, registry: rawRegistry }),\n\t\t\t\t),\n\t\t\t);\n\t\t};\n\t},\n});\n\nexport default defineComponent({\n\tname: \"PlayRenderer\",\n\tprops: {\n\t\tactor: {\n\t\t\ttype: Object as PropType<AbstractActor<AnyActorLogic> & Viewable>,\n\t\t\trequired: true,\n\t\t},\n\t\tregistryResult: {\n\t\t\ttype: Object as PropType<DefineRegistryResult>,\n\t\t\trequired: true,\n\t\t},\n\t\tstore: {\n\t\t\ttype: Object as PropType<StateStore>,\n\t\t\tdefault: undefined,\n\t\t},\n\t},\n\tsetup(props, { slots }) {\n\t\t// Unwrap actor from Vue's reactive proxy to access raw Signal objects\n\t\tconst actor = toRaw(props.actor);\n\n\t\t// Unwrap the registryResult and mark components as raw to avoid Vue reactivity overhead\n\t\tconst rawRegistryResult: DefineRegistryResult = {\n\t\t\t...toRaw(props.registryResult),\n\t\t\tregistry: markRaw(\n\t\t\t\tObject.fromEntries(\n\t\t\t\t\tObject.entries(toRaw(props.registryResult).registry).map(([k, v]) => [\n\t\t\t\t\t\tk,\n\t\t\t\t\t\tmarkRaw(v as object),\n\t\t\t\t\t]),\n\t\t\t\t) as DefineRegistryResult[\"registry\"],\n\t\t\t),\n\t\t};\n\n\t\t// Provide the raw actor to all descendants via Vue's provide/inject mechanism\n\t\tprovideActor(actor as PlayActor);\n\n\t\t// Get initial value from unwrapped signal\n\t\tconst initialView = actor.currentView.get();\n\n\t\t// Vue ref for triggering re-renders (NOT business logic state)\n\t\tconst view = ref<ViewMetadata | null>(initialView);\n\n\t\t// Internal per-view store — recreated on each view transition when no external store.\n\t\tlet internalStore: StateStore | null = null;\n\t\tlet lastView: ViewMetadata | null = null;\n\t\tlet storeKey = 0;\n\n\t\t// Signal watcher for bridging TC39 Signals to Vue reactivity\n\t\tconst unwatch = watchSignal(actor.currentView, (nextView) => {\n\t\t\tview.value = nextView;\n\t\t});\n\n\t\tonUnmounted(() => {\n\t\t\tunwatch();\n\t\t});\n\n\t\treturn () => {\n\t\t\t// No view — show fallback slot\n\t\t\tif (!view.value) {\n\t\t\t\treturn slots.fallback ? slots.fallback() : null;\n\t\t\t}\n\n\t\t\tconst spec = view.value.spec;\n\n\t\t\t// Resolve the store: external (controlled) or internal per-view atom\n\t\t\tlet store: StateStore;\n\t\t\tif (props.store) {\n\t\t\t\tstore = props.store;\n\t\t\t} else {\n\t\t\t\tif (internalStore === null || lastView !== view.value) {\n\t\t\t\t\tconst initialState = (spec.state as Record<string, unknown>) ?? {};\n\t\t\t\t\tinternalStore = xstateStoreStateStore({ atom: createAtom(initialState) });\n\t\t\t\t\tlastView = view.value;\n\t\t\t\t\tstoreKey++;\n\t\t\t\t}\n\t\t\t\tstore = internalStore;\n\t\t\t}\n\n\t\t\t// PlayRendererInner renders inside StateProvider so useStateStore() works\n\t\t\treturn h(StateProvider, { store, key: storeKey }, () =>\n\t\t\t\th(PlayRendererInner, { registryResult: rawRegistryResult, spec }),\n\t\t\t);\n\t\t};\n\t},\n});\n</script>\n"],"mappings":""}
1
+ {"version":3,"file":"PlayRenderer.js","names":[],"sources":["../src/PlayRenderer.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * PlayRenderer — zero-prop leaf component for the XMachines Vue render architecture.\n *\n * Reads the current view context from the nearest ActorProvider (or PlayUIProvider)\n * and renders <Renderer spec={view.spec} registry={view.registry} />.\n *\n * Must be used inside <ActorProvider> or <PlayUIProvider>.\n *\n * @example\n * ```ts\n * <PlayUIProvider :actor=\"actor\" :registryResult=\"registryResult\">\n * <PlayRenderer />\n * </PlayUIProvider>\n * ```\n *\n * @invariant Passive Infrastructure - Component observes context, never decides\n */\n\nimport { defineComponent, h } from \"vue\";\nimport { Renderer } from \"@json-render/vue\";\nimport { getPlayViewContext } from \"./actor-provider-context.js\";\n\nexport default defineComponent({\n\tname: \"PlayRenderer\",\n\tsetup() {\n\t\treturn () => {\n\t\t\tconst view = getPlayViewContext();\n\t\t\treturn h(Renderer, { spec: view.spec, registry: view.registry });\n\t\t};\n\t},\n});\n</script>\n"],"mappings":""}
@@ -1,40 +1,5 @@
1
- import { PropType } from 'vue';
2
- import { AbstractActor, Viewable } from '@xmachines/play-actor';
3
- import { AnyActorLogic } from 'xstate';
4
- import { DefineRegistryResult } from '@json-render/vue';
5
- import { StateStore } from '@json-render/core';
6
- declare const _default: import('vue', { with: { "resolution-mode": "import" } }).DefineComponent<import('vue', { with: { "resolution-mode": "import" } }).ExtractPropTypes<{
7
- actor: {
8
- type: PropType<AbstractActor<AnyActorLogic> & Viewable>;
9
- required: true;
10
- };
11
- registryResult: {
12
- type: PropType<DefineRegistryResult>;
13
- required: true;
14
- };
15
- store: {
16
- type: PropType<StateStore>;
17
- default: undefined;
18
- };
19
- }>, () => import('vue', { with: { "resolution-mode": "import" } }).VNode<import('vue', { with: { "resolution-mode": "import" } }).RendererNode, import('vue', { with: { "resolution-mode": "import" } }).RendererElement, {
1
+ declare const _default: import('vue', { with: { "resolution-mode": "import" } }).DefineComponent<{}, () => import('vue', { with: { "resolution-mode": "import" } }).VNode<import('vue', { with: { "resolution-mode": "import" } }).RendererNode, import('vue', { with: { "resolution-mode": "import" } }).RendererElement, {
20
2
  [key: string]: any;
21
- }> | import('vue', { with: { "resolution-mode": "import" } }).VNode<import('vue', { with: { "resolution-mode": "import" } }).RendererNode, import('vue', { with: { "resolution-mode": "import" } }).RendererElement, {
22
- [key: string]: any;
23
- }>[] | null, {}, {}, {}, import('vue', { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import('vue', { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {}, string, import('vue', { with: { "resolution-mode": "import" } }).PublicProps, Readonly<import('vue', { with: { "resolution-mode": "import" } }).ExtractPropTypes<{
24
- actor: {
25
- type: PropType<AbstractActor<AnyActorLogic> & Viewable>;
26
- required: true;
27
- };
28
- registryResult: {
29
- type: PropType<DefineRegistryResult>;
30
- required: true;
31
- };
32
- store: {
33
- type: PropType<StateStore>;
34
- default: undefined;
35
- };
36
- }>> & Readonly<{}>, {
37
- store: StateStore;
38
- }, {}, {}, {}, string, import('vue', { with: { "resolution-mode": "import" } }).ComponentProvideOptions, true, {}, any>;
3
+ }>, {}, {}, {}, import('vue', { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import('vue', { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {}, string, import('vue', { with: { "resolution-mode": "import" } }).PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue', { with: { "resolution-mode": "import" } }).ComponentProvideOptions, true, {}, any>;
39
4
  export default _default;
40
5
  //# sourceMappingURL=PlayRenderer.vue.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PlayRenderer.vue.d.ts","sourceRoot":"","sources":["../src/PlayRenderer.vue"],"names":[],"mappings":"AAuLA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAGpC,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAgB,MAAM,uBAAuB,CAAC;AACnF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;;;cAwDjC,QAAQ,CAAC,aAAa,CAAC,aAAa,CAAC,GAAG,QAAQ,CAAC;;;;cAIjD,QAAQ,CAAC,oBAAoB,CAAC;;;;cAI9B,QAAQ,CAAC,UAAU,CAAC;;;;;;;;;cARpB,QAAQ,CAAC,aAAa,CAAC,aAAa,CAAC,GAAG,QAAQ,CAAC;;;;cAIjD,QAAQ,CAAC,oBAAoB,CAAC;;;;cAI9B,QAAQ,CAAC,UAAU,CAAC;;;;;;AAZvC,wBAoFG"}
1
+ {"version":3,"file":"PlayRenderer.vue.d.ts","sourceRoot":"","sources":["../src/PlayRenderer.vue"],"names":[],"mappings":";;;AAyDA,wBAQG"}
@@ -1,74 +1,20 @@
1
- import { ActionProvider as e, Renderer as t, StateProvider as n, VisibilityProvider as r, useStateStore as i } from "./node_modules/@json-render/vue/dist/index.js";
2
- import { createAtom as a } from "./node_modules/@xstate/store/dist/store-69e7e2d5.esm.js";
3
- import { xstateStoreStateStore as o } from "./node_modules/@json-render/xstate/dist/index.js";
4
- import { provideActor as s } from "./useActor.js";
5
- import { defineComponent as c, h as l, markRaw as u, onUnmounted as d, ref as f, toRaw as p } from "vue";
6
- import { watchSignal as m } from "@xmachines/play-signals";
1
+ import { Renderer as e } from "./node_modules/@json-render/vue/dist/index.js";
2
+ import { getPlayViewContext as t } from "./actor-provider-context.js";
3
+ import { defineComponent as n, h as r } from "vue";
7
4
  //#region src/PlayRenderer.vue?vue&type=script&lang.ts
8
- var h = c({
9
- name: "PlayRendererInner",
10
- props: {
11
- registryResult: {
12
- type: Object,
13
- required: !0
14
- },
15
- spec: {
16
- type: Object,
17
- default: null
18
- }
19
- },
20
- setup(n) {
5
+ var i = n({
6
+ name: "PlayRenderer",
7
+ setup() {
21
8
  return () => {
22
- let { update: a, getSnapshot: o } = i(), s = (e) => {
23
- a(e(o()));
24
- }, c = n.registryResult.handlers(() => s, () => o()), u = n.registryResult.registry;
25
- return l(e, { handlers: c }, () => l(r, {}, () => l(t, {
9
+ let n = t();
10
+ return r(e, {
26
11
  spec: n.spec,
27
- registry: u
28
- })));
29
- };
30
- }
31
- }), g = c({
32
- name: "PlayRenderer",
33
- props: {
34
- actor: {
35
- type: Object,
36
- required: !0
37
- },
38
- registryResult: {
39
- type: Object,
40
- required: !0
41
- },
42
- store: {
43
- type: Object,
44
- default: void 0
45
- }
46
- },
47
- setup(e, { slots: t }) {
48
- let r = p(e.actor), i = {
49
- ...p(e.registryResult),
50
- registry: u(Object.fromEntries(Object.entries(p(e.registryResult).registry).map(([e, t]) => [e, u(t)])))
51
- };
52
- s(r);
53
- let c = f(r.currentView.get()), g = null, _ = null, v = 0, y = m(r.currentView, (e) => {
54
- c.value = e;
55
- });
56
- return d(() => {
57
- y();
58
- }), () => {
59
- if (!c.value) return t.fallback ? t.fallback() : null;
60
- let r = c.value.spec, s;
61
- return e.store ? s = e.store : ((g === null || _ !== c.value) && (g = o({ atom: a(r.state ?? {}) }), _ = c.value, v++), s = g), l(n, {
62
- store: s,
63
- key: v
64
- }, () => l(h, {
65
- registryResult: i,
66
- spec: r
67
- }));
12
+ registry: n.registry
13
+ });
68
14
  };
69
15
  }
70
16
  });
71
17
  //#endregion
72
- export { g as default };
18
+ export { i as default };
73
19
 
74
20
  //# sourceMappingURL=PlayRenderer.vue_vue_type_script_lang.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PlayRenderer.vue_vue_type_script_lang.js","names":[],"sources":["../src/PlayRenderer.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * PlayRenderer - Main Vue renderer component for XMachines Play architecture\n *\n * Architecture:\n * - Subscribes to actor.currentView signal via TC39 Signal watcher\n * - Renders view.spec via StateProvider → ActionProvider → VisibilityProvider → Renderer\n * - Routes actor actions via registryResult.handlers() real async dispatch functions\n * - Vue ref only for triggering renders, NOT business logic\n *\n * State store: uses external `store` prop if provided (controlled mode); otherwise\n * creates a fresh @xstate/store atom per view transition seeded from spec.state.\n *\n * @invariant Actor Authority - Actor decides all state transitions via guards\n * @invariant Passive Infrastructure - Component observes signals, sends events\n * @invariant Signal-Only Reactivity - Business logic state lives in actor signals\n */\n\nimport { defineComponent, ref, toRaw, markRaw, onUnmounted, h } from \"vue\";\nimport type { PropType } from \"vue\";\nimport { watchSignal } from \"@xmachines/play-signals\";\nimport type { PlayRendererProps } from \"./types.js\";\nimport type { AbstractActor, Viewable, ViewMetadata } from \"@xmachines/play-actor\";\nimport type { AnyActorLogic } from \"xstate\";\nimport type { DefineRegistryResult } from \"@json-render/vue\";\nimport type { StateStore } from \"@json-render/core\";\nimport {\n\tRenderer,\n\tStateProvider,\n\tActionProvider,\n\tVisibilityProvider,\n\tuseStateStore,\n} from \"@json-render/vue\";\nimport type { SetState } from \"@json-render/vue\";\nimport { createAtom } from \"@xstate/store\";\nimport { xstateStoreStateStore } from \"@json-render/xstate\";\nimport { provideActor, type PlayActor } from \"./useActor.js\";\n\n/**\n * Inner component that renders inside StateProvider so it can call useStateStore()\n * to get the live set/getSnapshot functions needed by registryResult.handlers().\n */\nconst PlayRendererInner = defineComponent({\n\tname: \"PlayRendererInner\",\n\tprops: {\n\t\tregistryResult: {\n\t\t\ttype: Object as PropType<DefineRegistryResult>,\n\t\t\trequired: true,\n\t\t},\n\t\tspec: {\n\t\t\ttype: Object as PropType<import(\"@json-render/core\").Spec | null>,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\tsetup(props) {\n\t\treturn () => {\n\t\t\tconst { update, getSnapshot } = useStateStore();\n\t\t\t// Build a SetState adapter: handlers factory expects updater-function pattern\n\t\t\tconst setStateAdapter: SetState = (updater) => {\n\t\t\t\tconst prev = getSnapshot();\n\t\t\t\tupdate(updater(prev));\n\t\t\t};\n\t\t\tconst handlers = props.registryResult.handlers(\n\t\t\t\t() => setStateAdapter,\n\t\t\t\t() => getSnapshot(),\n\t\t\t);\n\t\t\tconst rawRegistry = props.registryResult.registry;\n\n\t\t\treturn h(ActionProvider, { handlers }, () =>\n\t\t\t\th(VisibilityProvider, {}, () =>\n\t\t\t\t\th(Renderer, { spec: props.spec, registry: rawRegistry }),\n\t\t\t\t),\n\t\t\t);\n\t\t};\n\t},\n});\n\nexport default defineComponent({\n\tname: \"PlayRenderer\",\n\tprops: {\n\t\tactor: {\n\t\t\ttype: Object as PropType<AbstractActor<AnyActorLogic> & Viewable>,\n\t\t\trequired: true,\n\t\t},\n\t\tregistryResult: {\n\t\t\ttype: Object as PropType<DefineRegistryResult>,\n\t\t\trequired: true,\n\t\t},\n\t\tstore: {\n\t\t\ttype: Object as PropType<StateStore>,\n\t\t\tdefault: undefined,\n\t\t},\n\t},\n\tsetup(props, { slots }) {\n\t\t// Unwrap actor from Vue's reactive proxy to access raw Signal objects\n\t\tconst actor = toRaw(props.actor);\n\n\t\t// Unwrap the registryResult and mark components as raw to avoid Vue reactivity overhead\n\t\tconst rawRegistryResult: DefineRegistryResult = {\n\t\t\t...toRaw(props.registryResult),\n\t\t\tregistry: markRaw(\n\t\t\t\tObject.fromEntries(\n\t\t\t\t\tObject.entries(toRaw(props.registryResult).registry).map(([k, v]) => [\n\t\t\t\t\t\tk,\n\t\t\t\t\t\tmarkRaw(v as object),\n\t\t\t\t\t]),\n\t\t\t\t) as DefineRegistryResult[\"registry\"],\n\t\t\t),\n\t\t};\n\n\t\t// Provide the raw actor to all descendants via Vue's provide/inject mechanism\n\t\tprovideActor(actor as PlayActor);\n\n\t\t// Get initial value from unwrapped signal\n\t\tconst initialView = actor.currentView.get();\n\n\t\t// Vue ref for triggering re-renders (NOT business logic state)\n\t\tconst view = ref<ViewMetadata | null>(initialView);\n\n\t\t// Internal per-view store — recreated on each view transition when no external store.\n\t\tlet internalStore: StateStore | null = null;\n\t\tlet lastView: ViewMetadata | null = null;\n\t\tlet storeKey = 0;\n\n\t\t// Signal watcher for bridging TC39 Signals to Vue reactivity\n\t\tconst unwatch = watchSignal(actor.currentView, (nextView) => {\n\t\t\tview.value = nextView;\n\t\t});\n\n\t\tonUnmounted(() => {\n\t\t\tunwatch();\n\t\t});\n\n\t\treturn () => {\n\t\t\t// No view — show fallback slot\n\t\t\tif (!view.value) {\n\t\t\t\treturn slots.fallback ? slots.fallback() : null;\n\t\t\t}\n\n\t\t\tconst spec = view.value.spec;\n\n\t\t\t// Resolve the store: external (controlled) or internal per-view atom\n\t\t\tlet store: StateStore;\n\t\t\tif (props.store) {\n\t\t\t\tstore = props.store;\n\t\t\t} else {\n\t\t\t\tif (internalStore === null || lastView !== view.value) {\n\t\t\t\t\tconst initialState = (spec.state as Record<string, unknown>) ?? {};\n\t\t\t\t\tinternalStore = xstateStoreStateStore({ atom: createAtom(initialState) });\n\t\t\t\t\tlastView = view.value;\n\t\t\t\t\tstoreKey++;\n\t\t\t\t}\n\t\t\t\tstore = internalStore;\n\t\t\t}\n\n\t\t\t// PlayRendererInner renders inside StateProvider so useStateStore() works\n\t\t\treturn h(StateProvider, { store, key: storeKey }, () =>\n\t\t\t\th(PlayRendererInner, { registryResult: rawRegistryResult, spec }),\n\t\t\t);\n\t\t};\n\t},\n});\n</script>\n"],"mappings":";;;;;;;AA0CA,IAAM,IAAoB,EAAgB;CACzC,MAAM;CACN,OAAO;EACN,gBAAgB;GACf,MAAM;GACN,UAAU;GACV;EACD,MAAM;GACL,MAAM;GACN,SAAS;GACT;EACD;CACD,MAAM,GAAO;AACZ,eAAa;GACZ,IAAM,EAAE,WAAQ,mBAAgB,GAAe,EAEzC,KAA6B,MAAY;AAE9C,MAAO,EADM,GAAa,CACN,CAAC;MAEhB,IAAW,EAAM,eAAe,eAC/B,SACA,GAAa,CACnB,EACK,IAAc,EAAM,eAAe;AAEzC,UAAO,EAAE,GAAgB,EAAE,aAAU,QACpC,EAAE,GAAoB,EAAE,QACvB,EAAE,GAAU;IAAE,MAAM,EAAM;IAAM,UAAU;IAAa,CAAC,CACxD,CACD;;;CAGH,CAAC,EAEF,IAAe,EAAgB;CAC9B,MAAM;CACN,OAAO;EACN,OAAO;GACN,MAAM;GACN,UAAU;GACV;EACD,gBAAgB;GACf,MAAM;GACN,UAAU;GACV;EACD,OAAO;GACN,MAAM;GACN,SAAS,KAAA;GACT;EACD;CACD,MAAM,GAAO,EAAE,YAAS;EAEvB,IAAM,IAAQ,EAAM,EAAM,MAAM,EAG1B,IAA0C;GAC/C,GAAG,EAAM,EAAM,eAAe;GAC9B,UAAU,EACT,OAAO,YACN,OAAO,QAAQ,EAAM,EAAM,eAAe,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,OAAO,CACpE,GACA,EAAQ,EAAY,CACpB,CAAC,CACH,CACA;GACD;AAGD,IAAa,EAAmB;EAMhC,IAAM,IAAO,EAHO,EAAM,YAAY,KAAK,CAGO,EAG9C,IAAmC,MACnC,IAAgC,MAChC,IAAW,GAGT,IAAU,EAAY,EAAM,cAAc,MAAa;AAC5D,KAAK,QAAQ;IACZ;AAMF,SAJA,QAAkB;AACjB,MAAS;IACR,QAEW;AAEZ,OAAI,CAAC,EAAK,MACT,QAAO,EAAM,WAAW,EAAM,UAAS,GAAI;GAG5C,IAAM,IAAO,EAAK,MAAM,MAGpB;AAcJ,UAbI,EAAM,QACT,IAAQ,EAAM,UAEV,MAAkB,QAAQ,MAAa,EAAK,WAE/C,IAAgB,EAAsB,EAAE,MAAM,EADxB,EAAK,SAAqC,EAAE,CACG,EAAG,CAAC,EACzE,IAAW,EAAK,OAChB,MAED,IAAQ,IAIF,EAAE,GAAe;IAAE;IAAO,KAAK;IAAU,QAC/C,EAAE,GAAmB;IAAE,gBAAgB;IAAmB;IAAM,CAAC,CACjE;;;CAGH,CAAC"}
1
+ {"version":3,"file":"PlayRenderer.vue_vue_type_script_lang.js","names":[],"sources":["../src/PlayRenderer.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * PlayRenderer — zero-prop leaf component for the XMachines Vue render architecture.\n *\n * Reads the current view context from the nearest ActorProvider (or PlayUIProvider)\n * and renders <Renderer spec={view.spec} registry={view.registry} />.\n *\n * Must be used inside <ActorProvider> or <PlayUIProvider>.\n *\n * @example\n * ```ts\n * <PlayUIProvider :actor=\"actor\" :registryResult=\"registryResult\">\n * <PlayRenderer />\n * </PlayUIProvider>\n * ```\n *\n * @invariant Passive Infrastructure - Component observes context, never decides\n */\n\nimport { defineComponent, h } from \"vue\";\nimport { Renderer } from \"@json-render/vue\";\nimport { getPlayViewContext } from \"./actor-provider-context.js\";\n\nexport default defineComponent({\n\tname: \"PlayRenderer\",\n\tsetup() {\n\t\treturn () => {\n\t\t\tconst view = getPlayViewContext();\n\t\t\treturn h(Renderer, { spec: view.spec, registry: view.registry });\n\t\t};\n\t},\n});\n</script>\n"],"mappings":";;;;AAuBA,IAAA,IAAe,EAAgB;CAC9B,MAAM;CACN,QAAQ;AACP,eAAa;GACZ,IAAM,IAAO,GAAoB;AACjC,UAAO,EAAE,GAAU;IAAE,MAAM,EAAK;IAAM,UAAU,EAAK;IAAU,CAAC;;;CAGlE,CAAC"}
@@ -0,0 +1,7 @@
1
+ import e from "./PlayUIProvider.vue_vue_type_script_lang.js";
2
+ //#region src/PlayUIProvider.vue
3
+ var t = e;
4
+ //#endregion
5
+ export { t as default };
6
+
7
+ //# sourceMappingURL=PlayUIProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlayUIProvider.js","names":[],"sources":["../src/PlayUIProvider.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * PlayUIProvider — batteries-included composite provider for actor-driven UI rendering.\n *\n * Wraps ActorProvider + JSONUIProvider (from @json-render/vue) to provide a single\n * entry point for all actor lifecycle and UI rendering concerns.\n *\n * Standard usage:\n * ```ts\n * <PlayUIProvider :actor=\"actor\" :registryResult=\"registryResult\">\n * <PlayRenderer />\n * </PlayUIProvider>\n * ```\n *\n * For custom provider composition (escape hatch), use <ActorProvider> directly.\n *\n * @packageDocumentation\n */\n\nimport { defineComponent, h } from \"vue\";\nimport type { PropType } from \"vue\";\nimport { JSONUIProvider } from \"@json-render/vue\";\nimport type { DefineRegistryResult, RenderErrorHandler } from \"@json-render/vue\";\n\nimport type { StateStore } from \"@json-render/core\";\nimport type { AbstractActor, Viewable } from \"@xmachines/play-actor\";\nimport type { AnyActorLogic } from \"xstate\";\nimport ActorProvider from \"./ActorProvider.vue\";\nimport { getPlayViewContext } from \"./actor-provider-context.js\";\nimport type { PlayUIProviderProps } from \"./types.js\";\n\n// Re-export props type for consumers who import from this file\nexport type { PlayUIProviderProps } from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// JSONUIBridge — inner component inside ActorProvider's tree\n// Reads ViewContextValue via getPlayViewContext() and passes handlers + registry\n// to JSONUIProvider so both ActorProvider and JSONUIProvider share the same state.\n// ---------------------------------------------------------------------------\n\nconst JSONUIBridge = defineComponent({\n\tname: \"JSONUIBridge\",\n\tprops: {\n\t\tnavigate: {\n\t\t\ttype: Function as PropType<(path: string) => void>,\n\t\t\tdefault: undefined,\n\t\t},\n\t\tvalidationFunctions: {\n\t\t\ttype: Object as PropType<\n\t\t\t\tRecord<string, (value: unknown, args?: Record<string, unknown>) => boolean>\n\t\t\t>,\n\t\t\tdefault: undefined,\n\t\t},\n\t\tfunctions: {\n\t\t\ttype: Object as PropType<\n\t\t\t\tRecord<string, (args?: Record<string, unknown>, state?: Record<string, unknown>) => unknown>\n\t\t\t>,\n\t\t\tdefault: undefined,\n\t\t},\n\t},\n\tsetup(props, { slots }) {\n\t\treturn () => {\n\t\t\tconst view = getPlayViewContext();\n\t\t\treturn h(\n\t\t\t\tJSONUIProvider,\n\t\t\t\t{\n\t\t\t\t\tregistry: view.registry,\n\t\t\t\t\thandlers: view.handlers,\n\t\t\t\t\tstore: view.store,\n\t\t\t\t\t...(props.navigate ? { navigate: props.navigate } : {}),\n\t\t\t\t\t...(props.validationFunctions ? { validationFunctions: props.validationFunctions } : {}),\n\t\t\t\t\t...(props.functions ? { functions: props.functions } : {}),\n\t\t\t\t},\n\t\t\t\tslots,\n\t\t\t);\n\t\t};\n\t},\n});\n\n// ---------------------------------------------------------------------------\n// PlayUIProvider — main export\n// ---------------------------------------------------------------------------\n\nexport default defineComponent({\n\tname: \"PlayUIProvider\",\n\tprops: {\n\t\tactor: {\n\t\t\ttype: Object as PropType<AbstractActor<AnyActorLogic> & Viewable>,\n\t\t\trequired: true,\n\t\t},\n\t\tregistryResult: {\n\t\t\ttype: Object as PropType<DefineRegistryResult>,\n\t\t\trequired: true,\n\t\t},\n\t\tstore: {\n\t\t\ttype: Object as PropType<StateStore>,\n\t\t\tdefault: undefined,\n\t\t},\n\t\tonRenderError: {\n\t\t\ttype: Function as PropType<RenderErrorHandler>,\n\t\t\tdefault: undefined,\n\t\t},\n\t\tnavigate: {\n\t\t\ttype: Function as PropType<PlayUIProviderProps[\"navigate\"]>,\n\t\t\tdefault: undefined,\n\t\t},\n\t\tvalidationFunctions: {\n\t\t\ttype: Object as PropType<PlayUIProviderProps[\"validationFunctions\"]>,\n\t\t\tdefault: undefined,\n\t\t},\n\t\tfunctions: {\n\t\t\ttype: Object as PropType<PlayUIProviderProps[\"functions\"]>,\n\t\t\tdefault: undefined,\n\t\t},\n\t},\n\tsetup(props, { slots }) {\n\t\treturn () =>\n\t\t\th(\n\t\t\t\tActorProvider,\n\t\t\t\t{\n\t\t\t\t\tactor: props.actor,\n\t\t\t\t\tregistryResult: props.registryResult,\n\t\t\t\t\t...(props.store ? { store: props.store } : {}),\n\t\t\t\t\t...(props.onRenderError ? { onRenderError: props.onRenderError } : {}),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdefault: () =>\n\t\t\t\t\t\th(\n\t\t\t\t\t\t\tJSONUIBridge,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t...(props.navigate ? { navigate: props.navigate } : {}),\n\t\t\t\t\t\t\t\t...(props.validationFunctions\n\t\t\t\t\t\t\t\t\t? { validationFunctions: props.validationFunctions }\n\t\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t\t...(props.functions ? { functions: props.functions } : {}),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tslots,\n\t\t\t\t\t\t),\n\t\t\t\t\tfallback: slots.fallback,\n\t\t\t\t},\n\t\t\t);\n\t},\n});\n</script>\n"],"mappings":""}