@doeixd/machine 0.0.4 → 0.0.6
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/README.md +952 -13
- package/dist/cjs/development/index.js +691 -0
- package/dist/cjs/development/index.js.map +4 -4
- package/dist/cjs/production/index.js +5 -1
- package/dist/esm/development/index.js +698 -0
- package/dist/esm/development/index.js.map +4 -4
- package/dist/esm/production/index.js +5 -1
- package/dist/types/extract.d.ts +71 -0
- package/dist/types/extract.d.ts.map +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/multi.d.ts +838 -0
- package/dist/types/multi.d.ts.map +1 -0
- package/dist/types/primitives.d.ts +202 -0
- package/dist/types/primitives.d.ts.map +1 -0
- package/dist/types/runtime-extract.d.ts +53 -0
- package/dist/types/runtime-extract.d.ts.map +1 -0
- package/package.json +6 -2
- package/src/extract.ts +452 -67
- package/src/index.ts +49 -0
- package/src/multi.ts +1145 -0
- package/src/primitives.ts +135 -0
- package/src/react.ts +349 -28
- package/src/runtime-extract.ts +141 -0
- package/src/solid.ts +8 -8
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Runtime statechart extraction utilities
|
|
3
|
+
* @description Extract statecharts from running machine instances using Symbol-based metadata
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { RUNTIME_META, type RuntimeTransitionMeta } from './primitives';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Extract metadata from a single function if it has runtime metadata attached
|
|
10
|
+
*
|
|
11
|
+
* @param fn - Function to extract from
|
|
12
|
+
* @returns Metadata object or null if no metadata
|
|
13
|
+
*/
|
|
14
|
+
export function extractFunctionMetadata(fn: any): RuntimeTransitionMeta | null {
|
|
15
|
+
if (typeof fn !== 'function') {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const meta = fn[RUNTIME_META];
|
|
20
|
+
return meta || null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Extract state node from a machine class instance
|
|
25
|
+
*
|
|
26
|
+
* @param stateInstance - Instance of a machine state class
|
|
27
|
+
* @returns State node with transitions
|
|
28
|
+
*/
|
|
29
|
+
export function extractStateNode(stateInstance: any): any {
|
|
30
|
+
const stateNode: any = { on: {} };
|
|
31
|
+
const invoke: any[] = [];
|
|
32
|
+
|
|
33
|
+
// Iterate over all properties
|
|
34
|
+
for (const key in stateInstance) {
|
|
35
|
+
const value = stateInstance[key];
|
|
36
|
+
|
|
37
|
+
if (typeof value !== 'function') {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const meta = extractFunctionMetadata(value);
|
|
42
|
+
if (!meta) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Separate invoke from transitions
|
|
47
|
+
if (meta.invoke) {
|
|
48
|
+
invoke.push({
|
|
49
|
+
src: meta.invoke.src,
|
|
50
|
+
onDone: { target: meta.invoke.onDone },
|
|
51
|
+
onError: { target: meta.invoke.onError },
|
|
52
|
+
description: meta.invoke.description
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// If has target, it's a transition
|
|
57
|
+
if (meta.target) {
|
|
58
|
+
const transition: any = { target: meta.target };
|
|
59
|
+
|
|
60
|
+
if (meta.description) {
|
|
61
|
+
transition.description = meta.description;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (meta.guards && meta.guards.length > 0) {
|
|
65
|
+
transition.cond = meta.guards.map(g => g.name).join(' && ');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (meta.actions && meta.actions.length > 0) {
|
|
69
|
+
transition.actions = meta.actions.map(a => a.name);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
stateNode.on[key] = transition;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (invoke.length > 0) {
|
|
77
|
+
stateNode.invoke = invoke;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return stateNode;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Generate a complete statechart from multiple state class instances
|
|
85
|
+
*
|
|
86
|
+
* @param states - Object mapping state names to state instances
|
|
87
|
+
* @param config - Chart configuration
|
|
88
|
+
* @returns XState-compatible statechart JSON
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* const chart = generateStatechart({
|
|
92
|
+
* 'LoggedOut': new LoggedOutMachine(),
|
|
93
|
+
* 'LoggedIn': new LoggedInMachine()
|
|
94
|
+
* }, {
|
|
95
|
+
* id: 'auth',
|
|
96
|
+
* initial: 'LoggedOut'
|
|
97
|
+
* });
|
|
98
|
+
*/
|
|
99
|
+
export function generateStatechart(
|
|
100
|
+
states: Record<string, any>,
|
|
101
|
+
config: { id: string; initial: string; description?: string }
|
|
102
|
+
): any {
|
|
103
|
+
const chart: any = {
|
|
104
|
+
id: config.id,
|
|
105
|
+
initial: config.initial,
|
|
106
|
+
states: {}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
if (config.description) {
|
|
110
|
+
chart.description = config.description;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
for (const [stateName, stateInstance] of Object.entries(states)) {
|
|
114
|
+
chart.states[stateName] = extractStateNode(stateInstance);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return chart;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Convenience function to extract statechart from a single machine instance
|
|
122
|
+
* Useful for simple machines with a single context but multiple transitions
|
|
123
|
+
*
|
|
124
|
+
* @param machineInstance - Machine instance
|
|
125
|
+
* @param config - Chart configuration
|
|
126
|
+
* @returns XState-compatible statechart JSON
|
|
127
|
+
*/
|
|
128
|
+
export function extractFromInstance(
|
|
129
|
+
machineInstance: any,
|
|
130
|
+
config: { id: string; stateName?: string }
|
|
131
|
+
): any {
|
|
132
|
+
const stateName = config.stateName || machineInstance.constructor.name || 'State';
|
|
133
|
+
|
|
134
|
+
return {
|
|
135
|
+
id: config.id,
|
|
136
|
+
initial: stateName,
|
|
137
|
+
states: {
|
|
138
|
+
[stateName]: extractStateNode(machineInstance)
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}
|
package/src/solid.ts
CHANGED
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
type Accessor,
|
|
23
23
|
type Setter
|
|
24
24
|
} from 'solid-js';
|
|
25
|
-
import { createStore, type SetStoreFunction, type Store
|
|
25
|
+
import { createStore, type SetStoreFunction, type Store } from 'solid-js/store';
|
|
26
26
|
import { Machine, AsyncMachine, Event, Context, runMachine as runMachineCore } from './index';
|
|
27
27
|
|
|
28
28
|
// =============================================================================
|
|
@@ -86,12 +86,12 @@ export function createMachine<M extends Machine<any>>(
|
|
|
86
86
|
const { context, ...transitions } = machine();
|
|
87
87
|
|
|
88
88
|
const handlers = Object.fromEntries(
|
|
89
|
-
Object.entries(transitions).map(([key
|
|
89
|
+
Object.entries(transitions).map(([key]) => [
|
|
90
90
|
key,
|
|
91
91
|
(...args: any[]) => {
|
|
92
92
|
const currentMachine = machine();
|
|
93
93
|
const nextMachine = (currentMachine as any)[key](...args);
|
|
94
|
-
setMachine(
|
|
94
|
+
setMachine(nextMachine);
|
|
95
95
|
return nextMachine;
|
|
96
96
|
}
|
|
97
97
|
])
|
|
@@ -153,11 +153,11 @@ export function createMachineStore<M extends Machine<any>>(
|
|
|
153
153
|
const { context, ...transitions } = initial;
|
|
154
154
|
|
|
155
155
|
const handlers = Object.fromEntries(
|
|
156
|
-
Object.entries(transitions).map(([key
|
|
156
|
+
Object.entries(transitions).map(([key]) => [
|
|
157
157
|
key,
|
|
158
158
|
(...args: any[]) => {
|
|
159
159
|
const nextMachine = (store as any)[key](...args);
|
|
160
|
-
setStore(
|
|
160
|
+
setStore(nextMachine);
|
|
161
161
|
return nextMachine;
|
|
162
162
|
}
|
|
163
163
|
])
|
|
@@ -289,12 +289,12 @@ export function createMachineContext<C extends object, M extends Machine<C>>(
|
|
|
289
289
|
const { context: _, ...transitions } = currentMachine;
|
|
290
290
|
|
|
291
291
|
const handlers = Object.fromEntries(
|
|
292
|
-
Object.entries(transitions).map(([key
|
|
292
|
+
Object.entries(transitions).map(([key]) => [
|
|
293
293
|
key,
|
|
294
294
|
(...args: any[]) => {
|
|
295
295
|
const nextMachine = (currentMachine as any)[key](...args);
|
|
296
296
|
currentMachine = nextMachine;
|
|
297
|
-
setContext(
|
|
297
|
+
setContext(nextMachine.context);
|
|
298
298
|
return nextMachine;
|
|
299
299
|
}
|
|
300
300
|
])
|
|
@@ -383,7 +383,7 @@ export function batchTransitions<M extends Machine<any>>(
|
|
|
383
383
|
|
|
384
384
|
return batch(() => {
|
|
385
385
|
const finalMachine = transitions.reduce((m, transition) => transition(m), machine);
|
|
386
|
-
setMachine(finalMachine);
|
|
386
|
+
setMachine(() => finalMachine);
|
|
387
387
|
return finalMachine;
|
|
388
388
|
});
|
|
389
389
|
}
|