@xmachines/play-router 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 (58) hide show
  1. package/README.md +98 -89
  2. package/dist/base-route-map.d.ts +63 -57
  3. package/dist/base-route-map.d.ts.map +1 -1
  4. package/dist/base-route-map.js +65 -59
  5. package/dist/base-route-map.js.map +1 -1
  6. package/dist/build-tree.d.ts +13 -12
  7. package/dist/build-tree.d.ts.map +1 -1
  8. package/dist/build-tree.js +30 -28
  9. package/dist/build-tree.js.map +1 -1
  10. package/dist/create-route-map-from-tree.d.ts +15 -15
  11. package/dist/create-route-map-from-tree.js +15 -15
  12. package/dist/create-route-map.d.ts +18 -16
  13. package/dist/create-route-map.d.ts.map +1 -1
  14. package/dist/create-route-map.js +10 -9
  15. package/dist/create-route-map.js.map +1 -1
  16. package/dist/errors.d.ts +40 -38
  17. package/dist/errors.d.ts.map +1 -1
  18. package/dist/errors.js +40 -38
  19. package/dist/errors.js.map +1 -1
  20. package/dist/extract-routes.d.ts +8 -7
  21. package/dist/extract-routes.d.ts.map +1 -1
  22. package/dist/extract-routes.js +31 -27
  23. package/dist/extract-routes.js.map +1 -1
  24. package/dist/find-route.d.ts +18 -15
  25. package/dist/find-route.d.ts.map +1 -1
  26. package/dist/find-route.js +42 -38
  27. package/dist/find-route.js.map +1 -1
  28. package/dist/index.d.ts +6 -1
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +11 -10
  31. package/dist/index.js.map +1 -1
  32. package/dist/machine-to-graph.d.ts +3 -2
  33. package/dist/machine-to-graph.d.ts.map +1 -1
  34. package/dist/machine-to-graph.js +21 -30
  35. package/dist/machine-to-graph.js.map +1 -1
  36. package/dist/query.d.ts +39 -37
  37. package/dist/query.d.ts.map +1 -1
  38. package/dist/query.js +62 -57
  39. package/dist/query.js.map +1 -1
  40. package/dist/router-bridge-base.d.ts +208 -190
  41. package/dist/router-bridge-base.d.ts.map +1 -1
  42. package/dist/router-bridge-base.js +235 -211
  43. package/dist/router-bridge-base.js.map +1 -1
  44. package/dist/router-sync.d.ts +41 -35
  45. package/dist/router-sync.d.ts.map +1 -1
  46. package/dist/router-sync.js +53 -45
  47. package/dist/router-sync.js.map +1 -1
  48. package/dist/types.d.ts +163 -164
  49. package/dist/types.d.ts.map +1 -1
  50. package/dist/url-pattern-utils.d.ts +53 -47
  51. package/dist/url-pattern-utils.d.ts.map +1 -1
  52. package/dist/url-pattern-utils.js +61 -55
  53. package/dist/url-pattern-utils.js.map +1 -1
  54. package/dist/validate-routes.d.ts +32 -31
  55. package/dist/validate-routes.d.ts.map +1 -1
  56. package/dist/validate-routes.js +30 -29
  57. package/dist/validate-routes.js.map +1 -1
  58. package/package.json +23 -21
package/dist/types.d.ts CHANGED
@@ -2,146 +2,133 @@ import type { Graph } from "@statelyai/graph";
2
2
  import type { Signal } from "@xmachines/play-signals";
3
3
  import type { PlaySpec } from "@xmachines/play-actor";
4
4
  /**
5
- * Data attached to each node in the machine graph representation.
6
- * Captures the essential state metadata needed for route extraction and queries.
5
+ * The data on each node of the graph that represents the machine.
6
+ * It holds the state metadata that the route extraction and the queries need.
7
7
  */
