@xmachines/play-xstate 1.0.0-beta.1

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 (115) hide show
  1. package/.oxfmtrc.json +3 -0
  2. package/.oxlintrc.json +3 -0
  3. package/README.md +454 -0
  4. package/dist/catalog/index.d.ts +12 -0
  5. package/dist/catalog/index.d.ts.map +1 -0
  6. package/dist/catalog/index.js +11 -0
  7. package/dist/catalog/index.js.map +1 -0
  8. package/dist/catalog/types.d.ts +36 -0
  9. package/dist/catalog/types.d.ts.map +1 -0
  10. package/dist/catalog/types.js +2 -0
  11. package/dist/catalog/types.js.map +1 -0
  12. package/dist/catalog/validate-binding.d.ts +21 -0
  13. package/dist/catalog/validate-binding.d.ts.map +1 -0
  14. package/dist/catalog/validate-binding.js +30 -0
  15. package/dist/catalog/validate-binding.js.map +1 -0
  16. package/dist/catalog/validate-props.d.ts +41 -0
  17. package/dist/catalog/validate-props.d.ts.map +1 -0
  18. package/dist/catalog/validate-props.js +95 -0
  19. package/dist/catalog/validate-props.js.map +1 -0
  20. package/dist/define-player.d.ts +110 -0
  21. package/dist/define-player.d.ts.map +1 -0
  22. package/dist/define-player.js +116 -0
  23. package/dist/define-player.js.map +1 -0
  24. package/dist/guards/compose.d.ts +136 -0
  25. package/dist/guards/compose.d.ts.map +1 -0
  26. package/dist/guards/compose.js +156 -0
  27. package/dist/guards/compose.js.map +1 -0
  28. package/dist/guards/helpers.d.ts +60 -0
  29. package/dist/guards/helpers.d.ts.map +1 -0
  30. package/dist/guards/helpers.js +91 -0
  31. package/dist/guards/helpers.js.map +1 -0
  32. package/dist/guards/index.d.ts +12 -0
  33. package/dist/guards/index.d.ts.map +1 -0
  34. package/dist/guards/index.js +11 -0
  35. package/dist/guards/index.js.map +1 -0
  36. package/dist/guards/types.d.ts +21 -0
  37. package/dist/guards/types.d.ts.map +1 -0
  38. package/dist/guards/types.js +2 -0
  39. package/dist/guards/types.js.map +1 -0
  40. package/dist/index.d.ts +22 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +21 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/player-actor.d.ts +143 -0
  45. package/dist/player-actor.d.ts.map +1 -0
  46. package/dist/player-actor.js +294 -0
  47. package/dist/player-actor.js.map +1 -0
  48. package/dist/routing/build-url.d.ts +27 -0
  49. package/dist/routing/build-url.d.ts.map +1 -0
  50. package/dist/routing/build-url.js +111 -0
  51. package/dist/routing/build-url.js.map +1 -0
  52. package/dist/routing/derive-route.d.ts +111 -0
  53. package/dist/routing/derive-route.d.ts.map +1 -0
  54. package/dist/routing/derive-route.js +144 -0
  55. package/dist/routing/derive-route.js.map +1 -0
  56. package/dist/routing/format-play-route-transitions.d.ts +31 -0
  57. package/dist/routing/format-play-route-transitions.d.ts.map +1 -0
  58. package/dist/routing/format-play-route-transitions.js +70 -0
  59. package/dist/routing/format-play-route-transitions.js.map +1 -0
  60. package/dist/routing/index.d.ts +13 -0
  61. package/dist/routing/index.d.ts.map +1 -0
  62. package/dist/routing/index.js +12 -0
  63. package/dist/routing/index.js.map +1 -0
  64. package/dist/routing/types.d.ts +25 -0
  65. package/dist/routing/types.d.ts.map +1 -0
  66. package/dist/routing/types.js +2 -0
  67. package/dist/routing/types.js.map +1 -0
  68. package/dist/signals/debounce.d.ts +18 -0
  69. package/dist/signals/debounce.d.ts.map +1 -0
  70. package/dist/signals/debounce.js +35 -0
  71. package/dist/signals/debounce.js.map +1 -0
  72. package/dist/signals/index.d.ts +3 -0
  73. package/dist/signals/index.d.ts.map +1 -0
  74. package/dist/signals/index.js +3 -0
  75. package/dist/signals/index.js.map +1 -0
  76. package/dist/signals/state-signal.d.ts +33 -0
  77. package/dist/signals/state-signal.d.ts.map +1 -0
  78. package/dist/signals/state-signal.js +41 -0
  79. package/dist/signals/state-signal.js.map +1 -0
  80. package/dist/types.d.ts +39 -0
  81. package/dist/types.d.ts.map +1 -0
  82. package/dist/types.js +2 -0
  83. package/dist/types.js.map +1 -0
  84. package/examples/simple-machine.ts +187 -0
  85. package/package.json +46 -0
  86. package/src/catalog/index.ts +12 -0
  87. package/src/catalog/types.ts +38 -0
  88. package/src/catalog/validate-binding.ts +35 -0
  89. package/src/catalog/validate-props.ts +109 -0
  90. package/src/define-player.ts +121 -0
  91. package/src/guards/compose.ts +169 -0
  92. package/src/guards/helpers.ts +104 -0
  93. package/src/guards/index.ts +12 -0
  94. package/src/guards/types.ts +23 -0
  95. package/src/index.ts +40 -0
  96. package/src/player-actor.ts +346 -0
  97. package/src/routing/build-url.ts +127 -0
  98. package/src/routing/derive-route.ts +152 -0
  99. package/src/routing/format-play-route-transitions.ts +77 -0
  100. package/src/routing/index.ts +13 -0
  101. package/src/routing/types.ts +26 -0
  102. package/src/signals/debounce.ts +38 -0
  103. package/src/signals/index.ts +2 -0
  104. package/src/signals/state-signal.ts +45 -0
  105. package/src/types.ts +47 -0
  106. package/test/derive-route.test.ts +166 -0
  107. package/test/devtools-integration.spec.ts +97 -0
  108. package/test/format-play-route-transitions-query.test.ts +187 -0
  109. package/test/guards-edge-cases.spec.ts +630 -0
  110. package/test/player-actor-basic.spec.ts +189 -0
  111. package/test/player-actor-edge-cases.spec.ts +769 -0
  112. package/test/routing-edge-cases.spec.ts +340 -0
  113. package/tsconfig.json +15 -0
  114. package/tsconfig.tsbuildinfo +1 -0
  115. package/vitest.config.ts +27 -0
