@xmachines/play-actor 1.0.0-beta.2 → 1.0.0-beta.20
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 +42 -43
- package/dist/abstract-actor.d.ts +93 -27
- package/dist/abstract-actor.d.ts.map +1 -1
- package/dist/abstract-actor.js +13 -9
- package/dist/abstract-actor.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +18 -12
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ Foundation for all actor implementations, enforcing XState compatibility and rea
|
|
|
8
8
|
|
|
9
9
|
`@xmachines/play-actor` provides `AbstractActor`, a base class that extends XState's `Actor` while enforcing the Play Architecture's signal protocol. It maintains XState ecosystem compatibility (inspection tools, devtools) while exposing reactive signals for infrastructure layer communication.
|
|
10
10
|
|
|
11
|
-
Per [
|
|
11
|
+
Per [Play RFC](../docs/rfc/play.md), this package implements:
|
|
12
12
|
|
|
13
13
|
- **Actor Authority (INV-01):** Actor is sole source of truth for state transitions
|
|
14
14
|
- **Signal-Only Reactivity (INV-05):** Infrastructure observes via TC39 Signals, never directly queries
|
|
@@ -28,10 +28,11 @@ npm install @xmachines/play-actor
|
|
|
28
28
|
- `AbstractActor`
|
|
29
29
|
- `Routable` (type)
|
|
30
30
|
- `Viewable` (type)
|
|
31
|
+
- `ViewMetadata` (type)
|
|
31
32
|
|
|
32
33
|
**Peer dependencies:**
|
|
33
34
|
|
|
34
|
-
- `xstate` ^5.0.0
|
|
35
|
+
- `xstate` ^5.0.0 — State machine runtime (XState compatibility)
|
|
35
36
|
- `@xmachines/play-signals` - TC39 Signals primitives
|
|
36
37
|
- `@xmachines/play` - Protocol types (PlayEvent, etc.)
|
|
37
38
|
|
|
@@ -43,7 +44,7 @@ npm install @xmachines/play-actor
|
|
|
43
44
|
import { definePlayer } from "@xmachines/play-xstate";
|
|
44
45
|
|
|
45
46
|
// definePlayer returns PlayerActor (extends AbstractActor)
|
|
46
|
-
const createPlayer = definePlayer({ machine
|
|
47
|
+
const createPlayer = definePlayer({ machine });
|
|
47
48
|
const actor = createPlayer();
|
|
48
49
|
actor.start();
|
|
49
50
|
|
|
@@ -61,69 +62,64 @@ Abstract base class defining signal protocol:
|
|
|
61
62
|
|
|
62
63
|
**Abstract Properties (must implement):**
|
|
63
64
|
|
|
64
|
-
- `state: Signal.State<
|
|
65
|
+
- `state: Signal.State<unknown>` - Reactive snapshot of current state
|
|
66
|
+
|
|
67
|
+
**Optional capability interfaces:**
|
|
68
|
+
|
|
69
|
+
Implement `Routable` to add routing support:
|
|
70
|
+
|
|
65
71
|
- `currentRoute: Signal.Computed<string | null>` - Derived navigation path
|
|
66
|
-
|
|
67
|
-
|
|
72
|
+
|
|
73
|
+
Implement `Viewable` to add view rendering support:
|
|
74
|
+
|
|
75
|
+
- `currentView: Signal.State<ViewMetadata | null>` - Current view spec (updated on every state transition). `ViewMetadata` has the shape `{ component: string; spec: Spec }` where `spec` is a `@json-render/core` spec object driving the renderer.
|
|
68
76
|
|
|
69
77
|
**Inherited from XState Actor:**
|
|
70
78
|
|
|
71
|
-
- `send(event
|
|
79
|
+
- `send(event): void` - Send event to actor
|
|
72
80
|
- `start(): void` - Start the actor
|
|
73
81
|
- `stop(): void` - Stop the actor
|
|
74
|
-
- `getSnapshot()
|
|
82
|
+
- `getSnapshot()` - Get current XState snapshot (typed as `SnapshotFrom<TLogic>`)
|
|
75
83
|
|
|
76
84
|
**Example implementation pattern:**
|
|
77
85
|
|
|
78
86
|
```typescript
|
|
79
|
-
import {
|
|
87
|
+
import {
|
|
88
|
+
AbstractActor,
|
|
89
|
+
type Routable,
|
|
90
|
+
type Viewable,
|
|
91
|
+
type ViewMetadata,
|
|
92
|
+
} from "@xmachines/play-actor";
|
|
80
93
|
import { Signal } from "@xmachines/play-signals";
|
|
94
|
+
import type { AnyActorLogic, AnyMachineSnapshot } from "xstate";
|
|
81
95
|
|
|
82
|
-
class PlayerActor<TLogic extends AnyActorLogic>
|
|
83
|
-
|
|
84
|
-
|
|
96
|
+
class PlayerActor<TLogic extends AnyActorLogic>
|
|
97
|
+
extends AbstractActor<TLogic>
|
|
98
|
+
implements Routable, Viewable
|
|
99
|
+
{
|
|
100
|
+
// Required: reactive state snapshot
|
|
101
|
+
state = new Signal.State<AnyMachineSnapshot>(this.getSnapshot() as AnyMachineSnapshot);
|
|
85
102
|
|
|
103
|
+
// Routable: derived navigation path
|
|
86
104
|
currentRoute = new Signal.Computed(() => {
|
|
87
|
-
|
|
88
|
-
return deriveRoute(snapshot);
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
currentView = new Signal.Computed(() => {
|
|
92
|
-
const snapshot = this.state.get();
|
|
93
|
-
return snapshot.meta?.view ?? null;
|
|
105
|
+
return deriveRoute(this.state.get());
|
|
94
106
|
});
|
|
95
107
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
// Internal XState actor
|
|
99
|
-
private internalActor: Actor<TLogic>;
|
|
108
|
+
// Viewable: current view spec — Signal.State, updated on every state transition
|
|
109
|
+
currentView = new Signal.State<ViewMetadata | null>(null);
|
|
100
110
|
|
|
101
|
-
constructor(logic: TLogic
|
|
111
|
+
constructor(logic: TLogic) {
|
|
102
112
|
super(logic);
|
|
103
|
-
this.internalActor = createActor(logic);
|
|
104
113
|
|
|
105
|
-
// Subscribe to XState transitions
|
|
106
|
-
this.
|
|
107
|
-
this.state.set(snapshot);
|
|
114
|
+
// Subscribe to XState transitions and update signals
|
|
115
|
+
this.subscribe((snapshot) => {
|
|
116
|
+
this.state.set(snapshot as AnyMachineSnapshot);
|
|
117
|
+
// Derive currentView from snapshot meta and update the signal...
|
|
108
118
|
});
|
|
109
119
|
}
|
|
110
|
-
|
|
111
|
-
override start(): void {
|
|
112
|
-
this.internalActor.start();
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
override stop(): void {
|
|
116
|
-
this.internalActor.stop();
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
override send(event: PlayEvent): void {
|
|
120
|
-
this.internalActor.send(event as any);
|
|
121
|
-
}
|
|
122
120
|
}
|
|
123
121
|
```
|
|
124
122
|
|
|
125
|
-
**Complete API:** See [API Documentation](../../docs/api/@xmachines/play-actor)
|
|
126
|
-
|
|
127
123
|
## Examples
|
|
128
124
|
|
|
129
125
|
### Infrastructure Observing Signals
|
|
@@ -215,4 +211,7 @@ This base class enforces three architectural invariants:
|
|
|
215
211
|
|
|
216
212
|
## License
|
|
217
213
|
|
|
218
|
-
|
|
214
|
+
Copyright (c) 2016 [Mikael Karon](mailto:mikael@karon.se). All rights reserved.
|
|
215
|
+
|
|
216
|
+
This work is licensed under the terms of the MIT license.
|
|
217
|
+
For a copy, see <https://opensource.org/licenses/MIT>.
|
package/dist/abstract-actor.d.ts
CHANGED
|
@@ -16,8 +16,9 @@
|
|
|
16
16
|
*
|
|
17
17
|
* @packageDocumentation
|
|
18
18
|
*/
|
|
19
|
-
import { Actor, type AnyActorLogic } from "xstate";
|
|
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
22
|
/**
|
|
22
23
|
* Optional capability: Routing support
|
|
23
24
|
*
|
|
@@ -54,6 +55,18 @@ export interface Routable {
|
|
|
54
55
|
* ```
|
|
55
56
|
*/
|
|
56
57
|
readonly currentRoute: Signal.Computed<string | null>;
|
|
58
|
+
/**
|
|
59
|
+
* The route derived from the machine's **initial** state — fixed at construction
|
|
60
|
+
* and never changes, even after `start()` with a restored snapshot.
|
|
61
|
+
*
|
|
62
|
+
* Router bridges use this to distinguish a deep-link (browser URL differs from
|
|
63
|
+
* the initial route because the user navigated there) from a restore (browser is
|
|
64
|
+
* at the machine's default starting URL while the actor was restored to a
|
|
65
|
+
* different route from a snapshot).
|
|
66
|
+
*
|
|
67
|
+
* `null` when the machine's initial state has no `meta.route`.
|
|
68
|
+
*/
|
|
69
|
+
readonly initialRoute: string | null;
|
|
57
70
|
}
|
|
58
71
|
/**
|
|
59
72
|
* Optional capability: View rendering support
|
|
@@ -65,21 +78,75 @@ export interface Routable {
|
|
|
65
78
|
* ```typescript
|
|
66
79
|
* class MyActor extends AbstractActor implements Viewable {
|
|
67
80
|
* currentView = new Signal.State(null);
|
|
68
|
-
* catalog = { HomePage: HomeComponent };
|
|
69
81
|
* }
|
|
70
82
|
*
|
|
71
83
|
* // Renderer requires Viewable
|
|
72
84
|
* function renderView<T extends AbstractActor & Viewable>(actor: T) {
|
|
73
85
|
* const view = actor.currentView.get();
|
|
74
|
-
*
|
|
86
|
+
* // view.component is the component name; view.spec is the json-render spec
|
|
75
87
|
* }
|
|
76
88
|
* ```
|
|
77
89
|
*/
|
|
90
|
+
/**
|
|
91
|
+
* XMachines extension of `@json-render/core` `Spec`.
|
|
92
|
+
*
|
|
93
|
+
* Adds `contextProps` — an explicit allowlist of machine context fields that
|
|
94
|
+
* `deriveCurrentView` merges into element props as low-priority slots. Only
|
|
95
|
+
* fields named here are ever exposed to components; nothing leaks from context
|
|
96
|
+
* without an opt-in declaration.
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```ts
|
|
100
|
+
* spec: {
|
|
101
|
+
* root: "root",
|
|
102
|
+
* contextProps: ["username"], // expose context.username as a prop slot
|
|
103
|
+
* elements: {
|
|
104
|
+
* root: { type: "Dashboard", props: { username: undefined }, children: [] },
|
|
105
|
+
* },
|
|
106
|
+
* }
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
export interface PlaySpec extends Spec {
|
|
110
|
+
/**
|
|
111
|
+
* Explicit allowlist of machine context field names to expose as prop slots.
|
|
112
|
+
*
|
|
113
|
+
* Each named field is merged into every spec element's `props` at view derivation
|
|
114
|
+
* time, filling any slot whose current value is `undefined`. `null` and
|
|
115
|
+
* `undefined` context values are skipped. URL route params (from `context.routeParams`)
|
|
116
|
+
* take priority over `contextProps` values; explicit non-`undefined` spec props
|
|
117
|
+
* always take priority over both.
|
|
118
|
+
*/
|
|
119
|
+
contextProps?: string[];
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* View metadata for rendering
|
|
123
|
+
*
|
|
124
|
+
* Describes the component to be rendered and the json-render Spec to use.
|
|
125
|
+
* Used by PlayRenderer to dynamically render UI based on actor state.
|
|
126
|
+
*/
|
|
127
|
+
export interface ViewMetadata {
|
|
128
|
+
/** Root element type name (for diagnostics and component resolution) */
|
|
129
|
+
component: string;
|
|
130
|
+
/**
|
|
131
|
+
* XMachines view spec — extends `@json-render/core` Spec with `contextProps`
|
|
132
|
+
* for explicit context field exposure.
|
|
133
|
+
*/
|
|
134
|
+
spec: PlaySpec;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Actor capability for exposing renderable view state.
|
|
138
|
+
*
|
|
139
|
+
* `Viewable` marks actors that publish a `currentView` signal.
|
|
140
|
+
* Renderers such as `PlayRenderer` consume this contract to resolve the
|
|
141
|
+
* current view description into concrete UI without embedding view logic inside the
|
|
142
|
+
* framework adapter. Component lookup is handled by the json-render registry
|
|
143
|
+
* passed to PlayRenderer, not stored on the actor.
|
|
144
|
+
*/
|
|
78
145
|
export interface Viewable {
|
|
79
146
|
/**
|
|
80
147
|
* Current view signal
|
|
81
148
|
*
|
|
82
|
-
* State signal containing
|
|
149
|
+
* State signal containing view.component and view.spec from meta.view. Infrastructure renders view.
|
|
83
150
|
*
|
|
84
151
|
* Invariant: Logic-Driven UI - View structure is defined by business logic, not JSX.
|
|
85
152
|
*
|
|
@@ -87,19 +154,12 @@ export interface Viewable {
|
|
|
87
154
|
* ```typescript
|
|
88
155
|
* const watcher = new Signal.subtle.Watcher(() => {
|
|
89
156
|
* const view = actor.currentView.get();
|
|
90
|
-
* console.log('View changed:', view);
|
|
157
|
+
* console.log('View changed:', view.component, view.spec);
|
|
91
158
|
* });
|
|
92
159
|
* watcher.watch(actor.currentView);
|
|
93
160
|
* ```
|
|
94
161
|
*/
|
|
95
|
-
readonly currentView: Signal.State<
|
|
96
|
-
/**
|
|
97
|
-
* Component catalog for view resolution
|
|
98
|
-
*
|
|
99
|
-
* Maps component names to actual component implementations.
|
|
100
|
-
* Used by renderers to resolve view.component to actual UI components.
|
|
101
|
-
*/
|
|
102
|
-
readonly catalog: any;
|
|
162
|
+
readonly currentView: Signal.State<ViewMetadata | null>;
|
|
103
163
|
}
|
|
104
164
|
/**
|
|
105
165
|
* Abstract base class for Play Architecture actors.
|
|
@@ -118,50 +178,58 @@ export interface Viewable {
|
|
|
118
178
|
* Concrete implementations created by @xmachines/play-xstate adapter.
|
|
119
179
|
*
|
|
120
180
|
* @typeParam TLogic - XState actor logic type (maintains type safety)
|
|
181
|
+
* @typeParam TEvent - Event type union that this actor's send() accepts.
|
|
182
|
+
* Defaults to `EventObject` (`{ type: string }`) for backward compatibility.
|
|
183
|
+
* Use `EventFromLogic<TMachine>` from xstate to infer the exact event union
|
|
184
|
+
* from a state machine (e.g., in `PlayerActor`).
|
|
121
185
|
*
|
|
122
186
|
* Invariant: Actor Authority - Actor is the sole source of truth for state transitions.
|
|
123
187
|
* Invariant: Signal-Only Reactivity - Infrastructure observes via TC39 Signals.
|
|
124
188
|
* Invariant: Passive Infrastructure - Infrastructure reflects, never decides.
|
|
125
189
|
*
|
|
126
190
|
* @example
|
|
127
|
-
* Simple actor (no routing, no view)
|
|
191
|
+
* Simple actor (no routing, no view) - single type param, backward compat
|
|
128
192
|
* ```typescript
|
|
129
|
-
* class SimpleActor extends AbstractActor<
|
|
193
|
+
* class SimpleActor extends AbstractActor<AnyActorLogic> {
|
|
130
194
|
* state = new Signal.State({...});
|
|
131
195
|
* send(event) { ... }
|
|
132
196
|
* }
|
|
133
197
|
* ```
|
|
134
198
|
*
|
|
135
199
|
* @example
|
|
136
|
-
*
|
|
200
|
+
* Typed event actor - two type params
|
|
137
201
|
* ```typescript
|
|
138
|
-
*
|
|
202
|
+
* type AuthEvent = { type: "auth.login"; username: string } | { type: "auth.logout" };
|
|
203
|
+
* class AuthActor extends AbstractActor<AnyActorLogic, AuthEvent> {
|
|
139
204
|
* state = new Signal.State({...});
|
|
140
|
-
*
|
|
141
|
-
* send(event) { ... }
|
|
205
|
+
* send(event: AuthEvent) { ... }
|
|
142
206
|
* }
|
|
143
207
|
* ```
|
|
144
208
|
*
|
|
145
209
|
* @example
|
|
146
210
|
* Full-featured actor (routing + view)
|
|
147
211
|
* ```typescript
|
|
148
|
-
* class PlayerActor extends AbstractActor<
|
|
212
|
+
* class PlayerActor extends AbstractActor<AnyActorLogic, EventFromLogic<TMachine>>
|
|
213
|
+
* implements Routable, Viewable {
|
|
149
214
|
* state = new Signal.State({...});
|
|
150
215
|
* currentRoute = new Signal.Computed(() => deriveRoute(this.state.get()));
|
|
151
216
|
* currentView = new Signal.State(null);
|
|
152
|
-
* catalog = {};
|
|
153
217
|
* send(event) { ... }
|
|
154
218
|
* }
|
|
155
219
|
* ```
|
|
156
220
|
*
|
|
157
|
-
* @see
|
|
221
|
+
* @see [Play RFC](../../docs/rfc/play.md)
|
|
158
222
|
* @see {@link Routable} for routing capability
|
|
159
223
|
* @see {@link Viewable} for view rendering capability
|
|
160
224
|
*/
|
|
161
|
-
export declare abstract class AbstractActor<TLogic extends AnyActorLogic> extends Actor<TLogic> {
|
|
225
|
+
export declare abstract class AbstractActor<TLogic extends AnyActorLogic, TEvent extends EventObject = EventObject> extends Actor<TLogic> {
|
|
162
226
|
/**
|
|
163
227
|
* Reactive snapshot of current actor state.
|
|
164
228
|
*
|
|
229
|
+
* Typed as `Signal.State<unknown>` at the abstract level; concrete implementations
|
|
230
|
+
* narrow this to the actual snapshot type (e.g., `Signal.State<AnyMachineSnapshot>`
|
|
231
|
+
* in `@xmachines/play-xstate`'s `PlayerActor`).
|
|
232
|
+
*
|
|
165
233
|
* Infrastructure observes this signal to react to state changes without
|
|
166
234
|
* directly coupling to the Actor's internal state machine implementation.
|
|
167
235
|
*
|
|
@@ -174,7 +242,7 @@ export declare abstract class AbstractActor<TLogic extends AnyActorLogic> extend
|
|
|
174
242
|
* watcher.watch(actor.state);
|
|
175
243
|
* ```
|
|
176
244
|
*/
|
|
177
|
-
abstract state: Signal.State<
|
|
245
|
+
abstract state: Signal.State<unknown>;
|
|
178
246
|
/**
|
|
179
247
|
* Send event to Actor
|
|
180
248
|
*
|
|
@@ -197,8 +265,6 @@ export declare abstract class AbstractActor<TLogic extends AnyActorLogic> extend
|
|
|
197
265
|
* Accepts any event object with a type property. Core events (PlayEvent) are in
|
|
198
266
|
* @xmachines/play, routing events (PlayRouteEvent) are in @xmachines/play-router.
|
|
199
267
|
*/
|
|
200
|
-
abstract send(event:
|
|
201
|
-
readonly type: string;
|
|
202
|
-
} & Record<string, any>): void;
|
|
268
|
+
abstract send(event: TEvent): void;
|
|
203
269
|
}
|
|
204
270
|
//# sourceMappingURL=abstract-actor.d.ts.map
|
|
@@ -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,MAAM,QAAQ,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,MAAM,mBAAmB,CAAC;AAE9C;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,QAAQ;IACxB;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACtD;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,QAAS,SAAQ,IAAI;IACrC;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC5B,wEAAwE;IACxE,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,IAAI,EAAE,QAAQ,CAAC;CACf;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,QAAQ;IACxB;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;CACxD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,8BAAsB,aAAa,CAClC,MAAM,SAAS,aAAa,EAC5B,MAAM,SAAS,WAAW,GAAG,WAAW,CACvC,SAAQ,KAAK,CAAC,MAAM,CAAC;IACtB;;;;;;;;;;;;;;;;;;OAkBG;IACH,SAAgB,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAE7C;;;;;;;;;;;;;;;;;;;;;OAqBG;aACsB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;CAClD"}
|
package/dist/abstract-actor.js
CHANGED
|
@@ -34,43 +34,47 @@ import { Actor } from "xstate";
|
|
|
34
34
|
* Concrete implementations created by @xmachines/play-xstate adapter.
|
|
35
35
|
*
|
|
36
36
|
* @typeParam TLogic - XState actor logic type (maintains type safety)
|
|
37
|
+
* @typeParam TEvent - Event type union that this actor's send() accepts.
|
|
38
|
+
* Defaults to `EventObject` (`{ type: string }`) for backward compatibility.
|
|
39
|
+
* Use `EventFromLogic<TMachine>` from xstate to infer the exact event union
|
|
40
|
+
* from a state machine (e.g., in `PlayerActor`).
|
|
37
41
|
*
|
|
38
42
|
* Invariant: Actor Authority - Actor is the sole source of truth for state transitions.
|
|
39
43
|
* Invariant: Signal-Only Reactivity - Infrastructure observes via TC39 Signals.
|
|
40
44
|
* Invariant: Passive Infrastructure - Infrastructure reflects, never decides.
|
|
41
45
|
*
|
|
42
46
|
* @example
|
|
43
|
-
* Simple actor (no routing, no view)
|
|
47
|
+
* Simple actor (no routing, no view) - single type param, backward compat
|
|
44
48
|
* ```typescript
|
|
45
|
-
* class SimpleActor extends AbstractActor<
|
|
49
|
+
* class SimpleActor extends AbstractActor<AnyActorLogic> {
|
|
46
50
|
* state = new Signal.State({...});
|
|
47
51
|
* send(event) { ... }
|
|
48
52
|
* }
|
|
49
53
|
* ```
|
|
50
54
|
*
|
|
51
55
|
* @example
|
|
52
|
-
*
|
|
56
|
+
* Typed event actor - two type params
|
|
53
57
|
* ```typescript
|
|
54
|
-
*
|
|
58
|
+
* type AuthEvent = { type: "auth.login"; username: string } | { type: "auth.logout" };
|
|
59
|
+
* class AuthActor extends AbstractActor<AnyActorLogic, AuthEvent> {
|
|
55
60
|
* state = new Signal.State({...});
|
|
56
|
-
*
|
|
57
|
-
* send(event) { ... }
|
|
61
|
+
* send(event: AuthEvent) { ... }
|
|
58
62
|
* }
|
|
59
63
|
* ```
|
|
60
64
|
*
|
|
61
65
|
* @example
|
|
62
66
|
* Full-featured actor (routing + view)
|
|
63
67
|
* ```typescript
|
|
64
|
-
* class PlayerActor extends AbstractActor<
|
|
68
|
+
* class PlayerActor extends AbstractActor<AnyActorLogic, EventFromLogic<TMachine>>
|
|
69
|
+
* implements Routable, Viewable {
|
|
65
70
|
* state = new Signal.State({...});
|
|
66
71
|
* currentRoute = new Signal.Computed(() => deriveRoute(this.state.get()));
|
|
67
72
|
* currentView = new Signal.State(null);
|
|
68
|
-
* catalog = {};
|
|
69
73
|
* send(event) { ... }
|
|
70
74
|
* }
|
|
71
75
|
* ```
|
|
72
76
|
*
|
|
73
|
-
* @see
|
|
77
|
+
* @see [Play RFC](../../docs/rfc/play.md)
|
|
74
78
|
* @see {@link Routable} for routing capability
|
|
75
79
|
* @see {@link Viewable} for view rendering capability
|
|
76
80
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"abstract-actor.js","sourceRoot":"","sources":["../src/abstract-actor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,KAAK,
|
|
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;AAsJrE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,MAAM,OAAgB,aAGpB,SAAQ,KAAa;CA6CtB"}
|
package/dist/index.d.ts
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* reactive signals for Infrastructure layer communication.
|
|
14
14
|
*
|
|
15
15
|
* @packageDocumentation
|
|
16
|
-
* @see
|
|
16
|
+
* @see [Play RFC](../../docs/rfc/play.md)
|
|
17
17
|
*/
|
|
18
|
-
export { AbstractActor, type Routable, type Viewable } from "./abstract-actor.js";
|
|
18
|
+
export { AbstractActor, type Routable, type Viewable, type ViewMetadata, type PlaySpec, } 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,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EACN,aAAa,EACb,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,QAAQ,GACb,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* reactive signals for Infrastructure layer communication.
|
|
14
14
|
*
|
|
15
15
|
* @packageDocumentation
|
|
16
|
-
* @see
|
|
16
|
+
* @see [Play RFC](../../docs/rfc/play.md)
|
|
17
17
|
*/
|
|
18
|
-
export { AbstractActor } from "./abstract-actor.js";
|
|
18
|
+
export { AbstractActor, } from "./abstract-actor.js";
|
|
19
19
|
//# sourceMappingURL=index.js.map
|
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,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EACN,aAAa,GAKb,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.20",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Abstract Actor base class for XMachines Play Architecture",
|
|
6
6
|
"keywords": [
|
|
@@ -20,34 +20,40 @@
|
|
|
20
20
|
"type": "module",
|
|
21
21
|
"exports": {
|
|
22
22
|
".": {
|
|
23
|
+
"source": "./src/index.ts",
|
|
23
24
|
"types": "./dist/index.d.ts",
|
|
24
25
|
"import": "./dist/index.js"
|
|
25
26
|
}
|
|
26
27
|
},
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
27
31
|
"scripts": {
|
|
28
32
|
"build": "tsc --build",
|
|
29
|
-
"clean": "rm -rf dist *.tsbuildinfo",
|
|
30
|
-
"
|
|
31
|
-
"test": "vitest run",
|
|
33
|
+
"clean": "rm -rf dist *.tsbuildinfo coverage",
|
|
34
|
+
"test": "vitest",
|
|
32
35
|
"lint": "oxlint .",
|
|
33
36
|
"lint:fix": "oxlint --fix .",
|
|
34
37
|
"format": "oxfmt .",
|
|
35
38
|
"format:check": "oxfmt --check .",
|
|
36
39
|
"prepublishOnly": "npm run build"
|
|
37
40
|
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@json-render/core": "^0.16.0"
|
|
43
|
+
},
|
|
38
44
|
"devDependencies": {
|
|
39
|
-
"@types/node": "^25.
|
|
40
|
-
"
|
|
45
|
+
"@types/node": "^25.5.0",
|
|
46
|
+
"@xmachines/shared": "1.0.0-beta.20",
|
|
47
|
+
"vitest": "^4.1.2",
|
|
48
|
+
"xstate": "^5.30.0"
|
|
41
49
|
},
|
|
42
50
|
"peerDependencies": {
|
|
43
|
-
"@xmachines/play": "1.0.0-beta.
|
|
44
|
-
"@xmachines/play-signals": "1.0.0-beta.
|
|
45
|
-
"xstate": "^5.
|
|
51
|
+
"@xmachines/play": "1.0.0-beta.20",
|
|
52
|
+
"@xmachines/play-signals": "1.0.0-beta.20",
|
|
53
|
+
"xstate": "^5.30.0"
|
|
46
54
|
},
|
|
47
55
|
"engines": {
|
|
48
56
|
"node": ">=22.0.0"
|
|
49
57
|
},
|
|
50
|
-
"
|
|
51
|
-
"access": "public"
|
|
52
|
-
}
|
|
58
|
+
"_devDependencies_note": "xstate appears in both peerDependencies and devDependencies intentionally. devDependencies provides workspace resolution for local builds and tests. peerDependencies declares the consumer version constraint. Both are pinned to ^5.30.0 to prevent drift."
|
|
53
59
|
}
|