@xmachines/play-actor 2.0.0-alpha.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,10 +1,8 @@
1
- <!-- generated-by: gsd-doc-writer -->
2
-
3
1
  # @xmachines/play-actor
4
2
 
5
3
  Abstract Actor base class for XMachines Play Architecture.
6
4
 
7
- Part of the [xmachines-js monorepo](../../README.md).
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Version](https://img.shields.io/badge/version-2.1.0-blue)](https://www.npmjs.com/package/@xmachines/play-actor)
8
6
 
9
7
  ## Installation
10
8
 
@@ -12,90 +10,101 @@ Part of the [xmachines-js monorepo](../../README.md).
12
10
  pnpm add @xmachines/play-actor
13
11
  ```
14
12
 
15
- **Peer dependencies** install alongside the package:
13
+ **Peer dependencies.** Install them with the package:
16
14
 
17
15
  ```bash
18
- pnpm add xstate @xmachines/play @xmachines/play-signals
16
+ pnpm add xstate @xmachines/play @xmachines/play-signals @xmachines/json-render-core
19
17
  ```
20
18
 
21
19
  ## Overview
22
20
 
23
- `@xmachines/play-actor` provides `AbstractActor`, a minimal base class that extends the XState `Actor` class while enforcing the Play Architecture's **signal protocol** (RFC section 5.3). It exposes reactive TC39 Signals for infrastructure-layer communication while preserving full XState ecosystem compatibility (devtools, inspection).
21
+ `@xmachines/play-actor` gives you `AbstractActor`, a minimal base class. The class extends the XState `Actor` class, and it enforces the **signal protocol** of the Play Architecture (RFC section 5.3). It exposes reactive TC39 Signals for the infrastructure layer. It also keeps the complete compatibility with the XState ecosystem, which includes the devtools and the inspection.
24
22
 
25
- The core protocol is deliberately minimal:
23
+ The core protocol is small on purpose:
26
24
 
27
25
  | Property | Type | Description |
28
26
  | -------- | ------------------------- | ---------------------------------------- |
29
27
  | `state` | `Signal.State<unknown>` | Reactive snapshot of current actor state |
30
28
  | `send` | `(event: TEvent) => void` | Event dispatch method |
31
29
 
32
- Optional capabilities are declared as separate interfaces — a concrete actor opts in only to what it needs:
30
+ Separate interfaces declare the optional capabilities. A concrete actor implements only the interfaces that it needs:
33
31
 
34
32
  | Interface | Property | Description |
35
33
  | ---------- | ----------------------------------------------- | ------------------------------------- |
36
34
  | `Routable` | `currentRoute: Signal.Computed<string \| null>` | Current route path derived from state |
37
- | `Routable` | `initialRoute: string \| null` | Route the actor starts on |
35
+ | `Routable` | `initialRoute: string \| null` | The route where the actor starts |
38
36
  | `Viewable` | `currentView: Signal.State<PlaySpec \| null>` | Current JSON-render view spec |
39
37
 
40
- Concrete implementations are created by adapters such as [`@xmachines/play-xstate`](../play-xstate/README.md).
38
+ An adapter, such as [`@xmachines/play-xstate`](../play-xstate/README.md), makes the concrete implementations.
41
39
 
42
40
  ## API Summary
43
41
 
44
42
  ### `AbstractActor<TLogic, TEvent>`
45
43
 
46
- Abstract base class extending XState `Actor<TLogic>`.
44
+ The abstract base class extends the XState `Actor<TLogic>` class.
45
+
46
+ A subclass **is** the actor. Give the logic and its options to `super()`, so that one
47
+ instance holds the running machine. Reach the `send` method of XState through the
48
+ prototype. This class declares `send` as abstract for one reason only: to narrow the
49
+ event type. TypeScript forbids a `super` call to an abstract member.
47
50
 
48
51
  ```ts
49
52
  import { AbstractActor } from "@xmachines/play-actor";
50
53
  import { Signal } from "@xmachines/play-signals";
51
- import type { AnyActorLogic } from "xstate";
54
+ import { Actor, type ActorOptions, type AnyActorLogic } from "xstate";
52
55
 
53
56
  class MyActor extends AbstractActor<AnyActorLogic> {
54
57
  // Required: reactive state signal
55
- state = new Signal.State({});
58
+ state: Signal.State<unknown>;
59
+
60
+ constructor(logic: AnyActorLogic, options?: ActorOptions<AnyActorLogic>) {
61
+ super(logic, options);
62
+ this.state = new Signal.State(this.getSnapshot());
63
+ super.subscribe((snapshot) => this.state.set(snapshot));
64
+ }
56
65
 
57
66
  // Required: typed event dispatch
58
- send = (event: { type: string }) => {
59
- /* dispatch to XState */
60
- };
67
+ override send(event: { type: string }): void {
68
+ Actor.prototype.send.call(this, event);
69
+ }
61
70
  }
62
71
  ```
63
72
 
64
73
  With a typed event union:
65
74
 
66
75
  ```ts
76
+ // imports as in the previous example
67
77
  type AuthEvent = { type: "auth.login"; username: string } | { type: "auth.logout" };
68
78
 
69
79
  class AuthActor extends AbstractActor<AnyActorLogic, AuthEvent> {
70
80
  state = new Signal.State({ isAuthenticated: false, username: null });
71
81
 
72
- send = (event: AuthEvent) => {
73
- /* dispatch */
74
- };
82
+ override send(event: AuthEvent): void {
83
+ Actor.prototype.send.call(this, event);
84
+ }
75
85
  }
76
86
  ```
77
87
 
78
- ### `typedSpec<TContext>(spec)`
88
+ ### `typedSpec(spec)`
79
89
 
80
- Identity helper that constrains a `PlaySpec` object's `contextProps` to keys of a specific machine context type. This enables compile-time validation and IDE autocomplete without any runtime cost.
90
+ This identity helper gives a view-spec literal the type `PlaySpec` at the definition site. The
91
+ XState `meta` field has the type `Record<string, unknown>`. Therefore this helper is the place
92
+ where the spec shape receives the compile-time check and the IDE autocomplete. The helper has no
93
+ cost at run time.
81
94
 
82
95
  ```ts
83
96
  import { typedSpec } from "@xmachines/play-actor";
84
97
 
85
- interface DashboardCtx {
86
- username: string;
87
- params: Record<string, string>;
88
- query: Record<string, string>;
89
- }
90
-
91
98
  // In an XState machine meta block:
92
99
  meta: {
93
- view: typedSpec<DashboardCtx>({
100
+ view: typedSpec({
94
101
  root: "root",
95
- contextProps: ["username"], // ✓ key of DashboardCtx
96
- // contextProps: ["usernaem"], // ✗ compile error
97
102
  elements: {
98
- root: { type: "Dashboard", props: {}, children: [] },
103
+ root: {
104
+ type: "Dashboard",
105
+ props: { username: { $state: "/context/username" } },
106
+ children: [],
107
+ },
99
108
  },
100
109
  }),
101
110
  }
@@ -103,36 +112,76 @@ meta: {
103
112
 
104
113
  ### `PlaySpec`
105
114
 
106
- Extends `@xmachines/json-render-core`'s `Spec` with an optional `contextProps` field — an explicit allowlist of machine context fields that are merged into element props at view derivation time.
115
+ This type extends the `Spec` type of `@xmachines/json-render-core`. Each derived view receives
116
+ the complete machine context in its state store, under the read-only **`/context` subtree**. A
117
+ spec therefore reads the context through the ordinary `{ $state: "/context/…" }` grammar: in a
118
+ prop, in a `visible` condition, and in `repeat.statePath`.
119
+
120
+ `/context` is read-only by design. Nothing can write to it. The machine context changes through
121
+ an event only. A `$bindState` write or a `setState` write under `/context` throws an error, and
122
+ the error names the event to send. This is the model: the bindable ephemeral state is at the
123
+ root of the store, from `spec.state`; the domain state is in the machine, and it changes through
124
+ events that are meaningful and easy to inspect.
125
+
126
+ The path shows the origin of each value. `/context/params/username` comes from the URL.
127
+ `/context/username` belongs to the machine. One value can never hide the other.
128
+
129
+ The model projects everything, and this has two consequences. The first consequence is
130
+ **exposure**. The complete context is visible to the client in the view store, which includes a
131
+ debug panel, an inspector, and a validator. The context is a client-side value in each case, so
132
+ keep a secret out of it.
133
+
134
+ The second consequence is **emission granularity**. The emit gate compares the context field by
135
+ field, at the top level only. Therefore an event that changes any field emits the view again
136
+ with the same `viewKey`. A provider refreshes `/context` in the live store, and it does not seed
137
+ the store again. The component does not remount, and the ephemeral view state and the focus
138
+ stay. However, a new emission is still a render pass in the framework layer. Keep
139
+ high-frequency ephemeral data, such as a draft for each keystroke or a timer, in the view store
140
+ (`spec.state` with `$bindState`) or in a child actor. The domain state belongs in the context. A
141
+ keystroke does not.
107
142
 
108
143
  ```ts
109
144
  import type { PlaySpec } from "@xmachines/play-actor";
110
145
 
111
146
  const spec: PlaySpec = {
112
147
  root: "root",
113
- contextProps: ["username"], // only these keys are exposed to components
114
148
  elements: {
115
- root: { type: "Profile", props: { username: undefined }, children: [] },
149
+ root: {
150
+ type: "Profile",
151
+ props: { username: { $state: "/context/username" } },
152
+ children: [],
153
+ },
116
154
  },
117
155
  };
118
156
  ```
119
157
 
158
+ > Historical note: an earlier version had a `contextProps` field. At first the field drove an
159
+ > implicit prop-enrichment pass. That pass merged the allowlisted context fields and the URL
160
+ > params into the props of every element. We removed it, because it put values into components
161
+ > that never asked for them, and it let URL data from the user hide machine-owned state. The
162
+ > field was then a projection filter for a short time. We removed that filter too, because a
163
+ > limit on what a view can read added machinery without a real problem to solve. Always
164
+ > validate the **derived** view (`actor.currentView.get()`), not the raw `meta.view`. The
165
+ > `state` of the derived spec carries the projection, so a tool such as `validateSpec` sees a
166
+ > spec that is consistent with itself.
167
+
120
168
  ### `Routable`
121
169
 
122
170
  Interface for actors that support routing.
123
171
 
124
172
  ```ts
125
- import type { Routable } from "@xmachines/play-actor";
173
+ import { AbstractActor, type Routable } from "@xmachines/play-actor";
126
174
  import { Signal } from "@xmachines/play-signals";
175
+ import type { AnyActorLogic, EventObject } from "xstate";
127
176
 
128
177
  // Implement in a concrete actor (note: RoutableActor interface is exported from @xmachines/play-router):
129
178
  class MyRoutableActor extends AbstractActor<AnyActorLogic> implements Routable {
130
- state = new Signal.State({});
131
- currentRoute = new Signal.Computed(() => this.state.get().path ?? null);
179
+ state = new Signal.State<{ path?: string }>({});
180
+ currentRoute = new Signal.Computed<string | null>(() => this.state.get().path ?? null);
132
181
  initialRoute = "/";
133
- send = (event) => {
182
+ override send(event: EventObject): void {
134
183
  /* dispatch */
135
- };
184
+ }
136
185
  }
137
186
  ```
138
187
 
@@ -152,7 +201,7 @@ const viewable: Viewable = { currentView: signal };
152
201
 
153
202
  ### `BaseActorProviderProps<TRegistry>`
154
203
 
155
- Framework-agnostic base props shared by every `ActorProvider` implementation (React, Vue, Solid, Svelte). Framework renderer packages extend this interface.
204
+ The framework-agnostic base props. Every `ActorProvider` implementation shares them: React, Vue, Solid, and Svelte. Each framework renderer package extends this interface.
156
205
 
157
206
  ```ts
158
207
  import type { BaseActorProviderProps } from "@xmachines/play-actor";
@@ -166,7 +215,7 @@ interface ActorProviderProps extends BaseActorProviderProps<DefineRegistryResult
166
215
 
167
216
  ### `BaseViewContextValue<TRegistry>`
168
217
 
169
- Framework-agnostic base for every framework's `ViewContextValue`. Holds `spec`, `handlers`, `registry`, and `store` fields that are identical across React, Vue, Solid, and Svelte.
218
+ The framework-agnostic base of the `ViewContextValue` type in each framework. It holds the `spec`, `handlers`, `registry`, and `store` fields. These fields are identical in React, Vue, Solid, and Svelte.
170
219
 
171
220
  ## Testing
172
221
 
@@ -1,18 +1,19 @@
1
1
  /**
2
- * AbstractActor base class for Play Architecture
2
+ * The AbstractActor base class of the Play Architecture
3
3
  *
4
- * Extends XState Actor to maintain ecosystem compatibility (inspection, devtools)
5
- * while enforcing signal protocol for Actor Infrastructure communication.
4
+ * It extends the XState Actor class, which keeps the compatibility with the
5
+ * ecosystem, such as the inspection and the devtools. It also enforces the signal
6
+ * protocol of the communication between the Actor and the infrastructure.
6
7
  *
7
- * Per RFC section 5.3, the Actor exposes a minimal protocol:
8
- * - state: Current machine state snapshot
9
- * - send: Event dispatch method
8
+ * RFC section 5.3 gives the minimal protocol of the Actor:
9
+ * - state: the snapshot of the current machine state
10
+ * - send: the method that sends an event
10
11
  *
11
- * Optional capabilities are provided via interfaces:
12
- * - Routable: For actors that support routing
13
- * - Viewable: For actors that support view rendering
12
+ * Two interfaces give the optional capabilities:
13
+ * - Routable: for an actor with a routing support
14
+ * - Viewable: for an actor with a view rendering
14
15
  *
15
- * Concrete implementations are created by adapters (e.g., @xmachines/play-xstate).
16
+ * An adapter, such as @xmachines/play-xstate, makes the concrete implementations.
16
17
  *
17
18
  * @packageDocumentation
18
19
  */
@@ -20,110 +21,115 @@ import { Actor, type AnyActorLogic, type EventObject } from "xstate";
20
21
  import type { Signal } from "@xmachines/play-signals";
21
22
  import type { Spec, StateStore, RenderErrorHandler, ActionHandler } from "@xmachines/json-render-core";
22
23
  /**
23
- * Optional capability: Routing support
24
+ * An optional capability: the routing support
24
25
  */
25
26
  export interface Routable {
26
27
  readonly currentRoute: Signal.Computed<string | null>;
27
28
  readonly initialRoute: string | null;
28
29
  }
29
30
  /**
30
- * XMachines extension of `@xmachines/json-render-core` `Spec`.
31
+ * The XMachines extension of the `Spec` type of `@xmachines/json-render-core`.
31
32
  *
32
- * Adds `contextProps` an explicit allowlist of machine context fields that
33
- * `deriveCurrentView` merges into element props as low-priority slots. Only
34
- * fields named here are ever exposed to components; nothing leaks from context
35
- * without an opt-in declaration.
36
- *
37
- * Use `typedSpec<TContext>(...)` at the definition site to validate `contextProps`
38
- * entries against your machine's context type at compile time.
33
+ * Each derived view receives the machine context in its state store, under the
34
+ * read-only `/context` subtree. A spec therefore reads the context through the
35
+ * ordinary `{ $state: "/context/…" }` grammar: in a prop, in a `visible` condition,
36
+ * and in `repeat.statePath`. The store always holds the complete context, and a
37
+ * spec reads only the paths that it needs.
39
38
  */
40
39
  export interface PlaySpec extends Spec {
41
40
  /**
42
- * Explicit allowlist of machine context field names to expose as prop slots.
43
- * Each named field is merged into every spec element's `props` at view derivation
44
- * time, filling any slot whose current value is `undefined`.
45
- *
46
- * Use `typedSpec<TContext>(...)` to constrain entries to `keyof TContext & string`.
41
+ * The identity of the view of this derived spec. `deriveCurrentView` sets it from
42
+ * the meta entry that the derivation selected. A provider uses it as the key of its
43
+ * store lifecycle: a new `viewKey` seeds the store again, and the same `viewKey`
44
+ * refreshes `/context` in place, which keeps the ephemeral view state. Never write
45
+ * this field in `meta.view`.
47
46
  */
48
- readonly contextProps?: readonly string[];
47
+ readonly viewKey?: string;
49
48
  }
50
49
  /**
51
- * Identity helper that constrains a `PlaySpec` object's `contextProps` to keys
52
- * of a specific machine context type, giving compile-time validation and IDE
53
- * autocomplete at the definition site.
50
+ * The identity helper gives a view spec literal the type `PlaySpec` at the
51
+ * definition site. The compiler therefore checks the spec, and the IDE completes it.
52
+ *
53
+ * The XState `meta` field has the type `Record<string, unknown>`. TypeScript
54
+ * therefore infers no spec shape from the context. `typedSpec(...)` is the
55
+ * mechanism that starts the check where you write the spec. The parameter holds no
56
+ * `viewKey`: the derivation stamps that field, and it overwrites a value from an
57
+ * author without a notice. Therefore the compiler refuses a `viewKey` here.
54
58
  *
55
- * XState's `meta` field is typed as `Record<string, unknown>`, so TypeScript
56
- * cannot infer the constraint from context. `typedSpec<MyCtx>(...)` is the
57
- * opt-in mechanism that activates enforcement where the spec is written.
59
+ * The check of an excess property works on an inline object literal only. For a
60
+ * spec in a variable, or for a spec from a spread, write `satisfies PlaySpec` at
61
+ * the literal instead.
58
62
  *
59
- * At runtime this is a no-op the spec object is returned unchanged.
63
+ * At run time this function does nothing: it returns the spec object without a
64
+ * change.
60
65
  *
61
66
  * @example
62
67
  * ```ts
63
- * interface DashboardCtx {
64
- * username: string;
65
- * params: Record<string, string>;
66
- * query: Record<string, string>;
67
- * }
68
- *
69
68
  * meta: {
70
- * view: typedSpec<DashboardCtx>({
69
+ * view: typedSpec({
71
70
  * root: "root",
72
- * contextProps: ["username"], // ✓ key of DashboardCtx
73
- * // contextProps: ["usernaem"], // ✗ compile error
74
- * elements: { root: { type: "Dashboard", props: {}, children: [] } },
71
+ * elements: {
72
+ * root: {
73
+ * type: "Dashboard",
74
+ * props: { username: { $state: "/context/username" } },
75
+ * children: [],
76
+ * },
77
+ * },
75
78
  * }),
76
79
  * }
77
80
  * ```
78
81
  */
79
- export declare function typedSpec<TContext extends object>(spec: Omit<PlaySpec, "contextProps"> & {
80
- readonly contextProps?: readonly (keyof TContext & string)[];
81
- }): PlaySpec;
82
+ export declare function typedSpec(spec: Omit<PlaySpec, "viewKey">): PlaySpec;
82
83
  /**
83
- * Actor capability for exposing renderable view state.
84
+ * The actor capability that exposes a renderable view state.
84
85
  *
85
- * `Viewable` marks actors that publish a `currentView` signal.
86
- * Renderers such as `PlayRenderer` consume this contract to resolve the
87
- * current view description into concrete UI without embedding view logic inside the
88
- * framework adapter.
86
+ * `Viewable` marks an actor that publishes a `currentView` signal.
87
+ * A renderer, such as `PlayRenderer`, reads this contract. It converts the
88
+ * description of the current view into a concrete UI, and the framework adapter
89
+ * therefore holds no view logic.
89
90
  */
90
91
  export interface Viewable {
91
92
  /**
92
- * Current view signal. Contains the json-render PlaySpec for the current machine
93
- * state, or null when no view is active.
93
+ * The signal of the current view. It holds the json-render PlaySpec of the current
94
+ * machine state, or null when no view is active.
94
95
  *
95
- * Infrastructure renders view Logic-Driven UI invariant.
96
+ * The infrastructure renders the view. This is the Logic-Driven UI invariant.
96
97
  */
97
98
  readonly currentView: Signal.State<PlaySpec | null>;
98
99
  }
99
100
  /**
100
- * Framework-agnostic base for every framework's `ViewContextValue`.
101
+ * The framework-agnostic base of the `ViewContextValue` type in each framework.
101
102
  *
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`.
103
+ * It holds the three fields that are identical in React, Vue, Solid, and Svelte.
104
+ * The `registry` field belongs to one framework, because each framework has its own
105
+ * `ComponentRegistry` type. Therefore `TRegistry` gives its type, and this is the
106
+ * same generic parameter as in `BaseActorProviderProps`.
105
107
  *
106
- * @typeParam TRegistry - The framework's component registry type (e.g. `ComponentRegistry` from `@xmachines/json-render-react`).
108
+ * @typeParam TRegistry - The registry type of the component of the framework, for example `ComponentRegistry` from `@xmachines/json-render-react`.
107
109
  */
108
110
  export interface BaseViewContextValue<TRegistry extends object> {
109
111
  /** The current PlaySpec to render. */
110
112
  spec: PlaySpec;
111
- /** Action handlers resolved against the live StateStore. */
113
+ /** The action handlers, resolved against the live StateStore. */
112
114
  handlers: Record<string, ActionHandler>;
113
- /** Component registry from registryResult.registry. */
115
+ /** The component registry, from registryResult.registry. */
114
116
  registry: TRegistry;
115
- /** The active StateStore — pass to JSONUIProvider/JsonUIProvider as `store` to share state across providers. */
117
+ /**
118
+ * The active StateStore. Give it to JSONUIProvider or JsonUIProvider as `store`, and the providers then share the state.
119
+ */
116
120
  store: StateStore;
117
121
  }
118
122
  /**
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
- * `@xmachines/json-render-core` so no second generic is needed.
123
+ * The framework-agnostic base props. Every `ActorProvider` implementation shares
124
+ * them: React, Vue, Solid, and Svelte. `TRegistry` holds the
125
+ * `DefineRegistryResult` type of the framework. `RenderErrorHandler` comes from
126
+ * `@xmachines/json-render-core`, and a second generic parameter is therefore not
127
+ * necessary.
123
128
  *
124
- * Framework packages extend this with their `fallback`, `onError`, and `children` fields.
129
+ * Each framework package extends this interface with its `fallback` field, its
130
+ * `onError` field, and its `children` field.
125
131
  *
126
- * @typeParam TRegistry - The framework's `DefineRegistryResult` type.
132
+ * @typeParam TRegistry - The `DefineRegistryResult` type of the framework.
127
133
  *
128
134
  * @example
129
135
  * ```ts
@@ -140,44 +146,61 @@ export interface BaseActorProviderProps<TRegistry extends {
140
146
  registry: object;
141
147
  handlers: (...args: never[]) => unknown;
142
148
  }> {
143
- /** Actor instance with currentView signal (requires Viewable capability). */
149
+ /** The actor instance with the currentView signal. It requires the Viewable capability. */
144
150
  actor: AbstractActor<AnyActorLogic> & Viewable;
145
- /** Full result from defineRegistry() contains the component registry and action handlers factory. */
151
+ /** The complete result of defineRegistry(). It holds the component registry and the factory of the action handlers. */
146
152
  registryResult: TRegistry;
147
153
  /**
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.
154
+ * The optional external StateStore, which is the controlled mode.
155
+ * With this option, the provider ignores spec.state, and this store is the single
156
+ * source of truth. Without it, the provider makes a new @xstate/store atom for each
157
+ * view transition, with the values of spec.state.
151
158
  */
152
159
  store?: StateStore;
153
160
  /**
154
- * Called when an individual catalog component throws during render.
155
- * Takes precedence over any onRenderError set via defineRegistry.
161
+ * The provider calls it when one catalog component throws during a render.
162
+ * This handler replaces every onRenderError of defineRegistry.
156
163
  */
157
164
  onRenderError?: RenderErrorHandler;
158
165
  }
159
166
  /**
160
- * Abstract base class for Play Architecture actors.
167
+ * The abstract base class of an actor of the Play Architecture.
161
168
  *
162
- * Provides signal-driven state observation that integrates with XState ecosystem
163
- * tooling (devtools, inspection) while exposing reactive signals for
164
- * Infrastructure layer communication.
169
+ * It observes the state through the signals, and it works with the tools of the
170
+ * XState ecosystem, such as the devtools and the inspection. It also exposes the
171
+ * reactive signals of the communication with the infrastructure layer.
165
172
  *
166
- * @typeParam TLogic - XState actor logic type
167
- * @typeParam TEvent - Event type constraint (defaults to EventObject)
173
+ * **A subclass IS the actor.** Give the logic *and* its options to
174
+ * `super(logic, options)`, then observe `this`. A separate actor beside this
175
+ * instance leaves this instance as an empty second actor. Every inherited member
176
+ * then answers from that empty actor, until you forward each one: `system`,
177
+ * `sessionId`, `clock`, the internal `_send` that receives the traffic of
178
+ * `sendTo()`, and each member that a later XState version adds.
179
+ *
180
+ * @typeParam TLogic - The type of the XState actor logic
181
+ * @typeParam TEvent - The constraint of the event type. The default is EventObject
168
182
  */
169
183
  export declare abstract class AbstractActor<TLogic extends AnyActorLogic, TEvent extends EventObject = EventObject> extends Actor<TLogic> {
170
184
  /**
171
- * Reactive snapshot of current actor state.
185
+ * The reactive snapshot of the current actor state.
172
186
  *
173
- * Infrastructure observes this signal to react to state changes without
174
- * directly coupling to the actor's internal state machine implementation.
187
+ * The infrastructure observes this signal, and it reacts to each state change. It
188
+ * therefore holds no coupling to the internal state machine of the actor.
175
189
  */
176
190
  abstract state: Signal.State<unknown>;
177
191
  /**
178
- * Send event to Actor.
192
+ * Sends an event to the Actor.
193
+ *
194
+ * The constraint is TEvent, which gives the type safety of a concrete
195
+ * implementation.
179
196
  *
180
- * Constrained to TEvent for type safety in concrete implementations.
197
+ * A note for an implementation that wraps `send`, to check the event or to notify a
198
+ * hook around it: this declaration is abstract for one reason only, to narrow the
199
+ * event type, and TypeScript forbids a `super` call to an abstract member. Reach
200
+ * the implementation of XState with `Actor.prototype.send.call(this, event)`
201
+ * instead. A concrete declaration permits `super.send()`, but it also forces an
202
+ * `override` modifier in every subclass that exists now, and that is a breaking
203
+ * change for an adapter outside this repository.
181
204
  */
182
205
  abstract send(event: TEvent): void;
183
206
  }
@@ -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,EACX,IAAI,EACJ,UAAU,EACV,kBAAkB,EAClB,aAAa,EACb,MAAM,6BAA6B,CAAC;AAErC;;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"}
1
+ {"version":3,"file":"abstract-actor.d.ts","sourceRoot":"","sources":["../src/abstract-actor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;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,EACX,IAAI,EACJ,UAAU,EACV,kBAAkB,EAClB,aAAa,EACb,MAAM,6BAA6B,CAAC;AAErC;;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;;;;;;;;GAQG;AACH,MAAM,WAAW,QAAS,SAAQ,IAAI;IACrC;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,GAAG,QAAQ,CAEnE;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,QAAQ;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;CACpD;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,oBAAoB,CAAC,SAAS,SAAS,MAAM;IAC7D,sCAAsC;IACtC,IAAI,EAAE,QAAQ,CAAC;IACf,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACxC,4DAA4D;IAC5D,QAAQ,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,KAAK,EAAE,UAAU,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;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,2FAA2F;IAC3F,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC,GAAG,QAAQ,CAAC;IAC/C,uHAAuH;IACvH,cAAc,EAAE,SAAS,CAAC;IAC1B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB;;;OAGG;IACH,aAAa,CAAC,EAAE,kBAAkB,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;GAgBG;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;;;;;;;;;;;;;OAaG;aACsB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;CAClD"}