@xmachines/play-xstate 6.0.0 → 7.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.
Files changed (45) hide show
  1. package/README.md +87 -28
  2. package/dist/capabilities.d.ts +2 -2
  3. package/dist/capabilities.js +6 -2
  4. package/dist/capabilities.js.map +1 -1
  5. package/dist/define-player.js +8 -8
  6. package/dist/define-player.js.map +1 -1
  7. package/dist/errors.js +262 -259
  8. package/dist/errors.js.map +1 -1
  9. package/dist/index.js +4 -25
  10. package/dist/player-actor.js +318 -448
  11. package/dist/player-actor.js.map +1 -1
  12. package/dist/routing/build-url.js +74 -108
  13. package/dist/routing/build-url.js.map +1 -1
  14. package/dist/routing/derive-current-route.d.ts.map +1 -1
  15. package/dist/routing/derive-current-route.js +46 -67
  16. package/dist/routing/derive-current-route.js.map +1 -1
  17. package/dist/routing/derive-initial-route.js +53 -64
  18. package/dist/routing/derive-initial-route.js.map +1 -1
  19. package/dist/routing/derive-route.js +225 -242
  20. package/dist/routing/derive-route.js.map +1 -1
  21. package/dist/routing/format-play-route-transitions.d.ts.map +1 -1
  22. package/dist/routing/format-play-route-transitions.js +192 -257
  23. package/dist/routing/format-play-route-transitions.js.map +1 -1
  24. package/dist/state-meta.d.ts +84 -28
  25. package/dist/state-meta.d.ts.map +1 -1
  26. package/dist/state-meta.js +170 -72
  27. package/dist/state-meta.js.map +1 -1
  28. package/dist/view/derive-current-view.d.ts +18 -10
  29. package/dist/view/derive-current-view.d.ts.map +1 -1
  30. package/dist/view/derive-current-view.js +249 -128
  31. package/dist/view/derive-current-view.js.map +1 -1
  32. package/dist/with-routing.js +94 -136
  33. package/dist/with-routing.js.map +1 -1
  34. package/dist/with-view.d.ts +1 -3
  35. package/dist/with-view.d.ts.map +1 -1
  36. package/dist/with-view.js +82 -152
  37. package/dist/with-view.js.map +1 -1
  38. package/package.json +19 -19
  39. package/dist/index.js.map +0 -1
  40. package/dist/routing/index.js +0 -14
  41. package/dist/routing/index.js.map +0 -1
  42. package/dist/routing/types.js +0 -2
  43. package/dist/routing/types.js.map +0 -1
  44. package/dist/types.js +0 -2
  45. package/dist/types.js.map +0 -1
@@ -1,18 +1,64 @@
1
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.
2
+ * The walk of the active states, which BOTH capabilities share.
3
+ *
4
+ * `deriveCurrentRoute` folds the meta record of one active branch into a URL.
5
+ * `deriveCurrentView` walks the active tree with the same {@link branchOrder}, so a
6
+ * parallel node tries the region of the URL first for both. The view can still come from
7
+ * another region, when the region of the URL resolves to no view. For a snapshot without
8
+ * a machine tree, both read the flat `getMeta()` record.
9
+ *
10
+ * It lives in its own module, and not beside the route derivation, because it belongs to
11
+ * neither capability. `@xmachines/play-xstate/view` reads it, and a view-only application
12
+ * therefore loads no part of the route derivation.
14
13
  */
15
14
  import type { AnyMachineSnapshot } from "xstate";
