@quazardous/quarkernel 1.0.12 → 2.2.3
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 +168 -47
- package/dist/create-machine-CYsscHPX.d.cts +275 -0
- package/dist/create-machine-CYsscHPX.d.ts +275 -0
- package/dist/fsm.cjs +1436 -0
- package/dist/fsm.cjs.map +1 -0
- package/dist/fsm.d.cts +2 -0
- package/dist/fsm.d.ts +2 -0
- package/dist/fsm.js +1432 -0
- package/dist/fsm.js.map +1 -0
- package/dist/index-BDf1xZi6.d.cts +896 -0
- package/dist/index-BPMXiW32.d.ts +896 -0
- package/dist/index.cjs +1750 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +80 -0
- package/dist/index.d.ts +80 -0
- package/dist/index.js +1722 -0
- package/dist/index.js.map +1 -0
- package/dist/xstate.cjs +190 -0
- package/dist/xstate.cjs.map +1 -0
- package/dist/xstate.d.cts +152 -0
- package/dist/xstate.d.ts +152 -0
- package/dist/xstate.js +186 -0
- package/dist/xstate.js.map +1 -0
- package/package.json +63 -24
- package/LICENSE +0 -21
- package/src/index.js +0 -3
- package/src/lib/QuarKernel.js +0 -405
- package/types/QuarKernel.d.ts +0 -132
package/README.md
CHANGED
|
@@ -1,74 +1,195 @@
|
|
|
1
1
|
# QuarKernel
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@quazardous/quarkernel)
|
|
4
|
+
[](https://bundlephobia.com/package/@quazardous/quarkernel)
|
|
5
|
+
[](https://github.com/quazardous/quarkernel/blob/main/LICENSE)
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
**Event orchestration with dependency ordering, shared context, and state machines.**
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
TypeScript-first. Zero dependencies. < 2KB gzipped.
|
|
8
10
|
|
|
9
|
-
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
[](https://quazardous.github.io/quarkernel/qk-studio/)
|
|
12
|
+
[](https://quazardous.github.io/quarkernel/fsm-studio/)
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Why QuarKernel?
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
// Other event libs: fire and pray
|
|
20
|
+
emitter.emit('user:login', data);
|
|
21
|
+
|
|
22
|
+
// QuarKernel: orchestrate with confidence
|
|
23
|
+
qk.on('user:login', fetchUser, { id: 'fetch' });
|
|
24
|
+
qk.on('user:login', logAnalytics, { after: ['fetch'] }); // Guaranteed order
|
|
25
|
+
qk.on('user:login', (e) => greet(e.context.user)); // Shared context
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**What makes it different:**
|
|
29
|
+
|
|
30
|
+
| Feature | mitt | emittery | **QuarKernel** |
|
|
31
|
+
|---------|:----:|:--------:|:--------------:|
|
|
32
|
+
| Dependency ordering | - | - | **Yes** |
|
|
33
|
+
| Shared context | - | - | **Yes** |
|
|
34
|
+
| Composite events | - | - | **Yes** |
|
|
35
|
+
| Wildcards | - | - | **Yes** |
|
|
36
|
+
| Async/await | - | Yes | **Yes** |
|
|
37
|
+
| TypeScript | Yes | Yes | **Yes** |
|
|
38
|
+
| < 2KB | Yes | Yes | **Yes** |
|
|
39
|
+
|
|
40
|
+
---
|
|
13
41
|
|
|
14
42
|
## Install
|
|
15
43
|
|
|
16
44
|
```bash
|
|
17
|
-
npm
|
|
45
|
+
npm install @quazardous/quarkernel
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
```html
|
|
49
|
+
<!-- CDN -->
|
|
50
|
+
<script src="https://unpkg.com/@quazardous/quarkernel@2/dist/index.umd.js"></script>
|
|
18
51
|
```
|
|
19
52
|
|
|
20
|
-
|
|
53
|
+
---
|
|
21
54
|
|
|
22
|
-
|
|
23
|
-
Share context between components.
|
|
55
|
+
## Quick Start
|
|
24
56
|
|
|
25
|
-
```
|
|
26
|
-
import {
|
|
57
|
+
```typescript
|
|
58
|
+
import { createKernel } from '@quazardous/quarkernel';
|
|
27
59
|
|
|
28
|
-
|
|
29
|
-
const qk = new QuarKernel();
|
|
60
|
+
const qk = createKernel();
|
|
30
61
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
62
|
+
// 1. Dependency ordering - control execution sequence
|
|
63
|
+
qk.on('checkout', async (e) => {
|
|
64
|
+
e.context.inventory = await checkStock(e.data.items);
|
|
65
|
+
}, { id: 'stock' });
|
|
66
|
+
|
|
67
|
+
qk.on('checkout', async (e) => {
|
|
68
|
+
// Runs AFTER stock check - guaranteed
|
|
69
|
+
await processPayment(e.data.card, e.context.inventory);
|
|
70
|
+
}, { after: ['stock'] });
|
|
71
|
+
|
|
72
|
+
await qk.emit('checkout', { items: ['sku-123'], card: 'tok_visa' });
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
// 2. Composite events - react to event combinations
|
|
77
|
+
import { Composition } from '@quazardous/quarkernel';
|
|
78
|
+
|
|
79
|
+
const checkout = new Composition([
|
|
80
|
+
[qk, 'cart:ready'],
|
|
81
|
+
[qk, 'payment:confirmed']
|
|
82
|
+
]);
|
|
83
|
+
|
|
84
|
+
checkout.onComposed(() => {
|
|
85
|
+
console.log('Both events fired - proceed to shipping!');
|
|
34
86
|
});
|
|
87
|
+
```
|
|
35
88
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
89
|
+
```typescript
|
|
90
|
+
// 3. Wildcards - catch event patterns
|
|
91
|
+
qk.on('user:*', (e) => console.log('User action:', e.name));
|
|
92
|
+
// Matches: user:login, user:logout, user:signup...
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## State Machines (FSM)
|
|
98
|
+
|
|
99
|
+
Built-in finite state machine support with XState-compatible format:
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
import { createMachine } from '@quazardous/quarkernel/fsm';
|
|
103
|
+
|
|
104
|
+
const order = createMachine({
|
|
105
|
+
id: 'order',
|
|
106
|
+
initial: 'draft',
|
|
107
|
+
context: { items: 0 },
|
|
108
|
+
states: {
|
|
109
|
+
draft: { on: { SUBMIT: 'pending' } },
|
|
110
|
+
pending: { on: { APPROVE: 'confirmed', REJECT: 'draft' } },
|
|
111
|
+
confirmed: { on: { SHIP: 'shipped' } },
|
|
112
|
+
shipped: {}
|
|
113
|
+
},
|
|
114
|
+
onEnter: {
|
|
115
|
+
confirmed: (ctx, { log }) => log('Order confirmed!')
|
|
116
|
+
},
|
|
117
|
+
on: {
|
|
118
|
+
SUBMIT: (ctx, { set }) => set({ submittedAt: Date.now() })
|
|
119
|
+
}
|
|
52
120
|
});
|
|
53
|
-
|
|
121
|
+
|
|
122
|
+
order.send('SUBMIT');
|
|
123
|
+
console.log(order.state); // 'pending'
|
|
54
124
|
```
|
|
55
125
|
|
|
56
|
-
|
|
126
|
+
**Features:**
|
|
127
|
+
- XState import/export (`fromXState`, `toXState`)
|
|
128
|
+
- Behavior helpers: `set()`, `send()`, `log()`
|
|
129
|
+
- Auto-timers for delayed transitions
|
|
130
|
+
- Visual debugging with [FSM Studio](https://quazardous.github.io/quarkernel/fsm-studio/)
|
|
57
131
|
|
|
58
|
-
|
|
132
|
+
---
|
|
59
133
|
|
|
60
|
-
|
|
134
|
+
## Framework Adapters
|
|
61
135
|
|
|
62
|
-
|
|
63
|
-
...
|
|
64
|
-
// init
|
|
65
|
-
qk.addCompositeEvent(['A','B'], (stack) => new QKE('C'));
|
|
66
|
-
...
|
|
67
|
-
qk.dispatchEvent(new QKE('A'));
|
|
68
|
-
...
|
|
69
|
-
// this will auto dispatch C
|
|
70
|
-
qk.dispatchEvent(new QKE('B'));
|
|
136
|
+
Official bindings with auto-cleanup on unmount:
|
|
71
137
|
|
|
138
|
+
| Package | Framework | Docs |
|
|
139
|
+
|---------|-----------|------|
|
|
140
|
+
| `@quazardous/quarkernel-vue` | Vue 3 | [README](https://github.com/quazardous/quarkernel/blob/main/packages/vue/README.md) |
|
|
141
|
+
| `@quazardous/quarkernel-react` | React 18+ | [README](https://github.com/quazardous/quarkernel/blob/main/packages/react/README.md) |
|
|
142
|
+
| `@quazardous/quarkernel-svelte` | Svelte 5 | [README](https://github.com/quazardous/quarkernel/blob/main/packages/svelte/README.md) |
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
# Vue
|
|
146
|
+
npm install @quazardous/quarkernel @quazardous/quarkernel-vue
|
|
147
|
+
|
|
148
|
+
# React
|
|
149
|
+
npm install @quazardous/quarkernel @quazardous/quarkernel-react
|
|
150
|
+
|
|
151
|
+
# Svelte
|
|
152
|
+
npm install @quazardous/quarkernel @quazardous/quarkernel-svelte
|
|
72
153
|
```
|
|
73
154
|
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Documentation
|
|
158
|
+
|
|
159
|
+
**Guides:**
|
|
160
|
+
- [Getting Started](https://github.com/quazardous/quarkernel/blob/main/docs/getting-started.md) - Installation, first event, basic usage
|
|
161
|
+
- [API Reference](https://github.com/quazardous/quarkernel/blob/main/docs/api-reference.md) - Complete API documentation
|
|
162
|
+
- [Advanced Patterns](https://github.com/quazardous/quarkernel/blob/main/docs/advanced-qk.md) - Multi-machine, composition, sagas
|
|
163
|
+
- [Async Integration](https://github.com/quazardous/quarkernel/blob/main/docs/async-patterns.md) - QK + FSM + Promises synergies
|
|
164
|
+
- [Migration v1 to v2](https://github.com/quazardous/quarkernel/blob/main/docs/migration-v1-to-v2.md) - Upgrade guide
|
|
165
|
+
|
|
166
|
+
**Packages:**
|
|
167
|
+
- [Core package](https://github.com/quazardous/quarkernel/blob/main/packages/quarkernel/README.md) - Main QuarKernel library
|
|
168
|
+
|
|
169
|
+
**Resources:**
|
|
170
|
+
- [Benchmarks](https://github.com/quazardous/quarkernel/blob/main/benchmarks/README.md) - Performance comparisons
|
|
171
|
+
- [Demos](https://github.com/quazardous/quarkernel/blob/main/demos/README.md) - Live examples
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Use Cases
|
|
176
|
+
|
|
177
|
+
**Request pipeline** - Auth, validate, transform, respond in guaranteed order
|
|
178
|
+
|
|
179
|
+
**Game events** - Combo detection with composite events
|
|
180
|
+
|
|
181
|
+
**Form wizards** - Step dependencies with shared validation context
|
|
182
|
+
|
|
183
|
+
**Order workflows** - State machines for order lifecycle (draft → pending → confirmed → shipped)
|
|
184
|
+
|
|
185
|
+
**Analytics** - Wildcard listeners for all `track:*` events
|
|
186
|
+
|
|
187
|
+
**Microservices** - Event choreography with dependency graphs
|
|
188
|
+
|
|
189
|
+
**UI flows** - FSM-driven modals, wizards, and multi-step forms
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## License
|
|
74
194
|
|
|
195
|
+
[MIT](https://github.com/quazardous/quarkernel/blob/main/LICENSE) - Made by [quazardous](https://github.com/quazardous)
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FSM Types for QuarKernel
|
|
3
|
+
*
|
|
4
|
+
* Flexible state machine layer built on quarkernel events.
|
|
5
|
+
* Prefixed events allow loose coupling and multi-machine orchestration.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* State name type
|
|
9
|
+
*/
|
|
10
|
+
type StateName = string;
|
|
11
|
+
/**
|
|
12
|
+
* Transition event name type
|
|
13
|
+
*/
|
|
14
|
+
type TransitionEvent = string;
|
|
15
|
+
/**
|
|
16
|
+
* Guard function - returns true to allow transition
|
|
17
|
+
*/
|
|
18
|
+
type GuardFunction<TContext = any> = (context: TContext, event: TransitionEvent, payload?: any) => boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Action function - side effect on transition
|
|
21
|
+
*/
|
|
22
|
+
type ActionFunction<TContext = any> = (context: TContext, event: TransitionEvent, payload?: any) => void | Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Transition definition
|
|
25
|
+
*/
|
|
26
|
+
interface TransitionDef<TContext = any> {
|
|
27
|
+
/** Target state */
|
|
28
|
+
target: StateName;
|
|
29
|
+
/** Guard condition (optional) */
|
|
30
|
+
guard?: GuardFunction<TContext>;
|
|
31
|
+
/** Actions to run on transition (optional) */
|
|
32
|
+
actions?: ActionFunction<TContext> | ActionFunction<TContext>[];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Timer/after definition for auto-transitions
|
|
36
|
+
*/
|
|
37
|
+
interface AfterDef$1 {
|
|
38
|
+
/** Delay in milliseconds */
|
|
39
|
+
delay: number;
|
|
40
|
+
/** Event to send after delay */
|
|
41
|
+
send: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* State node definition (state-centric format)
|
|
45
|
+
*/
|
|
46
|
+
interface StateNode<TContext = any> {
|
|
47
|
+
/** Transitions from this state: event -> target or TransitionDef */
|
|
48
|
+
on?: Record<TransitionEvent, StateName | TransitionDef<TContext>>;
|
|
49
|
+
/** Action on entering this state */
|
|
50
|
+
entry?: ActionFunction<TContext>;
|
|
51
|
+
/** Action on exiting this state */
|
|
52
|
+
exit?: ActionFunction<TContext>;
|
|
53
|
+
/** Auto-transition after delay: { delay: 3000, send: 'TIMER' } */
|
|
54
|
+
after?: AfterDef$1;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Machine configuration
|
|
58
|
+
*/
|
|
59
|
+
interface MachineConfig<TContext = any> {
|
|
60
|
+
/** Event prefix for this machine (e.g., 'order', 'player') */
|
|
61
|
+
prefix: string;
|
|
62
|
+
/** Initial state */
|
|
63
|
+
initial: StateName;
|
|
64
|
+
/** State definitions */
|
|
65
|
+
states: Record<StateName, StateNode<TContext>>;
|
|
66
|
+
/** Initial context (optional) */
|
|
67
|
+
context?: TContext;
|
|
68
|
+
/** Allow force transitions that bypass guards */
|
|
69
|
+
allowForce?: boolean;
|
|
70
|
+
/** Restore from snapshot (overrides initial/context) */
|
|
71
|
+
snapshot?: MachineSnapshot<TContext>;
|
|
72
|
+
/** Track transition history */
|
|
73
|
+
trackHistory?: boolean;
|
|
74
|
+
/** Max history entries (default: 100) */
|
|
75
|
+
maxHistory?: number;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Send options
|
|
79
|
+
*/
|
|
80
|
+
interface SendOptions<TContext = any> {
|
|
81
|
+
/** Force transition (bypass guards and undefined transitions) */
|
|
82
|
+
force?: boolean;
|
|
83
|
+
/** Target state for force transitions */
|
|
84
|
+
target?: StateName;
|
|
85
|
+
/** Inline guard (overrides state guard) */
|
|
86
|
+
guard?: GuardFunction<TContext>;
|
|
87
|
+
/** Fallback state if guard fails */
|
|
88
|
+
fallback?: StateName;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Serialized machine state (for persistence)
|
|
92
|
+
*/
|
|
93
|
+
interface MachineSnapshot<TContext = any> {
|
|
94
|
+
/** Current state */
|
|
95
|
+
state: StateName;
|
|
96
|
+
/** Machine context */
|
|
97
|
+
context: TContext;
|
|
98
|
+
/** Transition history (optional) */
|
|
99
|
+
history?: Array<{
|
|
100
|
+
from: StateName;
|
|
101
|
+
to: StateName;
|
|
102
|
+
event: TransitionEvent;
|
|
103
|
+
timestamp: number;
|
|
104
|
+
}>;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Machine instance returned by useMachine()
|
|
108
|
+
*/
|
|
109
|
+
interface Machine<TContext = any> {
|
|
110
|
+
/** Current state */
|
|
111
|
+
getState(): StateName;
|
|
112
|
+
/** Machine context */
|
|
113
|
+
getContext(): TContext;
|
|
114
|
+
/** Update context */
|
|
115
|
+
setContext(updater: Partial<TContext> | ((ctx: TContext) => TContext)): void;
|
|
116
|
+
/** Send transition event */
|
|
117
|
+
send(event: TransitionEvent, payload?: any, options?: SendOptions<TContext>): Promise<boolean>;
|
|
118
|
+
/** Check if transition is valid from current state */
|
|
119
|
+
can(event: TransitionEvent): boolean;
|
|
120
|
+
/** Get available transitions from current state */
|
|
121
|
+
transitions(): TransitionEvent[];
|
|
122
|
+
/** Machine prefix */
|
|
123
|
+
readonly prefix: string;
|
|
124
|
+
/** Serialize machine state to JSON */
|
|
125
|
+
toJSON(): MachineSnapshot<TContext>;
|
|
126
|
+
/** Restore machine state from snapshot */
|
|
127
|
+
restore(snapshot: MachineSnapshot<TContext>): void;
|
|
128
|
+
/** Cleanup listeners */
|
|
129
|
+
destroy(): void;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* FSM event data emitted on kernel
|
|
133
|
+
*/
|
|
134
|
+
interface FSMEventData {
|
|
135
|
+
/** Machine prefix */
|
|
136
|
+
machine: string;
|
|
137
|
+
/** Current/new state */
|
|
138
|
+
state: StateName;
|
|
139
|
+
/** Previous state (for transition events) */
|
|
140
|
+
from?: StateName;
|
|
141
|
+
/** Target state (for transition events) */
|
|
142
|
+
to?: StateName;
|
|
143
|
+
/** Transition event name */
|
|
144
|
+
event?: TransitionEvent;
|
|
145
|
+
/** Event payload */
|
|
146
|
+
payload?: any;
|
|
147
|
+
/** Whether this was a forced transition */
|
|
148
|
+
forced?: boolean;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* createMachine - High-level FSM factory
|
|
153
|
+
*
|
|
154
|
+
* Standalone state machine with declarative behaviors.
|
|
155
|
+
* Can work independently or connect to a kernel.
|
|
156
|
+
*/
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Built-in helpers (always available)
|
|
160
|
+
*/
|
|
161
|
+
interface BuiltInHelpers<TContext = Record<string, unknown>> {
|
|
162
|
+
/** Merge into context */
|
|
163
|
+
set: (partial: Partial<TContext>) => void;
|
|
164
|
+
/** Trigger transition */
|
|
165
|
+
send: (event: string, payload?: unknown) => void;
|
|
166
|
+
/** Log message (default: console.log) */
|
|
167
|
+
log: (message: string) => void;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Behavior helpers passed to callbacks (built-ins + custom)
|
|
171
|
+
*/
|
|
172
|
+
type BehaviorHelpers<TContext = Record<string, unknown>, TCustom = Record<string, unknown>> = BuiltInHelpers<TContext> & TCustom;
|
|
173
|
+
/**
|
|
174
|
+
* Behavior callback
|
|
175
|
+
*/
|
|
176
|
+
type BehaviorFn<TContext = Record<string, unknown>> = (ctx: TContext, helpers: BehaviorHelpers<TContext>) => void | Promise<void>;
|
|
177
|
+
/**
|
|
178
|
+
* Timer/after definition
|
|
179
|
+
*/
|
|
180
|
+
interface AfterDef {
|
|
181
|
+
/** Event to send */
|
|
182
|
+
send: string;
|
|
183
|
+
/** Delay in ms */
|
|
184
|
+
delay: number;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* State-centric state definition
|
|
188
|
+
*/
|
|
189
|
+
interface StateConfig<TContext = Record<string, unknown>> {
|
|
190
|
+
/** Transitions: { EVENT: 'target' } or { EVENT: { target: 'x', cond: 'guard' } } */
|
|
191
|
+
on?: Record<string, string | {
|
|
192
|
+
target: string;
|
|
193
|
+
cond?: string;
|
|
194
|
+
}>;
|
|
195
|
+
/** Action on entering this state */
|
|
196
|
+
entry?: BehaviorFn<TContext>;
|
|
197
|
+
/** Action on exiting this state */
|
|
198
|
+
exit?: BehaviorFn<TContext>;
|
|
199
|
+
/** Auto-transition after delay: { delay: 3000, send: 'TIMER' } */
|
|
200
|
+
after?: AfterDef;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* High-level machine config (state-centric)
|
|
204
|
+
*/
|
|
205
|
+
interface CreateMachineConfig<TContext = Record<string, unknown>, THelpers = Record<string, unknown>> {
|
|
206
|
+
/** Machine identifier */
|
|
207
|
+
id: string;
|
|
208
|
+
/** Initial state */
|
|
209
|
+
initial: string;
|
|
210
|
+
/** Initial context */
|
|
211
|
+
context?: TContext;
|
|
212
|
+
/** State definitions with entry/exit/after inline */
|
|
213
|
+
states: Record<string, StateConfig<TContext>>;
|
|
214
|
+
/** Global event handlers: { EVENT_NAME: (ctx, helpers) => ... } */
|
|
215
|
+
on?: Record<string, BehaviorFn<TContext>>;
|
|
216
|
+
/** Custom helpers merged with built-ins (set, send) */
|
|
217
|
+
helpers?: THelpers;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Extended machine interface with behaviors
|
|
221
|
+
*/
|
|
222
|
+
interface BehaviorMachine<TContext = Record<string, unknown>> extends Machine<TContext> {
|
|
223
|
+
/** Machine ID */
|
|
224
|
+
readonly id: string;
|
|
225
|
+
/** Current state (getter) */
|
|
226
|
+
readonly state: string;
|
|
227
|
+
/** Current context (getter) */
|
|
228
|
+
readonly context: TContext;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Create a standalone state machine with behaviors (state-centric)
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* ```ts
|
|
235
|
+
* const order = createMachine({
|
|
236
|
+
* id: 'order',
|
|
237
|
+
* initial: 'draft',
|
|
238
|
+
* context: { items: 0, total: 0 },
|
|
239
|
+
*
|
|
240
|
+
* states: {
|
|
241
|
+
* draft: {
|
|
242
|
+
* on: { ADD_ITEM: 'draft', SUBMIT: 'pending' }
|
|
243
|
+
* },
|
|
244
|
+
* pending: {
|
|
245
|
+
* entry: (ctx, { log }) => log('Order pending...'),
|
|
246
|
+
* on: { APPROVE: 'confirmed', REJECT: 'draft' }
|
|
247
|
+
* },
|
|
248
|
+
* confirmed: {
|
|
249
|
+
* entry: (ctx, { log }) => log(`Order confirmed: ${ctx.items} items`),
|
|
250
|
+
* on: { SHIP: 'shipped' }
|
|
251
|
+
* },
|
|
252
|
+
* processing: {
|
|
253
|
+
* after: { delay: 2000, send: 'COMPLETE' },
|
|
254
|
+
* on: { COMPLETE: 'done' }
|
|
255
|
+
* },
|
|
256
|
+
* shipped: {},
|
|
257
|
+
* },
|
|
258
|
+
*
|
|
259
|
+
* // Global event handlers (optional)
|
|
260
|
+
* on: {
|
|
261
|
+
* ADD_ITEM: (ctx, { set }) => {
|
|
262
|
+
* set({ items: ctx.items + 1, total: ctx.total + 29.99 });
|
|
263
|
+
* },
|
|
264
|
+
* },
|
|
265
|
+
* });
|
|
266
|
+
*
|
|
267
|
+
* order.send('ADD_ITEM');
|
|
268
|
+
* order.send('SUBMIT');
|
|
269
|
+
* console.log(order.state); // 'pending'
|
|
270
|
+
* console.log(order.context); // { items: 1, total: 29.99 }
|
|
271
|
+
* ```
|
|
272
|
+
*/
|
|
273
|
+
declare function createMachine<TContext = Record<string, unknown>>(config: CreateMachineConfig<TContext>): BehaviorMachine<TContext>;
|
|
274
|
+
|
|
275
|
+
export { type ActionFunction as A, type BehaviorMachine as B, type CreateMachineConfig as C, type FSMEventData as F, type GuardFunction as G, type MachineConfig as M, type StateNode as S, type TransitionDef as T, type Machine as a, type MachineSnapshot as b, createMachine as c, type SendOptions as d, type StateName as e, type TransitionEvent as f, type StateConfig as g, type BehaviorFn as h, type BehaviorHelpers as i, type BuiltInHelpers as j, type AfterDef as k, type AfterDef$1 as l };
|