@xmachines/play-xstate 1.0.0-beta.2 → 1.0.0-beta.21

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 (80) hide show
  1. package/README.md +263 -107
  2. package/dist/define-player.d.ts +6 -56
  3. package/dist/define-player.d.ts.map +1 -1
  4. package/dist/define-player.js +8 -60
  5. package/dist/define-player.js.map +1 -1
  6. package/dist/define-player.typecheck.d.ts +2 -0
  7. package/dist/define-player.typecheck.d.ts.map +1 -0
  8. package/dist/define-player.typecheck.js +48 -0
  9. package/dist/define-player.typecheck.js.map +1 -0
  10. package/dist/errors.d.ts +66 -0
  11. package/dist/errors.d.ts.map +1 -0
  12. package/dist/errors.js +76 -0
  13. package/dist/errors.js.map +1 -0
  14. package/dist/guards/compose.d.ts +14 -3
  15. package/dist/guards/compose.d.ts.map +1 -1
  16. package/dist/guards/compose.js +26 -0
  17. package/dist/guards/compose.js.map +1 -1
  18. package/dist/guards/helpers.d.ts +13 -17
  19. package/dist/guards/helpers.d.ts.map +1 -1
  20. package/dist/guards/helpers.js +20 -25
  21. package/dist/guards/helpers.js.map +1 -1
  22. package/dist/guards/index.d.ts +2 -1
  23. package/dist/guards/index.d.ts.map +1 -1
  24. package/dist/guards/index.js +1 -1
  25. package/dist/guards/index.js.map +1 -1
  26. package/dist/guards/types.d.ts +3 -2
  27. package/dist/guards/types.d.ts.map +1 -1
  28. package/dist/index.d.ts +7 -8
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +3 -5
  31. package/dist/index.js.map +1 -1
  32. package/dist/player-actor.d.ts +70 -22
  33. package/dist/player-actor.d.ts.map +1 -1
  34. package/dist/player-actor.js +290 -88
  35. package/dist/player-actor.js.map +1 -1
  36. package/dist/player-actor.typecheck.d.ts +2 -0
  37. package/dist/player-actor.typecheck.d.ts.map +1 -0
  38. package/dist/player-actor.typecheck.js +27 -0
  39. package/dist/player-actor.typecheck.js.map +1 -0
  40. package/dist/routing/build-url.d.ts +22 -16
  41. package/dist/routing/build-url.d.ts.map +1 -1
  42. package/dist/routing/build-url.js +27 -20
  43. package/dist/routing/build-url.js.map +1 -1
  44. package/dist/routing/derive-route.d.ts +2 -2
  45. package/dist/routing/derive-route.d.ts.map +1 -1
  46. package/dist/routing/derive-route.js +3 -3
  47. package/dist/routing/derive-route.js.map +1 -1
  48. package/dist/routing/format-play-route-transitions.d.ts +41 -4
  49. package/dist/routing/format-play-route-transitions.d.ts.map +1 -1
  50. package/dist/routing/format-play-route-transitions.js +22 -19
  51. package/dist/routing/format-play-route-transitions.js.map +1 -1
  52. package/dist/routing/index.d.ts +2 -1
  53. package/dist/routing/index.d.ts.map +1 -1
  54. package/dist/routing/types.d.ts +8 -13
  55. package/dist/routing/types.d.ts.map +1 -1
  56. package/dist/signals/index.d.ts +0 -1
  57. package/dist/signals/index.d.ts.map +1 -1
  58. package/dist/signals/index.js +0 -1
  59. package/dist/signals/index.js.map +1 -1
  60. package/dist/signals/state-signal.d.ts +1 -1
  61. package/dist/signals/state-signal.d.ts.map +1 -1
  62. package/dist/types.d.ts +20 -14
  63. package/dist/types.d.ts.map +1 -1
  64. package/package.json +26 -19
  65. package/dist/catalog/index.d.ts +0 -12
  66. package/dist/catalog/index.d.ts.map +0 -1
  67. package/dist/catalog/index.js +0 -11
  68. package/dist/catalog/index.js.map +0 -1
  69. package/dist/catalog/types.d.ts +0 -36
  70. package/dist/catalog/types.d.ts.map +0 -1
  71. package/dist/catalog/types.js +0 -2
  72. package/dist/catalog/types.js.map +0 -1
  73. package/dist/catalog/validate-binding.d.ts +0 -21
  74. package/dist/catalog/validate-binding.d.ts.map +0 -1
  75. package/dist/catalog/validate-binding.js +0 -30
  76. package/dist/catalog/validate-binding.js.map +0 -1
  77. package/dist/catalog/validate-props.d.ts +0 -41
  78. package/dist/catalog/validate-props.d.ts.map +0 -1
  79. package/dist/catalog/validate-props.js +0 -95
  80. package/dist/catalog/validate-props.js.map +0 -1
