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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/README.md +114 -114
  2. package/dist/define-player.d.ts +16 -16
  3. package/dist/define-player.js +16 -16
  4. package/dist/errors.d.ts +84 -101
  5. package/dist/errors.d.ts.map +1 -1
  6. package/dist/errors.js +108 -108
  7. package/dist/errors.js.map +1 -1
  8. package/dist/guards/compose.d.ts +70 -77
  9. package/dist/guards/compose.d.ts.map +1 -1
  10. package/dist/guards/compose.js +90 -113
  11. package/dist/guards/compose.js.map +1 -1
  12. package/dist/guards/helpers.d.ts +22 -18
  13. package/dist/guards/helpers.d.ts.map +1 -1
  14. package/dist/guards/helpers.js +23 -19
  15. package/dist/guards/helpers.js.map +1 -1
  16. package/dist/guards/index.d.ts +10 -3
  17. package/dist/guards/index.d.ts.map +1 -1
  18. package/dist/guards/index.js +10 -3
  19. package/dist/guards/index.js.map +1 -1
  20. package/dist/guards/types.d.ts +9 -9
  21. package/dist/guards/types.d.ts.map +1 -1
  22. package/dist/index.d.ts +8 -8
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +9 -10
  25. package/dist/index.js.map +1 -1
  26. package/dist/player-actor.d.ts +197 -113
  27. package/dist/player-actor.d.ts.map +1 -1
  28. package/dist/player-actor.js +413 -401
  29. package/dist/player-actor.js.map +1 -1
  30. package/dist/routing/build-url.d.ts +19 -21
  31. package/dist/routing/build-url.d.ts.map +1 -1
  32. package/dist/routing/build-url.js +70 -71
  33. package/dist/routing/build-url.js.map +1 -1
  34. package/dist/routing/derive-current-route.d.ts +51 -13
  35. package/dist/routing/derive-current-route.d.ts.map +1 -1
  36. package/dist/routing/derive-current-route.js +69 -60
  37. package/dist/routing/derive-current-route.js.map +1 -1
  38. package/dist/routing/derive-initial-route.d.ts +23 -23
  39. package/dist/routing/derive-initial-route.js +27 -27
  40. package/dist/routing/derive-initial-route.js.map +1 -1
  41. package/dist/routing/derive-route.d.ts +38 -37
  42. package/dist/routing/derive-route.d.ts.map +1 -1
  43. package/dist/routing/derive-route.js +45 -42
  44. package/dist/routing/derive-route.js.map +1 -1
  45. package/dist/routing/format-play-route-transitions.d.ts +34 -71
  46. package/dist/routing/format-play-route-transitions.d.ts.map +1 -1
  47. package/dist/routing/format-play-route-transitions.js +74 -130
  48. package/dist/routing/format-play-route-transitions.js.map +1 -1
  49. package/dist/routing/index.d.ts +4 -8
  50. package/dist/routing/index.d.ts.map +1 -1
  51. package/dist/routing/index.js +4 -6
  52. package/dist/routing/index.js.map +1 -1
  53. package/dist/routing/types.d.ts +12 -11
  54. package/dist/routing/types.d.ts.map +1 -1
  55. package/dist/types.d.ts +97 -20
  56. package/dist/types.d.ts.map +1 -1
  57. package/dist/view/derive-current-view.d.ts +51 -0
  58. package/dist/view/derive-current-view.d.ts.map +1 -0
  59. package/dist/view/derive-current-view.js +119 -0
  60. package/dist/view/derive-current-view.js.map +1 -0
  61. package/package.json +22 -21
  62. package/dist/define-player.typecheck.d.ts +0 -2
  63. package/dist/define-player.typecheck.d.ts.map +0 -1
  64. package/dist/define-player.typecheck.js +0 -48
  65. package/dist/define-player.typecheck.js.map +0 -1
  66. package/dist/guards/compose.typecheck.d.ts +0 -2
  67. package/dist/guards/compose.typecheck.d.ts.map +0 -1
  68. package/dist/guards/compose.typecheck.js +0 -22
  69. package/dist/guards/compose.typecheck.js.map +0 -1
  70. package/dist/player-actor.typecheck.d.ts +0 -2
  71. package/dist/player-actor.typecheck.d.ts.map +0 -1
  72. package/dist/player-actor.typecheck.js +0 -30
  73. package/dist/player-actor.typecheck.js.map +0 -1
  74. package/dist/routing/create-routed-machine.d.ts +0 -71
  75. package/dist/routing/create-routed-machine.d.ts.map +0 -1
  76. package/dist/routing/create-routed-machine.js +0 -71
  77. package/dist/routing/create-routed-machine.js.map +0 -1
  78. package/dist/routing/play-route-event.typecheck.d.ts +0 -2
  79. package/dist/routing/play-route-event.typecheck.d.ts.map +0 -1
  80. package/dist/routing/play-route-event.typecheck.js +0 -43
  81. package/dist/routing/play-route-event.typecheck.js.map +0 -1
  82. package/dist/routing/schemas.d.ts +0 -99
  83. package/dist/routing/schemas.d.ts.map +0 -1
  84. package/dist/routing/schemas.js +0 -30
  85. package/dist/routing/schemas.js.map +0 -1
  86. package/dist/schemas.d.ts +0 -28
  87. package/dist/schemas.d.ts.map +0 -1
  88. package/dist/schemas.js +0 -29
  89. package/dist/schemas.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"format-play-route-transitions.d.ts","sourceRoot":"","sources":["../../src/routing/format-play-route-transitions.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG;IAC5B,iHAAiH;IACjH,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,iEAAiE;IACjE,IAAI,CAAC,EAAE;QACN;;;WAGG;QACH,KAAK,CAAC,EAAE,aAAa,CAAC;KACtB,CAAC;IACF,mEAAmE;IACnE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACxC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB,CAAC;AA4BF;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAC7C,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IACzC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AACH,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,kBAAkB,EAAE,aAAa,EAAE,CAAC,GAAG,CAAC,CAyH5F"}