8
8
  export interface MachineNodeData {
9
- /** XState state ID (e.g., "test.dashboard.overview") */
9
+ /** The XState state ID, for example "test.dashboard.overview" */
10
10
  stateId: string;
11
- /** State type from XState */
11
+ /** The state type of XState */
12
12
  type: "atomic" | "compound" | "parallel" | "final" | "history";
13
- /** Original state meta object */
13
+ /** The original meta object of the state */
14
14
  meta?: Record<string, unknown>;
15
- /** Extracted route path from meta.route (string form) */
15
+ /** The route path of meta.route, in its string form */
16
16
  route?: string;
17
17
  }
18
18
  /**
19
- * Data attached to each edge in the machine graph representation.
20
- * Captures transition event and guard information.
19
+ * The data on each edge of the graph that represents the machine.
20
+ * It holds the event of the transition and the information of its guard.
21
21
  */
22
22
  export interface MachineEdgeData {
23
- /** The event type that triggers this transition */
23
+ /** The event type that starts this transition */
24
24
  eventType: string;
25
25
  /**
26
- * @deprecated Never populated under XState v6: every guard (including
27
- * JSON-layer guard names via `createMachineFromConfig`) compiles to a
28
- * function, so guard identity is unrecoverable statically. Use
29
- * {@link MachineEdgeData.guarded} instead.
26
+ * The guard as a string, when a guard is present
27
+ *
28
+ * @deprecated Will be removed in the next major.
30
29
  */
31
30
  guardType?: string;
32
- /**
33
- * True when a guard function gates this transition. XState v6 compiles all
34
- * guards to functions (authored predicates, JSON-layer names, and the
35
- * route-matching guard synthesized on native route transitions), so only
36
- * the presence of a guard — not its identity — is statically knowable.
37
- */
38
- guarded?: boolean;
39
- /**
40
- * True when the transition is an XState v6 function transition: the function
41
- * acts as its own guard/resolver, so its target and conditionality are
42
- * dynamic and unknowable statically (the edge's target falls back to the
43
- * source state).
44
- */
45
- dynamic?: boolean;
46
31
  }
47
32
  /**
48
- * Routing protocol type definitions for @xmachines/play-router
33
+ * The type definitions of the routing protocol of @xmachines/play-router
49
34
  *
50
- * PlayRouteEvent, RouterBridge, RouteMetadata, and RouteObject live here to keep
51
- * routing concerns separate from the base event protocol in @xmachines/play.
35
+ * PlayRouteEvent, RouterBridge, RouteMetadata, and RouteObject are here. The routing
36
+ * therefore stays separate from the base event protocol of @xmachines/play.
52
37
  */
53
38
  /**
54
- * Route object with additional metadata.
39
+ * A route object, with more metadata.
55
40
  */
56
41
  export interface RouteObject {
57
- /** Route path template (e.g., '/user/:id') */
42
+ /** The template of the route path, for example '/user/:id' */
58
43
  path: string;
59
- /** Additional route metadata (title, breadcrumb, etc.) */
44
+ /** The additional metadata of the route: a title, a breadcrumb, and so on */
60
45
  [key: string]: unknown;
61
46
  }
62
47
  /**
63
- * Route metadata from state machine `meta.route` field.
48
+ * The route metadata of the `meta.route` field of a state machine.
64
49
  */
65
50
  export type RouteMetadata = string | RouteObject;
66
51
  /**
67
- * Extracted route information from a state node
52
+ * The route information of a state node
68
53
  */
