@xmachines/play-actor 3.0.0 → 4.0.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 +64 -183
- package/dist/index.d.ts +13 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -16
- package/dist/index.js.map +1 -1
- package/dist/play-actor.d.ts +88 -0
- package/dist/play-actor.d.ts.map +1 -0
- package/dist/play-actor.js +28 -0
- package/dist/play-actor.js.map +1 -0
- package/package.json +15 -17
- package/dist/abstract-actor.d.ts +0 -207
- package/dist/abstract-actor.d.ts.map +0 -1
- package/dist/abstract-actor.js +0 -76
- package/dist/abstract-actor.js.map +0 -1
- package/dist/context-projection.d.ts +0 -116
- package/dist/context-projection.d.ts.map +0 -1
- package/dist/context-projection.js +0 -236
- package/dist/context-projection.js.map +0 -1
- package/dist/failure-latch.d.ts +0 -157
- package/dist/failure-latch.d.ts.map +0 -1
- package/dist/failure-latch.js +0 -110
- package/dist/failure-latch.js.map +0 -1
- package/dist/provider-guards.d.ts +0 -58
- package/dist/provider-guards.d.ts.map +0 -1
- package/dist/provider-guards.js +0 -73
- package/dist/provider-guards.js.map +0 -1
- package/dist/view-store-lifecycle.d.ts +0 -82
- package/dist/view-store-lifecycle.d.ts.map +0 -1
- package/dist/view-store-lifecycle.js +0 -97
- package/dist/view-store-lifecycle.js.map +0 -1
package/dist/abstract-actor.d.ts
DELETED
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The AbstractActor base class of the Play Architecture
|
|
3
|
-
*
|
|
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.
|
|
7
|
-
*
|
|
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
|
|
11
|
-
*
|
|
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
|
|
15
|
-
*
|
|
16
|
-
* An adapter, such as @xmachines/play-xstate, makes the concrete implementations.
|
|
17
|
-
*
|
|
18
|
-
* @packageDocumentation
|
|
19
|
-
*/
|
|
20
|
-
import { Actor, type AnyActorLogic, type EventObject } from "xstate";
|
|
21
|
-
import type { Signal } from "@xmachines/play-signals";
|
|
22
|
-
import type { Spec, StateStore, RenderErrorHandler, ActionHandler } from "@xmachines/json-render-core";
|
|
23
|
-
/**
|
|
24
|
-
* An optional capability: the routing support
|
|
25
|
-
*/
|
|
26
|
-
export interface Routable {
|
|
27
|
-
readonly currentRoute: Signal.Computed<string | null>;
|
|
28
|
-
readonly initialRoute: string | null;
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* The XMachines extension of the `Spec` type of `@xmachines/json-render-core`.
|
|
32
|
-
*
|
|
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.
|
|
38
|
-
*/
|
|
39
|
-
export interface PlaySpec extends Spec {
|
|
40
|
-
/**
|
|
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`.
|
|
46
|
-
*/
|
|
47
|
-
readonly viewKey?: string;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
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.
|
|
58
|
-
*
|
|
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.
|
|
62
|
-
*
|
|
63
|
-
* At run time this function does nothing: it returns the spec object without a
|
|
64
|
-
* change.
|
|
65
|
-
*
|
|
66
|
-
* @example
|
|
67
|
-
* ```ts
|
|
68
|
-
* meta: {
|
|
69
|
-
* view: typedSpec({
|
|
70
|
-
* root: "root",
|
|
71
|
-
* elements: {
|
|
72
|
-
* root: {
|
|
73
|
-
* type: "Dashboard",
|
|
74
|
-
* props: { username: { $state: "/context/username" } },
|
|
75
|
-
* children: [],
|
|
76
|
-
* },
|
|
77
|
-
* },
|
|
78
|
-
* }),
|
|
79
|
-
* }
|
|
80
|
-
* ```
|
|
81
|
-
*/
|
|
82
|
-
export declare function typedSpec(spec: Omit<PlaySpec, "viewKey">): PlaySpec;
|
|
83
|
-
/**
|
|
84
|
-
* The actor capability that exposes a renderable view state.
|
|
85
|
-
*
|
|
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.
|
|
90
|
-
*/
|
|
91
|
-
export interface Viewable {
|
|
92
|
-
/**
|
|
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.
|
|
95
|
-
*
|
|
96
|
-
* The infrastructure renders the view. This is the Logic-Driven UI invariant.
|
|
97
|
-
*/
|
|
98
|
-
readonly currentView: Signal.State<PlaySpec | null>;
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* The framework-agnostic base of the `ViewContextValue` type in each framework.
|
|
102
|
-
*
|
|
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`.
|
|
107
|
-
*
|
|
108
|
-
* @typeParam TRegistry - The registry type of the component of the framework, for example `ComponentRegistry` from `@xmachines/json-render-react`.
|
|
109
|
-
*/
|
|
110
|
-
export interface BaseViewContextValue<TRegistry extends object> {
|
|
111
|
-
/** The current PlaySpec to render. */
|
|
112
|
-
spec: PlaySpec;
|
|
113
|
-
/** The action handlers, resolved against the live StateStore. */
|
|
114
|
-
handlers: Record<string, ActionHandler>;
|
|
115
|
-
/** The component registry, from registryResult.registry. */
|
|
116
|
-
registry: TRegistry;
|
|
117
|
-
/**
|
|
118
|
-
* The active StateStore. Give it to JSONUIProvider or JsonUIProvider as `store`, and the providers then share the state.
|
|
119
|
-
*/
|
|
120
|
-
store: StateStore;
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
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.
|
|
128
|
-
*
|
|
129
|
-
* Each framework package extends this interface with its `fallback` field, its
|
|
130
|
-
* `onError` field, and its `children` field.
|
|
131
|
-
*
|
|
132
|
-
* @typeParam TRegistry - The `DefineRegistryResult` type of the framework.
|
|
133
|
-
*
|
|
134
|
-
* @example
|
|
135
|
-
* ```ts
|
|
136
|
-
* import type { BaseActorProviderProps } from "@xmachines/play-actor";
|
|
137
|
-
* import type { DefineRegistryResult } from "@xmachines/json-render-react";
|
|
138
|
-
*
|
|
139
|
-
* interface ActorProviderProps extends BaseActorProviderProps<DefineRegistryResult> {
|
|
140
|
-
* fallback?: React.ReactNode;
|
|
141
|
-
* children: React.ReactNode;
|
|
142
|
-
* }
|
|
143
|
-
* ```
|
|
144
|
-
*/
|
|
145
|
-
export interface BaseActorProviderProps<TRegistry extends {
|
|
146
|
-
registry: object;
|
|
147
|
-
handlers: (...args: never[]) => unknown;
|
|
148
|
-
}> {
|
|
149
|
-
/** The actor instance with the currentView signal. It requires the Viewable capability. */
|
|
150
|
-
actor: AbstractActor<AnyActorLogic> & Viewable;
|
|
151
|
-
/** The complete result of defineRegistry(). It holds the component registry and the factory of the action handlers. */
|
|
152
|
-
registryResult: TRegistry;
|
|
153
|
-
/**
|
|
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.
|
|
158
|
-
*/
|
|
159
|
-
store?: StateStore;
|
|
160
|
-
/**
|
|
161
|
-
* The provider calls it when one catalog component throws during a render.
|
|
162
|
-
* This handler replaces every onRenderError of defineRegistry.
|
|
163
|
-
*/
|
|
164
|
-
onRenderError?: RenderErrorHandler;
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* The abstract base class of an actor of the Play Architecture.
|
|
168
|
-
*
|
|
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.
|
|
172
|
-
*
|
|
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
|
|
182
|
-
*/
|
|
183
|
-
export declare abstract class AbstractActor<TLogic extends AnyActorLogic, TEvent extends EventObject = EventObject> extends Actor<TLogic> {
|
|
184
|
-
/**
|
|
185
|
-
* The reactive snapshot of the current actor state.
|
|
186
|
-
*
|
|
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.
|
|
189
|
-
*/
|
|
190
|
-
abstract state: Signal.State<unknown>;
|
|
191
|
-
/**
|
|
192
|
-
* Sends an event to the Actor.
|
|
193
|
-
*
|
|
194
|
-
* The constraint is TEvent, which gives the type safety of a concrete
|
|
195
|
-
* implementation.
|
|
196
|
-
*
|
|
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.
|
|
204
|
-
*/
|
|
205
|
-
abstract send(event: TEvent): void;
|
|
206
|
-
}
|
|
207
|
-
//# sourceMappingURL=abstract-actor.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
package/dist/abstract-actor.js
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The AbstractActor base class of the Play Architecture
|
|
3
|
-
*
|
|
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.
|
|
7
|
-
*
|
|
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
|
|
11
|
-
*
|
|
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
|
|
15
|
-
*
|
|
16
|
-
* An adapter, such as @xmachines/play-xstate, makes the concrete implementations.
|
|
17
|
-
*
|
|
18
|
-
* @packageDocumentation
|
|
19
|
-
*/
|
|
20
|
-
import { Actor } from "xstate";
|
|
21
|
-
/**
|
|
22
|
-
* The identity helper gives a view spec literal the type `PlaySpec` at the
|
|
23
|
-
* definition site. The compiler therefore checks the spec, and the IDE completes it.
|
|
24
|
-
*
|
|
25
|
-
* The XState `meta` field has the type `Record<string, unknown>`. TypeScript
|
|
26
|
-
* therefore infers no spec shape from the context. `typedSpec(...)` is the
|
|
27
|
-
* mechanism that starts the check where you write the spec. The parameter holds no
|
|
28
|
-
* `viewKey`: the derivation stamps that field, and it overwrites a value from an
|
|
29
|
-
* author without a notice. Therefore the compiler refuses a `viewKey` here.
|
|
30
|
-
*
|
|
31
|
-
* The check of an excess property works on an inline object literal only. For a
|
|
32
|
-
* spec in a variable, or for a spec from a spread, write `satisfies PlaySpec` at
|
|
33
|
-
* the literal instead.
|
|
34
|
-
*
|
|
35
|
-
* At run time this function does nothing: it returns the spec object without a
|
|
36
|
-
* change.
|
|
37
|
-
*
|
|
38
|
-
* @example
|
|
39
|
-
* ```ts
|
|
40
|
-
* meta: {
|
|
41
|
-
* view: typedSpec({
|
|
42
|
-
* root: "root",
|
|
43
|
-
* elements: {
|
|
44
|
-
* root: {
|
|
45
|
-
* type: "Dashboard",
|
|
46
|
-
* props: { username: { $state: "/context/username" } },
|
|
47
|
-
* children: [],
|
|
48
|
-
* },
|
|
49
|
-
* },
|
|
50
|
-
* }),
|
|
51
|
-
* }
|
|
52
|
-
* ```
|
|
53
|
-
*/
|
|
54
|
-
export function typedSpec(spec) {
|
|
55
|
-
return spec;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* The abstract base class of an actor of the Play Architecture.
|
|
59
|
-
*
|
|
60
|
-
* It observes the state through the signals, and it works with the tools of the
|
|
61
|
-
* XState ecosystem, such as the devtools and the inspection. It also exposes the
|
|
62
|
-
* reactive signals of the communication with the infrastructure layer.
|
|
63
|
-
*
|
|
64
|
-
* **A subclass IS the actor.** Give the logic *and* its options to
|
|
65
|
-
* `super(logic, options)`, then observe `this`. A separate actor beside this
|
|
66
|
-
* instance leaves this instance as an empty second actor. Every inherited member
|
|
67
|
-
* then answers from that empty actor, until you forward each one: `system`,
|
|
68
|
-
* `sessionId`, `clock`, the internal `_send` that receives the traffic of
|
|
69
|
-
* `sendTo()`, and each member that a later XState version adds.
|
|
70
|
-
*
|
|
71
|
-
* @typeParam TLogic - The type of the XState actor logic
|
|
72
|
-
* @typeParam TEvent - The constraint of the event type. The default is EventObject
|
|
73
|
-
*/
|
|
74
|
-
export class AbstractActor extends Actor {
|
|
75
|
-
}
|
|
76
|
-
//# sourceMappingURL=abstract-actor.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"abstract-actor.js","sourceRoot":"","sources":["../src/abstract-actor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,KAAK,EAAwC,MAAM,QAAQ,CAAC;AAqCrE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,UAAU,SAAS,CAAC,IAA+B;IACxD,OAAO,IAAI,CAAC;AACb,CAAC;AAuFD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAgB,aAGpB,SAAQ,KAAa;CAwBtB"}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The context projection — the machine context as the read-only `/context`
|
|
3
|
-
* subtree of the view state store.
|
|
4
|
-
*
|
|
5
|
-
* `deriveCurrentView` composes the `state` field of each emitted view as
|
|
6
|
-
* `{ ...meta.view.state, context: <slice> }`. The spec is therefore consistent with
|
|
7
|
-
* itself: its `state` field describes the contents of the store correctly, and
|
|
8
|
-
* `repeat.statePath`, `visible.$state`, a `$state` prop, and a validator all read
|
|
9
|
-
* the machine context through the ordinary `{ $state: "/context/…" }` grammar.
|
|
10
|
-
*
|
|
11
|
-
* The subtree is read-only **to the spec, and not to the machinery**: a provider
|
|
12
|
-
* gives the bindings and the action handlers a store with the wrapper of
|
|
13
|
-
* {@link guardContextWrites}, and it refreshes the projection through the store
|
|
14
|
-
* below that wrapper, which has no guard. The context changes through a machine
|
|
15
|
-
* event only. Therefore a write under `/context` is always a fault of the spec, and
|
|
16
|
-
* the guard says so.
|
|
17
|
-
*
|
|
18
|
-
* @packageDocumentation
|
|
19
|
-
*/
|
|
20
|
-
import type { StateStore } from "@xmachines/json-render-core";
|
|
21
|
-
import type { PlaySpec } from "./abstract-actor.js";
|
|
22
|
-
/**
|
|
23
|
-
* The reserved top-level state key of the projection.
|
|
24
|
-
*
|
|
25
|
-
* The `spec.state` object of a view must not declare this key. When it does, the
|
|
26
|
-
* derivation skips the projection for that view, the authored state wins, and the
|
|
27
|
-
* code writes a warning in development. See {@link composePlayState}.
|
|
28
|
-
*/
|
|
29
|
-
export declare const CONTEXT_STATE_KEY = "context";
|
|
30
|
-
/**
|
|
31
|
-
* The shallow equality of the own keys, with `Object.is`. It can ignore one key on
|
|
32
|
-
* both sides.
|
|
33
|
-
*
|
|
34
|
-
* This is the one comparison rule behind every decision of the emission dedup: the
|
|
35
|
-
* equality of a slice, and also the emit gate of the player, which compares the
|
|
36
|
-
* spec fields in `viewSpecsEquivalent` and reuses the composed state in
|
|
37
|
-
* {@link reuseComposedState}.
|
|
38
|
-
*/
|
|
39
|
-
export declare function shallowEqualExcept(a: object, b: object, except?: string): boolean;
|
|
40
|
-
/**
|
|
41
|
-
* Reuses the composed `state` of the previous emission, or the complete previous
|
|
42
|
-
* spec, when the value of the projection did not change.
|
|
43
|
-
*
|
|
44
|
-
* `deriveCurrentView` composes `state: { ...meta.view.state, context: slice }` new
|
|
45
|
-
* on each call, and the XState function `assign` makes a new context object on
|
|
46
|
-
* every event. Without this reuse, every event therefore presents a new `state`
|
|
47
|
-
* reference, and the `Object.is` test of each field in the emit gate emits the view
|
|
48
|
-
* again and remounts it, without an end. The function compares the slices field by
|
|
49
|
-
* field ({@link shallowEqualExcept}), because the XState function `assign` makes a
|
|
50
|
-
* new context object for each event, and a test of the identity of the whole object
|
|
51
|
-
* therefore reports a change every time. The authored fields come from the static
|
|
52
|
-
* `meta.view.state` through a spread. Therefore their references are stable for an
|
|
53
|
-
* unchanged `viewKey`, and a plain `Object.is` test is correct for them.
|
|
54
|
-
*
|
|
55
|
-
* The function returns one of three values, in this order of preference:
|
|
56
|
-
* - `prev` itself, when nothing observable changed. The emit gate then stops at the
|
|
57
|
-
* identity of the reference, and it walks no element;
|
|
58
|
-
* - `{ ...next, state: prev.state }`, when the value of the state did not change
|
|
59
|
-
* but another top-level field is different;
|
|
60
|
-
* - `next`, when something changed.
|
|
61
|
-
*/
|
|
62
|
-
export declare function reuseComposedState(prev: PlaySpec | null, next: PlaySpec | null): PlaySpec | null;
|
|
63
|
-
/**
|
|
64
|
-
* Wraps a StateStore, and the wrapper refuses each write under `/context`.
|
|
65
|
-
*
|
|
66
|
-
* A provider applies it to the store that it gives to the bindings and to the
|
|
67
|
-
* action handlers (`$bindState`, `setState`, and a chained `set`). The provider
|
|
68
|
-
* keeps the store without the wrapper, and it refreshes the projection through that
|
|
69
|
-
* store. The subtree is therefore read-only to the spec, and not to the machinery.
|
|
70
|
-
*
|
|
71
|
-
* A write with a value that is **identical** to the current value passes in
|
|
72
|
-
* silence. A handler in the style of `setState` reads the complete snapshot,
|
|
73
|
-
* changes it, and writes the whole object back. The `context` key that goes through
|
|
74
|
-
* that round trip without a change is no attempt of a mutation. Only a write that
|
|
75
|
-
* changes the subtree throws.
|
|
76
|
-
*
|
|
77
|
-
* Each read passes through without a change. The wrapper delegates every member
|
|
78
|
-
* explicitly, and it does not use a spread: a store from a consumer can be an
|
|
79
|
-
* instance of a class, and the methods of that instance are on the prototype. Those
|
|
80
|
-
* methods do not survive `{ ...store }`, and the first render then fails with
|
|
81
|
-
* `store.getSnapshot is not a function`. The code builds the wrapper one time for
|
|
82
|
-
* each resolved store. Therefore the identity of the delegating `getSnapshot` and
|
|
83
|
-
* of the delegating `subscribe` stays stable for a consumer in the style of
|
|
84
|
-
* `useSyncExternalStore`.
|
|
85
|
-
*
|
|
86
|
-
* @param store - The store below the wrapper.
|
|
87
|
-
* @returns A store with a guard on `set` and on `update`.
|
|
88
|
-
*/
|
|
89
|
-
export declare function guardContextWrites(store: StateStore): StateStore;
|
|
90
|
-
/**
|
|
91
|
-
* Refreshes the `/context` subtree of a live store from the composed state of a
|
|
92
|
-
* derived view. An emission with the same `viewKey` means that only the projection
|
|
93
|
-
* changed. The function therefore replaces the complete subtree, and it never
|
|
94
|
-
* merges it field by field, because `update` cannot delete a key. Every ephemeral
|
|
95
|
-
* value at the root level stays. The function does nothing when the view carries no
|
|
96
|
-
* slice, or when the store holds the slice already.
|
|
97
|
-
*
|
|
98
|
-
* @param store - The store WITHOUT the guard. A provider refreshes through it.
|
|
99
|
-
* @param view - The derived view. Its `state.context` field carries the slice.
|
|
100
|
-
*/
|
|
101
|
-
export declare function refreshContextSubtree(store: StateStore, view: {
|
|
102
|
-
state?: unknown;
|
|
103
|
-
}): void;
|
|
104
|
-
/**
|
|
105
|
-
* Composes the effective state of a view: the authored `spec.state` and the
|
|
106
|
-
* `/context` slice.
|
|
107
|
-
*
|
|
108
|
-
* When the authored state declares the reserved key already, the function skips the
|
|
109
|
-
* projection, the authored state wins, and the code writes a warning in
|
|
110
|
-
* development. No spec that exists now therefore fails.
|
|
111
|
-
*
|
|
112
|
-
* @param authoredState - The raw `meta.view.state` value. It can be anything, and the caller or toAtomState cleans it.
|
|
113
|
-
* @param slice - The context of the machine, as one complete value.
|
|
114
|
-
*/
|
|
115
|
-
export declare function composePlayState(authoredState: Record<string, unknown> | undefined, slice: Record<string, unknown> | undefined): Record<string, unknown> | undefined;
|
|
116
|
-
//# sourceMappingURL=context-projection.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context-projection.d.ts","sourceRoot":"","sources":["../src/context-projection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,YAAY,CAAC;AAiB3C;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAUjF;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,GAAG,QAAQ,GAAG,IAAI,CAiBhG;AAgBD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CA8ChE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAKxF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC/B,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAClD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GACxC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAcrC"}
|
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The context projection — the machine context as the read-only `/context`
|
|
3
|
-
* subtree of the view state store.
|
|
4
|
-
*
|
|
5
|
-
* `deriveCurrentView` composes the `state` field of each emitted view as
|
|
6
|
-
* `{ ...meta.view.state, context: <slice> }`. The spec is therefore consistent with
|
|
7
|
-
* itself: its `state` field describes the contents of the store correctly, and
|
|
8
|
-
* `repeat.statePath`, `visible.$state`, a `$state` prop, and a validator all read
|
|
9
|
-
* the machine context through the ordinary `{ $state: "/context/…" }` grammar.
|
|
10
|
-
*
|
|
11
|
-
* The subtree is read-only **to the spec, and not to the machinery**: a provider
|
|
12
|
-
* gives the bindings and the action handlers a store with the wrapper of
|
|
13
|
-
* {@link guardContextWrites}, and it refreshes the projection through the store
|
|
14
|
-
* below that wrapper, which has no guard. The context changes through a machine
|
|
15
|
-
* event only. Therefore a write under `/context` is always a fault of the spec, and
|
|
16
|
-
* the guard says so.
|
|
17
|
-
*
|
|
18
|
-
* @packageDocumentation
|
|
19
|
-
*/
|
|
20
|
-
/**
|
|
21
|
-
* The reserved top-level state key of the projection.
|
|
22
|
-
*
|
|
23
|
-
* The `spec.state` object of a view must not declare this key. When it does, the
|
|
24
|
-
* derivation skips the projection for that view, the authored state wins, and the
|
|
25
|
-
* code writes a warning in development. See {@link composePlayState}.
|
|
26
|
-
*/
|
|
27
|
-
export const CONTEXT_STATE_KEY = "context";
|
|
28
|
-
/**
|
|
29
|
-
* The record that reports each diagnostic one time for each spec. The condition
|
|
30
|
-
* here is a static property of the authored meta.view, because its `state` object
|
|
31
|
-
* never changes between two events. `deriveCurrentView` runs on every machine
|
|
32
|
-
* snapshot, and a report for each derivation therefore floods the console at the
|
|
33
|
-
* rate of the events. The key is the identity of the static object. Each spec
|
|
34
|
-
* therefore reports one time, and a test with a new literal stays separate.
|
|
35
|
-
*/
|
|
36
|
-
const reportedDiagnostics = new WeakSet();
|
|
37
|
-
function warnOnce(anchor, message) {
|
|
38
|
-
if (reportedDiagnostics.has(anchor))
|
|
39
|
-
return;
|
|
40
|
-
reportedDiagnostics.add(anchor);
|
|
41
|
-
console.warn(message);
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* The shallow equality of the own keys, with `Object.is`. It can ignore one key on
|
|
45
|
-
* both sides.
|
|
46
|
-
*
|
|
47
|
-
* This is the one comparison rule behind every decision of the emission dedup: the
|
|
48
|
-
* equality of a slice, and also the emit gate of the player, which compares the
|
|
49
|
-
* spec fields in `viewSpecsEquivalent` and reuses the composed state in
|
|
50
|
-
* {@link reuseComposedState}.
|
|
51
|
-
*/
|
|
52
|
-
export function shallowEqualExcept(a, b, except) {
|
|
53
|
-
const aEntries = Object.entries(a).filter(([key]) => key !== except);
|
|
54
|
-
const bKeyCount = Object.keys(b).filter((key) => key !== except).length;
|
|
55
|
-
if (aEntries.length !== bKeyCount)
|
|
56
|
-
return false;
|
|
57
|
-
const bRecord = b;
|
|
58
|
-
for (const [key, value] of aEntries) {
|
|
59
|
-
// nosemgrep: gitlab.eslint.detect-object-injection
|
|
60
|
-
if (!Object.hasOwn(b, key) || !Object.is(value, bRecord[key]))
|
|
61
|
-
return false;
|
|
62
|
-
}
|
|
63
|
-
return true;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Reuses the composed `state` of the previous emission, or the complete previous
|
|
67
|
-
* spec, when the value of the projection did not change.
|
|
68
|
-
*
|
|
69
|
-
* `deriveCurrentView` composes `state: { ...meta.view.state, context: slice }` new
|
|
70
|
-
* on each call, and the XState function `assign` makes a new context object on
|
|
71
|
-
* every event. Without this reuse, every event therefore presents a new `state`
|
|
72
|
-
* reference, and the `Object.is` test of each field in the emit gate emits the view
|
|
73
|
-
* again and remounts it, without an end. The function compares the slices field by
|
|
74
|
-
* field ({@link shallowEqualExcept}), because the XState function `assign` makes a
|
|
75
|
-
* new context object for each event, and a test of the identity of the whole object
|
|
76
|
-
* therefore reports a change every time. The authored fields come from the static
|
|
77
|
-
* `meta.view.state` through a spread. Therefore their references are stable for an
|
|
78
|
-
* unchanged `viewKey`, and a plain `Object.is` test is correct for them.
|
|
79
|
-
*
|
|
80
|
-
* The function returns one of three values, in this order of preference:
|
|
81
|
-
* - `prev` itself, when nothing observable changed. The emit gate then stops at the
|
|
82
|
-
* identity of the reference, and it walks no element;
|
|
83
|
-
* - `{ ...next, state: prev.state }`, when the value of the state did not change
|
|
84
|
-
* but another top-level field is different;
|
|
85
|
-
* - `next`, when something changed.
|
|
86
|
-
*/
|
|
87
|
-
export function reuseComposedState(prev, next) {
|
|
88
|
-
if (!prev || !next || prev.viewKey !== next.viewKey)
|
|
89
|
-
return next;
|
|
90
|
-
const prevState = prev.state;
|
|
91
|
-
const nextState = next.state;
|
|
92
|
-
if (prevState !== nextState) {
|
|
93
|
-
if (prevState === undefined || nextState === undefined)
|
|
94
|
-
return next;
|
|
95
|
-
if (!shallowEqualExcept(prevState, nextState, CONTEXT_STATE_KEY))
|
|
96
|
-
return next;
|
|
97
|
-
const prevSlice = prevState[CONTEXT_STATE_KEY];
|
|
98
|
-
const nextSlice = nextState[CONTEXT_STATE_KEY];
|
|
99
|
-
if (prevSlice !== nextSlice) {
|
|
100
|
-
if (prevSlice === undefined || nextSlice === undefined)
|
|
101
|
-
return next;
|
|
102
|
-
if (!shallowEqualExcept(prevSlice, nextSlice))
|
|
103
|
-
return next;
|
|
104
|
-
}
|
|
105
|
-
if (shallowEqualExcept(prev, next, "state"))
|
|
106
|
-
return prev;
|
|
107
|
-
return { ...next, state: prevState };
|
|
108
|
-
}
|
|
109
|
-
return shallowEqualExcept(prev, next, "state") ? prev : next;
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* The paths of the reserved subtree: `"/context"` itself, and every path below it.
|
|
113
|
-
* An update map of the store can hold a bare top-level key ("context") and also a
|
|
114
|
-
* JSON Pointer ("/context/…"). Both forms address the same subtree.
|
|
115
|
-
*/
|
|
116
|
-
function toPointer(path) {
|
|
117
|
-
return path.startsWith("/") ? path : `/${path}`;
|
|
118
|
-
}
|
|
119
|
-
/** This function expects a NORMALIZED pointer from {@link toPointer}. */
|
|
120
|
-
function isContextPointer(pointer) {
|
|
121
|
-
return pointer === `/${CONTEXT_STATE_KEY}` || pointer.startsWith(`/${CONTEXT_STATE_KEY}/`);
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Wraps a StateStore, and the wrapper refuses each write under `/context`.
|
|
125
|
-
*
|
|
126
|
-
* A provider applies it to the store that it gives to the bindings and to the
|
|
127
|
-
* action handlers (`$bindState`, `setState`, and a chained `set`). The provider
|
|
128
|
-
* keeps the store without the wrapper, and it refreshes the projection through that
|
|
129
|
-
* store. The subtree is therefore read-only to the spec, and not to the machinery.
|
|
130
|
-
*
|
|
131
|
-
* A write with a value that is **identical** to the current value passes in
|
|
132
|
-
* silence. A handler in the style of `setState` reads the complete snapshot,
|
|
133
|
-
* changes it, and writes the whole object back. The `context` key that goes through
|
|
134
|
-
* that round trip without a change is no attempt of a mutation. Only a write that
|
|
135
|
-
* changes the subtree throws.
|
|
136
|
-
*
|
|
137
|
-
* Each read passes through without a change. The wrapper delegates every member
|
|
138
|
-
* explicitly, and it does not use a spread: a store from a consumer can be an
|
|
139
|
-
* instance of a class, and the methods of that instance are on the prototype. Those
|
|
140
|
-
* methods do not survive `{ ...store }`, and the first render then fails with
|
|
141
|
-
* `store.getSnapshot is not a function`. The code builds the wrapper one time for
|
|
142
|
-
* each resolved store. Therefore the identity of the delegating `getSnapshot` and
|
|
143
|
-
* of the delegating `subscribe` stays stable for a consumer in the style of
|
|
144
|
-
* `useSyncExternalStore`.
|
|
145
|
-
*
|
|
146
|
-
* @param store - The store below the wrapper.
|
|
147
|
-
* @returns A store with a guard on `set` and on `update`.
|
|
148
|
-
*/
|
|
149
|
-
export function guardContextWrites(store) {
|
|
150
|
-
const reject = (path) => {
|
|
151
|
-
throw new Error(`[play-actor] "${path}" is read-only: /${CONTEXT_STATE_KEY} mirrors the machine's context. ` +
|
|
152
|
-
`Send the actor an event to change it — context never changes through the view store.`);
|
|
153
|
-
};
|
|
154
|
-
const checkWrite = (path, value) => {
|
|
155
|
-
const pointer = toPointer(path);
|
|
156
|
-
if (!isContextPointer(pointer))
|
|
157
|
-
return true;
|
|
158
|
-
// A round trip without a change, which is a read-modify-write of the complete
|
|
159
|
-
// snapshot, does nothing to this subtree, and it is no mutation. Drop the key in
|
|
160
|
-
// silence.
|
|
161
|
-
if (Object.is(store.get(pointer), value))
|
|
162
|
-
return false;
|
|
163
|
-
return reject(path);
|
|
164
|
-
};
|
|
165
|
-
const guarded = {
|
|
166
|
-
get: (path) => store.get(path),
|
|
167
|
-
getSnapshot: () => store.getSnapshot(),
|
|
168
|
-
subscribe: (listener) => store.subscribe(listener),
|
|
169
|
-
set: (path, value) => {
|
|
170
|
-
if (checkWrite(path, value))
|
|
171
|
-
store.set(path, value);
|
|
172
|
-
},
|
|
173
|
-
update: (updates) => {
|
|
174
|
-
const allowed = {};
|
|
175
|
-
let dropped = false;
|
|
176
|
-
for (const [path, value] of Object.entries(updates)) {
|
|
177
|
-
if (checkWrite(path, value)) {
|
|
178
|
-
allowed[path] = value; // nosemgrep: gitlab.eslint.detect-object-injection
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
dropped = true;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
store.update(dropped ? allowed : updates);
|
|
185
|
-
},
|
|
186
|
-
};
|
|
187
|
-
// The contract makes this member optional, and its absence has a meaning:
|
|
188
|
-
// json-render-core uses `getSnapshot` when the key is absent. Therefore the wrapper
|
|
189
|
-
// must build no member that returns `undefined`.
|
|
190
|
-
const { getServerSnapshot } = store;
|
|
191
|
-
if (getServerSnapshot) {
|
|
192
|
-
guarded.getServerSnapshot = () => getServerSnapshot.call(store);
|
|
193
|
-
}
|
|
194
|
-
return guarded;
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Refreshes the `/context` subtree of a live store from the composed state of a
|
|
198
|
-
* derived view. An emission with the same `viewKey` means that only the projection
|
|
199
|
-
* changed. The function therefore replaces the complete subtree, and it never
|
|
200
|
-
* merges it field by field, because `update` cannot delete a key. Every ephemeral
|
|
201
|
-
* value at the root level stays. The function does nothing when the view carries no
|
|
202
|
-
* slice, or when the store holds the slice already.
|
|
203
|
-
*
|
|
204
|
-
* @param store - The store WITHOUT the guard. A provider refreshes through it.
|
|
205
|
-
* @param view - The derived view. Its `state.context` field carries the slice.
|
|
206
|
-
*/
|
|
207
|
-
export function refreshContextSubtree(store, view) {
|
|
208
|
-
const slice = view.state?.[CONTEXT_STATE_KEY];
|
|
209
|
-
if (slice !== undefined && !Object.is(store.get(`/${CONTEXT_STATE_KEY}`), slice)) {
|
|
210
|
-
store.update({ [`/${CONTEXT_STATE_KEY}`]: slice });
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* Composes the effective state of a view: the authored `spec.state` and the
|
|
215
|
-
* `/context` slice.
|
|
216
|
-
*
|
|
217
|
-
* When the authored state declares the reserved key already, the function skips the
|
|
218
|
-
* projection, the authored state wins, and the code writes a warning in
|
|
219
|
-
* development. No spec that exists now therefore fails.
|
|
220
|
-
*
|
|
221
|
-
* @param authoredState - The raw `meta.view.state` value. It can be anything, and the caller or toAtomState cleans it.
|
|
222
|
-
* @param slice - The context of the machine, as one complete value.
|
|
223
|
-
*/
|
|
224
|
-
export function composePlayState(authoredState, slice) {
|
|
225
|
-
if (authoredState !== undefined && Object.hasOwn(authoredState, CONTEXT_STATE_KEY)) {
|
|
226
|
-
warnOnce(authoredState, `[play-actor] spec.state declares a top-level "${CONTEXT_STATE_KEY}" key; ` +
|
|
227
|
-
`skipping the machine-context projection for this view. ` +
|
|
228
|
-
`Rename the state field to project context at /${CONTEXT_STATE_KEY}.`);
|
|
229
|
-
return authoredState;
|
|
230
|
-
}
|
|
231
|
-
if (slice === undefined) {
|
|
232
|
-
return authoredState;
|
|
233
|
-
}
|
|
234
|
-
return { ...authoredState, [CONTEXT_STATE_KEY]: slice };
|
|
235
|
-
}
|
|
236
|
-
//# sourceMappingURL=context-projection.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context-projection.js","sourceRoot":"","sources":["../src/context-projection.ts"],"names":[],"mappings":"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"}
|