1
+ {"version":3,"file":"format-play-route-transitions.d.ts","sourceRoot":"","sources":["../../src/routing/format-play-route-transitions.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAkBhD;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG;IAC5B;;OAEG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,wEAAwE;IACxE,IAAI,CAAC,EAAE;QACN;;;;WAIG;QACH,KAAK,CAAC,EAAE,aAAa,CAAC;KACtB,CAAC;IACF,2FAA2F;IAC3F,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACxC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB,CAAC;AAaF;;;;;;;;;;GAUG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAC7C,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IACzC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,kBAAkB,EAAE,aAAa,EAAE,CAAC,GAAG,CAAC,CAmF5F"}
@@ -1,18 +1,28 @@
1
+ import { assign } from "xstate";
2
+ import { shallowEqualExcept } from "@xmachines/play-actor";
1
3
  import { MissingStateIdError } from "../errors.js";
2
4
  import { normalizeRoute } from "./derive-route.js";
3
5
  /**
4
- * Formats play.route routing from declarative route configs.
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.
5
8
  *
6
- * Crawls machine states looking for states with `meta.route` and wires them to
7
- * XState v6's **native routing machinery**:
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
+ */
16
+ const keepEqualContainer = (prev, next) => (prev !== undefined && shallowEqualExcept(prev, next) ? prev : next);
17
+ /**
18
+ * Makes the play.route transitions from the declarative route configs
8
19
  *
9
- * - every routed state gets a native `route: {}` config (unless it already
10
- * declares its own `route`), making it targetable via the built-in
11
- * `{ type: "xstate.route", to: "#id" }` event (Stately tooling interop and
12
- * statically-known graph edges), and
13
- * - one root-level `play.route` forwarder performs the navigation for those
14
- * targets as ONE atomic transition: target + re-entry + a shallow
15
- * `params`/`query` context patch.
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.
23
+ *
24
+ * The internal formatRouteTransitions function of XState was the model for this
25
+ * function (stateUtils.ts, line 391).
16
26
  *
17
27
  * @example
18
28
  * ```typescript
@@ -27,142 +37,76 @@ import { normalizeRoute } from "./derive-route.js";
27
37
  * const machine = createMachine(formatPlayRouteTransitions(machineConfig));
28
38
  * ```
29
39
  *
30
- * Because the injected `route` configs are static (object form), the machine's
31
- * route transitions keep **statically-known targets** — `toDirectedGraph()` /
32
- * `machineToGraph()` edges point at the actual routed states, so graph
33
- * reachability queries work. (Function-form transition candidates would have
34
- * dynamic targets, opaque to static analysis.)
35
- *
36
- * The `play.route` public API and its v5 semantics are preserved:
37
- * - `send({ type: "play.route", to: "#home", params, query })` navigates and
38
- * patches `context.params`/`context.query` in the SAME transition — exit
39
- * actions of the departing state observe the OLD params, entry actions of
40
- * the target observe the NEW ones, `always` transitions never see a
41
- * half-navigated intermediate state, and entry/exit actions receive the
42
- * original `play.route` event;
43
- * - user-defined `play.route` transitions (e.g. a hand-written 404 fallback)
44
- * are preserved AFTER the forwarder: for unknown targets the forwarder
45
- * returns `undefined`, so evaluation falls through to them;
46
- * - `params`/`query` are only patched when the forwarder navigates — unknown
47
- * and blocked targets leave context untouched.
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
48
45
  *
49
- * When a state declares its OWN `route` config (which wins over the injected
50
- * default), the forwarder re-raises the event as `xstate.route` instead of
51
- * navigating, so the user's resolver decides — including blocking. The
52
- * forwarder does NOT patch `params`/`query` for such targets (a blocking
53
- * resolver would otherwise leave context describing a route that was never
54
- * entered); the user's function-form resolver owns any context patch, and
55
- * that navigation microstep runs under the `xstate.route` event.
56
- *
57
- * Native `xstate.route` events also work directly (Stately ecosystem tooling),
58
- * but bypass the forwarder — no `params`/`query` context patch is applied, so
59
- * stale values from earlier `play.route` events linger in context (and a
60
- * router bridge deriving the URL from context would interpolate those stale
61
- * params).
62
- *
63
- * @param machineConfig - XState machine config (before createMachine). Must extend `RouteMachineConfig`.
64
- * @returns The machine config with native `route` configs and the `play.route` forwarder merged in, preserving the original type `T`.
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.
65
48
  */
66
49
  export function formatPlayRouteTransitions(machineConfig) {
67
- /**
68
- * Routing table: `#id` -> the state's key path (e.g. `.dashboard.stats`)
69
- * for targets whose `route` config was injected by this transform, or
70
- * `null` for targets with a USER-declared `route` config (the user's
71
- * resolver decides those — the forwarder re-raises instead of navigating).
72
- */
73
- const routeTargets = new Map();
74
- /**
75
- * Rebuild the states tree, injecting a native `route` config into routed
76
- * nodes. The input config is never mutated — every node is shallow-copied.
77
- */
78
- const injectRoutes = (states, parentPath = "") => {
79
- const next = {};
80
- for (const [key, stateConfig] of Object.entries(states)) {
81
- const node = { ...stateConfig };
50
+ const routeTransitions = [];
51
+ const collectRoutes = (states, parentPath = "") => {
52
+ Object.entries(states).forEach(([key, stateConfig]) => {
53
+ const node = stateConfig;
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.
82
57
  const statePath = parentPath ? `${parentPath}.${key}` : key;
83
- // Validates the metadata (malformed object routes throw
84
- // InvalidRouteMetadataError) and normalizes to the path string. Both
85
- // the string form ("") and the object form ({ path: "" }) of an empty
86
- // path mark the state non-routable.
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: "" }).
87
62
  const routePath = node.meta?.route === undefined
88
63
  ? ""
89
64
  : normalizeRoute(node.meta.route, "formatPlayRouteTransitions");
90
65
  if (routePath && !node.id) {
91
66
  throw new MissingStateIdError(key, routePath);
92
67
  }
93
- if (node.states) {
94
- node.states = injectRoutes(node.states, statePath);
95
- }
96
68
  if (routePath && node.id) {
97
- if (node.route === undefined) {
98
- // Native object-form route config: statically-targeted transition,
99
- // visible to graph tooling. The play.route forwarder navigates these
100
- // targets DIRECTLY (atomically); the native config exists for
101
- // xstate.route interop (Stately tooling, devtools).
102
- node.route = {};
103
- routeTargets.set(`#${node.id}`, `.${statePath}`);
104
- }
105
- else {
106
- // A user-declared route config wins: the forwarder re-raises
107
- // xstate.route so the user's resolver decides (and owns any
108
- // context patch).
109
- routeTargets.set(`#${node.id}`, null);
110
- }
69
+ const transition = {
70
+ target: `.${statePath}`,
71
+ guard: ({ event }) => event.to === `#${node.id}`,
72
+ reenter: true,
73
+ actions: assign({
74
+ params: ({ context, event }) => keepEqualContainer(context.params, event.params || {}),
75
+ query: ({ context, event }) => keepEqualContainer(context.query, event.query || {}),
76
+ }),
77
+ };
78
+ routeTransitions.push(transition);
111
79
  }
112
- next[key] = node;
113
- }
114
- return next;
80
+ if (node.states) {
81
+ collectRoutes(node.states, statePath);
82
+ }
83
+ });
115
84
  };
116
85
  const machineStates = machineConfig.states;
117
- const injectedStates = machineStates ? injectRoutes(machineStates) : machineStates;
118
- if (routeTargets.size === 0) {
119
- return machineConfig;
86
+ if (machineStates) {
87
+ collectRoutes(machineStates);
120
88
  }
121
- // Root play.route forwarder. For injected-route targets it returns ONE
122
- // atomic transition (target + reenter + params/query patch): exit actions
123
- // see the OLD params, `always` transitions never observe a half-navigated
124
- // intermediate state, and entry/exit actions receive the original
125
- // play.route event. For user-routed targets it re-raises xstate.route
126
- // WITHOUT patching (the user's resolver owns the patch — otherwise a
127
- // blocking resolver would leave context describing a route that was never
128
- // entered). Unknown targets return undefined so user fallback candidates
129
- // below are evaluated.
130
- const forwarder = ({ event }, enq) => {
131
- const target = routeTargets.get(event.to);
132
- if (target === undefined)
133
- return undefined;
134
- if (target === null) {
135
- enq.raise({ ...event, type: "xstate.route" });
136
- return {};
137
- }
89
+ if (routeTransitions.length > 0) {
90
+ const existingOn = machineConfig.on || {};
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.
95
+ const userRouteTransitions = existingOn["play.route"];
96
+ const normalizedUserTransitions = userRouteTransitions === undefined
97
+ ? []
98
+ : Array.isArray(userRouteTransitions)
99
+ ? userRouteTransitions
100
+ : [userRouteTransitions];
101
+ const updatedOn = {
102
+ ...existingOn,
103
+ "play.route": [...routeTransitions, ...normalizedUserTransitions],
104
+ };
138
105
  return {
139
- target,
140
- reenter: true,
141
- // Shallow context patch — v6's replacement for assign().
142
- context: {
143
- params: event.params || {},
144
- query: event.query || {},
145
- },
106
+ ...machineConfig,
107
+ on: updatedOn,
146
108
  };
147
- };
148
- // Preserve user-defined play.route transitions (e.g. a hand-written 404
149
- // fallback) by appending them AFTER the forwarder: XState evaluates
150
- // candidate transitions in order, so the forwarder wins for known targets
151
- // and the user's transitions act as fallbacks otherwise.
152
- const existingOn = machineConfig.on || {};
153
- const userRouteTransitions = existingOn["play.route"];
154
- const normalizedUserTransitions = userRouteTransitions === undefined
155
- ? []
156
- : Array.isArray(userRouteTransitions)
157
- ? userRouteTransitions
158
- : [userRouteTransitions];
159
- return {
160
- ...machineConfig,
161
- states: injectedStates,
162
- on: {
163
- ...existingOn,
164
- "play.route": [forwarder, ...normalizedUserTransitions],
165
- },
166
- };
109
+ }
110
+ return machineConfig;
167
111
  }
168
112
  //# sourceMappingURL=format-play-route-transitions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"format-play-route-transitions.js","sourceRoot":"","sources":["../../src/routing/format-play-route-transitions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"format-play-route-transitions.js","sourceRoot":"","sources":["../../src/routing/format-play-route-transitions.ts"],"names":[],"mappings":"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"}
@@ -1,20 +1,16 @@
1
1
  /**
2
- * Route derivation and URL building utilities
2
+ * The utilities of the route derivation and of the URL construction
3
3
  *
4
- * Provides functions for extracting routes from state metadata
5
- * and building full URLs with parameter substitution.
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
  */
9
9
  export { deriveRoute, isAbsoluteRoute } from "./derive-route.js";
10
- export { deriveCurrentRoute } from "./derive-current-route.js";
10
+ export { activeStateMeta, deriveCurrentRoute, firstActiveBranchMeta, } from "./derive-current-route.js";
11
11
  export { deriveInitialRoute } from "./derive-initial-route.js";
12
12
  export { buildRouteUrl } from "./build-url.js";
13
13
  export { formatPlayRouteTransitions } from "./format-play-route-transitions.js";
14
- export { playMetaSchema, playRouteEventSchema } from "./schemas.js";
15
- export type { PlayRoutePayload, WithOptional } from "./schemas.js";
16
- export type { SetupLike } from "./create-routed-machine.js";
17
- export { createRoutedMachine } from "./create-routed-machine.js";
18
14
  export type { RouteMachineConfig, RouteStateNode } from "./format-play-route-transitions.js";
19
15
  export type { RouteContext, RouteObject, RouteMetadata } from "./types.js";
20
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/routing/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpE,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACnE,YAAY,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAC7F,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/routing/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EACN,eAAe,EACf,kBAAkB,EAClB,qBAAqB,GACrB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAChF,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAC7F,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
@@ -1,16 +1,14 @@
1
1
  /**
2
- * Route derivation and URL building utilities
2
+ * The utilities of the route derivation and of the URL construction
3
3
  *
4
- * Provides functions for extracting routes from state metadata
5
- * and building full URLs with parameter substitution.
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
  */
9
9
  export { deriveRoute, isAbsoluteRoute } from "./derive-route.js";
10
- export { deriveCurrentRoute } from "./derive-current-route.js";
10
+ export { activeStateMeta, deriveCurrentRoute, firstActiveBranchMeta, } from "./derive-current-route.js";
11
11
  export { deriveInitialRoute } from "./derive-initial-route.js";
12
12
  export { buildRouteUrl } from "./build-url.js";
13
13
  export { formatPlayRouteTransitions } from "./format-play-route-transitions.js";
14
- export { playMetaSchema, playRouteEventSchema } from "./schemas.js";
15
- export { createRoutedMachine } from "./create-routed-machine.js";
16
14
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/routing/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAGpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/routing/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EACN,eAAe,EACf,kBAAkB,EAClB,qBAAqB,GACrB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC"}
@@ -4,24 +4,25 @@ export interface RouteObject {
4
4
  }
5
5
  export type RouteMetadata = string | RouteObject;
6
6
  /**
7
- * Route build context from machine context.
7
+ * The context of the route construction, from the machine context.
8
8
  *
9
- * All URL parameter substitution must go through `params` — flat context fields are not
10
- * inspected. This is intentional: the index signature was removed to enable compile-time
11
- * validation of context shapes and IDE autocomplete on context fields.
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
- * Machines using `formatPlayRouteTransitions` have `params` and `query` assigned
14
- * automatically from each `play.route` event. Machines that call `buildRouteUrl` directly
15
- * must populate `params` explicitly.
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
- /** Base path for relative routes */
19
+ /** The base path of a relative route */
19
20
  basePath?: string;
20
- /** Path-only route parameters to substitute (e.g., `:userId` from `/profile/:userId`) */
21
+ /** The parameters of the path to substitute, for example `:userId` of `/profile/:userId` */
21
22
  params?: Record<string, unknown>;
22
- /** Query parameters */
23
+ /** The query parameters */
23
24
  query?: Record<string, unknown>;
24
- /** Hash fragment */
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;;;;;;;;;;GAUG;AACH,MAAM,WAAW,YAAY;IAC5B,oCAAoC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yFAAyF;IACzF,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,uBAAuB;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,oBAAoB;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACd"}
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,45 +1,122 @@
1
- import type { AnyStateMachine, InputFrom, SnapshotFrom } from "xstate";
1
+ import type { ActorOptions, AnyStateMachine, InputFrom, SnapshotFrom } from "xstate";
2
2
  import type { PlayerActor as PlayerActorClass } from "./player-actor.js";
3
3
  /**
4
- * Configuration for definePlayer()
4
+ * The configuration of definePlayer()
5
5
  */
6
6
  export interface PlayerConfig<TMachine extends AnyStateMachine> {
7
- /** XState v6 state machine */
7
+ /** The XState v5 state machine */
8
8
  machine: TMachine;
9
- /** Lifecycle hooks and configuration */
9
+ /** The lifecycle hooks and the configuration */
10
10
  options?: PlayerOptions<TMachine>;
11
11
  }
12
12
  /**
13
- * Player lifecycle hooks
14
- *
15
- * Per CONTEXT.md: Rich set of hooks for observability
13
+ * The lifecycle hooks of the player — the observability surface around the actor.
16
14
  */
17
15
  export interface PlayerOptions<TMachine extends AnyStateMachine> {
18
- /** Called when actor starts */
16
+ /**
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
+ */
19
21
  onStart?: (actor: PlayerActorClass<TMachine>) => void;
20
- /** Called when actor stops */
22
+ /**
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
+ */
21
27
  onStop?: (actor: PlayerActorClass<TMachine>) => void;
22
- /** Called on every state transition */
28
+ /**
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.
33
+ */
23
34
  onTransition?: (actor: PlayerActorClass<TMachine>, prevState: SnapshotFrom<TMachine>, nextState: SnapshotFrom<TMachine>) => void;
24
- /** Called when state signal changes */
35
+ /** The actor calls it when the state signal changes */
25
36
  onStateChange?: (actor: PlayerActorClass<TMachine>, state: SnapshotFrom<TMachine>) => void;
26
- /** Called on actor errors */
37
+ /**
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.
40
+ *
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.
45
+ *
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.
50
+ *
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.
54
+ *
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.
59
+ */
27
60
  onError?: (actor: PlayerActorClass<TMachine>, error: Error) => void;
61
+ /**
62
+ * The inspection observer. The factory gives it to `createActor` of XState without
63
+ * a change.
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.
69
+ *
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.
75
+ *
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.
81
+ *
82
+ * @example
83
+ * ```typescript
84
+ * import { createBrowserInspector } from "@statelyai/inspect";
85
+ *
86
+ * const { inspect } = createBrowserInspector();
87
+ * const createPlayer = definePlayer({ machine, options: { inspect } });
88
+ * ```
89
+ *
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)`.
93
+ */
94
+ inspect?: ActorOptions<TMachine>["inspect"];
28
95
  }
29
96
  /**
30
- * Optional restore arguments for the player factory.
97
+ * The optional restore arguments of the player factory.
31
98
  *
32
- * Mirrors XState's createActor options bag while preserving the existing
33
- * `createPlayer(input?)` calling convention for fresh actors.
99
+ * The shape follows the options object of `createActor` in XState. It also keeps the
100
+ * `createPlayer(input?)` calling convention of a new actor.
34
101
  */
35
102
  export interface PlayerFactoryResumeOptions<TMachine extends AnyStateMachine> {
36
- /** Persisted XState snapshot used to restore actor state. */
37
- snapshot?: SnapshotFrom<TMachine>;
103
+ /**
104
+ * The persisted XState snapshot. The factory restores the actor state from it.
105
+ *
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.
109
+ */
110
+ snapshot?: ActorOptions<TMachine>["snapshot"];
38
111
  }
39
112
  /**
40
- * Factory function returned by definePlayer()
113
+ * The factory function that definePlayer() returns. Each call makes an independent
114
+ * actor instance from the same configuration.
41
115
  *
42
- * Per CONTEXT.md: Factory supports creating multiple actor instances
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.
43
120
  */
44
- export type PlayerFactory<TMachine extends AnyStateMachine> = (input?: InputFrom<TMachine>, options?: PlayerFactoryResumeOptions<TMachine>) => PlayerActorClass<TMachine>;
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>;
45
122
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACvE,OAAO,KAAK,EAAE,WAAW,IAAI,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAEzE;;GAEG;AACH,MAAM,WAAW,YAAY,CAAC,QAAQ,SAAS,eAAe;IAC7D,8BAA8B;IAC9B,OAAO,EAAE,QAAQ,CAAC;IAElB,wCAAwC;IACxC,OAAO,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;CAClC;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa,CAAC,QAAQ,SAAS,eAAe;IAC9D,+BAA+B;IAC/B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;IAEtD,8BAA8B;IAC9B,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;IAErD,uCAAuC;IACvC,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,uCAAuC;IACvC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;IAE3F,6BAA6B;IAC7B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACpE;AAED;;;;;GAKG;AACH,MAAM,WAAW,0BAA0B,CAAC,QAAQ,SAAS,eAAe;IAC3E,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;CAClC;AAED;;;;GAIG;AACH,MAAM,MAAM,aAAa,CAAC,QAAQ,SAAS,eAAe,IAAI,CAC7D,KAAK,CAAC,EAAE,SAAS,CAAC,QAAQ,CAAC,EAC3B,OAAO,CAAC,EAAE,0BAA0B,CAAC,QAAQ,CAAC,KAC1C,gBAAgB,CAAC,QAAQ,CAAC,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;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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * The view derivation — the meta.view half of the player pipeline.
3
+ *
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
+ */
9
+ import type { AnyMachineSnapshot } from "xstate";
10
+ import { type PlaySpec } from "@xmachines/play-actor";
11
+ /**
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.
49
+ */
50
+ export declare const deriveCurrentView: (snapshot: AnyMachineSnapshot) => PlaySpec | null;
51
+ //# sourceMappingURL=derive-current-view.d.ts.map
@@ -0,0 +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;AAwDrF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,eAAO,MAAM,iBAAiB,GAAI,UAAU,kBAAkB,KAAG,QAAQ,GAAG,IA4C3E,CAAC"}