69
54
  export interface RouteInfo {
70
- /** State identifier (node.id or path.join('.')) */
55
+ /** The identifier of the state: node.id, or path.join('.') */
71
56
  stateId: string;
72
- /** State path segments from root */
57
+ /** The segments of the state path, from the root */
73
58
  statePath: string[];
74
- /** Route path extracted from meta.route */
59
+ /** The route path of meta.route */
75
60
  routePath: string;
76
- /** Route pattern with parameters (e.g., /profile/:userId) if routePath contains params */
61
+ /** The route pattern with its parameters, for example /profile/:userId, when routePath holds a parameter */
77
62
  pattern?: string;
78
- /** Whether route path is absolute (starts with /) */
63
+ /** It tells you if the route path is absolute, which means that it starts with / */
79
64
  isAbsolute: boolean;
80
65
  /**
81
- * Whether this state is routable (has meta.route)
82
- * true = has meta.route, can receive play.route events
66
+ * It tells you if this state has a route, which means that it has a meta.route field.
67
+ * true = it has a meta.route field, and it can receive a play.route event
83
68
  */
84
69
  routable: boolean;
85
- /** Original route metadata */
70
+ /** The original route metadata */
86
71
  metadata: RouteMetadata;
87
72
  }
88
73
  /**
89
- * Node in the route tree representing a single route
74
+ * A node of the route tree. It represents one route
90
75
  */
91
76
  export interface RouteNode {
92
- /** Unique identifier (state ID) */
77
+ /** The unique identifier, which is the state ID */
93
78
  id: string;
94
79
  /**
95
- * The raw route path segment as declared in `meta.route` — may be relative (e.g. `"overview"`)
96
- * or absolute (e.g. `"/dashboard"`). Do not use this for URL matching; use `fullPath` instead.
80
+ * The raw segment of the route path, as `meta.route` declares it. It is relative,
81
+ * for example `"overview"`, or absolute, for example `"/dashboard"`. Never use it for
82
+ * a match of a URL: use `fullPath` for that.
97
83
  */
98
84
  path: string;
99
85
  /**
100
- * The fully resolved absolute path from the root (e.g. `"/dashboard/overview"`).
101
- * Always use `fullPath` for browser URL matching and route map construction.
102
- * `createRouteMapFromTree` and `createRouteMap` both use this field.
86
+ * The complete absolute path from the root, for example `"/dashboard/overview"`.
87
+ * Always use `fullPath` for a match of a browser URL and for the construction of a
88
+ * route map. `createRouteMapFromTree` and `createRouteMap` both use this field.
103
89
  */
104
90
  fullPath: string;
105
- /** Route pattern with parameters (e.g., /profile/:userId) if path contains params */
91
+ /** The route pattern with its parameters, for example /profile/:userId, when path holds a parameter */
106
92
  pattern?: string;
107
- /** XState state ID this route maps to */
93
+ /** The XState state ID of this route */
108
94
  stateId: string;
109
95
  /**
110
- * Whether this state is routable (has meta.route)
111
- * States with meta.route can receive play.route events
96
+ * It tells you if this state has a route, which means that it has a meta.route field.
97
+ * A state with a meta.route field can receive a play.route event
112
98
  */
113
99
  routable: boolean;
114
- /** Child routes */
100
+ /** The child routes */
115
101
  children: RouteNode[];
116
- /** Parent route (null for root) */
102
+ /** The parent route. It is null for the root */
117
103
  parent: RouteNode | null;
118
- /** Original meta.route metadata */
104
+ /** The original meta.route metadata */
119
105
  metadata: RouteMetadata;
120
106
  }
121
107
  /**
122
- * Complete route tree with lookup maps
108
+ * The complete route tree, with its lookup maps
123
109
  *
124
- * Provides bidirectional mapping between state IDs and URL paths:
125
- * - byStateId: Maps state IDs to route nodes (for play.route event targeting)
126
- * - byPath: Maps URL paths to route nodes (for browser navigation)
110
+ * It gives you the map between a state ID and a URL path, in both directions:
111
+ * - byStateId: it maps each state ID to its route node, for the target of a play.route event
112
+ * - byPath: it maps each URL path to its route node, for the browser navigation
127
113
  */
