@xmachines/play-xstate 2.2.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 +158 -54
- package/dist/capabilities.d.ts +92 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +4 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/define-player.d.ts +7 -1
- package/dist/define-player.d.ts.map +1 -1
- package/dist/define-player.js +9 -60
- package/dist/define-player.js.map +1 -1
- package/dist/errors.d.ts +29 -26
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +53 -35
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +3 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -4
- package/dist/index.js.map +1 -1
- package/dist/player-actor.d.ts +74 -114
- package/dist/player-actor.d.ts.map +1 -1
- package/dist/player-actor.js +94 -223
- package/dist/player-actor.js.map +1 -1
- package/dist/routing/derive-current-route.d.ts +1 -36
- package/dist/routing/derive-current-route.d.ts.map +1 -1
- package/dist/routing/derive-current-route.js +2 -76
- package/dist/routing/derive-current-route.js.map +1 -1
- package/dist/routing/derive-initial-route.d.ts.map +1 -1
- package/dist/routing/derive-initial-route.js +11 -0
- package/dist/routing/derive-initial-route.js.map +1 -1
- package/dist/routing/derive-route.d.ts +81 -2
- package/dist/routing/derive-route.d.ts.map +1 -1
- package/dist/routing/derive-route.js +97 -3
- package/dist/routing/derive-route.js.map +1 -1
- package/dist/routing/format-play-route-transitions.d.ts +8 -2
- package/dist/routing/format-play-route-transitions.d.ts.map +1 -1
- package/dist/routing/format-play-route-transitions.js +170 -43
- package/dist/routing/format-play-route-transitions.js.map +1 -1
- package/dist/routing/index.d.ts +1 -1
- package/dist/routing/index.d.ts.map +1 -1
- package/dist/routing/types.d.ts +9 -5
- package/dist/routing/types.d.ts.map +1 -1
- package/dist/state-meta.d.ts +52 -0
- package/dist/state-meta.d.ts.map +1 -0
- package/dist/state-meta.js +77 -0
- package/dist/state-meta.js.map +1 -0
- package/dist/types.d.ts +18 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/view/derive-current-view.d.ts +1 -1
- package/dist/view/derive-current-view.d.ts.map +1 -1
- package/dist/view/derive-current-view.js +35 -17
- package/dist/view/derive-current-view.js.map +1 -1
- package/dist/with-routing.d.ts +45 -0
- package/dist/with-routing.d.ts.map +1 -0
- package/dist/with-routing.js +78 -0
- package/dist/with-routing.js.map +1 -0
- package/dist/with-view.d.ts +42 -0
- package/dist/with-view.d.ts.map +1 -0
- package/dist/with-view.js +150 -0
- package/dist/with-view.js.map +1 -0
- package/package.json +39 -18
- package/dist/guards/compose.d.ts +0 -158
- package/dist/guards/compose.d.ts.map +0 -1
- package/dist/guards/compose.js +0 -188
- package/dist/guards/compose.js.map +0 -1
- package/dist/guards/helpers.d.ts +0 -62
- package/dist/guards/helpers.d.ts.map +0 -1
- package/dist/guards/helpers.js +0 -85
- package/dist/guards/helpers.js.map +0 -1
- package/dist/guards/index.d.ts +0 -20
- package/dist/guards/index.d.ts.map +0 -1
- package/dist/guards/index.js +0 -18
- package/dist/guards/index.js.map +0 -1
- package/dist/guards/types.d.ts +0 -22
- package/dist/guards/types.d.ts.map +0 -1
- package/dist/guards/types.js +0 -2
- package/dist/guards/types.js.map +0 -1
package/dist/routing/types.d.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
/**
|
|
2
|
+
* `RouteObject` and `RouteMetadata` have ONE definition, and it lives in
|
|
3
|
+
* `@xmachines/play-router`. That package owns the routing protocol, and this package
|
|
4
|
+
* consumes it. A second definition here would be a copy that drifts: a field added to
|
|
5
|
+
* one of them would leave the other behind, and nothing would fail.
|
|
6
|
+
*
|
|
7
|
+
* The re-export keeps the import path of every consumer of this package unchanged.
|
|
8
|
+
*/
|
|
9
|
+
export type { RouteObject, RouteMetadata, RouteData, RouteDataResolver, } from "@xmachines/play-router";
|
|
6
10
|
/**
|
|
7
11
|
* The context of the route construction, from the machine context.
|
|
8
12
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/routing/types.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/routing/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,YAAY,EACX,WAAW,EACX,aAAa,EACb,SAAS,EACT,iBAAiB,GACjB,MAAM,wBAAwB,CAAC;AAEhC;;;;;;;;;;;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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The read of the `meta` of the active states, which BOTH capabilities share.
|
|
3
|
+
*
|
|
4
|
+
* `deriveCurrentRoute` folds this record into a URL, and `deriveCurrentView` folds the
|
|
5
|
+
* same record into a view spec. The two therefore cannot move apart on the selection of
|
|
6
|
+
* the branch, and they cannot move apart on their tolerance of a degenerate snapshot.
|
|
7
|
+
*
|
|
8
|
+
* It lives in its own module, and no longer beside the route derivation, because it
|
|
9
|
+
* belongs to neither capability. `@xmachines/play-xstate/view` imported it from
|
|
10
|
+
* `routing/derive-current-route.ts`, and that module reads `deriveRoute`, which names
|
|
11
|
+
* `@xmachines/play-router`. A view-only application therefore loaded the whole route
|
|
12
|
+
* derivation, and the OPTIONAL peer of the routing reached the runtime graph of the view
|
|
13
|
+
* entry point.
|
|
14
|
+
*/
|
|
15
|
+
import type { AnyMachineSnapshot } from "xstate";
|
|
16
|
+
/**
|
|
17
|
+
* Collects the `meta` object of the active state nodes of a SINGLE branch, from the
|
|
18
|
+
* root to a leaf. The key of each entry is the state id, and the order is the
|
|
19
|
+
* ancestors first. {@link deriveRoute} folds this shape.
|
|
20
|
+
*
|
|
21
|
+
* `snapshot.getMeta()` returns a FLAT record of the meta object of every active
|
|
22
|
+
* state. For a machine that is not parallel, that record is one chain of ancestors
|
|
23
|
+
* already. For a PARALLEL machine, it mixes the entries of every active region. A
|
|
24
|
+
* blind fold therefore joins a relative route of one region to an absolute route of
|
|
25
|
+
* a sibling region, and the URL belongs to the tree of neither region. The flat
|
|
26
|
+
* record also cannot go back into a hierarchy: when a state declares an explicit
|
|
27
|
+
* `id`, for example a child with `id: "dashboard-overview"` under `id: "dashboard"`,
|
|
28
|
+
* the meta keys are those ids, and they carry no information about the ancestry.
|
|
29
|
+
*
|
|
30
|
+
* Therefore this function walks `snapshot.value`, which holds the real hierarchy of
|
|
31
|
+
* the active states by the state key, against the node tree of the machine. It
|
|
32
|
+
* follows the FIRST active child at each level. This gives one deterministic branch,
|
|
33
|
+
* which matches the historical behavior of "the first that it finds" for a parallel
|
|
34
|
+
* machine. It also works with an explicit id, because each node carries its own `id`
|
|
35
|
+
* and its own `meta`.
|
|
36
|
+
*
|
|
37
|
+
* The function returns `null` when the snapshot exposes no machine and no value to
|
|
38
|
+
* walk. This is a defensive measure, because a real XState snapshot always exposes
|
|
39
|
+
* them. The caller then uses `getMeta()`, as before.
|
|
40
|
+
*/
|
|
41
|
+
export declare const firstActiveBranchMeta: (snapshot: AnyMachineSnapshot) => Record<string, unknown> | null;
|
|
42
|
+
/**
|
|
43
|
+
* Resolves the meta record that the route derivation and the view derivation fold:
|
|
44
|
+
* the single active branch that {@link firstActiveBranchMeta} walks, which is
|
|
45
|
+
* correct for a parallel machine and for an explicit id, or the flat `getMeta()`
|
|
46
|
+
* record when the snapshot has no machine tree to walk. `deriveCurrentRoute` and
|
|
47
|
+
* `deriveCurrentView` share this function. Therefore the two sides cannot move apart
|
|
48
|
+
* on the selection of the branch, and they cannot move apart on their tolerance of a
|
|
49
|
+
* degenerate snapshot.
|
|
50
|
+
*/
|
|
51
|
+
export declare const activeStateMeta: (snapshot: AnyMachineSnapshot) => Record<string, unknown> | null;
|
|
52
|
+
//# sourceMappingURL=state-meta.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-meta.d.ts","sourceRoot":"","sources":["../src/state-meta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAEjD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,qBAAqB,GACjC,UAAU,kBAAkB,KAC1B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAqC5B,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,GAAI,UAAU,kBAAkB,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAMxF,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collects the `meta` object of the active state nodes of a SINGLE branch, from the
|
|
3
|
+
* root to a leaf. The key of each entry is the state id, and the order is the
|
|
4
|
+
* ancestors first. {@link deriveRoute} folds this shape.
|
|
5
|
+
*
|
|
6
|
+
* `snapshot.getMeta()` returns a FLAT record of the meta object of every active
|
|
7
|
+
* state. For a machine that is not parallel, that record is one chain of ancestors
|
|
8
|
+
* already. For a PARALLEL machine, it mixes the entries of every active region. A
|
|
9
|
+
* blind fold therefore joins a relative route of one region to an absolute route of
|
|
10
|
+
* a sibling region, and the URL belongs to the tree of neither region. The flat
|
|
11
|
+
* record also cannot go back into a hierarchy: when a state declares an explicit
|
|
12
|
+
* `id`, for example a child with `id: "dashboard-overview"` under `id: "dashboard"`,
|
|
13
|
+
* the meta keys are those ids, and they carry no information about the ancestry.
|
|
14
|
+
*
|
|
15
|
+
* Therefore this function walks `snapshot.value`, which holds the real hierarchy of
|
|
16
|
+
* the active states by the state key, against the node tree of the machine. It
|
|
17
|
+
* follows the FIRST active child at each level. This gives one deterministic branch,
|
|
18
|
+
* which matches the historical behavior of "the first that it finds" for a parallel
|
|
19
|
+
* machine. It also works with an explicit id, because each node carries its own `id`
|
|
20
|
+
* and its own `meta`.
|
|
21
|
+
*
|
|
22
|
+
* The function returns `null` when the snapshot exposes no machine and no value to
|
|
23
|
+
* walk. This is a defensive measure, because a real XState snapshot always exposes
|
|
24
|
+
* them. The caller then uses `getMeta()`, as before.
|
|
25
|
+
*/
|
|
26
|
+
export const firstActiveBranchMeta = (snapshot) => {
|
|
27
|
+
const root = snapshot.machine?.root;
|
|
28
|
+
if (!root)
|
|
29
|
+
return null;
|
|
30
|
+
const ordered = {};
|
|
31
|
+
let node = root;
|
|
32
|
+
let value = snapshot.value;
|
|
33
|
+
while (node) {
|
|
34
|
+
if (node.meta && typeof node.meta === "object") {
|
|
35
|
+
ordered[node.id] = node.meta; // nosemgrep: gitlab.eslint.detect-object-injection
|
|
36
|
+
}
|
|
37
|
+
// Find the key of the active child at this level. A string value is the name of an
|
|
38
|
+
// atomic active leaf. An object value is a compound node, with one key, or a
|
|
39
|
+
// parallel node, with many keys: take the first key, for one deterministic
|
|
40
|
+
// branch.
|
|
41
|
+
let key;
|
|
42
|
+
if (typeof value === "string") {
|
|
43
|
+
key = value;
|
|
44
|
+
}
|
|
45
|
+
else if (value && typeof value === "object") {
|
|
46
|
+
key = Object.keys(value)[0];
|
|
47
|
+
}
|
|
48
|
+
if (key === undefined)
|
|
49
|
+
break;
|
|
50
|
+
const child = node.states?.[key]; // nosemgrep: gitlab.eslint.detect-object-injection
|
|
51
|
+
if (!child)
|
|
52
|
+
break;
|
|
53
|
+
value =
|
|
54
|
+
typeof value === "object" && value !== null
|
|
55
|
+
? value[key] // nosemgrep: gitlab.eslint.detect-object-injection
|
|
56
|
+
: {};
|
|
57
|
+
node = child;
|
|
58
|
+
}
|
|
59
|
+
return ordered;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Resolves the meta record that the route derivation and the view derivation fold:
|
|
63
|
+
* the single active branch that {@link firstActiveBranchMeta} walks, which is
|
|
64
|
+
* correct for a parallel machine and for an explicit id, or the flat `getMeta()`
|
|
65
|
+
* record when the snapshot has no machine tree to walk. `deriveCurrentRoute` and
|
|
66
|
+
* `deriveCurrentView` share this function. Therefore the two sides cannot move apart
|
|
67
|
+
* on the selection of the branch, and they cannot move apart on their tolerance of a
|
|
68
|
+
* degenerate snapshot.
|
|
69
|
+
*/
|
|
70
|
+
export const activeStateMeta = (snapshot) => {
|
|
71
|
+
if (!snapshot || typeof snapshot.getMeta !== "function") {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
const meta = firstActiveBranchMeta(snapshot) ?? snapshot.getMeta();
|
|
75
|
+
return meta && typeof meta === "object" ? meta : null;
|
|
76
|
+
};
|
|
77
|
+
//# sourceMappingURL=state-meta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-meta.js","sourceRoot":"","sources":["../src/state-meta.ts"],"names":[],"mappings":"AAgBA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACpC,QAA4B,EACK,EAAE;IACnC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,IAEnB,CAAC;IACb,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAEvB,MAAM,OAAO,GAA4B,EAAE,CAAC;IAC5C,IAAI,IAAI,GAA4B,IAAI,CAAC;IACzC,IAAI,KAAK,GAAY,QAAQ,CAAC,KAAK,CAAC;IAEpC,OAAO,IAAI,EAAE,CAAC;QACb,IAAI,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAChD,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,mDAAmD;QAClF,CAAC;QAED,mFAAmF;QACnF,6EAA6E;QAC7E,2EAA2E;QAC3E,UAAU;QACV,IAAI,GAAuB,CAAC;QAC5B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC/B,GAAG,GAAG,KAAK,CAAC;QACb,CAAC;aAAM,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC/C,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC;QACD,IAAI,GAAG,KAAK,SAAS;YAAE,MAAM;QAE7B,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,CAA4B,CAAC,CAAC,mDAAmD;QAChH,IAAI,CAAC,KAAK;YAAE,MAAM;QAClB,KAAK;YACJ,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;gBAC1C,CAAC,CAAE,KAAiC,CAAC,GAAG,CAAC,CAAC,mDAAmD;gBAC7F,CAAC,CAAC,EAAE,CAAC;QACP,IAAI,GAAG,KAAK,CAAC;IACd,CAAC;IAED,OAAO,OAAO,CAAC;AAChB,CAAC,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,QAA4B,EAAkC,EAAE;IAC/F,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QACzD,OAAO,IAAI,CAAC;IACb,CAAC;IACD,MAAM,IAAI,GAAG,qBAAqB,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;IACnE,OAAO,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAE,IAAgC,CAAC,CAAC,CAAC,IAAI,CAAC;AACpF,CAAC,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
import type { ActorOptions, AnyStateMachine, InputFrom, SnapshotFrom } from "xstate";
|
|
2
2
|
import type { PlayerActor as PlayerActorClass } from "./player-actor.js";
|
|
3
|
+
import type { PlayerConstructor } from "./capabilities.js";
|
|
3
4
|
/**
|
|
4
5
|
* The configuration of definePlayer()
|
|
5
6
|
*/
|
|
6
|
-
export interface PlayerConfig<TMachine extends AnyStateMachine> {
|
|
7
|
+
export interface PlayerConfig<TMachine extends AnyStateMachine, TCapabilities extends object = object> {
|
|
7
8
|
/** The XState v5 state machine */
|
|
8
9
|
machine: TMachine;
|
|
9
10
|
/** The lifecycle hooks and the configuration */
|
|
10
11
|
options?: PlayerOptions<TMachine>;
|
|
12
|
+
/**
|
|
13
|
+
* The actor class to build, which decides which CAPABILITIES the actor carries.
|
|
14
|
+
*
|
|
15
|
+
* `PlayerActor` is the default, and it holds `state` and `send` alone. Compose a class
|
|
16
|
+
* to add a capability, and the factory then answers an actor with it:
|
|
17
|
+
*
|
|
18
|
+
* ```typescript
|
|
19
|
+
* definePlayer({ machine, actor: compose(PlayerActor, withRouting, withView) });
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* An application that declares no route, and renders no view, passes nothing and loads
|
|
23
|
+
* neither body of code.
|
|
24
|
+
*/
|
|
25
|
+
actor?: PlayerConstructor<TMachine, TCapabilities>;
|
|
11
26
|
}
|
|
12
27
|
/**
|
|
13
28
|
* The lifecycle hooks of the player — the observability surface around the actor.
|
|
@@ -21,7 +36,7 @@ export interface PlayerOptions<TMachine extends AnyStateMachine> {
|
|
|
21
36
|
onStart?: (actor: PlayerActorClass<TMachine>) => void;
|
|
22
37
|
/**
|
|
23
38
|
* The actor calls it on each real stop, which means only after it tore a running
|
|
24
|
-
* actor down. A second `stop()` call,
|
|
39
|
+
* actor down. A second `stop()` call, and a stop of an
|
|
25
40
|
* actor that never started fire the hook not.
|
|
26
41
|
*/
|
|
27
42
|
onStop?: (actor: PlayerActorClass<TMachine>) => void;
|
|
@@ -118,5 +133,5 @@ export interface PlayerFactoryResumeOptions<TMachine extends AnyStateMachine> {
|
|
|
118
133
|
* An absent input is then a compile error, and not an actor that starts in an error
|
|
119
134
|
* status with a `null` initial route.
|
|
120
135
|
*/
|
|
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
|
|
136
|
+
export type PlayerFactory<TMachine extends AnyStateMachine, TCapabilities extends object = object> = undefined extends InputFrom<TMachine> ? (input?: InputFrom<TMachine>, options?: PlayerFactoryResumeOptions<TMachine>) => PlayerActorClass<TMachine> & TCapabilities : (input: InputFrom<TMachine>, options?: PlayerFactoryResumeOptions<TMachine>) => PlayerActorClass<TMachine> & TCapabilities;
|
|
122
137
|
//# 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;
|
|
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;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,YAAY,CAC5B,QAAQ,SAAS,eAAe,EAChC,aAAa,SAAS,MAAM,GAAG,MAAM;IAErC,kCAAkC;IAClC,OAAO,EAAE,QAAQ,CAAC;IAElB,gDAAgD;IAChD,OAAO,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IAElC;;;;;;;;;;;;OAYG;IACH,KAAK,CAAC,EAAE,iBAAiB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;CACnD;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,EAAE,aAAa,SAAS,MAAM,GAAG,MAAM,IAChG,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,GAAG,aAAa,GAC9C,CACA,KAAK,EAAE,SAAS,CAAC,QAAQ,CAAC,EAC1B,OAAO,CAAC,EAAE,0BAA0B,CAAC,QAAQ,CAAC,KAC1C,gBAAgB,CAAC,QAAQ,CAAC,GAAG,aAAa,CAAC"}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* machine always belongs to the region of its URL.
|
|
8
8
|
*/
|
|
9
9
|
import type { AnyMachineSnapshot } from "xstate";
|
|
10
|
-
import { type PlaySpec } from "@xmachines/play-
|
|
10
|
+
import { type PlaySpec } from "@xmachines/play-view";
|
|
11
11
|
/**
|
|
12
12
|
* Derives the current view of the actor from the state metadata.
|
|
13
13
|
*
|
|
@@ -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,
|
|
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,sBAAsB,CAAC;AAyEpF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,eAAO,MAAM,iBAAiB,GAAI,UAAU,kBAAkB,KAAG,QAAQ,GAAG,IA4C3E,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { composePlayState, toAtomState } from "@xmachines/play-
|
|
2
|
-
import { activeStateMeta } from "../
|
|
1
|
+
import { composePlayState, toAtomState } from "@xmachines/play-view";
|
|
2
|
+
import { activeStateMeta } from "../state-meta.js";
|
|
3
3
|
/**
|
|
4
4
|
* The migration warning of the `contextProps` field, which 1.x removed. The code
|
|
5
5
|
* writes it one time for each spec. A meta.view object from a person passes around
|
|
@@ -17,22 +17,40 @@ const warnRemovedContextProps = (viewMeta) => {
|
|
|
17
17
|
console.warn("[play-xstate] meta.view.contextProps has been removed: the whole machine context " +
|
|
18
18
|
"is always projected under /context. Delete the field — it no longer filters anything.");
|
|
19
19
|
};
|
|
20
|
+
/** Reads the `view` of one meta entry, when the entry holds a whole PlaySpec. */
|
|
21
|
+
const viewOfEntry = (stateMeta) => {
|
|
22
|
+
const maybeView = stateMeta && typeof stateMeta === "object"
|
|
23
|
+
? stateMeta.view
|
|
24
|
+
: undefined;
|
|
25
|
+
return maybeView &&
|
|
26
|
+
typeof maybeView === "object" &&
|
|
27
|
+
"root" in maybeView &&
|
|
28
|
+
"elements" in maybeView
|
|
29
|
+
? maybeView
|
|
30
|
+
: null;
|
|
31
|
+
};
|
|
20
32
|
const resolveViewMeta = (meta) => {
|
|
21
|
-
//
|
|
22
|
-
// ancestors first
|
|
23
|
-
// active state
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
// Take the LAST entry that holds a view, and not the first: snapshot.getMeta() puts
|
|
34
|
+
// the keys of the ancestors first, so the last match is the meta.view of the deepest
|
|
35
|
+
// active state. An ancestor hides it not.
|
|
36
|
+
//
|
|
37
|
+
// A walk from the end, and not a findLast or a mapped copy: this runs for each
|
|
38
|
+
// snapshot. The walk stops at the first match, and `viewOfEntry` runs one time for
|
|
39
|
+
// each entry that it visits — a `findLast` would run it a second time on the entry
|
|
40
|
+
// that its own predicate had already resolved, and a `map()` would visit every entry
|
|
41
|
+
// and allocate one object for each match before the search began.
|
|
42
|
+
//
|
|
43
|
+
// `toReversed()`, which copies, and not `reverse()`, which mutates: one spelling for
|
|
44
|
+
// one operation, beside the `toSorted()` that `unicorn/no-array-sort` asks for.
|
|
45
|
+
//
|
|
46
|
+
// The copy costs about 10 ns for the handful of entries that a state path holds, and
|
|
47
|
+
// `Object.entries` above it costs twenty times that. Measured, after a review called
|
|
48
|
+
// this line a cost of a hot path: it is not one, at any rate of snapshots that an
|
|
49
|
+
// actor produces.
|
|
50
|
+
for (const [key, stateMeta] of Object.entries(meta).toReversed()) {
|
|
51
|
+
const view = viewOfEntry(stateMeta);
|
|
52
|
+
if (view) {
|
|
53
|
+
return { key, view };
|
|
36
54
|
}
|
|
37
55
|
}
|
|
38
56
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derive-current-view.js","sourceRoot":"","sources":["../../src/view/derive-current-view.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAiB,MAAM,
|
|
1
|
+
{"version":3,"file":"derive-current-view.js","sourceRoot":"","sources":["../../src/view/derive-current-view.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAiB,MAAM,sBAAsB,CAAC;AAEpF,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AASnD;;;;;;;;GAQG;AACH,MAAM,kBAAkB,GAAG,IAAI,OAAO,EAAU,CAAC;AACjD,MAAM,uBAAuB,GAAG,CAAC,QAAgB,EAAQ,EAAE;IAC1D,IAAI,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC;QAAE,OAAO;IAC7C,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjC,OAAO,CAAC,IAAI,CACX,mFAAmF;QAClF,uFAAuF,CACxF,CAAC;AACH,CAAC,CAAC;AAEF,iFAAiF;AACjF,MAAM,WAAW,GAAG,CAAC,SAAkB,EAAmB,EAAE;IAC3D,MAAM,SAAS,GACd,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ;QACzC,CAAC,CAAE,SAAgC,CAAC,IAAI;QACxC,CAAC,CAAC,SAAS,CAAC;IAEd,OAAO,SAAS;QACf,OAAO,SAAS,KAAK,QAAQ;QAC7B,MAAM,IAAK,SAAoB;QAC/B,UAAU,IAAK,SAAoB;QACnC,CAAC,CAAE,SAAsB;QACzB,CAAC,CAAC,IAAI,CAAC;AACT,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,IAA6B,EAA2B,EAAE;IAClF,oFAAoF;IACpF,qFAAqF;IACrF,0CAA0C;IAC1C,EAAE;IACF,+EAA+E;IAC/E,mFAAmF;IACnF,mFAAmF;IACnF,qFAAqF;IACrF,kEAAkE;IAClE,EAAE;IACF,qFAAqF;IACrF,gFAAgF;IAChF,EAAE;IACF,qFAAqF;IACrF,qFAAqF;IACrF,kFAAkF;IAClF,kBAAkB;IAClB,KAAK,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC;QAClE,MAAM,IAAI,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;QACpC,IAAI,IAAI,EAAE,CAAC;YACV,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;QACtB,CAAC;IACF,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,QAA4B,EAAmB,EAAE;IAClF,mFAAmF;IACnF,kFAAkF;IAClF,0BAA0B;IAC1B,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,CAAC,IAAI,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACb,CAAC;IAED,iFAAiF;IACjF,oFAAoF;IACpF,oFAAoF;IACpF,qEAAqE;IACrE,IAAI,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;QACpC,IAAI,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC9C,QAAQ,GAAG,eAAe,CAAC,QAAmC,CAAC,CAAC;QACjE,CAAC;IACF,CAAC;IACD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACb,CAAC;IACD,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC;IAElD,IAAI,cAAc,IAAI,QAAQ,EAAE,CAAC;QAChC,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED,0EAA0E;IAC1E,qFAAqF;IACrF,8DAA8D;IAC9D,MAAM,KAAK,GACV,QAAQ,CAAC,OAAO,KAAK,IAAI,IAAI,OAAO,QAAQ,CAAC,OAAO,KAAK,QAAQ;QAChE,CAAC,CAAE,QAAQ,CAAC,OAAmC;QAC/C,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7F,MAAM,KAAK,GAAG,gBAAgB,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IAErD,OAAO;QACN,GAAG,QAAQ;QACX,OAAO;QACP,GAAG,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,CAAC;KACrC,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The routing capability of an XState actor, as a mixin.
|
|
3
|
+
*
|
|
4
|
+
* `PlayerActor` holds `state` and `send`, and nothing about a route. This module adds
|
|
5
|
+
* `currentRoute` and `initialRoute`, which is what `Routable` of `@xmachines/play-router`
|
|
6
|
+
* asks for and what every router bridge reads.
|
|
7
|
+
*
|
|
8
|
+
* It is a SEPARATE entry point, `@xmachines/play-xstate/routing`, and the core imports it
|
|
9
|
+
* never. `@xmachines/play-router` is an OPTIONAL peer of this package for the same reason:
|
|
10
|
+
* an application that declares no route installs neither that package nor the route map
|
|
11
|
+
* and the bridge that it carries.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { definePlayer, PlayerActor, compose } from "@xmachines/play-xstate";
|
|
16
|
+
* import { withRouting } from "@xmachines/play-xstate/routing";
|
|
17
|
+
*
|
|
18
|
+
* const createPlayer = definePlayer({ machine, actor: compose(PlayerActor, withRouting) });
|
|
19
|
+
* const actor = createPlayer();
|
|
20
|
+
* actor.currentRoute.get(); // "/profile/alice"
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @packageDocumentation
|
|
24
|
+
*/
|
|
25
|
+
import type { AnyStateMachine } from "xstate";
|
|
26
|
+
import type { Routable } from "@xmachines/play-router";
|
|
27
|
+
import type { PlayerConstructor } from "./capabilities.js";
|
|
28
|
+
/**
|
|
29
|
+
* Adds the routing capability to an actor class.
|
|
30
|
+
*
|
|
31
|
+
* The result satisfies `Routable`, so a router bridge accepts it. A class without this
|
|
32
|
+
* mixin exposes no `currentRoute`, and a bridge therefore refuses it when it compiles,
|
|
33
|
+
* rather than at the first navigation.
|
|
34
|
+
*
|
|
35
|
+
* The mixin declares NO constructor, and that is deliberate: TypeScript demands the
|
|
36
|
+
* signature `...args: any[]` from a mixin over a generic base (TS2545), and this
|
|
37
|
+
* workspace writes no `any`. A field initializer of a subclass runs after `super()`
|
|
38
|
+
* instead, and it reads the inputs that `PlayerActor` keeps for a capability.
|
|
39
|
+
*
|
|
40
|
+
* @param Base - The actor class to extend, normally `PlayerActor`.
|
|
41
|
+
*/
|
|
42
|
+
export declare function withRouting<TMachine extends AnyStateMachine>(Base: PlayerConstructor<TMachine>): PlayerConstructor<TMachine, Routable>;
|
|
43
|
+
export { deriveRoute, isAbsoluteRoute, buildRouteUrl, formatPlayRouteTransitions, } from "./routing/index.js";
|
|
44
|
+
export type { RouteMachineConfig, RouteStateNode, RouteContext, RouteObject, RouteMetadata, RouteData, RouteDataResolver, } from "./routing/index.js";
|
|
45
|
+
//# sourceMappingURL=with-routing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with-routing.d.ts","sourceRoot":"","sources":["../src/with-routing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAEvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG3D;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,QAAQ,SAAS,eAAe,EAC3D,IAAI,EAAE,iBAAiB,CAAC,QAAQ,CAAC,GAC/B,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAoDvC;AAcD,OAAO,EACN,WAAW,EACX,eAAe,EACf,aAAa,EACb,0BAA0B,GAC1B,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACX,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,WAAW,EACX,aAAa,EACb,SAAS,EACT,iBAAiB,GACjB,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { Signal } from "@xmachines/play-signals";
|
|
2
|
+
import { deriveCurrentRoute, deriveInitialRoute } from "./routing/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Adds the routing capability to an actor class.
|
|
5
|
+
*
|
|
6
|
+
* The result satisfies `Routable`, so a router bridge accepts it. A class without this
|
|
7
|
+
* mixin exposes no `currentRoute`, and a bridge therefore refuses it when it compiles,
|
|
8
|
+
* rather than at the first navigation.
|
|
9
|
+
*
|
|
10
|
+
* The mixin declares NO constructor, and that is deliberate: TypeScript demands the
|
|
11
|
+
* signature `...args: any[]` from a mixin over a generic base (TS2545), and this
|
|
12
|
+
* workspace writes no `any`. A field initializer of a subclass runs after `super()`
|
|
13
|
+
* instead, and it reads the inputs that `PlayerActor` keeps for a capability.
|
|
14
|
+
*
|
|
15
|
+
* @param Base - The actor class to extend, normally `PlayerActor`.
|
|
16
|
+
*/
|
|
17
|
+
export function withRouting(Base) {
|
|
18
|
+
class RoutableActor extends Base {
|
|
19
|
+
/**
|
|
20
|
+
* A TC39 `Signal.Computed`. It derives the current URL path from the `meta.route`
|
|
21
|
+
* template of the active machine state and from the context of the actor.
|
|
22
|
+
*
|
|
23
|
+
* It returns `null` when the current state has no `meta.route` field, and also when
|
|
24
|
+
* a necessary `:param` has no value in the context. The second case is normally
|
|
25
|
+
* temporary during a transition, and the signal computes the value again on the next
|
|
26
|
+
* snapshot.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* // It returns "/profile/alice" when context.params.userId === "alice",
|
|
31
|
+
* // and null while the param is still absent.
|
|
32
|
+
* const route = actor.currentRoute.get();
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
currentRoute = new Signal.Computed(() => deriveCurrentRoute(this.state.get()));
|
|
36
|
+
/**
|
|
37
|
+
* The route of the initial state of the machine. The construction fixes it, and it
|
|
38
|
+
* never changes, also when the code restores the actor from a snapshot.
|
|
39
|
+
*
|
|
40
|
+
* A router bridge compares it with the browser URL, and it therefore separates a
|
|
41
|
+
* deep link (a URL that is not the initial one → the router wins) from a restore
|
|
42
|
+
* (the initial URL, and the actor at a different route from the restore → the actor
|
|
43
|
+
* wins).
|
|
44
|
+
*
|
|
45
|
+
* `deriveInitialRoute` derives the value statically from the machine definition,
|
|
46
|
+
* with the pure `initialTransition` helper of XState: the chain of the initial states
|
|
47
|
+
* and their `meta.route` templates are fixed at the moment of the machine
|
|
48
|
+
* definition, and the substitution of a `:param` uses the real initial context of
|
|
49
|
+
* the machine for the `input` of this actor. The code makes no second actor, and a
|
|
50
|
+
* snapshot of a restore changes the value never: it is always the **default**
|
|
51
|
+
* initial route of the machine.
|
|
52
|
+
*
|
|
53
|
+
* Without a snapshot of a restore, the pre-start snapshot of this actor IS that
|
|
54
|
+
* default initial state, so the code derives the route from it directly. A restore
|
|
55
|
+
* alone needs `initialTransition`, whose inert actor scope runs the initial
|
|
56
|
+
* transition two more times, one of them with an undefined `input`. That is a quirk
|
|
57
|
+
* of XState, and it costs too much for every other case.
|
|
58
|
+
*/
|
|
59
|
+
initialRoute = this.playerRestoredSnapshot === undefined
|
|
60
|
+
? deriveCurrentRoute(this.getSnapshot())
|
|
61
|
+
: deriveInitialRoute(this.playerMachine, this.playerInput);
|
|
62
|
+
}
|
|
63
|
+
return RoutableActor;
|
|
64
|
+
}
|
|
65
|
+
// The utilities of the route derivation and of the URL construction.
|
|
66
|
+
//
|
|
67
|
+
// They belong HERE, and no longer on the main entry. Each one names
|
|
68
|
+
// `@xmachines/play-router` in its own `.d.ts` — `PlayRouteEvent`, `RouteData`,
|
|
69
|
+
// `RouteObject` and `RouteMetadata` all have their single definition there. That
|
|
70
|
+
// package is an OPTIONAL peer, so a main entry that reached them gave every consumer
|
|
71
|
+
// of `definePlayer` a type graph that names a package their node_modules does not
|
|
72
|
+
// hold. `skipLibCheck` hides the fault and does not remove it: the types resolve to
|
|
73
|
+
// nothing.
|
|
74
|
+
//
|
|
75
|
+
// The view half exposes nothing on the main entry, for the same reason. The two
|
|
76
|
+
// capabilities hold one shape.
|
|
77
|
+
export { deriveRoute, isAbsoluteRoute, buildRouteUrl, formatPlayRouteTransitions, } from "./routing/index.js";
|
|
78
|
+
//# sourceMappingURL=with-routing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with-routing.js","sourceRoot":"","sources":["../src/with-routing.ts"],"names":[],"mappings":"AAyBA,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAIjD,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE5E;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,WAAW,CAC1B,IAAiC;IAEjC,MAAM,aAAc,SAAQ,IAAI;QAC/B;;;;;;;;;;;;;;;WAeG;QACa,YAAY,GAAmC,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,CACvF,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CACpC,CAAC;QAEF;;;;;;;;;;;;;;;;;;;;;;WAsBG;QACa,YAAY,GAC3B,IAAI,CAAC,sBAAsB,KAAK,SAAS;YACxC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACxC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;KAC7D;IAED,OAAO,aAAa,CAAC;AACtB,CAAC;AAED,qEAAqE;AACrE,EAAE;AACF,oEAAoE;AACpE,+EAA+E;AAC/E,iFAAiF;AACjF,qFAAqF;AACrF,kFAAkF;AAClF,oFAAoF;AACpF,WAAW;AACX,EAAE;AACF,gFAAgF;AAChF,+BAA+B;AAC/B,OAAO,EACN,WAAW,EACX,eAAe,EACf,aAAa,EACb,0BAA0B,GAC1B,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The view capability of an XState actor, as a mixin.
|
|
3
|
+
*
|
|
4
|
+
* `PlayerActor` holds `state` and `send`, and nothing about a view. This module adds
|
|
5
|
+
* `currentView`, which is what `Viewable` of `@xmachines/play-view` asks for and what
|
|
6
|
+
* every renderer reads.
|
|
7
|
+
*
|
|
8
|
+
* It is a SEPARATE entry point, `@xmachines/play-xstate/view`, and the core imports it
|
|
9
|
+
* never. `@xmachines/play-view` is an OPTIONAL peer of this package for the same reason:
|
|
10
|
+
* an application that renders no view installs neither that package nor the json-render
|
|
11
|
+
* types that it names.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { definePlayer, PlayerActor, compose } from "@xmachines/play-xstate";
|
|
16
|
+
* import { withRouting } from "@xmachines/play-xstate/routing";
|
|
17
|
+
* import { withView } from "@xmachines/play-xstate/view";
|
|
18
|
+
*
|
|
19
|
+
* const createPlayer = definePlayer({
|
|
20
|
+
* machine,
|
|
21
|
+
* actor: compose(PlayerActor, withRouting, withView),
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @packageDocumentation
|
|
26
|
+
*/
|
|
27
|
+
import type { AnyStateMachine } from "xstate";
|
|
28
|
+
import { type Viewable } from "@xmachines/play-view";
|
|
29
|
+
import type { PlayerConstructor } from "./capabilities.js";
|
|
30
|
+
/**
|
|
31
|
+
* Adds the view capability to an actor class.
|
|
32
|
+
*
|
|
33
|
+
* Compose it AFTER the routing capability. An override calls `super.onSnapshot()` first,
|
|
34
|
+
* so `compose(PlayerActor, withRouting, withView)` gives the route its new value before
|
|
35
|
+
* the view derives from the same transition. A router bridge therefore sees a guard
|
|
36
|
+
* redirect before a renderer sees the view of the state that the guard refused.
|
|
37
|
+
*
|
|
38
|
+
* @param Base - The actor class to extend, normally `PlayerActor` or the result of
|
|
39
|
+
* another capability.
|
|
40
|
+
*/
|
|
41
|
+
export declare function withView<TMachine extends AnyStateMachine>(Base: PlayerConstructor<TMachine>): PlayerConstructor<TMachine, Viewable>;
|
|
42
|
+
//# sourceMappingURL=with-view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with-view.d.ts","sourceRoot":"","sources":["../src/with-view.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EAAsB,eAAe,EAAE,MAAM,QAAQ,CAAC;AAGlE,OAAO,EAAqC,KAAK,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAGxF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAsD3D;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,SAAS,eAAe,EACxD,IAAI,EAAE,iBAAiB,CAAC,QAAQ,CAAC,GAC/B,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAgFvC"}
|