@xmachines/play-vue 2.0.0 → 2.1.1
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 +26 -25
- package/dist/ActorProvider.js.map +1 -1
- package/dist/ActorProvider.vue_vue_type_script_lang.js +13 -13
- package/dist/ActorProvider.vue_vue_type_script_lang.js.map +1 -1
- package/dist/PlayRenderer.js.map +1 -1
- package/dist/PlayRenderer.vue_vue_type_script_lang.js +7 -7
- package/dist/PlayRenderer.vue_vue_type_script_lang.js.map +1 -1
- package/dist/PlayUIProvider.js.map +1 -1
- package/dist/PlayUIProvider.vue_vue_type_script_lang.js +8 -7
- package/dist/PlayUIProvider.vue_vue_type_script_lang.js.map +1 -1
- package/dist/actor-provider-context.d.ts +22 -14
- package/dist/actor-provider-context.d.ts.map +1 -1
- package/dist/actor-provider-context.js +20 -13
- package/dist/actor-provider-context.js.map +1 -1
- package/dist/define-registry.d.ts +41 -36
- package/dist/define-registry.d.ts.map +1 -1
- package/dist/define-registry.js +57 -50
- package/dist/define-registry.js.map +1 -1
- package/dist/index.d.ts +9 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/types.d.ts +11 -7
- package/dist/types.d.ts.map +1 -1
- package/dist/useActor.d.ts +31 -25
- package/dist/useActor.d.ts.map +1 -1
- package/dist/useActor.js +28 -24
- package/dist/useActor.js.map +1 -1
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -1,22 +1,20 @@
|
|
|
1
1
|
# `@xmachines/play-vue`
|
|
2
2
|
|
|
3
|
-
> Vue 3 renderer for the XMachines Play Architecture
|
|
3
|
+
> Vue 3 renderer for the XMachines Play Architecture. It observes the actor signals and renders the UI through `@xmachines/json-render-vue`.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
[](https://opensource.org/licenses/MIT) [](https://www.npmjs.com/package/@xmachines/play-vue)
|
|
5
|
+
[](https://opensource.org/licenses/MIT) [](https://www.npmjs.com/package/@xmachines/play-vue)
|
|
8
6
|
|
|
9
7
|
---
|
|
10
8
|
|
|
11
9
|
## Overview
|
|
12
10
|
|
|
13
|
-
`@xmachines/play-vue` is the Vue 3 rendering layer
|
|
11
|
+
`@xmachines/play-vue` is the Vue 3 rendering layer of XMachines Play. It connects the TC39 Signals (the actor state) to the Vue reactivity, and it renders the components through `@xmachines/json-render-vue`.
|
|
14
12
|
|
|
15
|
-
**
|
|
13
|
+
**The architecture invariants that this package keeps:**
|
|
16
14
|
|
|
17
|
-
- **Passive Infrastructure** —
|
|
18
|
-
- **Signal-Only Reactivity** — TC39 Signals are the source of truth
|
|
19
|
-
- **Actor Authority** —
|
|
15
|
+
- **Passive Infrastructure** — the components observe the actor signals. They never decide a state transition.
|
|
16
|
+
- **Signal-Only Reactivity** — the TC39 Signals are the source of truth. Vue reactivity only triggers the re-render.
|
|
17
|
+
- **Actor Authority** — the actor controls the view selection. The renderer reflects it.
|
|
20
18
|
|
|
21
19
|
---
|
|
22
20
|
|
|
@@ -26,7 +24,7 @@ Part of the [XMachines Play monorepo](../../README.md).
|
|
|
26
24
|
pnpm add @xmachines/play-vue
|
|
27
25
|
```
|
|
28
26
|
|
|
29
|
-
**Peer dependencies
|
|
27
|
+
**Peer dependencies.** Install them with the package:
|
|
30
28
|
|
|
31
29
|
```bash
|
|
32
30
|
pnpm add vue@^3.5.0 xstate@^5.31.0 @xstate/store@^3.17.0 @xmachines/json-render-vue@^0.20.0-xm.2 @xmachines/json-render-core@^0.20.0-xm.2 @xmachines/json-render-xstate@^0.20.0-xm.2
|
|
@@ -77,7 +75,7 @@ const registryResult = defineRegistry(myCatalog, {
|
|
|
77
75
|
|
|
78
76
|
#### `<PlayUIProvider>`
|
|
79
77
|
|
|
80
|
-
|
|
78
|
+
The composite provider. It wraps `<ActorProvider>` and `JSONUIProvider` in one component. **Use it in most applications.**
|
|
81
79
|
|
|
82
80
|
| Prop | Type | Required | Description |
|
|
83
81
|
| --------------------- | -------------------------- | -------- | ------------------------------------------- |
|
|
@@ -89,11 +87,11 @@ Batteries-included composite provider. Wraps `<ActorProvider>` and `JSONUIProvid
|
|
|
89
87
|
| `validationFunctions` | `Record<string, Function>` | — | Custom validation functions |
|
|
90
88
|
| `functions` | `Record<string, Function>` | — | Named functions for `$computed` expressions |
|
|
91
89
|
|
|
92
|
-
**Slots:** `default` (rendered content), `fallback` (
|
|
90
|
+
**Slots:** `default` (the rendered content), `fallback` (the content while the actor view is `null`)
|
|
93
91
|
|
|
94
92
|
#### `<PlayRenderer>`
|
|
95
93
|
|
|
96
|
-
|
|
94
|
+
The leaf component without props. It reads the current `spec` and `registry` from the nearest `<ActorProvider>` or `<PlayUIProvider>` context, then renders them with `<Renderer>`. Put it inside one of those providers.
|
|
97
95
|
|
|
98
96
|
```vue
|
|
99
97
|
<PlayUIProvider :actor="actor" :registryResult="registryResult">
|
|
@@ -103,7 +101,7 @@ Zero-prop leaf component. Reads the current `spec` and `registry` from the neare
|
|
|
103
101
|
|
|
104
102
|
#### `<ActorProvider>`
|
|
105
103
|
|
|
106
|
-
|
|
104
|
+
The low-level provider for a custom provider composition. It owns the complete actor lifecycle: the signal subscription, the state store of each view, the handler resolution, and the Vue context. Use `<PlayUIProvider>` when you do not need this control.
|
|
107
105
|
|
|
108
106
|
| Prop | Type | Required | Description |
|
|
109
107
|
| ---------------- | -------------------------- | -------- | ------------------------------- |
|
|
@@ -118,33 +116,34 @@ Low-level escape hatch for custom provider composition. Owns the full actor life
|
|
|
118
116
|
|
|
119
117
|
#### `defineRegistry(catalog, options)`
|
|
120
118
|
|
|
121
|
-
|
|
119
|
+
This function is the drop-in replacement for `defineRegistry` from `@xmachines/json-render-vue`. **Always import it from `@xmachines/play-vue`** when you work with a Vue SFC, not from `@xmachines/json-render-vue`. The wrapper finds each `.vue` SFC in the `components` map, and wraps it with `h()`. A Vue composable, and also a composable that uses `inject`, then works correctly inside `<script setup>`.
|
|
122
120
|
|
|
123
121
|
```typescript
|
|
124
122
|
import { defineRegistry } from "@xmachines/play-vue";
|
|
125
123
|
// NOT: import { defineRegistry } from "@xmachines/json-render-vue"
|
|
126
124
|
|
|
125
|
+
import { myCatalog } from "./catalog.js"; // as in the Quick Start
|
|
127
126
|
import LoginSFC from "./views/Login.vue";
|
|
128
127
|
import DashboardSFC from "./views/Dashboard.vue";
|
|
129
128
|
|
|
130
|
-
const registryResult = defineRegistry(
|
|
129
|
+
const registryResult = defineRegistry(myCatalog, {
|
|
131
130
|
components: {
|
|
132
131
|
Login: LoginSFC, // .vue SFC — auto-wrapped via h()
|
|
133
132
|
Dashboard: DashboardSFC,
|
|
134
133
|
},
|
|
135
134
|
actions: {
|
|
136
|
-
login: async (args, setState,
|
|
135
|
+
login: async (args, setState, state) => {
|
|
137
136
|
/* ... */
|
|
138
137
|
},
|
|
139
138
|
},
|
|
140
139
|
});
|
|
141
140
|
```
|
|
142
141
|
|
|
143
|
-
|
|
142
|
+
A plain `ComponentFn` function also works, and the wrapper passes it through without a change. One registry can hold both SFCs and plain functions.
|
|
144
143
|
|
|
145
144
|
#### `useActor()`
|
|
146
145
|
|
|
147
|
-
Vue composable
|
|
146
|
+
The Vue composable that gives the raw actor inside a `PlayRenderer` tree. A deeply nested component then does not need the actor as a prop.
|
|
148
147
|
|
|
149
148
|
```typescript
|
|
150
149
|
import { useActor } from "@xmachines/play-vue";
|
|
@@ -154,25 +153,27 @@ const actor = useActor();
|
|
|
154
153
|
actor.send({ type: "SUBMIT" });
|
|
155
154
|
```
|
|
156
155
|
|
|
157
|
-
|
|
156
|
+
It throws when the caller is outside an `<ActorProvider>` or a `<PlayUIProvider>` tree.
|
|
158
157
|
|
|
159
|
-
#### `
|
|
158
|
+
#### `usePlayView()`
|
|
160
159
|
|
|
161
160
|
Access the current `ViewContextValue` — `{ spec, handlers, registry, store }` — from inside an `<ActorProvider>` tree.
|
|
162
161
|
|
|
163
162
|
```typescript
|
|
164
|
-
import {
|
|
163
|
+
import { usePlayView } from "@xmachines/play-vue";
|
|
165
164
|
|
|
166
165
|
// Inside setup() of a component within an ActorProvider tree:
|
|
167
|
-
const view =
|
|
166
|
+
const view = usePlayView();
|
|
168
167
|
// view.spec, view.handlers, view.registry, view.store
|
|
169
168
|
```
|
|
170
169
|
|
|
170
|
+
> **Note:** `usePlayView` was previously named `getPlayViewContext`. The old name is still exported as a deprecated alias and will be removed in the next major.
|
|
171
|
+
|
|
171
172
|
---
|
|
172
173
|
|
|
173
174
|
### Re-exported from `@xmachines/json-render-vue`
|
|
174
175
|
|
|
175
|
-
|
|
176
|
+
This package re-exports the following, so that a consumer imports everything from `@xmachines/play-vue`:
|
|
176
177
|
|
|
177
178
|
**Components:** `JSONUIProvider`, `StateProvider`, `ActionProvider`, `VisibilityProvider`, `ValidationProvider`, `Renderer`
|
|
178
179
|
|
|
@@ -197,7 +198,7 @@ pnpm --filter @xmachines/play-vue run test:watch
|
|
|
197
198
|
pnpm exec vitest run --coverage --config packages/play-vue/vitest.config.ts
|
|
198
199
|
```
|
|
199
200
|
|
|
200
|
-
|
|
201
|
+
The tests use [Vitest](https://vitest.dev/) in a `jsdom` environment. They mount the components with `@vue/test-utils`.
|
|
201
202
|
|
|
202
203
|
---
|
|
203
204
|
|
|
@@ -1 +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 {\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 { attachRenderErrorHandler, createViewStoreLifecycle } 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// Store lifecycle (reseed on viewKey change, refresh /context in place\n\t\t// otherwise, actor-swap reset, guard identity cache) — the shared\n\t\t// coordinator from @xmachines/play-actor; only the reactivity wiring\n\t\t// below is Vue's.\n\t\tconst storeLifecycle = createViewStoreLifecycle((seed) =>\n\t\t\txstateStoreStateStore({ atom: createAtom(seed) }),\n\t\t);\n\t\t// storeKey is a SUBTREE REMOUNT key — it must bump only when the store is\n\t\t// actually reseeded, never on an in-place /context refresh, or every\n\t\t// projection update would wipe the rendered subtree.\n\t\t// (Controlled mode never reseeds, so it never bumps.)\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// (The store lifecycle resets itself on the actor swap — the kept\n\t\t\t\t// store must not outlive its actor.)\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-viewKey) via\n\t\t\t// the shared lifecycle; children get the guarded store — /context is\n\t\t\t// read-only to the spec, and the machinery refreshes through the\n\t\t\t// unguarded reference inside the coordinator.\n\t\t\tconst resolution = storeLifecycle.resolve(actorRef.value, spec, props.store);\n\t\t\tif (resolution.reseeded) storeKey++;\n\t\t\tconst store: StateStore = resolution.guardedStore;\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
|
+
{"version":3,"file":"ActorProvider.js","names":[],"sources":["../src/ActorProvider.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * ActorProvider — the low-level provider of the XMachines Vue render architecture.\n *\n * It owns the complete actor lifecycle:\n * - the signal subscription (watchSignal), which connects the TC39 Signals to the Vue reactivity\n * - the StateStore lifecycle of each view, controlled and uncontrolled\n * - the resolution of the handlers, through ActorProviderInner, which must be inside StateProvider\n * - the ViewContextValue, which it provides through the ViewKey injection key\n * - the ActionProvider wrapper and the VisibilityProvider wrapper, for the Renderer below\n * - the injection of onRenderError into the registry\n *\n * The author of a library who needs this control uses the component directly.\n * An end user takes <PlayUIProvider> instead.\n *\n * @invariant Actor Authority - the Actor decides each state transition, with its guards\n * @invariant Passive Infrastructure - the component observes the signals, and it sends the events\n * @invariant Signal-Only Reactivity - the state of the business logic is in the 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 { attachRenderErrorHandler, createViewStoreLifecycle } 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 the props type and the context accessors, for a consumer that imports from this file\nexport type { ActorProviderProps } from \"./types.js\";\nexport { usePlayView, getPlayViewContext } from \"./actor-provider-context.js\"; // getPlayViewContext @deprecated\nexport type { ViewContextValue } from \"./actor-provider-context.js\";\n\n// ---------------------------------------------------------------------------\n// ActorProviderInner — it renders inside StateProvider, so that it can call useStateStore()\n// It gives the ViewContextValue, the ActionProvider, and the VisibilityProvider to the Renderer below.\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// The code uses a shallowRef for the value of the view context, because a deep\n\t\t// reactivity costs too much. The Proxy below lets inject() always read the newest\n\t\t// value.\n\t\tconst viewRef = shallowRef<ViewContextValue | null>(null);\n\n\t\t// Give the ViewContextValue through the inject and provide system of Vue.\n\t\t// The code calls provide synchronously in setup(), so that Vue registers the value on\n\t\t// the instance of the component. It uses a Proxy, so that each descendant always\n\t\t// receives the newest 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() during setup(), which is synchronous and before the return.\n\t\t// A Vue composable that uses inject() must run during setup(), and not in a render\n\t\t// function.\n\t\tconst stateStore = useStateStore();\n\n\t\t// Build a SetState adapter, because the factory of the handlers expects the pattern\n\t\t// of an updater function. The code defines it one time, in setup(). It reads\n\t\t// stateStore.getSnapshot and stateStore.update at the moment of the call. Therefore\n\t\t// it always works on the live state of the store, and it needs no new definition when\n\t\t// the identity of stateStore changes between two 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// Keep the handlers, with the identity of the registryResult prop as the key. The\n\t\t// getter functions are stable closures, and they hold the stateStore of setup().\n\t\t// Therefore they cause no new computation. The code computes the handlers again only\n\t\t// after a change of the definition of the registry, and not on each render of a view\n\t\t// update.\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 the children with an ActionProvider and a VisibilityProvider. The Renderer of\n\t\t\t// PlayRenderer therefore works also with ActorProvider alone, without PlayUIProvider\n\t\t\t// and without 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 — the 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// Take the actor out of the reactive proxy of Vue, to reach the raw Signal objects.\n\t\t// A shallowRef holds the actor. Therefore the injected value and the signal watcher\n\t\t// can follow `props.actor` when the prop changes after the mount.\n\t\tconst actorRef = shallowRef(toRaw(props.actor as AbstractActor<AnyActorLogic> & Viewable));\n\n\t\t// Take the registryResult out of the proxy, and mark each component as raw, because the reactivity of Vue costs too much here\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// Put the onRenderError prop into the registry. The property is not enumerable, and\n\t\t// it replaces the handler of the defineRegistry level. attachRenderErrorHandler makes\n\t\t// a copy, and it changes the registry of the caller never.\n\t\t// The code must call markRaw on the copy again, because a copy does not carry the\n\t\t// non-enumerable flag of markRaw.\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// Give the actor to each descendant, through the provide and inject mechanism of Vue.\n\t\t//\n\t\t// The code gives a stable Proxy, and not the raw actor. The pattern is the same as\n\t\t// the ViewKey proxy of ActorProviderInner. The injected value therefore follows the\n\t\t// CURRENT `props.actor`: each injector keeps the reference of the setup(), and every\n\t\t// trap resolves against the newest actor (actorRef.value) after a change of the prop.\n\t\t// The proxy forwards each relevant trap. Therefore it behaves like the actor below it\n\t\t// for a read, for a write, for a membership test (`in`), for an enumeration\n\t\t// (Object.keys and a spread), and for a prototype test (`instanceof`). Each method\n\t\t// binds to the current raw actor. Therefore `this`, and also each private field,\n\t\t// works exactly as in a direct call.\n\t\t//\n\t\t// IMPORTANT: this proxy is NOT identity-equal to `props.actor`, because it is a\n\t\t// separate object, and therefore a separate key of a WeakMap. A consumer that uses\n\t\t// the identity as its key must receive the `props.actor` value itself, and never this\n\t\t// injected proxy. The most important such consumer is the guard of one bridge for\n\t\t// each actor in RouterBridgeBase: it uses the identity of the actor as the key of a\n\t\t// WeakMap at the module level.\n\t\t//\n\t\t// The identity of a method: the code keeps each bound method, with the method below\n\t\t// it as the key. A repeated read therefore returns the SAME function\n\t\t// (actor.send === actor.send), and the hot path allocates nothing. A read binds the\n\t\t// method again only after a change of the method below it. The watch handler below\n\t\t// CLEARS the cache on a change of the actor. Therefore each prototype method binds to\n\t\t// 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// An invariant of a Proxy: the target of this proxy is an empty {}. Therefore each\n\t\t\t\t\t// key of ownKeys must resolve to a configurable descriptor here. Without that, the\n\t\t\t\t\t// [[GetOwnProperty]] invariant throws, because a proxy must not report a property that\n\t\t\t\t\t// its target has not as non-configurable. The own props of the actor are mutable at\n\t\t\t\t\t// run time in each case. Therefore `configurable: true` is correct enough for the\n\t\t\t\t\t// enumeration of Object.keys and of a spread.\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 the first value, then subscribe. Both steps are synchronous, and no scheduler\n\t\t// runs between them.\n\t\t// Solid does the same with createEffect, and Svelte does the same with $effect.\n\t\t// The pattern is therefore the same in each framework.\n\t\tconst view = ref<PlaySpec | null>(actorRef.value.currentView.get());\n\n\t\t// The store lifecycle: it seeds the store again on a change of the viewKey, it\n\t\t// refreshes /context in place in every other case, it resets the store on a change of\n\t\t// the actor, and it guards the identity cache. The shared coordinator comes from\n\t\t// @xmachines/play-actor. Only the wiring of the reactivity below belongs to Vue.\n\t\tconst storeLifecycle = createViewStoreLifecycle((seed) =>\n\t\t\txstateStoreStateStore({ atom: createAtom(seed) }),\n\t\t);\n\t\t// storeKey is the key of a SUBTREE REMOUNT. Therefore it must change only after a\n\t\t// new seed of the store, and never after a refresh of /context in place. Without this\n\t\t// rule, each update of the projection removes the subtree on the screen.\n\t\t// (The controlled mode seeds the store never again. Therefore the key changes never\n\t\t// there.)\n\t\tlet storeKey = 0;\n\n\t\t// The signal watcher connects the TC39 Signals to the reactivity of Vue.\n\t\t// The code assigns it again on a change of the actor. Therefore the cleanup always\n\t\t// 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 a change of `props.actor`: cancel the subscription to the currentView of\n\t\t// the OLD actor, seed the view from the NEW actor synchronously (`flush: \"sync\"`, so\n\t\t// that no scheduler runs between the steps, as in the seed and watch pattern of the\n\t\t// mount above), and subscribe to the new signal. The view of the new seed has a new\n\t\t// identity. Therefore the branch of the internal store below builds the store again,\n\t\t// and it changes storeKey, exactly like a normal 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// (The store lifecycle resets itself on a change of the actor, because a store that\n\t\t\t\t// stays alive must not outlive its actor.)\n\t\t\t\t// Clear the cache of the bound methods. Each prototype method therefore binds to the\n\t\t\t\t// new actor on the next read. See the get trap of the injected proxy.\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 the fallback slot, or show 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, which is external and controlled, or internal for each\n\t\t\t// viewKey, through the shared lifecycle. The children receive the store with the\n\t\t\t// guard, because /context is read-only to the spec. The machinery refreshes the\n\t\t\t// store through the reference without a guard, inside the coordinator.\n\t\t\tconst resolution = storeLifecycle.resolve(actorRef.value, spec, props.store);\n\t\t\tif (resolution.reseeded) storeKey++;\n\t\t\tconst store: StateStore = resolution.guardedStore;\n\n\t\t\t// ActorProviderInner renders inside StateProvider. Therefore 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":""}
|
|
@@ -8,22 +8,22 @@ import { createAtom } from "@xstate/store";
|
|
|
8
8
|
import { xstateStoreStateStore } from "@xmachines/json-render-xstate";
|
|
9
9
|
//#region packages/play-vue/src/ActorProvider.vue?vue&type=script&lang.ts
|
|
10
10
|
/**
|
|
11
|
-
* ActorProvider —
|
|
11
|
+
* ActorProvider — the low-level provider of the XMachines Vue render architecture.
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
* -
|
|
15
|
-
* -
|
|
16
|
-
* -
|
|
17
|
-
* - ViewContextValue
|
|
18
|
-
* - ActionProvider
|
|
19
|
-
* -
|
|
13
|
+
* It owns the complete actor lifecycle:
|
|
14
|
+
* - the signal subscription (watchSignal), which connects the TC39 Signals to the Vue reactivity
|
|
15
|
+
* - the StateStore lifecycle of each view, controlled and uncontrolled
|
|
16
|
+
* - the resolution of the handlers, through ActorProviderInner, which must be inside StateProvider
|
|
17
|
+
* - the ViewContextValue, which it provides through the ViewKey injection key
|
|
18
|
+
* - the ActionProvider wrapper and the VisibilityProvider wrapper, for the Renderer below
|
|
19
|
+
* - the injection of onRenderError into the registry
|
|
20
20
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
21
|
+
* The author of a library who needs this control uses the component directly.
|
|
22
|
+
* An end user takes <PlayUIProvider> instead.
|
|
23
23
|
*
|
|
24
|
-
* @invariant Actor Authority - Actor decides
|
|
25
|
-
* @invariant Passive Infrastructure -
|
|
26
|
-
* @invariant Signal-Only Reactivity -
|
|
24
|
+
* @invariant Actor Authority - the Actor decides each state transition, with its guards
|
|
25
|
+
* @invariant Passive Infrastructure - the component observes the signals, and it sends the events
|
|
26
|
+
* @invariant Signal-Only Reactivity - the state of the business logic is in the actor signals
|
|
27
27
|
*/
|
|
28
28
|
var ActorProviderInner = defineComponent({
|
|
29
29
|
name: "ActorProviderInner",
|
|
@@ -1 +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 {\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 { attachRenderErrorHandler, createViewStoreLifecycle } 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// Store lifecycle (reseed on viewKey change, refresh /context in place\n\t\t// otherwise, actor-swap reset, guard identity cache) — the shared\n\t\t// coordinator from @xmachines/play-actor; only the reactivity wiring\n\t\t// below is Vue's.\n\t\tconst storeLifecycle = createViewStoreLifecycle((seed) =>\n\t\t\txstateStoreStateStore({ atom: createAtom(seed) }),\n\t\t);\n\t\t// storeKey is a SUBTREE REMOUNT key — it must bump only when the store is\n\t\t// actually reseeded, never on an in-place /context refresh, or every\n\t\t// projection update would wipe the rendered subtree.\n\t\t// (Controlled mode never reseeds, so it never bumps.)\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// (The store lifecycle resets itself on the actor swap — the kept\n\t\t\t\t// store must not outlive its actor.)\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-viewKey) via\n\t\t\t// the shared lifecycle; children get the guarded store — /context is\n\t\t\t// read-only to the spec, and the machinery refreshes through the\n\t\t\t// unguarded reference inside the coordinator.\n\t\t\tconst resolution = storeLifecycle.resolve(actorRef.value, spec, props.store);\n\t\t\tif (resolution.reseeded) storeKey++;\n\t\t\tconst store: StateStore = resolution.guardedStore;\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":"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"}
|
|
1
|
+
{"version":3,"file":"ActorProvider.vue_vue_type_script_lang.js","names":[],"sources":["../src/ActorProvider.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * ActorProvider — the low-level provider of the XMachines Vue render architecture.\n *\n * It owns the complete actor lifecycle:\n * - the signal subscription (watchSignal), which connects the TC39 Signals to the Vue reactivity\n * - the StateStore lifecycle of each view, controlled and uncontrolled\n * - the resolution of the handlers, through ActorProviderInner, which must be inside StateProvider\n * - the ViewContextValue, which it provides through the ViewKey injection key\n * - the ActionProvider wrapper and the VisibilityProvider wrapper, for the Renderer below\n * - the injection of onRenderError into the registry\n *\n * The author of a library who needs this control uses the component directly.\n * An end user takes <PlayUIProvider> instead.\n *\n * @invariant Actor Authority - the Actor decides each state transition, with its guards\n * @invariant Passive Infrastructure - the component observes the signals, and it sends the events\n * @invariant Signal-Only Reactivity - the state of the business logic is in the 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 { attachRenderErrorHandler, createViewStoreLifecycle } 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 the props type and the context accessors, for a consumer that imports from this file\nexport type { ActorProviderProps } from \"./types.js\";\nexport { usePlayView, getPlayViewContext } from \"./actor-provider-context.js\"; // getPlayViewContext @deprecated\nexport type { ViewContextValue } from \"./actor-provider-context.js\";\n\n// ---------------------------------------------------------------------------\n// ActorProviderInner — it renders inside StateProvider, so that it can call useStateStore()\n// It gives the ViewContextValue, the ActionProvider, and the VisibilityProvider to the Renderer below.\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// The code uses a shallowRef for the value of the view context, because a deep\n\t\t// reactivity costs too much. The Proxy below lets inject() always read the newest\n\t\t// value.\n\t\tconst viewRef = shallowRef<ViewContextValue | null>(null);\n\n\t\t// Give the ViewContextValue through the inject and provide system of Vue.\n\t\t// The code calls provide synchronously in setup(), so that Vue registers the value on\n\t\t// the instance of the component. It uses a Proxy, so that each descendant always\n\t\t// receives the newest 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() during setup(), which is synchronous and before the return.\n\t\t// A Vue composable that uses inject() must run during setup(), and not in a render\n\t\t// function.\n\t\tconst stateStore = useStateStore();\n\n\t\t// Build a SetState adapter, because the factory of the handlers expects the pattern\n\t\t// of an updater function. The code defines it one time, in setup(). It reads\n\t\t// stateStore.getSnapshot and stateStore.update at the moment of the call. Therefore\n\t\t// it always works on the live state of the store, and it needs no new definition when\n\t\t// the identity of stateStore changes between two 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// Keep the handlers, with the identity of the registryResult prop as the key. The\n\t\t// getter functions are stable closures, and they hold the stateStore of setup().\n\t\t// Therefore they cause no new computation. The code computes the handlers again only\n\t\t// after a change of the definition of the registry, and not on each render of a view\n\t\t// update.\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 the children with an ActionProvider and a VisibilityProvider. The Renderer of\n\t\t\t// PlayRenderer therefore works also with ActorProvider alone, without PlayUIProvider\n\t\t\t// and without 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 — the 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// Take the actor out of the reactive proxy of Vue, to reach the raw Signal objects.\n\t\t// A shallowRef holds the actor. Therefore the injected value and the signal watcher\n\t\t// can follow `props.actor` when the prop changes after the mount.\n\t\tconst actorRef = shallowRef(toRaw(props.actor as AbstractActor<AnyActorLogic> & Viewable));\n\n\t\t// Take the registryResult out of the proxy, and mark each component as raw, because the reactivity of Vue costs too much here\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// Put the onRenderError prop into the registry. The property is not enumerable, and\n\t\t// it replaces the handler of the defineRegistry level. attachRenderErrorHandler makes\n\t\t// a copy, and it changes the registry of the caller never.\n\t\t// The code must call markRaw on the copy again, because a copy does not carry the\n\t\t// non-enumerable flag of markRaw.\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// Give the actor to each descendant, through the provide and inject mechanism of Vue.\n\t\t//\n\t\t// The code gives a stable Proxy, and not the raw actor. The pattern is the same as\n\t\t// the ViewKey proxy of ActorProviderInner. The injected value therefore follows the\n\t\t// CURRENT `props.actor`: each injector keeps the reference of the setup(), and every\n\t\t// trap resolves against the newest actor (actorRef.value) after a change of the prop.\n\t\t// The proxy forwards each relevant trap. Therefore it behaves like the actor below it\n\t\t// for a read, for a write, for a membership test (`in`), for an enumeration\n\t\t// (Object.keys and a spread), and for a prototype test (`instanceof`). Each method\n\t\t// binds to the current raw actor. Therefore `this`, and also each private field,\n\t\t// works exactly as in a direct call.\n\t\t//\n\t\t// IMPORTANT: this proxy is NOT identity-equal to `props.actor`, because it is a\n\t\t// separate object, and therefore a separate key of a WeakMap. A consumer that uses\n\t\t// the identity as its key must receive the `props.actor` value itself, and never this\n\t\t// injected proxy. The most important such consumer is the guard of one bridge for\n\t\t// each actor in RouterBridgeBase: it uses the identity of the actor as the key of a\n\t\t// WeakMap at the module level.\n\t\t//\n\t\t// The identity of a method: the code keeps each bound method, with the method below\n\t\t// it as the key. A repeated read therefore returns the SAME function\n\t\t// (actor.send === actor.send), and the hot path allocates nothing. A read binds the\n\t\t// method again only after a change of the method below it. The watch handler below\n\t\t// CLEARS the cache on a change of the actor. Therefore each prototype method binds to\n\t\t// 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// An invariant of a Proxy: the target of this proxy is an empty {}. Therefore each\n\t\t\t\t\t// key of ownKeys must resolve to a configurable descriptor here. Without that, the\n\t\t\t\t\t// [[GetOwnProperty]] invariant throws, because a proxy must not report a property that\n\t\t\t\t\t// its target has not as non-configurable. The own props of the actor are mutable at\n\t\t\t\t\t// run time in each case. Therefore `configurable: true` is correct enough for the\n\t\t\t\t\t// enumeration of Object.keys and of a spread.\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 the first value, then subscribe. Both steps are synchronous, and no scheduler\n\t\t// runs between them.\n\t\t// Solid does the same with createEffect, and Svelte does the same with $effect.\n\t\t// The pattern is therefore the same in each framework.\n\t\tconst view = ref<PlaySpec | null>(actorRef.value.currentView.get());\n\n\t\t// The store lifecycle: it seeds the store again on a change of the viewKey, it\n\t\t// refreshes /context in place in every other case, it resets the store on a change of\n\t\t// the actor, and it guards the identity cache. The shared coordinator comes from\n\t\t// @xmachines/play-actor. Only the wiring of the reactivity below belongs to Vue.\n\t\tconst storeLifecycle = createViewStoreLifecycle((seed) =>\n\t\t\txstateStoreStateStore({ atom: createAtom(seed) }),\n\t\t);\n\t\t// storeKey is the key of a SUBTREE REMOUNT. Therefore it must change only after a\n\t\t// new seed of the store, and never after a refresh of /context in place. Without this\n\t\t// rule, each update of the projection removes the subtree on the screen.\n\t\t// (The controlled mode seeds the store never again. Therefore the key changes never\n\t\t// there.)\n\t\tlet storeKey = 0;\n\n\t\t// The signal watcher connects the TC39 Signals to the reactivity of Vue.\n\t\t// The code assigns it again on a change of the actor. Therefore the cleanup always\n\t\t// 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 a change of `props.actor`: cancel the subscription to the currentView of\n\t\t// the OLD actor, seed the view from the NEW actor synchronously (`flush: \"sync\"`, so\n\t\t// that no scheduler runs between the steps, as in the seed and watch pattern of the\n\t\t// mount above), and subscribe to the new signal. The view of the new seed has a new\n\t\t// identity. Therefore the branch of the internal store below builds the store again,\n\t\t// and it changes storeKey, exactly like a normal 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// (The store lifecycle resets itself on a change of the actor, because a store that\n\t\t\t\t// stays alive must not outlive its actor.)\n\t\t\t\t// Clear the cache of the bound methods. Each prototype method therefore binds to the\n\t\t\t\t// new actor on the next read. See the get trap of the injected proxy.\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 the fallback slot, or show 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, which is external and controlled, or internal for each\n\t\t\t// viewKey, through the shared lifecycle. The children receive the store with the\n\t\t\t// guard, because /context is read-only to the spec. The machinery refreshes the\n\t\t\t// store through the reference without a guard, inside the coordinator.\n\t\t\tconst resolution = storeLifecycle.resolve(actorRef.value, spec, props.store);\n\t\t\tif (resolution.reseeded) storeKey++;\n\t\t\tconst store: StateStore = resolution.guardedStore;\n\n\t\t\t// ActorProviderInner renders inside StateProvider. Therefore 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":"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"}
|
package/dist/PlayRenderer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlayRenderer.js","names":[],"sources":["../src/PlayRenderer.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * PlayRenderer —
|
|
1
|
+
{"version":3,"file":"PlayRenderer.js","names":[],"sources":["../src/PlayRenderer.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * PlayRenderer — the leaf component without props of the XMachines Vue render architecture.\n *\n * It reads the current view context of the nearest ActorProvider, or of the nearest\n * PlayUIProvider. It then renders <Renderer spec={view.spec} registry={view.registry} />.\n *\n * Use it 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 - the component observes the context. It never decides\n */\n\nimport { defineComponent, h } from \"vue\";\nimport { Renderer } from \"@xmachines/json-render-vue\";\nimport { usePlayView } from \"./actor-provider-context.js\";\n\nexport default defineComponent({\n\tname: \"PlayRenderer\",\n\tsetup() {\n\t\t// Call inject during setup(), which the composition API of Vue permits.\n\t\t// usePlayView() uses inject(), and inject() must run synchronously during\n\t\t// setup(). The Proxy of ActorProviderInner gives view.spec and view.registry their\n\t\t// newest values on each read in the render function.\n\t\tconst view = usePlayView();\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,14 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { usePlayView } from "./actor-provider-context.js";
|
|
2
2
|
import { defineComponent, h } from "vue";
|
|
3
3
|
import { Renderer } from "@xmachines/json-render-vue";
|
|
4
4
|
//#region packages/play-vue/src/PlayRenderer.vue?vue&type=script&lang.ts
|
|
5
5
|
/**
|
|
6
|
-
* PlayRenderer —
|
|
6
|
+
* PlayRenderer — the leaf component without props of the XMachines Vue render architecture.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
8
|
+
* It reads the current view context of the nearest ActorProvider, or of the nearest
|
|
9
|
+
* PlayUIProvider. It then renders <Renderer spec={view.spec} registry={view.registry} />.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
11
|
+
* Use it inside <ActorProvider> or <PlayUIProvider>.
|
|
12
12
|
*
|
|
13
13
|
* @example
|
|
14
14
|
* ```ts
|
|
@@ -17,12 +17,12 @@ import { Renderer } from "@xmachines/json-render-vue";
|
|
|
17
17
|
* </PlayUIProvider>
|
|
18
18
|
* ```
|
|
19
19
|
*
|
|
20
|
-
* @invariant Passive Infrastructure -
|
|
20
|
+
* @invariant Passive Infrastructure - the component observes the context. It never decides
|
|
21
21
|
*/
|
|
22
22
|
var PlayRenderer_vue_vue_type_script_lang_default = defineComponent({
|
|
23
23
|
name: "PlayRenderer",
|
|
24
24
|
setup() {
|
|
25
|
-
const view =
|
|
25
|
+
const view = usePlayView();
|
|
26
26
|
return () => {
|
|
27
27
|
return h(Renderer, {
|
|
28
28
|
spec: view.spec,
|
|
@@ -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 —
|
|
1
|
+
{"version":3,"file":"PlayRenderer.vue_vue_type_script_lang.js","names":[],"sources":["../src/PlayRenderer.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * PlayRenderer — the leaf component without props of the XMachines Vue render architecture.\n *\n * It reads the current view context of the nearest ActorProvider, or of the nearest\n * PlayUIProvider. It then renders <Renderer spec={view.spec} registry={view.registry} />.\n *\n * Use it 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 - the component observes the context. It never decides\n */\n\nimport { defineComponent, h } from \"vue\";\nimport { Renderer } from \"@xmachines/json-render-vue\";\nimport { usePlayView } from \"./actor-provider-context.js\";\n\nexport default defineComponent({\n\tname: \"PlayRenderer\",\n\tsetup() {\n\t\t// Call inject during setup(), which the composition API of Vue permits.\n\t\t// usePlayView() uses inject(), and inject() must run synchronously during\n\t\t// setup(). The Proxy of ActorProviderInner gives view.spec and view.registry their\n\t\t// newest values on each read in the render function.\n\t\tconst view = usePlayView();\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,gDAAe,gBAAgB;CAC9B,MAAM;CACN,QAAQ;EAKP,MAAM,OAAO,YAAY;EACzB,aAAa;GACZ,OAAO,EAAE,UAAU;IAAE,MAAM,KAAK;IAAM,UAAU,KAAK;GAAS,CAAC;EAChE;CACD;AACD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlayUIProvider.js","names":[],"sources":["../src/PlayUIProvider.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * PlayUIProvider —
|
|
1
|
+
{"version":3,"file":"PlayUIProvider.js","names":[],"sources":["../src/PlayUIProvider.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * PlayUIProvider — the composite provider of an actor-driven UI.\n *\n * It wraps ActorProvider and JSONUIProvider, from @xmachines/json-render-vue. One\n * component therefore serves the complete actor lifecycle and the complete UI\n * rendering.\n *\n * The standard use:\n * ```ts\n * <PlayUIProvider :actor=\"actor\" :registryResult=\"registryResult\">\n * <PlayRenderer />\n * </PlayUIProvider>\n * ```\n *\n * For a custom provider composition, 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 { usePlayView } from \"./actor-provider-context.js\";\nimport type { PlayUIProviderProps } from \"./types.js\";\n\n// Re-export the props type, for a consumer that imports from this file\nexport type { PlayUIProviderProps } from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// JSONUIBridge — the inner component inside the tree of ActorProvider\n// It reads the ViewContextValue with usePlayView(), and it gives the handlers\n// and the registry to JSONUIProvider. Therefore ActorProvider and JSONUIProvider\n// share one 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 = usePlayView();\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 — the 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,22 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { usePlayView } from "./actor-provider-context.js";
|
|
2
2
|
import ActorProvider_default from "./ActorProvider.js";
|
|
3
3
|
import { defineComponent, h } from "vue";
|
|
4
4
|
import { JSONUIProvider } from "@xmachines/json-render-vue";
|
|
5
5
|
//#region packages/play-vue/src/PlayUIProvider.vue?vue&type=script&lang.ts
|
|
6
6
|
/**
|
|
7
|
-
* PlayUIProvider —
|
|
7
|
+
* PlayUIProvider — the composite provider of an actor-driven UI.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* It wraps ActorProvider and JSONUIProvider, from @xmachines/json-render-vue. One
|
|
10
|
+
* component therefore serves the complete actor lifecycle and the complete UI
|
|
11
|
+
* rendering.
|
|
11
12
|
*
|
|
12
|
-
*
|
|
13
|
+
* The standard use:
|
|
13
14
|
* ```ts
|
|
14
15
|
* <PlayUIProvider :actor="actor" :registryResult="registryResult">
|
|
15
16
|
* <PlayRenderer />
|
|
16
17
|
* </PlayUIProvider>
|
|
17
18
|
* ```
|
|
18
19
|
*
|
|
19
|
-
* For custom provider composition
|
|
20
|
+
* For a custom provider composition, use <ActorProvider> directly.
|
|
20
21
|
*
|
|
21
22
|
* @packageDocumentation
|
|
22
23
|
*/
|
|
@@ -38,7 +39,7 @@ var JSONUIBridge = defineComponent({
|
|
|
38
39
|
},
|
|
39
40
|
setup(props, { slots }) {
|
|
40
41
|
return () => {
|
|
41
|
-
const view =
|
|
42
|
+
const view = usePlayView();
|
|
42
43
|
return h(JSONUIProvider, {
|
|
43
44
|
registry: view.registry,
|
|
44
45
|
handlers: view.handlers,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlayUIProvider.vue_vue_type_script_lang.js","names":[],"sources":["../src/PlayUIProvider.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * PlayUIProvider —
|
|
1
|
+
{"version":3,"file":"PlayUIProvider.vue_vue_type_script_lang.js","names":[],"sources":["../src/PlayUIProvider.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * PlayUIProvider — the composite provider of an actor-driven UI.\n *\n * It wraps ActorProvider and JSONUIProvider, from @xmachines/json-render-vue. One\n * component therefore serves the complete actor lifecycle and the complete UI\n * rendering.\n *\n * The standard use:\n * ```ts\n * <PlayUIProvider :actor=\"actor\" :registryResult=\"registryResult\">\n * <PlayRenderer />\n * </PlayUIProvider>\n * ```\n *\n * For a custom provider composition, 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 { usePlayView } from \"./actor-provider-context.js\";\nimport type { PlayUIProviderProps } from \"./types.js\";\n\n// Re-export the props type, for a consumer that imports from this file\nexport type { PlayUIProviderProps } from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// JSONUIBridge — the inner component inside the tree of ActorProvider\n// It reads the ViewContextValue with usePlayView(), and it gives the handlers\n// and the registry to JSONUIProvider. Therefore ActorProvider and JSONUIProvider\n// share one 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 = usePlayView();\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 — the 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":";;;;;;;;;;;;;;;;;;;;;;;AA0CA,IAAM,eAAe,gBAAgB;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,OAAO,EAAE,SAAS;EACvB,aAAa;GACZ,MAAM,OAAO,YAAY;GACzB,OAAO,EACN,gBACA;IACC,UAAU,KAAK;IACf,UAAU,KAAK;IACf,OAAO,KAAK;IACZ,GAAI,MAAM,WAAW,EAAE,UAAU,MAAM,SAAS,IAAI,CAAC;IACrD,GAAI,MAAM,sBACP,EAAE,qBAAqB,MAAM,oBAAoB,IACjD,CAAC;IACJ,GAAI,MAAM,YAAY,EAAE,WAAW,MAAM,UAAU,IAAI,CAAC;GACzD,GACA,KACD;EACD;CACD;AACD,CAAC;AAMD,IAAA,kDAAe,gBAAgB;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,OAAO,EAAE,SAAS;EACvB,aACC,EACC,uBACA;GACC,OAAO,MAAM;GACb,gBAAgB,MAAM;GACtB,GAAI,MAAM,QAAQ,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC;GAC5C,GAAI,MAAM,gBAAgB,EAAE,eAAe,MAAM,cAAc,IAAI,CAAC;EACrE,GACA;GACC,eACC,EACC,cACA;IACC,GAAI,MAAM,WAAW,EAAE,UAAU,MAAM,SAAS,IAAI,CAAC;IACrD,GAAI,MAAM,sBACP,EAAE,qBAAqB,MAAM,oBAAoB,IACjD,CAAC;IACJ,GAAI,MAAM,YAAY,EAAE,WAAW,MAAM,UAAU,IAAI,CAAC;GACzD,GACA,KACD;GACD,UAAU,MAAM;EACjB,CACD;CACF;AACD,CAAC"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ViewContextValue and
|
|
2
|
+
* ViewContextValue and usePlayView — the shared context types of the Vue provider architecture.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* (The vue-shim.d.ts
|
|
6
|
-
*
|
|
4
|
+
* This file holds them, and not ActorProvider.vue, so that TypeScript can
|
|
5
|
+
* re-export the types from index.ts. (The file vue-shim.d.ts declares a default
|
|
6
|
+
* export of each *.vue file only. Therefore TypeScript does not see a named export
|
|
7
|
+
* of a .vue SFC when it resolves a re-export.)
|
|
7
8
|
*
|
|
8
9
|
* @packageDocumentation
|
|
9
10
|
*/
|
|
@@ -11,30 +12,37 @@ import type { InjectionKey } from "vue";
|
|
|
11
12
|
import type { ComponentRegistry } from "@xmachines/json-render-vue";
|
|
12
13
|
import type { BaseViewContextValue } from "@xmachines/play-actor";
|
|
13
14
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
15
|
+
* The context value that ActorProvider provides and PlayRenderer, the leaf without
|
|
16
|
+
* props, reads. usePlayView() gives it inside every ActorProvider tree and
|
|
17
|
+
* PlayUIProvider tree.
|
|
16
18
|
*/
|
|
17
19
|
export interface ViewContextValue extends BaseViewContextValue<ComponentRegistry> {
|
|
18
20
|
}
|
|
19
21
|
/**
|
|
20
|
-
*
|
|
21
|
-
* as the canonical key
|
|
22
|
+
* The injection key of the ViewContextValue. This file exports it, so that
|
|
23
|
+
* ActorProvider.vue uses it as the canonical key and declares no second key.
|
|
22
24
|
*
|
|
23
|
-
* @internal Use
|
|
25
|
+
* @internal Use usePlayView() as the public API. Never inject ViewKey directly.
|
|
24
26
|
*/
|
|
25
27
|
export declare const ViewKey: InjectionKey<ViewContextValue>;
|
|
26
28
|
/**
|
|
27
|
-
*
|
|
29
|
+
* Returns the current ViewContextValue inside an ActorProvider tree.
|
|
28
30
|
*
|
|
29
|
-
* @throws {Error}
|
|
31
|
+
* @throws {Error} When the caller is outside an <ActorProvider> tree or a <PlayUIProvider> tree
|
|
30
32
|
*
|
|
31
33
|
* @example
|
|
32
34
|
* ```typescript
|
|
33
|
-
* import {
|
|
35
|
+
* import { usePlayView } from "@xmachines/play-vue";
|
|
34
36
|
*
|
|
35
|
-
* const view =
|
|
37
|
+
* const view = usePlayView();
|
|
36
38
|
* // view.spec, view.handlers, view.registry
|
|
37
39
|
* ```
|
|
38
40
|
*/
|
|
39
|
-
export declare function
|
|
41
|
+
export declare function usePlayView(): ViewContextValue;
|
|
42
|
+
/**
|
|
43
|
+
* Access the current ViewContextValue from inside an ActorProvider tree.
|
|
44
|
+
*
|
|
45
|
+
* @deprecated Renamed to {@link usePlayView}; will be removed in the next major.
|
|
46
|
+
*/
|
|
47
|
+
export declare const getPlayViewContext: typeof usePlayView;
|
|
40
48
|
//# sourceMappingURL=actor-provider-context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actor-provider-context.d.ts","sourceRoot":"","sources":["../src/actor-provider-context.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"actor-provider-context.d.ts","sourceRoot":"","sources":["../src/actor-provider-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,KAAK,CAAC;AAExC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAElE;;;;GAIG;AACH,MAAM,WAAW,gBAAiB,SAAQ,oBAAoB,CAAC,iBAAiB,CAAC;CAAG;AAEpF;;;;;GAKG;AACH,eAAO,MAAM,OAAO,EAAE,YAAY,CAAC,gBAAgB,CAA4B,CAAC;AAEhF;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,IAAI,gBAAgB,CAE9C;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,oBAAc,CAAC"}
|