effect-machine 0.6.0 → 0.7.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.
Files changed (68) hide show
  1. package/dist/actor.d.ts +2 -2
  2. package/dist/actor.js +12 -14
  3. package/dist/cluster/entity-machine.d.ts +2 -2
  4. package/dist/cluster/entity-machine.js +1 -1
  5. package/dist/cluster/to-entity.d.ts +5 -5
  6. package/dist/cluster/to-entity.js +2 -2
  7. package/dist/errors.d.ts +25 -40
  8. package/dist/errors.js +10 -10
  9. package/dist/inspection.d.ts +3 -3
  10. package/dist/inspection.js +2 -2
  11. package/dist/internal/brands.d.ts +3 -6
  12. package/dist/internal/inspection.js +5 -1
  13. package/dist/internal/transition.d.ts +2 -2
  14. package/dist/internal/transition.js +6 -6
  15. package/dist/internal/utils.js +5 -1
  16. package/dist/machine.d.ts +5 -5
  17. package/dist/machine.js +9 -5
  18. package/dist/persistence/adapter.d.ts +18 -21
  19. package/dist/persistence/adapter.js +4 -4
  20. package/dist/persistence/adapters/in-memory.js +4 -4
  21. package/dist/persistence/persistent-actor.js +9 -9
  22. package/dist/persistence/persistent-machine.d.ts +3 -3
  23. package/dist/schema.d.ts +4 -4
  24. package/dist/schema.js +2 -2
  25. package/dist/slot.d.ts +3 -3
  26. package/dist/slot.js +2 -2
  27. package/dist-v3/_virtual/_rolldown/runtime.js +18 -0
  28. package/dist-v3/actor.d.ts +291 -0
  29. package/dist-v3/actor.js +459 -0
  30. package/dist-v3/cluster/entity-machine.d.ts +90 -0
  31. package/dist-v3/cluster/entity-machine.js +80 -0
  32. package/dist-v3/cluster/index.d.ts +3 -0
  33. package/dist-v3/cluster/index.js +4 -0
  34. package/dist-v3/cluster/to-entity.d.ts +61 -0
  35. package/dist-v3/cluster/to-entity.js +53 -0
  36. package/dist-v3/errors.d.ts +27 -0
  37. package/dist-v3/errors.js +38 -0
  38. package/dist-v3/index.d.ts +13 -0
  39. package/dist-v3/index.js +14 -0
  40. package/dist-v3/inspection.d.ts +125 -0
  41. package/dist-v3/inspection.js +50 -0
  42. package/dist-v3/internal/brands.d.ts +40 -0
  43. package/dist-v3/internal/brands.js +0 -0
  44. package/dist-v3/internal/inspection.d.ts +11 -0
  45. package/dist-v3/internal/inspection.js +15 -0
  46. package/dist-v3/internal/transition.d.ts +160 -0
  47. package/dist-v3/internal/transition.js +238 -0
  48. package/dist-v3/internal/utils.d.ts +60 -0
  49. package/dist-v3/internal/utils.js +51 -0
  50. package/dist-v3/machine.d.ts +278 -0
  51. package/dist-v3/machine.js +317 -0
  52. package/dist-v3/persistence/adapter.d.ts +125 -0
  53. package/dist-v3/persistence/adapter.js +27 -0
  54. package/dist-v3/persistence/adapters/in-memory.d.ts +32 -0
  55. package/dist-v3/persistence/adapters/in-memory.js +176 -0
  56. package/dist-v3/persistence/index.d.ts +5 -0
  57. package/dist-v3/persistence/index.js +6 -0
  58. package/dist-v3/persistence/persistent-actor.d.ts +49 -0
  59. package/dist-v3/persistence/persistent-actor.js +367 -0
  60. package/dist-v3/persistence/persistent-machine.d.ts +105 -0
  61. package/dist-v3/persistence/persistent-machine.js +24 -0
  62. package/dist-v3/schema.d.ts +141 -0
  63. package/dist-v3/schema.js +165 -0
  64. package/dist-v3/slot.d.ts +130 -0
  65. package/dist-v3/slot.js +99 -0
  66. package/dist-v3/testing.d.ts +136 -0
  67. package/dist-v3/testing.js +138 -0
  68. package/package.json +29 -21
@@ -1,10 +1,10 @@
1
- import { Context, Schema } from "effect";
1
+ import { Schema, ServiceMap } from "effect";
2
2
 
3
3
  //#region src/persistence/adapter.ts
4
4
  /**
5
5
  * Error type for persistence operations
6
6
  */