@@ -0,0 +1,60 @@
1
+ import type { Guard } from "./types.js";
2
+ /**
3
+ * Check if context has a truthy value at path
4
+ *
5
+ * Per CONTEXT.md: Convenience helper for common guard pattern
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * const machine = setup({
10
+ * guards: {
11
+ * hasUserId: hasContext('userId'),
12
+ * hasEmail: hasContext('user.email')
13
+ * }
14
+ * });
15
+ * ```
16
+ *
17
+ * @param path - Dot-separated path to context property
18
+ * @returns Guard predicate checking if property is truthy
19
+ */
20
+ export declare const hasContext: <TContext = any>(path: string) => Guard<TContext, any>;
21
+ /**
22
+ * Check if event type matches expected type
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * const machine = setup({
27
+ * guards: {
28
+ * isSubmitEvent: eventMatches('submit'),
29
+ * isBackOrForward: composeGuardsOr([
30
+ * eventMatches('back'),
31
+ * eventMatches('forward')
32
+ * ])
33
+ * }
34
+ * });
35
+ * ```
36
+ *
37
+ * @param eventType - Expected event type
38
+ * @returns Guard predicate checking event type
39
+ */
40
+ export declare const eventMatches: <TEvent extends {
41
+ type: string;
42
+ } = any>(eventType: string) => Guard<any, TEvent>;
43
+ /**
44
+ * Check if current state matches expected value
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * const machine = setup({
49
+ * guards: {
50
+ * isLoggedIn: stateMatches('authenticated'),
51
+ * isDashboard: stateMatches('authenticated.dashboard')
52
+ * }
53
+ * });
54
+ * ```
55
+ *
56
+ * @param stateValue - Expected state value (string or object)
57
+ * @returns Guard predicate checking state value
58
+ */
59
+ export declare const stateMatches: <TContext = any>(stateValue: string) => Guard<TContext, any>;
60
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/guards/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,UAAU,GACrB,QAAQ,GAAG,GAAG,EAAE,MAAM,MAAM,KAAG,KAAK,CAAC,QAAQ,EAAE,GAAG,CAIlD,CAAC;AAEH;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,YAAY,GACvB,MAAM,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,GAAG,EAAE,WAAW,MAAM,KAAG,KAAK,CAAC,GAAG,EAAE,MAAM,CAG5E,CAAC;AAEH;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,YAAY,GACvB,QAAQ,GAAG,GAAG,EAAE,YAAY,MAAM,KAAG,KAAK,CAAC,QAAQ,EAAE,GAAG,CAexD,CAAC"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Check if context has a truthy value at path
3
+ *
4
+ * Per CONTEXT.md: Convenience helper for common guard pattern
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * const machine = setup({
9
+ * guards: {
10
+ * hasUserId: hasContext('userId'),
11
+ * hasEmail: hasContext('user.email')
12
+ * }
13
+ * });
14
+ * ```
15
+ *
16
+ * @param path - Dot-separated path to context property
17
+ * @returns Guard predicate checking if property is truthy
18
+ */
19
+ export const hasContext = (path) => ({ context }) => {
20
+ const value = getNestedValue(context, path);
21
+ return value !== undefined && value !== null && value !== "";
22
+ };
23
+ /**
24
+ * Check if event type matches expected type
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * const machine = setup({
29
+ * guards: {
30
+ * isSubmitEvent: eventMatches('submit'),
31
+ * isBackOrForward: composeGuardsOr([
32
+ * eventMatches('back'),
33
+ * eventMatches('forward')
34
+ * ])
35
+ * }
36
+ * });
37
+ * ```
38
+ *
39
+ * @param eventType - Expected event type
40
+ * @returns Guard predicate checking event type
41
+ */
42
+ export const eventMatches = (eventType) => ({ event }) => {
43
+ return event.type === eventType;
44
+ };
45
+ /**
46
+ * Check if current state matches expected value
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * const machine = setup({
51
+ * guards: {
52
+ * isLoggedIn: stateMatches('authenticated'),
53
+ * isDashboard: stateMatches('authenticated.dashboard')
54
+ * }
55
+ * });
56
+ * ```
57
+ *
58
+ * @param stateValue - Expected state value (string or object)
59
+ * @returns Guard predicate checking state value
60
+ */
61
+ export const stateMatches = (stateValue) => ({ context }) => {
62
+ // Note: This helper checks context for state info
63
+ // For actual XState state matching, use machine.matches() in actions
64
+ // This is a simplified version for context-based state checks
65
+ const currentState = context._state || context.state;
66
+ if (!currentState)
67
+ return false;
68
+ // Simple string matching (can be enhanced for nested states)
69
+ if (typeof currentState === "string") {
70
+ return currentState === stateValue;
71
+ }
72
+ // Object state matching
73
+ return JSON.stringify(currentState).includes(stateValue);
74
+ };
75
+ /**
76
+ * Get nested value from object using dot-separated path
77
+ *
78
+ * @internal
79
+ */
80
+ const getNestedValue = (obj, path) => {
81
+ const keys = path.split(".");
82
+ let value = obj;
83
+ for (const key of keys) {
84
+ if (value === null || value === undefined) {
85
+ return undefined;
86
+ }
87
+ value = value[key];
88
+ }
89
+ return value;
90
+ };
91
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/guards/helpers.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,UAAU,GACtB,CAAiB,IAAY,EAAwB,EAAE,CACvD,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;IACf,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC5C,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;AAC9D,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,YAAY,GACxB,CAAwC,SAAiB,EAAsB,EAAE,CACjF,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;IACb,OAAO,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC;AACjC,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,YAAY,GACxB,CAAiB,UAAkB,EAAwB,EAAE,CAC7D,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;IACf,kDAAkD;IAClD,qEAAqE;IACrE,8DAA8D;IAC9D,MAAM,YAAY,GAAI,OAAe,CAAC,MAAM,IAAK,OAAe,CAAC,KAAK,CAAC;IACvE,IAAI,CAAC,YAAY;QAAE,OAAO,KAAK,CAAC;IAEhC,6DAA6D;IAC7D,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;QACtC,OAAO,YAAY,KAAK,UAAU,CAAC;IACpC,CAAC;IAED,wBAAwB;IACxB,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;AAC1D,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,cAAc,GAAG,CAAC,GAAQ,EAAE,IAAY,EAAO,EAAE;IACtD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,KAAK,GAAG,GAAG,CAAC;IAEhB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACxB,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC3C,OAAO,SAAS,CAAC;QAClB,CAAC;QACD,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC;IAED,OAAO,KAAK,CAAC;AACd,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Guard composition and helper utilities for XState machines
3
+ *
4
+ * Provides array-means-AND composition and convenience helpers
5
+ * for common guard patterns in Play Architecture.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ export { composeGuards, composeGuardsOr, negateGuard } from "./compose.js";
10
+ export { hasContext, eventMatches, stateMatches } from "./helpers.js";
11
+ export type { Guard, GuardArray } from "./types.js";
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/guards/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACtE,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Guard composition and helper utilities for XState machines
3
+ *
4
+ * Provides array-means-AND composition and convenience helpers
5
+ * for common guard patterns in Play Architecture.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ export { composeGuards, composeGuardsOr, negateGuard } from "./compose.js";
10
+ export { hasContext, eventMatches, stateMatches } from "./helpers.js";
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/guards/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Standard XState guard function signature
3
+ *
4
+ * Per CONTEXT.md: Guards receive { context, event } per XState standard
5
+ *
6
+ * @param args - Guard arguments with context and event
7
+ * @param args.context - Current machine context
8
+ * @param args.event - Event that triggered the guard evaluation
9
+ * @returns boolean indicating if guard passes
10
+ */
11
+ export type Guard<TContext = any, TEvent = any> = (args: {
12
+ context: TContext;
13
+ event: TEvent;
14
+ }) => boolean;
15
+ /**
16
+ * Array of guard predicates or guard names
17
+ *
18
+ * Per CONTEXT.md: Array means AND - all guards must pass
19
+ */
20
+ export type GuardArray<TContext = any, TEvent = any> = Array<Guard<TContext, TEvent>> | Array<string>;
21
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/guards/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,MAAM,KAAK,CAAC,QAAQ,GAAG,GAAG,EAAE,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE;IACxD,OAAO,EAAE,QAAQ,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACd,KAAK,OAAO,CAAC;AAEd;;;;GAIG;AACH,MAAM,MAAM,UAAU,CAAC,QAAQ,GAAG,GAAG,EAAE,MAAM,GAAG,GAAG,IAChD,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,GAC9B,KAAK,CAAC,MAAM,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/guards/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @xmachines/play-xstate - XState v5 adapter for Play Architecture
3
+ *
4
+ * Provides definePlayer() API for binding XState state machines to the
5
+ * actor base with catalog binding, signal lifecycle, and DevTools integration.
6
+ *
7
+ * Per RFC Play v1, this package implements the Logic Layer adapter that
8
+ * transforms declarative machine definitions into live actors with signal-driven
9
+ * reactivity.
10
+ *
11
+ * @packageDocumentation
12
+ */
13
+ export { definePlayer } from "./define-player.js";
14
+ export { PlayerActor } from "./player-actor.js";
15
+ export type { PlayerConfig, PlayerOptions, PlayerFactory } from "./types.js";
16
+ export { composeGuards, composeGuardsOr, negateGuard, hasContext, eventMatches, stateMatches, } from "./guards/index.js";
17
+ export type { Guard, GuardArray } from "./guards/types.js";
18
+ export { deriveRoute, isAbsoluteRoute, buildRouteUrl, formatPlayRouteTransitions, } from "./routing/index.js";
19
+ export type { RouteMetadata, RouteObject, RouteContext } from "./routing/types.js";
20
+ export { validateComponentBinding, validateViewProps, mergeViewProps } from "./catalog/index.js";
21
+ export type { Catalog, CatalogEntry, ViewMetadata } from "./catalog/types.js";
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAG7E,OAAO,EACN,aAAa,EACb,eAAe,EACf,WAAW,EACX,UAAU,EACV,YAAY,EACZ,YAAY,GACZ,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAG3D,OAAO,EACN,WAAW,EACX,eAAe,EACf,aAAa,EACb,0BAA0B,GAC1B,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGnF,OAAO,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACjG,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @xmachines/play-xstate - XState v5 adapter for Play Architecture
3
+ *
4
+ * Provides definePlayer() API for binding XState state machines to the
5
+ * actor base with catalog binding, signal lifecycle, and DevTools integration.
6
+ *
7
+ * Per RFC Play v1, this package implements the Logic Layer adapter that
8
+ * transforms declarative machine definitions into live actors with signal-driven
9
+ * reactivity.
10
+ *
11
+ * @packageDocumentation
12
+ */
13
+ export { definePlayer } from "./define-player.js";
14
+ export { PlayerActor } from "./player-actor.js";
15
+ // Guard utilities
16
+ export { composeGuards, composeGuardsOr, negateGuard, hasContext, eventMatches, stateMatches, } from "./guards/index.js";
17
+ // Routing utilities
18
+ export { deriveRoute, isAbsoluteRoute, buildRouteUrl, formatPlayRouteTransitions, } from "./routing/index.js";
19
+ // Catalog utilities
20
+ export { validateComponentBinding, validateViewProps, mergeViewProps } from "./catalog/index.js";
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,kBAAkB;AAClB,OAAO,EACN,aAAa,EACb,eAAe,EACf,WAAW,EACX,UAAU,EACV,YAAY,EACZ,YAAY,GACZ,MAAM,mBAAmB,CAAC;AAG3B,oBAAoB;AACpB,OAAO,EACN,WAAW,EACX,eAAe,EACf,aAAa,EACb,0BAA0B,GAC1B,MAAM,oBAAoB,CAAC;AAG5B,oBAAoB;AACpB,OAAO,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,143 @@
1
+ import { type AnyStateMachine, type AnyActorLogic } from "xstate";
2
+ import { AbstractActor, type Routable, type Viewable } from "@xmachines/play-actor";
3
+ import { Signal } from "@xmachines/play-signals";
4
+ import type { PlayEvent } from "@xmachines/play";
5
+ import type { PlayerOptions } from "./types.js";
6
+ /**
7
+ * Concrete XState actor implementing Play Architecture signal protocol
8
+ *
9
+ * Extends {@link @xmachines/play-actor!AbstractActor} to provide XState v5 integration
10
+ * while maintaining ecosystem compatibility (XState inspection, devtools). This actor
11
+ * wraps an internal XState actor and exposes TC39 Signal-based reactive state for
12
+ * Infrastructure observation.
13
+ *
14
+ * **Capabilities:** Implements both {@link @xmachines/play-actor!Routable} and
15
+ * {@link @xmachines/play-actor!Viewable} interfaces, providing routing and view
16
+ * rendering support.
17
+ *
18
+ * **Architectural Context:** Implements **Actor Authority (INV-01)** by ensuring the
19
+ * XState machine's guards control all navigation decisions. Infrastructure observes
20
+ * the actor's signals (`state`, `currentRoute`, `currentView`) but cannot directly
21
+ * manipulate state—all mutations flow through the state machine's event handlers.
22
+ *
23
+ * @typeParam TMachine - XState v5 state machine type
24
+ *
25
+ * @example
26
+ * Basic actor creation and lifecycle
27
+ * ```typescript
28
+ * import { setup } from "xstate";
29
+ * import { definePlayer } from "@xmachines/play-xstate";
30
+ *
31
+ * const machine = setup({}).createMachine({
32
+ * initial: 'idle',
33
+ * states: {
34
+ * idle: {
35
+ * meta: { route: '/', view: { component: 'HomePage' } }
36
+ * }
37
+ * }
38
+ * });
39
+ *
40
+ * const createPlayer = definePlayer({ machine });
41
+ * const actor = createPlayer();
42
+ * actor.start();
43
+ *
44
+ * // Observe signals
45
+ * console.log(actor.currentRoute.get()); // '/'
46
+ * console.log(actor.currentView.get()); // { component: 'HomePage' }
47
+ * ```
48
+ *
49
+ * @example
50
+ * Signal lifecycle with watchers (microtask batching)
51
+ * ```typescript
52
+ * import { Signal } from "@xmachines/play-signals";
53
+ *
54
+ * const watcher = new Signal.subtle.Watcher(() => {
55
+ * queueMicrotask(() => {
56
+ * const pending = watcher.getPending();
57
+ * console.log('State changed:', actor.state.get());
58
+ * });
59
+ * });
60
+ *
61
+ * watcher.watch(actor.state);
62
+ * actor.send({ type: 'play.route', to: '#about' });
63
+ * // Watcher notification scheduled via microtask
64
+ * ```
65
+ *
66
+ * @see {@link https://gitlab.com/xmachin-es/rfc/-/blob/main/src/play-v1.md | RFC Play v1}
67
+ * @see {@link definePlayer} for factory creation
68
+ * @see {@link @xmachines/play-actor!AbstractActor} for signal protocol
69
+ * @see {@link @xmachines/play-actor!Routable} for routing capability
70
+ * @see {@link @xmachines/play-actor!Viewable} for view rendering capability
71
+ *
72
+ * @remarks
73
+ * **Routing:** This actor supports both XState's `route: {}` config pattern
74
+ * and `play.route` events with parameters. The `deriveRoute()` function checks
75
+ * `meta.route` (Stately pattern) for URL templates with parameter substitution support.
76
+ *
77
+ * **View Signal Pattern:** The `currentView` signal is a direct `Signal.State` (not
78
+ * `Signal.Computed`) to ensure proper watcher propagation in PlayRenderer. Views are
79
+ * cached and updated at state entry, not computed on every read.
80
+ */
81
+ export declare class PlayerActor<TMachine extends AnyStateMachine> extends AbstractActor<AnyActorLogic> implements Routable, Viewable, Record<string, any> {
82
+ private _xstateActor;
83
+ private _stateManager;
84
+ private _options;
85
+ private _catalog;
86
+ private _viewSignal;
87
+ state: Signal.State<any>;
88
+ currentRoute: Signal.Computed<string | null>;
89
+ currentView: Signal.State<{
90
+ component: string;
91
+ props: any;
92
+ } | null>;
93
+ catalog: any;
94
+ constructor(machine: TMachine, catalog: any, options: PlayerOptions, input?: any);
95
+ /**
96
+ * Start the actor
97
+ *
98
+ * Per RESEARCH.md Pitfall 1: Always call start() after creation
99
+ */
100
+ start(): this;
101
+ /**
102
+ * Stop the actor and cleanup
103
+ */
104
+ stop(): this;
105
+ /**
106
+ * Send event to actor
107
+ *
108
+ * Forwards events to the underlying XState actor. The actor's state machine
109
+ * guards determine whether each event is valid from the current state.
110
+ *
111
+ * @param event - Any event object with a type property
112
+ *
113
+ * @example
114
+ * ```typescript
115
+ * // Domain event
116
+ * actor.send({ type: 'auth.login', userId: '123' });
117
+ *
118
+ * // Routing event
119
+ * actor.send({ type: 'play.route', to: '#home' });
120
+ * ```
121
+ */
122
+ send(event: PlayEvent): void;
123
+ /**
124
+ * Get current snapshot
125
+ */
126
+ getSnapshot(): any;
127
+ /**
128
+ * Validate view at state entry and cache result
129
+ *
130
+ * Per CONTEXT.md: "Prop validation: At state entry (when state becomes active)"
131
+ * Validates once per transition and stores result in signal.
132
+ *
133
+ * @param snapshot - Current XState snapshot
134
+ */
135
+ private _validateAndCacheView;
136
+ /**
137
+ * Convenience dispose method for cleanup
138
+ *
139
+ * Per CONTEXT.md: "Both .dispose() convenience method and manual machine.stop()"
140
+ */
141
+ dispose(): void;
142
+ }
143
+ //# sourceMappingURL=player-actor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"player-actor.d.ts","sourceRoot":"","sources":["../src/player-actor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,eAAe,EAAc,KAAK,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC3F,OAAO,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACpF,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAKhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0EG;AACH,qBAAa,WAAW,CAAC,QAAQ,SAAS,eAAe,CACxD,SAAQ,aAAa,CAAC,aAAa,CACnC,YAAW,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAElD,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,aAAa,CAA0B;IAC/C,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,WAAW,CAAyD;IAGrE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC7C,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,GAAG,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IACpE,OAAO,EAAE,GAAG,CAAC;gBAER,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,CAAC,EAAE,GAAG;IA+EhF;;;;OAIG;IACM,KAAK,IAAI,IAAI;IAWtB;;OAEG;IACM,IAAI,IAAI,IAAI;IAYrB;;;;;;;;;;;;;;;;OAgBG;IACM,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAsBrC;;OAEG;IACM,WAAW,IAAI,GAAG;IAI3B;;;;;;;OAOG;IACH,OAAO,CAAC,qBAAqB;IAwE7B;;;;OAIG;IACH,OAAO,IAAI,IAAI;CAGf"}