@@ -1,27 +1,34 @@
1
1
  import { isAbsoluteRoute } from "./derive-route.js";
2
+ import { MissingRouteParamError } from "../errors.js";
2
3
  /**
3
- * Build full URL from route template and context
4
+ * Build a full URL from a route template and the actor's context.
4
5
  *
5
- * Per CONTEXT.md:
6
- * - "currentRoute derivation: Full URL generation including query params, hash, base path"
7
- * - "Parameters: String template syntax — /user/:id"
8
- * - "Inheritance: relative paths inherit parent route"
6
+ * Substitutes `:param` and `:param?` placeholders from `context.routeParams`
7
+ * or flat `context` values, then appends query params and hash fragments.
9
8
  *
10
- * Per RESEARCH.md Pattern 3: Replace :param with context values
9
+ * Parameter lookup order for each placeholder:
10
+ * 1. `context.routeParams[param]` — preferred when the state machine stores
11
+ * route parameters in a dedicated sub-object
12
+ * 2. `context[param]` — flat context fallback
13
+ *
14
+ * @param routeTemplate - Route path template, e.g. `"/profile/:userId"` or
15
+ * `"/settings/:section?"`.
16
+ * @param context - Actor context object containing parameter values, optional
17
+ * `query` record, optional `hash` string, and optional `basePath` prefix.
18
+ * @returns The fully resolved URL string.
19
+ *
20
+ * @throws {MissingRouteParamError} When a **required** `:param` placeholder has no
21
+ * matching value in context. Optional parameters (`:param?`) are silently omitted
22
+ * when missing. Import the class from `@xmachines/play-xstate/errors`.
11
23
  *
12
24
  * @example
13
25
  * ```typescript
14
- * const url = buildRouteUrl('/user/:id', {
15
- * id: '123',
16
- * query: { tab: 'profile' },
17
- * hash: 'section-1'
18
- * });
19
- * // Result: '/user/123?tab=profile#section-1'
20
- * ```
26
+ * buildRouteUrl("/user/:id", { id: "123", query: { tab: "profile" }, hash: "top" });
27
+ * // → "/user/123?tab=profile#top"
21
28
  *
22
- * @param routeTemplate - Route path with :param placeholders
23
- * @param context - Route context with parameters, query, hash
24
- * @returns Full URL string
29
+ * buildRouteUrl("/settings/:section?", {});
30
+ * // "/settings" (optional param omitted)
31
+ * ```
25
32
  */