15
+ /** The part of an XState state node that the walks of this module read. */
16
+ export interface BranchNode {
17
+ id: string;
18
+ meta?: unknown;
19
+ states?: Record<string, BranchNode>;
20
+ }
21
+ /**
22
+ * The keys of the active children of a node, from its part of `snapshot.value`: one key
23
+ * for a compound node, one for each region of a parallel node, in the order of the
24
+ * machine, and none for an atomic node.
25
+ */
26
+ export declare const activeChildKeys: (value: unknown) => string[];
27
+ /** The part of `snapshot.value` that belongs to the active child `key`. */
28
+ export declare const activeChildValue: (value: unknown, key: string) => unknown;
29
+ /**
30
+ * The keys of the active children of a node, in the order that a branch walk tries
31
+ * them. For a parallel node, one region comes first:
32
+ *
33
+ * 1. the first region whose ACTIVE subtree declares a `meta.route`;
34
+ * 2. else the first region that declares a route in any of its states. A region that
35
+ * owns the routes keeps its place while it sits in a state without a route of its
36
+ * own, such as a load;
37
+ * 3. else the first region.
38
+ *
39
+ * The other regions keep the order of the machine.
40
+ *
41
+ * A parallel machine often holds its routes in ONE region, and that region need not be
42
+ * the first one: a menu or a session region can come before it. The route derivation
43
+ * and the view derivation both follow this order, so the URL comes from the routed
44
+ * region, and the view without outlets comes from the region of the URL when that region
45
+ * resolves to a view.
46
+ */
47
+ export declare const branchOrder: (node: BranchNode, value: unknown) => string[];
48
+ /**
49
+ * Warns one time for each machine whose state ids break a record that is keyed on them.
50
+ *
51
+ * XState does not check that the ids of the states are unique, and a repeated id makes a
52
+ * `#id` target name two states. play-xstate keys the route, the view and its store on the
53
+ * id of a state, so a repeated id gives two states one route entry, one store, and one
54
+ * key. An id that is an array index, such as "42", moves to the front of every record that is
55
+ * keyed on ids, also the `getMeta()` record of XState, so the route of its state loses its
56
+ * place in the branch.
57
+ *
58
+ * The route derivation and the view derivation call this function. A read helper, such
59
+ * as {@link firstActiveBranchMeta}, writes no warning.
60
+ */
61
+ export declare const warnStateIds: (root: BranchNode) => void;
16
62
  /**
17
63
  * Collects the `meta` object of the active state nodes of a SINGLE branch, from the
18
64
  * root to a leaf. The key of each entry is the state id, and the order is the
@@ -28,25 +74,35 @@ import type { AnyMachineSnapshot } from "xstate";
28
74
  * the meta keys are those ids, and they carry no information about the ancestry.
29
75
  *
30
76
  * 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.
77
+ * the active states by the state key, against the node tree of the machine. At each
78
+ * level it follows the first key of {@link branchOrder}: for a parallel node, that is
79
+ * the first region whose active subtree declares a route, else the first region that
80
+ * declares a route in any state, else the first region. This gives one deterministic
81
+ * branch. It also works with an explicit id,
82
+ * because each node carries its own `id` and its own `meta`.
83
+ *
84
+ * The function returns `null` when the snapshot exposes no machine tree to walk. This
85
+ * is a defensive measure, because a real XState snapshot always exposes one. The caller
86
+ * then reads the flat `getMeta()` record.
40
87
  */
41
88
  export declare const firstActiveBranchMeta: (snapshot: AnyMachineSnapshot) => Record<string, unknown> | null;
42
89
  /**
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.
90
+ * Resolves the meta record that the route derivation folds: the single active branch
91
+ * that {@link firstActiveBranchMeta} walks, which is correct for a parallel machine and
92
+ * for an explicit id, or the flat `getMeta()` record when the snapshot has no machine
93
+ * tree to walk.
94
+ *
95
+ * The view derivation does not call this function. It walks the tree with
96
+ * `resolveViewTree`, which shares {@link branchOrder}, so both sides try the routed
97
+ * region of a parallel node first. They can still select different regions: when the
98
+ * routed region resolves to no view, the view comes from the next region that resolves
99
+ * to one, and the route stays in the routed region.
50
100
  */
51
101
  export declare const activeStateMeta: (snapshot: AnyMachineSnapshot) => Record<string, unknown> | null;
