effect-machine 0.12.0 → 0.14.0
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 +133 -324
- package/dist/actor.d.ts +46 -28
- package/dist/actor.js +276 -315
- package/dist/cluster/entity-machine.d.ts +1 -1
- package/dist/cluster/entity-machine.js +20 -9
- package/dist/cluster/to-entity.d.ts +3 -3
- package/dist/errors.d.ts +24 -20
- package/dist/errors.js +10 -6
- package/dist/index.d.ts +5 -4
- package/dist/index.js +3 -2
- package/dist/internal/runtime.d.ts +82 -7
- package/dist/internal/runtime.js +162 -58
- package/dist/internal/transition.d.ts +12 -11
- package/dist/internal/transition.js +12 -14
- package/dist/machine.d.ts +148 -140
- package/dist/machine.js +141 -155
- package/dist/schema.d.ts +14 -0
- package/dist/schema.js +10 -1
- package/dist/slot.d.ts +112 -86
- package/dist/slot.js +92 -59
- package/dist/supervision.d.ts +97 -0
- package/dist/supervision.js +42 -0
- package/dist/testing.d.ts +21 -12
- package/dist/testing.js +23 -26
- package/package.json +7 -7
- package/v3/dist/actor.d.ts +53 -30
- package/v3/dist/actor.js +286 -311
- package/v3/dist/cluster/entity-machine.d.ts +1 -1
- package/v3/dist/cluster/entity-machine.js +5 -5
- package/v3/dist/cluster/to-entity.d.ts +1 -1
- package/v3/dist/errors.d.ts +14 -10
- package/v3/dist/errors.js +11 -7
- package/v3/dist/index.d.ts +6 -5
- package/v3/dist/index.js +3 -2
- package/v3/dist/inspection.d.ts +3 -22
- package/v3/dist/inspection.js +1 -15
- package/v3/dist/internal/brands.d.ts +4 -8
- package/v3/dist/internal/inspection.js +1 -1
- package/v3/dist/internal/runtime.d.ts +87 -10
- package/v3/dist/internal/runtime.js +177 -61
- package/v3/dist/internal/transition.d.ts +13 -12
- package/v3/dist/internal/transition.js +14 -16
- package/v3/dist/internal/utils.js +5 -1
- package/v3/dist/machine.d.ts +158 -143
- package/v3/dist/machine.js +148 -155
- package/v3/dist/schema.d.ts +25 -11
- package/v3/dist/schema.js +18 -5
- package/v3/dist/slot.d.ts +112 -86
- package/v3/dist/slot.js +92 -59
- package/v3/dist/supervision.d.ts +97 -0
- package/v3/dist/supervision.js +42 -0
- package/v3/dist/testing.d.ts +21 -12
- package/v3/dist/testing.js +23 -24
package/v3/dist/testing.js
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
import { stubSystem } from "./internal/utils.js";
|
|
2
2
|
import { AssertionError } from "./errors.js";
|
|
3
|
-
import { BuiltMachine } from "./machine.js";
|
|
4
3
|
import { executeTransition, shouldPostpone } from "./internal/transition.js";
|
|
4
|
+
import { materializeMachine } from "./machine.js";
|
|
5
5
|
import { Effect, SubscriptionRef } from "effect";
|
|
6
6
|
//#region src/testing.ts
|
|
7
|
+
const makeDummySelf = (label) => {
|
|
8
|
+
const dummySend = Effect.fn(label)((_event) => Effect.void);
|
|
9
|
+
return {
|
|
10
|
+
send: dummySend,
|
|
11
|
+
cast: dummySend,
|
|
12
|
+
spawn: () => Effect.die(`spawn not supported in ${label}`),
|
|
13
|
+
reply: () => Effect.succeed(false)
|
|
14
|
+
};
|
|
15
|
+
};
|
|
7
16
|
/**
|
|
8
17
|
* Simulate a sequence of events through a machine without running an actor.
|
|
9
18
|
* Useful for testing state transitions in isolation.
|
|
10
|
-
* Does not run onEnter/spawn/background effects, but does run
|
|
19
|
+
* Does not run onEnter/spawn/background effects, but does run slots
|
|
11
20
|
* within transition handlers.
|
|
12
21
|
*
|
|
13
22
|
* @example
|
|
@@ -24,14 +33,9 @@ import { Effect, SubscriptionRef } from "effect";
|
|
|
24
33
|
* expect(result.states).toHaveLength(3) // Idle -> Loading -> Success
|
|
25
34
|
* ```
|
|
26
35
|
*/
|
|
27
|
-
const simulate = Effect.fn("effect-machine.simulate")(function* (input, events) {
|
|
28
|
-
const machine = input
|
|
29
|
-
const
|
|
30
|
-
const dummySelf = {
|
|
31
|
-
send: dummySend,
|
|
32
|
-
cast: dummySend,
|
|
33
|
-
spawn: () => Effect.die("spawn not supported in simulation")
|
|
34
|
-
};
|
|
36
|
+
const simulate = Effect.fn("effect-machine.simulate")(function* (input, events, options) {
|
|
37
|
+
const machine = materializeMachine(input, options?.slots);
|
|
38
|
+
const dummySelf = makeDummySelf("effect-machine.testing.simulate");
|
|
35
39
|
let currentState = machine.initial;
|
|
36
40
|
const states = [currentState];
|
|
37
41
|
const hasPostponeRules = machine.postponeRules.length > 0;
|
|
@@ -73,8 +77,8 @@ const simulate = Effect.fn("effect-machine.simulate")(function* (input, events)
|
|
|
73
77
|
/**
|
|
74
78
|
* Assert that a machine can reach a specific state given a sequence of events
|
|
75
79
|
*/
|
|
76
|
-
const assertReaches = Effect.fn("effect-machine.assertReaches")(function* (input, events, expectedTag) {
|
|
77
|
-
const result = yield* simulate(input, events);
|
|
80
|
+
const assertReaches = Effect.fn("effect-machine.assertReaches")(function* (input, events, expectedTag, options) {
|
|
81
|
+
const result = yield* simulate(input, events, options);
|
|
78
82
|
if (result.finalState._tag !== expectedTag) return yield* new AssertionError({ message: `Expected final state "${expectedTag}" but got "${result.finalState._tag}". States visited: ${result.states.map((s) => s._tag).join(" -> ")}` });
|
|
79
83
|
return result.finalState;
|
|
80
84
|
});
|
|
@@ -90,8 +94,8 @@ const assertReaches = Effect.fn("effect-machine.assertReaches")(function* (input
|
|
|
90
94
|
* )
|
|
91
95
|
* ```
|
|
92
96
|
*/
|
|
93
|
-
const assertPath = Effect.fn("effect-machine.assertPath")(function* (input, events, expectedPath) {
|
|
94
|
-
const result = yield* simulate(input, events);
|
|
97
|
+
const assertPath = Effect.fn("effect-machine.assertPath")(function* (input, events, expectedPath, options) {
|
|
98
|
+
const result = yield* simulate(input, events, options);
|
|
95
99
|
const actualPath = result.states.map((s) => s._tag);
|
|
96
100
|
if (actualPath.length !== expectedPath.length) return yield* new AssertionError({ message: `Path length mismatch. Expected ${expectedPath.length} states but got ${actualPath.length}.\nExpected: ${expectedPath.join(" -> ")}\nActual: ${actualPath.join(" -> ")}` });
|
|
97
101
|
for (let i = 0; i < expectedPath.length; i++) if (actualPath[i] !== expectedPath[i]) return yield* new AssertionError({ message: `Path mismatch at position ${i}. Expected "${expectedPath[i]}" but got "${actualPath[i]}".\nExpected: ${expectedPath.join(" -> ")}\nActual: ${actualPath.join(" -> ")}` });
|
|
@@ -110,15 +114,15 @@ const assertPath = Effect.fn("effect-machine.assertPath")(function* (input, even
|
|
|
110
114
|
* )
|
|
111
115
|
* ```
|
|
112
116
|
*/
|
|
113
|
-
const assertNeverReaches = Effect.fn("effect-machine.assertNeverReaches")(function* (input, events, forbiddenTag) {
|
|
114
|
-
const result = yield* simulate(input, events);
|
|
117
|
+
const assertNeverReaches = Effect.fn("effect-machine.assertNeverReaches")(function* (input, events, forbiddenTag, options) {
|
|
118
|
+
const result = yield* simulate(input, events, options);
|
|
115
119
|
const visitedIndex = result.states.findIndex((s) => s._tag === forbiddenTag);
|
|
116
120
|
if (visitedIndex !== -1) return yield* new AssertionError({ message: `Machine reached forbidden state "${forbiddenTag}" at position ${visitedIndex}.\nStates visited: ${result.states.map((s) => s._tag).join(" -> ")}` });
|
|
117
121
|
return result;
|
|
118
122
|
});
|
|
119
123
|
/**
|
|
120
124
|
* Create a test harness for step-by-step testing.
|
|
121
|
-
* Does not run onEnter/spawn/background effects, but does run
|
|
125
|
+
* Does not run onEnter/spawn/background effects, but does run slots
|
|
122
126
|
* within transition handlers.
|
|
123
127
|
*
|
|
124
128
|
* @example Basic usage
|
|
@@ -138,13 +142,8 @@ const assertNeverReaches = Effect.fn("effect-machine.assertNeverReaches")(functi
|
|
|
138
142
|
* ```
|
|
139
143
|
*/
|
|
140
144
|
const createTestHarness = Effect.fn("effect-machine.createTestHarness")(function* (input, options) {
|
|
141
|
-
const machine = input
|
|
142
|
-
const
|
|
143
|
-
const dummySelf = {
|
|
144
|
-
send: dummySend,
|
|
145
|
-
cast: dummySend,
|
|
146
|
-
spawn: () => Effect.die("spawn not supported in test harness")
|
|
147
|
-
};
|
|
145
|
+
const machine = materializeMachine(input, options?.slots);
|
|
146
|
+
const dummySelf = makeDummySelf("effect-machine.testing.harness");
|
|
148
147
|
const stateRef = yield* SubscriptionRef.make(machine.initial);
|
|
149
148
|
const hasPostponeRules = machine.postponeRules.length > 0;
|
|
150
149
|
const postponed = [];
|