effect-machine 0.6.0 → 0.7.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/dist/actor.d.ts +2 -2
- package/dist/actor.js +13 -15
- package/dist/cluster/entity-machine.d.ts +2 -2
- package/dist/cluster/entity-machine.js +1 -1
- package/dist/cluster/to-entity.d.ts +5 -5
- package/dist/cluster/to-entity.js +2 -2
- package/dist/errors.d.ts +25 -40
- package/dist/errors.js +10 -10
- package/dist/inspection.d.ts +3 -3
- package/dist/inspection.js +2 -2
- package/dist/internal/brands.d.ts +3 -6
- package/dist/internal/inspection.js +5 -1
- package/dist/internal/transition.d.ts +2 -2
- package/dist/internal/transition.js +6 -6
- package/dist/internal/utils.js +5 -1
- package/dist/machine.d.ts +5 -5
- package/dist/machine.js +9 -5
- package/dist/persistence/adapter.d.ts +18 -21
- package/dist/persistence/adapter.js +4 -4
- package/dist/persistence/adapters/in-memory.js +4 -4
- package/dist/persistence/persistent-actor.js +9 -9
- package/dist/persistence/persistent-machine.d.ts +3 -3
- package/dist/schema.d.ts +4 -4
- package/dist/schema.js +2 -2
- package/dist/slot.d.ts +3 -3
- package/dist/slot.js +2 -2
- package/dist-v3/_virtual/_rolldown/runtime.js +18 -0
- package/dist-v3/actor.d.ts +291 -0
- package/dist-v3/actor.js +459 -0
- package/dist-v3/cluster/entity-machine.d.ts +90 -0
- package/dist-v3/cluster/entity-machine.js +80 -0
- package/dist-v3/cluster/index.d.ts +3 -0
- package/dist-v3/cluster/index.js +4 -0
- package/dist-v3/cluster/to-entity.d.ts +61 -0
- package/dist-v3/cluster/to-entity.js +53 -0
- package/dist-v3/errors.d.ts +27 -0
- package/dist-v3/errors.js +38 -0
- package/dist-v3/index.d.ts +13 -0
- package/dist-v3/index.js +14 -0
- package/dist-v3/inspection.d.ts +125 -0
- package/dist-v3/inspection.js +50 -0
- package/dist-v3/internal/brands.d.ts +40 -0
- package/dist-v3/internal/brands.js +0 -0
- package/dist-v3/internal/inspection.d.ts +11 -0
- package/dist-v3/internal/inspection.js +15 -0
- package/dist-v3/internal/transition.d.ts +160 -0
- package/dist-v3/internal/transition.js +238 -0
- package/dist-v3/internal/utils.d.ts +60 -0
- package/dist-v3/internal/utils.js +51 -0
- package/dist-v3/machine.d.ts +278 -0
- package/dist-v3/machine.js +317 -0
- package/dist-v3/persistence/adapter.d.ts +125 -0
- package/dist-v3/persistence/adapter.js +27 -0
- package/dist-v3/persistence/adapters/in-memory.d.ts +32 -0
- package/dist-v3/persistence/adapters/in-memory.js +176 -0
- package/dist-v3/persistence/index.d.ts +5 -0
- package/dist-v3/persistence/index.js +6 -0
- package/dist-v3/persistence/persistent-actor.d.ts +49 -0
- package/dist-v3/persistence/persistent-actor.js +367 -0
- package/dist-v3/persistence/persistent-machine.d.ts +105 -0
- package/dist-v3/persistence/persistent-machine.js +24 -0
- package/dist-v3/schema.d.ts +141 -0
- package/dist-v3/schema.js +165 -0
- package/dist-v3/slot.d.ts +130 -0
- package/dist-v3/slot.js +99 -0
- package/dist-v3/testing.d.ts +136 -0
- package/dist-v3/testing.js +138 -0
- package/package.json +29 -21
package/dist/actor.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { ProcessEventError, ProcessEventHooks, ProcessEventResult, processEventC
|
|
|
5
5
|
import { PersistentActorRef } from "./persistence/persistent-actor.js";
|
|
6
6
|
import { ActorMetadata, PersistenceAdapterTag, PersistenceError, RestoreResult, VersionConflictError } from "./persistence/adapter.js";
|
|
7
7
|
import { BuiltMachine, Machine, MachineRef } from "./machine.js";
|
|
8
|
-
import {
|
|
8
|
+
import { Effect, Layer, Option, Queue, Ref, Scope, ServiceMap, Stream, SubscriptionRef } from "effect";
|
|
9
9
|
import * as effect_Tracer0 from "effect/Tracer";
|
|
10
10
|
|
|
11
11
|
//#region src/actor.d.ts
|
|
@@ -261,7 +261,7 @@ interface ActorSystem {
|
|
|
261
261
|
/**
|
|
262
262
|
* ActorSystem service tag
|
|
263
263
|
*/
|
|
264
|
-
declare const ActorSystem:
|
|
264
|
+
declare const ActorSystem: ServiceMap.Service<ActorSystem, ActorSystem>;
|
|
265
265
|
/** Listener set for sync subscriptions */
|
|
266
266
|
type Listeners<S> = Set<(state: S) => void>;
|
|
267
267
|
/**
|
package/dist/actor.js
CHANGED
|
@@ -6,7 +6,7 @@ import { processEventCore, resolveTransition, runSpawnEffects } from "./internal
|
|
|
6
6
|
import { emitWithTimestamp } from "./internal/inspection.js";
|
|
7
7
|
import { PersistenceAdapterTag, PersistenceError } from "./persistence/adapter.js";
|
|
8
8
|
import { createPersistentActor, restorePersistentActor } from "./persistence/persistent-actor.js";
|
|
9
|
-
import { Cause,
|
|
9
|
+
import { Cause, Deferred, Effect, Exit, Fiber, Layer, MutableHashMap, Option, PubSub, Queue, Ref, Scope, Semaphore, ServiceMap, Stream, SubscriptionRef } from "effect";
|
|
10
10
|
|
|
11
11
|
//#region src/actor.ts
|
|
12
12
|
/**
|
|
@@ -20,7 +20,7 @@ import { Cause, Context, Deferred, Effect, Exit, Fiber, Layer, MutableHashMap, O
|
|
|
20
20
|
/**
|
|
21
21
|
* ActorSystem service tag
|
|
22
22
|
*/
|
|
23
|
-
const ActorSystem =
|
|
23
|
+
const ActorSystem = ServiceMap.Service("@effect/machine/ActorSystem");
|
|
24
24
|
/**
|
|
25
25
|
* Notify all listeners of state change.
|
|
26
26
|
*/
|
|
@@ -49,10 +49,8 @@ const buildActorRefCore = (id, machine, stateRef, eventQueue, stoppedRef, listen
|
|
|
49
49
|
const current = yield* SubscriptionRef.get(stateRef);
|
|
50
50
|
if (predicate(current)) return current;
|
|
51
51
|
const done = yield* Deferred.make();
|
|
52
|
-
const rt = yield* Effect.runtime();
|
|
53
|
-
const runFork = Runtime.runFork(rt);
|
|
54
52
|
const listener = (state) => {
|
|
55
|
-
if (predicate(state)) runFork(Deferred.succeed(done, state));
|
|
53
|
+
if (predicate(state)) Effect.runFork(Deferred.succeed(done, state));
|
|
56
54
|
};
|
|
57
55
|
listeners.add(listener);
|
|
58
56
|
const afterSubscribe = yield* SubscriptionRef.get(stateRef);
|
|
@@ -84,7 +82,7 @@ const buildActorRefCore = (id, machine, stateRef, eventQueue, stoppedRef, listen
|
|
|
84
82
|
canSync: (event) => {
|
|
85
83
|
return resolveTransition(machine, Effect.runSync(SubscriptionRef.get(stateRef)), event) !== void 0;
|
|
86
84
|
},
|
|
87
|
-
changes:
|
|
85
|
+
changes: SubscriptionRef.changes(stateRef),
|
|
88
86
|
waitFor,
|
|
89
87
|
awaitFinal,
|
|
90
88
|
sendAndWait,
|
|
@@ -153,7 +151,7 @@ const createActor = Effect.fn("effect-machine.actor.spawn")(function* (id, machi
|
|
|
153
151
|
};
|
|
154
152
|
const { effects: effectSlots } = machine._slots;
|
|
155
153
|
for (const bg of machine.backgroundEffects) {
|
|
156
|
-
const fiber = yield* Effect.
|
|
154
|
+
const fiber = yield* Effect.forkDetach(bg.handler({
|
|
157
155
|
state: machine.initial,
|
|
158
156
|
event: initEvent,
|
|
159
157
|
self,
|
|
@@ -177,7 +175,7 @@ const createActor = Effect.fn("effect-machine.actor.spawn")(function* (id, machi
|
|
|
177
175
|
if (implicitSystemScope !== void 0) yield* Scope.close(implicitSystemScope, Exit.void);
|
|
178
176
|
return buildActorRefCore(id, machine, stateRef, eventQueue, stoppedRef, listeners, Ref.set(stoppedRef, true).pipe(Effect.withSpan("effect-machine.actor.stop"), Effect.asVoid), system, childrenMap);
|
|
179
177
|
}
|
|
180
|
-
const loopFiber = yield* Effect.
|
|
178
|
+
const loopFiber = yield* Effect.forkDetach(eventLoop(machine, stateRef, eventQueue, stoppedRef, self, listeners, backgroundFibers, stateScopeRef, id, inspectorValue, system));
|
|
181
179
|
return buildActorRefCore(id, machine, stateRef, eventQueue, stoppedRef, listeners, Effect.gen(function* () {
|
|
182
180
|
const finalState = yield* SubscriptionRef.get(stateRef);
|
|
183
181
|
yield* emitWithTimestamp(inspectorValue, (timestamp) => ({
|
|
@@ -303,10 +301,10 @@ const notifySystemListeners = (listeners, event) => {
|
|
|
303
301
|
};
|
|
304
302
|
const make = Effect.fn("effect-machine.actorSystem.make")(function* () {
|
|
305
303
|
const actorsMap = MutableHashMap.empty();
|
|
306
|
-
const withSpawnGate = (yield*
|
|
304
|
+
const withSpawnGate = (yield* Semaphore.make(1)).withPermits(1);
|
|
307
305
|
const eventPubSub = yield* PubSub.unbounded();
|
|
308
306
|
const eventListeners = /* @__PURE__ */ new Set();
|
|
309
|
-
const emitSystemEvent = (event) => Effect.sync(() => notifySystemListeners(eventListeners, event)).pipe(Effect.andThen(PubSub.publish(eventPubSub, event)), Effect.
|
|
307
|
+
const emitSystemEvent = (event) => Effect.sync(() => notifySystemListeners(eventListeners, event)).pipe(Effect.andThen(PubSub.publish(eventPubSub, event)), Effect.catchCause(() => Effect.void), Effect.asVoid);
|
|
310
308
|
yield* Effect.addFinalizer(() => {
|
|
311
309
|
const stops = [];
|
|
312
310
|
MutableHashMap.forEach(actorsMap, (actor) => {
|
|
@@ -390,12 +388,12 @@ const make = Effect.fn("effect-machine.actorSystem.make")(function* () {
|
|
|
390
388
|
const failed = [];
|
|
391
389
|
for (const id of ids) {
|
|
392
390
|
if (MutableHashMap.has(actorsMap, id)) continue;
|
|
393
|
-
const result = yield* Effect.
|
|
394
|
-
if (result._tag === "
|
|
391
|
+
const result = yield* Effect.result(restore(id, persistentMachine));
|
|
392
|
+
if (result._tag === "Failure") failed.push({
|
|
395
393
|
id,
|
|
396
|
-
error: result.
|
|
394
|
+
error: result.failure
|
|
397
395
|
});
|
|
398
|
-
else if (Option.isSome(result.
|
|
396
|
+
else if (Option.isSome(result.success)) restored.push(result.success.value);
|
|
399
397
|
else failed.push({
|
|
400
398
|
id,
|
|
401
399
|
error: new PersistenceError({
|
|
@@ -453,7 +451,7 @@ const make = Effect.fn("effect-machine.actorSystem.make")(function* () {
|
|
|
453
451
|
/**
|
|
454
452
|
* Default ActorSystem layer
|
|
455
453
|
*/
|
|
456
|
-
const Default = Layer.
|
|
454
|
+
const Default = Layer.effect(ActorSystem, make());
|
|
457
455
|
|
|
458
456
|
//#endregion
|
|
459
457
|
export { ActorSystem, Default, buildActorRefCore, createActor, notifyListeners, processEventCore, resolveTransition, runSpawnEffects };
|
|
@@ -3,8 +3,8 @@ import { ProcessEventHooks } from "../internal/transition.js";
|
|
|
3
3
|
import { Machine } from "../machine.js";
|
|
4
4
|
import "../actor.js";
|
|
5
5
|
import { Layer } from "effect";
|
|
6
|
-
import { Entity } from "
|
|
7
|
-
import { Rpc } from "
|
|
6
|
+
import { Entity } from "effect/unstable/cluster";
|
|
7
|
+
import { Rpc } from "effect/unstable/rpc";
|
|
8
8
|
|
|
9
9
|
//#region src/cluster/entity-machine.d.ts
|
|
10
10
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { processEventCore, runSpawnEffects } from "../internal/transition.js";
|
|
2
2
|
import { ActorSystem } from "../actor.js";
|
|
3
3
|
import { Effect, Option, Queue, Ref, Scope } from "effect";
|
|
4
|
-
import { Entity } from "
|
|
4
|
+
import { Entity } from "effect/unstable/cluster";
|
|
5
5
|
|
|
6
6
|
//#region src/cluster/entity-machine.ts
|
|
7
7
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Machine } from "../machine.js";
|
|
2
2
|
import { Schema } from "effect";
|
|
3
|
-
import { Entity } from "
|
|
4
|
-
import { Rpc } from "
|
|
3
|
+
import { Entity } from "effect/unstable/cluster";
|
|
4
|
+
import { Rpc } from "effect/unstable/rpc";
|
|
5
5
|
|
|
6
6
|
//#region src/cluster/to-entity.d.ts
|
|
7
7
|
/**
|
|
@@ -19,7 +19,7 @@ interface ToEntityOptions {
|
|
|
19
19
|
* - `Send` - Send event to machine, returns new state
|
|
20
20
|
* - `GetState` - Get current state
|
|
21
21
|
*/
|
|
22
|
-
type EntityRpcs<StateSchema extends Schema.
|
|
22
|
+
type EntityRpcs<StateSchema extends Schema.Top, EventSchema extends Schema.Top> = readonly [Rpc.Rpc<"Send", Schema.Struct<{
|
|
23
23
|
readonly event: EventSchema;
|
|
24
24
|
}>, StateSchema, typeof Schema.Never, never>, Rpc.Rpc<"GetState", typeof Schema.Void, StateSchema, typeof Schema.Never, never>];
|
|
25
25
|
/**
|
|
@@ -58,7 +58,7 @@ declare const toEntity: <S extends {
|
|
|
58
58
|
}, E extends {
|
|
59
59
|
readonly _tag: string;
|
|
60
60
|
}, R>(machine: Machine<S, E, R, any, any, any, any>, options: ToEntityOptions) => Entity.Entity<string, Rpc.Rpc<"Send", Schema.Struct<{
|
|
61
|
-
event: Schema.Schema<E
|
|
62
|
-
}>, Schema.Schema<S
|
|
61
|
+
event: Schema.Schema<E>;
|
|
62
|
+
}>, Schema.Schema<S>, Schema.Never, never, never> | Rpc.Rpc<"GetState", Schema.Void, Schema.Schema<S>, Schema.Never, never, never>>;
|
|
63
63
|
//#endregion
|
|
64
64
|
export { EntityRpcs, ToEntityOptions, toEntity };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MissingSchemaError } from "../errors.js";
|
|
2
|
-
import { Entity } from "
|
|
3
|
-
import { Rpc } from "
|
|
2
|
+
import { Entity } from "effect/unstable/cluster";
|
|
3
|
+
import { Rpc } from "effect/unstable/rpc";
|
|
4
4
|
|
|
5
5
|
//#region src/cluster/to-entity.ts
|
|
6
6
|
/**
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,60 +1,45 @@
|
|
|
1
1
|
import { Schema } from "effect";
|
|
2
|
+
import * as effect_Cause0 from "effect/Cause";
|
|
2
3
|
|
|
3
4
|
//#region src/errors.d.ts
|
|
4
|
-
declare const DuplicateActorError_base: Schema.
|
|
5
|
-
readonly
|
|
6
|
-
}
|
|
7
|
-
actorId: typeof Schema.String;
|
|
8
|
-
}>;
|
|
5
|
+
declare const DuplicateActorError_base: Schema.ErrorClass<DuplicateActorError, Schema.TaggedStruct<"DuplicateActorError", {
|
|
6
|
+
readonly actorId: Schema.String;
|
|
7
|
+
}>, effect_Cause0.YieldableError>;
|
|
9
8
|
/** Attempted to spawn/restore actor with ID already in use */
|
|
10
9
|
declare class DuplicateActorError extends DuplicateActorError_base {}
|
|
11
|
-
declare const UnprovidedSlotsError_base: Schema.
|
|
12
|
-
readonly
|
|
13
|
-
}
|
|
14
|
-
slots: Schema.Array$<typeof Schema.String>;
|
|
15
|
-
}>;
|
|
10
|
+
declare const UnprovidedSlotsError_base: Schema.ErrorClass<UnprovidedSlotsError, Schema.TaggedStruct<"UnprovidedSlotsError", {
|
|
11
|
+
readonly slots: Schema.$Array<Schema.String>;
|
|
12
|
+
}>, effect_Cause0.YieldableError>;
|
|
16
13
|
/** Machine has unprovided effect slots */
|
|
17
14
|
declare class UnprovidedSlotsError extends UnprovidedSlotsError_base {}
|
|
18
|
-
declare const MissingSchemaError_base: Schema.
|
|
19
|
-
readonly
|
|
20
|
-
}
|
|
21
|
-
operation: typeof Schema.String;
|
|
22
|
-
}>;
|
|
15
|
+
declare const MissingSchemaError_base: Schema.ErrorClass<MissingSchemaError, Schema.TaggedStruct<"MissingSchemaError", {
|
|
16
|
+
readonly operation: Schema.String;
|
|
17
|
+
}>, effect_Cause0.YieldableError>;
|
|
23
18
|
/** Operation requires schemas attached to machine */
|
|
24
19
|
declare class MissingSchemaError extends MissingSchemaError_base {}
|
|
25
|
-
declare const InvalidSchemaError_base: Schema.
|
|
26
|
-
readonly _tag: Schema.tag<"InvalidSchemaError">;
|
|
27
|
-
}>;
|
|
20
|
+
declare const InvalidSchemaError_base: Schema.ErrorClass<InvalidSchemaError, Schema.TaggedStruct<"InvalidSchemaError", {}>, effect_Cause0.YieldableError>;
|
|
28
21
|
/** State/Event schema has no variants */
|
|
29
22
|
declare class InvalidSchemaError extends InvalidSchemaError_base {}
|
|
30
|
-
declare const MissingMatchHandlerError_base: Schema.
|
|
31
|
-
readonly
|
|
32
|
-
}
|
|
33
|
-
tag: typeof Schema.String;
|
|
34
|
-
}>;
|
|
23
|
+
declare const MissingMatchHandlerError_base: Schema.ErrorClass<MissingMatchHandlerError, Schema.TaggedStruct<"MissingMatchHandlerError", {
|
|
24
|
+
readonly tag: Schema.String;
|
|
25
|
+
}>, effect_Cause0.YieldableError>;
|
|
35
26
|
/** $match called with missing handler for tag */
|
|
36
27
|
declare class MissingMatchHandlerError extends MissingMatchHandlerError_base {}
|
|
37
|
-
declare const SlotProvisionError_base: Schema.
|
|
38
|
-
readonly
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
slotType: Schema.Literal<["guard", "effect"]>;
|
|
42
|
-
}>;
|
|
28
|
+
declare const SlotProvisionError_base: Schema.ErrorClass<SlotProvisionError, Schema.TaggedStruct<"SlotProvisionError", {
|
|
29
|
+
readonly slotName: Schema.String;
|
|
30
|
+
readonly slotType: Schema.Literals<readonly ["guard", "effect"]>;
|
|
31
|
+
}>, effect_Cause0.YieldableError>;
|
|
43
32
|
/** Slot handler not found at runtime (internal error) */
|
|
44
33
|
declare class SlotProvisionError extends SlotProvisionError_base {}
|
|
45
|
-
declare const ProvisionValidationError_base: Schema.
|
|
46
|
-
readonly
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
extra: Schema.Array$<typeof Schema.String>;
|
|
50
|
-
}>;
|
|
34
|
+
declare const ProvisionValidationError_base: Schema.ErrorClass<ProvisionValidationError, Schema.TaggedStruct<"ProvisionValidationError", {
|
|
35
|
+
readonly missing: Schema.$Array<Schema.String>;
|
|
36
|
+
readonly extra: Schema.$Array<Schema.String>;
|
|
37
|
+
}>, effect_Cause0.YieldableError>;
|
|
51
38
|
/** Machine.build() validation failed - missing or extra handlers */
|
|
52
39
|
declare class ProvisionValidationError extends ProvisionValidationError_base {}
|
|
53
|
-
declare const AssertionError_base: Schema.
|
|
54
|
-
readonly
|
|
55
|
-
}
|
|
56
|
-
message: typeof Schema.String;
|
|
57
|
-
}>;
|
|
40
|
+
declare const AssertionError_base: Schema.ErrorClass<AssertionError, Schema.TaggedStruct<"AssertionError", {
|
|
41
|
+
readonly message: Schema.String;
|
|
42
|
+
}>, effect_Cause0.YieldableError>;
|
|
58
43
|
/** Assertion failed in testing utilities */
|
|
59
44
|
declare class AssertionError extends AssertionError_base {}
|
|
60
45
|
//#endregion
|
package/dist/errors.js
CHANGED
|
@@ -4,7 +4,7 @@ import { Schema } from "effect";
|
|
|
4
4
|
/**
|
|
5
5
|
* Typed error classes for effect-machine.
|
|
6
6
|
*
|
|
7
|
-
* All errors extend Schema.
|
|
7
|
+
* All errors extend Schema.TaggedErrorClassClass for:
|
|
8
8
|
* - Type-safe catching via Effect.catchTag
|
|
9
9
|
* - Serialization support
|
|
10
10
|
* - Composable error handling
|
|
@@ -12,27 +12,27 @@ import { Schema } from "effect";
|
|
|
12
12
|
* @module
|
|
13
13
|
*/
|
|
14
14
|
/** Attempted to spawn/restore actor with ID already in use */
|
|
15
|
-
var DuplicateActorError = class extends Schema.
|
|
15
|
+
var DuplicateActorError = class extends Schema.TaggedErrorClass()("DuplicateActorError", { actorId: Schema.String }) {};
|
|
16
16
|
/** Machine has unprovided effect slots */
|
|
17
|
-
var UnprovidedSlotsError = class extends Schema.
|
|
17
|
+
var UnprovidedSlotsError = class extends Schema.TaggedErrorClass()("UnprovidedSlotsError", { slots: Schema.Array(Schema.String) }) {};
|
|
18
18
|
/** Operation requires schemas attached to machine */
|
|
19
|
-
var MissingSchemaError = class extends Schema.
|
|
19
|
+
var MissingSchemaError = class extends Schema.TaggedErrorClass()("MissingSchemaError", { operation: Schema.String }) {};
|
|
20
20
|
/** State/Event schema has no variants */
|
|
21
|
-
var InvalidSchemaError = class extends Schema.
|
|
21
|
+
var InvalidSchemaError = class extends Schema.TaggedErrorClass()("InvalidSchemaError", {}) {};
|
|
22
22
|
/** $match called with missing handler for tag */
|
|
23
|
-
var MissingMatchHandlerError = class extends Schema.
|
|
23
|
+
var MissingMatchHandlerError = class extends Schema.TaggedErrorClass()("MissingMatchHandlerError", { tag: Schema.String }) {};
|
|
24
24
|
/** Slot handler not found at runtime (internal error) */
|
|
25
|
-
var SlotProvisionError = class extends Schema.
|
|
25
|
+
var SlotProvisionError = class extends Schema.TaggedErrorClass()("SlotProvisionError", {
|
|
26
26
|
slotName: Schema.String,
|
|
27
|
-
slotType: Schema.
|
|
27
|
+
slotType: Schema.Literals(["guard", "effect"])
|
|
28
28
|
}) {};
|
|
29
29
|
/** Machine.build() validation failed - missing or extra handlers */
|
|
30
|
-
var ProvisionValidationError = class extends Schema.
|
|
30
|
+
var ProvisionValidationError = class extends Schema.TaggedErrorClass()("ProvisionValidationError", {
|
|
31
31
|
missing: Schema.Array(Schema.String),
|
|
32
32
|
extra: Schema.Array(Schema.String)
|
|
33
33
|
}) {};
|
|
34
34
|
/** Assertion failed in testing utilities */
|
|
35
|
-
var AssertionError = class extends Schema.
|
|
35
|
+
var AssertionError = class extends Schema.TaggedErrorClass()("AssertionError", { message: Schema.String }) {};
|
|
36
36
|
|
|
37
37
|
//#endregion
|
|
38
38
|
export { AssertionError, DuplicateActorError, InvalidSchemaError, MissingMatchHandlerError, MissingSchemaError, ProvisionValidationError, SlotProvisionError, UnprovidedSlotsError };
|
package/dist/inspection.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Schema, ServiceMap } from "effect";
|
|
2
2
|
|
|
3
3
|
//#region src/inspection.d.ts
|
|
4
4
|
/**
|
|
5
5
|
* Resolve a type param: if it's a Schema, extract `.Type`; otherwise use as-is.
|
|
6
6
|
*/
|
|
7
|
-
type ResolveType<T> = T extends Schema.Schema<infer A
|
|
7
|
+
type ResolveType<T> = T extends Schema.Schema<infer A> ? A : T;
|
|
8
8
|
/**
|
|
9
9
|
* Event emitted when an actor is spawned
|
|
10
10
|
*/
|
|
@@ -91,7 +91,7 @@ interface Inspector<S, E> {
|
|
|
91
91
|
* Inspector service tag - optional service for machine introspection
|
|
92
92
|
* Uses `any` types to allow variance flexibility when providing the service
|
|
93
93
|
*/
|
|
94
|
-
declare const Inspector:
|
|
94
|
+
declare const Inspector: ServiceMap.Service<Inspector<any, any>, Inspector<any, any>>;
|
|
95
95
|
/**
|
|
96
96
|
* Create an inspector from a callback function.
|
|
97
97
|
*
|
package/dist/inspection.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ServiceMap } from "effect";
|
|
2
2
|
|
|
3
3
|
//#region src/inspection.ts
|
|
4
4
|
/**
|
|
5
5
|
* Inspector service tag - optional service for machine introspection
|
|
6
6
|
* Uses `any` types to allow variance flexibility when providing the service
|
|
7
7
|
*/
|
|
8
|
-
const Inspector =
|
|
8
|
+
const Inspector = ServiceMap.Service("@effect/machine/Inspector");
|
|
9
9
|
/**
|
|
10
10
|
* Create an inspector from a callback function.
|
|
11
11
|
*
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { Brand } from "effect";
|
|
2
2
|
|
|
3
3
|
//#region src/internal/brands.d.ts
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
type StateTypeId = typeof StateTypeId;
|
|
7
|
-
type EventTypeId = typeof EventTypeId;
|
|
4
|
+
type StateTypeId = "effect-machine/StateTypeId";
|
|
5
|
+
type EventTypeId = "effect-machine/EventTypeId";
|
|
8
6
|
interface StateBrand extends Brand.Brand<StateTypeId> {}
|
|
9
7
|
interface EventBrand extends Brand.Brand<EventTypeId> {}
|
|
10
8
|
type BrandedState = {
|
|
@@ -13,8 +11,7 @@ type BrandedState = {
|
|
|
13
11
|
type BrandedEvent = {
|
|
14
12
|
readonly _tag: string;
|
|
15
13
|
} & EventBrand;
|
|
16
|
-
|
|
17
|
-
type SchemaIdTypeId = typeof SchemaIdTypeId;
|
|
14
|
+
type SchemaIdTypeId = "effect-machine/SchemaIdTypeId";
|
|
18
15
|
/**
|
|
19
16
|
* Brand that captures the schema definition type D.
|
|
20
17
|
* Two schemas with identical definition shapes will have compatible brands.
|
|
@@ -8,7 +8,11 @@ import { Clock, Effect } from "effect";
|
|
|
8
8
|
const emitWithTimestamp = Effect.fn("effect-machine.emitWithTimestamp")(function* (inspector, makeEvent) {
|
|
9
9
|
if (inspector === void 0) return;
|
|
10
10
|
const timestamp = yield* Clock.currentTimeMillis;
|
|
11
|
-
yield* Effect.
|
|
11
|
+
yield* Effect.sync(() => {
|
|
12
|
+
try {
|
|
13
|
+
inspector.onInspect(makeEvent(timestamp));
|
|
14
|
+
} catch {}
|
|
15
|
+
});
|
|
12
16
|
});
|
|
13
17
|
|
|
14
18
|
//#endregion
|
|
@@ -102,7 +102,7 @@ declare const processEventCore: <S extends {
|
|
|
102
102
|
}, E extends {
|
|
103
103
|
readonly _tag: string;
|
|
104
104
|
}, R, GD extends GuardsDef, EFD extends EffectsDef>(machine: Machine<S, E, R, Record<string, never>, Record<string, never>, GD, EFD>, currentState: S, event: E, self: MachineRef<E>, stateScopeRef: {
|
|
105
|
-
current: Scope.
|
|
105
|
+
current: Scope.Closeable;
|
|
106
106
|
}, system: ActorSystem, hooks?: ProcessEventHooks<S, E> | undefined) => Effect.Effect<{
|
|
107
107
|
newState: S;
|
|
108
108
|
previousState: S;
|
|
@@ -119,7 +119,7 @@ declare const runSpawnEffects: <S extends {
|
|
|
119
119
|
readonly _tag: string;
|
|
120
120
|
}, E extends {
|
|
121
121
|
readonly _tag: string;
|
|
122
|
-
}, R, GD extends GuardsDef, EFD extends EffectsDef>(machine: Machine<S, E, R, Record<string, never>, Record<string, never>, GD, EFD>, state: S, event: E, self: MachineRef<E>, stateScope: Scope.
|
|
122
|
+
}, R, GD extends GuardsDef, EFD extends EffectsDef>(machine: Machine<S, E, R, Record<string, never>, Record<string, never>, GD, EFD>, state: S, event: E, self: MachineRef<E>, stateScope: Scope.Closeable, system: ActorSystem, onError?: ((info: ProcessEventError<S, E>) => Effect.Effect<void>) | undefined) => Effect.Effect<void, never, Exclude<Exclude<R, MachineContext<S, E, MachineRef<E>>>, Scope.Scope>>;
|
|
123
123
|
/**
|
|
124
124
|
* Resolve which transition should fire for a given state and event.
|
|
125
125
|
* Uses indexed O(1) lookup. First matching transition wins.
|
|
@@ -77,8 +77,8 @@ const executeTransition = Effect.fn("effect-machine.executeTransition")(function
|
|
|
77
77
|
* @internal
|
|
78
78
|
*/
|
|
79
79
|
const processEventCore = Effect.fn("effect-machine.processEventCore")(function* (machine, currentState, event, self, stateScopeRef, system, hooks) {
|
|
80
|
-
const result = yield* executeTransition(machine, currentState, event, self, system).pipe(Effect.
|
|
81
|
-
if (Cause.
|
|
80
|
+
const result = yield* executeTransition(machine, currentState, event, self, system).pipe(Effect.catchCause((cause) => {
|
|
81
|
+
if (Cause.hasInterruptsOnly(cause)) return Effect.interrupt;
|
|
82
82
|
const onError = hooks?.onError;
|
|
83
83
|
if (onError === void 0) return Effect.failCause(cause).pipe(Effect.orDie);
|
|
84
84
|
return onError({
|
|
@@ -86,7 +86,7 @@ const processEventCore = Effect.fn("effect-machine.processEventCore")(function*
|
|
|
86
86
|
state: currentState,
|
|
87
87
|
event,
|
|
88
88
|
cause
|
|
89
|
-
}).pipe(Effect.
|
|
89
|
+
}).pipe(Effect.andThen(Effect.failCause(cause).pipe(Effect.orDie)));
|
|
90
90
|
}));
|
|
91
91
|
if (!result.transitioned) return {
|
|
92
92
|
newState: currentState,
|
|
@@ -134,15 +134,15 @@ const runSpawnEffects = Effect.fn("effect-machine.runSpawnEffects")(function* (m
|
|
|
134
134
|
self,
|
|
135
135
|
effects: effectSlots,
|
|
136
136
|
system
|
|
137
|
-
}).pipe(Effect.provideService(machine.Context, ctx), Effect.
|
|
138
|
-
if (Cause.
|
|
137
|
+
}).pipe(Effect.provideService(machine.Context, ctx), Effect.catchCause((cause) => {
|
|
138
|
+
if (Cause.hasInterruptsOnly(cause)) return Effect.interrupt;
|
|
139
139
|
if (reportError === void 0) return Effect.failCause(cause).pipe(Effect.orDie);
|
|
140
140
|
return reportError({
|
|
141
141
|
phase: "spawn",
|
|
142
142
|
state,
|
|
143
143
|
event,
|
|
144
144
|
cause
|
|
145
|
-
}).pipe(Effect.
|
|
145
|
+
}).pipe(Effect.andThen(Effect.failCause(cause).pipe(Effect.orDie)));
|
|
146
146
|
}));
|
|
147
147
|
yield* Effect.forkScoped(effect).pipe(Effect.provideService(Scope.Scope, stateScope));
|
|
148
148
|
}
|
package/dist/internal/utils.js
CHANGED
|
@@ -2,6 +2,10 @@ import { Effect, Stream } from "effect";
|
|
|
2
2
|
|
|
3
3
|
//#region src/internal/utils.ts
|
|
4
4
|
/**
|
|
5
|
+
* Internal utilities for effect-machine.
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
5
9
|
* Internal event tags used for lifecycle effect contexts.
|
|
6
10
|
* Prefixed with $ to distinguish from user events.
|
|
7
11
|
* @internal
|
|
@@ -25,7 +29,7 @@ const getTag = (constructorOrValue) => {
|
|
|
25
29
|
}
|
|
26
30
|
};
|
|
27
31
|
/** Check if a value is an Effect */
|
|
28
|
-
const isEffect =
|
|
32
|
+
const isEffect = Effect.isEffect;
|
|
29
33
|
/**
|
|
30
34
|
* Stub ActorSystem that dies on any method call.
|
|
31
35
|
* Used in contexts where spawning/system access isn't supported
|
package/dist/machine.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { DuplicateActorError } from "./errors.js";
|
|
|
7
7
|
import { findTransitions } from "./internal/transition.js";
|
|
8
8
|
import "./persistence/index.js";
|
|
9
9
|
import { ActorRef, ActorSystem } from "./actor.js";
|
|
10
|
-
import { Cause,
|
|
10
|
+
import { Cause, Effect, Schedule, Schema, Scope, ServiceMap } from "effect";
|
|
11
11
|
|
|
12
12
|
//#region src/machine.d.ts
|
|
13
13
|
declare namespace machine_d_exports {
|
|
@@ -159,13 +159,13 @@ declare class Machine<State, Event, R = never, _SD extends Record<string, Schema
|
|
|
159
159
|
guards: GuardSlots<GD>;
|
|
160
160
|
effects: EffectSlots<EFD>;
|
|
161
161
|
};
|
|
162
|
-
readonly stateSchema?: Schema.Schema<State
|
|
163
|
-
readonly eventSchema?: Schema.Schema<Event
|
|
162
|
+
readonly stateSchema?: Schema.Schema<State>;
|
|
163
|
+
readonly eventSchema?: Schema.Schema<Event>;
|
|
164
164
|
/**
|
|
165
165
|
* Context tag for accessing machine state/event/self in slot handlers.
|
|
166
166
|
* Uses shared module-level tag for all machines.
|
|
167
167
|
*/
|
|
168
|
-
readonly Context:
|
|
168
|
+
readonly Context: ServiceMap.Service<MachineContext<State, Event, MachineRef<Event>>, MachineContext<State, Event, MachineRef<Event>>>;
|
|
169
169
|
get transitions(): ReadonlyArray<Transition<State, Event, GD, EFD, R>>;
|
|
170
170
|
get spawnEffects(): ReadonlyArray<SpawnEffect<State, Event, EFD, R>>;
|
|
171
171
|
get backgroundEffects(): ReadonlyArray<BackgroundEffect<State, Event, EFD, R>>;
|
|
@@ -173,7 +173,7 @@ declare class Machine<State, Event, R = never, _SD extends Record<string, Schema
|
|
|
173
173
|
get guardsSchema(): GuardsSchema<GD> | undefined;
|
|
174
174
|
get effectsSchema(): EffectsSchema<EFD> | undefined;
|
|
175
175
|
/** @internal */
|
|
176
|
-
constructor(initial: State, stateSchema?: Schema.Schema<State
|
|
176
|
+
constructor(initial: State, stateSchema?: Schema.Schema<State>, eventSchema?: Schema.Schema<Event>, guardsSchema?: GuardsSchema<GD>, effectsSchema?: EffectsSchema<EFD>);
|
|
177
177
|
/** Register transition for a single state */
|
|
178
178
|
on<NS extends VariantsUnion<_SD> & BrandedState, NE extends VariantsUnion<_ED> & BrandedEvent, RS extends VariantsUnion<_SD> & BrandedState>(state: TaggedOrConstructor<NS>, event: TaggedOrConstructor<NE>, handler: TransitionHandler<NS, NE, RS, GD, EFD, never>): Machine<State, Event, R, _SD, _ED, GD, EFD>;
|
|
179
179
|
/** Register transition for multiple states (handler receives union of state types) */
|
package/dist/machine.js
CHANGED
|
@@ -98,7 +98,9 @@ var Machine = class Machine {
|
|
|
98
98
|
this.stateSchema = stateSchema;
|
|
99
99
|
this.eventSchema = eventSchema;
|
|
100
100
|
this._slots = {
|
|
101
|
-
guards: this._guardsSchema !== void 0 ? this._guardsSchema._createSlots((name, params) => Effect.flatMap(Effect.
|
|
101
|
+
guards: this._guardsSchema !== void 0 ? this._guardsSchema._createSlots((name, params) => Effect.flatMap(Effect.serviceOption(this.Context), (maybeCtx) => {
|
|
102
|
+
if (Option.isNone(maybeCtx)) return Effect.die("MachineContext not available");
|
|
103
|
+
const ctx = maybeCtx.value;
|
|
102
104
|
const handler = this._guardHandlers.get(name);
|
|
103
105
|
if (handler === void 0) return Effect.die(new SlotProvisionError({
|
|
104
106
|
slotName: name,
|
|
@@ -107,7 +109,9 @@ var Machine = class Machine {
|
|
|
107
109
|
const result = handler(params, ctx);
|
|
108
110
|
return typeof result === "boolean" ? Effect.succeed(result) : result;
|
|
109
111
|
})) : {},
|
|
110
|
-
effects: this._effectsSchema !== void 0 ? this._effectsSchema._createSlots((name, params) => Effect.flatMap(Effect.
|
|
112
|
+
effects: this._effectsSchema !== void 0 ? this._effectsSchema._createSlots((name, params) => Effect.flatMap(Effect.serviceOption(this.Context), (maybeCtx) => {
|
|
113
|
+
if (Option.isNone(maybeCtx)) return Effect.die("MachineContext not available");
|
|
114
|
+
const ctx = maybeCtx.value;
|
|
111
115
|
const handler = this._effectHandlers.get(name);
|
|
112
116
|
if (handler === void 0) return Effect.die(new SlotProvisionError({
|
|
113
117
|
slotName: name,
|
|
@@ -194,14 +198,14 @@ var Machine = class Machine {
|
|
|
194
198
|
const exit = yield* Effect.exit(run(ctx));
|
|
195
199
|
if (Exit.isSuccess(exit)) {
|
|
196
200
|
yield* ctx.self.send(options.onSuccess(exit.value, ctx));
|
|
197
|
-
yield* Effect.yieldNow
|
|
201
|
+
yield* Effect.yieldNow;
|
|
198
202
|
return;
|
|
199
203
|
}
|
|
200
204
|
const cause = exit.cause;
|
|
201
|
-
if (Cause.
|
|
205
|
+
if (Cause.hasInterruptsOnly(cause)) return;
|
|
202
206
|
if (options.onFailure !== void 0) {
|
|
203
207
|
yield* ctx.self.send(options.onFailure(cause, ctx));
|
|
204
|
-
yield* Effect.yieldNow
|
|
208
|
+
yield* Effect.yieldNow;
|
|
205
209
|
return;
|
|
206
210
|
}
|
|
207
211
|
return yield* Effect.failCause(cause).pipe(Effect.orDie);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { DuplicateActorError } from "../errors.js";
|
|
2
2
|
import { PersistentActorRef } from "./persistent-actor.js";
|
|
3
|
-
import {
|
|
3
|
+
import { Effect, Option, Schema, ServiceMap } from "effect";
|
|
4
|
+
import * as effect_Cause0 from "effect/Cause";
|
|
4
5
|
|
|
5
6
|
//#region src/persistence/adapter.d.ts
|
|
6
7
|
/**
|
|
@@ -64,20 +65,20 @@ interface PersistenceAdapter {
|
|
|
64
65
|
* Save a snapshot of actor state.
|
|
65
66
|
* Implementations should use optimistic locking — fail if version mismatch.
|
|
66
67
|
*/
|
|
67
|
-
readonly saveSnapshot: <S
|
|
68
|
+
readonly saveSnapshot: <S>(id: string, snapshot: Snapshot<S>, schema: Schema.Codec<S, unknown, never, never>) => Effect.Effect<void, PersistenceError | VersionConflictError>;
|
|
68
69
|
/**
|
|
69
70
|
* Load the latest snapshot for an actor.
|
|
70
71
|
* Returns None if no snapshot exists.
|
|
71
72
|
*/
|
|
72
|
-
readonly loadSnapshot: <S
|
|
73
|
+
readonly loadSnapshot: <S>(id: string, schema: Schema.Codec<S, unknown, never, never>) => Effect.Effect<Option.Option<Snapshot<S>>, PersistenceError>;
|
|
73
74
|
/**
|
|
74
75
|
* Append an event to the actor's event journal.
|
|
75
76
|
*/
|
|
76
|
-
readonly appendEvent: <E
|
|
77
|
+
readonly appendEvent: <E>(id: string, event: PersistedEvent<E>, schema: Schema.Codec<E, unknown, never, never>) => Effect.Effect<void, PersistenceError>;
|
|
77
78
|
/**
|
|
78
79
|
* Load events from the journal, optionally after a specific version.
|
|
79
80
|
*/
|
|
80
|
-
readonly loadEvents: <E
|
|
81
|
+
readonly loadEvents: <E>(id: string, schema: Schema.Codec<E, unknown, never, never>, afterVersion?: number) => Effect.Effect<ReadonlyArray<PersistedEvent<E>>, PersistenceError>;
|
|
81
82
|
/**
|
|
82
83
|
* Delete all persisted data for an actor (snapshot + events).
|
|
83
84
|
*/
|
|
@@ -106,30 +107,26 @@ interface PersistenceAdapter {
|
|
|
106
107
|
*/
|
|
107
108
|
readonly loadMetadata?: (id: string) => Effect.Effect<Option.Option<ActorMetadata>, PersistenceError>;
|
|
108
109
|
}
|
|
109
|
-
declare const PersistenceError_base: Schema.
|
|
110
|
-
readonly
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
message: Schema.optional<typeof Schema.String>;
|
|
116
|
-
}>;
|
|
110
|
+
declare const PersistenceError_base: Schema.ErrorClass<PersistenceError, Schema.TaggedStruct<"PersistenceError", {
|
|
111
|
+
readonly operation: Schema.String;
|
|
112
|
+
readonly actorId: Schema.String;
|
|
113
|
+
readonly cause: Schema.optional<Schema.Unknown>;
|
|
114
|
+
readonly message: Schema.optional<Schema.String>;
|
|
115
|
+
}>, effect_Cause0.YieldableError>;
|
|
117
116
|
/**
|
|
118
117
|
* Error type for persistence operations
|
|
119
118
|
*/
|
|
120
119
|
declare class PersistenceError extends PersistenceError_base {}
|
|
121
|
-
declare const VersionConflictError_base: Schema.
|
|
122
|
-
readonly
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
actualVersion: typeof Schema.Number;
|
|
127
|
-
}>;
|
|
120
|
+
declare const VersionConflictError_base: Schema.ErrorClass<VersionConflictError, Schema.TaggedStruct<"VersionConflictError", {
|
|
121
|
+
readonly actorId: Schema.String;
|
|
122
|
+
readonly expectedVersion: Schema.Number;
|
|
123
|
+
readonly actualVersion: Schema.Number;
|
|
124
|
+
}>, effect_Cause0.YieldableError>;
|
|
128
125
|
/**
|
|
129
126
|
* Version conflict error — snapshot version doesn't match expected
|
|
130
127
|
*/
|
|
131
128
|
declare class VersionConflictError extends VersionConflictError_base {}
|
|
132
|
-
declare const PersistenceAdapterTag_base:
|
|
129
|
+
declare const PersistenceAdapterTag_base: ServiceMap.ServiceClass<PersistenceAdapterTag, "effect-machine/src/persistence/adapter/PersistenceAdapterTag", PersistenceAdapter>;
|
|
133
130
|
/**
|
|
134
131
|
* PersistenceAdapter service tag
|
|
135
132
|
*/
|