26
33
  export const buildRouteUrl = (routeTemplate, context = {}) => {
27
34
  // Handle relative vs absolute paths
@@ -33,7 +40,8 @@ export const buildRouteUrl = (routeTemplate, context = {}) => {
33
40
  url = substituteParams(url, context);
34
41
  // Append query params from context
35
42
  if (context.query && typeof context.query === "object") {
36
- const params = new URLSearchParams(context.query);
43
+ const stringEntries = Object.entries(context.query).map(([k, v]) => [k, String(v)]);
44
+ const params = new URLSearchParams(stringEntries);
37
45
  const queryString = params.toString();
38
46
  if (queryString) {
39
47
  url += `?${queryString}`;
@@ -61,6 +69,7 @@ export const buildRouteUrl = (routeTemplate, context = {}) => {
61
69
  * @param template - URL template with :param or :param? syntax
62
70
  * @param context - Context with parameter values (may have routeParams field)
63
71
  * @returns URL with parameters substituted and double slashes cleaned
72
+ * @throws {MissingRouteParamError} When a required route parameter is missing
64
73
  */
65
74
  const substituteParams = (template, context) => {
66
75
  // Replace parameters, handling optional syntax
@@ -78,9 +87,7 @@ const substituteParams = (template, context) => {
78
87
  hasOptionalRemoval = true;
79
88
  return ""; // Will leave // in path, cleaned up below
80
89
  }
81
- // Required parameter missing - warn and use empty string
82
- console.warn(`Route parameter '${param}' not found in context. Template: ${template}`);
83
- return "";
90
+ throw new MissingRouteParamError(param, template);
84
91
  });
85
92
  // Clean up double slashes
86
93
  let cleaned = result.replace(/\/+/g, "/");
@@ -1 +1 @@
1
- {"version":3,"file":"build-url.js","sourceRoot":"","sources":["../../src/routing/build-url.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"build-url.js","sourceRoot":"","sources":["../../src/routing/build-url.ts"],"names":[],"mappings":"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"}
@@ -72,7 +72,7 @@
72
72
  * console.log(route); // "/dashboard"
73
73
  * ```
74
74
  *
75
- * @see {@link https://gitlab.com/xmachin-es/rfc/-/blob/main/src/play-v1.md | RFC Play v1}
75
+ * @see [Play RFC](../../../docs/rfc/play.md)
76
76
  * @see {@link buildRouteUrl} for URL construction with parameter substitution
77
77
  * @see {@link isAbsoluteRoute} for checking path absoluteness
78
78
  *
@@ -85,7 +85,7 @@
85
85
  * not all states need routes. For example, intermediate loading states or substates may
86
86
  * not correspond to distinct URLs.
87
87
  */
88
- export declare const deriveRoute: (stateMeta: Record<string, any>) => string | null;
88
+ export declare const deriveRoute: (stateMeta: Record<string, unknown>) => string | null;
89
89
  /**
90
90
  * Check if route path is absolute
91
91
  *
@@ -1 +1 @@
1
- {"version":3,"file":"derive-route.d.ts","sourceRoot":"","sources":["../../src/routing/derive-route.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsFG;AACH,eAAO,MAAM,WAAW,GAAI,WAAW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAG,MAAM,GAAG,IAYrE,CAAC;AA2BF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,KAAG,OAE9C,CAAC"}
1
+ {"version":3,"file":"derive-route.d.ts","sourceRoot":"","sources":["../../src/routing/derive-route.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsFG;AACH,eAAO,MAAM,WAAW,GAAI,WAAW,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,MAAM,GAAG,IAYzE,CAAC;AA2BF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,KAAG,OAE9C,CAAC"}
@@ -72,7 +72,7 @@
72
72
  * console.log(route); // "/dashboard"
73
73
  * ```
74
74
  *
75
- * @see {@link https://gitlab.com/xmachin-es/rfc/-/blob/main/src/play-v1.md | RFC Play v1}
75
+ * @see [Play RFC](../../../docs/rfc/play.md)
76
76
  * @see {@link buildRouteUrl} for URL construction with parameter substitution
77
77
  * @see {@link isAbsoluteRoute} for checking path absoluteness
78
78
  *
@@ -88,10 +88,10 @@
88
88
  export const deriveRoute = (stateMeta) => {
89
89
  // Iterate through active state nodes to find route information
90
90
  for (const [_stateId, meta] of Object.entries(stateMeta)) {
91
- if (!meta)
91
+ if (typeof meta !== "object" || meta === null)
92
92
  continue;
93
93
  // Check meta.route for routable states
94
- if (meta.route) {
94
+ if ("route" in meta && meta.route) {
95
95
  return normalizeRoute(meta.route);
96
96
  }
97
97
  }
@@ -1 +1 @@
1
- {"version":3,"file":"derive-route.js","sourceRoot":"","sources":["../../src/routing/derive-route.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsFG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,SAA8B,EAAiB,EAAE;IAC5E,+DAA+D;IAC/D,KAAK,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1D,IAAI,CAAC,IAAI;YAAE,SAAS;QAEpB,uCAAuC;QACvC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,OAAO,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;IACF,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,cAAc,GAAG,CAAC,KAAoB,EAAU,EAAE;IACvD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACd,CAAC;IAED,kCAAkC;IAClC,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;QAC3D,OAAQ,KAAqB,CAAC,IAAI,CAAC;IACpC,CAAC;IAED,MAAM,IAAI,KAAK,CACd,2BAA2B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,uCAAuC,CACvF,CAAC;AACH,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAAY,EAAW,EAAE;IACxD,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC,CAAC"}
1
+ {"version":3,"file":"derive-route.js","sourceRoot":"","sources":["../../src/routing/derive-route.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsFG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,SAAkC,EAAiB,EAAE;IAChF,+DAA+D;IAC/D,KAAK,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1D,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;YAAE,SAAS;QAExD,uCAAuC;QACvC,IAAI,OAAO,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACnC,OAAO,cAAc,CAAC,IAAI,CAAC,KAAsB,CAAC,CAAC;QACpD,CAAC;IACF,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,cAAc,GAAG,CAAC,KAAoB,EAAU,EAAE;IACvD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACd,CAAC;IAED,kCAAkC;IAClC,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;QAC3D,OAAQ,KAAqB,CAAC,IAAI,CAAC;IACpC,CAAC;IAED,MAAM,IAAI,KAAK,CACd,2BAA2B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,uCAAuC,CACvF,CAAC;AACH,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAAY,EAAW,EAAE;IACxD,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC,CAAC"}
@@ -1,3 +1,40 @@
1
+ /**
2
+ * Minimal structural shape of a single XState state node as read by
3
+ * `formatPlayRouteTransitions` when crawling the machine config.
4
+ *
5
+ * Only the fields the function actually inspects are typed here; all other
6
+ * state-node fields (e.g. `on`, `entry`, `after`) pass through unmodified via
7
+ * the index signature.
8
+ */
9
+ export type RouteStateNode = {
10
+ /** Optional explicit state ID (e.g. `"home"`, `"settings"`). Used as the `#id` target in `play.route` events. */
11
+ id?: string;
12
+ /** State metadata — `meta.route` marks the state as routable. */
13
+ meta?: {
14
+ /** URL path template (e.g. `"/profile/:username"`, `"/settings/:section?"`). */
15
+ route?: string;
16
+ };
17
+ /** Nested child states, recursively crawled for additional route declarations. */
18
+ states?: Record<string, RouteStateNode>;
19
+ [key: string]: unknown;
20
+ };
21
+ /**
22
+ * Minimal structural constraint for machine configs accepted by
23
+ * `formatPlayRouteTransitions`.
24
+ *
25
+ * This is intentionally loose so the function accepts both the bare `createMachine`
26
+ * config object and the stricter `setup().createMachine` config without requiring
27
+ * any type casts at the call site. The generic `T extends RouteMachineConfig`
28
+ * parameter on `formatPlayRouteTransitions` preserves the original concrete type
29
+ * through the transform, so the return value remains directly usable by
30
+ * `setup().createMachine()`.
31
+ */
32
+ export type RouteMachineConfig = {
33
+ context?: unknown;
34
+ states?: Record<string, unknown> | undefined;
35
+ on?: Record<string, unknown> | undefined;
36
+ [key: string]: unknown;
37
+ };
1
38
  /**
2
39
  * Formats play.route transitions from declarative route configs
3
40
  *
@@ -6,7 +43,7 @@
6
43
  *
7
44
  * Inspired by XState's internal formatRouteTransitions (stateUtils.ts line 391).
8
45
  *
9
- * Usage:
46
+ * @example
10
47
  * ```typescript
11
48
  * const machineConfig = {
12
49
  * id: "myMachine",
@@ -24,8 +61,8 @@
24
61
  * - Target the appropriate state
25
62
  * - Assign routeParams and queryParams from the event to context
26
63
  *
27
- * @param machineConfig - XState machine config (before createMachine)
28
- * @returns Machine config with auto-generated play.route handlers
64
+ * @param machineConfig - XState machine config (before createMachine). Must extend `RouteMachineConfig`.
65
+ * @returns The same machine config with auto-generated `play.route` handlers merged in, preserving the original type `T`.
29
66
  */
30
- export declare function formatPlayRouteTransitions(machineConfig: any): any;
67
+ export declare function formatPlayRouteTransitions<T extends RouteMachineConfig>(machineConfig: T): T;
31
68
  //# sourceMappingURL=format-play-route-transitions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"format-play-route-transitions.d.ts","sourceRoot":"","sources":["../../src/routing/format-play-route-transitions.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,0BAA0B,CAAC,aAAa,EAAE,GAAG,GAAG,GAAG,CA6ClE"}
1
+ {"version":3,"file":"format-play-route-transitions.d.ts","sourceRoot":"","sources":["../../src/routing/format-play-route-transitions.ts"],"names":[],"mappings":"AAYA;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG;IAC5B,iHAAiH;IACjH,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,iEAAiE;IACjE,IAAI,CAAC,EAAE;QACN,gFAAgF;QAChF,KAAK,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACxC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB,CAAC;AASF;;;;;;;;;;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;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,kBAAkB,EAAE,aAAa,EAAE,CAAC,GAAG,CAAC,CAiD5F"}
@@ -7,7 +7,7 @@ import { assign } from "xstate";
7
7
  *
8
8
  * Inspired by XState's internal formatRouteTransitions (stateUtils.ts line 391).
9
9
  *
10
- * Usage:
10
+ * @example
11
11
  * ```typescript
12
12
  * const machineConfig = {
13
13
  * id: "myMachine",
@@ -25,20 +25,22 @@ import { assign } from "xstate";
25
25
  * - Target the appropriate state
26
26
  * - Assign routeParams and queryParams from the event to context
27
27
  *
28
- * @param machineConfig - XState machine config (before createMachine)
29
- * @returns Machine config with auto-generated play.route handlers
28
+ * @param machineConfig - XState machine config (before createMachine). Must extend `RouteMachineConfig`.
29
+ * @returns The same machine config with auto-generated `play.route` handlers merged in, preserving the original type `T`.
30
30
  */
31
31
  export function formatPlayRouteTransitions(machineConfig) {
32
32
  const routeTransitions = [];
33
33
  const collectRoutes = (states, parentPath = "") => {
34
34
  Object.entries(states).forEach(([key, stateConfig]) => {
35
- const stateId = stateConfig.id || (parentPath ? `${parentPath}.${key}` : key);
36
- if (stateConfig.meta?.route && stateConfig.id) {
37
- // Generate transition for this routable state
35
+ const node = stateConfig;
36
+ // Build the full key-based path from the root for the transition target
37
+ // (XState targets use the state key hierarchy, not explicit IDs)
38
+ const statePath = parentPath ? `${parentPath}.${key}` : key;
39
+ if (node.meta?.route && node.id) {
38
40
  const transition = {
39
- target: `.${key}`, // Relative target from root
40
- guard: ({ event }) => event.to === `#${stateConfig.id}`,
41
- reenter: true, // Enable context updates on self-transitions
41
+ target: `.${statePath}`,
42
+ guard: ({ event }) => event.to === `#${node.id}`,
43
+ reenter: true,
42
44
  actions: assign({
43
45
  routeParams: ({ event }) => event.params || {},
44
46
  queryParams: ({ event }) => event.query || {},
@@ -46,23 +48,24 @@ export function formatPlayRouteTransitions(machineConfig) {
46
48
  };
47
49
  routeTransitions.push(transition);
48
50
  }
49
- // Recursively collect from child states
50
- if (stateConfig.states) {
51
- collectRoutes(stateConfig.states, stateId);
51
+ if (node.states) {
52
+ collectRoutes(node.states, statePath);
52
53
  }
53
54
  });
54
55
  };
55
- if (machineConfig.states) {
56
- collectRoutes(machineConfig.states);
56
+ const machineStates = machineConfig.states;
57
+ if (machineStates) {
58
+ collectRoutes(machineStates);
57
59
  }
58
- // Add play.route handler to root if we found any routes
59
60
  if (routeTransitions.length > 0) {
61
+ const existingOn = machineConfig.on || {};
62
+ const updatedOn = {
63
+ ...existingOn,
64
+ "play.route": routeTransitions,
65
+ };
60
66
  return {
61
67
  ...machineConfig,
62
- on: {
63
- ...machineConfig.on,
64
- "play.route": routeTransitions,
65
- },
68
+ on: updatedOn,
66
69
  };
67
70
  }
68
71
  return machineConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"format-play-route-transitions.js","sourceRoot":"","sources":["../../src/routing/format-play-route-transitions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,0BAA0B,CAAC,aAAkB;IAC5D,MAAM,gBAAgB,GAAU,EAAE,CAAC;IAEnC,MAAM,aAAa,GAAG,CAAC,MAA2B,EAAE,UAAU,GAAG,EAAE,EAAE,EAAE;QACtE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,EAAE;YACrD,MAAM,OAAO,GAAG,WAAW,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAE9E,IAAI,WAAW,CAAC,IAAI,EAAE,KAAK,IAAI,WAAW,CAAC,EAAE,EAAE,CAAC;gBAC/C,8CAA8C;gBAC9C,MAAM,UAAU,GAAG;oBAClB,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,4BAA4B;oBAC/C,KAAK,EAAE,CAAC,EAAE,KAAK,EAAkB,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,IAAI,WAAW,CAAC,EAAE,EAAE;oBACvE,OAAO,EAAE,IAAI,EAAE,6CAA6C;oBAC5D,OAAO,EAAE,MAAM,CAAC;wBACf,WAAW,EAAE,CAAC,EAAE,KAAK,EAAkB,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE;wBAC9D,WAAW,EAAE,CAAC,EAAE,KAAK,EAAkB,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE;qBAC7D,CAAC;iBACF,CAAC;gBAEF,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACnC,CAAC;YAED,wCAAwC;YACxC,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;gBACxB,aAAa,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC5C,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC;IAEF,IAAI,aAAa,CAAC,MAAM,EAAE,CAAC;QAC1B,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IAED,wDAAwD;IACxD,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjC,OAAO;YACN,GAAG,aAAa;YAChB,EAAE,EAAE;gBACH,GAAG,aAAa,CAAC,EAAE;gBACnB,YAAY,EAAE,gBAAgB;aAC9B;SACD,CAAC;IACH,CAAC;IAED,OAAO,aAAa,CAAC;AACtB,CAAC"}
1
+ {"version":3,"file":"format-play-route-transitions.js","sourceRoot":"","sources":["../../src/routing/format-play-route-transitions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AA0DhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,0BAA0B,CAA+B,aAAgB;IACxF,MAAM,gBAAgB,GAAsB,EAAE,CAAC;IAE/C,MAAM,aAAa,GAAG,CAAC,MAA+B,EAAE,UAAU,GAAG,EAAE,EAAE,EAAE;QAC1E,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,EAAE;YACrD,MAAM,IAAI,GAAG,WAA6B,CAAC;YAC3C,wEAAwE;YACxE,iEAAiE;YACjE,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;YAE5D,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;gBACjC,MAAM,UAAU,GAAoB;oBACnC,MAAM,EAAE,IAAI,SAAS,EAAE;oBACvB,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,IAAI,IAAI,CAAC,EAAE,EAAE;oBAChD,OAAO,EAAE,IAAI;oBACb,OAAO,EAAE,MAAM,CAAC;wBACf,WAAW,EAAE,CAAC,EAAE,KAAK,EAAkB,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE;wBAC9D,WAAW,EAAE,CAAC,EAAE,KAAK,EAAkB,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE;qBAC7D,CAAC;iBACF,CAAC;gBAEF,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACnC,CAAC;YAED,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBACjB,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YACvC,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,aAAa,CAAC,MAAM,CAAC;IAC3C,IAAI,aAAa,EAAE,CAAC;QACnB,aAAa,CAAC,aAAa,CAAC,CAAC;IAC9B,CAAC;IAED,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjC,MAAM,UAAU,GAAG,aAAa,CAAC,EAAE,IAAI,EAAE,CAAC;QAC1C,MAAM,SAAS,GAAG;YACjB,GAAG,UAAU;YACb,YAAY,EAAE,gBAAgB;SAC9B,CAAC;QAEF,OAAO;YACN,GAAG,aAAa;YAChB,EAAE,EAAE,SAAS;SACR,CAAC;IACR,CAAC;IAED,OAAO,aAAa,CAAC;AACtB,CAAC"}
@@ -9,5 +9,6 @@
9
9
  export { deriveRoute, isAbsoluteRoute } from "./derive-route.js";
10
10
  export { buildRouteUrl } from "./build-url.js";
11
11
  export { formatPlayRouteTransitions } from "./format-play-route-transitions.js";
12
- export type { RouteMetadata, RouteObject, RouteContext } from "./types.js";
12
+ export type { RouteMachineConfig, RouteStateNode } from "./format-play-route-transitions.js";
13
+ export type { RouteContext } from "./types.js";
13
14
  //# 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,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAChF,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,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,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,MAAM,YAAY,CAAC"}
@@ -1,18 +1,8 @@
1
- /**
2
- * Route metadata from state machine
3
- *
4
- * Per CONTEXT.md: Both simple strings and objects supported
5
- */
6
- export type RouteMetadata = string | RouteObject;
7
- /**
8
- * Route object with additional metadata
9
- */
10
1
  export interface RouteObject {
11
- /** Route path template (e.g., '/user/:id') */
12
2
  path: string;
13
- /** Additional route metadata (title, etc.) */
14
- [key: string]: any;
3
+ [key: string]: unknown;
15
4
  }
5
+ export type RouteMetadata = string | RouteObject;
16
6
  /**
17
7
  * Route build context from machine context
18
8
  */
@@ -20,6 +10,11 @@ export interface RouteContext {
20
10
  /** Base path for relative routes */
21
11
  basePath?: string;
22
12
  /** Route parameters to substitute */
23
- [key: string]: any;
13
+ routeParams?: Record<string, unknown>;
14
+ /** Query parameters */
15
+ query?: Record<string, unknown>;
16
+ /** Hash fragment */
17
+ hash?: string;
18
+ [key: string]: unknown;
24
19
  }
25
20
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/routing/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,WAAW,CAAC;AAEjD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B,oCAAoC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACnB"}
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;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B,oCAAoC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,uBAAuB;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,oBAAoB;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB"}
@@ -1,3 +1,2 @@
1
1
  export { StateSignalManager } from "./state-signal.js";
2
- export { scheduleMicrotask } from "./debounce.js";
3
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/signals/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/signals/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -1,3 +1,2 @@
1
1
  export { StateSignalManager } from "./state-signal.js";
2
- export { scheduleMicrotask } from "./debounce.js";
3
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/signals/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/signals/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -9,7 +9,7 @@ import { Signal } from "@xmachines/play-signals";
9
9
  * XState already provides coalescence - if multiple transitions occur in a single send(),
10
10
  * the subscription callback only fires once with the final state.
11
11
  */
12
- export declare class StateSignalManager<TSnapshot = any> {
12
+ export declare class StateSignalManager<TSnapshot = unknown> {
13
13
  private _signal;
14
14
  constructor(initialSnapshot: TSnapshot);
15
15
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"state-signal.d.ts","sourceRoot":"","sources":["../../src/signals/state-signal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEjD;;;;;;;;;GASG;AACH,qBAAa,kBAAkB,CAAC,SAAS,GAAG,GAAG;IAC9C,OAAO,CAAC,OAAO,CAA0B;gBAE7B,eAAe,EAAE,SAAS;IAItC;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAEpC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,QAAQ,EAAE,SAAS,GAAG,IAAI;IAIzC;;OAEG;IACH,OAAO,IAAI,IAAI;CAGf"}
1
+ {"version":3,"file":"state-signal.d.ts","sourceRoot":"","sources":["../../src/signals/state-signal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEjD;;;;;;;;;GASG;AACH,qBAAa,kBAAkB,CAAC,SAAS,GAAG,OAAO;IAClD,OAAO,CAAC,OAAO,CAA0B;gBAE7B,eAAe,EAAE,SAAS;IAItC;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAEpC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,QAAQ,EAAE,SAAS,GAAG,IAAI;IAIzC;;OAEG;IACH,OAAO,IAAI,IAAI;CAGf"}
package/dist/types.d.ts CHANGED
@@ -1,39 +1,45 @@
1
- import type { AnyStateMachine } from "xstate";
1
+ import type { AnyStateMachine, InputFrom, SnapshotFrom } from "xstate";
2
2
  import type { PlayerActor as PlayerActorClass } from "./player-actor.js";
3
3
  /**
4
4
  * Configuration for definePlayer()
5
- *
6
- * Per CONTEXT.md: Single config object with machine, catalog, options
7
5
  */
8
- export interface PlayerConfig<TMachine extends AnyStateMachine, TCatalog = any> {
6
+ export interface PlayerConfig<TMachine extends AnyStateMachine> {
9
7
  /** XState v5 state machine */
10
8
  machine: TMachine;
11
- /** UI component catalog (optional - allows machines without UI) */
12
- catalog?: TCatalog;
13
9
  /** Lifecycle hooks and configuration */
14
- options?: PlayerOptions;
10
+ options?: PlayerOptions<TMachine>;
15
11
  }
16
12
  /**
17
13
  * Player lifecycle hooks
18
14
  *
19
15
  * Per CONTEXT.md: Rich set of hooks for observability
20
16
  */
21
- export interface PlayerOptions {
17
+ export interface PlayerOptions<TMachine extends AnyStateMachine> {
22
18
  /** Called when actor starts */
23
- onStart?: (actor: any) => void;
19
+ onStart?: (actor: PlayerActorClass<TMachine>) => void;
24
20
  /** Called when actor stops */
25
- onStop?: (actor: any) => void;
21
+ onStop?: (actor: PlayerActorClass<TMachine>) => void;
26
22
  /** Called on every state transition */
27
- onTransition?: (actor: any, prevState: any, nextState: any) => void;
23
+ onTransition?: (actor: PlayerActorClass<TMachine>, prevState: SnapshotFrom<TMachine>, nextState: SnapshotFrom<TMachine>) => void;
28
24
  /** Called when state signal changes */
29
- onStateChange?: (actor: any, state: any) => void;
25
+ onStateChange?: (actor: PlayerActorClass<TMachine>, state: SnapshotFrom<TMachine>) => void;
30
26
  /** Called on actor errors */
31
- onError?: (actor: any, error: Error) => void;
27
+ onError?: (actor: PlayerActorClass<TMachine>, error: Error) => void;
28
+ }
29
+ /**
30
+ * Optional restore arguments for the player factory.
31
+ *
32
+ * Mirrors XState's createActor options bag while preserving the existing
33
+ * `createPlayer(input?)` calling convention for fresh actors.
34
+ */
35
+ export interface PlayerFactoryResumeOptions<TMachine extends AnyStateMachine> {
36
+ /** Persisted XState snapshot used to restore actor state. */
37
+ snapshot?: SnapshotFrom<TMachine>;
32
38
  }
33
39
  /**
34
40
  * Factory function returned by definePlayer()
35
41
  *
36
42
  * Per CONTEXT.md: Factory supports creating multiple actor instances
37
43
  */
38
- export type PlayerFactory<TInput = any> = (input?: TInput) => PlayerActorClass<any>;
44
+ export type PlayerFactory<TMachine extends AnyStateMachine> = (input?: InputFrom<TMachine>, options?: PlayerFactoryResumeOptions<TMachine>) => PlayerActorClass<TMachine>;
39
45
  //# 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,MAAM,QAAQ,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,IAAI,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAEzE;;;;GAIG;AACH,MAAM,WAAW,YAAY,CAAC,QAAQ,SAAS,eAAe,EAAE,QAAQ,GAAG,GAAG;IAC7E,8BAA8B;IAC9B,OAAO,EAAE,QAAQ,CAAC;IAElB,mEAAmE;IACnE,OAAO,CAAC,EAAE,QAAQ,CAAC;IAEnB,wCAAwC;IACxC,OAAO,CAAC,EAAE,aAAa,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC7B,+BAA+B;IAC/B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAE/B,8BAA8B;IAC9B,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAE9B,uCAAuC;IACvC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,KAAK,IAAI,CAAC;IAEpE,uCAAuC;IACvC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAEjD,6BAA6B;IAC7B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC7C;AAED;;;;GAIG;AACH,MAAM,MAAM,aAAa,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,gBAAgB,CAAC,GAAG,CAAC,CAAC"}
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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xmachines/play-xstate",
3
- "version": "1.0.0-beta.2",
3
+ "version": "1.0.0-beta.21",
4
4
  "description": "XState v5 adapter for Play Architecture",
5
5
  "keywords": [
6
6
  "actor-model",
@@ -11,41 +11,48 @@
11
11
  ],
12
12
  "license": "MIT",
13
13
  "author": "",
14
+ "files": [
15
+ "dist",
16
+ "README.md",
17
+ "LICENSE"
18
+ ],
14
19
  "type": "module",
15
20
  "main": "./dist/index.js",
16
21
  "types": "./dist/index.d.ts",
17
22
  "exports": {
18
23
  ".": {
24
+ "source": "./src/index.ts",
19
25
  "types": "./dist/index.d.ts",
20
26
  "import": "./dist/index.js"
27
+ },
28
+ "./errors": {
29
+ "source": "./src/errors.ts",
30
+ "types": "./dist/errors.d.ts",
31
+ "import": "./dist/errors.js"
21
32
  }
22
33
  },
34
+ "publishConfig": {
35
+ "access": "public"
36
+ },
23
37
  "scripts": {
24
38
  "build": "tsc --build",
25
- "clean": "rm -rf dist *.tsbuildinfo",
26
- "typecheck": "tsc --noEmit",
27
- "test": "vitest run",
39
+ "clean": "rm -rf dist *.tsbuildinfo coverage",
40
+ "test": "vitest",
28
41
  "prepublishOnly": "npm run build"
29
42
  },
30
43
  "dependencies": {
31
- "@xmachines/play": "1.0.0-beta.2",
32
- "@xmachines/play-actor": "1.0.0-beta.2",
33
- "@xmachines/play-catalog": "1.0.0-beta.2",
34
- "@xmachines/play-signals": "1.0.0-beta.2",
35
- "zod": "^4.3.6"
44
+ "@xmachines/play": "1.0.0-beta.21",
45
+ "@xmachines/play-actor": "1.0.0-beta.21",
46
+ "@xmachines/play-signals": "1.0.0-beta.21"
36
47
  },
37
48
  "devDependencies": {
38
- "@statelyai/inspect": "^0.4.0"
49
+ "@xmachines/shared": "1.0.0-beta.21",
50
+ "typescript": "^5.9.3 || ^6.0.2",
51
+ "vitest": "^4.1.2",
52
+ "xstate": "^5.30.0"
39
53
  },
40
54
  "peerDependencies": {
41
- "xstate": "^5.28.0"
55
+ "xstate": "^5.30.0"
42
56
  },
43
- "publishConfig": {
44
- "access": "public"
45
- },
46
- "files": [
47
- "dist",
48
- "README.md",
49
- "LICENSE"
50
- ]
57
+ "_devDependencies_note": "xstate appears in both peerDependencies and devDependencies intentionally. devDependencies provides workspace resolution for local builds, tests, and typechecking. peerDependencies declares the consumer version constraint. Both are pinned to ^5.30.0 to prevent drift."
51
58
  }
@@ -1,12 +0,0 @@
1
- /**
2
- * Catalog binding and validation utilities
3
- *
4
- * Provides functions for validating component references and props
5
- * using Zod schemas from the catalog.
6
- *
7
- * @packageDocumentation
8
- */
9
- export { validateComponentBinding } from "./validate-binding.js";
10
- export { validateViewProps, mergeViewProps } from "./validate-props.js";
11
- export type { Catalog, CatalogEntry, ViewMetadata } from "./types.js";
12
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/catalog/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACxE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
@@ -1,11 +0,0 @@
1
- /**
2
- * Catalog binding and validation utilities
3
- *
4
- * Provides functions for validating component references and props
5
- * using Zod schemas from the catalog.
6
- *
7
- * @packageDocumentation
8
- */
9
- export { validateComponentBinding } from "./validate-binding.js";
10
- export { validateViewProps, mergeViewProps } from "./validate-props.js";
11
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/catalog/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
@@ -1,36 +0,0 @@
1
- import type { z } from "zod";
2
- import type { Catalog as BaseCatalog } from "@xmachines/play-catalog";
3
- /**
4
- * UI component catalog entry with schema and component reference
5
- *
6
- * Per CONTEXT.md: String keys reference components, Zod schemas validate props
7
- */
8
- export interface CatalogEntry {
9
- /** Zod schema for component props */
10
- schema: z.ZodType<any>;
11
- /** React component (or other framework component) */
12
- component: any;
13
- }
14
- /**
15
- * Component catalog mapping
16
- *
17
- * Re-export from @xmachines/play-catalog for consistent API.
18
- *
19
- * Supports two formats:
20
- * - Direct Zod schemas: `Record<string, z.ZodType>` via defineCatalog()
21
- * - CatalogEntry objects: `Record<string, CatalogEntry>` with { schema, component }
22
- *
23
- * PlayerActor accepts either format - if entry has 'schema' property, uses CatalogEntry pattern,
24
- * otherwise treats as direct Zod schema.
25
- */
26
- export type Catalog = BaseCatalog | Record<string, CatalogEntry>;
27
- /**
28
- * View metadata from state machine
29
- */
30
- export interface ViewMetadata {
31
- /** Component name from catalog */
32
- component: string;
33
- /** Additional view props/data */
34
- [key: string]: any;
35
- }
36
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/catalog/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtE;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC5B,qCAAqC;IACrC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACvB,qDAAqD;IACrD,SAAS,EAAE,GAAG,CAAC;CACf;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,OAAO,GAAG,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AAEjE;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B,kCAAkC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACnB"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/catalog/types.ts"],"names":[],"mappings":""}