102
+ /**
103
+ * The flat `getMeta()` record of a snapshot, or `null` when the snapshot gives none. The
104
+ * keys of the ancestors come first. Both derivations read it for a snapshot that exposes
105
+ * no machine tree, so they read it through this one function.
106
+ */
107
+ export declare const flatStateMeta: (snapshot: AnyMachineSnapshot) => Record<string, unknown> | null;
52
108
  //# sourceMappingURL=state-meta.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"state-meta.d.ts","sourceRoot":"","sources":["../src/state-meta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAEjD,2EAA2E;AAC3E,MAAM,WAAW,UAAU;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACpC;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,OAAO,KAAG,MAAM,EAKhD,CAAC;AAER,2EAA2E;AAC3E,eAAO,MAAM,gBAAgB,GAAI,OAAO,OAAO,EAAE,KAAK,MAAM,KAAG,OAGlD,CAAC;AA8Bd;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,UAAU,EAAE,OAAO,OAAO,KAAG,MAAM,EAgBpE,CAAC;AAaF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,YAAY,GAAI,MAAM,UAAU,KAAG,IA2B/C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,qBAAqB,GACjC,UAAU,kBAAkB,KAC1B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAgC5B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,eAAe,GAAI,UAAU,kBAAkB,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAGxF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,UAAU,kBAAkB,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAItF,CAAC"}
