@xmachines/play-actor 1.0.0-beta.32 → 1.0.0-beta.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -18
- package/dist/abstract-actor.d.ts +70 -31
- package/dist/abstract-actor.d.ts.map +1 -1
- package/dist/abstract-actor.js +6 -9
- package/dist/abstract-actor.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -28,7 +28,10 @@ npm install @xmachines/play-actor
|
|
|
28
28
|
- `AbstractActor`
|
|
29
29
|
- `Routable` (type)
|
|
30
30
|
- `Viewable` (type)
|
|
31
|
-
- `
|
|
31
|
+
- `PlaySpec` (type)
|
|
32
|
+
- `typedSpec`
|
|
33
|
+
- `BaseActorProviderProps` (type)
|
|
34
|
+
- `BaseViewContextValue` (type)
|
|
32
35
|
|
|
33
36
|
**Peer dependencies:**
|
|
34
37
|
|
|
@@ -72,7 +75,7 @@ Implement `Routable` to add routing support:
|
|
|
72
75
|
|
|
73
76
|
Implement `Viewable` to add view rendering support:
|
|
74
77
|
|
|
75
|
-
- `currentView: Signal.State<
|
|
78
|
+
- `currentView: Signal.State<PlaySpec | null>` - Current view spec (updated on every state transition). `PlaySpec` is a `@json-render/core` spec object (`{ root, elements }`) that drives the renderer directly.
|
|
76
79
|
|
|
77
80
|
**Inherited from XState Actor:**
|
|
78
81
|
|
|
@@ -84,12 +87,7 @@ Implement `Viewable` to add view rendering support:
|
|
|
84
87
|
**Example implementation pattern:**
|
|
85
88
|
|
|
86
89
|
```typescript
|
|
87
|
-
import {
|
|
88
|
-
AbstractActor,
|
|
89
|
-
type Routable,
|
|
90
|
-
type Viewable,
|
|
91
|
-
type ViewMetadata,
|
|
92
|
-
} from "@xmachines/play-actor";
|
|
90
|
+
import { AbstractActor, type Routable, type Viewable, type PlaySpec } from "@xmachines/play-actor";
|
|
93
91
|
import { Signal } from "@xmachines/play-signals";
|
|
94
92
|
import type { AnyActorLogic, AnyMachineSnapshot } from "xstate";
|
|
95
93
|
|
|
@@ -106,7 +104,7 @@ class PlayerActor<TLogic extends AnyActorLogic>
|
|
|
106
104
|
});
|
|
107
105
|
|
|
108
106
|
// Viewable: current view spec — Signal.State, updated on every state transition
|
|
109
|
-
currentView = new Signal.State<
|
|
107
|
+
currentView = new Signal.State<PlaySpec | null>(null);
|
|
110
108
|
|
|
111
109
|
constructor(logic: TLogic) {
|
|
112
110
|
super(logic);
|
|
@@ -178,19 +176,19 @@ function connectBrowserNavigation(actor: AbstractActor<any>) {
|
|
|
178
176
|
This base class enforces three architectural invariants:
|
|
179
177
|
|
|
180
178
|
1. **Actor Authority (INV-01):**
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
179
|
+
- Actor decides all state transitions via guards
|
|
180
|
+
- Infrastructure sends events, actor validates and processes
|
|
181
|
+
- Actor's decision is final — no override by infrastructure
|
|
184
182
|
|
|
185
183
|
2. **Signal-Only Reactivity (INV-05):**
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
184
|
+
- All reactive state exposed via TC39 Signals
|
|
185
|
+
- Infrastructure uses `Signal.subtle.Watcher` to observe
|
|
186
|
+
- No direct queries (`getSnapshot()` for internal use only)
|
|
189
187
|
|
|
190
188
|
3. **Passive Infrastructure (INV-04):**
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
189
|
+
- Infrastructure reflects actor state (via signals)
|
|
190
|
+
- Infrastructure never decides transitions
|
|
191
|
+
- Browser/router events sent as commands to actor
|
|
194
192
|
|
|
195
193
|
## XState Compatibility
|
|
196
194
|
|
package/dist/abstract-actor.d.ts
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import { Actor, type AnyActorLogic, type EventObject } from "xstate";
|
|
20
20
|
import type { Signal } from "@xmachines/play-signals";
|
|
21
|
-
import type { Spec } from "@json-render/core";
|
|
21
|
+
import type { Spec, StateStore, RenderErrorHandler, ActionHandler } from "@json-render/core";
|
|
22
22
|
/**
|
|
23
23
|
* Optional capability: Routing support
|
|
24
24
|
*/
|
|
@@ -67,39 +67,18 @@ export interface PlaySpec extends Spec {
|
|
|
67
67
|
* }
|
|
68
68
|
*
|
|
69
69
|
* meta: {
|
|
70
|
-
* view: {
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
* elements: { root: { type: "Dashboard", props: {}, children: [] } },
|
|
77
|
-
* }),
|
|
78
|
-
* },
|
|
70
|
+
* view: typedSpec<DashboardCtx>({
|
|
71
|
+
* root: "root",
|
|
72
|
+
* contextProps: ["username"], // ✓ key of DashboardCtx
|
|
73
|
+
* // contextProps: ["usernaem"], // ✗ compile error
|
|
74
|
+
* elements: { root: { type: "Dashboard", props: {}, children: [] } },
|
|
75
|
+
* }),
|
|
79
76
|
* }
|
|
80
77
|
* ```
|
|
81
78
|
*/
|
|
82
79
|
export declare function typedSpec<TContext extends object>(spec: Omit<PlaySpec, "contextProps"> & {
|
|
83
80
|
readonly contextProps?: readonly (keyof TContext & string)[];
|
|
84
81
|
}): PlaySpec;
|
|
85
|
-
/**
|
|
86
|
-
* View metadata for rendering.
|
|
87
|
-
*
|
|
88
|
-
* Describes the component to be rendered and the json-render Spec to use.
|
|
89
|
-
* Used by PlayRenderer to dynamically render UI based on actor state.
|
|
90
|
-
*/
|
|
91
|
-
export interface ViewMetadata {
|
|
92
|
-
/** Root element type name (for diagnostics and component resolution) */
|
|
93
|
-
component: string;
|
|
94
|
-
/**
|
|
95
|
-
* XMachines view spec — extends `@json-render/core` Spec with `contextProps`
|
|
96
|
-
* for explicit context field exposure.
|
|
97
|
-
*
|
|
98
|
-
* Use `typedSpec<TContext>(...)` at the definition site to validate
|
|
99
|
-
* `contextProps` entries against the machine context type.
|
|
100
|
-
*/
|
|
101
|
-
spec: PlaySpec;
|
|
102
|
-
}
|
|
103
82
|
/**
|
|
104
83
|
* Actor capability for exposing renderable view state.
|
|
105
84
|
*
|
|
@@ -110,12 +89,72 @@ export interface ViewMetadata {
|
|
|
110
89
|
*/
|
|
111
90
|
export interface Viewable {
|
|
112
91
|
/**
|
|
113
|
-
* Current view signal.
|
|
92
|
+
* Current view signal. Contains the json-render PlaySpec for the current machine
|
|
93
|
+
* state, or null when no view is active.
|
|
114
94
|
*
|
|
115
|
-
* State signal containing view.component and view.spec from meta.view.
|
|
116
95
|
* Infrastructure renders view — Logic-Driven UI invariant.
|
|
117
96
|
*/
|
|
118
|
-
readonly currentView: Signal.State<
|
|
97
|
+
readonly currentView: Signal.State<PlaySpec | null>;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Framework-agnostic base for every framework's `ViewContextValue`.
|
|
101
|
+
*
|
|
102
|
+
* Holds the three fields that are identical across React, Vue, Solid, and Svelte.
|
|
103
|
+
* `registry` is framework-specific (each framework has its own `ComponentRegistry`
|
|
104
|
+
* type) so it is typed via `TRegistry` — the same generic used in `BaseActorProviderProps`.
|
|
105
|
+
*
|
|
106
|
+
* @typeParam TRegistry - The framework's component registry type (e.g. `ComponentRegistry` from `@json-render/react`).
|
|
107
|
+
*/
|
|
108
|
+
export interface BaseViewContextValue<TRegistry extends object> {
|
|
109
|
+
/** The current PlaySpec to render. */
|
|
110
|
+
spec: PlaySpec;
|
|
111
|
+
/** Action handlers resolved against the live StateStore. */
|
|
112
|
+
handlers: Record<string, ActionHandler>;
|
|
113
|
+
/** Component registry from registryResult.registry. */
|
|
114
|
+
registry: TRegistry;
|
|
115
|
+
/** The active StateStore — pass to JSONUIProvider/JsonUIProvider as `store` to share state across providers. */
|
|
116
|
+
store: StateStore;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Framework-agnostic base props shared by every `ActorProvider` implementation
|
|
120
|
+
* (React, Vue, Solid, Svelte). `TRegistry` captures the framework-specific
|
|
121
|
+
* `DefineRegistryResult` type; `RenderErrorHandler` is sourced from
|
|
122
|
+
* `@json-render/core` so no second generic is needed.
|
|
123
|
+
*
|
|
124
|
+
* Framework packages extend this with their `fallback`, `onError`, and `children` fields.
|
|
125
|
+
*
|
|
126
|
+
* @typeParam TRegistry - The framework's `DefineRegistryResult` type.
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```ts
|
|
130
|
+
* import type { BaseActorProviderProps } from "@xmachines/play-actor";
|
|
131
|
+
* import type { DefineRegistryResult } from "@json-render/react";
|
|
132
|
+
*
|
|
133
|
+
* interface ActorProviderProps extends BaseActorProviderProps<DefineRegistryResult> {
|
|
134
|
+
* fallback?: React.ReactNode;
|
|
135
|
+
* children: React.ReactNode;
|
|
136
|
+
* }
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
export interface BaseActorProviderProps<TRegistry extends {
|
|
140
|
+
registry: object;
|
|
141
|
+
handlers: (...args: never[]) => unknown;
|
|
142
|
+
}> {
|
|
143
|
+
/** Actor instance with currentView signal (requires Viewable capability). */
|
|
144
|
+
actor: AbstractActor<AnyActorLogic> & Viewable;
|
|
145
|
+
/** Full result from defineRegistry() — contains the component registry and action handlers factory. */
|
|
146
|
+
registryResult: TRegistry;
|
|
147
|
+
/**
|
|
148
|
+
* Optional external StateStore (controlled mode).
|
|
149
|
+
* When provided, spec.state is ignored and this store is the single source of truth.
|
|
150
|
+
* When omitted, a fresh @xstate/store atom is created per view transition from spec.state.
|
|
151
|
+
*/
|
|
152
|
+
store?: StateStore;
|
|
153
|
+
/**
|
|
154
|
+
* Called when an individual catalog component throws during render.
|
|
155
|
+
* Takes precedence over any onRenderError set via defineRegistry.
|
|
156
|
+
*/
|
|
157
|
+
onRenderError?: RenderErrorHandler;
|
|
119
158
|
}
|
|
120
159
|
/**
|
|
121
160
|
* Abstract base class for Play Architecture actors.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"abstract-actor.d.ts","sourceRoot":"","sources":["../src/abstract-actor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,KAAK,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"abstract-actor.d.ts","sourceRoot":"","sources":["../src/abstract-actor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,KAAK,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAE7F;;GAEG;AACH,MAAM,WAAW,QAAQ;IACxB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACtD,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,QAAS,SAAQ,IAAI;IACrC;;;;;;OAMG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,SAAS,CAAC,QAAQ,SAAS,MAAM,EAChD,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,GAAG;IACtC,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAE,CAAC;CAC7D,GACC,QAAQ,CAEV;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,QAAQ;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;CACpD;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,oBAAoB,CAAC,SAAS,SAAS,MAAM;IAC7D,sCAAsC;IACtC,IAAI,EAAE,QAAQ,CAAC;IACf,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACxC,uDAAuD;IACvD,QAAQ,EAAE,SAAS,CAAC;IACpB,gHAAgH;IAChH,KAAK,EAAE,UAAU,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,sBAAsB,CACtC,SAAS,SAAS;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAA;CAAE;IAE/E,6EAA6E;IAC7E,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC,GAAG,QAAQ,CAAC;IAC/C,uGAAuG;IACvG,cAAc,EAAE,SAAS,CAAC;IAC1B;;;;OAIG;IACH,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB;;;OAGG;IACH,aAAa,CAAC,EAAE,kBAAkB,CAAC;CACnC;AAED;;;;;;;;;GASG;AACH,8BAAsB,aAAa,CAClC,MAAM,SAAS,aAAa,EAC5B,MAAM,SAAS,WAAW,GAAG,WAAW,CACvC,SAAQ,KAAK,CAAC,MAAM,CAAC;IACtB;;;;;OAKG;IACH,SAAgB,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAE7C;;;;OAIG;aACsB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;CAClD"}
|
package/dist/abstract-actor.js
CHANGED
|
@@ -37,15 +37,12 @@ import { Actor } from "xstate";
|
|
|
37
37
|
* }
|
|
38
38
|
*
|
|
39
39
|
* meta: {
|
|
40
|
-
* view: {
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* elements: { root: { type: "Dashboard", props: {}, children: [] } },
|
|
47
|
-
* }),
|
|
48
|
-
* },
|
|
40
|
+
* view: typedSpec<DashboardCtx>({
|
|
41
|
+
* root: "root",
|
|
42
|
+
* contextProps: ["username"], // ✓ key of DashboardCtx
|
|
43
|
+
* // contextProps: ["usernaem"], // ✗ compile error
|
|
44
|
+
* elements: { root: { type: "Dashboard", props: {}, children: [] } },
|
|
45
|
+
* }),
|
|
49
46
|
* }
|
|
50
47
|
* ```
|
|
51
48
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"abstract-actor.js","sourceRoot":"","sources":["../src/abstract-actor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,KAAK,EAAwC,MAAM,QAAQ,CAAC;AAkCrE
|
|
1
|
+
{"version":3,"file":"abstract-actor.js","sourceRoot":"","sources":["../src/abstract-actor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,KAAK,EAAwC,MAAM,QAAQ,CAAC;AAkCrE;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,SAAS,CACxB,IAEC;IAED,OAAO,IAAgB,CAAC;AACzB,CAAC;AAiFD;;;;;;;;;GASG;AACH,MAAM,OAAgB,aAGpB,SAAQ,KAAa;CAetB"}
|
package/dist/index.d.ts
CHANGED
|
@@ -15,5 +15,5 @@
|
|
|
15
15
|
* @packageDocumentation
|
|
16
16
|
* @see [Play RFC](../../docs/rfc/play.md)
|
|
17
17
|
*/
|
|
18
|
-
export { AbstractActor, typedSpec, type Routable, type Viewable, type
|
|
18
|
+
export { AbstractActor, typedSpec, type Routable, type Viewable, type PlaySpec, type BaseActorProviderProps, type BaseViewContextValue, } from "./abstract-actor.js";
|
|
19
19
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EACN,aAAa,EACb,SAAS,EACT,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EACN,aAAa,EACb,SAAS,EACT,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,GACzB,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EACN,aAAa,EACb,SAAS,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EACN,aAAa,EACb,SAAS,GAMT,MAAM,qBAAqB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xmachines/play-actor",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.34",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Abstract Actor base class for XMachines Play Architecture",
|
|
6
6
|
"keywords": [
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
},
|
|
31
31
|
"scripts": {
|
|
32
32
|
"build": "tsc --build",
|
|
33
|
-
"clean": "rm -rf dist *.tsbuildinfo coverage",
|
|
33
|
+
"clean": "rm -rf dist *.tsbuildinfo coverage node_modules/.svelte2tsx-*",
|
|
34
34
|
"test": "vitest",
|
|
35
35
|
"lint": "oxlint .",
|
|
36
36
|
"lint:fix": "oxlint --fix .",
|
|
@@ -43,15 +43,15 @@
|
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@types/node": "^25.6.0",
|
|
46
|
-
"@xmachines/shared": "1.0.0-beta.
|
|
46
|
+
"@xmachines/shared": "1.0.0-beta.34",
|
|
47
47
|
"oxfmt": "^0.45.0",
|
|
48
48
|
"oxlint": "^1.60.0",
|
|
49
49
|
"vitest": "^4.1.4",
|
|
50
50
|
"xstate": "^5.30.0"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
|
-
"@xmachines/play": "1.0.0-beta.
|
|
54
|
-
"@xmachines/play-signals": "1.0.0-beta.
|
|
53
|
+
"@xmachines/play": "1.0.0-beta.34",
|
|
54
|
+
"@xmachines/play-signals": "1.0.0-beta.34",
|
|
55
55
|
"xstate": "^5.30.0"
|
|
56
56
|
},
|
|
57
57
|
"engines": {
|