@xmachines/play-vue 1.0.0 → 1.1.0

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.
package/README.md CHANGED
@@ -1,13 +1,11 @@
1
- <!-- generated-by: gsd-doc-writer -->
2
-
3
1
  # `@xmachines/play-vue`
4
2
 
5
3
  > Vue 3 renderer for the XMachines Play Architecture — passively observes actor signals and renders UI via `@xmachines/json-render-vue`.
6
4
 
7
5
  Part of the [XMachines Play monorepo](../../README.md).
8
6
 
9
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
10
- [![Version](https://img.shields.io/badge/version-1.0.0--beta.51-blue.svg)](package.json)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+ [![Version](https://img.shields.io/badge/version-1.1.0-blue)](https://www.npmjs.com/package/@xmachines/play-vue)
11
9
 
12
10
  ---
13
11
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xmachines/play-vue",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Vue renderer for XMachines Play architecture",
5
5
  "keywords": [
6
6
  "reactive",
@@ -10,6 +10,7 @@
10
10
  "xmachines"
11
11
  ],
12
12
  "license": "MIT",
13
+ "author": "Mikael Karon <mikael@karon.se>",
13
14
  "repository": {
14
15
  "type": "git",
15
16
  "url": "git+ssh://git@gitlab.com/xmachin-es/xmachines-js.git",
@@ -21,11 +22,11 @@
21
22
  "LICENSE"
22
23
  ],
23
24
  "type": "module",
25
+ "sideEffects": false,
24
26
  "main": "./dist/index.js",
25
27
  "types": "./dist/index.d.ts",
26
28
  "exports": {
27
29
  ".": {
28
- "source": "./src/index.ts",
29
30
  "types": "./dist/index.d.ts",
30
31
  "default": "./dist/index.js"
31
32
  }
@@ -39,31 +40,29 @@
39
40
  "lint": "oxlint .",
40
41
  "format": "oxfmt .",
41
42
  "test": "vitest",
42
- "test:watch": "vitest",
43
- "prepublishOnly": "npm run build"
43
+ "test:watch": "vitest"
44
44
  },
45
45
  "dependencies": {
46
- "@xmachines/play": "1.0.0",
47
- "@xmachines/play-actor": "1.0.0",
48
- "@xmachines/play-signals": "1.0.0"
46
+ "@xmachines/play": "1.1.0",
47
+ "@xmachines/play-actor": "1.1.0",
48
+ "@xmachines/play-signals": "1.1.0"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@testing-library/jest-dom": "^6.9.1",
52
- "@types/node": "^26.1.1",
52
+ "@types/node": "^26.2.0",
53
53
  "@vitejs/plugin-vue": "^6.0.5",
54
54
  "@vitest/browser-playwright": "^4.1.10",
55
55
  "@vue/test-utils": "^2.4.9",
56
56
  "@xmachines/json-render-core": "^0.19.0-xm.2",
57
57
  "@xmachines/json-render-vue": "^0.19.0-xm.2",
58
58
  "@xmachines/json-render-xstate": "^0.19.0-xm.2",
59
- "@xmachines/shared": "1.0.0",
60
59
  "@xstate/store": "^3.17.0",
61
- "oxfmt": "^0.58.0",
62
- "oxlint": "^1.73.0",
60
+ "oxfmt": "^0.64.0",
61
+ "oxlint": "^1.79.0",
63
62
  "typescript": "^5.9.3 || ^6.0.3",
64
63
  "vite": "^8.0.10",
65
64
  "vite-plugin-dts": "^4.5.4",
66
- "vitest": "^4.1.10",
65
+ "vitest": "^4.1.11",
67
66
  "vue": "^3.5.33",
68
67
  "xstate": "^5.31.0",
69
68
  "zod": "^4.4.1"
@@ -1,8 +0,0 @@
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
@@ -1 +0,0 @@
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 {\n\tdefineComponent,\n\tref,\n\tcomputed,\n\ttoRaw,\n\tmarkRaw,\n\tonUnmounted,\n\th,\n\tprovide,\n\tshallowRef,\n\twatch,\n} from \"vue\";\nimport type { PropType } from \"vue\";\nimport { watchSignal } from \"@xmachines/play-signals\";\nimport { toAtomState, attachRenderErrorHandler } from \"@xmachines/play-actor\";\nimport type { AbstractActor, Viewable, PlaySpec } from \"@xmachines/play-actor\";\nimport type { AnyActorLogic } from \"xstate\";\nimport type {\n\tDefineRegistryResult,\n\tSetState,\n\tRenderErrorHandler,\n} from \"@xmachines/json-render-vue\";\n\nimport {\n\tStateProvider,\n\tuseStateStore,\n\tActionProvider,\n\tVisibilityProvider,\n} from \"@xmachines/json-render-vue\";\nimport type { StateStore } from \"@xmachines/json-render-core\";\nimport { createAtom } from \"@xstate/store\";\nimport { xstateStoreStateStore } from \"@xmachines/json-render-xstate\";\nimport { provideActor, type AnyPlayActor } 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\t// Call useStateStore() at setup() time (synchronous, before return).\n\t\t// Vue composables that use inject() must be called during setup(), not in a render function.\n\t\tconst stateStore = useStateStore();\n\n\t\t// Build a SetState adapter: handlers factory expects updater-function pattern.\n\t\t// Defined once in setup() — reads stateStore.getSnapshot/update at invocation\n\t\t// time so it always operates on the live store state without needing to be\n\t\t// recreated when stateStore identity changes across renders.\n\t\tconst setStateAdapter: SetState = (updater) => {\n\t\t\tconst prev = stateStore.getSnapshot();\n\t\t\tstateStore.update(updater(prev));\n\t\t};\n\n\t\t// Memoize handlers keyed to registryResult prop identity. The getter functions\n\t\t// are stable closures capturing stateStore from setup(), so they do not\n\t\t// contribute to invalidation. Handlers are only recomputed when the registry\n\t\t// definition itself changes — not on every render triggered by view updates.\n\t\tconst handlers = computed(() =>\n\t\t\tprops.registryResult.handlers(\n\t\t\t\t() => setStateAdapter,\n\t\t\t\t() => stateStore.getSnapshot(),\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\tviewRef.value = {\n\t\t\t\tspec: props.spec,\n\t\t\t\thandlers: handlers.value,\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: handlers.value }, () =>\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\t// Held in a shallowRef so the provided injection and the signal watcher\n\t\t// can follow `props.actor` when the prop swaps after mount.\n\t\tconst actorRef = shallowRef(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 rawRegistry = Object.fromEntries(\n\t\t\tObject.entries(toRaw(props.registryResult).registry).map(([k, v]) => [\n\t\t\t\tk,\n\t\t\t\tmarkRaw(v as object),\n\t\t\t]),\n\t\t) as DefineRegistryResult[\"registry\"];\n\n\t\t// Inject onRenderError prop into registry (non-enumerable, overrides defineRegistry-level\n\t\t// handler). attachRenderErrorHandler clones — the caller's registry is never mutated.\n\t\t// The clone must be re-markRaw'd: markRaw's non-enumerable flag is not carried by the clone.\n\t\tconst rawRegistryResult: DefineRegistryResult = {\n\t\t\t...toRaw(props.registryResult),\n\t\t\tregistry: markRaw(\n\t\t\t\tprops.onRenderError\n\t\t\t\t\t? attachRenderErrorHandler(rawRegistry, props.onRenderError)\n\t\t\t\t\t: rawRegistry,\n\t\t\t),\n\t\t};\n\n\t\t// Provide the actor to all descendants via Vue's provide/inject mechanism.\n\t\t//\n\t\t// A stable Proxy (same pattern as ActorProviderInner's ViewKey proxy) is\n\t\t// provided instead of the raw actor so the injection tracks the CURRENT\n\t\t// `props.actor`: injectors keep the reference obtained at setup() time,\n\t\t// yet every trap resolves against the latest actor (actorRef.value) after a\n\t\t// prop swap. All relevant traps are forwarded so the proxy behaves like the\n\t\t// underlying actor for reads, writes, membership (`in`), enumeration\n\t\t// (Object.keys / spread), and prototype checks (`instanceof`). Methods are\n\t\t// bound to the current raw actor so `this` (including private fields) works\n\t\t// exactly as with a direct call.\n\t\t//\n\t\t// IMPORTANT: this proxy is NOT identity-equal to `props.actor` — it is a\n\t\t// distinct object, hence a distinct WeakMap key. Identity-keyed consumers —\n\t\t// notably RouterBridgeBase's one-bridge-per-actor guard, which keys a\n\t\t// module-level WeakMap on actor identity — must be handed the `props.actor`\n\t\t// value itself, never this injected proxy.\n\t\t//\n\t\t// Method identity: bound methods are cached per underlying method so repeated\n\t\t// reads return the SAME function (actor.send === actor.send — allocation-free\n\t\t// hot path). A read rebinds only when the underlying method changes; the cache\n\t\t// is CLEARED on actor swap (see the watch handler below) so prototype methods\n\t\t// rebind to the new actor.\n\t\tconst boundMethodCache = new Map<PropertyKey, { source: unknown; bound: unknown }>();\n\t\tprovideActor(\n\t\t\tnew Proxy({} as AnyPlayActor, {\n\t\t\t\tget(_target, prop) {\n\t\t\t\t\tconst current = actorRef.value;\n\t\t\t\t\tconst value = Reflect.get(current, prop, current) as unknown;\n\t\t\t\t\tif (typeof value !== \"function\") return value;\n\t\t\t\t\tconst cached = boundMethodCache.get(prop);\n\t\t\t\t\tif (cached && cached.source === value) return cached.bound;\n\t\t\t\t\tconst bound = (value as (...args: unknown[]) => unknown).bind(current);\n\t\t\t\t\tboundMethodCache.set(prop, { source: value, bound });\n\t\t\t\t\treturn bound;\n\t\t\t\t},\n\t\t\t\thas(_target, prop) {\n\t\t\t\t\treturn prop in actorRef.value;\n\t\t\t\t},\n\t\t\t\tset(_target, prop, value) {\n\t\t\t\t\treturn Reflect.set(actorRef.value, prop, value, actorRef.value);\n\t\t\t\t},\n\t\t\t\tdeleteProperty(_target, prop) {\n\t\t\t\t\treturn Reflect.deleteProperty(actorRef.value, prop);\n\t\t\t\t},\n\t\t\t\townKeys() {\n\t\t\t\t\treturn Reflect.ownKeys(actorRef.value);\n\t\t\t\t},\n\t\t\t\tgetOwnPropertyDescriptor(_target, prop) {\n\t\t\t\t\tconst desc = Reflect.getOwnPropertyDescriptor(actorRef.value, prop);\n\t\t\t\t\tif (!desc) return undefined;\n\t\t\t\t\t// Proxy invariant: the proxy target is an empty {}, so every key\n\t\t\t\t\t// reported via ownKeys must resolve to a configurable descriptor here\n\t\t\t\t\t// — otherwise the [[GetOwnProperty]] invariant throws (a non-existent\n\t\t\t\t\t// target property may not be reported as non-configurable). The actor's\n\t\t\t\t\t// own props are runtime-mutable anyway, so reporting configurable:true\n\t\t\t\t\t// is faithful enough for Object.keys / spread enumeration.\n\t\t\t\t\tdesc.configurable = true;\n\t\t\t\t\treturn desc;\n\t\t\t\t},\n\t\t\t\tgetPrototypeOf() {\n\t\t\t\t\treturn Reflect.getPrototypeOf(actorRef.value);\n\t\t\t\t},\n\t\t\t}) as AnyPlayActor,\n\t\t);\n\n\t\t// Seed initial value then subscribe — both synchronous, no scheduler gap.\n\t\t// This mirrors the atomic seed+watch pattern used in Solid (createEffect)\n\t\t// and Svelte ($effect) for cross-framework consistency.\n\t\tconst view = ref<PlaySpec | null>(actorRef.value.currentView.get());\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\t// storeKey is only incremented in the internalStore branch (not when props.store is set)\n\t\tlet storeKey = 0;\n\n\t\t// Signal watcher for bridging TC39 Signals to Vue reactivity.\n\t\t// Re-assigned on actor swap so cleanup always releases the live watcher.\n\t\tlet unwatch = watchSignal(actorRef.value.currentView, (nextView) => {\n\t\t\tview.value = nextView;\n\t\t});\n\n\t\t// React to `props.actor` swaps: unsubscribe the OLD actor's currentView,\n\t\t// re-seed the view from the NEW actor synchronously (flush: \"sync\" — no\n\t\t// scheduler gap, matching the mount-time seed+watch pattern above), and\n\t\t// subscribe the new signal. The re-seeded view is a new object identity,\n\t\t// so the internal-store branch below rebuilds the store and bumps\n\t\t// storeKey exactly like a regular view transition.\n\t\twatch(\n\t\t\t() => toRaw(props.actor as AbstractActor<AnyActorLogic> & Viewable),\n\t\t\t(nextActor) => {\n\t\t\t\tif (nextActor === actorRef.value) return;\n\t\t\t\tunwatch();\n\t\t\t\tactorRef.value = nextActor;\n\t\t\t\t// Invalidate cached bound methods so prototype methods rebind to the\n\t\t\t\t// new actor on the next read (see the injected proxy's get trap).\n\t\t\t\tboundMethodCache.clear();\n\t\t\t\tview.value = nextActor.currentView.get();\n\t\t\t\tunwatch = watchSignal(nextActor.currentView, (nextView) => {\n\t\t\t\t\tview.value = nextView;\n\t\t\t\t});\n\t\t\t},\n\t\t\t{ flush: \"sync\" },\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\tinternalStore = xstateStoreStateStore({\n\t\t\t\t\t\tatom: createAtom(toAtomState(spec.state)),\n\t\t\t\t\t});\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":""}
@@ -1,51 +0,0 @@
1
- import { PropType } from 'vue';
2
- import { DefineRegistryResult, RenderErrorHandler } from '@xmachines/json-render-vue';
3
- import { StateStore } from '@xmachines/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/runtime-core').DefineComponent<import('@vue/runtime-core').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/runtime-core').VNode<import('@vue/runtime-core').RendererNode, import('@vue/runtime-core').RendererElement, {
26
- [key: string]: any;
27
- }> | import('@vue/runtime-core').VNode<import('@vue/runtime-core').RendererNode, import('@vue/runtime-core').RendererElement, {
28
- [key: string]: any;
29
- }>[] | null, {}, {}, {}, import('@vue/runtime-core').ComponentOptionsMixin, import('@vue/runtime-core').ComponentOptionsMixin, {}, string, import('@vue/runtime-core').PublicProps, Readonly<import('@vue/runtime-core').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
- onRenderError: RenderErrorHandler;
48
- store: StateStore;
49
- }, {}, {}, {}, string, import('@vue/runtime-core').ComponentProvideOptions, true, {}, any>;
50
- export default _default;
51
- //# sourceMappingURL=ActorProvider.vue.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ActorProvider.vue.d.ts","sourceRoot":"","sources":["../src/ActorProvider.vue"],"names":[],"mappings":"AAkXA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAKpC,OAAO,KAAK,EACX,oBAAoB,EAEpB,kBAAkB,EAClB,MAAM,4BAA4B,CAAC;AAQpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAK9D,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;;;cA8FjD,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,wBA0LG"}
@@ -1,125 +0,0 @@
1
- import { ViewKey as e } from "./actor-provider-context.js";
2
- import { provideActor as t } from "./useActor.js";
3
- import { computed as n, defineComponent as r, h as i, markRaw as a, onUnmounted as o, provide as s, ref as c, shallowRef as l, toRaw as u, watch as d } from "vue";
4
- import { ActionProvider as f, StateProvider as p, VisibilityProvider as m, useStateStore as h } from "@xmachines/json-render-vue";
5
- import { watchSignal as g } from "@xmachines/play-signals";
6
- import { attachRenderErrorHandler as _, toAtomState as v } from "@xmachines/play-actor";
7
- import { createAtom as y } from "@xstate/store";
8
- import { xstateStoreStateStore as b } from "@xmachines/json-render-xstate";
9
- //#region src/ActorProvider.vue?vue&type=script&lang.ts
10
- var x = r({
11
- name: "ActorProviderInner",
12
- props: {
13
- registryResult: {
14
- type: Object,
15
- required: !0
16
- },
17
- spec: {
18
- type: Object,
19
- default: null
20
- },
21
- store: {
22
- type: Object,
23
- required: !0
24
- }
25
- },
26
- setup(t, { slots: r }) {
27
- let a = l(null);
28
- s(e, new Proxy({}, { get(e, t) {
29
- return a.value?.[t];
30
- } }));
31
- let o = h(), c = (e) => {
32
- let t = o.getSnapshot();
33
- o.update(e(t));
34
- }, u = n(() => t.registryResult.handlers(() => c, () => o.getSnapshot()));
35
- return () => t.spec ? (a.value = {
36
- spec: t.spec,
37
- handlers: u.value,
38
- registry: t.registryResult.registry,
39
- store: t.store
40
- }, i(f, { handlers: u.value }, () => i(m, {}, () => r.default?.() ?? null))) : (a.value = null, r.default?.() ?? null);
41
- }
42
- }), S = r({
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 = l(u(e.actor)), s = Object.fromEntries(Object.entries(u(e.registryResult).registry).map(([e, t]) => [e, a(t)])), f = {
64
- ...u(e.registryResult),
65
- registry: a(e.onRenderError ? _(s, e.onRenderError) : s)
66
- }, m = /* @__PURE__ */ new Map();
67
- t(new Proxy({}, {
68
- get(e, t) {
69
- let n = r.value, i = Reflect.get(n, t, n);
70
- if (typeof i != "function") return i;
71
- let a = m.get(t);
72
- if (a && a.source === i) return a.bound;
73
- let o = i.bind(n);
74
- return m.set(t, {
75
- source: i,
76
- bound: o
77
- }), o;
78
- },
79
- has(e, t) {
80
- return t in r.value;
81
- },
82
- set(e, t, n) {
83
- return Reflect.set(r.value, t, n, r.value);
84
- },
85
- deleteProperty(e, t) {
86
- return Reflect.deleteProperty(r.value, t);
87
- },
88
- ownKeys() {
89
- return Reflect.ownKeys(r.value);
90
- },
91
- getOwnPropertyDescriptor(e, t) {
92
- let n = Reflect.getOwnPropertyDescriptor(r.value, t);
93
- if (n) return n.configurable = !0, n;
94
- },
95
- getPrototypeOf() {
96
- return Reflect.getPrototypeOf(r.value);
97
- }
98
- }));
99
- let h = c(r.value.currentView.get()), S = null, C = null, w = 0, T = g(r.value.currentView, (e) => {
100
- h.value = e;
101
- });
102
- return d(() => u(e.actor), (e) => {
103
- e !== r.value && (T(), r.value = e, m.clear(), h.value = e.currentView.get(), T = g(e.currentView, (e) => {
104
- h.value = e;
105
- }));
106
- }, { flush: "sync" }), o(() => {
107
- T();
108
- }), () => {
109
- if (!h.value) return n.fallback ? n.fallback() : null;
110
- let t = h.value, r;
111
- return e.store ? r = e.store : ((S === null || C !== h.value) && (S = b({ atom: y(v(t.state)) }), C = h.value, w++), r = S), i(p, {
112
- store: r,
113
- key: w
114
- }, () => i(x, {
115
- registryResult: f,
116
- spec: t,
117
- store: r
118
- }, n));
119
- };
120
- }
121
- });
122
- //#endregion
123
- export { S as default };
124
-
125
- //# sourceMappingURL=ActorProvider.vue_vue_type_script_lang.js.map
@@ -1 +0,0 @@
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 {\n\tdefineComponent,\n\tref,\n\tcomputed,\n\ttoRaw,\n\tmarkRaw,\n\tonUnmounted,\n\th,\n\tprovide,\n\tshallowRef,\n\twatch,\n} from \"vue\";\nimport type { PropType } from \"vue\";\nimport { watchSignal } from \"@xmachines/play-signals\";\nimport { toAtomState, attachRenderErrorHandler } from \"@xmachines/play-actor\";\nimport type { AbstractActor, Viewable, PlaySpec } from \"@xmachines/play-actor\";\nimport type { AnyActorLogic } from \"xstate\";\nimport type {\n\tDefineRegistryResult,\n\tSetState,\n\tRenderErrorHandler,\n} from \"@xmachines/json-render-vue\";\n\nimport {\n\tStateProvider,\n\tuseStateStore,\n\tActionProvider,\n\tVisibilityProvider,\n} from \"@xmachines/json-render-vue\";\nimport type { StateStore } from \"@xmachines/json-render-core\";\nimport { createAtom } from \"@xstate/store\";\nimport { xstateStoreStateStore } from \"@xmachines/json-render-xstate\";\nimport { provideActor, type AnyPlayActor } 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\t// Call useStateStore() at setup() time (synchronous, before return).\n\t\t// Vue composables that use inject() must be called during setup(), not in a render function.\n\t\tconst stateStore = useStateStore();\n\n\t\t// Build a SetState adapter: handlers factory expects updater-function pattern.\n\t\t// Defined once in setup() — reads stateStore.getSnapshot/update at invocation\n\t\t// time so it always operates on the live store state without needing to be\n\t\t// recreated when stateStore identity changes across renders.\n\t\tconst setStateAdapter: SetState = (updater) => {\n\t\t\tconst prev = stateStore.getSnapshot();\n\t\t\tstateStore.update(updater(prev));\n\t\t};\n\n\t\t// Memoize handlers keyed to registryResult prop identity. The getter functions\n\t\t// are stable closures capturing stateStore from setup(), so they do not\n\t\t// contribute to invalidation. Handlers are only recomputed when the registry\n\t\t// definition itself changes — not on every render triggered by view updates.\n\t\tconst handlers = computed(() =>\n\t\t\tprops.registryResult.handlers(\n\t\t\t\t() => setStateAdapter,\n\t\t\t\t() => stateStore.getSnapshot(),\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\tviewRef.value = {\n\t\t\t\tspec: props.spec,\n\t\t\t\thandlers: handlers.value,\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: handlers.value }, () =>\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\t// Held in a shallowRef so the provided injection and the signal watcher\n\t\t// can follow `props.actor` when the prop swaps after mount.\n\t\tconst actorRef = shallowRef(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 rawRegistry = Object.fromEntries(\n\t\t\tObject.entries(toRaw(props.registryResult).registry).map(([k, v]) => [\n\t\t\t\tk,\n\t\t\t\tmarkRaw(v as object),\n\t\t\t]),\n\t\t) as DefineRegistryResult[\"registry\"];\n\n\t\t// Inject onRenderError prop into registry (non-enumerable, overrides defineRegistry-level\n\t\t// handler). attachRenderErrorHandler clones — the caller's registry is never mutated.\n\t\t// The clone must be re-markRaw'd: markRaw's non-enumerable flag is not carried by the clone.\n\t\tconst rawRegistryResult: DefineRegistryResult = {\n\t\t\t...toRaw(props.registryResult),\n\t\t\tregistry: markRaw(\n\t\t\t\tprops.onRenderError\n\t\t\t\t\t? attachRenderErrorHandler(rawRegistry, props.onRenderError)\n\t\t\t\t\t: rawRegistry,\n\t\t\t),\n\t\t};\n\n\t\t// Provide the actor to all descendants via Vue's provide/inject mechanism.\n\t\t//\n\t\t// A stable Proxy (same pattern as ActorProviderInner's ViewKey proxy) is\n\t\t// provided instead of the raw actor so the injection tracks the CURRENT\n\t\t// `props.actor`: injectors keep the reference obtained at setup() time,\n\t\t// yet every trap resolves against the latest actor (actorRef.value) after a\n\t\t// prop swap. All relevant traps are forwarded so the proxy behaves like the\n\t\t// underlying actor for reads, writes, membership (`in`), enumeration\n\t\t// (Object.keys / spread), and prototype checks (`instanceof`). Methods are\n\t\t// bound to the current raw actor so `this` (including private fields) works\n\t\t// exactly as with a direct call.\n\t\t//\n\t\t// IMPORTANT: this proxy is NOT identity-equal to `props.actor` — it is a\n\t\t// distinct object, hence a distinct WeakMap key. Identity-keyed consumers —\n\t\t// notably RouterBridgeBase's one-bridge-per-actor guard, which keys a\n\t\t// module-level WeakMap on actor identity — must be handed the `props.actor`\n\t\t// value itself, never this injected proxy.\n\t\t//\n\t\t// Method identity: bound methods are cached per underlying method so repeated\n\t\t// reads return the SAME function (actor.send === actor.send — allocation-free\n\t\t// hot path). A read rebinds only when the underlying method changes; the cache\n\t\t// is CLEARED on actor swap (see the watch handler below) so prototype methods\n\t\t// rebind to the new actor.\n\t\tconst boundMethodCache = new Map<PropertyKey, { source: unknown; bound: unknown }>();\n\t\tprovideActor(\n\t\t\tnew Proxy({} as AnyPlayActor, {\n\t\t\t\tget(_target, prop) {\n\t\t\t\t\tconst current = actorRef.value;\n\t\t\t\t\tconst value = Reflect.get(current, prop, current) as unknown;\n\t\t\t\t\tif (typeof value !== \"function\") return value;\n\t\t\t\t\tconst cached = boundMethodCache.get(prop);\n\t\t\t\t\tif (cached && cached.source === value) return cached.bound;\n\t\t\t\t\tconst bound = (value as (...args: unknown[]) => unknown).bind(current);\n\t\t\t\t\tboundMethodCache.set(prop, { source: value, bound });\n\t\t\t\t\treturn bound;\n\t\t\t\t},\n\t\t\t\thas(_target, prop) {\n\t\t\t\t\treturn prop in actorRef.value;\n\t\t\t\t},\n\t\t\t\tset(_target, prop, value) {\n\t\t\t\t\treturn Reflect.set(actorRef.value, prop, value, actorRef.value);\n\t\t\t\t},\n\t\t\t\tdeleteProperty(_target, prop) {\n\t\t\t\t\treturn Reflect.deleteProperty(actorRef.value, prop);\n\t\t\t\t},\n\t\t\t\townKeys() {\n\t\t\t\t\treturn Reflect.ownKeys(actorRef.value);\n\t\t\t\t},\n\t\t\t\tgetOwnPropertyDescriptor(_target, prop) {\n\t\t\t\t\tconst desc = Reflect.getOwnPropertyDescriptor(actorRef.value, prop);\n\t\t\t\t\tif (!desc) return undefined;\n\t\t\t\t\t// Proxy invariant: the proxy target is an empty {}, so every key\n\t\t\t\t\t// reported via ownKeys must resolve to a configurable descriptor here\n\t\t\t\t\t// — otherwise the [[GetOwnProperty]] invariant throws (a non-existent\n\t\t\t\t\t// target property may not be reported as non-configurable). The actor's\n\t\t\t\t\t// own props are runtime-mutable anyway, so reporting configurable:true\n\t\t\t\t\t// is faithful enough for Object.keys / spread enumeration.\n\t\t\t\t\tdesc.configurable = true;\n\t\t\t\t\treturn desc;\n\t\t\t\t},\n\t\t\t\tgetPrototypeOf() {\n\t\t\t\t\treturn Reflect.getPrototypeOf(actorRef.value);\n\t\t\t\t},\n\t\t\t}) as AnyPlayActor,\n\t\t);\n\n\t\t// Seed initial value then subscribe — both synchronous, no scheduler gap.\n\t\t// This mirrors the atomic seed+watch pattern used in Solid (createEffect)\n\t\t// and Svelte ($effect) for cross-framework consistency.\n\t\tconst view = ref<PlaySpec | null>(actorRef.value.currentView.get());\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\t// storeKey is only incremented in the internalStore branch (not when props.store is set)\n\t\tlet storeKey = 0;\n\n\t\t// Signal watcher for bridging TC39 Signals to Vue reactivity.\n\t\t// Re-assigned on actor swap so cleanup always releases the live watcher.\n\t\tlet unwatch = watchSignal(actorRef.value.currentView, (nextView) => {\n\t\t\tview.value = nextView;\n\t\t});\n\n\t\t// React to `props.actor` swaps: unsubscribe the OLD actor's currentView,\n\t\t// re-seed the view from the NEW actor synchronously (flush: \"sync\" — no\n\t\t// scheduler gap, matching the mount-time seed+watch pattern above), and\n\t\t// subscribe the new signal. The re-seeded view is a new object identity,\n\t\t// so the internal-store branch below rebuilds the store and bumps\n\t\t// storeKey exactly like a regular view transition.\n\t\twatch(\n\t\t\t() => toRaw(props.actor as AbstractActor<AnyActorLogic> & Viewable),\n\t\t\t(nextActor) => {\n\t\t\t\tif (nextActor === actorRef.value) return;\n\t\t\t\tunwatch();\n\t\t\t\tactorRef.value = nextActor;\n\t\t\t\t// Invalidate cached bound methods so prototype methods rebind to the\n\t\t\t\t// new actor on the next read (see the injected proxy's get trap).\n\t\t\t\tboundMethodCache.clear();\n\t\t\t\tview.value = nextActor.currentView.get();\n\t\t\t\tunwatch = watchSignal(nextActor.currentView, (nextView) => {\n\t\t\t\t\tview.value = nextView;\n\t\t\t\t});\n\t\t\t},\n\t\t\t{ flush: \"sync\" },\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\tinternalStore = xstateStoreStateStore({\n\t\t\t\t\t\tatom: createAtom(toAtomState(spec.state)),\n\t\t\t\t\t});\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":";;;;;;;;;AAkEA,IAAM,IAAqB,EAAgB;CAC1C,MAAM;CACN,OAAO;EACN,gBAAgB;GACf,MAAM;GACN,UAAU;EACX;EACA,MAAM;GACL,MAAM;GACN,SAAS;EACV;EACA,OAAO;GACN,MAAM;GACN,UAAU;EACX;CACD;CACA,MAAM,GAAO,EAAE,YAAS;EAGvB,IAAM,IAAU,EAAoC,IAAI;EAKxD,EACC,GACA,IAAI,MAAM,CAAC,GAAuB,EACjC,IAAI,GAAS,GAAc;GAC1B,OAAO,EAAQ,QAAQ;EACxB,EACD,CAAC,CACF;EAIA,IAAM,IAAa,EAAc,GAM3B,KAA6B,MAAY;GAC9C,IAAM,IAAO,EAAW,YAAY;GACpC,EAAW,OAAO,EAAQ,CAAI,CAAC;EAChC,GAMM,IAAW,QAChB,EAAM,eAAe,eACd,SACA,EAAW,YAAY,CAC9B,CACD;EAEA,aACM,EAAM,QAKX,EAAQ,QAAQ;GACf,MAAM,EAAM;GACZ,UAAU,EAAS;GACnB,UAAU,EAAM,eAAe;GAC/B,OAAO,EAAM;EACd,GAIO,EAAE,GAAgB,EAAE,UAAU,EAAS,MAAM,SACnD,EAAE,GAAoB,CAAC,SAAS,EAAM,UAAU,KAAK,IAAI,CAC1D,MAfC,EAAQ,QAAQ,MACT,EAAM,UAAU,KAAK;CAgB/B;AACD,CAAC,GAMD,IAAe,EAAgB;CAC9B,MAAM;CACN,OAAO;EACN,OAAO;GACN,MAAM;GACN,UAAU;EACX;EACA,gBAAgB;GACf,MAAM;GACN,UAAU;EACX;EACA,OAAO;GACN,MAAM;GACN,SAAS,KAAA;EACV;EACA,eAAe;GACd,MAAM;GACN,SAAS,KAAA;EACV;CACD;CACA,MAAM,GAAO,EAAE,YAAS;EAIvB,IAAM,IAAW,EAAW,EAAM,EAAM,KAAgD,CAAC,GAGnF,IAAc,OAAO,YAC1B,OAAO,QAAQ,EAAM,EAAM,cAAc,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,OAAO,CACpE,GACA,EAAQ,CAAW,CACpB,CAAC,CACF,GAKM,IAA0C;GAC/C,GAAG,EAAM,EAAM,cAAc;GAC7B,UAAU,EACT,EAAM,gBACH,EAAyB,GAAa,EAAM,aAAa,IACzD,CACJ;EACD,GAyBM,oBAAmB,IAAI,IAAsD;EACnF,EACC,IAAI,MAAM,CAAC,GAAmB;GAC7B,IAAI,GAAS,GAAM;IAClB,IAAM,IAAU,EAAS,OACnB,IAAQ,QAAQ,IAAI,GAAS,GAAM,CAAO;IAChD,IAAI,OAAO,KAAU,YAAY,OAAO;IACxC,IAAM,IAAS,EAAiB,IAAI,CAAI;IACxC,IAAI,KAAU,EAAO,WAAW,GAAO,OAAO,EAAO;IACrD,IAAM,IAAS,EAA0C,KAAK,CAAO;IAErE,OADA,EAAiB,IAAI,GAAM;KAAE,QAAQ;KAAO;IAAM,CAAC,GAC5C;GACR;GACA,IAAI,GAAS,GAAM;IAClB,OAAO,KAAQ,EAAS;GACzB;GACA,IAAI,GAAS,GAAM,GAAO;IACzB,OAAO,QAAQ,IAAI,EAAS,OAAO,GAAM,GAAO,EAAS,KAAK;GAC/D;GACA,eAAe,GAAS,GAAM;IAC7B,OAAO,QAAQ,eAAe,EAAS,OAAO,CAAI;GACnD;GACA,UAAU;IACT,OAAO,QAAQ,QAAQ,EAAS,KAAK;GACtC;GACA,yBAAyB,GAAS,GAAM;IACvC,IAAM,IAAO,QAAQ,yBAAyB,EAAS,OAAO,CAAI;IAC7D,OAQL,OADA,EAAK,eAAe,IACb;GACR;GACA,iBAAiB;IAChB,OAAO,QAAQ,eAAe,EAAS,KAAK;GAC7C;EACD,CAAC,CACF;EAKA,IAAM,IAAO,EAAqB,EAAS,MAAM,YAAY,IAAI,CAAC,GAG9D,IAAmC,MACnC,IAA4B,MAE5B,IAAW,GAIX,IAAU,EAAY,EAAS,MAAM,cAAc,MAAa;GACnE,EAAK,QAAQ;EACd,CAAC;EA6BD,OArBA,QACO,EAAM,EAAM,KAAgD,IACjE,MAAc;GACV,MAAc,EAAS,UAC3B,EAAQ,GACR,EAAS,QAAQ,GAGjB,EAAiB,MAAM,GACvB,EAAK,QAAQ,EAAU,YAAY,IAAI,GACvC,IAAU,EAAY,EAAU,cAAc,MAAa;IAC1D,EAAK,QAAQ;GACd,CAAC;EACF,GACA,EAAE,OAAO,OAAO,CACjB,GAEA,QAAkB;GACjB,EAAQ;EACT,CAAC,SAEY;GAEZ,IAAI,CAAC,EAAK,OACT,OAAO,EAAM,WAAW,EAAM,SAAS,IAAI;GAG5C,IAAM,IAAO,EAAK,OAGd;GAgBJ,OAfI,EAAM,QACT,IAAQ,EAAM,UAEV,MAAkB,QAAQ,MAAa,EAAK,WAE/C,IAAgB,EAAsB,EACrC,MAAM,EAAW,EAAY,EAAK,KAAK,CAAC,EACzC,CAAC,GACD,IAAW,EAAK,OAChB,MAED,IAAQ,IAIF,EAAE,GAAe;IAAE;IAAO,KAAK;GAAS,SAC9C,EAAE,GAAoB;IAAE,gBAAgB;IAAmB;IAAM;GAAM,GAAG,CAAK,CAChF;EACD;CACD;AACD,CAAC"}
@@ -1,7 +0,0 @@
1
- import e from "./PlayRenderer.vue_vue_type_script_lang.js";
2
- //#region src/PlayRenderer.vue
3
- var t = e;
4
- //#endregion
5
- export { t as default };
6
-
7
- //# sourceMappingURL=PlayRenderer.js.map
@@ -1 +0,0 @@
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 \"@xmachines/json-render-vue\";\nimport { getPlayViewContext } from \"./actor-provider-context.js\";\n\nexport default defineComponent({\n\tname: \"PlayRenderer\",\n\tsetup() {\n\t\t// Call inject at setup() time — valid Vue composition API.\n\t\t// getPlayViewContext() uses inject() which must run synchronously during setup().\n\t\t// The Proxy returned by ActorProviderInner ensures view.spec and view.registry\n\t\t// always reflect the latest values when accessed during the render function.\n\t\tconst view = getPlayViewContext();\n\t\treturn () => {\n\t\t\treturn h(Renderer, { spec: view.spec, registry: view.registry });\n\t\t};\n\t},\n});\n</script>\n"],"mappings":""}
@@ -1,5 +0,0 @@
1
- declare const _default: import('@vue/runtime-core').DefineComponent<{}, () => import('@vue/runtime-core').VNode<import('@vue/runtime-core').RendererNode, import('@vue/runtime-core').RendererElement, {
2
- [key: string]: any;
3
- }>, {}, {}, {}, import('@vue/runtime-core').ComponentOptionsMixin, import('@vue/runtime-core').ComponentOptionsMixin, {}, string, import('@vue/runtime-core').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('@vue/runtime-core').ComponentProvideOptions, true, {}, any>;
4
- export default _default;
5
- //# sourceMappingURL=PlayRenderer.vue.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PlayRenderer.vue.d.ts","sourceRoot":"","sources":["../src/PlayRenderer.vue"],"names":[],"mappings":";;;AA6DA,wBAYG"}
@@ -1,18 +0,0 @@
1
- import { getPlayViewContext as e } from "./actor-provider-context.js";
2
- import { defineComponent as t, h as n } from "vue";
3
- import { Renderer as r } from "@xmachines/json-render-vue";
4
- //#region src/PlayRenderer.vue?vue&type=script&lang.ts
5
- var i = t({
6
- name: "PlayRenderer",
7
- setup() {
8
- let t = e();
9
- return () => n(r, {
10
- spec: t.spec,
11
- registry: t.registry
12
- });
13
- }
14
- });
15
- //#endregion
16
- export { i as default };
17
-
18
- //# sourceMappingURL=PlayRenderer.vue_vue_type_script_lang.js.map
@@ -1 +0,0 @@
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 \"@xmachines/json-render-vue\";\nimport { getPlayViewContext } from \"./actor-provider-context.js\";\n\nexport default defineComponent({\n\tname: \"PlayRenderer\",\n\tsetup() {\n\t\t// Call inject at setup() time — valid Vue composition API.\n\t\t// getPlayViewContext() uses inject() which must run synchronously during setup().\n\t\t// The Proxy returned by ActorProviderInner ensures view.spec and view.registry\n\t\t// always reflect the latest values when accessed during the render function.\n\t\tconst view = getPlayViewContext();\n\t\treturn () => {\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;EAKP,IAAM,IAAO,EAAmB;EAChC,aACQ,EAAE,GAAU;GAAE,MAAM,EAAK;GAAM,UAAU,EAAK;EAAS,CAAC;CAEjE;AACD,CAAC"}
@@ -1,7 +0,0 @@
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
@@ -1 +0,0 @@
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 @xmachines/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 \"@xmachines/json-render-vue\";\nimport type { DefineRegistryResult, RenderErrorHandler } from \"@xmachines/json-render-vue\";\n\nimport type { StateStore } from \"@xmachines/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<\n\t\t\t\t\tstring,\n\t\t\t\t\t(args?: Record<string, unknown>, state?: Record<string, unknown>) => unknown\n\t\t\t\t>\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\n\t\t\t\t\t\t? { validationFunctions: props.validationFunctions }\n\t\t\t\t\t\t: {}),\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":""}
@@ -1,76 +0,0 @@
1
- import { PropType } from 'vue';
2
- import { DefineRegistryResult, RenderErrorHandler } from '@xmachines/json-render-vue';
3
- import { StateStore } from '@xmachines/json-render-core';
4
- import { AbstractActor, Viewable } from '@xmachines/play-actor';
5
- import { AnyActorLogic } from 'xstate';
6
- import { PlayUIProviderProps } from './types.js';
7
- export type { PlayUIProviderProps } from './types.js';
8
- declare const _default: import('@vue/runtime-core').DefineComponent<import('@vue/runtime-core').ExtractPropTypes<{
9
- actor: {
10
- type: PropType<AbstractActor<AnyActorLogic> & Viewable>;
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
- navigate: {
26
- type: PropType<PlayUIProviderProps["navigate"]>;
27
- default: undefined;
28
- };
29
- validationFunctions: {
30
- type: PropType<PlayUIProviderProps["validationFunctions"]>;
31
- default: undefined;
32
- };
33
- functions: {
34
- type: PropType<PlayUIProviderProps["functions"]>;
35
- default: undefined;
36
- };
37
- }>, () => import('@vue/runtime-core').VNode<import('@vue/runtime-core').RendererNode, import('@vue/runtime-core').RendererElement, {
38
- [key: string]: any;
39
- }>, {}, {}, {}, import('@vue/runtime-core').ComponentOptionsMixin, import('@vue/runtime-core').ComponentOptionsMixin, {}, string, import('@vue/runtime-core').PublicProps, Readonly<import('@vue/runtime-core').ExtractPropTypes<{
40
- actor: {
41
- type: PropType<AbstractActor<AnyActorLogic> & Viewable>;
42
- required: true;
43
- };
44
- registryResult: {
45
- type: PropType<DefineRegistryResult>;
46
- required: true;
47
- };
48
- store: {
49
- type: PropType<StateStore>;
50
- default: undefined;
51
- };
52
- onRenderError: {
53
- type: PropType<RenderErrorHandler>;
54
- default: undefined;
55
- };
56
- navigate: {
57
- type: PropType<PlayUIProviderProps["navigate"]>;
58
- default: undefined;
59
- };
60
- validationFunctions: {
61
- type: PropType<PlayUIProviderProps["validationFunctions"]>;
62
- default: undefined;
63
- };
64
- functions: {
65
- type: PropType<PlayUIProviderProps["functions"]>;
66
- default: undefined;
67
- };
68
- }>> & Readonly<{}>, {
69
- onRenderError: RenderErrorHandler;
70
- store: StateStore;
71
- navigate: ((path: string) => void) | undefined;
72
- validationFunctions: Record<string, (value: unknown, args?: Record<string, unknown>) => boolean> | undefined;
73
- functions: Record<string, (args?: Record<string, unknown>, state?: Record<string, unknown>) => unknown> | undefined;
74
- }, {}, {}, {}, string, import('@vue/runtime-core').ComponentProvideOptions, true, {}, any>;
75
- export default _default;
76
- //# sourceMappingURL=PlayUIProvider.vue.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PlayUIProvider.vue.d.ts","sourceRoot":"","sources":["../src/PlayUIProvider.vue"],"names":[],"mappings":"AA0KA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAEpC,OAAO,KAAK,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAE3F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAG5C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAGtD,YAAY,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;;;cA4DnC,QAAQ,CAAC,aAAa,CAAC,aAAa,CAAC,GAAG,QAAQ,CAAC;;;;cAIjD,QAAQ,CAAC,oBAAoB,CAAC;;;;cAI9B,QAAQ,CAAC,UAAU,CAAC;;;;cAIlB,QAAQ,CAAC,kBAAkB,CAAC;;;;cAI5B,QAAQ,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;;;;cAI3C,QAAQ,CAAC,mBAAmB,CAAC,qBAAqB,CAAC,CAAC;;;;cAIpD,QAAQ,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;;;;;;;cAxB1C,QAAQ,CAAC,aAAa,CAAC,aAAa,CAAC,GAAG,QAAQ,CAAC;;;;cAIjD,QAAQ,CAAC,oBAAoB,CAAC;;;;cAI9B,QAAQ,CAAC,UAAU,CAAC;;;;cAIlB,QAAQ,CAAC,kBAAkB,CAAC;;;;cAI5B,QAAQ,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;;;;cAI3C,QAAQ,CAAC,mBAAmB,CAAC,qBAAqB,CAAC,CAAC;;;;cAIpD,QAAQ,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;;;;;;;;;;AA5B7D,wBA2DG"}
@@ -1,86 +0,0 @@
1
- import { getPlayViewContext as e } from "./actor-provider-context.js";
2
- import t from "./ActorProvider.js";
3
- import { defineComponent as n, h as r } from "vue";
4
- import { JSONUIProvider as i } from "@xmachines/json-render-vue";
5
- //#region src/PlayUIProvider.vue?vue&type=script&lang.ts
6
- var a = n({
7
- name: "JSONUIBridge",
8
- props: {
9
- navigate: {
10
- type: Function,
11
- default: void 0
12
- },
13
- validationFunctions: {
14
- type: Object,
15
- default: void 0
16
- },
17
- functions: {
18
- type: Object,
19
- default: void 0
20
- }
21
- },
22
- setup(t, { slots: n }) {
23
- return () => {
24
- let a = e();
25
- return r(i, {
26
- registry: a.registry,
27
- handlers: a.handlers,
28
- store: a.store,
29
- ...t.navigate ? { navigate: t.navigate } : {},
30
- ...t.validationFunctions ? { validationFunctions: t.validationFunctions } : {},
31
- ...t.functions ? { functions: t.functions } : {}
32
- }, n);
33
- };
34
- }
35
- }), o = n({
36
- name: "PlayUIProvider",
37
- props: {
38
- actor: {
39
- type: Object,
40
- required: !0
41
- },
42
- registryResult: {
43
- type: Object,
44
- required: !0
45
- },
46
- store: {
47
- type: Object,
48
- default: void 0
49
- },
50
- onRenderError: {
51
- type: Function,
52
- default: void 0
53
- },
54
- navigate: {
55
- type: Function,
56
- default: void 0
57
- },
58
- validationFunctions: {
59
- type: Object,
60
- default: void 0
61
- },
62
- functions: {
63
- type: Object,
64
- default: void 0
65
- }
66
- },
67
- setup(e, { slots: n }) {
68
- return () => r(t, {
69
- actor: e.actor,
70
- registryResult: e.registryResult,
71
- ...e.store ? { store: e.store } : {},
72
- ...e.onRenderError ? { onRenderError: e.onRenderError } : {}
73
- }, {
74
- default: () => r(a, {
75
- ...e.navigate ? { navigate: e.navigate } : {},
76
- ...e.validationFunctions ? { validationFunctions: e.validationFunctions } : {},
77
- ...e.functions ? { functions: e.functions } : {}
78
- }, n),
79
- fallback: n.fallback
80
- });
81
- }
82
- });
83
- //#endregion
84
- export { o as default };
85
-
86
- //# sourceMappingURL=PlayUIProvider.vue_vue_type_script_lang.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PlayUIProvider.vue_vue_type_script_lang.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 @xmachines/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 \"@xmachines/json-render-vue\";\nimport type { DefineRegistryResult, RenderErrorHandler } from \"@xmachines/json-render-vue\";\n\nimport type { StateStore } from \"@xmachines/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<\n\t\t\t\t\tstring,\n\t\t\t\t\t(args?: Record<string, unknown>, state?: Record<string, unknown>) => unknown\n\t\t\t\t>\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\n\t\t\t\t\t\t? { validationFunctions: props.validationFunctions }\n\t\t\t\t\t\t: {}),\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":";;;;;AAwCA,IAAM,IAAe,EAAgB;CACpC,MAAM;CACN,OAAO;EACN,UAAU;GACT,MAAM;GACN,SAAS,KAAA;EACV;EACA,qBAAqB;GACpB,MAAM;GAGN,SAAS,KAAA;EACV;EACA,WAAW;GACV,MAAM;GAMN,SAAS,KAAA;EACV;CACD;CACA,MAAM,GAAO,EAAE,YAAS;EACvB,aAAa;GACZ,IAAM,IAAO,EAAmB;GAChC,OAAO,EACN,GACA;IACC,UAAU,EAAK;IACf,UAAU,EAAK;IACf,OAAO,EAAK;IACZ,GAAI,EAAM,WAAW,EAAE,UAAU,EAAM,SAAS,IAAI,CAAC;IACrD,GAAI,EAAM,sBACP,EAAE,qBAAqB,EAAM,oBAAoB,IACjD,CAAC;IACJ,GAAI,EAAM,YAAY,EAAE,WAAW,EAAM,UAAU,IAAI,CAAC;GACzD,GACA,CACD;EACD;CACD;AACD,CAAC,GAMD,IAAe,EAAgB;CAC9B,MAAM;CACN,OAAO;EACN,OAAO;GACN,MAAM;GACN,UAAU;EACX;EACA,gBAAgB;GACf,MAAM;GACN,UAAU;EACX;EACA,OAAO;GACN,MAAM;GACN,SAAS,KAAA;EACV;EACA,eAAe;GACd,MAAM;GACN,SAAS,KAAA;EACV;EACA,UAAU;GACT,MAAM;GACN,SAAS,KAAA;EACV;EACA,qBAAqB;GACpB,MAAM;GACN,SAAS,KAAA;EACV;EACA,WAAW;GACV,MAAM;GACN,SAAS,KAAA;EACV;CACD;CACA,MAAM,GAAO,EAAE,YAAS;EACvB,aACC,EACC,GACA;GACC,OAAO,EAAM;GACb,gBAAgB,EAAM;GACtB,GAAI,EAAM,QAAQ,EAAE,OAAO,EAAM,MAAM,IAAI,CAAC;GAC5C,GAAI,EAAM,gBAAgB,EAAE,eAAe,EAAM,cAAc,IAAI,CAAC;EACrE,GACA;GACC,eACC,EACC,GACA;IACC,GAAI,EAAM,WAAW,EAAE,UAAU,EAAM,SAAS,IAAI,CAAC;IACrD,GAAI,EAAM,sBACP,EAAE,qBAAqB,EAAM,oBAAoB,IACjD,CAAC;IACJ,GAAI,EAAM,YAAY,EAAE,WAAW,EAAM,UAAU,IAAI,CAAC;GACzD,GACA,CACD;GACD,UAAU,EAAM;EACjB,CACD;CACF;AACD,CAAC"}
@@ -1,11 +0,0 @@
1
- import { inject as e } from "vue";
2
- import { assertNonNullable as t } from "@xmachines/play";
3
- //#region src/actor-provider-context.ts
4
- var n = Symbol("xmachines.view");
5
- function r() {
6
- return t(e(n), "ViewKey");
7
- }
8
- //#endregion
9
- export { n as ViewKey, r as getPlayViewContext };
10
-
11
- //# sourceMappingURL=actor-provider-context.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"actor-provider-context.js","names":[],"sources":["../src/actor-provider-context.ts"],"sourcesContent":["/**\n * ViewContextValue and getPlayViewContext — shared context types for Vue provider architecture.\n *\n * Extracted from ActorProvider.vue so TypeScript can re-export these types from index.ts.\n * (The vue-shim.d.ts only declares a default export from *.vue files, so named exports\n * from .vue SFCs are not visible to TypeScript's re-export resolution.)\n *\n * @packageDocumentation\n */\n\nimport { inject } from \"vue\";\nimport type { InjectionKey } from \"vue\";\nimport { assertNonNullable } from \"@xmachines/play\";\nimport type { ComponentRegistry } from \"@xmachines/json-render-vue\";\nimport type { BaseViewContextValue } from \"@xmachines/play-actor\";\n\n/**\n * Context value provided by ActorProvider and consumed by PlayRenderer (zero-prop leaf).\n * Accessible via getPlayViewContext() inside any ActorProvider/PlayUIProvider tree.\n */\nexport interface ViewContextValue extends BaseViewContextValue<ComponentRegistry> {}\n\n/**\n * Injection key for the ViewContextValue. Exported so ActorProvider.vue can use it\n * as the canonical key without re-declaring.\n *\n * @internal Use getPlayViewContext() as the public API; do not inject ViewKey directly.\n */\nexport const ViewKey: InjectionKey<ViewContextValue> = Symbol(\"xmachines.view\");\n\n/**\n * Access the current ViewContextValue from inside an ActorProvider tree.\n *\n * @throws {Error} If called outside an <ActorProvider> (or <PlayUIProvider>) tree\n *\n * @example\n * ```typescript\n * import { getPlayViewContext } from \"@xmachines/play-vue\";\n *\n * const view = getPlayViewContext();\n * // view.spec, view.handlers, view.registry\n * ```\n */\nexport function getPlayViewContext(): ViewContextValue {\n\treturn assertNonNullable(inject(ViewKey), \"ViewKey\");\n}\n"],"mappings":";;;AA4BA,IAAa,IAA0C,OAAO,gBAAgB;AAe9E,SAAgB,IAAuC;CACtD,OAAO,EAAkB,EAAO,CAAO,GAAG,SAAS;AACpD"}
@@ -1,27 +0,0 @@
1
- import { h as e } from "vue";
2
- import { defineRegistry as t } from "@xmachines/json-render-vue";
3
- //#region src/define-registry.ts
4
- function n(e) {
5
- if (typeof e != "object" || !e) return !1;
6
- let t = e;
7
- return "__vccOpts" in t || "__name" in t ? !0 : typeof t.setup == "function" || typeof t.render == "function";
8
- }
9
- function r(t) {
10
- return (n) => e(t, n);
11
- }
12
- function i(e, i) {
13
- let a = {};
14
- for (let [e, t] of Object.entries(i.components ?? {})) {
15
- if (t === void 0) continue;
16
- let i = e;
17
- a[i] = n(t) ? r(t) : t;
18
- }
19
- return t(e, {
20
- ...i,
21
- components: a
22
- });
23
- }
24
- //#endregion
25
- export { i as defineRegistry };
26
-
27
- //# sourceMappingURL=define-registry.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"define-registry.js","names":[],"sources":["../src/define-registry.ts"],"sourcesContent":["/**\n * `defineRegistry` wrapper for @xmachines/play-vue.\n *\n * Wraps `defineRegistry` from `@xmachines/json-render-vue` with automatic SFC support.\n *\n * ## Vue-specific — React and Solid do not need this\n *\n * In React, `useContext()` works anywhere inside the component call tree.\n * In Solid, `useContext()` works inside reactive computations and component renders.\n * Neither has the strict \"synchronous setup() only\" constraint that Vue's `inject()`\n * imposes — so their `defineRegistry` implementations call `componentFn(ctx)` directly\n * with no wrapping needed.\n *\n * For the DOM renderer, there is no component system at all — just render functions\n * returning `HTMLElement` — so injection context is not applicable.\n *\n * Only Vue requires this adapter.\n *\n * ## Why this wrapper exists\n *\n * `@xmachines/json-render-vue`'s `defineRegistry` calls each registered component as a plain\n * function: `componentFn(ctx)`. A `.vue` SFC (output of `defineComponent` or\n * `<script setup>`) is an **object**, not a function — calling it throws.\n *\n * More fundamentally, `defineRegistry` calls components inside its own render\n * function (the return value of `setup()`). Vue's `inject()` — and composables built\n * on it: `useStateBinding`, `useStateStore` — only work during synchronous `setup()`\n * execution, not inside render functions. Plain `.ts` `ComponentFn` files cannot\n * call any Vue composable for this reason.\n *\n * This wrapper auto-detects Vue SFCs in the `components` map and wraps them via\n * `h(SFC, ctx)`. The SFC renders as a child component with its own `setup()`,\n * giving full access to composables inside `<script setup>`.\n *\n * ## Usage\n *\n * Import `defineRegistry` from `@xmachines/play-vue` instead of `@xmachines/json-render-vue`:\n *\n * ```ts\n * import { defineRegistry } from \"@xmachines/play-vue\";\n * // not: import { defineRegistry } from \"@xmachines/json-render-vue\";\n *\n * import LoginSFC from \"./views/Login.vue\";\n * import DashboardSFC from \"./views/Dashboard.vue\";\n *\n * const { registry } = defineRegistry(catalog, {\n * components: {\n * Login: LoginSFC, // .vue SFC — auto-wrapped\n * Dashboard: DashboardSFC, // .vue SFC — auto-wrapped\n * },\n * });\n * ```\n *\n * Plain `ComponentFn` functions still work and are passed through unchanged.\n * Mixing SFCs and plain functions in the same registry is supported.\n */\n\nimport { h, type Component } from \"vue\";\nimport {\n\tdefineRegistry as defineRegistryBase,\n\ttype ComponentContext,\n\ttype ComponentFn,\n\ttype Components,\n} from \"@xmachines/json-render-vue\";\nimport type { Catalog, InferCatalogComponents } from \"@xmachines/json-render-core\";\n\n/**\n * Detect whether a value is a Vue component object (SFC) rather than a plain\n * `ComponentFn` function.\n *\n * Vue SFCs produced by `defineComponent` or `<script setup>` compilation are\n * plain objects (not callable). A `ComponentFn` is always a plain function.\n *\n * Detection strategy (checked in order):\n * 1. `__vccOpts` — set by vite-plugin-vue / vue-loader on every `<script setup>` SFC.\n * 2. `__name` — set by Vite on named SFCs (present alongside `__vccOpts` but also\n * on `defineComponent({ name: \"...\" })` output without `<script setup>`).\n * 3. `setup` is a function — the `defineComponent({ setup() {} })` signature.\n * 4. `render` is a function — the `defineComponent({ render() {} })` signature.\n *\n * Requiring `setup` / `render` to be **functions** prevents plain POJOs that\n * happen to have a `setup` or `render` key from being misidentified as components.\n */\nfunction isVueSFC(value: unknown): value is Component {\n\tif (typeof value !== \"object\" || value === null) return false;\n\tconst v = value as Record<string, unknown>;\n\t// Compiler-injected markers — unambiguous Vue component identifiers.\n\tif (\"__vccOpts\" in v || \"__name\" in v) return true;\n\t// defineComponent() output: setup or render must be callable, not just present.\n\treturn typeof v[\"setup\"] === \"function\" || typeof v[\"render\"] === \"function\";\n}\n\n/**\n * Wrap a Vue SFC as a `ComponentFn` by rendering it via `h()`.\n *\n * The SFC receives the full `ComponentContext` as its props and renders in its\n * own child component `setup()`, where Vue composables work correctly.\n */\nfunction wrapSFC<C extends Catalog, K extends keyof InferCatalogComponents<C>>(\n\tcomponent: Component,\n): ComponentFn<C, K> {\n\treturn (ctx: ComponentContext<C, K>) => h(component, ctx);\n}\n\nexport type ComponentEntry<C extends Catalog, K extends keyof InferCatalogComponents<C>> =\n\t| ComponentFn<C, K>\n\t| Component;\n\nexport type ComponentsMap<C extends Catalog> = {\n\t[K in keyof InferCatalogComponents<C>]?: ComponentEntry<C, K>;\n};\n\nexport type DefineRegistryOptions<C extends Catalog> = Omit<\n\tParameters<typeof defineRegistryBase<C>>[1],\n\t\"components\"\n> & {\n\tcomponents?: ComponentsMap<C>;\n};\n\n/**\n * Create a component registry, automatically wrapping `.vue` SFCs so they work\n * correctly with `@xmachines/json-render-vue`'s rendering pipeline.\n *\n * Drop-in replacement for `defineRegistry` from `@xmachines/json-render-vue`. Import from\n * `@xmachines/play-vue` to get SFC support for free.\n *\n * @param catalog - The json-render catalog defining component prop shapes.\n * @param options - Registry options. `components` entries may be `.vue` SFCs\n * (objects) or plain `ComponentFn` functions — both are handled automatically.\n */\nexport function defineRegistry<C extends Catalog>(\n\tcatalog: C,\n\toptions: DefineRegistryOptions<C>,\n): ReturnType<typeof defineRegistryBase<C>> {\n\tconst wrappedComponents = {} as Components<C>;\n\n\tfor (const [key, component] of Object.entries(options.components ?? {})) {\n\t\tif (component === undefined) continue;\n\t\tconst k = key as keyof InferCatalogComponents<C>;\n\t\twrappedComponents[k] = isVueSFC(component)\n\t\t\t? wrapSFC(component as Component)\n\t\t\t: (component as ComponentFn<C, typeof k>);\n\t}\n\n\tconst baseOptions = options as Parameters<typeof defineRegistryBase<C>>[1];\n\treturn defineRegistryBase(catalog, { ...baseOptions, components: wrappedComponents });\n}\n"],"mappings":";;;AAmFA,SAAS,EAAS,GAAoC;CACrD,IAAI,OAAO,KAAU,aAAY,GAAgB,OAAO;CACxD,IAAM,IAAI;CAIV,OAFI,eAAe,KAAK,YAAY,IAAU,KAEvC,OAAO,EAAE,SAAa,cAAc,OAAO,EAAE,UAAc;AACnE;AAQA,SAAS,EACR,GACoB;CACpB,QAAQ,MAAgC,EAAE,GAAW,CAAG;AACzD;AA4BA,SAAgB,EACf,GACA,GAC2C;CAC3C,IAAM,IAAoB,CAAC;CAE3B,KAAK,IAAM,CAAC,GAAK,MAAc,OAAO,QAAQ,EAAQ,cAAc,CAAC,CAAC,GAAG;EACxE,IAAI,MAAc,KAAA,GAAW;EAC7B,IAAM,IAAI;EACV,EAAkB,KAAK,EAAS,CAAS,IACtC,EAAQ,CAAsB,IAC7B;CACL;CAGA,OAAO,EAAmB,GAAS;EAAE,GAAG;EAAa,YAAY;CAAkB,CAAC;AACrF"}
package/dist/index.js DELETED
@@ -1,8 +0,0 @@
1
- import { getPlayViewContext as e } from "./actor-provider-context.js";
2
- import t from "./PlayRenderer.js";
3
- import { useActor as n } from "./useActor.js";
4
- import r from "./ActorProvider.js";
5
- import i from "./PlayUIProvider.js";
6
- import { defineRegistry as a } from "./define-registry.js";
7
- import { ActionProvider as o, JSONUIProvider as s, Renderer as c, StateProvider as l, ValidationProvider as u, VisibilityProvider as d, useBoundProp as f } from "@xmachines/json-render-vue";
8
- export { o as ActionProvider, r as ActorProvider, s as JSONUIProvider, t as PlayRenderer, i as PlayUIProvider, c as Renderer, l as StateProvider, u as ValidationProvider, d as VisibilityProvider, a as defineRegistry, e as getPlayViewContext, n as useActor, f as useBoundProp };
package/dist/useActor.js DELETED
@@ -1,14 +0,0 @@
1
- import { inject as e, provide as t } from "vue";
2
- import { assertNonNullable as n } from "@xmachines/play";
3
- //#region src/useActor.ts
4
- var r = Symbol("xmachines.actor");
5
- function i(e) {
6
- t(r, e);
7
- }
8
- function a() {
9
- return n(e(r), "ActorKey");
10
- }
11
- //#endregion
12
- export { r as ActorKey, i as provideActor, a as useActor };
13
-
14
- //# sourceMappingURL=useActor.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useActor.js","names":[],"sources":["../src/useActor.ts"],"sourcesContent":["/**\n * useActor — Vue composable for accessing the provided actor inside a PlayRenderer tree.\n *\n * Components rendered inside PlayRenderer can call useActor() to reach the actor\n * instance without prop drilling.\n *\n * What is returned is a **swap-following proxy**, not the raw actor object:\n * - It is a stable reference for the lifetime of the injection, yet forwards every\n * operation (property reads/writes, `in`, `Object.keys` / spread, `instanceof`)\n * to whichever actor is CURRENTLY provided — so it transparently follows a\n * `props.actor` swap on `<ActorProvider>` without consumers re-injecting.\n * - Method identity is stable per underlying method: `actor.send === actor.send`\n * across repeated reads (allocation-free), and rebinds only when the underlying\n * method changes or the actor is swapped.\n * - It is NOT `===` the `actor` prop passed to `<ActorProvider>` (it is a distinct\n * Proxy object). Any consumer keyed on actor identity — most notably a router\n * bridge extending `RouterBridgeBase`, whose one-bridge-per-actor guard keys a\n * WeakMap on the actor instance — must be given the actor prop itself, not the\n * value returned by `useActor()`.\n *\n * @throws {Error} If called outside a PlayRenderer tree\n *\n * @example\n * ```typescript\n * import { useActor } from \"@xmachines/play-vue\";\n *\n * const actor = useActor();\n * actor.send({ type: \"SUBMIT\" });\n * ```\n *\n * @packageDocumentation\n */\n\nimport { inject, provide } from \"vue\";\nimport type { InjectionKey } from \"vue\";\nimport { assertNonNullable } from \"@xmachines/play\";\nimport type { AbstractActor } from \"@xmachines/play-actor\";\nimport type { AnyActorLogic } from \"xstate\";\n\n/** Bare actor type accepted by Vue context providers. For the full routing + view shape, use `PlayActor` from `@xmachines/play-router`. */\nexport type AnyPlayActor = AbstractActor<AnyActorLogic>;\n\nexport const ActorKey: InjectionKey<AnyPlayActor> = Symbol(\"xmachines.actor\");\n\n/**\n * Provide the actor to all descendant components via Vue's inject/provide mechanism.\n *\n * Called inside `PlayRenderer.vue`'s `setup()` to make the actor available to any\n * child component that calls `useActor()`. Not typically needed outside framework\n * internals unless building a custom renderer wrapper.\n *\n * @param actor - The actor instance to inject into the component tree.\n */\nexport function provideActor(actor: AnyPlayActor): void {\n\tprovide(ActorKey, actor);\n}\n\nexport function useActor(): AnyPlayActor {\n\treturn assertNonNullable(inject(ActorKey), \"ActorKey\");\n}\n"],"mappings":";;;AA0CA,IAAa,IAAuC,OAAO,iBAAiB;AAW5E,SAAgB,EAAa,GAA2B;CACvD,EAAQ,GAAU,CAAK;AACxB;AAEA,SAAgB,IAAyB;CACxC,OAAO,EAAkB,EAAO,CAAQ,GAAG,UAAU;AACtD"}