128
114
  export interface RouteTree {
129
- /** Root route node */
115
+ /** The root node of the routes */
130
116
  root: RouteNode;
131
117
  /**
132
- * Map state ID -> route node
133
- * Used to look up URL path from state ID for browser URL sync
118
+ * The map from a state ID to its route node.
119
+ * It gives you the URL path of a state ID, for the update of the browser URL
134
120
  */
135
121
  byStateId: Map<string, RouteNode>;
136
122
  /**
137
- * Map full path -> route node
138
- * Used to look up state ID from URL path for play.route event targeting
123
+ * The map from a complete path to its route node.
124
+ * It gives you the state ID of a URL path, for the target of a play.route event
139
125
  */
140
126
  byPath: Map<string, RouteNode>;
141
127
  /**
142
- * Graph representation of the state machine for advanced queries.
143
- * Populated by extractMachineRoutes() — use for hierarchy queries, reachability checks,
144
- * and transition-aware navigation via @statelyai/graph algorithms.
128
+ * The graph of the state machine, for an advanced query.
129
+ * extractMachineRoutes() fills it. Use it for a query of the hierarchy, for a test of
130
+ * the reachability, and for a navigation that knows the transitions, through the
131
+ * algorithms of @statelyai/graph.
145
132
  *
146
133
  * @example
147
134
  * ```typescript
@@ -152,31 +139,36 @@ export interface RouteTree {
152
139
  graph?: Graph<MachineNodeData, MachineEdgeData>;
153
140
  }
154
141
  /**
155
- * Enhanced routing event with parameter and query support
156
- *
157
- * Unified routing event used throughout the Play architecture. Supports parameter-aware
158
- * navigation patterns (e.g., `/profile/:userId`) for dynamic route segments.
159
- *
160
- * **Architectural Context:** Implements **Passive Infrastructure (INV-04)** by representing
161
- * user navigation intent that the Actor evaluates through guards. Infrastructure proposes
162
- * via `play.route` events, Actor decides via state machine transitions.
163
- *
164
- * **Browser Navigation Flow:**
165
- * 1. Browser fires `popstate`
166
- * 2. Router adapter resolves URL to route target
167
- * 3. Adapter sends `PlayRouteEvent` to Actor
168
- * 4. Actor validates transition via state machine guards
169
- *
170
- * @param type - Event discriminator (always "play.route")
171
- * @param to - Target state ID with # prefix (e.g., '#home', '#profile')
172
- * @param params - Path-only route parameters extracted from the URL path (e.g., `{ userId: '123' }` from `/profile/123`). Query parameters are kept separate in `query`.
173
- * @param query - Query parameters only (isolated from path params)
174
- * @param match - Full URLPattern match result for debugging/observability (optional)
175
- *
176
- * @returns N/A - Interface defines event shape only
142
+ * The routing event, with its parameters and its query
143
+ *
144
+ * This is the one routing event of the complete Play architecture. It supports a
145
+ * navigation that knows the parameters, for example `/profile/:userId`, for a dynamic
146
+ * route segment.
147
+ *
148
+ * **Architectural context:** the event implements **Passive Infrastructure
149
+ * (INV-04)**, because it holds the navigation intent of the user, and the Actor then
150
+ * evaluates that intent with its guards. The infrastructure makes a request with a
151
+ * `play.route` event, and the Actor decides with a transition of its state machine.
152
+ *
153
+ * **The flow of a browser navigation:**
154
+ * 1. The browser fires `popstate`
155
+ * 2. The router adapter resolves the URL to a route target
156
+ * 3. The adapter sends a `PlayRouteEvent` to the Actor
157
+ * 4. The Actor checks the transition with the guards of its state machine
158
+ *
159
+ * @param type - The discriminator of the event. It is always "play.route"
160
+ * @param to - The target state ID, with a # prefix, for example '#home' or '#profile'
161
+ * @param params - The route parameters of the path only, from the URL path, for
162
+ * example `{ userId: '123' }` of `/profile/123`. The `query` field holds the query
163
+ * parameters separately.
164
+ * @param query - The query parameters only. They stay separate from the params of the path
165
+ * @param match - The complete match result of URLPattern, for the debug work and for
166
+ * the observability. It is optional
167
+ *
168
+ * @returns Nothing. This interface defines the shape of the event only
177
169
  *
178
170
  * @example
179
- * Combining base and routing events
171
+ * The base event and the routing event together
180
172
  * ```typescript
181
173
  * import type { PlayEvent } from "@xmachines/play";
182
174
  * import type { PlayRouteEvent } from "@xmachines/play-router";
@@ -185,7 +177,7 @@ export interface RouteTree {
185
177
  * ```
186
178
  *
187
179
  * @example
188
- * Basic navigation to a route
180
+ * A basic navigation to a route
189
181
  * ```typescript
190
182
  * import type { PlayRouteEvent } from "@xmachines/play-router";
191
183
  *
@@ -197,7 +189,7 @@ export interface RouteTree {
197
189
  * ```
198
190
  *
199
191
  * @example
200
- * Navigation with route parameters
192
+ * A navigation with route parameters
201
193
  * ```typescript
202
194
  * import type { PlayRouteEvent } from "@xmachines/play-router";
203
195
  *
@@ -207,30 +199,31 @@ export interface RouteTree {
207
199
  * params: { userId: '123' }
208
200
  * };
209
201
  * actor.send(event);
210
- * // Resolves to route: /profile/123
202
+ * // It resolves to the route /profile/123
211
203
  * ```
212
204
  *
213
205
  * @example
214
- * Navigation with query parameters
206
+ * A navigation with query parameters
215
207
  * ```typescript
216
208
  * import type { PlayRouteEvent } from "@xmachines/play-router";
217
209
  *
218
210
  * const event: PlayRouteEvent = {
219
211
  * type: 'play.route',
220
212
  * to: '#settings',
221
- * params: { section: 'profile' }, // Path-only route parameter
222
- * query: { tab: 'security' } // Query-only
213
+ * params: { section: 'profile' }, // a route parameter of the path only
214
+ * query: { tab: 'security' } // the query only
223
215
  * };
224
216
  * actor.send(event);
225
- * // Resolves to route: /settings/profile?tab=security
217
+ * // It resolves to the route /settings/profile?tab=security
226
218
  * ```
227
219
  *
228
220
  * @see [Play RFC](../../docs/rfc/play.md)
229
221
  *
230
222
  * @remarks
231
- * Use `play.route` when you need parameter-aware navigation with the `route: {}`
232
- * config pattern on your state machine nodes. The `match` field exposes the full
233
- * URLPatternResult for advanced use cases (debugging, pattern analysis).
223
+ * Use `play.route` when you need a navigation that knows the parameters, with the
224
+ * `route: {}` config pattern on the nodes of your state machine. The `match` field
225
+ * gives you the complete URLPatternResult, for an advanced use such as a debug or an
226
+ * analysis of the pattern.
234
227
  */
235
228
  export interface PlayRouteEvent {
236
229
  readonly type: "play.route";
@@ -241,18 +234,19 @@ export interface PlayRouteEvent {
241
234
  [key: string]: unknown;
242
235
  }
243
236
  /**
244
- * Minimal actor interface required by `RouterBridgeBase` and all framework router
245
- * adapters.
237
+ * The minimal actor interface that `RouterBridgeBase` and every framework router
238
+ * adapter require.
246
239
  *
247
- * Using this interface instead of `AbstractActor<AnyActorLogic> & Routable` lets
248
- * `RouterBridgeBase.actor.send` be typed to accept `PlayRouteEvent` directly —
249
- * eliminating the unsafe `(actor.send as (e: PlayRouteEvent) => void)` cast that
250
- * existed when the actor was typed with the weaker `EventObject` constraint.
240
+ * This interface, and not `AbstractActor<AnyActorLogic> & Routable`, gives
241
+ * `RouterBridgeBase.actor.send` the type that accepts a `PlayRouteEvent` directly.
242
+ * It therefore removes the unsafe cast `(actor.send as (e: PlayRouteEvent) => void)`,
243
+ * which the weaker `EventObject` constraint of the actor type needed before.
251
244
  *
252
- * All `AbstractActor` subclasses satisfy this interface structurally because:
253
- * - `AbstractActor` implements `send(event: TEvent): void` where `TEvent` accepts
254
- * any `EventObject`, so `PlayRouteEvent` (a subtype) is always accepted.
255
- * - `Routable` provides `currentRoute` and `initialRoute`.
245
+ * Every `AbstractActor` subclass satisfies this interface structurally, for two
246
+ * reasons:
247
+ * - `AbstractActor` implements `send(event: TEvent): void`, and `TEvent` accepts each
248
+ * `EventObject`. Therefore it always accepts a `PlayRouteEvent`, which is a subtype.
249
+ * - `Routable` gives `currentRoute` and `initialRoute`.
256
250
  *
257
251
  * @example
258
252
  * ```typescript
@@ -266,59 +260,63 @@ export interface PlayRouteEvent {
266
260
  * ```
267
261
  */
268
262
  export interface RoutableActor {
269
- /** TC39 Signal exposing the actor's current URL path (or state ID). */
263
+ /** The TC39 Signal of the current URL path of the actor, or of its state ID. */
270
264
  readonly currentRoute: Signal.Computed<string | null>;
271
265
  /**
272
- * The route derived from the machine's initial state — fixed at construction.
273
- * Router bridges compare this against the browser URL to distinguish a deep-link
274
- * (router wins) from a session restore (actor wins).
266
+ * The route of the initial state of the machine. The constructor fixes it.
267
+ * A router bridge compares it with the browser URL. It therefore separates a deep
268
+ * link, where the router wins, from a restore of a session, where the actor wins.
275
269
  */
276
270
  readonly initialRoute: string | null;
277
- /** Send a route navigation event to the actor. */
271
+ /** Sends a route navigation event to the actor. */
278
272
  send(event: PlayRouteEvent): void;
279
273
  }
280
274
  /**
281
- * Full actor shape used by `PlayRouterProvider` components across all framework
282
- * adapters (`play-solid-router`, `play-vue-router`, `play-react-router`, and the
283
- * adapters built on the shared framework-router bridge bases).
275
+ * The complete actor shape of the `PlayRouterProvider` component of each framework
276
+ * adapter: `play-solid-router`, `play-vue-router`, `play-react-router`, and each
277
+ * adapter on the shared framework router bridge bases.
284
278
  *
285
- * Extends `RoutableActor` with `currentView` — the provider renders the current
286
- * view spec in addition to synchronizing routes, so it needs both capabilities.
279
+ * The shape extends `RoutableActor` with `currentView`, because the provider renders
280
+ * the current view spec and also keeps the routes in step. It therefore needs both
281
+ * capabilities.
287
282
  *
288
- * - Use `RoutableActor` when only routing is needed (e.g. `RouterBridgeBase` subclasses,
289
- * `connectRouter`).
290
- * - Use `PlayActor` when the component also renders the current view spec
291
- * (e.g. `PlayRouterProvider` renderer callback parameter, `PlayRenderer`).
283
+ * - Use `RoutableActor` when you need the routing alone, for example in a
284
+ * `RouterBridgeBase` subclass, or in `connectRouter`.
285
+ * - Use `PlayActor` when the component also renders the current view spec, for
286
+ * example for the renderer callback parameter of `PlayRouterProvider`, and in
287
+ * `PlayRenderer`.
292
288
  *
293
- * All `AbstractActor` subclasses that implement both `Routable` and `Viewable`
294
- * satisfy this interface structurally.
289
+ * Every `AbstractActor` subclass that implements both `Routable` and `Viewable`
290
+ * satisfies this interface structurally.
295
291
  *
296
292
  * @example
297
293
  * ```typescript
298
294
  * import type { PlayActor } from "@xmachines/play-router";
299
295
  *
300
296
  * function MyRouterProvider({ actor }: { actor: PlayActor }) {
301
- * // access actor.currentRoute (routing) and actor.currentView (rendering)
297
+ * // it reads actor.currentRoute for the routing, and actor.currentView for the render
302
298
  * }
303
299
  * ```
304
300
  */
305
301
  export interface PlayActor extends RoutableActor {
306
- /** TC39 Signal exposing the actor's current view spec, or `null` when inactive. */
302
+ /** The TC39 Signal of the current view spec of the actor, or `null` when no view is active. */
307
303
  readonly currentView: Signal.State<PlaySpec | null>;
308
304
  }
309
305
  /**
310
- * RouterBridge interface for runtime infrastructure adapters
306
+ * The RouterBridge interface of a runtime infrastructure adapter
311
307
  *
312
- * Defines the lifecycle connection between Infrastructure (e.g., a framework router) and
313
- * the Actor. Infrastructure "bridges" to the Actor by observing its signals and
314
- * managing its own lifecycle accordingly.
308
+ * The interface defines the connection of the lifecycle between the infrastructure,
309
+ * for example a framework router, and the Actor. The infrastructure builds a "bridge"
310
+ * to the Actor: it observes the signals of the Actor, and it manages its own
311
+ * lifecycle accordingly.
315
312
  *
316
- * **Architectural Context:** Implements **Passive Infrastructure (INV-04)** by establishing
317
- * a unidirectional observation pattern. Infrastructure connects to observe Actor signals
318
- * (currentRoute, currentView, state) and reflects changes without making state decisions.
313
+ * **Architectural context:** the interface implements **Passive Infrastructure
314
+ * (INV-04)**, because it gives an observation in one direction. The infrastructure
315
+ * connects to observe the signals of the Actor (currentRoute, currentView, and
316
+ * state), and it reflects each change. It makes no decision about the state.
319
317
  *
320
318
  * @example
321
- * Framework router bridge implementation
319
+ * The implementation of a framework router bridge
322
320
  * ```typescript
323
321
  * import type { RouterBridge } from "@xmachines/play-router";
324
322
  * import { Signal } from "@xmachines/play-signals";
@@ -327,7 +325,7 @@ export interface PlayActor extends RoutableActor {
327
325
  * private watcher: Signal.Watcher | null = null;
328
326
  *
329
327
  * async connect(): Promise<void> {
330
- * // Start observing actor.currentRoute signal
328
+ * // Start the observation of the actor.currentRoute signal
331
329
  * this.watcher = new Signal.subtle.Watcher(() => {
332
330
  * const route = actor.currentRoute.get();
333
331
  * if (route) router.navigate(route);
@@ -336,62 +334,63 @@ export interface PlayActor extends RoutableActor {
336
334
  * }
337
335
  *
338
336
  * async disconnect(): Promise<void> {
339
- * // Stop observing, cleanup watchers
337
+ * // Stop the observation, and clean the watchers up
340
338
  * this.watcher?.unwatch(actor.currentRoute);
341
339
  * this.watcher = null;
342
340
  * }
343
341
  * }
344
342
  * ```
345
343
  *
346
- * @see [Play RFC](../../docs/rfc/play.md) - Invariant INV-04
344
+ * @see [Play RFC](../../docs/rfc/play.md) - invariant INV-04
347
345
  */
348
346
  export interface RouterBridge {
349
347
  /**
350
- * Connect the router bridge to the Actor
348
+ * Connects the router bridge to the Actor
351
349
  *
352
- * Called when Infrastructure should begin observing Actor signals and
353
- * synchronizing its state (e.g., browser URL) with Actor state.
350
+ * The infrastructure calls it when it must start the observation of the Actor
351
+ * signals, and when it must bring its own state, for example the browser URL, in line
352
+ * with the Actor state.
354
353
  *
355
- * @returns Promise that resolves when connection is established, or void for synchronous connection
354
+ * @returns The promise that resolves after the connection, or void for a synchronous connection
356
355
  *
357
356
  * @example
358
357
  * ```typescript
359
358
  * const bridge: RouterBridge = createBridge(actor, router);
360
359
  * await bridge.connect();
361
- * // Bridge now observing actor.currentRoute signal
360
+ * // The bridge observes the actor.currentRoute signal now
362
361
  * ```
363
362
  */
364
363
  connect(): void | Promise<void>;
365
364
  /**
366
- * Disconnect the router bridge from the Actor
365
+ * Disconnects the router bridge from the Actor
367
366
  *
368
- * Called when Infrastructure should stop observing and clean up resources
369
- * (e.g., signal watchers, event listeners).
367
+ * The infrastructure calls it when it must stop the observation and free its
368
+ * resources, for example a signal watcher and an event listener.
370
369
  *
371
- * @returns Promise that resolves when disconnection is complete, or void for synchronous disconnection
370
+ * @returns The promise that resolves after the disconnection, or void for a synchronous disconnection
372
371
  *
373
372
  * @example
374
373
  * ```typescript
375
374
  * await bridge.disconnect();
376
- * // Bridge stopped observing, resources cleaned up
375
+ * // The bridge stopped its observation, and it freed its resources
377
376
  * ```
378
377
  */
379
378
  disconnect(): void | Promise<void>;
380
379
  }
381
380
  /**
382
- * Minimal window interface required by adapters that subscribe to DOM events
383
- * (e.g. `hashchange`). Injectable for SSR and testing — pass a mock instead of
384
- * the global `window` when the DOM is unavailable.
381
+ * The minimal window interface of an adapter that subscribes to a DOM event, for
382
+ * example to `hashchange`. You can inject it for SSR and for a test: give a mock in
383
+ * place of the global `window` when no DOM is available.
385
384
  *
386
- * Defined structurally (no `Window` reference) so this package compiles without
387
- * the DOM lib.
385
+ * The definition is structural, and it holds no reference to `Window`. This package
386
+ * therefore compiles without the DOM lib.
388
387
  *
389
388
  * @example
390
389
  * ```typescript
391
- * // Normal usage — global window (default)
390
+ * // The normal use — the global window, which is the default
392
391
  * connectRouter({ actor, routeMap });
393
392
  *
394
- * // SSR / test — injected mock
393
+ * // SSR or a test — an injected mock
395
394
  * const mockWin: WindowLike = { addEventListener: vi.fn(), removeEventListener: vi.fn() };
396
395
  * connectRouter({ actor, routeMap, window: mockWin });
397
396
  * ```
@@ -401,16 +400,16 @@ export interface WindowLike {
401
400
  removeEventListener(type: string, listener: (event: Event) => void): void;
402
401
  }
403
402
  /**
404
- * Minimal location interface required by adapters that read the current URL at
405
- * `connect()` time. Injectable for SSR and testing — pass a mock instead of the
406
- * global `location` when the DOM is unavailable.
403
+ * The minimal location interface of an adapter that reads the current URL at the
404
+ * moment of `connect()`. You can inject it for SSR and for a test: give a mock in
405
+ * place of the global `location` when no DOM is available.
407
406
  *
408
- * Defined structurally (no `Location` reference) so this package compiles without
409
- * the DOM lib.
407
+ * The definition is structural, and it holds no reference to `Location`. This package
408
+ * therefore compiles without the DOM lib.
410
409
  *
411
410
  * @example
412
411
  * ```typescript
413
- * // SSR / test — injected mock
412
+ * // SSR or a test — an injected mock
414
413
  * const mockLoc: LocationLike = { pathname: "/dashboard", search: "?tab=posts" };
415
414
  * connectRouter({ actor, routeMap, location: mockLoc });
416
415
  * ```
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}