@@ -1,77 +1,175 @@
1
+ //#region packages/play-xstate/src/state-meta.ts
1
2
  /**
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;
3
+ * The keys of the active children of a node, from its part of `snapshot.value`: one key
4
+ * for a compound node, one for each region of a parallel node, in the order of the
5
+ * machine, and none for an atomic node.
6
+ */
7
+ var activeChildKeys = (value) => typeof value === "string" ? [value] : value !== null && typeof value === "object" ? Object.keys(value) : [];
8
+ /** The part of `snapshot.value` that belongs to the active child `key`. */
9
+ var activeChildValue = (value, key) => value !== null && typeof value === "object" ? value[key] : void 0;
10
+ var declaresRoute = (node) => node.meta !== null && typeof node.meta === "object" && node.meta.route !== void 0;
11
+ /** `true` when a state of the active subtree of `node` declares a `meta.route`. */
12
+ var routeBelow = (node, value) => {
13
+ if (declaresRoute(node)) return true;
14
+ for (const key of activeChildKeys(value)) {
15
+ const child = node.states?.[key];
16
+ if (child && routeBelow(child, activeChildValue(value, key))) return true;
17
+ }
18
+ return false;
19
+ };
20
+ var routesByNode = /* @__PURE__ */ new WeakMap();
21
+ var holdsRoutes = (node) => {
22
+ let holds = routesByNode.get(node);
23
+ if (holds === void 0) {
24
+ holds = declaresRoute(node) || Object.values(node.states ?? {}).some(holdsRoutes);
25
+ routesByNode.set(node, holds);
26
+ }
27
+ return holds;
28
+ };
29
+ /**
30
+ * The keys of the active children of a node, in the order that a branch walk tries
31
+ * them. For a parallel node, one region comes first:
32
+ *
33
+ * 1. the first region whose ACTIVE subtree declares a `meta.route`;
34
+ * 2. else the first region that declares a route in any of its states. A region that
35
+ * owns the routes keeps its place while it sits in a state without a route of its
36
+ * own, such as a load;
37
+ * 3. else the first region.
38
+ *
39
+ * The other regions keep the order of the machine.
40
+ *
41
+ * A parallel machine often holds its routes in ONE region, and that region need not be
42
+ * the first one: a menu or a session region can come before it. The route derivation
43
+ * and the view derivation both follow this order, so the URL comes from the routed
44
+ * region, and the view without outlets comes from the region of the URL when that region
45
+ * resolves to a view.
46
+ */
47
+ var branchOrder = (node, value) => {
48
+ const keys = activeChildKeys(value);
49
+ if (keys.length < 2) return keys;
50
+ const childOf = (key) => node.states?.[key];
51
+ const routed = keys.find((key) => {
52
+ const child = childOf(key);
53
+ return child !== void 0 && routeBelow(child, activeChildValue(value, key));
54
+ }) ?? keys.find((key) => {
55
+ const child = childOf(key);
56
+ return child !== void 0 && holdsRoutes(child);
57
+ });
58
+ return routed === void 0 || routed === keys[0] ? keys : [routed, ...keys.filter((key) => key !== routed)];
59
+ };
60
+ var checkedMachines = /* @__PURE__ */ new WeakSet();
61
+ /**
62
+ * An id that JavaScript reads as an array index: a whole number from 0 to 2^32 - 2, with
63
+ * no leading zero. An object lists such a key before every other key.
64
+ */
65
+ var isIndexLike = (id) => /^(0|[1-9]\d*)$/.test(id) && Number(id) < 2 ** 32 - 1;
66
+ /** The ids in quotes, separated by commas, for a warning. */
67
+ var quoted = (ids) => [...ids].map((id) => `"${id}"`).join(", ");
68
+ /**
69
+ * Warns one time for each machine whose state ids break a record that is keyed on them.
70
+ *
71
+ * XState does not check that the ids of the states are unique, and a repeated id makes a
72
+ * `#id` target name two states. play-xstate keys the route, the view and its store on the
73
+ * id of a state, so a repeated id gives two states one route entry, one store, and one
74
+ * key. An id that is an array index, such as "42", moves to the front of every record that is
75
+ * keyed on ids, also the `getMeta()` record of XState, so the route of its state loses its
76
+ * place in the branch.
77
+ *
78
+ * The route derivation and the view derivation call this function. A read helper, such
79
+ * as {@link firstActiveBranchMeta}, writes no warning.
80
+ */
81
+ var warnStateIds = (root) => {
82
+ if (checkedMachines.has(root)) return;
83
+ checkedMachines.add(root);
84
+ const seen = /* @__PURE__ */ new Set();
85
+ const repeated = /* @__PURE__ */ new Set();
86
+ const indexLike = /* @__PURE__ */ new Set();
87
+ const visit = (node) => {
88
+ if (seen.has(node.id)) repeated.add(node.id);
89
+ seen.add(node.id);
90
+ if (isIndexLike(node.id)) indexLike.add(node.id);
91
+ for (const child of Object.values(node.states ?? {})) visit(child);
92
+ };
93
+ visit(root);
94
+ const faults = [...repeated.size > 0 ? [`it gives two or more states the same id (${quoted(repeated)})`] : [], ...indexLike.size > 0 ? [`it gives a state an id that is an array index (${quoted(indexLike)})`] : []];
95
+ if (faults.length === 0) return;
96
+ console.warn(`[play-xstate] The state ids of the machine "${root.id}" break a rule: ${faults.join("; ")}. play-xstate keys the route, the view and its store on the id of a state. Give each state its own id, and do not use an array index as an id.`);
97
+ };
98
+ /**
99
+ * Collects the `meta` object of the active state nodes of a SINGLE branch, from the
100
+ * root to a leaf. The key of each entry is the state id, and the order is the
101
+ * ancestors first. {@link deriveRoute} folds this shape.
102
+ *
103
+ * `snapshot.getMeta()` returns a FLAT record of the meta object of every active
104
+ * state. For a machine that is not parallel, that record is one chain of ancestors
105
+ * already. For a PARALLEL machine, it mixes the entries of every active region. A
106
+ * blind fold therefore joins a relative route of one region to an absolute route of
107
+ * a sibling region, and the URL belongs to the tree of neither region. The flat
108
+ * record also cannot go back into a hierarchy: when a state declares an explicit
109
+ * `id`, for example a child with `id: "dashboard-overview"` under `id: "dashboard"`,
110
+ * the meta keys are those ids, and they carry no information about the ancestry.
111
+ *
112
+ * Therefore this function walks `snapshot.value`, which holds the real hierarchy of
113
+ * the active states by the state key, against the node tree of the machine. At each
114
+ * level it follows the first key of {@link branchOrder}: for a parallel node, that is
115
+ * the first region whose active subtree declares a route, else the first region that
116
+ * declares a route in any state, else the first region. This gives one deterministic
117
+ * branch. It also works with an explicit id,
118
+ * because each node carries its own `id` and its own `meta`.
119
+ *
120
+ * The function returns `null` when the snapshot exposes no machine tree to walk. This
121
+ * is a defensive measure, because a real XState snapshot always exposes one. The caller
122
+ * then reads the flat `getMeta()` record.
123
+ */
124
+ var firstActiveBranchMeta = (snapshot) => {
125
+ const root = snapshot.machine?.root;
126
+ if (!root) return null;
127
+ const ordered = {};
128
+ let node = root;
129
+ let value = snapshot.value;
130
+ while (node) {
131
+ if (node.meta && typeof node.meta === "object") Object.defineProperty(ordered, node.id, {
132
+ value: node.meta,
133
+ enumerable: true,
134
+ writable: true,
135
+ configurable: true
136
+ });
137
+ const key = branchOrder(node, value)[0];
138
+ if (key === void 0) break;
139
+ const child = node.states?.[key];
140
+ if (!child) break;
141
+ value = activeChildValue(value, key);
142
+ node = child;
143
+ }
144
+ return ordered;
145
+ };
146
+ /**
147
+ * Resolves the meta record that the route derivation folds: the single active branch
148
+ * that {@link firstActiveBranchMeta} walks, which is correct for a parallel machine and
149
+ * for an explicit id, or the flat `getMeta()` record when the snapshot has no machine
150
+ * tree to walk.
151
+ *
152
+ * The view derivation does not call this function. It walks the tree with
153
+ * `resolveViewTree`, which shares {@link branchOrder}, so both sides try the routed
154
+ * region of a parallel node first. They can still select different regions: when the
155
+ * routed region resolves to no view, the view comes from the next region that resolves
156
+ * to one, and the route stays in the routed region.
157
+ */
158
+ var activeStateMeta = (snapshot) => {
159
+ if (!snapshot) return null;
160
+ return firstActiveBranchMeta(snapshot) ?? flatStateMeta(snapshot);
60
161
  };
