@@ -29,24 +29,25 @@ Effect.runPromise(Effect.scoped(program).pipe(Effect.provide(ActorSystemDefault)
2929
3030## ActorRef Methods
3131
32- | Method | Type | Description |
33- | -------------------------- | ----------------- | ---------------------------------- |
34- | ` send(event) ` | ` Effect<void> ` | Queue event for processing |
35- | ` sendSync(event) ` | ` void ` | Fire-and-forget (sync, for UI) |
36- | ` snapshot ` | ` Effect<State> ` | Get current state |
37- | ` snapshotSync() ` | ` State ` | Get current state (sync) |
38- | ` matches(tag) ` | ` Effect<boolean> ` | Check if in state |
39- | ` matchesSync(tag) ` | ` boolean ` | Check if in state (sync) |
40- | ` can(event) ` | ` Effect<boolean> ` | Can handle event in current state? |
41- | ` canSync(event) ` | ` boolean ` | Can handle event? (sync) |
42- | ` changes ` | ` Stream<State> ` | Stream of state changes |
43- | ` waitFor(State.X) ` | ` Effect<State> ` | Wait for state (constructor or fn) |
44- | ` awaitFinal ` | ` Effect<State> ` | Wait for final state |
45- | ` sendAndWait(ev, State.X) ` | ` Effect<State> ` | Send + wait for state |
46- | ` sendAndWait(ev) ` | ` Effect<State> ` | Send + wait for final state |
47- | ` subscribe(fn) ` | ` () => void ` | Sync callback, returns unsubscribe |
48- | ` system ` | ` ActorSystem ` | Access the actor's system |
49- | ` stop ` | ` Effect<void> ` | Stop actor gracefully |
32+ | Method | Type | Description |
33+ | -------------------------- | ----------------- | ----------------------------------- |
34+ | ` send(event) ` | ` Effect<void> ` | Queue event for processing |
35+ | ` sendSync(event) ` | ` void ` | Fire-and-forget (sync, for UI) |
36+ | ` snapshot ` | ` Effect<State> ` | Get current state |
37+ | ` snapshotSync() ` | ` State ` | Get current state (sync) |
38+ | ` matches(tag) ` | ` Effect<boolean> ` | Check if in state |
39+ | ` matchesSync(tag) ` | ` boolean ` | Check if in state (sync) |
40+ | ` can(event) ` | ` Effect<boolean> ` | Can handle event in current state? |
41+ | ` canSync(event) ` | ` boolean ` | Can handle event? (sync) |
42+ | ` changes ` | ` Stream<State> ` | Stream of state changes |
43+ | ` waitFor(State.X) ` | ` Effect<State> ` | Wait for state (constructor or fn) |
44+ | ` awaitFinal ` | ` Effect<State> ` | Wait for final state |
45+ | ` sendAndWait(ev, State.X) ` | ` Effect<State> ` | Send + wait for state |
46+ | ` sendAndWait(ev) ` | ` Effect<State> ` | Send + wait for final state |
47+ | ` subscribe(fn) ` | ` () => void ` | Sync callback, returns unsubscribe |
48+ | ` system ` | ` ActorSystem ` | Access the actor's system |
49+ | ` children ` | ` ReadonlyMap ` | Child actors spawned via self.spawn |
50+ | ` stop ` | ` Effect<void> ` | Stop actor gracefully |
5051
5152## Sending Events
5253
@@ -247,6 +248,57 @@ const stopped = yield * system.stop("order-1");
247248// true if actor existed and was stopped
248249```
249250
251+ ## System Observation
252+
253+ Observe actors joining and leaving the system without polling:
254+
255+ ### Sync Callback
256+
257+ ``` ts
258+ const system = yield * ActorSystemService ;
259+
260+ const unsub = system .subscribe ((event ) => {
261+ switch (event ._tag ) {
262+ case " ActorSpawned" :
263+ console .log (` Spawned: ${event .id } ` );
264+ break ;
265+ case " ActorStopped" :
266+ console .log (` Stopped: ${event .id } ` );
267+ // event.actor still readable — can check final state
268+ break ;
269+ }
270+ });
271+
272+ // Later: unsub() to stop receiving events
273+ ```
274+
275+ ### Actors Snapshot
276+
277+ ``` ts
278+ // Sync snapshot — returns new Map each time (not live)
279+ const actors = system .actors ; // ReadonlyMap<string, ActorRef>
280+ console .log (` ${actors .size } actors running ` );
281+ ```
282+
283+ ### Async Stream
284+
285+ ``` ts
286+ // Each subscriber gets own queue — late subscribers miss prior events
287+ yield *
288+ system .events .pipe (
289+ Stream .tap ((e ) => Effect .log (e ._tag , e .id )),
290+ Stream .runDrain ,
291+ );
292+ ```
293+
294+ ### Edge Cases
295+
296+ - ** System teardown** : No events emitted — PubSub is shutting down
297+ - ** Late stream subscribers** : Miss prior events (PubSub gives each subscriber their own queue)
298+ - ** Listener errors** : Caught and ignored — won't crash the system
299+ - ** Scope cleanup** : Actors stopped via scope close emit ` ActorStopped `
300+ - ** Double stop** : ` system.stop(id) ` + scope finalizer won't double-emit (guarded by map check)
301+
250302## Duplicate Actor Prevention
251303
252304Same ID cannot be spawned twice:
0 commit comments