7
- var PersistenceError = class extends Schema.TaggedError()("PersistenceError", {
7
+ var PersistenceError = class extends Schema.TaggedErrorClass()("PersistenceError", {
8
8
  operation: Schema.String,
9
9
  actorId: Schema.String,
10
10
  cause: Schema.optional(Schema.Unknown),
@@ -13,7 +13,7 @@ var PersistenceError = class extends Schema.TaggedError()("PersistenceError", {
13
13
  /**
14
14
  * Version conflict error — snapshot version doesn't match expected
15
15
  */
16
- var VersionConflictError = class extends Schema.TaggedError()("VersionConflictError", {
16
+ var VersionConflictError = class extends Schema.TaggedErrorClass()("VersionConflictError", {
17
17
  actorId: Schema.String,
18
18
  expectedVersion: Schema.Number,
19
19
  actualVersion: Schema.Number
@@ -21,7 +21,7 @@ var VersionConflictError = class extends Schema.TaggedError()("VersionConflictEr
21
21
  /**
22
22
  * PersistenceAdapter service tag
23
23
  */
24
- var PersistenceAdapterTag = class extends Context.Tag("effect-machine/src/persistence/adapter/PersistenceAdapterTag")() {};
24
+ var PersistenceAdapterTag = class extends ServiceMap.Service()("effect-machine/src/persistence/adapter/PersistenceAdapterTag") {};
25
25
 
26
26
  //#endregion
27
27
  export { PersistenceAdapterTag, PersistenceError, VersionConflictError };
@@ -42,7 +42,7 @@ const make = Effect.gen(function* () {
42
42
  actualVersion: snapshot.version
43
43
  });
44
44
  }
45
- const encoded = yield* Schema.encode(schema)(snapshot.state).pipe(Effect.mapError((cause) => new PersistenceError({
45
+ const encoded = yield* Schema.encodeEffect(schema)(snapshot.state).pipe(Effect.mapError((cause) => new PersistenceError({
46
46
  operation: "saveSnapshot",
47
47
  actorId: id,
48
48
  cause,
@@ -61,7 +61,7 @@ const make = Effect.gen(function* () {
61
61
  const actorStorage = yield* getOrCreateStorage(id);
62
62
  if (Option.isNone(actorStorage.snapshot)) return Option.none();
63
63
  const stored = actorStorage.snapshot.value;
64
- const decoded = yield* Schema.decode(schema)(stored.data).pipe(Effect.mapError((cause) => new PersistenceError({
64
+ const decoded = yield* Schema.decodeEffect(schema)(stored.data).pipe(Effect.mapError((cause) => new PersistenceError({
65
65
  operation: "loadSnapshot",
66
66
  actorId: id,
67
67
  cause,
@@ -75,7 +75,7 @@ const make = Effect.gen(function* () {
75
75
  }),
76
76
  appendEvent: Effect.fn("effect-machine.persistence.inMemory.appendEvent")(function* (id, event, schema) {
77
77
  yield* getOrCreateStorage(id);
78
- const encoded = yield* Schema.encode(schema)(event.event).pipe(Effect.mapError((cause) => new PersistenceError({
78
+ const encoded = yield* Schema.encodeEffect(schema)(event.event).pipe(Effect.mapError((cause) => new PersistenceError({
79
79
  operation: "appendEvent",
80
80
  actorId: id,
81
81
  cause,
@@ -95,7 +95,7 @@ const make = Effect.gen(function* () {
95
95
  const decoded = [];
96
96
  for (const stored of actorStorage.events) {
97
97
  if (afterVersion !== void 0 && stored.version <= afterVersion) continue;
98
- const event = yield* Schema.decode(schema)(stored.data).pipe(Effect.mapError((cause) => new PersistenceError({
98
+ const event = yield* Schema.decodeEffect(schema)(stored.data).pipe(Effect.mapError((cause) => new PersistenceError({
99
99
  operation: "loadEvents",
100
100
  actorId: id,
101
101
  cause,
@@ -139,10 +139,10 @@ const createPersistentActor = Effect.fn("effect-machine.persistentActor.spawn")(
139
139
  }));
140
140
  const snapshotEnabledRef = yield* Ref.make(true);
141
141
  const persistenceQueue = yield* Queue.unbounded();
142
- const persistenceFiber = yield* Effect.forkDaemon(persistenceWorker(persistenceQueue));
142
+ const persistenceFiber = yield* Effect.forkDetach(persistenceWorker(persistenceQueue));
143
143
  yield* Queue.offer(persistenceQueue, saveMetadata(id, resolvedInitial, initialVersion, createdAt, persistence, adapter));
144
144
  const snapshotQueue = yield* Queue.unbounded();
145
- const snapshotFiber = yield* Effect.forkDaemon(snapshotWorker(id, persistence, adapter, snapshotQueue, snapshotEnabledRef));
145
+ const snapshotFiber = yield* Effect.forkDetach(snapshotWorker(id, persistence, adapter, snapshotQueue, snapshotEnabledRef));
146
146
  const backgroundFibers = [];
147
147
  const initEvent = { _tag: INTERNAL_INIT_EVENT };
148
148
  const initCtx = {
@@ -153,7 +153,7 @@ const createPersistentActor = Effect.fn("effect-machine.persistentActor.spawn")(
153
153
  };
154
154
  const { effects: effectSlots } = typedMachine._slots;
155
155
  for (const bg of typedMachine.backgroundEffects) {
156
- const fiber = yield* Effect.forkDaemon(bg.handler({
156
+ const fiber = yield* Effect.forkDetach(bg.handler({
157
157
  state: resolvedInitial,
158
158
  event: initEvent,
159
159
  self,
@@ -178,7 +178,7 @@ const createPersistentActor = Effect.fn("effect-machine.persistentActor.spawn")(
178
178
  }));
179
179
  return buildPersistentActorRef(id, persistentMachine, stateRef, versionRef, eventQueue, stoppedRef, listeners, Ref.set(stoppedRef, true).pipe(Effect.withSpan("effect-machine.persistentActor.stop"), Effect.asVoid), adapter, system, childrenMap);
180
180
  }
181
- const loopFiber = yield* Effect.forkDaemon(persistentEventLoop(id, persistentMachine, stateRef, versionRef, eventQueue, stoppedRef, self, listeners, adapter, createdAt, stateScopeRef, backgroundFibers, snapshotQueue, snapshotEnabledRef, persistenceQueue, snapshotFiber, persistenceFiber, inspector, system));
181
+ const loopFiber = yield* Effect.forkDetach(persistentEventLoop(id, persistentMachine, stateRef, versionRef, eventQueue, stoppedRef, self, listeners, adapter, createdAt, stateScopeRef, backgroundFibers, snapshotQueue, snapshotEnabledRef, persistenceQueue, snapshotFiber, persistenceFiber, inspector, system));
182
182
  return buildPersistentActorRef(id, persistentMachine, stateRef, versionRef, eventQueue, stoppedRef, listeners, Effect.gen(function* () {
183
183
  const finalState = yield* SubscriptionRef.get(stateRef);
184
184
  yield* emitWithTimestamp(inspector, (timestamp) => ({
@@ -250,7 +250,7 @@ const persistentEventLoop = Effect.fn("effect-machine.persistentActor.eventLoop"
250
250
  version: newVersion,
251
251
  timestamp: yield* now
252
252
  };
253
- const journalTask = adapter.appendEvent(id, persistedEvent, persistence.eventSchema).pipe(Effect.catchAll((e) => Effect.logWarning(`Failed to journal event for actor ${id}`, e)), Effect.asVoid);
253
+ const journalTask = adapter.appendEvent(id, persistedEvent, persistence.eventSchema).pipe(Effect.catchEager((e) => Effect.logWarning(`Failed to journal event for actor ${id}`, e)), Effect.asVoid);
254
254
  yield* Queue.offer(persistenceQueue, journalTask);
255
255
  }
256
256
  yield* Queue.offer(persistenceQueue, saveMetadata(id, result.newState, newVersion, createdAt, persistence, adapter));
@@ -306,11 +306,11 @@ const persistenceWorker = Effect.fn("effect-machine.persistentActor.persistenceW
306
306
  * Snapshot scheduler worker (runs in background).
307
307
  */
308
308
  const snapshotWorker = Effect.fn("effect-machine.persistentActor.snapshotWorker")(function* (id, persistence, adapter, queue, enabledRef) {
309
- const driver = yield* Schedule.driver(persistence.snapshotSchedule);
309
+ const step = yield* Schedule.toStep(persistence.snapshotSchedule);
310
310
  while (true) {
311
311
  const { state, version } = yield* Queue.take(queue);
312
312
  if (!(yield* Ref.get(enabledRef))) continue;
313
- if (!(yield* driver.next(state).pipe(Effect.match({
313
+ if (!(yield* step(yield* Clock.currentTimeMillis, state).pipe(Effect.match({
314
314
  onFailure: () => false,
315
315
  onSuccess: () => true
316
316
  })))) {
@@ -330,7 +330,7 @@ const saveSnapshot = Effect.fn("effect-machine.persistentActor.saveSnapshot")(fu
330
330
  version,
331
331
  timestamp: yield* now
332
332
  };
333
- yield* adapter.saveSnapshot(id, snapshot, persistence.stateSchema).pipe(Effect.catchAll((e) => Effect.logWarning(`Failed to save snapshot for actor ${id}`, e)));
333
+ yield* adapter.saveSnapshot(id, snapshot, persistence.stateSchema).pipe(Effect.catchEager((e) => Effect.logWarning(`Failed to save snapshot for actor ${id}`, e)));
334
334
  });
335
335
  /**
336
336
  * Save or update actor metadata if adapter supports registry.
@@ -347,7 +347,7 @@ const saveMetadata = Effect.fn("effect-machine.persistentActor.saveMetadata")(fu
347
347
  lastActivityAt,
348
348
  version,
349
349
  stateTag: state._tag
350
- }).pipe(Effect.catchAll((e) => Effect.logWarning(`Failed to save metadata for actor ${id}`, e)));
350
+ }).pipe(Effect.catchEager((e) => Effect.logWarning(`Failed to save metadata for actor ${id}`, e)));
351
351
  });
352
352
  /**
353
353
  * Restore an actor from persistence.
@@ -16,7 +16,7 @@ type BrandedEvent = {
16
16
  * Note: Schema types S and E should match the structural shape of the machine's
17
17
  * state and event types (without brands). The schemas don't know about brands.
18
18
  */
19
- interface PersistenceConfig<S, E, SSI = unknown, ESI = unknown> {
19
+ interface PersistenceConfig<S, E> {
20
20
  /**
21
21
  * Schedule controlling when snapshots are taken.
22
22
  * Input is the new state after each transition.
@@ -36,12 +36,12 @@ interface PersistenceConfig<S, E, SSI = unknown, ESI = unknown> {
36
36
  * Schema for serializing/deserializing state.
37
37
  * Always present at runtime (resolved from config or machine).
38
38
  */
39
- readonly stateSchema: Schema.Schema<S, SSI, never>;
39
+ readonly stateSchema: Schema.Codec<S, unknown, never, never>;
40
40
  /**
41
41
  * Schema for serializing/deserializing events.
42
42
  * Always present at runtime (resolved from config or machine).
43
43
  */
44
- readonly eventSchema: Schema.Schema<E, ESI, never>;
44
+ readonly eventSchema: Schema.Codec<E, unknown, never, never>;
45
45
  /**
46
46
  * User-provided identifier for the machine type.
47
47
  * Used for filtering actors in restoreAll.
package/dist/schema.d.ts CHANGED
@@ -36,8 +36,8 @@ type IsEmptyFields<Fields extends Schema.Struct.Fields> = keyof Fields extends n
36
36
  */
37
37
  type VariantConstructors<D extends Record<string, Schema.Struct.Fields>, Brand> = { readonly [K in keyof D & string]: IsEmptyFields<D[K]> extends true ? TaggedStructType<K, D[K]> & Brand & {
38
38
  readonly derive: (source: object) => TaggedStructType<K, D[K]> & Brand;
39
- } : ((args: Schema.Struct.Constructor<D[K]>) => TaggedStructType<K, D[K]> & Brand) & {
40
- readonly derive: (source: object, partial?: Partial<Schema.Struct.Constructor<D[K]>>) => TaggedStructType<K, D[K]> & Brand;
39
+ } : ((args: Schema.Struct.Type<D[K]>) => TaggedStructType<K, D[K]> & Brand) & {
40
+ readonly derive: (source: object, partial?: Partial<Schema.Struct.Type<D[K]>>) => TaggedStructType<K, D[K]> & Brand;
41
41
  readonly _tag: K;
42
42
  } };
43
43
  /**
@@ -78,14 +78,14 @@ interface MachineSchemaBase<D extends Record<string, Schema.Struct.Fields>, Bran
78
78
  * The D type parameter captures the definition, creating a unique brand
79
79
  * per distinct schema definition shape.
80
80
  */
81
- type MachineStateSchema<D extends Record<string, Schema.Struct.Fields>> = Schema.Schema<VariantsUnion<D> & FullStateBrand<D>, VariantsUnion<D>, never> & MachineSchemaBase<D, FullStateBrand<D>> & VariantConstructors<D, FullStateBrand<D>>;
81
+ type MachineStateSchema<D extends Record<string, Schema.Struct.Fields>> = Schema.Codec<VariantsUnion<D> & FullStateBrand<D>, unknown, never, never> & MachineSchemaBase<D, FullStateBrand<D>> & VariantConstructors<D, FullStateBrand<D>>;
82
82
  /**
83
83
  * Schema-first event definition (same structure as state, different brand)
84
84
  *
85
85
  * The D type parameter captures the definition, creating a unique brand
86
86
  * per distinct schema definition shape.
87
87
  */
88
- type MachineEventSchema<D extends Record<string, Schema.Struct.Fields>> = Schema.Schema<VariantsUnion<D> & FullEventBrand<D>, VariantsUnion<D>, never> & MachineSchemaBase<D, FullEventBrand<D>> & VariantConstructors<D, FullEventBrand<D>>;
88
+ type MachineEventSchema<D extends Record<string, Schema.Struct.Fields>> = Schema.Codec<VariantsUnion<D> & FullEventBrand<D>, unknown, never, never> & MachineSchemaBase<D, FullEventBrand<D>> & VariantConstructors<D, FullEventBrand<D>>;
89
89
  /**
90
90
  * Create a schema-first State definition.
91
91
  *
package/dist/schema.js CHANGED
@@ -69,8 +69,8 @@ const buildMachineSchema = (definition) => {
69
69
  };
70
70
  }
71
71
  const variantArray = Object.values(variants);
72
- if (variantArray.length === 0) throw new InvalidSchemaError();
73
- const unionSchema = variantArray.length === 1 ? variantArray[0] : Schema.Union(...variantArray);
72
+ if (variantArray.length === 0) throw new InvalidSchemaError({});
73
+ const unionSchema = variantArray.length === 1 ? variantArray[0] : Schema.Union(variantArray);
74
74
  const $is = (tag) => (u) => typeof u === "object" && u !== null && "_tag" in u && u._tag === tag;
75
75
  const $match = (valueOrCases, maybeCases) => {
76
76
  if (maybeCases !== void 0) {
package/dist/slot.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { ActorSystem } from "./actor.js";
2
- import { Context, Effect, Schema } from "effect";
2
+ import { Effect, Schema, ServiceMap } from "effect";
3
3
 
4
4
  //#region src/slot.d.ts
5
5
  /** Schema fields definition (like Schema.Struct.Fields) */
6
- type Fields = Record<string, Schema.Schema.All>;
6
+ type Fields = Record<string, Schema.Top>;
7
7
  /** Extract the encoded type from schema fields (used for parameters) */
8
8
  type FieldsToParams<F extends Fields> = keyof F extends never ? void : Schema.Schema.Type<Schema.Struct<F>>;
9
9
  /**
@@ -53,7 +53,7 @@ interface MachineContext<State, Event, Self> {
53
53
  * Single module-level tag instead of per-machine allocation.
54
54
  * @internal
55
55
  */
56
- declare const MachineContextTag: Context.Tag<MachineContext<any, any, any>, MachineContext<any, any, any>>;
56
+ declare const MachineContextTag: ServiceMap.Service<MachineContext<any, any, any>, MachineContext<any, any, any>>;
57
57
  /**
58
58
  * Guard handler implementation.
59
59
  * Receives params and context, returns Effect<boolean>.
package/dist/slot.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Context } from "effect";
1
+ import { ServiceMap } from "effect";
2
2
 
3
3
  //#region src/slot.ts
4
4
  /**
@@ -41,7 +41,7 @@ import { Context } from "effect";
41
41
  * Single module-level tag instead of per-machine allocation.
42
42
  * @internal
43
43
  */
44
- const MachineContextTag = Context.GenericTag("@effect-machine/Context");
44
+ const MachineContextTag = ServiceMap.Service("@effect-machine/Context");
45
45
  /**
46
46
  * Generic slot schema factory. Used internally by Guards() and Effects().
47
47
  * @internal
@@ -0,0 +1,18 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __defProp = Object.defineProperty;
3
+ var __exportAll = (all, no_symbols) => {
4
+ let target = {};
5
+ for (var name in all) {
6
+ __defProp(target, name, {
7
+ get: all[name],
8
+ enumerable: true
9
+ });
10
+ }
11
+ if (!no_symbols) {
12
+ __defProp(target, Symbol.toStringTag, { value: "Module" });
13
+ }
14
+ return target;
15
+ };
16
+
17
+ //#endregion
18
+ export { __exportAll };
@@ -0,0 +1,291 @@
1
+ import { PersistentMachine } from "./persistence/persistent-machine.js";
2
+ import { DuplicateActorError } from "./errors.js";
3
+ import { EffectsDef, GuardsDef } from "./slot.js";
4
+ import { ProcessEventError, ProcessEventHooks, ProcessEventResult, processEventCore, resolveTransition, runSpawnEffects } from "./internal/transition.js";
5
+ import { PersistentActorRef } from "./persistence/persistent-actor.js";
6
+ import { ActorMetadata, PersistenceAdapterTag, PersistenceError, RestoreResult, VersionConflictError } from "./persistence/adapter.js";
7
+ import { BuiltMachine, Machine } from "./machine.js";
8
+ import { Effect, Option, Queue, Ref, Stream, SubscriptionRef } from "effect";
9
+
10
+ //#region src-v3/actor.d.ts
11
+ /**
12
+ * Reference to a running actor.
13
+ */
14
+ interface ActorRef<State extends {
15
+ readonly _tag: string;
16
+ }, Event> {
17
+ /**
18
+ * Unique identifier for this actor
19
+ */
20
+ readonly id: string;
21
+ /**
22
+ * Send an event to the actor
23
+ */
24
+ readonly send: (event: Event) => Effect.Effect<void>;
25
+ /**
26
+ * Observable state of the actor
27
+ */
28
+ readonly state: SubscriptionRef.SubscriptionRef<State>;
29
+ /**
30
+ * Stop the actor gracefully
31
+ */
32
+ readonly stop: Effect.Effect<void>;
33
+ /**
34
+ * Stop the actor (fire-and-forget).
35
+ * Signals graceful shutdown without waiting for completion.
36
+ * Use when stopping from sync contexts (e.g. framework cleanup hooks).
37
+ */
38
+ readonly stopSync: () => void;
39
+ /**
40
+ * Get current state snapshot (Effect)
41
+ */
42
+ readonly snapshot: Effect.Effect<State>;
43
+ /**
44
+ * Get current state snapshot (sync)
45
+ */
46
+ readonly snapshotSync: () => State;
47
+ /**
48
+ * Check if current state matches tag (Effect)
49
+ */
50
+ readonly matches: (tag: State["_tag"]) => Effect.Effect<boolean>;
51
+ /**
52
+ * Check if current state matches tag (sync)
53
+ */
54
+ readonly matchesSync: (tag: State["_tag"]) => boolean;
55
+ /**
56
+ * Check if event can be handled in current state (Effect)
57
+ */
58
+ readonly can: (event: Event) => Effect.Effect<boolean>;
59
+ /**
60
+ * Check if event can be handled in current state (sync)
61
+ */
62
+ readonly canSync: (event: Event) => boolean;
63
+ /**
64
+ * Stream of state changes
65
+ */
66
+ readonly changes: Stream.Stream<State>;
67
+ /**
68
+ * Wait for a state that matches predicate or state variant (includes current snapshot).
69
+ * Accepts a predicate function or a state constructor/value (e.g. `State.Active`).
70
+ */
71
+ readonly waitFor: {
72
+ (predicate: (state: State) => boolean): Effect.Effect<State>;
73
+ (state: {
74
+ readonly _tag: State["_tag"];
75
+ }): Effect.Effect<State>;
76
+ };
77
+ /**
78
+ * Wait for a final state (includes current snapshot)
79
+ */
80
+ readonly awaitFinal: Effect.Effect<State>;
81
+ /**
82
+ * Send event and wait for predicate, state variant, or final state.
83
+ * Accepts a predicate function or a state constructor/value (e.g. `State.Active`).
84
+ */
85
+ readonly sendAndWait: {
86
+ (event: Event, predicate: (state: State) => boolean): Effect.Effect<State>;
87
+ (event: Event, state: {
88
+ readonly _tag: State["_tag"];
89
+ }): Effect.Effect<State>;
90
+ (event: Event): Effect.Effect<State>;
91
+ };
92
+ /**
93
+ * Send event synchronously (fire-and-forget).
94
+ * No-op on stopped actors. Use when you need to send from sync contexts
95
+ * (e.g. framework hooks, event handlers).
96
+ */
97
+ readonly sendSync: (event: Event) => void;
98
+ /**
99
+ * Subscribe to state changes (sync callback)
100
+ * Returns unsubscribe function
101
+ */
102
+ readonly subscribe: (fn: (state: State) => void) => () => void;
103
+ /**
104
+ * The actor system this actor belongs to.
105
+ * Every actor always has a system — either inherited from context or implicitly created.
106
+ */
107
+ readonly system: ActorSystem;
108
+ /**
109
+ * Child actors spawned via `self.spawn` in this actor's handlers.
110
+ * State-scoped children are auto-removed on state exit.
111
+ */
112
+ readonly children: ReadonlyMap<string, ActorRef<AnyState, unknown>>;
113
+ }
114
+ /** Base type for stored actors (internal) */
115
+ type AnyState = {
116
+ readonly _tag: string;
117
+ };
118
+ /**
119
+ * Events emitted by the ActorSystem when actors are spawned or stopped.
120
+ */
121
+ type SystemEvent = {
122
+ readonly _tag: "ActorSpawned";
123
+ readonly id: string;
124
+ readonly actor: ActorRef<AnyState, unknown>;
125
+ } | {
126
+ readonly _tag: "ActorStopped";
127
+ readonly id: string;
128
+ readonly actor: ActorRef<AnyState, unknown>;
129
+ };
130
+ /**
131
+ * Listener callback for system events.
132
+ */
133
+ type SystemEventListener = (event: SystemEvent) => void;
134
+ /**
135
+ * Actor system for managing actor lifecycles
136
+ */
137
+ interface ActorSystem {
138
+ /**
139
+ * Spawn a new actor with the given machine.
140
+ *
141
+ * For regular machines, returns ActorRef.
142
+ * For persistent machines (created with Machine.persist), returns PersistentActorRef.
143
+ *
144
+ * All effect slots must be provided via `.build()` before spawning.
145
+ *
146
+ * @example
147
+ * ```ts
148
+ * // Regular machine (built)
149
+ * const built = machine.build({ fetchData: ... })
150
+ * const actor = yield* system.spawn("my-actor", built);
151
+ *
152
+ * // Persistent machine (auto-detected)
153
+ * const persistentActor = yield* system.spawn("my-actor", persistentMachine);
154
+ * persistentActor.persist; // available
155
+ * persistentActor.version; // available
156
+ * ```
157
+ */
158
+ readonly spawn: {
159
+ <S extends {
160
+ readonly _tag: string;
161
+ }, E extends {
162
+ readonly _tag: string;
163
+ }, R>(id: string, machine: BuiltMachine<S, E, R>): Effect.Effect<ActorRef<S, E>, DuplicateActorError, R>;
164
+ <S extends {
165
+ readonly _tag: string;
166
+ }, E extends {
167
+ readonly _tag: string;
168
+ }, R>(id: string, machine: PersistentMachine<S, E, R>): Effect.Effect<PersistentActorRef<S, E, R>, PersistenceError | VersionConflictError | DuplicateActorError, R | PersistenceAdapterTag>;
169
+ };
170
+ /**
171
+ * Restore an actor from persistence.
172
+ * Returns None if no persisted state exists for the given ID.
173
+ *
174
+ * @example
175
+ * ```ts
176
+ * const maybeActor = yield* system.restore("order-1", persistentMachine);
177
+ * if (Option.isSome(maybeActor)) {
178
+ * const actor = maybeActor.value;
179
+ * const state = yield* actor.snapshot;
180
+ * console.log(`Restored to state: ${state._tag}`);
181
+ * }
182
+ * ```
183
+ */
184
+ readonly restore: <S extends {
185
+ readonly _tag: string;
186
+ }, E extends {
187
+ readonly _tag: string;
188
+ }, R>(id: string, machine: PersistentMachine<S, E, R>) => Effect.Effect<Option.Option<PersistentActorRef<S, E, R>>, PersistenceError | DuplicateActorError, R | PersistenceAdapterTag>;
189
+ /**
190
+ * Get an existing actor by ID
191
+ */
192
+ readonly get: (id: string) => Effect.Effect<Option.Option<ActorRef<AnyState, unknown>>>;
193
+ /**
194
+ * Stop an actor by ID
195
+ */
196
+ readonly stop: (id: string) => Effect.Effect<boolean>;
197
+ /**
198
+ * Async stream of system events (actor spawned/stopped).
199
+ * Each subscriber gets their own queue — late subscribers miss prior events.
200
+ */
201
+ readonly events: Stream.Stream<SystemEvent>;
202
+ /**
203
+ * Sync snapshot of all currently registered actors.
204
+ * Returns a new Map on each access (not live).
205
+ */
206
+ readonly actors: ReadonlyMap<string, ActorRef<AnyState, unknown>>;
207
+ /**
208
+ * Subscribe to system events synchronously.
209
+ * Returns an unsubscribe function.
210
+ */
211
+ readonly subscribe: (fn: SystemEventListener) => () => void;
212
+ /**
213
+ * List all persisted actor metadata.
214
+ * Returns empty array if adapter doesn't support registry.
215
+ *
216
+ * @example
217
+ * ```ts
218
+ * const actors = yield* system.listPersisted();
219
+ * for (const meta of actors) {
220
+ * console.log(`${meta.id}: ${meta.stateTag} (v${meta.version})`);
221
+ * }
222
+ * ```
223
+ */
224
+ readonly listPersisted: () => Effect.Effect<ReadonlyArray<ActorMetadata>, PersistenceError, PersistenceAdapterTag>;
225
+ /**
226
+ * Restore multiple actors by ID.
227
+ * Returns both successfully restored actors and failures.
228
+ *
229
+ * @example
230
+ * ```ts
231
+ * const result = yield* system.restoreMany(["order-1", "order-2"], orderMachine);
232
+ * console.log(`Restored: ${result.restored.length}, Failed: ${result.failed.length}`);
233
+ * ```
234
+ */
235
+ readonly restoreMany: <S extends {
236
+ readonly _tag: string;
237
+ }, E extends {
238
+ readonly _tag: string;
239
+ }, R>(ids: ReadonlyArray<string>, machine: PersistentMachine<S, E, R>) => Effect.Effect<RestoreResult<S, E, R>, never, R | PersistenceAdapterTag>;
240
+ /**
241
+ * Restore all persisted actors for a machine type.
242
+ * Uses adapter registry if available, otherwise returns empty result.
243
+ *
244
+ * @example
245
+ * ```ts
246
+ * const result = yield* system.restoreAll(orderMachine, {
247
+ * filter: (meta) => meta.stateTag !== "Done"
248
+ * });
249
+ * console.log(`Restored ${result.restored.length} active orders`);
250
+ * ```
251
+ */
252
+ readonly restoreAll: <S extends {
253
+ readonly _tag: string;
254
+ }, E extends {
255
+ readonly _tag: string;
256
+ }, R>(machine: PersistentMachine<S, E, R>, options?: {
257
+ filter?: (meta: ActorMetadata) => boolean;
258
+ }) => Effect.Effect<RestoreResult<S, E, R>, PersistenceError, R | PersistenceAdapterTag>;
259
+ }
260
+ /**
261
+ * ActorSystem service tag
262
+ */
263
+ declare const ActorSystem: any;
264
+ /** Listener set for sync subscriptions */
265
+ type Listeners<S> = Set<(state: S) => void>;
266
+ /**
267
+ * Notify all listeners of state change.
268
+ */
269
+ declare const notifyListeners: <S>(listeners: Listeners<S>, state: S) => void;
270
+ /**
271
+ * Build core ActorRef methods shared between regular and persistent actors.
272
+ */
273
+ declare const buildActorRefCore: <S extends {
274
+ readonly _tag: string;
275
+ }, E extends {
276
+ readonly _tag: string;
277
+ }, R, GD extends GuardsDef, EFD extends EffectsDef>(id: string, machine: Machine<S, E, R, any, any, GD, EFD>, stateRef: SubscriptionRef.SubscriptionRef<S>, eventQueue: Queue.Queue<E>, stoppedRef: Ref.Ref<boolean>, listeners: Listeners<S>, stop: Effect.Effect<void>, system: ActorSystem, childrenMap: ReadonlyMap<string, ActorRef<AnyState, unknown>>) => ActorRef<S, E>;
278
+ /**
279
+ * Create and start an actor for a machine
280
+ */
281
+ declare const createActor: <S extends {
282
+ readonly _tag: string;
283
+ }, E extends {
284
+ readonly _tag: string;
285
+ }, R, GD extends GuardsDef, EFD extends EffectsDef>(id: string, machine: Machine<S, E, R, Record<string, never>, Record<string, never>, GD, EFD>) => Effect.Effect<ActorRef<S, E>, unknown, unknown>;
286
+ /**
287
+ * Default ActorSystem layer
288
+ */
289
+ declare const Default: any;
290
+ //#endregion
291
+ export { ActorRef, ActorSystem, Default, Listeners, type ProcessEventError, type ProcessEventHooks, type ProcessEventResult, SystemEvent, SystemEventListener, buildActorRefCore, createActor, notifyListeners, processEventCore, resolveTransition, runSpawnEffects };