@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.
- package/.oxfmtrc.json +3 -0
- package/.oxlintrc.json +3 -0
- package/README.md +454 -0
- package/dist/catalog/index.d.ts +12 -0
- package/dist/catalog/index.d.ts.map +1 -0
- package/dist/catalog/index.js +11 -0
- package/dist/catalog/index.js.map +1 -0
- package/dist/catalog/types.d.ts +36 -0
- package/dist/catalog/types.d.ts.map +1 -0
- package/dist/catalog/types.js +2 -0
- package/dist/catalog/types.js.map +1 -0
- package/dist/catalog/validate-binding.d.ts +21 -0
- package/dist/catalog/validate-binding.d.ts.map +1 -0
- package/dist/catalog/validate-binding.js +30 -0
- package/dist/catalog/validate-binding.js.map +1 -0
- package/dist/catalog/validate-props.d.ts +41 -0
- package/dist/catalog/validate-props.d.ts.map +1 -0
- package/dist/catalog/validate-props.js +95 -0
- package/dist/catalog/validate-props.js.map +1 -0
- package/dist/define-player.d.ts +110 -0
- package/dist/define-player.d.ts.map +1 -0
- package/dist/define-player.js +116 -0
- package/dist/define-player.js.map +1 -0
- package/dist/guards/compose.d.ts +136 -0
- package/dist/guards/compose.d.ts.map +1 -0
- package/dist/guards/compose.js +156 -0
- package/dist/guards/compose.js.map +1 -0
- package/dist/guards/helpers.d.ts +60 -0
- package/dist/guards/helpers.d.ts.map +1 -0
- package/dist/guards/helpers.js +91 -0
- package/dist/guards/helpers.js.map +1 -0
- package/dist/guards/index.d.ts +12 -0
- package/dist/guards/index.d.ts.map +1 -0
- package/dist/guards/index.js +11 -0
- package/dist/guards/index.js.map +1 -0
- package/dist/guards/types.d.ts +21 -0
- package/dist/guards/types.d.ts.map +1 -0
- package/dist/guards/types.js +2 -0
- package/dist/guards/types.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/player-actor.d.ts +143 -0
- package/dist/player-actor.d.ts.map +1 -0
- package/dist/player-actor.js +294 -0
- package/dist/player-actor.js.map +1 -0
- package/dist/routing/build-url.d.ts +27 -0
- package/dist/routing/build-url.d.ts.map +1 -0
- package/dist/routing/build-url.js +111 -0
- package/dist/routing/build-url.js.map +1 -0
- package/dist/routing/derive-route.d.ts +111 -0
- package/dist/routing/derive-route.d.ts.map +1 -0
- package/dist/routing/derive-route.js +144 -0
- package/dist/routing/derive-route.js.map +1 -0
- package/dist/routing/format-play-route-transitions.d.ts +31 -0
- package/dist/routing/format-play-route-transitions.d.ts.map +1 -0
- package/dist/routing/format-play-route-transitions.js +70 -0
- package/dist/routing/format-play-route-transitions.js.map +1 -0
- package/dist/routing/index.d.ts +13 -0
- package/dist/routing/index.d.ts.map +1 -0
- package/dist/routing/index.js +12 -0
- package/dist/routing/index.js.map +1 -0
- package/dist/routing/types.d.ts +25 -0
- package/dist/routing/types.d.ts.map +1 -0
- package/dist/routing/types.js +2 -0
- package/dist/routing/types.js.map +1 -0
- package/dist/signals/debounce.d.ts +18 -0
- package/dist/signals/debounce.d.ts.map +1 -0
- package/dist/signals/debounce.js +35 -0
- package/dist/signals/debounce.js.map +1 -0
- package/dist/signals/index.d.ts +3 -0
- package/dist/signals/index.d.ts.map +1 -0
- package/dist/signals/index.js +3 -0
- package/dist/signals/index.js.map +1 -0
- package/dist/signals/state-signal.d.ts +33 -0
- package/dist/signals/state-signal.d.ts.map +1 -0
- package/dist/signals/state-signal.js +41 -0
- package/dist/signals/state-signal.js.map +1 -0
- package/dist/types.d.ts +39 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/examples/simple-machine.ts +187 -0
- package/package.json +46 -0
- package/src/catalog/index.ts +12 -0
- package/src/catalog/types.ts +38 -0
- package/src/catalog/validate-binding.ts +35 -0
- package/src/catalog/validate-props.ts +109 -0
- package/src/define-player.ts +121 -0
- package/src/guards/compose.ts +169 -0
- package/src/guards/helpers.ts +104 -0
- package/src/guards/index.ts +12 -0
- package/src/guards/types.ts +23 -0
- package/src/index.ts +40 -0
- package/src/player-actor.ts +346 -0
- package/src/routing/build-url.ts +127 -0
- package/src/routing/derive-route.ts +152 -0
- package/src/routing/format-play-route-transitions.ts +77 -0
- package/src/routing/index.ts +13 -0
- package/src/routing/types.ts +26 -0
- package/src/signals/debounce.ts +38 -0
- package/src/signals/index.ts +2 -0
- package/src/signals/state-signal.ts +45 -0
- package/src/types.ts +47 -0
- package/test/derive-route.test.ts +166 -0
- package/test/devtools-integration.spec.ts +97 -0
- package/test/format-play-route-transitions-query.test.ts +187 -0
- package/test/guards-edge-cases.spec.ts +630 -0
- package/test/player-actor-basic.spec.ts +189 -0
- package/test/player-actor-edge-cases.spec.ts +769 -0
- package/test/routing-edge-cases.spec.ts +340 -0
- package/tsconfig.json +15 -0
- package/tsconfig.tsbuildinfo +1 -0
- 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 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/guards/types.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
ADDED
|
@@ -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"}
|