61
162
  /**
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;
163
+ * The flat `getMeta()` record of a snapshot, or `null` when the snapshot gives none. The
164
+ * keys of the ancestors come first. Both derivations read it for a snapshot that exposes
165
+ * no machine tree, so they read it through this one function.
166
+ */
167
+ var flatStateMeta = (snapshot) => {
168
+ if (!snapshot || typeof snapshot.getMeta !== "function") return null;
169
+ const meta = snapshot.getMeta();
170
+ return meta && typeof meta === "object" ? meta : null;
76
171
  };
172
+ //#endregion
173
+ export { activeChildKeys, activeChildValue, activeStateMeta, branchOrder, firstActiveBranchMeta, flatStateMeta, warnStateIds };
174
+
77
175
  //# sourceMappingURL=state-meta.js.map
@@ -1 +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"}
1
+ {"version":3,"file":"state-meta.js","names":[],"sources":["../src/state-meta.ts"],"sourcesContent":["/**\n * The walk of the active states, which BOTH capabilities share.\n *\n * `deriveCurrentRoute` folds the meta record of one active branch into a URL.\n * `deriveCurrentView` walks the active tree with the same {@link branchOrder}, so a\n * parallel node tries the region of the URL first for both. The view can still come from\n * another region, when the region of the URL resolves to no view. For a snapshot without\n * a machine tree, both read the flat `getMeta()` record.\n *\n * It lives in its own module, and not beside the route derivation, because it belongs to\n * neither capability. `@xmachines/play-xstate/view` reads it, and a view-only application\n * therefore loads no part of the route derivation.\n */\nimport type { AnyMachineSnapshot } from \"xstate\";\n\n/** The part of an XState state node that the walks of this module read. */\nexport interface BranchNode {\n\tid: string;\n\tmeta?: unknown;\n\tstates?: Record<string, BranchNode>;\n}\n\n/**\n * The keys of the active children of a node, from its part of `snapshot.value`: one key\n * for a compound node, one for each region of a parallel node, in the order of the\n * machine, and none for an atomic node.\n */\nexport const activeChildKeys = (value: unknown): string[] =>\n\ttypeof value === \"string\"\n\t\t? [value]\n\t\t: value !== null && typeof value === \"object\"\n\t\t\t? Object.keys(value)\n\t\t\t: [];\n\n/** The part of `snapshot.value` that belongs to the active child `key`. */\nexport const activeChildValue = (value: unknown, key: string): unknown =>\n\tvalue !== null && typeof value === \"object\"\n\t\t? (value as Record<string, unknown>)[key] // nosemgrep: gitlab.eslint.detect-object-injection\n\t\t: undefined;\n\nconst declaresRoute = (node: BranchNode): boolean =>\n\tnode.meta !== null &&\n\ttypeof node.meta === \"object\" &&\n\t(node.meta as { route?: unknown }).route !== undefined;\n\n/** `true` when a state of the active subtree of `node` declares a `meta.route`. */\nconst routeBelow = (node: BranchNode, value: unknown): boolean => {\n\tif (declaresRoute(node)) return true;\n\tfor (const key of activeChildKeys(value)) {\n\t\tconst child = node.states?.[key]; // nosemgrep: gitlab.eslint.detect-object-injection\n\t\tif (child && routeBelow(child, activeChildValue(value, key))) return true;\n\t}\n\treturn false;\n};\n\n// Whether a state node or one of its descendants declares a `meta.route`, for each\n// node. The state nodes of a machine are static, so one answer holds for its life.\nconst routesByNode = new WeakMap<BranchNode, boolean>();\n\nconst holdsRoutes = (node: BranchNode): boolean => {\n\tlet holds = routesByNode.get(node);\n\tif (holds === undefined) {\n\t\tholds = declaresRoute(node) || Object.values(node.states ?? {}).some(holdsRoutes);\n\t\troutesByNode.set(node, holds);\n\t}\n\treturn holds;\n};\n\n/**\n * The keys of the active children of a node, in the order that a branch walk tries\n * them. For a parallel node, one region comes first:\n *\n * 1. the first region whose ACTIVE subtree declares a `meta.route`;\n * 2. else the first region that declares a route in any of its states. A region that\n * owns the routes keeps its place while it sits in a state without a route of its\n * own, such as a load;\n * 3. else the first region.\n *\n * The other regions keep the order of the machine.\n *\n * A parallel machine often holds its routes in ONE region, and that region need not be\n * the first one: a menu or a session region can come before it. The route derivation\n * and the view derivation both follow this order, so the URL comes from the routed\n * region, and the view without outlets comes from the region of the URL when that region\n * resolves to a view.\n */\nexport const branchOrder = (node: BranchNode, value: unknown): string[] => {\n\tconst keys = activeChildKeys(value);\n\tif (keys.length < 2) return keys;\n\tconst childOf = (key: string): BranchNode | undefined => node.states?.[key]; // nosemgrep: gitlab.eslint.detect-object-injection\n\tconst routed =\n\t\tkeys.find((key) => {\n\t\t\tconst child = childOf(key);\n\t\t\treturn child !== undefined && routeBelow(child, activeChildValue(value, key));\n\t\t}) ??\n\t\tkeys.find((key) => {\n\t\t\tconst child = childOf(key);\n\t\t\treturn child !== undefined && holdsRoutes(child);\n\t\t});\n\treturn routed === undefined || routed === keys[0]\n\t\t? keys\n\t\t: [routed, ...keys.filter((key) => key !== routed)];\n};\n\nconst checkedMachines = new WeakSet<BranchNode>();\n\n/**\n * An id that JavaScript reads as an array index: a whole number from 0 to 2^32 - 2, with\n * no leading zero. An object lists such a key before every other key.\n */\nconst isIndexLike = (id: string): boolean => /^(0|[1-9]\\d*)$/.test(id) && Number(id) < 2 ** 32 - 1;\n\n/** The ids in quotes, separated by commas, for a warning. */\nconst quoted = (ids: Set<string>): string => [...ids].map((id) => `\"${id}\"`).join(\", \");\n\n/**\n * Warns one time for each machine whose state ids break a record that is keyed on them.\n *\n * XState does not check that the ids of the states are unique, and a repeated id makes a\n * `#id` target name two states. play-xstate keys the route, the view and its store on the\n * id of a state, so a repeated id gives two states one route entry, one store, and one\n * key. An id that is an array index, such as \"42\", moves to the front of every record that is\n * keyed on ids, also the `getMeta()` record of XState, so the route of its state loses its\n * place in the branch.\n *\n * The route derivation and the view derivation call this function. A read helper, such\n * as {@link firstActiveBranchMeta}, writes no warning.\n */\nexport const warnStateIds = (root: BranchNode): void => {\n\tif (checkedMachines.has(root)) return;\n\tcheckedMachines.add(root);\n\tconst seen = new Set<string>();\n\tconst repeated = new Set<string>();\n\tconst indexLike = new Set<string>();\n\tconst visit = (node: BranchNode): void => {\n\t\tif (seen.has(node.id)) repeated.add(node.id);\n\t\tseen.add(node.id);\n\t\tif (isIndexLike(node.id)) indexLike.add(node.id);\n\t\tfor (const child of Object.values(node.states ?? {})) visit(child);\n\t};\n\tvisit(root);\n\tconst faults = [\n\t\t...(repeated.size > 0\n\t\t\t? [`it gives two or more states the same id (${quoted(repeated)})`]\n\t\t\t: []),\n\t\t...(indexLike.size > 0\n\t\t\t? [`it gives a state an id that is an array index (${quoted(indexLike)})`]\n\t\t\t: []),\n\t];\n\tif (faults.length === 0) return;\n\tconsole.warn(\n\t\t`[play-xstate] The state ids of the machine \"${root.id}\" break a rule: ` +\n\t\t\t`${faults.join(\"; \")}. play-xstate keys the route, the view and its store on the id ` +\n\t\t\t\"of a state. Give each state its own id, and do not use an array index as an id.\",\n\t);\n};\n\n/**\n * Collects the `meta` object of the active state nodes of a SINGLE branch, from the\n * root to a leaf. The key of each entry is the state id, and the order is the\n * ancestors first. {@link deriveRoute} folds this shape.\n *\n * `snapshot.getMeta()` returns a FLAT record of the meta object of every active\n * state. For a machine that is not parallel, that record is one chain of ancestors\n * already. For a PARALLEL machine, it mixes the entries of every active region. A\n * blind fold therefore joins a relative route of one region to an absolute route of\n * a sibling region, and the URL belongs to the tree of neither region. The flat\n * record also cannot go back into a hierarchy: when a state declares an explicit\n * `id`, for example a child with `id: \"dashboard-overview\"` under `id: \"dashboard\"`,\n * the meta keys are those ids, and they carry no information about the ancestry.\n *\n * Therefore this function walks `snapshot.value`, which holds the real hierarchy of\n * the active states by the state key, against the node tree of the machine. At each\n * level it follows the first key of {@link branchOrder}: for a parallel node, that is\n * the first region whose active subtree declares a route, else the first region that\n * declares a route in any state, else the first region. This gives one deterministic\n * branch. It also works with an explicit id,\n * because each node carries its own `id` and its own `meta`.\n *\n * The function returns `null` when the snapshot exposes no machine tree to walk. This\n * is a defensive measure, because a real XState snapshot always exposes one. The caller\n * then reads the flat `getMeta()` record.\n */\nexport const firstActiveBranchMeta = (\n\tsnapshot: AnyMachineSnapshot,\n): Record<string, unknown> | null => {\n\tconst root = snapshot.machine?.root as BranchNode | undefined;\n\tif (!root) return null;\n\n\tconst ordered: Record<string, unknown> = {};\n\tlet node: BranchNode | undefined = root;\n\tlet value: unknown = snapshot.value;\n\n\twhile (node) {\n\t\tif (node.meta && typeof node.meta === \"object\") {\n\t\t\t// A definition, and not an assignment: an id \"__proto__\" would set the prototype\n\t\t\t// of the record, and the entry would leave Object.entries.\n\t\t\tObject.defineProperty(ordered, node.id, {\n\t\t\t\tvalue: node.meta,\n\t\t\t\tenumerable: true,\n\t\t\t\twritable: true,\n\t\t\t\tconfigurable: true,\n\t\t\t});\n\t\t}\n\n\t\t// The key of the active child at this level: the name of an atomic active leaf, the\n\t\t// one key of a compound node, or the routed region of a parallel node.\n\t\tconst key: string | undefined = branchOrder(node, value)[0];\n\t\tif (key === undefined) break;\n\n\t\tconst child: BranchNode | undefined = node.states?.[key]; // nosemgrep: gitlab.eslint.detect-object-injection\n\t\tif (!child) break;\n\t\tvalue = activeChildValue(value, key);\n\t\tnode = child;\n\t}\n\n\treturn ordered;\n};\n\n/**\n * Resolves the meta record that the route derivation folds: the single active branch\n * that {@link firstActiveBranchMeta} walks, which is correct for a parallel machine and\n * for an explicit id, or the flat `getMeta()` record when the snapshot has no machine\n * tree to walk.\n *\n * The view derivation does not call this function. It walks the tree with\n * `resolveViewTree`, which shares {@link branchOrder}, so both sides try the routed\n * region of a parallel node first. They can still select different regions: when the\n * routed region resolves to no view, the view comes from the next region that resolves\n * to one, and the route stays in the routed region.\n */\nexport const activeStateMeta = (snapshot: AnyMachineSnapshot): Record<string, unknown> | null => {\n\tif (!snapshot) return null;\n\treturn firstActiveBranchMeta(snapshot) ?? flatStateMeta(snapshot);\n};\n\n/**\n * The flat `getMeta()` record of a snapshot, or `null` when the snapshot gives none. The\n * keys of the ancestors come first. Both derivations read it for a snapshot that exposes\n * no machine tree, so they read it through this one function.\n */\nexport const flatStateMeta = (snapshot: AnyMachineSnapshot): Record<string, unknown> | null => {\n\tif (!snapshot || typeof snapshot.getMeta !== \"function\") return null;\n\tconst meta: unknown = snapshot.getMeta();\n\treturn meta && typeof meta === \"object\" ? (meta as Record<string, unknown>) : null;\n};\n"],"mappings":"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"}
@@ -2,9 +2,10 @@
2
2
  * The view derivation — the meta.view half of the player pipeline.
