@xmachines/play-xstate 2.0.0 → 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 +66 -65
- package/dist/define-player.d.ts +16 -16
- package/dist/define-player.js +16 -16
- package/dist/errors.d.ts +57 -50
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +63 -55
- package/dist/errors.js.map +1 -1
- package/dist/guards/compose.d.ts +53 -50
- package/dist/guards/compose.d.ts.map +1 -1
- package/dist/guards/compose.js +67 -63
- package/dist/guards/compose.js.map +1 -1
- package/dist/guards/helpers.d.ts +22 -22
- package/dist/guards/helpers.js +23 -23
- package/dist/guards/index.d.ts +9 -9
- package/dist/guards/index.js +9 -9
- package/dist/guards/types.d.ts +9 -8
- package/dist/guards/types.d.ts.map +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -7
- package/dist/index.js.map +1 -1
- package/dist/player-actor.d.ts +162 -146
- package/dist/player-actor.d.ts.map +1 -1
- package/dist/player-actor.js +269 -241
- package/dist/player-actor.js.map +1 -1
- package/dist/routing/build-url.d.ts +19 -16
- package/dist/routing/build-url.d.ts.map +1 -1
- package/dist/routing/build-url.js +62 -59
- package/dist/routing/build-url.js.map +1 -1
- package/dist/routing/derive-current-route.d.ts +42 -36
- package/dist/routing/derive-current-route.d.ts.map +1 -1
- package/dist/routing/derive-current-route.js +57 -49
- package/dist/routing/derive-current-route.js.map +1 -1
- package/dist/routing/derive-initial-route.d.ts +23 -20
- package/dist/routing/derive-initial-route.d.ts.map +1 -1
- package/dist/routing/derive-initial-route.js +27 -24
- package/dist/routing/derive-initial-route.js.map +1 -1
- package/dist/routing/derive-route.d.ts +38 -37
- package/dist/routing/derive-route.d.ts.map +1 -1
- package/dist/routing/derive-route.js +45 -42
- package/dist/routing/derive-route.js.map +1 -1
- package/dist/routing/format-play-route-transitions.d.ts +34 -28
- package/dist/routing/format-play-route-transitions.d.ts.map +1 -1
- package/dist/routing/format-play-route-transitions.js +32 -28
- package/dist/routing/format-play-route-transitions.js.map +1 -1
- package/dist/routing/index.d.ts +3 -3
- package/dist/routing/index.js +3 -3
- package/dist/routing/types.d.ts +12 -11
- package/dist/routing/types.d.ts.map +1 -1
- package/dist/types.d.ts +64 -60
- package/dist/types.d.ts.map +1 -1
- package/dist/view/derive-current-view.d.ts +42 -40
- package/dist/view/derive-current-view.d.ts.map +1 -1
- package/dist/view/derive-current-view.js +51 -47
- package/dist/view/derive-current-view.js.map +1 -1
- package/package.json +7 -6
|
@@ -3,24 +3,26 @@ import { shallowEqualExcept } from "@xmachines/play-actor";
|
|
|
3
3
|
import { MissingStateIdError } from "../errors.js";
|
|
4
4
|
import { normalizeRoute } from "./derive-route.js";
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
* shallow
|
|
6
|
+
* Reuses the previous container of the params and of the query when the new
|
|
7
|
+
* container is equal to it in a shallow comparison.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* `Object.is`. Without reuse, a
|
|
13
|
-
* the current URL
|
|
14
|
-
* for nothing.
|
|
9
|
+
* The params and the query of a route arrive in a FRESH object on every `play.route`
|
|
10
|
+
* event: a bridge builds them again for each parse of a URL, and `|| {}` allocates
|
|
11
|
+
* an object also for the empty case. The emit gate of the view compares the context
|
|
12
|
+
* field by field, with `Object.is`. Without this reuse, a navigation to the same
|
|
13
|
+
* values, such as a popstate event to the current URL or a second send from the
|
|
14
|
+
* code, emits the view again for nothing.
|
|
15
15
|
*/
|
|
16
16
|
const keepEqualContainer = (prev, next) => (prev !== undefined && shallowEqualExcept(prev, next) ? prev : next);
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
18
|
+
* Makes the play.route transitions from the declarative route configs
|
|
19
19
|
*
|
|
20
|
-
*
|
|
21
|
-
* transitions that handle `play.route`
|
|
20
|
+
* The function walks the machine states. It looks for each state with a `meta.route`
|
|
21
|
+
* field, and it generates the transitions that handle a `play.route` event: each
|
|
22
|
+
* transition matches event.to against a state ID.
|
|
22
23
|
*
|
|
23
|
-
*
|
|
24
|
+
* The internal formatRouteTransitions function of XState was the model for this
|
|
25
|
+
* function (stateUtils.ts, line 391).
|
|
24
26
|
*
|
|
25
27
|
* @example
|
|
26
28
|
* ```typescript
|
|
@@ -35,26 +37,28 @@ const keepEqualContainer = (prev, next) => (prev !== undefined && shallowEqualEx
|
|
|
35
37
|
* const machine = createMachine(formatPlayRouteTransitions(machineConfig));
|
|
36
38
|
* ```
|
|
37
39
|
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* -
|
|
41
|
-
* -
|
|
40
|
+
* The function generates the `play.route` handlers at the root level. Those
|
|
41
|
+
* handlers:
|
|
42
|
+
* - match event.to against a state ID, for example event.to === "#home"
|
|
43
|
+
* - target the correct state
|
|
44
|
+
* - assign the params and the query of the event to the context
|
|
42
45
|
*
|
|
43
|
-
* @param machineConfig - XState machine config
|
|
44
|
-
* @returns The same machine config with
|
|
46
|
+
* @param machineConfig - The XState machine config, before `createMachine`. It must extend `RouteMachineConfig`.
|
|
47
|
+
* @returns The same machine config, with the generated `play.route` handlers in it. The original type `T` stays.
|
|
45
48
|
*/
|
|
46
49
|
export function formatPlayRouteTransitions(machineConfig) {
|
|
47
50
|
const routeTransitions = [];
|
|
48
51
|
const collectRoutes = (states, parentPath = "") => {
|
|
49
52
|
Object.entries(states).forEach(([key, stateConfig]) => {
|
|
50
53
|
const node = stateConfig;
|
|
51
|
-
// Build the
|
|
52
|
-
//
|
|
54
|
+
// Build the complete path of the keys, from the root, for the target of the
|
|
55
|
+
// transition. An XState target uses the hierarchy of the state keys, and not the
|
|
56
|
+
// explicit IDs.
|
|
53
57
|
const statePath = parentPath ? `${parentPath}.${key}` : key;
|
|
54
|
-
//
|
|
55
|
-
// InvalidRouteMetadataError
|
|
56
|
-
//
|
|
57
|
-
//
|
|
58
|
+
// The function checks the metadata, and a malformed object route therefore throws an
|
|
59
|
+
// InvalidRouteMetadataError. It then normalizes the value into the string of the
|
|
60
|
+
// path. An empty path marks the state as a state without a route, in the string form
|
|
61
|
+
// ("") and also in the object form ({ path: "" }).
|
|
58
62
|
const routePath = node.meta?.route === undefined
|
|
59
63
|
? ""
|
|
60
64
|
: normalizeRoute(node.meta.route, "formatPlayRouteTransitions");
|
|
@@ -84,10 +88,10 @@ export function formatPlayRouteTransitions(machineConfig) {
|
|
|
84
88
|
}
|
|
85
89
|
if (routeTransitions.length > 0) {
|
|
86
90
|
const existingOn = machineConfig.on || {};
|
|
87
|
-
//
|
|
88
|
-
//
|
|
89
|
-
// candidate transitions in order
|
|
90
|
-
// and the
|
|
91
|
+
// Keep each play.route transition of the user, for example a 404 fallback that a
|
|
92
|
+
// person wrote, and append those transitions AFTER the generated ones: XState
|
|
93
|
+
// evaluates the candidate transitions in their order. Therefore a generated guard
|
|
94
|
+
// wins when it matches, and the transitions of the user are the fallback.
|
|
91
95
|
const userRouteTransitions = existingOn["play.route"];
|
|
92
96
|
const normalizedUserTransitions = userRouteTransitions === undefined
|
|
93
97
|
? []
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format-play-route-transitions.js","sourceRoot":"","sources":["../../src/routing/format-play-route-transitions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGnD;;;;;;;;;;GAUG;AACH,MAAM,kBAAkB,GAAG,CAC1B,IAAwC,EACxC,IAA4B,EACH,EAAE,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"format-play-route-transitions.js","sourceRoot":"","sources":["../../src/routing/format-play-route-transitions.ts"],"names":[],"mappings":"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"}
|
package/dist/routing/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* The utilities of the route derivation and of the URL construction
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* This module gives you the functions that read a route from the state metadata, and
|
|
5
|
+
* that build a complete URL with the substitution of each parameter.
|
|
6
6
|
*
|
|
7
7
|
* @packageDocumentation
|
|
8
8
|
*/
|
package/dist/routing/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* The utilities of the route derivation and of the URL construction
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* This module gives you the functions that read a route from the state metadata, and
|
|
5
|
+
* that build a complete URL with the substitution of each parameter.
|
|
6
6
|
*
|
|
7
7
|
* @packageDocumentation
|
|
8
8
|
*/
|
package/dist/routing/types.d.ts
CHANGED
|
@@ -4,24 +4,25 @@ export interface RouteObject {
|
|
|
4
4
|
}
|
|
5
5
|
export type RouteMetadata = string | RouteObject;
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* The context of the route construction, from the machine context.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* Every substitution of a URL parameter reads `params`, because the type reads no
|
|
10
|
+
* flat context field. This is deliberate: the type has no index signature now, and
|
|
11
|
+
* the compiler therefore checks the shape of a context, and the IDE completes each
|
|
12
|
+
* context field.
|
|
12
13
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* must
|
|
14
|
+
* A machine with `formatPlayRouteTransitions` receives its `params` field and its
|
|
15
|
+
* `query` field from each `play.route` event, and the transitions assign them. A
|
|
16
|
+
* machine that calls `buildRouteUrl` itself must fill `params` itself.
|
|
16
17
|
*/
|
|
17
18
|
export interface RouteContext {
|
|
18
|
-
/**
|
|
19
|
+
/** The base path of a relative route */
|
|
19
20
|
basePath?: string;
|
|
20
|
-
/**
|
|
21
|
+
/** The parameters of the path to substitute, for example `:userId` of `/profile/:userId` */
|
|
21
22
|
params?: Record<string, unknown>;
|
|
22
|
-
/**
|
|
23
|
+
/** The query parameters */
|
|
23
24
|
query?: Record<string, unknown>;
|
|
24
|
-
/**
|
|
25
|
+
/** The hash fragment */
|
|
25
26
|
hash?: string;
|
|
26
27
|
}
|
|
27
28
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/routing/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,WAAW,CAAC;AAEjD
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/routing/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,WAAW,CAAC;AAEjD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,YAAY;IAC5B,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4FAA4F;IAC5F,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,wBAAwB;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;CACd"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,80 +1,83 @@
|
|
|
1
1
|
import type { ActorOptions, AnyStateMachine, InputFrom, SnapshotFrom } from "xstate";
|
|
2
2
|
import type { PlayerActor as PlayerActorClass } from "./player-actor.js";
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* The configuration of definePlayer()
|
|
5
5
|
*/
|
|
6
6
|
export interface PlayerConfig<TMachine extends AnyStateMachine> {
|
|
7
|
-
/** XState v5 state machine */
|
|
7
|
+
/** The XState v5 state machine */
|
|
8
8
|
machine: TMachine;
|
|
9
|
-
/**
|
|
9
|
+
/** The lifecycle hooks and the configuration */
|
|
10
10
|
options?: PlayerOptions<TMachine>;
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
13
|
+
* The lifecycle hooks of the player — the observability surface around the actor.
|
|
14
14
|
*/
|
|
15
15
|
export interface PlayerOptions<TMachine extends AnyStateMachine> {
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
17
|
+
* The actor calls it on each real start, which is every transition from "not
|
|
18
|
+
* running" to "running". A start after a stop is such a transition. A second
|
|
19
|
+
* `start()` call while the actor runs fires the hook not again.
|
|
20
20
|
*/
|
|
21
21
|
onStart?: (actor: PlayerActorClass<TMachine>) => void;
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
24
|
-
* down.
|
|
25
|
-
* never started
|
|
23
|
+
* The actor calls it on each real stop, which means only after it tore a running
|
|
24
|
+
* actor down. A second `stop()` call, a second `dispose()` call, and a stop of an
|
|
25
|
+
* actor that never started fire the hook not.
|
|
26
26
|
*/
|
|
27
27
|
onStop?: (actor: PlayerActorClass<TMachine>) => void;
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
30
|
-
* machine ignores,
|
|
31
|
-
* snapshot. Compare the two when only real
|
|
29
|
+
* The actor calls it after every event that `send()` processes. This includes an
|
|
30
|
+
* event that the machine ignores, and `prevState` and `nextState` are then the same
|
|
31
|
+
* snapshot. Compare the two values when only a real transition is important to
|
|
32
|
+
* you.
|
|
32
33
|
*/
|
|
33
34
|
onTransition?: (actor: PlayerActorClass<TMachine>, prevState: SnapshotFrom<TMachine>, nextState: SnapshotFrom<TMachine>) => void;
|
|
34
|
-
/**
|
|
35
|
+
/** The actor calls it when the state signal changes */
|
|
35
36
|
onStateChange?: (actor: PlayerActorClass<TMachine>, state: SnapshotFrom<TMachine>) => void;
|
|
36
37
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
38
|
+
* The actor calls it on an actor error: a snapshot restore that fails at `start()`,
|
|
39
|
+
* an action or a guard that throws, and a failure of the view derivation.
|
|
39
40
|
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
41
|
+
* The actor reads this field at the moment of the delivery of an error, and not at
|
|
42
|
+
* its construction. The options object is shared by its reference. Therefore a
|
|
43
|
+
* handler on that object still receives each actor error, also after a later
|
|
44
|
+
* attachment, and the removal of the handler restores the loud default below.
|
|
43
45
|
*
|
|
44
|
-
* With a handler in place, the
|
|
45
|
-
* handled. XState decides its global rethrow
|
|
46
|
-
*
|
|
47
|
-
* still forces
|
|
46
|
+
* With a handler in place, the actor sends the error there, and the error counts as
|
|
47
|
+
* handled. XState decides its own global rethrow for each observer, and this option
|
|
48
|
+
* does not reach that decision: a subscription of your own without an `error`
|
|
49
|
+
* listener still forces the rethrow, with an `onError` handler and without one.
|
|
48
50
|
*
|
|
49
|
-
* Without `onError`, actor
|
|
50
|
-
* `setTimeout
|
|
51
|
-
*
|
|
51
|
+
* Without `onError`, each actor error stays loud, with an unhandled rethrow through
|
|
52
|
+
* `setTimeout`. No error therefore disappears in silence. Your own `error`
|
|
53
|
+
* subscribers stop that default not: `onError` alone stops it.
|
|
52
54
|
*
|
|
53
|
-
*
|
|
54
|
-
* identity the machine
|
|
55
|
-
* arrives as `ActorThrewNonErrorError
|
|
55
|
+
* A failure of the actor that is an `Error` already arrives without a change, and it
|
|
56
|
+
* keeps the identity of the machine. A machine that throws a value that is not an
|
|
57
|
+
* `Error` arrives as an `ActorThrewNonErrorError`, with the value from the throw on
|
|
58
|
+
* its `cause` field.
|
|
56
59
|
*/
|
|
57
60
|
onError?: (actor: PlayerActorClass<TMachine>, error: Error) => void;
|
|
58
61
|
/**
|
|
59
|
-
*
|
|
62
|
+
* The inspection observer. The factory gives it to `createActor` of XState without
|
|
63
|
+
* a change.
|
|
60
64
|
*
|
|
61
|
-
* This is the
|
|
62
|
-
* the
|
|
63
|
-
* `actor.system.inspect(fn)
|
|
64
|
-
*
|
|
65
|
+
* This is the attachment at the moment of the creation, and it is the only route
|
|
66
|
+
* that observes the construction events of the actor. An attachment later, with
|
|
67
|
+
* `actor.system.inspect(fn)`, also works, but it sees only the events after that
|
|
68
|
+
* moment.
|
|
65
69
|
*
|
|
66
|
-
* A `PlayerActor` is
|
|
67
|
-
* `actorRef === playerActor
|
|
68
|
-
* `PlayerActor` is also its own root system
|
|
69
|
-
* actor.sessionId`
|
|
70
|
-
* invoked and spawned
|
|
70
|
+
* A `PlayerActor` is the XState actor itself. Therefore its own events carry
|
|
71
|
+
* `actorRef === playerActor`, and you can recognize it by its identity. Each
|
|
72
|
+
* `PlayerActor` is also its own root system. Therefore `event.rootId ===
|
|
73
|
+
* actor.sessionId` separates the complete tree, and this includes the events of an
|
|
74
|
+
* invoked child and of a spawned child, whose `actorRef` is the child.
|
|
71
75
|
*
|
|
72
|
-
*
|
|
73
|
-
* inside the
|
|
74
|
-
*
|
|
75
|
-
* `initialRoute` do not exist yet
|
|
76
|
-
* reference and read the signals from a later event, or
|
|
77
|
-
* observer.
|
|
76
|
+
* That identity brings one point to note: the `@xstate.actor` event fires from
|
|
77
|
+
* inside the constructor of the actor. Its `actorRef` value is therefore the
|
|
78
|
+
* instance during the construction, and `state`, `currentRoute`, `currentView`, and
|
|
79
|
+
* `initialRoute` do not exist yet. A read of one of them there throws. Keep the
|
|
80
|
+
* reference, and read the signals from a later event, or outside the observer.
|
|
78
81
|
*
|
|
79
82
|
* @example
|
|
80
83
|
* ```typescript
|
|
@@ -84,35 +87,36 @@ export interface PlayerOptions<TMachine extends AnyStateMachine> {
|
|
|
84
87
|
* const createPlayer = definePlayer({ machine, options: { inspect } });
|
|
85
88
|
* ```
|
|
86
89
|
*
|
|
87
|
-
* For an inspector
|
|
88
|
-
*
|
|
90
|
+
* For an inspector that you create after the factory, for example behind a dev-tools
|
|
91
|
+
* switch, give the factory a function that forwards each event:
|
|
92
|
+
* `inspect: (event) => currentInspector?.(event)`.
|
|
89
93
|
*/
|
|
90
94
|
inspect?: ActorOptions<TMachine>["inspect"];
|
|
91
95
|
}
|
|
92
96
|
/**
|
|
93
|
-
*
|
|
97
|
+
* The optional restore arguments of the player factory.
|
|
94
98
|
*
|
|
95
|
-
*
|
|
96
|
-
* `createPlayer(input?)` calling convention
|
|
99
|
+
* The shape follows the options object of `createActor` in XState. It also keeps the
|
|
100
|
+
* `createPlayer(input?)` calling convention of a new actor.
|
|
97
101
|
*/
|
|
98
102
|
export interface PlayerFactoryResumeOptions<TMachine extends AnyStateMachine> {
|
|
99
103
|
/**
|
|
100
|
-
*
|
|
104
|
+
* The persisted XState snapshot. The factory restores the actor state from it.
|
|
101
105
|
*
|
|
102
|
-
*
|
|
103
|
-
* `createActor` accepts and `getPersistedSnapshot()` returns
|
|
104
|
-
* a stored snapshot
|
|
106
|
+
* Its type is the `ActorOptions["snapshot"]` type of XState, which is the exact type
|
|
107
|
+
* that `createActor` accepts and that `getPersistedSnapshot()` returns. The restore
|
|
108
|
+
* of a stored snapshot therefore needs no cast.
|
|
105
109
|
*/
|
|
106
110
|
snapshot?: ActorOptions<TMachine>["snapshot"];
|
|
107
111
|
}
|
|
108
112
|
/**
|
|
109
|
-
*
|
|
110
|
-
*
|
|
113
|
+
* The factory function that definePlayer() returns. Each call makes an independent
|
|
114
|
+
* actor instance from the same configuration.
|
|
111
115
|
*
|
|
112
|
-
*
|
|
113
|
-
* cannot be `undefined
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
+
* The `input` argument follows the rule of `createActor` in XState. If the input of
|
|
117
|
+
* a machine cannot be `undefined`, the first argument of the factory is necessary.
|
|
118
|
+
* An absent input is then a compile error, and not an actor that starts in an error
|
|
119
|
+
* status with a `null` initial route.
|
|
116
120
|
*/
|
|
117
121
|
export type PlayerFactory<TMachine extends AnyStateMachine> = undefined extends InputFrom<TMachine> ? (input?: InputFrom<TMachine>, options?: PlayerFactoryResumeOptions<TMachine>) => PlayerActorClass<TMachine> : (input: InputFrom<TMachine>, options?: PlayerFactoryResumeOptions<TMachine>) => PlayerActorClass<TMachine>;
|
|
118
122
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACrF,OAAO,KAAK,EAAE,WAAW,IAAI,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAEzE;;GAEG;AACH,MAAM,WAAW,YAAY,CAAC,QAAQ,SAAS,eAAe;IAC7D,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACrF,OAAO,KAAK,EAAE,WAAW,IAAI,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAEzE;;GAEG;AACH,MAAM,WAAW,YAAY,CAAC,QAAQ,SAAS,eAAe;IAC7D,kCAAkC;IAClC,OAAO,EAAE,QAAQ,CAAC;IAElB,gDAAgD;IAChD,OAAO,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,QAAQ,SAAS,eAAe;IAC9D;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;IAEtD;;;;OAIG;IACH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;IAErD;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CACd,KAAK,EAAE,gBAAgB,CAAC,QAAQ,CAAC,EACjC,SAAS,EAAE,YAAY,CAAC,QAAQ,CAAC,EACjC,SAAS,EAAE,YAAY,CAAC,QAAQ,CAAC,KAC7B,IAAI,CAAC;IAEV,uDAAuD;IACvD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;IAE3F;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAEpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;IACH,OAAO,CAAC,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC;CAC5C;AAED;;;;;GAKG;AACH,MAAM,WAAW,0BAA0B,CAAC,QAAQ,SAAS,eAAe;IAC3E;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,CAAC;CAC9C;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,CAAC,QAAQ,SAAS,eAAe,IACzD,SAAS,SAAS,SAAS,CAAC,QAAQ,CAAC,GAClC,CACA,KAAK,CAAC,EAAE,SAAS,CAAC,QAAQ,CAAC,EAC3B,OAAO,CAAC,EAAE,0BAA0B,CAAC,QAAQ,CAAC,KAC1C,gBAAgB,CAAC,QAAQ,CAAC,GAC9B,CACA,KAAK,EAAE,SAAS,CAAC,QAAQ,CAAC,EAC1B,OAAO,CAAC,EAAE,0BAA0B,CAAC,QAAQ,CAAC,KAC1C,gBAAgB,CAAC,QAAQ,CAAC,CAAC"}
|
|
@@ -1,49 +1,51 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* The view derivation — the meta.view half of the player pipeline.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* signals, hooks, and lifecycle. The
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* This file is beside src/routing/, so that player-actor.ts holds the actor
|
|
5
|
+
* itself only: the signals, the hooks, and the lifecycle. The walk over the active
|
|
6
|
+
* branch is shared with the route derivation. Therefore the view of a parallel
|
|
7
|
+
* machine always belongs to the region of its URL.
|
|
8
8
|
*/
|
|
9
9
|
import type { AnyMachineSnapshot } from "xstate";
|
|
10
10
|
import { type PlaySpec } from "@xmachines/play-actor";
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* the UI on every event.
|
|
21
|
-
*
|
|
22
|
-
* ###
|
|
23
|
-
*
|
|
24
|
-
* The
|
|
25
|
-
* read-only `/context` subtree:
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* the
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
12
|
+
* Derives the current view of the actor from the state metadata.
|
|
13
|
+
*
|
|
14
|
+
* The function always returns a **fresh** `PlaySpec` object. The `Object.is`
|
|
15
|
+
* equality test of `Signal.State` therefore stops no real change of the view.
|
|
16
|
+
* `PlayerActor.validateAndCacheView` decides if the actor emits that fresh object:
|
|
17
|
+
* it compares the object with the last spec of an emission, it reuses the reference
|
|
18
|
+
* of the composed `state` field when the value of the projection did not change, and
|
|
19
|
+
* it emits nothing when the view on the screen is the same. A provider below the
|
|
20
|
+
* actor therefore mounts the UI again not on every event.
|
|
21
|
+
*
|
|
22
|
+
* ### The context projection
|
|
23
|
+
*
|
|
24
|
+
* The function projects the context of the machine into the `state` field of the
|
|
25
|
+
* derived spec, under the read-only `/context` subtree:
|
|
26
|
+
* `state: { ...meta.view.state, context: slice }`. The spec of the emission is
|
|
27
|
+
* therefore **consistent with itself**, and its `state` field describes the contents
|
|
28
|
+
* of the store correctly. `repeat.statePath: "/context/tasks"`,
|
|
29
|
+
* `visible: { $state: "/context/…" }`, and a `{ $state: "/context/…" }` prop all
|
|
30
|
+
* resolve through the ordinary state grammar. A tool such as `validateSpec` also
|
|
31
|
+
* passes on a derived view, with no special case. Validate the derived view, and not
|
|
32
|
+
* the raw `meta.view`.
|
|
33
|
+
*
|
|
34
|
+
* The store always holds the complete context. The function changes the authored
|
|
35
|
+
* `meta.view` object never.
|
|
36
|
+
*
|
|
37
|
+
* ### The viewKey
|
|
38
|
+
*
|
|
39
|
+
* The derived spec carries a `viewKey` field. Its value is the key of the meta
|
|
40
|
+
* record, which is the id of the state node, of the entry that this derivation
|
|
41
|
+
* selected. A provider uses it as the key of its store lifecycle: a new key seeds
|
|
42
|
+
* the store again, and the same key refreshes `/context` in place. The value comes
|
|
43
|
+
* from the selected entry, and not from "the id of the active state", because for a
|
|
44
|
+
* parallel machine the branch of the walk and the flat `getMeta()` fallback can
|
|
45
|
+
* select a view of a different region than the leaf of the branch.
|
|
46
|
+
*
|
|
47
|
+
* @param snapshot - The current snapshot of the XState machine.
|
|
48
|
+
* @returns The derived `PlaySpec`, or `null` when the current state has no view metadata.
|
|
47
49
|
*/
|
|
48
50
|
export declare const deriveCurrentView: (snapshot: AnyMachineSnapshot) => PlaySpec | null;
|
|
49
51
|
//# sourceMappingURL=derive-current-view.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derive-current-view.d.ts","sourceRoot":"","sources":["../../src/view/derive-current-view.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,EAAiC,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"derive-current-view.d.ts","sourceRoot":"","sources":["../../src/view/derive-current-view.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,EAAiC,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAwDrF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,eAAO,MAAM,iBAAiB,GAAI,UAAU,kBAAkB,KAAG,QAAQ,GAAG,IA4C3E,CAAC"}
|