effect-machine 0.21.0 → 0.22.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 CHANGED
@@ -204,6 +204,7 @@ Read [Atom and UI integration](./docs/atom-and-ui.md) and browse [all examples](
204
204
  - Durability saves committed transitions.
205
205
  - Supervision restarts defects within an Effect `Schedule` budget.
206
206
  - Inspection reports events, named transition operations, transitions, named guards, tasks, Effects, errors, stops, and actor generations.
207
+ - Dynamic Inspector hubs let lazy tools observe existing actors without actor restart or state duplication.
207
208
 
208
209
  Read [Persistence and supervision](./docs/persistence-and-supervision.md) and [Inspection](./docs/inspection.md).
209
210
 
package/dist/index.d.ts CHANGED
@@ -6,5 +6,5 @@ import { Durability, DurabilityCommit, FinalContext, GuardPredicate, HandlerCont
6
6
  import { ProcessEventResult } from "./internal/transition.js";
7
7
  import { ActorClient, ActorLifecycle, ActorRef, ActorRefSync, ActorScope, ActorSystem, ActorSystemKey, ActorSystemService, Default, SystemEvent, SystemEventListener, SystemSpawnOptions, TransitionInfo, actorSystemKey } from "./actor.js";
8
8
  import { InputTestHarnessOptions, SimulationOptions, SimulationResult, TestHarness, TestHarnessOptions, assertNeverReaches, assertPath, assertReaches, createTestHarness, simulate } from "./testing.js";
9
- import { AnyInspectionEvent, EffectEvent, ErrorEvent, EventReceivedEvent, GuardEvent, InspectionEvent, Inspector, InspectorHandler, InspectorService, OperationEvent, SpawnEvent, StopEvent, TaskEvent, TracingInspectorOptions, TransitionEvent, collectingInspector, combineInspectors, consoleInspector, makeInspector, makeInspectorEffect, tracingInspector } from "./inspection.js";
10
- export { type ActorClient, ActorExit, type ActorExit as ActorExitType, type ActorLifecycle, type ActorRef, type ActorRefSync, ActorScope, ActorStoppedError, type ActorSystemService as ActorSystem, Default as ActorSystemDefault, ActorSystemKey, ActorSystem as ActorSystemService, type AnyInspectionEvent, AssertionError, type DefectPhase, type DeferReplyResult, DuplicateActorError, type Durability, type DurabilityCommit, type EffectEvent, type ErrorEvent, Event, type EventReceivedEvent, type FinalContext, type GuardEvent, type GuardPredicate, type HandlerContext, type InputMakeConfig, type InputTestHarnessOptions, type InspectionEvent, type InspectorService as Inspector, type InspectorHandler, Inspector as InspectorService, InvalidSchemaError, type Lifecycle, machine_d_exports as Machine, type MachineEventSchema, type MachineRef, type MachineStateSchema, type Machine as MachineType, type MakeConfig, MissingMatchHandlerError, NoReplyError, type OperationEvent, PersistenceError, type ProcessEventResult, type Recovery, type RecoveryContext, type ReplayOptions, type ReplyFields, type ReplyResult, type SimulationOptions, type SimulationResult, type SpawnEvent, type SpawnOptions, State, type StateHandlerContext, type StopEvent, Supervision, type SystemEvent, type SystemEventListener, type SystemSpawnOptions, type TaskEvent, type TaskOptions, type TestHarness, type TestHarnessOptions, type TimeoutConfig, type TracingInspectorOptions, type TransitionEvent, type TransitionInfo, VersionConflictError, actorSystemKey, assertNeverReaches, assertPath, assertReaches, collectingInspector, combineInspectors, consoleInspector, createTestHarness, makeInspector, makeInspectorEffect, simulate, tracingInspector };
9
+ import { AnyInspectionEvent, EffectEvent, ErrorEvent, EventReceivedEvent, GuardEvent, InspectionEvent, Inspector, InspectorHandler, InspectorHub, InspectorService, OperationEvent, SpawnEvent, StopEvent, TaskEvent, TracingInspectorOptions, TransitionEvent, collectingInspector, combineInspectors, consoleInspector, makeInspector, makeInspectorEffect, makeInspectorHub, tracingInspector } from "./inspection.js";
10
+ export { type ActorClient, ActorExit, type ActorExit as ActorExitType, type ActorLifecycle, type ActorRef, type ActorRefSync, ActorScope, ActorStoppedError, type ActorSystemService as ActorSystem, Default as ActorSystemDefault, ActorSystemKey, ActorSystem as ActorSystemService, type AnyInspectionEvent, AssertionError, type DefectPhase, type DeferReplyResult, DuplicateActorError, type Durability, type DurabilityCommit, type EffectEvent, type ErrorEvent, Event, type EventReceivedEvent, type FinalContext, type GuardEvent, type GuardPredicate, type HandlerContext, type InputMakeConfig, type InputTestHarnessOptions, type InspectionEvent, type InspectorService as Inspector, type InspectorHandler, type InspectorHub, Inspector as InspectorService, InvalidSchemaError, type Lifecycle, machine_d_exports as Machine, type MachineEventSchema, type MachineRef, type MachineStateSchema, type Machine as MachineType, type MakeConfig, MissingMatchHandlerError, NoReplyError, type OperationEvent, PersistenceError, type ProcessEventResult, type Recovery, type RecoveryContext, type ReplayOptions, type ReplyFields, type ReplyResult, type SimulationOptions, type SimulationResult, type SpawnEvent, type SpawnOptions, State, type StateHandlerContext, type StopEvent, Supervision, type SystemEvent, type SystemEventListener, type SystemSpawnOptions, type TaskEvent, type TaskOptions, type TestHarness, type TestHarnessOptions, type TimeoutConfig, type TracingInspectorOptions, type TransitionEvent, type TransitionInfo, VersionConflictError, actorSystemKey, assertNeverReaches, assertPath, assertReaches, collectingInspector, combineInspectors, consoleInspector, createTestHarness, makeInspector, makeInspectorEffect, makeInspectorHub, simulate, tracingInspector };
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { ActorStoppedError, AssertionError, DuplicateActorError, InvalidSchemaError, MissingMatchHandlerError, NoReplyError, PersistenceError, VersionConflictError } from "./errors.js";
2
2
  import { Event, State } from "./schema.js";
3
- import { Inspector, collectingInspector, combineInspectors, consoleInspector, makeInspector, makeInspectorEffect, tracingInspector } from "./inspection.js";
3
+ import { Inspector, collectingInspector, combineInspectors, consoleInspector, makeInspector, makeInspectorEffect, makeInspectorHub, tracingInspector } from "./inspection.js";
4
4
  import { ActorExit, Supervision } from "./supervision.js";
5
5
  import { ActorScope, ActorSystem, ActorSystemKey, Default, actorSystemKey } from "./actor.js";
6
6
  import { machine_exports } from "./machine.js";
7
7
  import { assertNeverReaches, assertPath, assertReaches, createTestHarness, simulate } from "./testing.js";
8
- export { ActorExit, ActorScope, ActorStoppedError, Default as ActorSystemDefault, ActorSystemKey, ActorSystem as ActorSystemService, AssertionError, DuplicateActorError, Event, Inspector as InspectorService, InvalidSchemaError, machine_exports as Machine, MissingMatchHandlerError, NoReplyError, PersistenceError, State, Supervision, VersionConflictError, actorSystemKey, assertNeverReaches, assertPath, assertReaches, collectingInspector, combineInspectors, consoleInspector, createTestHarness, makeInspector, makeInspectorEffect, simulate, tracingInspector };
8
+ export { ActorExit, ActorScope, ActorStoppedError, Default as ActorSystemDefault, ActorSystemKey, ActorSystem as ActorSystemService, AssertionError, DuplicateActorError, Event, Inspector as InspectorService, InvalidSchemaError, machine_exports as Machine, MissingMatchHandlerError, NoReplyError, PersistenceError, State, Supervision, VersionConflictError, actorSystemKey, assertNeverReaches, assertPath, assertReaches, collectingInspector, combineInspectors, consoleInspector, createTestHarness, makeInspector, makeInspectorEffect, makeInspectorHub, simulate, tracingInspector };
@@ -124,6 +124,13 @@ type InspectorHandler<S, E> = (event: InspectionEvent<S, E>) => void | Effect.Ef
124
124
  interface InspectorService<S, E> {
125
125
  readonly onInspect: InspectorHandler<S, E>;
126
126
  }
127
+ /**
128
+ * Dynamic Inspector fan-out for applications that load inspection consumers after actors start.
129
+ */
130
+ interface InspectorHub<S, E> {
131
+ readonly inspector: InspectorService<S, E>;
132
+ readonly register: (inspector: InspectorService<S, E>) => () => void;
133
+ }
127
134
  declare const Inspector_base: Context.ServiceClass<Inspector, "effect-machine/inspection/Inspector", InspectorService<any, any>>;
128
135
  /**
129
136
  * Inspector service tag - optional service for machine introspection
@@ -149,6 +156,17 @@ declare const makeInspectorEffect: <S = {
149
156
  readonly _tag: string;
150
157
  }>(onInspect: (event: InspectionEvent<ResolveType<S>, ResolveType<E>>) => Effect.Effect<void>) => InspectorService<ResolveType<S>, ResolveType<E>>;
151
158
  declare const combineInspectors: <S, E>(...inspectors: ReadonlyArray<InspectorService<S, E>>) => InspectorService<S, E>;
159
+ /**
160
+ * Create an Inspector that accepts sinks throughout its lifetime.
161
+ *
162
+ * Provide `hub.inspector` before actor startup. Consumers can then register and unregister sinks
163
+ * without restarting the actor. A sink failure does not affect the actor or other sinks.
164
+ */
165
+ declare const makeInspectorHub: <S = {
166
+ readonly _tag: string;
167
+ }, E = {
168
+ readonly _tag: string;
169
+ }>() => InspectorHub<ResolveType<S>, ResolveType<E>>;
152
170
  interface TracingInspectorOptions<S, E> {
153
171
  readonly spanName?: string | ((event: InspectionEvent<S, E>) => string);
154
172
  readonly attributes?: (event: InspectionEvent<S, E>) => Readonly<Record<string, string | number | boolean>>;
@@ -176,4 +194,4 @@ declare const collectingInspector: <S extends {
176
194
  readonly _tag: string;
177
195
  }>(events: InspectionEvent<S, E>[]) => InspectorService<S, E>;
178
196
  //#endregion
179
- export { AnyInspectionEvent, EffectEvent, ErrorEvent, EventReceivedEvent, GuardEvent, InspectionEvent, Inspector, InspectorHandler, InspectorService, OperationEvent, SpawnEvent, StopEvent, TaskEvent, TracingInspectorOptions, TransitionEvent, collectingInspector, combineInspectors, consoleInspector, makeInspector, makeInspectorEffect, tracingInspector };
197
+ export { AnyInspectionEvent, EffectEvent, ErrorEvent, EventReceivedEvent, GuardEvent, InspectionEvent, Inspector, InspectorHandler, InspectorHub, InspectorService, OperationEvent, SpawnEvent, StopEvent, TaskEvent, TracingInspectorOptions, TransitionEvent, collectingInspector, combineInspectors, consoleInspector, makeInspector, makeInspectorEffect, makeInspectorHub, tracingInspector };
@@ -15,15 +15,39 @@ var Inspector = class extends Context.Service()("effect-machine/inspection/Inspe
15
15
  */
16
16
  const makeInspector = (onInspect) => ({ onInspect });
17
17
  const makeInspectorEffect = (onInspect) => ({ onInspect });
18
- const inspectionEffect = (inspector, event) => {
18
+ const inspectionEffect = (inspector, event) => Effect.suspend(() => {
19
19
  const result = inspector.onInspect(event);
20
20
  if (Effect.isEffect(result)) return result;
21
21
  return Effect.void;
22
- };
22
+ });
23
23
  const combineInspectors = (...inspectors) => ({ onInspect: (event) => Effect.forEach(inspectors, (inspector) => inspectionEffect(inspector, event).pipe(Effect.ignoreCause), {
24
24
  concurrency: 16,
25
25
  discard: true
26
26
  }) });
27
+ /**
28
+ * Create an Inspector that accepts sinks throughout its lifetime.
29
+ *
30
+ * Provide `hub.inspector` before actor startup. Consumers can then register and unregister sinks
31
+ * without restarting the actor. A sink failure does not affect the actor or other sinks.
32
+ */
33
+ const makeInspectorHub = () => {
34
+ const inspectorByRegistration = /* @__PURE__ */ new Map();
35
+ const inspector = { onInspect: (event) => Effect.forEach(Array.from(inspectorByRegistration.values()), (registeredInspector) => inspectionEffect(registeredInspector, event).pipe(Effect.ignoreCause), {
36
+ concurrency: 16,
37
+ discard: true
38
+ }) };
39
+ const register = (registeredInspector) => {
40
+ const registration = Symbol();
41
+ inspectorByRegistration.set(registration, registeredInspector);
42
+ return () => {
43
+ inspectorByRegistration.delete(registration);
44
+ };
45
+ };
46
+ return {
47
+ inspector,
48
+ register
49
+ };
50
+ };
27
51
  const inspectionSpanName = (event) => {
28
52
  switch (event.type) {
29
53
  case "@machine.spawn": return `Machine.inspect ${event.initialState._tag}`;
@@ -157,4 +181,4 @@ const collectingInspector = (events) => ({ onInspect: (event) => {
157
181
  events.push(event);
158
182
  } });
159
183
  //#endregion
160
- export { Inspector, collectingInspector, combineInspectors, consoleInspector, makeInspector, makeInspectorEffect, tracingInspector };
184
+ export { Inspector, collectingInspector, combineInspectors, consoleInspector, makeInspector, makeInspectorEffect, makeInspectorHub, tracingInspector };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "effect-machine",
3
- "version": "0.21.0",
3
+ "version": "0.22.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/cevr/effect-machine.git"