3
3
  *
4
4
  * This file is beside src/routing/, so that player-actor.ts holds the actor
5
- * itself only: the atoms, 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.
5
+ * itself only: the atoms, the hooks, and the lifecycle. The walk shares
6
+ * `branchOrder` with the route derivation, so a parallel node tries the region of its
7
+ * URL first. When that region resolves to no view, the view comes from the next region
8
+ * that resolves to one.
8
9
  */
9
10
  import type { AnyMachineSnapshot } from "xstate";
10
11
  import { type PlaySpec } from "@xmachines/play-view";
@@ -37,13 +38,20 @@ import { type PlaySpec } from "@xmachines/play-view";
37
38
  *
38
39
  * ### The viewKey
39
40
  *
40
- * The derived spec carries a `viewKey` field. Its value is the key of the meta
41
- * record, which is the id of the state node, of the entry that this derivation
42
- * selected. A provider uses it as the key of its store lifecycle: a new key seeds
43
- * the store again, and the same key refreshes `/context` in place. The value comes
44
- * from the selected entry, and not from "the id of the active state", because for a
45
- * parallel machine the branch of the walk and the flat `getMeta()` fallback can
46
- * select a view of a different region than the leaf of the branch.
41
+ * The derived spec carries a `viewKey` field. Its value is the id of the state node
42
+ * whose view the walk selected: the outermost state that composes with `outlets`, or
43
+ * the state of the deepest view. A provider uses it as the key of its store lifecycle:
44
+ * a new key seeds the store again, and the same key refreshes `/context` in place. The
45
+ * value comes from the selected view, and not from "the id of the active state",
46
+ * because for a parallel machine the walk can select a view of a different region than
47
+ * the leaf of the routed branch.
48
+ *
49
+ * ### One rule
50
+ *
51
+ * One walk of the active state tree derives every view, and a machine with no
52
+ * `outlets` is its simple case: the deepest view wins. Declare `outlets` on a state to
53
+ * show its view beside the views of its children. A snapshot that exposes no machine
54
+ * tree falls back to its flat `getMeta()` record, as the route derivation does.
47
55
  *
48
56
  * @param snapshot - The current snapshot of the XState machine.
49
57
  * @returns The derived `PlaySpec`, or `null` when the current state has no view metadata.
@@ -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,sBAAsB,CAAC;AAyEpF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,eAAO,MAAM,iBAAiB,GAAI,UAAU,kBAAkB,KAAG,QAAQ,GAAG,IA4C3E,CAAC"}
1
+ {"version":3,"file":"derive-current-view.d.ts","sourceRoot":"","sources":["../../src/view/derive-current-view.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,EAKN,KAAK,QAAQ,EAIb,MAAM,sBAAsB,CAAC;AAqO9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,eAAO,MAAM,iBAAiB,GAAI,UAAU,kBAAkB,KAAG,QAAQ,GAAG,IAmC3E,CAAC"}