effect-machine 0.2.1 → 0.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/package.json +1 -1
- package/src/actor.ts +12 -8
- package/src/index.ts +1 -0
- package/src/inspection.ts +27 -7
package/package.json
CHANGED
package/src/actor.ts
CHANGED
|
@@ -364,12 +364,14 @@ export const buildActorRefCore = <
|
|
|
364
364
|
const waitFor = Effect.fn("effect-machine.actor.waitFor")(function* (
|
|
365
365
|
predicate: (state: S) => boolean,
|
|
366
366
|
) {
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
367
|
+
// Use stateRef.changes directly — it emits the current value as its first
|
|
368
|
+
// element inside the SubscriptionRef semaphore, so this is atomic and
|
|
369
|
+
// race-free (no gap between "check current" and "subscribe").
|
|
370
|
+
const result = yield* stateRef.changes.pipe(Stream.filter(predicate), Stream.runHead);
|
|
371
|
+
if (Option.isSome(result)) return result.value;
|
|
372
|
+
// Unreachable: changes always emits at least the current value.
|
|
373
|
+
// Fallback to snapshot for type completeness.
|
|
374
|
+
return yield* SubscriptionRef.get(stateRef);
|
|
373
375
|
});
|
|
374
376
|
|
|
375
377
|
const awaitFinal = waitFor((state) => machine.finalStates.has(state._tag)).pipe(
|
|
@@ -518,8 +520,10 @@ export const createActor = Effect.fn("effect-machine.actor.spawn")(function* <
|
|
|
518
520
|
return buildActorRefCore(id, machine, stateRef, eventQueue, stoppedRef, listeners, stop);
|
|
519
521
|
}
|
|
520
522
|
|
|
521
|
-
// Start the event loop
|
|
522
|
-
|
|
523
|
+
// Start the event loop — use forkScoped so the event loop fiber's lifetime
|
|
524
|
+
// is tied to the provided Scope, not the calling fiber. This prevents the
|
|
525
|
+
// event loop from being interrupted when a transient caller completes.
|
|
526
|
+
const loopFiber = yield* Effect.forkScoped(
|
|
523
527
|
eventLoop(
|
|
524
528
|
machine,
|
|
525
529
|
stateRef,
|
package/src/index.ts
CHANGED
package/src/inspection.ts
CHANGED
|
@@ -82,6 +82,17 @@ export type InspectionEvent<S, E> =
|
|
|
82
82
|
| ErrorEvent<S, E>
|
|
83
83
|
| StopEvent<S>;
|
|
84
84
|
|
|
85
|
+
/**
|
|
86
|
+
* Convenience alias for untyped inspection events.
|
|
87
|
+
* Useful for general-purpose inspectors that don't need specific state/event types.
|
|
88
|
+
* State and event fields are typed as `{ readonly _tag: string }` so discriminated
|
|
89
|
+
* access to `_tag` works without casting.
|
|
90
|
+
*/
|
|
91
|
+
export type AnyInspectionEvent = InspectionEvent<
|
|
92
|
+
{ readonly _tag: string },
|
|
93
|
+
{ readonly _tag: string }
|
|
94
|
+
>;
|
|
95
|
+
|
|
85
96
|
// ============================================================================
|
|
86
97
|
// Inspector Service
|
|
87
98
|
// ============================================================================
|
|
@@ -101,9 +112,14 @@ export interface Inspector<S, E> {
|
|
|
101
112
|
export const Inspector = Context.GenericTag<Inspector<any, any>>("@effect/machine/Inspector");
|
|
102
113
|
|
|
103
114
|
/**
|
|
104
|
-
* Create an inspector from a callback function
|
|
115
|
+
* Create an inspector from a callback function.
|
|
116
|
+
* Defaults to `AnyInspectionEvent` when type params are not provided,
|
|
117
|
+
* giving access to `_tag` on state/event fields without casts.
|
|
105
118
|
*/
|
|
106
|
-
export const makeInspector = <
|
|
119
|
+
export const makeInspector = <
|
|
120
|
+
S extends { readonly _tag: string } = { readonly _tag: string },
|
|
121
|
+
E extends { readonly _tag: string } = { readonly _tag: string },
|
|
122
|
+
>(
|
|
107
123
|
onInspect: (event: InspectionEvent<S, E>) => void,
|
|
108
124
|
): Inspector<S, E> => ({ onInspect });
|
|
109
125
|
|
|
@@ -115,10 +131,10 @@ export const makeInspector = <S, E>(
|
|
|
115
131
|
* Console inspector that logs events in a readable format
|
|
116
132
|
*/
|
|
117
133
|
export const consoleInspector = <
|
|
118
|
-
S extends { readonly _tag: string },
|
|
119
|
-
E extends { readonly _tag: string },
|
|
134
|
+
S extends { readonly _tag: string } = { readonly _tag: string },
|
|
135
|
+
E extends { readonly _tag: string } = { readonly _tag: string },
|
|
120
136
|
>(): Inspector<S, E> =>
|
|
121
|
-
makeInspector((event) => {
|
|
137
|
+
makeInspector<S, E>((event) => {
|
|
122
138
|
const prefix = `[${event.actorId}]`;
|
|
123
139
|
switch (event.type) {
|
|
124
140
|
case "@machine.spawn":
|
|
@@ -145,5 +161,9 @@ export const consoleInspector = <
|
|
|
145
161
|
/**
|
|
146
162
|
* Collecting inspector that stores events in an array for testing
|
|
147
163
|
*/
|
|
148
|
-
export const collectingInspector = <
|
|
149
|
-
|
|
164
|
+
export const collectingInspector = <
|
|
165
|
+
S extends { readonly _tag: string },
|
|
166
|
+
E extends { readonly _tag: string },
|
|
167
|
+
>(
|
|
168
|
+
events: InspectionEvent<S, E>[],
|
|
169
|
+
): Inspector<S, E> => makeInspector<S, E>((event) => events.push(event));
|