posipaki 0.28.0 → 0.30.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.
@@ -1,4 +1,4 @@
1
- import { r as Message } from "./types-Dbe4BSPC.js";
1
+ import { r as Message } from "./types-BsynPeOf.js";
2
2
  //#region src/remote/channel.d.ts
3
3
  interface StringTransport {
4
4
  send(frame: string): void | Promise<void>;
@@ -39,4 +39,4 @@ declare function isExit(msg: Record<string, unknown>): msg is {
39
39
  };
40
40
  //#endregion
41
41
  export { isMsg as a, isInit as i, StringTransport as n, isProto as o, isExit as r, isState as s, Channel as t };
42
- //# sourceMappingURL=channel-Dakf3HAG.d.ts.map
42
+ //# sourceMappingURL=channel-CwvNcxhn.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"channel-Dakf3HAG.d.ts","names":[],"sources":["../src/remote/channel.ts"],"mappings":";;UAUiB;EACf,KAAK,uBAAuB;EAC5B,UAAU,UAAU;EACpB;;EAEA,QAAQ;EACR,SAAS;;UAGM;EACf,KAAK,OAAO,iCAAiC;EAC7C,UAAU,UAAU,OAAO;EAC3B;;EAEA,QAAQ;EACR,SAAS;;iBAKK,QAAQ,KAAK,0BAA0B;EAAS;;iBAGhD,OAAO,KAAK,0BAA0B;EAAS,OAAO;;iBAGtD,QAAQ,KAAK,0BAA0B;EAAS,QAAQ;;iBAGxD,MACd,KAAK,0BACJ;EAAS;IAAQ;IAAkB,MAAM;;;iBAG5B,OACd,KAAK,0BACJ;EAAS;IAAS;IAAc"}
1
+ {"version":3,"file":"channel-CwvNcxhn.d.ts","names":[],"sources":["../src/remote/channel.ts"],"mappings":";;UAUiB;EACf,KAAK,uBAAuB;EAC5B,UAAU,UAAU;EACpB;;EAEA,QAAQ;EACR,SAAS;;UAGM;EACf,KAAK,OAAO,iCAAiC;EAC7C,UAAU,UAAU,OAAO;EAC3B;;EAEA,QAAQ;EACR,SAAS;;iBAKK,QAAQ,KAAK,0BAA0B;EAAS;;iBAGhD,OAAO,KAAK,0BAA0B;EAAS,OAAO;;iBAGtD,QAAQ,KAAK,0BAA0B;EAAS,QAAQ;;iBAGxD,MACd,KAAK,0BACJ;EAAS;IAAQ;IAAkB,MAAM;;;iBAG5B,OACd,KAAK,0BACJ;EAAS;IAAS;IAAc"}
@@ -92,6 +92,9 @@ var AsyncProcess = class AsyncProcess {
92
92
  },
93
93
  toParent: (msg) => {
94
94
  this.messageSubscribers.forEach((cb) => cb(msg, selfCtx));
95
+ },
96
+ notify: () => {
97
+ this.notify();
95
98
  }
96
99
  };
97
100
  this.current = this.pvtWatchExit(ctx, arg0);
@@ -616,4 +619,4 @@ function defineActor(config) {
616
619
  //#endregion
617
620
  export { spawnAsync as a, runDispatchAsync as i, defineMessages as n, asyncify as o, AsyncProcess as r, defineActor as t };
618
621
 
619
- //# sourceMappingURL=define-actor-Dg5_koH3.js.map
622
+ //# sourceMappingURL=define-actor-BgC4BUK8.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-actor-BgC4BUK8.js","names":[],"sources":["../src/adapters.ts","../src/process.async.ts","../src/define-actor.ts"],"sourcesContent":["import type { ProcessFn, AsyncProcessFn, Message } from \"./types.js\";\n\nexport function asyncify<A, S, IM extends Message, OM extends Message>(\n fn: ProcessFn<A, S, IM, OM>,\n): AsyncProcessFn<A, S, IM, OM> {\n return async function* (ctx, args) {\n yield* fn(ctx, args) as any;\n };\n}\n","import { defer, makeWaiter, debugLog, withTimeout } from \"./util.js\";\nimport type { DeferredCall, Waiter } from \"./util.js\";\nimport type {\n Message,\n WithSender,\n SenderInfo,\n ExitMessage,\n StopMessage,\n ProcessCtx,\n AsyncProcessFn,\n ProcessFn,\n} from \"./types.js\";\nimport { asyncify } from \"./adapters.js\";\n\n// ---- types ------------------------------------------------------------------\n\n/** An async iterator over process state. Receives `WithSender<InMessage | StopMessage>`. */\ntype AsyncProcessGenerator<ProcessState, InMessage extends Message> = AsyncGenerator<\n ProcessState | null,\n void,\n WithSender<InMessage | StopMessage>\n>;\n\ntype NotifyFn = () => void;\n\n// ---- runDispatchAsync -------------------------------------------------------\n\ntype AsyncReducer<M> = (msg: M) => Promise<void>;\ntype ReadyFn = () => boolean;\n\n/**\n * Async equivalent of `runDispatch`. Loops, yielding `null` and feeding\n * each incoming message to an `async` reducer. Exits when `readyFn()`\n * returns true.\n */\nexport async function* runDispatchAsync<M>(\n name: string,\n fn: AsyncReducer<M>,\n readyFn: ReadyFn = () => false,\n debugLevel = false,\n): AsyncGenerator<null, void, M> {\n let msg: M;\n while (!readyFn()) {\n msg = yield null;\n debugLog(debugLevel, \"msg\", name, \" <- \", msg);\n await fn(msg);\n }\n}\n\n// ---- AsyncProcess -----------------------------------------------------------\n\n/** A subscriber to this process's message channel: receives the message and\n * its sender separately (not a `WithSender` tuple). */\ntype MessageCallback<M extends Message> = (msg: M, from: SenderInfo) => void;\n\n/** How long a parent waits for a child to stop before continuing shutdown. */\nconst CHILD_STOP_TIMEOUT_MS = 1_000;\n\n/**\n * A process driven by an async generator. Functionally identical to\n * {@link Process} but supports `await` inside reducers.\n *\n * Messages are processed **one at a time** — if a tick is already\n * in-flight, new messages are buffered and processed when the current\n * tick completes.\n */\nexport class AsyncProcess<\n Args,\n State,\n InMessage extends Message,\n OutMessage extends Message,\n ReflectionMethods extends object,\n> {\n /** Reflection methods. Empty by default — defineActor fills in configured methods. */\n $reflection: ReflectionMethods = {} as ReflectionMethods;\n pgenerator: AsyncProcessFn<Args, State, InMessage, OutMessage>;\n pname: string;\n /** Subscribers to this process's message channel (`ctx.toParent`). */\n private messageSubscribers: Array<MessageCallback<OutMessage>> = [];\n id: symbol;\n state: State | null;\n\n private current: AsyncProcessGenerator<State, InMessage> | null = null;\n /** Every buffered message carries sender provenance. */\n private buffer: Array<WithSender<InMessage | StopMessage>> = [];\n private nextTick: DeferredCall | null = null;\n /** Child processes forked from this one (any fork method). */\n children: Array<AsyncProcess<unknown, unknown, Message, Message, {}>> = [];\n /** Children inherited from a child that exited (see ctx-orphans proposal). */\n orphans: Array<AsyncProcess<unknown, unknown, Message, Message, {}>> = [];\n private stateSubscribers: Array<NotifyFn> = [];\n /** Unsubscribe handles for outgoing message subscriptions (monitor only). */\n private pvtOutgoingSubscriptions: Array<() => void> = [];\n /** Unsubscribe handles for adopt (ownership) subscriptions, keyed by child id. */\n private pvtAdoptUnsubs: Map<symbol, () => void> = new Map();\n /** Live buffer while this process is an unowned orphan mid-handoff. */\n private pvtPending: Array<WithSender<Message>> | null = null;\n /** Unsubscribe for the collector currently buffering into pvtPending. */\n private pvtCollectorUnsub: (() => void) | null = null;\n private exitWaiter: Waiter;\n private pvtIsPaused: boolean = false;\n private pvtDead: boolean = false;\n private pvtTickInProgress: boolean = false;\n private pvtExitReject: ((e: unknown) => void) | null = null;\n private pvtReady!: Waiter;\n private pvtResolveReady!: () => void;\n\n constructor(\n fn: AsyncProcessFn<Args, State, InMessage, OutMessage>,\n pname: string,\n toParent?: MessageCallback<OutMessage>,\n ) {\n this.pgenerator = fn;\n this.pname = pname;\n if (toParent) this.messageSubscribers.push(toParent);\n this.id = Symbol(pname);\n this.state = null;\n this.exitWaiter = makeWaiter();\n this.pvtReady = makeWaiter();\n this.pvtResolveReady = this.pvtReady.resolve;\n }\n\n /** Compact handle for `util.inspect` — actor state often holds process\n * references, and dumping the internals would be unreadable. */\n [Symbol.for(\"nodejs.util.inspect.custom\")](): string {\n return `AsyncProcess<${this.pname}>`;\n }\n\n /** Promise that resolves once the initial state is available. */\n ready(): Promise<void> {\n return this.pvtReady.promise;\n }\n\n // ---- lifecycle ------------------------------------------------------------\n\n /**\n * Kick off the async generator. The first `yield` sets the initial\n * state; for async generators this happens in a microtask.\n */\n start(arg0: Args, parentName?: string | null, parentId?: symbol | null) {\n const selfCtx: SenderInfo = { fromName: this.pname, fromId: this.id };\n\n const ctx: ProcessCtx<Args, State, InMessage, OutMessage | ExitMessage> = {\n pname: this.pname,\n id: this.id,\n parentName: parentName ?? null,\n parentId: parentId ?? null,\n fork: this.fork.bind(this),\n forkSync: this.forkSync.bind(this),\n children: this.children,\n orphans: this.orphans,\n adopt: this.adopt.bind(this),\n monitor: this.monitor.bind(this),\n sendSelf: (msg) => {\n this.send([msg, selfCtx]);\n },\n toParent: (msg) => {\n this.messageSubscribers.forEach((cb) => cb(msg as OutMessage, selfCtx));\n },\n notify: () => {\n this.notify();\n },\n };\n\n this.current = this.pvtWatchExit(ctx, arg0);\n void this.current.next().then((ret: IteratorResult<State | null, void>) => {\n this.state = ret.value ?? null;\n this.pvtResolveReady();\n if (ret.done) {\n this.exitWaiter.resolve();\n return;\n }\n // Advance past the initial yield so the pvtWatchExit generator\n // runs its finally block (EXIT/STOP) and the inner generator\n // enters its dispatch loop.\n const advance: WithSender<InMessage | StopMessage> = [\n { type: \"__ADVANCE__\" } as InMessage,\n {\n fromName: \"__internal__\",\n fromId: Symbol(\"__internal__\"),\n } as SenderInfo,\n ];\n this.pvtEatResult(this.current!.next(advance));\n });\n return this;\n }\n\n /** Wrap the user's generator so EXIT/STOP logic fires on completion. */\n private async *pvtWatchExit(\n ctx: ProcessCtx<Args, State, InMessage, OutMessage | ExitMessage>,\n arg0: Args,\n ): AsyncProcessGenerator<State, InMessage> {\n try {\n yield* this.pgenerator(ctx, arg0);\n } finally {\n // Cascade: stop every child (nice) and collect the refusers as orphans.\n const orphans: Array<AnyProcess> = [...this.orphans];\n const parentSender: SenderInfo = { fromName: this.pname, fromId: this.id };\n const stopPromises = this.children.map(async (child) => {\n const stopped = await child.stop({ from: parentSender });\n if (!stopped) {\n orphans.push(child);\n console.warn(\n `posipaki: child \"${child.pname}\" did not stop within ${CHILD_STOP_TIMEOUT_MS}ms; continuing shutdown`,\n );\n }\n });\n\n await Promise.all(stopPromises);\n // Hand surviving children and inherited orphans up to the parent for adoption (see ctx-orphans proposal).\n // In-process only.\n this.pvtPrepareHandoff(orphans);\n ctx.toParent({ type: \"EXIT\", orphans });\n // Unsubscribe from children/monitored processes so a dead parent\n // doesn't keep receiving their messages (handoff collectors stay on the orphans).\n this.pvtUnsubscribeAll();\n if (ctx.afterExit) await ctx.afterExit();\n }\n }\n\n // ---- fork -----------------------------------------------------------------\n\n fork<ChildArgs, ChildState, ChildIM extends Message, ChildOM extends Message>(\n fn: AsyncProcessFn<ChildArgs, ChildState, ChildIM, ChildOM>,\n pname: string,\n ): (args: ChildArgs) => AsyncProcess<ChildArgs, ChildState, ChildIM, ChildOM, {}> {\n return (args: ChildArgs) => {\n const child = new AsyncProcess<ChildArgs, ChildState, ChildIM, ChildOM, {}>(fn, pname);\n this.adopt(child);\n child.start(args, this.pname, this.id);\n return child;\n };\n }\n\n forkSync<ChildArgs, ChildState, ChildIM extends Message, ChildOM extends InMessage>(\n fn: ProcessFn<ChildArgs, ChildState, ChildIM, ChildOM>,\n pname: string,\n ): (args: ChildArgs) => AsyncProcess<ChildArgs, ChildState, ChildIM, ChildOM, {}> {\n return this.fork(asyncify(fn), pname);\n }\n\n // ---- message processing ---------------------------------------------------\n\n protected async pvtTick(): Promise<void> {\n if (!this.current || this.pvtTickInProgress) return;\n\n this.pvtTickInProgress = true;\n try {\n let msgAndSender: WithSender<InMessage | StopMessage> | undefined;\n let ret: IteratorResult<State | null, void> | null = null;\n while ((msgAndSender = this.buffer.shift()) !== undefined) {\n ret = await this.pvtSafeNext(msgAndSender);\n if (!ret || ret.done) break;\n }\n this.notify();\n this.pvtEatResult(ret);\n } catch (e) {\n this.pvtExitReject?.(e);\n this.pvtExitReject = null;\n } finally {\n this.pvtTickInProgress = false;\n }\n }\n\n /** Call `.next()` and redirect unhandled rejections. */\n private async pvtSafeNext(\n msgAndSender: WithSender<InMessage | StopMessage>,\n ): Promise<IteratorResult<State | null, void> | null> {\n try {\n return await this.current!.next(msgAndSender);\n } catch (e) {\n this.pvtExitReject?.(e);\n this.pvtExitReject = null;\n return { done: true, value: undefined };\n }\n }\n\n private pvtEatResult(\n ret: IteratorResult<State | null, void> | Promise<IteratorResult<State | null, void>> | null,\n ): void {\n if (!ret) return;\n Promise.resolve(ret).then((r) => {\n if (r.done) {\n this.exitWaiter.resolve();\n }\n });\n }\n\n /** Broadcast a message to all children. */\n toAllChildren(msg: Message): void {\n const stamp: SenderInfo = { fromName: this.pname, fromId: this.id };\n this.children.forEach((p) => p.send([msg, stamp] as WithSender<Message>));\n }\n\n /** Stamp and enqueue a message from a named sender (external API). */\n send(msg: InMessage | StopMessage, from?: SenderInfo): void;\n /** Enqueue a pre-stamped message (internal: fromChild, toAllChildren). */\n send(msgAndSender: WithSender<InMessage | StopMessage>): void;\n send(\n msgOrTuple: InMessage | StopMessage | WithSender<InMessage | StopMessage>,\n from?: SenderInfo,\n ): void {\n if (this.pvtDead) return;\n if (\"type\" in msgOrTuple) {\n this.buffer.push([msgOrTuple as InMessage | StopMessage, from as SenderInfo]);\n } else {\n this.buffer.push(msgOrTuple as WithSender<InMessage | StopMessage>);\n }\n this.pvtScheduleTick();\n }\n\n /**\n * Synchronously flush the buffer. For sync processes use {@link Process.tick};\n * for async processes this is **not guaranteed** to process everything\n * immediately if reducers contain `await`. Prefer `send()` + `await proc.wait()`.\n */\n tick(): void {\n this.nextTick?.flush();\n this.nextTick = null;\n }\n\n private pvtScheduleTick(): void {\n if (this.pvtIsPaused || this.pvtDead) return;\n\n this.nextTick?.cancel();\n this.nextTick = defer(() => {\n this.nextTick = null;\n void this.pvtTick();\n });\n }\n\n // ---- subscribers ----------------------------------------------------------\n\n notify(): void {\n this.stateSubscribers.forEach((f) => f());\n }\n\n get isListenedTo(): boolean {\n return this.stateSubscribers.length > 0;\n }\n\n subscribe(channel: \"message\", cb: MessageCallback<OutMessage>): () => void;\n subscribe(channel: \"state\", cb: NotifyFn): () => void;\n /** @deprecated Use `subscribe(\"state\", cb)`. */\n subscribe(cb: NotifyFn): () => void;\n subscribe(\n channelOrCb: \"message\" | \"state\" | NotifyFn,\n cb?: MessageCallback<OutMessage> | NotifyFn,\n ): () => void {\n if (typeof channelOrCb === \"function\") {\n return this.subscribe(\"state\", channelOrCb);\n }\n if (channelOrCb === \"message\") {\n const fn = cb as MessageCallback<OutMessage>;\n this.messageSubscribers.push(fn);\n return () => this.pvtUnsubscribe(this.messageSubscribers, fn);\n }\n const fn = cb as NotifyFn;\n this.stateSubscribers.push(fn);\n return () => this.pvtUnsubscribe(this.stateSubscribers, fn);\n }\n\n private pvtUnsubscribe<T>(list: Array<T>, fn: T): void {\n const idx = list.indexOf(fn);\n if (idx >= 0) list.splice(idx, 1);\n }\n\n // ---- pause / resume -------------------------------------------------------\n\n /**\n * Freeze dispatch: no further ticks are scheduled, so the process stops\n * *processing* incoming messages. This is half-working as a \"quiesce\"\n * primitive — it does not stop the process from *emitting* via async\n * callbacks (timers, fetch) that bypass the dispatch loop.\n */\n pause(): void {\n this.nextTick?.cancel();\n this.nextTick = null;\n this.pvtIsPaused = true;\n }\n\n resume(): void {\n this.pvtIsPaused = false;\n this.pvtScheduleTick();\n }\n\n /**\n * Hard-kill this process: abandon the generator without running its\n * `finally` (no EXIT, no STOP cascade), drop the inbox and observers,\n * unsubscribe from children/monitors, and settle `wait()`/`ready()`.\n *\n * There is nothing to observe afterward — callers remove the process from\n * their `children`/`orphans` lists imperatively. Does not cascade to this\n * process's own children; they are abandoned (force-stop them separately if\n * owned).\n *\n * Best-effort: an idle generator (suspended at `yield`) is abandoned\n * cleanly; a generator mid-`await` completes its `finally` when that await\n * settles, because JS offers no way to cancel a pending promise.\n */\n forceStop(opts?: { cascade?: boolean }): void {\n if (this.pvtDead) return;\n this.pvtDead = true;\n\n // Abandon the generator so its finally block never runs.\n this.current = null;\n\n // Drop the inbox and stop scheduling.\n this.buffer.length = 0;\n this.nextTick?.cancel();\n this.nextTick = null;\n\n // Release incoming observers and outgoing subscriptions.\n this.messageSubscribers.length = 0;\n this.stateSubscribers.length = 0;\n this.pvtUnsubscribeAll();\n // Drop any handoff state this process carried as an unowned orphan.\n this.unparent();\n\n // Settle waiters.\n this.pvtResolveReady();\n this.exitWaiter.resolve();\n this.pvtExitReject = null;\n\n if (opts?.cascade) {\n // Stop the children too, starting with the nice stop (fire-and-forget:\n // the hard kill itself does not block on their graceful exit).\n const selfSender: SenderInfo = { fromName: this.pname, fromId: this.id };\n for (const child of this.children) {\n void child.stop({ force: true, from: selfSender }).catch(() => {});\n }\n }\n }\n\n /**\n * Stop this process. Sends STOP (the nice way — the generator cooperates\n * and its `finally` runs) and awaits on a best-effort basis.\n *\n * With `{ force: true }`, when the process refuses (does not exit within the\n * timeout) it escalates: fires `generator.return()` *without awaiting* (throw\n * the generator away for GC to find), cascades to children with the same\n * ladder, then hard-kills itself.\n *\n * Resolves `true` if the process stopped (gracefully or forced), `false` if\n * it refused and `force` was not requested.\n */\n async stop(opts?: { force?: boolean; from?: SenderInfo }): Promise<boolean> {\n if (this.pvtDead) return true;\n\n this.send({ type: \"STOP\" } as StopMessage, opts?.from);\n\n try {\n await withTimeout(this.wait(), CHILD_STOP_TIMEOUT_MS, \"stop\");\n return true;\n } catch (e) {\n if ((e as Error)?.message !== \"Timeout:stop\") throw e;\n // refused to stop within the timeout\n }\n\n if (!opts?.force) return false;\n\n // Escalate: give the finally a chance to run (fire-and-forget), but do not\n // block on it — the process may be stuck awaiting a dead promise.\n void this.current?.return(undefined);\n\n // Cascade to children with the same ladder, stamped from this process.\n const selfSender: SenderInfo = { fromName: this.pname, fromId: this.id };\n await Promise.all(\n [...this.children].map((child) => child.stop({ force: true, from: selfSender })),\n );\n\n this.forceStop();\n return true;\n }\n\n // ---- waiting --------------------------------------------------------------\n\n /**\n * Returns a promise that resolves when the generator completes, or\n * rejects if an unhandled error occurs during message processing.\n */\n wait(): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n this.pvtExitReject = reject;\n\n this.exitWaiter.promise.then(\n () => {\n this.pvtExitReject = null;\n resolve();\n },\n (e) => {\n this.pvtExitReject = null;\n reject(e);\n },\n );\n });\n }\n\n // ---- child messages -------------------------------------------------------\n\n /**\n * Tap another process's message channel: every message it emits is fed\n * into this process's incoming queue. No ownership — the sender's EXIT\n * does not touch `children`/`orphans`.\n */\n monitor<ChildArgs, ChildState, ChildIM extends Message, ChildOM extends Message>(\n child: AsyncProcess<ChildArgs, ChildState, ChildIM, ChildOM, {}>,\n ): () => void {\n const unsub = child.subscribe(\"message\", (msg, from) => {\n this.send([msg, from] as WithSender<InMessage | StopMessage>);\n });\n this.pvtOutgoingSubscriptions.push(unsub);\n return unsub;\n }\n\n /**\n * Claim another process as a child: its messages are routed here and its\n * EXIT removes it from `children` (collecting its orphans). Generalizes\n * what `fork` does — used for both spawning and orphan adoption.\n */\n adopt<ChildArgs, ChildState, ChildIM extends Message, ChildOM extends Message>(\n child: AsyncProcess<ChildArgs, ChildState, ChildIM, ChildOM, {}>,\n ): () => void {\n this.children.push(child as unknown as AnyProcess);\n const unsub = child.subscribe(\"message\", (msg, from) => {\n this.pvtChildMessage(msg, from);\n });\n this.pvtAdoptUnsubs.set(child.id, unsub);\n // Lossless handoff: drain a pending buffer left by the previous parent.\n this.pvtDrainPending(child as unknown as AnyProcess);\n return unsub;\n }\n\n /** Handles a child's emitted message: EXIT cleanup + forward to the queue. */\n private pvtChildMessage(msg: Message, sender: SenderInfo): void {\n if (msg.type === \"EXIT\") {\n // sender.fromId === child's id (stamped by the child's ctx.toParent)\n // Mutate in place so ctx.children (a live reference) stays consistent.\n const idx = this.children.findIndex((p) => p.id === sender.fromId);\n if (idx >= 0) this.children.splice(idx, 1);\n const orphans = (msg as ExitMessage).orphans;\n if (orphans && orphans.length > 0) {\n this.orphans.push(...orphans);\n }\n }\n this.send([msg, sender] as WithSender<InMessage | StopMessage>);\n }\n\n // ---- orphan handoff -------------------------------------------------------\n\n /** Unsubscribe from all outgoing subscriptions (monitors + adopt). */\n private pvtUnsubscribeAll(): void {\n for (const unsub of this.pvtOutgoingSubscriptions) unsub();\n this.pvtOutgoingSubscriptions = [];\n for (const unsub of this.pvtAdoptUnsubs.values()) unsub();\n this.pvtAdoptUnsubs.clear();\n }\n\n /** Prepare surviving children and inherited orphans for a lossless handoff:\n * recover undrained messages and install a collector on each orphan. */\n private pvtPrepareHandoff(orphans: Array<AnyProcess>): void {\n for (const orphan of orphans) {\n this.pvtBackFeed(orphan);\n if (!orphan.pvtCollectorUnsub) {\n this.pvtSwapToCollector(orphan);\n }\n }\n }\n\n /** Recover messages the orphan emitted into my inbox that I never drained. */\n private pvtBackFeed(orphan: AnyProcess): void {\n const fromOrphan: Array<WithSender<Message>> = [];\n this.buffer = this.buffer.filter((entry) => {\n if (entry[1].fromId === orphan.id) {\n fromOrphan.push(entry);\n return false;\n }\n return true;\n });\n if (fromOrphan.length === 0) return;\n if (!orphan.pvtPending) orphan.pvtPending = [];\n orphan.pvtPending.unshift(...fromOrphan);\n }\n\n /** Replace my ownership subscription to `orphan` with a handoff collector. */\n private pvtSwapToCollector(orphan: AnyProcess): void {\n const mine = this.pvtAdoptUnsubs.get(orphan.id);\n if (mine) {\n mine();\n this.pvtAdoptUnsubs.delete(orphan.id);\n }\n if (!orphan.pvtPending) orphan.pvtPending = [];\n const pending = orphan.pvtPending;\n orphan.pvtCollectorUnsub = orphan.subscribe(\"message\", (msg, from) => {\n pending.push([msg, from]);\n });\n }\n\n /** Drain a handed-off orphan's pending buffer into my inbox (lossless adopt). */\n private pvtDrainPending(orphan: AnyProcess): void {\n if (orphan.pvtCollectorUnsub) {\n orphan.pvtCollectorUnsub();\n orphan.pvtCollectorUnsub = null;\n }\n const pending = orphan.pvtPending;\n if (!pending) return;\n orphan.pvtPending = null;\n for (const [msg, from] of pending) {\n this.pvtChildMessage(msg, from);\n }\n }\n\n /**\n * Drop this process's handoff state (collector + pending buffer) without\n * stopping it. Used by `onOrphan`'s \"unparent\" decision: the orphan keeps\n * running and stays in the orphans list, but its in-flight buffer is gone.\n */\n unparent(): void {\n if (this.pvtCollectorUnsub) {\n this.pvtCollectorUnsub();\n this.pvtCollectorUnsub = null;\n }\n this.pvtPending = null;\n }\n}\nexport type AnyProcess = AsyncProcess<unknown, unknown, Message, Message, {}>;\n// ---- spawnAsync -------------------------------------------------------------\n\n/**\n * Spawn a new async process. Accepts both sync and async process\n * functions — sync ones are automatically wrapped with {@link asyncify}.\n */\nexport function spawnAsync<\n Args,\n State,\n InMessage extends Message = Message,\n OutMessage extends Message = ExitMessage,\n>(\n fn: AsyncProcessFn<Args, State, InMessage, OutMessage>,\n pname: string,\n toParent?: MessageCallback<OutMessage>,\n parentName?: string | null,\n parentId?: symbol | null,\n): (args: Args) => AsyncProcess<Args, State, InMessage, OutMessage, {}> {\n return (args: Args) => {\n const proc = new AsyncProcess<Args, State, InMessage, OutMessage, {}>(fn, pname, toParent);\n proc.start(args, parentName, parentId);\n return proc;\n };\n}\n","// ── defineActor — high-level actor wrapper ───────────────────────────────────\n//\n// Compiles a declarative config into an AsyncProcessFn. Built on top of\n// the existing runDispatchAsync / spawnAsync primitives.\n//\nimport { type AsyncProcess, runDispatchAsync, spawnAsync, AnyProcess } from \"./process.async.js\";\nimport type {\n WithSender,\n SenderInfo,\n AsyncProcessFn,\n Message,\n ExitMessage,\n ProcessCtx,\n} from \"./types.js\";\nimport type {\n ActorDefinition,\n ActorConfig,\n ActorContext,\n MethodOptions,\n ActorMessages,\n HandlerOptions,\n HandlerFn,\n ReflectionOptions,\n AnyConfig,\n HidePrivate,\n} from \"./actor-types.js\";\nimport { STOP_SENTINEL } from \"./actor-types.js\";\nimport { ActorDecorated, type ActorPlugin, ActorReflection, callHook } from \"./hooks.js\";\n\nexport function defineMessages<OutMsg extends Message = Message>(): ActorMessages<OutMsg> {\n return undefined as unknown as ActorMessages<OutMsg>;\n}\n\nfunction hidePrivate<T>(value: T): HidePrivate<T> {\n if (value && typeof value === \"object\" && \"private\" in value && \"public\" in value) {\n return value.public as HidePrivate<T>;\n }\n return value as HidePrivate<T>;\n}\n\nfunction resolvePlugins(\n raw: ActorPlugin[] | ((parents: ActorPlugin[]) => ActorPlugin[]) | undefined,\n parentPlugins?: ActorPlugin[],\n addPlugins?: ActorPlugin[],\n): ActorPlugin[] {\n const resolved = !raw\n ? parentPlugins\n ? [...parentPlugins]\n : []\n : Array.isArray(raw)\n ? [...raw]\n : raw(parentPlugins ?? []);\n\n const combined = addPlugins ? [...resolved, ...addPlugins] : resolved;\n\n // Deduplicate by function name\n const seen = new Set<string>();\n return combined.filter((p) => {\n const name = p.name;\n if (!name) {\n console.warn(\"posipaki: plugin has no name, dedup won't work\");\n return true;\n }\n if (seen.has(name)) return false;\n seen.add(name);\n return true;\n });\n}\n\nasync function assembleActor<C>(\n config: C,\n plugins: ActorPlugin[],\n addPlugins?: ActorPlugin[],\n): Promise<C> {\n // Work with the default ActorPlugin type internally, cast back on return\n let cur = config as AnyConfig;\n for (const p of plugins) {\n try {\n cur = await p(cur);\n } catch (e: unknown) {\n console.error(`[assembleActor] plugin \"${p.name || \"?\"}\" failed:`, e);\n }\n }\n cur.resolvedPlugins = plugins;\n if (addPlugins) cur.addPlugins = addPlugins;\n return cur as C;\n}\n\nexport function defineActor<\n Args,\n InternalState,\n InMsg extends Message,\n OutMsg extends Message,\n Methods extends MethodOptions,\n Handlers extends HandlerOptions<InMsg>,\n ReflectionMethods extends ReflectionOptions,\n>(\n config: ActorConfig<Args, InternalState, InMsg, OutMsg, Methods, Handlers, ReflectionMethods>,\n): ActorDefinition<Args, InternalState, InMsg, OutMsg, ReflectionMethods> {\n const actorCtxMap = new Map<\n symbol,\n ActorContext<Args, InternalState, InMsg, OutMsg, Methods, Handlers, ReflectionMethods>\n >();\n\n function makeRuntime(\n assembly: ActorConfig<Args, InternalState, InMsg, OutMsg, Methods, Handlers, ReflectionMethods>,\n ): AsyncProcessFn<Args, HidePrivate<InternalState>, InMsg, OutMsg> {\n return async function* (\n ctx,\n args,\n ): AsyncGenerator<HidePrivate<InternalState | null>, void, WithSender<InMsg>> {\n let done = false;\n let exitReason: unknown;\n let rawState: InternalState = undefined as unknown as InternalState;\n\n const decorated = new Map();\n const self: ActorContext<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods & ActorReflection\n > = {\n ctx,\n ...((assembly.methods || {}) as Methods),\n ...((assembly.$decorate || {}) as ActorDecorated),\n reflection: {} as ReflectionMethods & ActorReflection,\n state: rawState,\n name: ctx.pname,\n id: ctx.id,\n async emit(msg: OutMsg) {\n await callHook(assembly.onEmit, undefined, self, msg, {\n fromName: ctx.pname,\n fromId: ctx.id,\n });\n ctx.toParent(msg);\n },\n agreeToStop() {\n exitReason = \"stopped\";\n done = true;\n },\n exit(reason: unknown) {\n exitReason = reason;\n done = true;\n },\n $child: {} as Record<string, AnyProcess>,\n decorators: {},\n fork: async <A, S, IM extends Message, OM extends InMsg, R extends ReflectionOptions>(\n childActor: ActorDefinition<A, S, IM, OM, R>,\n childArgs?: A,\n forkOpts?: { name?: string; addPlugins?: ActorPlugin[] },\n ): Promise<AsyncProcess<A, HidePrivate<S>, IM, OM, R & ActorReflection>> => {\n let child: AsyncProcess<A, HidePrivate<S>, IM, OM, R & ActorReflection>;\n const childName =\n forkOpts?.name ?? childActor?.name ?? `child-${Object.keys(self.$child).length}`;\n const treeName = `${ctx.pname}:${childName}`;\n const childAddPlugins = [...(assembly.addPlugins || []), ...(forkOpts?.addPlugins || [])];\n child = await childActor.spawnAsChild(ctx, childArgs!, {\n name: treeName,\n parentPlugins: assembly.resolvedPlugins || [],\n ...(childAddPlugins.length ? { addPlugins: childAddPlugins } : {}),\n });\n self.$child[child.pname] = child as unknown as AnyProcess;\n return child;\n },\n };\n actorCtxMap.set(ctx.id, self);\n ctx.afterExit = async () => {\n await callHook(assembly.afterEnd, assembly.onError, self, exitReason);\n };\n\n for (const [k, v] of decorated) {\n (self as Record<string, unknown>)[k] = v;\n }\n\n await callHook(\n assembly.beforeStart,\n assembly.onError,\n self as ActorContext<\n Args,\n never, // state not set yet\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods & ActorReflection\n >,\n );\n\n if (assembly.setup) {\n rawState = await assembly.setup.call(\n self as ActorContext<\n Args,\n never, // break inference cycle here\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods & ActorReflection\n >,\n args,\n );\n } else {\n rawState = null as InternalState;\n }\n self.state = rawState;\n yield hidePrivate(rawState);\n await callHook(assembly.afterStart, assembly.onError, self);\n\n yield* runDispatchAsync<WithSender<InMsg | ExitMessage>>(\n ctx.pname,\n async (stamped) => {\n const [msg, sender] = stamped;\n if (msg.type === \"STOP\") {\n if (assembly.onStopRequested) {\n await callHook(assembly.onStopRequested, assembly.onError, self);\n // Hook may call agreeToStop(). If not, actor keeps running.\n } else {\n exitReason = \"stopped\";\n done = true;\n }\n return;\n }\n if (msg.type === \"EXIT\") {\n // FIXME: process name are user-specified\n // and should not be used for indexing so\n // we don't get into name conflicts\n const childName = sender.fromName;\n if (childName && self.$child[childName]) {\n delete self.$child[childName];\n }\n await callHook(\n assembly.onChildExit,\n assembly.onError,\n self,\n childName,\n msg as ExitMessage,\n );\n // Orphan policy: a child that exits may leave still-running\n // grandchildren behind (see ctx-orphans / orphan-policy).\n const orphans = (msg as ExitMessage).orphans;\n if (orphans && orphans.length > 0) {\n for (const orphan of orphans) {\n // Default when no hook is defined: hard-kill the orphan.\n const decision = assembly.onOrphan\n ? await callHook(assembly.onOrphan, assembly.onError, self, orphan)\n : \"force-stop\";\n if (decision === \"adopt\") {\n ctx.adopt(orphan);\n const idx = ctx.orphans.indexOf(orphan);\n if (idx >= 0) ctx.orphans.splice(idx, 1);\n self.$child[orphan.pname] = orphan;\n } else if (decision === \"force-stop\") {\n orphan.forceStop({ cascade: true });\n const idx = ctx.orphans.indexOf(orphan);\n if (idx >= 0) ctx.orphans.splice(idx, 1);\n } else if (decision === \"unparent\") {\n orphan.unparent();\n }\n // 'leave' (or undefined) → do nothing; it propagates on exit.\n }\n }\n }\n let hookStopped = false;\n if (msg.type !== \"STOP\" && msg.type !== \"EXIT\" && assembly.onMessage) {\n const result = await callHook(\n assembly.onMessage,\n assembly.onError,\n self,\n msg as InMsg,\n sender,\n );\n if (result === STOP_SENTINEL) hookStopped = true;\n }\n if (msg.type !== \"STOP\" && !hookStopped) {\n const handler =\n ((assembly.handlers || ({} as Handlers))[\n msg.type as keyof Handlers\n ] as HandlerFn<InMsg>) || assembly.onUnhandled;\n\n await callHook(handler, assembly.onError, self, msg as InMsg, sender);\n }\n },\n () => done,\n );\n\n await callHook(assembly.beforeEnd, assembly.onError, self, exitReason);\n };\n }\n\n type ReflectableProcess = {\n id: symbol;\n $reflection: Record<string, Function>;\n };\n function attachReflection(\n proc: ReflectableProcess,\n reflectionMethods: ReflectionMethods | undefined,\n ): void {\n if (!reflectionMethods) return;\n const self = actorCtxMap.get(proc.id);\n const refl = proc.$reflection as Record<string, Function>;\n for (const [k, m] of Object.entries(reflectionMethods)) {\n refl[k] = m.bind(self);\n }\n }\n\n return {\n fn: makeRuntime(config),\n name: config.name,\n pvtPluginsRaw: config.plugins,\n inMessages: config.inMessages,\n outMessages: config.outMessages,\n async spawn(\n args: Args,\n opts?: {\n name?: string;\n toParent?: (msg: OutMsg, from: SenderInfo) => void;\n addPlugins?: ActorPlugin[];\n parentName?: string | null;\n parentId?: symbol | null;\n },\n ): Promise<\n AsyncProcess<\n Args,\n HidePrivate<InternalState>,\n InMsg,\n OutMsg,\n ReflectionMethods & ActorReflection\n >\n > {\n const plugs = resolvePlugins(config.plugins, undefined, opts?.addPlugins);\n const assembly = await assembleActor(config, plugs, opts?.addPlugins);\n const runtime = makeRuntime(assembly);\n const proc = spawnAsync(\n runtime,\n opts?.name ?? assembly.name ?? \"actor\",\n opts?.toParent,\n opts?.parentName,\n opts?.parentId,\n )(args);\n attachReflection(proc, assembly.$reflectionMethods as ReflectionMethods);\n return proc as AsyncProcess<\n Args,\n HidePrivate<InternalState>,\n InMsg,\n OutMsg,\n ReflectionMethods & ActorReflection\n >;\n },\n async spawnAsChild(\n ctx: ProcessCtx<unknown, unknown, OutMsg, Message>,\n args: Args,\n opts?: {\n name?: string;\n parentPlugins?: ActorPlugin[];\n addPlugins?: ActorPlugin[];\n },\n ) {\n const plugs = resolvePlugins(config.plugins, opts?.parentPlugins, opts?.addPlugins);\n const assembly = await assembleActor(config, plugs, opts?.addPlugins);\n const runtime = makeRuntime(assembly);\n const proc = ctx.fork(runtime, opts?.name ?? assembly.name ?? \"child\")(args);\n attachReflection(proc, assembly.$reflectionMethods as ReflectionMethods);\n return proc as AsyncProcess<\n Args,\n HidePrivate<InternalState>,\n InMsg,\n OutMsg,\n ReflectionMethods & ActorReflection\n >;\n },\n };\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { d as AnyProcess, f as AsyncProcess, i as ProcessCtx, n as ExitMessage, o as SenderInfo, r as Message, t as AsyncProcessFn } from "./types-Dbe4BSPC.js";
1
+ import { d as AnyProcess, f as AsyncProcess, i as ProcessCtx, n as ExitMessage, o as SenderInfo, r as Message, t as AsyncProcessFn } from "./types-BsynPeOf.js";
2
2
  //#region src/actor-types.d.ts
3
3
  type ActorMessages<M extends Message> = {
4
4
  __tag_messages: M;
@@ -162,4 +162,4 @@ type Hook<T, I extends unknown[], O> = (this: T, ...args: I) => O;
162
162
  declare function callHook<T, I extends unknown[], O>(fn: Hook<T, I, O> | undefined, eh: ((e: unknown) => unknown) | undefined, thisArg: T, ...args: I): Promise<O | undefined>;
163
163
  //#endregion
164
164
  export { ReflectionOptions as _, chainHook as a, stopPropagation as b, ActorContext as c, ActorPlugin as d, HandlerFn as f, PluginTransform as g, MethodOptions as h, callHook as i, ActorDefinition as l, HookResult as m, ActorReflection as n, mergeConfigs as o, HandlerOptions as p, Hook as r, ActorConfig as s, ActorDecorated as t, ActorMessages as u, STOP_SENTINEL as v, SpawnedFrom as y };
165
- //# sourceMappingURL=hooks-Dnmr7Ain.d.ts.map
165
+ //# sourceMappingURL=hooks-DDlJQJi_.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hooks-Dnmr7Ain.d.ts","names":[],"sources":["../src/actor-types.ts","../src/hooks.ts"],"mappings":"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"}
1
+ {"version":3,"file":"hooks-DDlJQJi_.d.ts","names":[],"sources":["../src/actor-types.ts","../src/hooks.ts"],"mappings":"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"}
package/dist/hooks.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as chainHook, b as stopPropagation, d as ActorPlugin, g as PluginTransform, i as callHook, m as HookResult, n as ActorReflection, o as mergeConfigs, r as Hook, t as ActorDecorated, v as STOP_SENTINEL } from "./hooks-Dnmr7Ain.js";
1
+ import { a as chainHook, b as stopPropagation, d as ActorPlugin, g as PluginTransform, i as callHook, m as HookResult, n as ActorReflection, o as mergeConfigs, r as Hook, t as ActorDecorated, v as STOP_SENTINEL } from "./hooks-DDlJQJi_.js";
2
2
  export { ActorDecorated, type ActorPlugin, ActorReflection, Hook, type HookResult, type PluginTransform, STOP_SENTINEL, callHook, chainHook, mergeConfigs, stopPropagation };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { a as ProcessFn, c as StopMessage, d as AnyProcess, f as AsyncProcess, i as ProcessCtx, l as WithSender, m as spawnAsync, n as ExitMessage, o as SenderInfo, p as runDispatchAsync, r as Message, s as SenderOrigin, t as AsyncProcessFn, u as WithoutSender } from "./types-Dbe4BSPC.js";
2
- import { _ as ReflectionOptions, a as chainHook, b as stopPropagation, c as ActorContext, d as ActorPlugin, f as HandlerFn, g as PluginTransform, h as MethodOptions, i as callHook, l as ActorDefinition, m as HookResult, n as ActorReflection, o as mergeConfigs, p as HandlerOptions, s as ActorConfig, t as ActorDecorated, u as ActorMessages, y as SpawnedFrom } from "./hooks-Dnmr7Ain.js";
3
- import { n as spawn, t as Process } from "./process-BTC8JV8_.js";
1
+ import { a as ProcessFn, c as StopMessage, d as AnyProcess, f as AsyncProcess, i as ProcessCtx, l as WithSender, m as spawnAsync, n as ExitMessage, o as SenderInfo, p as runDispatchAsync, r as Message, s as SenderOrigin, t as AsyncProcessFn, u as WithoutSender } from "./types-BsynPeOf.js";
2
+ import { _ as ReflectionOptions, a as chainHook, b as stopPropagation, c as ActorContext, d as ActorPlugin, f as HandlerFn, g as PluginTransform, h as MethodOptions, i as callHook, l as ActorDefinition, m as HookResult, n as ActorReflection, o as mergeConfigs, p as HandlerOptions, s as ActorConfig, t as ActorDecorated, u as ActorMessages, y as SpawnedFrom } from "./hooks-DDlJQJi_.js";
3
+ import { n as spawn, t as Process } from "./process-C9Gb0qKx.js";
4
4
  //#region src/util.d.ts
5
5
  type ReducerClosure<M> = (msg: M) => void;
6
6
  type ReadyFn = () => boolean;
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { i as runDispatch } from "./util-Brtfgv68.js";
2
- import { a as spawnAsync, i as runDispatchAsync, n as defineMessages, o as asyncify, r as AsyncProcess, t as defineActor } from "./define-actor-Dg5_koH3.js";
2
+ import { a as spawnAsync, i as runDispatchAsync, n as defineMessages, o as asyncify, r as AsyncProcess, t as defineActor } from "./define-actor-BgC4BUK8.js";
3
3
  import { a as stopPropagation, n as chainHook, r as mergeConfigs, t as callHook } from "./hooks-V-PEPJHv.js";
4
4
  //#region src/process.ts
5
5
  /** @deprecated Use {@link spawnAsync} instead. */
@@ -1,4 +1,4 @@
1
- import { t as defineActor } from "./define-actor-Dg5_koH3.js";
1
+ import { t as defineActor } from "./define-actor-BgC4BUK8.js";
2
2
  import { a as stopPropagation } from "./hooks-V-PEPJHv.js";
3
3
  //#region src/remote/channel.ts
4
4
  function isProto(msg) {
@@ -112,8 +112,10 @@ function remoteClient(name, spawner) {
112
112
  exitResolver = resolve;
113
113
  });
114
114
  channel.onMessage((frame) => {
115
- if (isState(frame)) Object.assign(currentState, frame.$state);
116
- else if (isMsg(frame)) this.emit(frame.$msg.body);
115
+ if (isState(frame)) {
116
+ Object.assign(currentState, frame.$state);
117
+ this.ctx.notify();
118
+ } else if (isMsg(frame)) this.emit(frame.$msg.body);
117
119
  else if (isExit(frame)) {
118
120
  if (exitResolver) {
119
121
  exitResolver({
@@ -195,4 +197,4 @@ function json1Channel(transport) {
195
197
  //#endregion
196
198
  export { remoteClient as a, isExit as c, isProto as d, isState as f, json1Channel as i, isInit as l, decode as n, makeSender as o, encode as r, serveRemoteActor as s, VERSION as t, isMsg as u };
197
199
 
198
- //# sourceMappingURL=json1-tKb32fT6.js.map
200
+ //# sourceMappingURL=json1-BHNbVSW_.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"json1-tKb32fT6.js","names":[],"sources":["../src/remote/channel.ts","../src/remote/server.ts","../src/remote/client.ts","../src/remote/protocols/json1.ts"],"sourcesContent":["// ── Frame channel ──────────────────────────────────────────────────────────\n//\n// The seam's shared vocabulary. A StringTransport moves encoded frames\n// (strings); a Channel moves decoded frame objects. The frame guards narrow a\n// decoded frame to one of the `$`-key shapes. server.ts / client.ts speak only\n// in Channels and these guards — they never see a specific protocol or\n// transport.\n\nimport type { Message } from \"../types.js\";\n\nexport interface StringTransport {\n send(frame: string): void | Promise<void>;\n onMessage(handler: (frame: string) => void): void;\n removeHandler(): void;\n /** Fires when the peer disconnects (transport closes from the other side). */\n onClose(handler: () => void): void;\n close(): Promise<void>;\n}\n\nexport interface Channel {\n send(frame: Record<string, unknown>): void | Promise<void>;\n onMessage(handler: (frame: Record<string, unknown>) => void): void;\n removeHandler(): void;\n /** Fires when the peer disconnects (transport closes from the other side). */\n onClose(handler: () => void): void;\n close(): Promise<void>;\n}\n\n// ── frame guards ──────────────────────────────────────────────────────────\n\nexport function isProto(msg: Record<string, unknown>): msg is { $proto: string } {\n return \"$proto\" in msg;\n}\nexport function isInit(msg: Record<string, unknown>): msg is { $init: Record<string, unknown> } {\n return \"$init\" in msg;\n}\nexport function isState(msg: Record<string, unknown>): msg is { $state: Record<string, unknown> } {\n return \"$state\" in msg;\n}\nexport function isMsg(\n msg: Record<string, unknown>,\n): msg is { $msg: { fromName: string; body: Message } } {\n return \"$msg\" in msg;\n}\nexport function isExit(\n msg: Record<string, unknown>,\n): msg is { $exit: { code: number; state: unknown } } {\n return \"$exit\" in msg;\n}\n","// ── Server side of the seam ────────────────────────────────────────────────\n//\n// serveRemoteActor serves a posipaki actor over a frame Channel produced by a\n// spawner. It knows only the frame vocabulary (channel.ts) — no protocol, no\n// transport, no spawner. The spawner has already done the $proto handshake.\n\nimport type { ActorDefinition, ReflectionOptions } from \"../actor-types.js\";\nimport type { Message } from \"../types.js\";\nimport type { Channel } from \"./channel.js\";\nimport { isInit, isMsg } from \"./channel.js\";\n\nexport type Spawner = () => Promise<Channel>;\n\nexport function makeSender(\n fromName: string,\n parentName: string | null,\n parentId: symbol | null,\n): { fromName: string; fromId: symbol } {\n if (parentId && fromName === parentName) {\n return { fromName, fromId: parentId };\n }\n return { fromName, fromId: Symbol() };\n}\n\nexport async function serveRemoteActor<\n Args,\n State,\n InMsg extends Message,\n OutMsg extends Message,\n R extends ReflectionOptions,\n>(actor: ActorDefinition<Args, State, InMsg, OutMsg, R>, spawner: Spawner): Promise<void> {\n const channel = await spawner();\n\n // await $init\n const initFrame = await new Promise<Record<string, unknown>>((resolve) => {\n channel.onMessage((frame) => resolve(frame));\n });\n channel.removeHandler();\n if (!isInit(initFrame)) {\n throw new Error(\"serveRemoteActor: expected $init\");\n }\n\n const init = initFrame.$init;\n const parentName = (init.parentName as string) ?? null;\n const parentIdName = (init.parentIdName as string) ?? null;\n const parentId = parentIdName ? Symbol.for(parentIdName) : null;\n const { parentName: _pn, parentIdName: _pid, ...initArgs } = init;\n\n const proc = await actor.spawn(initArgs as unknown as Args, {\n name: \"remote\",\n parentName,\n parentId,\n });\n\n // bridge actor output → channel\n proc.subscribe(\"message\", async (msg, sender) => {\n try {\n await channel.send({ $msg: { fromName: sender.fromName, body: msg } });\n } catch {\n console.error(\"Error sending out the message\");\n }\n });\n proc.subscribe(\"state\", async () => {\n try {\n await channel.send({ $state: proc.state as Record<string, unknown> });\n } catch (e) {\n console.error(\"Error sending out the message\", e);\n }\n });\n\n await proc.ready();\n await channel.send({ $state: proc.state as Record<string, unknown> });\n\n // bridge channel input → actor\n channel.onMessage((frame) => {\n if (isMsg(frame)) {\n const { fromName, body } = frame.$msg;\n proc.send(body as InMsg, makeSender(fromName, parentName, parentId));\n }\n });\n\n // await actor exit, announce it, close\n let code = 0;\n try {\n await proc.wait();\n } catch (err) {\n console.error(\"server actor error:\", err);\n code = 1;\n }\n await channel.send({ $exit: { code, state: proc.state } });\n await channel.close();\n}\n","// ── Client side of the seam ────────────────────────────────────────────────\n//\n// remoteClient builds a posipaki actor that talks to a remote server through a\n// frame Channel produced by a spawner. It knows only the frame vocabulary\n// (channel.ts) — no protocol, no transport, no spawner. The spawner has\n// already done the $proto handshake.\n\nimport { defineActor } from \"../define-actor.js\";\nimport { stopPropagation } from \"../hooks.js\";\nimport type { HookResult } from \"../hooks.js\";\nimport type { ActorDefinition, HandlerOptions, MethodOptions, ReflectionOptions } from \"../actor-types.js\";\nimport type { Message } from \"../types.js\";\nimport type { Channel } from \"./channel.js\";\nimport { isState, isMsg, isExit } from \"./channel.js\";\n\nexport type ClientSpawner<Args> = (args: Args) => Promise<Channel>;\n\nexport function remoteClient<\n Args,\n State,\n InMsg extends Message,\n OutMsg extends Message,\n Methods extends MethodOptions = MethodOptions,\n Handlers extends HandlerOptions<InMsg> = HandlerOptions<InMsg>,\n R extends ReflectionOptions = ReflectionOptions,\n>(\n name: string,\n spawner: ClientSpawner<Args>,\n): ActorDefinition<Args, State, InMsg, OutMsg, R> {\n const proxyDef = defineActor<\n Args,\n { public: State; private: { channel: Channel; exitPromise: Promise<{ code: number | null; state: State }>; fromName: string } },\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n R\n >({\n name,\n handlers: {} as unknown as Handlers,\n async setup(args: Args) {\n const channel = await spawner(args);\n const fromName = name;\n await channel.send({\n $init: { ...(args as unknown as Record<string, unknown>), parentName: fromName, parentIdName: fromName },\n });\n\n let currentState: Record<string, unknown> = {};\n await new Promise<void>((resolve) => {\n channel.onMessage((frame) => {\n if (isState(frame)) {\n Object.assign(currentState, frame.$state);\n resolve();\n }\n });\n });\n channel.removeHandler();\n\n let exitResolver: ((v: { code: number | null; state: State }) => void) | null = null;\n const exitPromise = new Promise<{ code: number | null; state: State }>((resolve) => {\n exitResolver = resolve;\n });\n\n channel.onMessage((frame) => {\n if (isState(frame)) {\n Object.assign(currentState, frame.$state);\n } else if (isMsg(frame)) {\n this.emit(frame.$msg.body as OutMsg);\n } else if (isExit(frame)) {\n if (exitResolver) {\n exitResolver({ code: frame.$exit.code, state: frame.$exit.state as State });\n exitResolver = null;\n }\n }\n });\n channel.onClose(() => {\n if (exitResolver) {\n exitResolver({ code: null, state: currentState as State });\n exitResolver = null;\n }\n });\n\n return {\n public: currentState as State,\n private: { channel, exitPromise, fromName },\n };\n },\n async onMessage(msg: InMsg): Promise<HookResult> {\n this.state.private.channel?.send({ $msg: { fromName: this.state.private.fromName, body: msg } });\n return stopPropagation();\n },\n async onStopRequested() {\n if (this.state.private.channel) {\n this.state.private.channel.send({ $msg: { fromName: this.state.private.fromName, body: { type: \"STOP\" } } });\n await this.state.private.exitPromise;\n }\n this.agreeToStop();\n },\n async afterEnd() {\n if (this.state.private.channel) {\n await this.state.private.channel.close();\n }\n },\n });\n\n return proxyDef as unknown as ActorDefinition<Args, State, InMsg, OutMsg, R>;\n}\n","// ── json1 wire protocol ────────────────────────────────────────────────────\n//\n// One JSON object per frame: `{\"$key\": value}`. encode/decode turn a decoded\n// frame object into a string and back. json1Channel wraps a StringTransport so\n// it moves frame objects instead of strings.\n\nimport type { Channel, StringTransport } from \"../channel.js\";\n\nexport const VERSION = \"json.v1\";\n\nexport function encode(frame: Record<string, unknown>): string {\n return JSON.stringify(frame);\n}\n\nexport function decode(str: string): Record<string, unknown> {\n return JSON.parse(str);\n}\n\nexport function json1Channel(transport: StringTransport): Channel {\n return {\n send(frame) {\n return transport.send(encode(frame));\n },\n onMessage(handler) {\n transport.onMessage((str) => handler(decode(str)));\n },\n removeHandler() {\n transport.removeHandler();\n },\n onClose(handler) {\n transport.onClose(handler);\n },\n close() {\n return transport.close();\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"json1-BHNbVSW_.js","names":[],"sources":["../src/remote/channel.ts","../src/remote/server.ts","../src/remote/client.ts","../src/remote/protocols/json1.ts"],"sourcesContent":["// ── Frame channel ──────────────────────────────────────────────────────────\n//\n// The seam's shared vocabulary. A StringTransport moves encoded frames\n// (strings); a Channel moves decoded frame objects. The frame guards narrow a\n// decoded frame to one of the `$`-key shapes. server.ts / client.ts speak only\n// in Channels and these guards — they never see a specific protocol or\n// transport.\n\nimport type { Message } from \"../types.js\";\n\nexport interface StringTransport {\n send(frame: string): void | Promise<void>;\n onMessage(handler: (frame: string) => void): void;\n removeHandler(): void;\n /** Fires when the peer disconnects (transport closes from the other side). */\n onClose(handler: () => void): void;\n close(): Promise<void>;\n}\n\nexport interface Channel {\n send(frame: Record<string, unknown>): void | Promise<void>;\n onMessage(handler: (frame: Record<string, unknown>) => void): void;\n removeHandler(): void;\n /** Fires when the peer disconnects (transport closes from the other side). */\n onClose(handler: () => void): void;\n close(): Promise<void>;\n}\n\n// ── frame guards ──────────────────────────────────────────────────────────\n\nexport function isProto(msg: Record<string, unknown>): msg is { $proto: string } {\n return \"$proto\" in msg;\n}\nexport function isInit(msg: Record<string, unknown>): msg is { $init: Record<string, unknown> } {\n return \"$init\" in msg;\n}\nexport function isState(msg: Record<string, unknown>): msg is { $state: Record<string, unknown> } {\n return \"$state\" in msg;\n}\nexport function isMsg(\n msg: Record<string, unknown>,\n): msg is { $msg: { fromName: string; body: Message } } {\n return \"$msg\" in msg;\n}\nexport function isExit(\n msg: Record<string, unknown>,\n): msg is { $exit: { code: number; state: unknown } } {\n return \"$exit\" in msg;\n}\n","// ── Server side of the seam ────────────────────────────────────────────────\n//\n// serveRemoteActor serves a posipaki actor over a frame Channel produced by a\n// spawner. It knows only the frame vocabulary (channel.ts) — no protocol, no\n// transport, no spawner. The spawner has already done the $proto handshake.\n\nimport type { ActorDefinition, ReflectionOptions } from \"../actor-types.js\";\nimport type { Message } from \"../types.js\";\nimport type { Channel } from \"./channel.js\";\nimport { isInit, isMsg } from \"./channel.js\";\n\nexport type Spawner = () => Promise<Channel>;\n\nexport function makeSender(\n fromName: string,\n parentName: string | null,\n parentId: symbol | null,\n): { fromName: string; fromId: symbol } {\n if (parentId && fromName === parentName) {\n return { fromName, fromId: parentId };\n }\n return { fromName, fromId: Symbol() };\n}\n\nexport async function serveRemoteActor<\n Args,\n State,\n InMsg extends Message,\n OutMsg extends Message,\n R extends ReflectionOptions,\n>(actor: ActorDefinition<Args, State, InMsg, OutMsg, R>, spawner: Spawner): Promise<void> {\n const channel = await spawner();\n\n // await $init\n const initFrame = await new Promise<Record<string, unknown>>((resolve) => {\n channel.onMessage((frame) => resolve(frame));\n });\n channel.removeHandler();\n if (!isInit(initFrame)) {\n throw new Error(\"serveRemoteActor: expected $init\");\n }\n\n const init = initFrame.$init;\n const parentName = (init.parentName as string) ?? null;\n const parentIdName = (init.parentIdName as string) ?? null;\n const parentId = parentIdName ? Symbol.for(parentIdName) : null;\n const { parentName: _pn, parentIdName: _pid, ...initArgs } = init;\n\n const proc = await actor.spawn(initArgs as unknown as Args, {\n name: \"remote\",\n parentName,\n parentId,\n });\n\n // bridge actor output → channel\n proc.subscribe(\"message\", async (msg, sender) => {\n try {\n await channel.send({ $msg: { fromName: sender.fromName, body: msg } });\n } catch {\n console.error(\"Error sending out the message\");\n }\n });\n proc.subscribe(\"state\", async () => {\n try {\n await channel.send({ $state: proc.state as Record<string, unknown> });\n } catch (e) {\n console.error(\"Error sending out the message\", e);\n }\n });\n\n await proc.ready();\n await channel.send({ $state: proc.state as Record<string, unknown> });\n\n // bridge channel input → actor\n channel.onMessage((frame) => {\n if (isMsg(frame)) {\n const { fromName, body } = frame.$msg;\n proc.send(body as InMsg, makeSender(fromName, parentName, parentId));\n }\n });\n\n // await actor exit, announce it, close\n let code = 0;\n try {\n await proc.wait();\n } catch (err) {\n console.error(\"server actor error:\", err);\n code = 1;\n }\n await channel.send({ $exit: { code, state: proc.state } });\n await channel.close();\n}\n","// ── Client side of the seam ────────────────────────────────────────────────\n//\n// remoteClient builds a posipaki actor that talks to a remote server through a\n// frame Channel produced by a spawner. It knows only the frame vocabulary\n// (channel.ts) — no protocol, no transport, no spawner. The spawner has\n// already done the $proto handshake.\n\nimport { defineActor } from \"../define-actor.js\";\nimport { stopPropagation } from \"../hooks.js\";\nimport type { HookResult } from \"../hooks.js\";\nimport type { ActorDefinition, HandlerOptions, MethodOptions, ReflectionOptions } from \"../actor-types.js\";\nimport type { Message } from \"../types.js\";\nimport type { Channel } from \"./channel.js\";\nimport { isState, isMsg, isExit } from \"./channel.js\";\n\nexport type ClientSpawner<Args> = (args: Args) => Promise<Channel>;\n\nexport function remoteClient<\n Args,\n State,\n InMsg extends Message,\n OutMsg extends Message,\n Methods extends MethodOptions = MethodOptions,\n Handlers extends HandlerOptions<InMsg> = HandlerOptions<InMsg>,\n R extends ReflectionOptions = ReflectionOptions,\n>(\n name: string,\n spawner: ClientSpawner<Args>,\n): ActorDefinition<Args, State, InMsg, OutMsg, R> {\n const proxyDef = defineActor<\n Args,\n { public: State; private: { channel: Channel; exitPromise: Promise<{ code: number | null; state: State }>; fromName: string } },\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n R\n >({\n name,\n handlers: {} as unknown as Handlers,\n async setup(args: Args) {\n const channel = await spawner(args);\n const fromName = name;\n await channel.send({\n $init: { ...(args as unknown as Record<string, unknown>), parentName: fromName, parentIdName: fromName },\n });\n\n let currentState: Record<string, unknown> = {};\n await new Promise<void>((resolve) => {\n channel.onMessage((frame) => {\n if (isState(frame)) {\n Object.assign(currentState, frame.$state);\n resolve();\n }\n });\n });\n channel.removeHandler();\n\n let exitResolver: ((v: { code: number | null; state: State }) => void) | null = null;\n const exitPromise = new Promise<{ code: number | null; state: State }>((resolve) => {\n exitResolver = resolve;\n });\n\n channel.onMessage((frame) => {\n if (isState(frame)) {\n Object.assign(currentState, frame.$state);\n // $state frames arrive outside this actor's dispatch loop; notify\n // state subscribers so observers (Vue, nextState, …) see the change.\n this.ctx.notify();\n } else if (isMsg(frame)) {\n this.emit(frame.$msg.body as OutMsg);\n } else if (isExit(frame)) {\n if (exitResolver) {\n exitResolver({ code: frame.$exit.code, state: frame.$exit.state as State });\n exitResolver = null;\n }\n }\n });\n channel.onClose(() => {\n if (exitResolver) {\n exitResolver({ code: null, state: currentState as State });\n exitResolver = null;\n }\n });\n\n return {\n public: currentState as State,\n private: { channel, exitPromise, fromName },\n };\n },\n async onMessage(msg: InMsg): Promise<HookResult> {\n this.state.private.channel?.send({ $msg: { fromName: this.state.private.fromName, body: msg } });\n return stopPropagation();\n },\n async onStopRequested() {\n if (this.state.private.channel) {\n this.state.private.channel.send({ $msg: { fromName: this.state.private.fromName, body: { type: \"STOP\" } } });\n await this.state.private.exitPromise;\n }\n this.agreeToStop();\n },\n async afterEnd() {\n if (this.state.private.channel) {\n await this.state.private.channel.close();\n }\n },\n });\n\n return proxyDef as unknown as ActorDefinition<Args, State, InMsg, OutMsg, R>;\n}\n","// ── json1 wire protocol ────────────────────────────────────────────────────\n//\n// One JSON object per frame: `{\"$key\": value}`. encode/decode turn a decoded\n// frame object into a string and back. json1Channel wraps a StringTransport so\n// it moves frame objects instead of strings.\n\nimport type { Channel, StringTransport } from \"../channel.js\";\n\nexport const VERSION = \"json.v1\";\n\nexport function encode(frame: Record<string, unknown>): string {\n return JSON.stringify(frame);\n}\n\nexport function decode(str: string): Record<string, unknown> {\n return JSON.parse(str);\n}\n\nexport function json1Channel(transport: StringTransport): Channel {\n return {\n send(frame) {\n return transport.send(encode(frame));\n },\n onMessage(handler) {\n transport.onMessage((str) => handler(decode(str)));\n },\n removeHandler() {\n transport.removeHandler();\n },\n onClose(handler) {\n transport.onClose(handler);\n },\n close() {\n return transport.close();\n },\n };\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { r as Message } from "../types-Dbe4BSPC.js";
2
- import { d as ActorPlugin } from "../hooks-Dnmr7Ain.js";
1
+ import { o as SenderInfo, r as Message } from "../types-BsynPeOf.js";
2
+ import { d as ActorPlugin } from "../hooks-DDlJQJi_.js";
3
3
  //#region src/plugins/debug-logger.d.ts
4
4
  declare module "../index" {
5
5
  interface ActorDecorated {
@@ -9,8 +9,18 @@ declare module "../index" {
9
9
  interface DebugLogFn {
10
10
  (message: string, ...args: unknown[]): void;
11
11
  }
12
+ /**
13
+ * Optional context for a logged message. The plugin fills both fields for the
14
+ * traffic it observes; a caller logging a message by hand may omit them.
15
+ */
16
+ interface MessageLogOpts {
17
+ /** Who sent it. Present for traffic observed by the plugin. */
18
+ sender?: SenderInfo;
19
+ /** Direction: "in" = received by this actor, "out" = emitted by it. */
20
+ direction?: "in" | "out";
21
+ }
12
22
  interface MessageLogFn {
13
- (message: Message): void;
23
+ (message: Message, opts?: MessageLogOpts): void;
14
24
  }
15
25
  interface LifecycleLogFn {
16
26
  (event: string, detail?: unknown): void;
@@ -53,5 +63,5 @@ declare function defaultMsgFilter(msg: Message): Message;
53
63
  */
54
64
  declare function debugLogger(opts?: DebugLoggerOpts): ActorPlugin;
55
65
  //#endregion
56
- export { DebugLogFn, DebugLoggerOpts, LifecycleLogFn, Logger, LoggerFactory, MessageLogFn, MsgFilter, debugLogger, defaultMsgFilter };
66
+ export { DebugLogFn, DebugLoggerOpts, LifecycleLogFn, Logger, LoggerFactory, MessageLogFn, MessageLogOpts, MsgFilter, debugLogger, defaultMsgFilter };
57
67
  //# sourceMappingURL=debug-logger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"debug-logger.d.ts","names":[],"sources":["../../src/plugins/debug-logger.ts"],"mappings":";;;;YAKY;IACR,KAAK;;;UAIQ;GACd,oBAAoB;;UAEN;GACd,SAAS;;UAEK;GACd,eAAe;;UAGD;EACf,OAAO;EACP,MAAM;EACN,MAAM;EACN,OAAO;EACP,KAAK;EACL,WAAW;;KAED,iBAAiB,iBAAiB;;;;;;KAOlC,aAAa,KAAK,YAAY;UAEzB;;EAEf;EACA,UAAU;;;EAGV,YAAY;;;;;;;iBAYE,iBAAiB,KAAK,UAAU;;;;;;;;iBAoChC,YAAY,OAAO,kBAAkB"}
1
+ {"version":3,"file":"debug-logger.d.ts","names":[],"sources":["../../src/plugins/debug-logger.ts"],"mappings":";;;;YAKY;IACR,KAAK;;;UAIQ;GACd,oBAAoB;;;;;;UAMN;;EAEf,SAAS;;EAET;;UAEe;GACd,SAAS,SAAS,OAAO;;UAEX;GACd,eAAe;;UAGD;EACf,OAAO;EACP,MAAM;EACN,MAAM;EACN,OAAO;EACP,KAAK;EACL,WAAW;;KAED,iBAAiB,iBAAiB;;;;;;KAOlC,aAAa,KAAK,YAAY;UAEzB;;EAEf;EACA,UAAU;;;EAGV,YAAY;;;;;;;iBAYE,iBAAiB,KAAK,UAAU;;;;;;;;iBAsEhC,YAAY,OAAO,kBAAkB"}
@@ -27,7 +27,7 @@ function defaultMsgFilter(msg) {
27
27
  function defaultFactory(name) {
28
28
  return {
29
29
  debug: (...a) => console.debug(`[${name}]`, ...a),
30
- msg: (msg) => console.debug(`[${name}] ←`, msg),
30
+ msg: (msg, opts) => console.debug(`[${name}] ${opts?.direction === "out" ? "→" : "←"} ${msg.type}`, msg),
31
31
  info: (...a) => console.info(`[${name}]`, ...a),
32
32
  warn: (...a) => console.warn(`[${name}]`, ...a),
33
33
  error: (...a) => console.error(`[${name}]`, ...a),
@@ -35,6 +35,36 @@ function defaultFactory(name) {
35
35
  };
36
36
  }
37
37
  /**
38
+ * A logger that is constructed on first use, and rebuilt if the name it is
39
+ * bound to changes.
40
+ *
41
+ * The plugin cannot build its logger eagerly: `config.name` is only a
42
+ * *preferred* name — most actors leave it unset and get their process name
43
+ * assigned by the framework — so binding a logger to it at plugin time files
44
+ * every entry under the fallback name. Deferring construction until the actor
45
+ * has actually started means the factory always receives the resolved name.
46
+ */
47
+ function deferredLogger(factory, getName) {
48
+ let inner = null;
49
+ let boundTo = null;
50
+ const resolve = () => {
51
+ const name = getName();
52
+ if (!inner || boundTo !== name) {
53
+ inner = factory(name);
54
+ boundTo = name;
55
+ }
56
+ return inner;
57
+ };
58
+ return {
59
+ debug: (msg, ...args) => resolve().debug(msg, ...args),
60
+ info: (msg, ...args) => resolve().info(msg, ...args),
61
+ warn: (msg, ...args) => resolve().warn(msg, ...args),
62
+ error: (msg, ...args) => resolve().error(msg, ...args),
63
+ msg: (msg, opts) => resolve().msg(msg, opts),
64
+ lifecycle: (event, detail) => resolve().lifecycle(event, detail)
65
+ };
66
+ }
67
+ /**
38
68
  * A debug/logging plugin that decorates `this.log` and observes the actor
39
69
  * lifecycle (started / stopping / stopped / child-exited / error) plus message
40
70
  * traffic. Hook registration is no longer gated by `DEBUG` — the supplied
@@ -46,13 +76,16 @@ function debugLogger(opts) {
46
76
  const factory = opts?.factory ?? defaultFactory;
47
77
  const msgFilter = opts?.msgFilter ?? defaultMsgFilter;
48
78
  return async function debugLoggerPlugin(config) {
49
- const name = config.name ?? "actor";
50
- const log = factory(name);
79
+ let name = config.name ?? "actor";
80
+ const log = deferredLogger(factory, () => name);
51
81
  let result = mergeConfigs(config, {
52
82
  methods: { ...config.methods },
53
83
  $decorate: { log }
54
84
  });
55
85
  result = mergeConfigs(result, {
86
+ beforeStart() {
87
+ name = this.name;
88
+ },
56
89
  afterStart() {
57
90
  log.lifecycle("started");
58
91
  },
@@ -68,15 +101,21 @@ function debugLogger(opts) {
68
101
  onError(err) {
69
102
  log.error(`${err?.message ?? err}`);
70
103
  },
71
- onMessage(msg) {
104
+ onMessage(msg, sender) {
72
105
  if (ignoreSet.has(msg.type)) return;
73
106
  const m = msgFilter ? msgFilter(msg) : msg;
74
- if (m) log.msg(m);
107
+ if (m) log.msg(m, {
108
+ sender,
109
+ direction: "in"
110
+ });
75
111
  },
76
- onEmit(msg) {
112
+ onEmit(msg, sender) {
77
113
  if (ignoreSet.has(msg.type)) return;
78
114
  const m = msgFilter ? msgFilter(msg) : msg;
79
- if (m) log.debug(`${name} → ${m.type}`, m);
115
+ if (m) log.msg(m, {
116
+ sender,
117
+ direction: "out"
118
+ });
80
119
  }
81
120
  });
82
121
  return result;
@@ -1 +1 @@
1
- {"version":3,"file":"debug-logger.js","names":[],"sources":["../../src/plugins/debug-logger.ts"],"sourcesContent":["import type { ActorPlugin } from \"../hooks\";\nimport { mergeConfigs } from \"../hooks\";\nimport type { Message } from \"../types\";\n\ndeclare module \"../index\" {\n interface ActorDecorated {\n log: Logger;\n }\n}\n\nexport interface DebugLogFn {\n (message: string, ...args: unknown[]): void;\n}\nexport interface MessageLogFn {\n (message: Message): void;\n}\nexport interface LifecycleLogFn {\n (event: string, detail?: unknown): void;\n}\n\nexport interface Logger {\n debug: DebugLogFn;\n info: DebugLogFn;\n warn: DebugLogFn;\n error: DebugLogFn;\n msg: MessageLogFn;\n lifecycle: LifecycleLogFn;\n}\nexport type LoggerFactory = (name: string) => Logger;\n\n/**\n * Filter a message before it is logged. Return a (possibly shrunk) message,\n * or `null` to skip it entirely. Used to keep large payloads — a full\n * conversation history, a big tool result — out of the log scroll.\n */\nexport type MsgFilter = (msg: Message) => Message | null;\n\nexport interface DebugLoggerOpts {\n /** Message types to skip entirely (in addition to any `msgFilter`). */\n ignore?: string[];\n factory?: LoggerFactory;\n /** Shrink or skip a message before it is logged via onMessage/onEmit.\n * Defaults to {@link defaultMsgFilter}. */\n msgFilter?: MsgFilter;\n}\n\n/** Fields larger than this are shrunk by {@link defaultMsgFilter}. */\nconst MAX_STRING = 256;\nconst MAX_ARRAY = 16;\n\n/**\n * Default message filter: shrink oversized string/array fields in place so a\n * single message (a full conversation history, a big tool result) can't flood\n * the log. Returns the message unchanged when nothing needs shrinking.\n */\nexport function defaultMsgFilter(msg: Message): Message {\n const src = msg as unknown as Record<string, unknown>;\n const shrunk: Record<string, unknown> = { ...src };\n let changed = false;\n for (const key of Object.keys(src)) {\n const v = src[key];\n if (typeof v === \"string\" && v.length > MAX_STRING) {\n shrunk[key] = `${v.slice(0, MAX_STRING)}… (${v.length} chars)`;\n changed = true;\n } else if (Array.isArray(v) && v.length > MAX_ARRAY) {\n shrunk[key] = `[${v.length} items]`;\n changed = true;\n }\n }\n return changed ? (shrunk as unknown as Message) : msg;\n}\n\nfunction defaultFactory(name: string): Logger {\n return {\n debug: (...a: unknown[]) => console.debug(`[${name}]`, ...a),\n msg: (msg: Message) => console.debug(`[${name}] ←`, msg),\n info: (...a: unknown[]) => console.info(`[${name}]`, ...a),\n warn: (...a: unknown[]) => console.warn(`[${name}]`, ...a),\n error: (...a: unknown[]) => console.error(`[${name}]`, ...a),\n lifecycle: (event: string, detail?: unknown) =>\n console.debug(`[${name}] lifecycle ${event}`, detail ?? \"\"),\n };\n}\n\n/**\n * A debug/logging plugin that decorates `this.log` and observes the actor\n * lifecycle (started / stopping / stopped / child-exited / error) plus message\n * traffic. Hook registration is no longer gated by `DEBUG` — the supplied\n * factory decides what to actually emit, so a ringbuffer (or anything else)\n * can gate output at runtime.\n */\nexport function debugLogger(opts?: DebugLoggerOpts): ActorPlugin {\n const ignoreSet = new Set(opts?.ignore ?? []);\n const factory = opts?.factory ?? defaultFactory;\n const msgFilter = opts?.msgFilter ?? defaultMsgFilter;\n return async function debugLoggerPlugin(config) {\n const name: string = config.name ?? \"actor\";\n const log = factory(name);\n\n let result = mergeConfigs(config, {\n methods: { ...config.methods },\n $decorate: { log },\n });\n\n result = mergeConfigs(result, {\n afterStart() {\n log.lifecycle(\"started\");\n },\n beforeEnd(reason: unknown) {\n log.lifecycle(\"stopping\", reason);\n },\n afterEnd(reason: unknown) {\n log.lifecycle(\"stopped\", reason);\n },\n onChildExit(childName: string) {\n log.lifecycle(\"child-exited\", childName);\n },\n onError(err: unknown) {\n log.error(`${(err as Error)?.message ?? err}`);\n },\n onMessage(msg: Message) {\n if (ignoreSet.has(msg.type)) return;\n const m = msgFilter ? msgFilter(msg) : msg;\n if (m) log.msg(m);\n },\n onEmit(msg: Message) {\n if (ignoreSet.has(msg.type)) return;\n const m = msgFilter ? msgFilter(msg) : msg;\n if (m) log.debug(`${name} ${m.type}`, m);\n },\n });\n\n return result;\n };\n}\n"],"mappings":";;;AA+CA,MAAM,aAAa;AACnB,MAAM,YAAY;;;;;;AAOlB,SAAgB,iBAAiB,KAAuB;CACtD,MAAM,MAAM;CACZ,MAAM,SAAkC,EAAE,GAAG,IAAI;CACjD,IAAI,UAAU;CACd,KAAK,MAAM,OAAO,OAAO,KAAK,GAAG,GAAG;EAClC,MAAM,IAAI,IAAI;EACd,IAAI,OAAO,MAAM,YAAY,EAAE,SAAS,YAAY;GAClD,OAAO,OAAO,GAAG,EAAE,MAAM,GAAG,UAAU,EAAE,KAAK,EAAE,OAAO;GACtD,UAAU;EACZ,OAAO,IAAI,MAAM,QAAQ,CAAC,KAAK,EAAE,SAAS,WAAW;GACnD,OAAO,OAAO,IAAI,EAAE,OAAO;GAC3B,UAAU;EACZ;CACF;CACA,OAAO,UAAW,SAAgC;AACpD;AAEA,SAAS,eAAe,MAAsB;CAC5C,OAAO;EACL,QAAQ,GAAG,MAAiB,QAAQ,MAAM,IAAI,KAAK,IAAI,GAAG,CAAC;EAC3D,MAAM,QAAiB,QAAQ,MAAM,IAAI,KAAK,MAAM,GAAG;EACvD,OAAO,GAAG,MAAiB,QAAQ,KAAK,IAAI,KAAK,IAAI,GAAG,CAAC;EACzD,OAAO,GAAG,MAAiB,QAAQ,KAAK,IAAI,KAAK,IAAI,GAAG,CAAC;EACzD,QAAQ,GAAG,MAAiB,QAAQ,MAAM,IAAI,KAAK,IAAI,GAAG,CAAC;EAC3D,YAAY,OAAe,WACzB,QAAQ,MAAM,IAAI,KAAK,cAAc,SAAS,UAAU,EAAE;CAC9D;AACF;;;;;;;;AASA,SAAgB,YAAY,MAAqC;CAC/D,MAAM,YAAY,IAAI,IAAI,MAAM,UAAU,CAAC,CAAC;CAC5C,MAAM,UAAU,MAAM,WAAW;CACjC,MAAM,YAAY,MAAM,aAAa;CACrC,OAAO,eAAe,kBAAkB,QAAQ;EAC9C,MAAM,OAAe,OAAO,QAAQ;EACpC,MAAM,MAAM,QAAQ,IAAI;EAExB,IAAI,SAAS,aAAa,QAAQ;GAChC,SAAS,EAAE,GAAG,OAAO,QAAQ;GAC7B,WAAW,EAAE,IAAI;EACnB,CAAC;EAED,SAAS,aAAa,QAAQ;GAC5B,aAAa;IACX,IAAI,UAAU,SAAS;GACzB;GACA,UAAU,QAAiB;IACzB,IAAI,UAAU,YAAY,MAAM;GAClC;GACA,SAAS,QAAiB;IACxB,IAAI,UAAU,WAAW,MAAM;GACjC;GACA,YAAY,WAAmB;IAC7B,IAAI,UAAU,gBAAgB,SAAS;GACzC;GACA,QAAQ,KAAc;IACpB,IAAI,MAAM,GAAI,KAAe,WAAW,KAAK;GAC/C;GACA,UAAU,KAAc;IACtB,IAAI,UAAU,IAAI,IAAI,IAAI,GAAG;IAC7B,MAAM,IAAI,YAAY,UAAU,GAAG,IAAI;IACvC,IAAI,GAAG,IAAI,IAAI,CAAC;GAClB;GACA,OAAO,KAAc;IACnB,IAAI,UAAU,IAAI,IAAI,IAAI,GAAG;IAC7B,MAAM,IAAI,YAAY,UAAU,GAAG,IAAI;IACvC,IAAI,GAAG,IAAI,MAAM,GAAG,KAAK,KAAK,EAAE,QAAQ,CAAC;GAC3C;EACF,CAAC;EAED,OAAO;CACT;AACF"}
1
+ {"version":3,"file":"debug-logger.js","names":[],"sources":["../../src/plugins/debug-logger.ts"],"sourcesContent":["import type { ActorPlugin } from \"../hooks\";\nimport { mergeConfigs } from \"../hooks\";\nimport type { Message, SenderInfo } from \"../types\";\n\ndeclare module \"../index\" {\n interface ActorDecorated {\n log: Logger;\n }\n}\n\nexport interface DebugLogFn {\n (message: string, ...args: unknown[]): void;\n}\n/**\n * Optional context for a logged message. The plugin fills both fields for the\n * traffic it observes; a caller logging a message by hand may omit them.\n */\nexport interface MessageLogOpts {\n /** Who sent it. Present for traffic observed by the plugin. */\n sender?: SenderInfo;\n /** Direction: \"in\" = received by this actor, \"out\" = emitted by it. */\n direction?: \"in\" | \"out\";\n}\nexport interface MessageLogFn {\n (message: Message, opts?: MessageLogOpts): void;\n}\nexport interface LifecycleLogFn {\n (event: string, detail?: unknown): void;\n}\n\nexport interface Logger {\n debug: DebugLogFn;\n info: DebugLogFn;\n warn: DebugLogFn;\n error: DebugLogFn;\n msg: MessageLogFn;\n lifecycle: LifecycleLogFn;\n}\nexport type LoggerFactory = (name: string) => Logger;\n\n/**\n * Filter a message before it is logged. Return a (possibly shrunk) message,\n * or `null` to skip it entirely. Used to keep large payloads — a full\n * conversation history, a big tool result — out of the log scroll.\n */\nexport type MsgFilter = (msg: Message) => Message | null;\n\nexport interface DebugLoggerOpts {\n /** Message types to skip entirely (in addition to any `msgFilter`). */\n ignore?: string[];\n factory?: LoggerFactory;\n /** Shrink or skip a message before it is logged via onMessage/onEmit.\n * Defaults to {@link defaultMsgFilter}. */\n msgFilter?: MsgFilter;\n}\n\n/** Fields larger than this are shrunk by {@link defaultMsgFilter}. */\nconst MAX_STRING = 256;\nconst MAX_ARRAY = 16;\n\n/**\n * Default message filter: shrink oversized string/array fields in place so a\n * single message (a full conversation history, a big tool result) can't flood\n * the log. Returns the message unchanged when nothing needs shrinking.\n */\nexport function defaultMsgFilter(msg: Message): Message {\n const src = msg as unknown as Record<string, unknown>;\n const shrunk: Record<string, unknown> = { ...src };\n let changed = false;\n for (const key of Object.keys(src)) {\n const v = src[key];\n if (typeof v === \"string\" && v.length > MAX_STRING) {\n shrunk[key] = `${v.slice(0, MAX_STRING)}… (${v.length} chars)`;\n changed = true;\n } else if (Array.isArray(v) && v.length > MAX_ARRAY) {\n shrunk[key] = `[${v.length} items]`;\n changed = true;\n }\n }\n return changed ? (shrunk as unknown as Message) : msg;\n}\n\nfunction defaultFactory(name: string): Logger {\n return {\n debug: (...a: unknown[]) => console.debug(`[${name}]`, ...a),\n msg: (msg: Message, opts?: MessageLogOpts) =>\n console.debug(`[${name}] ${opts?.direction === \"out\" ? \"→\" : \"←\"} ${msg.type}`, msg),\n info: (...a: unknown[]) => console.info(`[${name}]`, ...a),\n warn: (...a: unknown[]) => console.warn(`[${name}]`, ...a),\n error: (...a: unknown[]) => console.error(`[${name}]`, ...a),\n lifecycle: (event: string, detail?: unknown) =>\n console.debug(`[${name}] lifecycle ${event}`, detail ?? \"\"),\n };\n}\n\n/**\n * A logger that is constructed on first use, and rebuilt if the name it is\n * bound to changes.\n *\n * The plugin cannot build its logger eagerly: `config.name` is only a\n * *preferred* name — most actors leave it unset and get their process name\n * assigned by the framework — so binding a logger to it at plugin time files\n * every entry under the fallback name. Deferring construction until the actor\n * has actually started means the factory always receives the resolved name.\n */\nfunction deferredLogger(factory: LoggerFactory, getName: () => string): Logger {\n let inner: Logger | null = null;\n let boundTo: string | null = null;\n\n const resolve = (): Logger => {\n const name = getName();\n if (!inner || boundTo !== name) {\n inner = factory(name);\n boundTo = name;\n }\n return inner;\n };\n\n return {\n debug: (msg: string, ...args: unknown[]) => resolve().debug(msg, ...args),\n info: (msg: string, ...args: unknown[]) => resolve().info(msg, ...args),\n warn: (msg: string, ...args: unknown[]) => resolve().warn(msg, ...args),\n error: (msg: string, ...args: unknown[]) => resolve().error(msg, ...args),\n msg: (msg: Message, opts?: MessageLogOpts) => resolve().msg(msg, opts),\n lifecycle: (event: string, detail?: unknown) => resolve().lifecycle(event, detail),\n };\n}\n\n/**\n * A debug/logging plugin that decorates `this.log` and observes the actor\n * lifecycle (started / stopping / stopped / child-exited / error) plus message\n * traffic. Hook registration is no longer gated by `DEBUG` — the supplied\n * factory decides what to actually emit, so a ringbuffer (or anything else)\n * can gate output at runtime.\n */\nexport function debugLogger(opts?: DebugLoggerOpts): ActorPlugin {\n const ignoreSet = new Set(opts?.ignore ?? []);\n const factory = opts?.factory ?? defaultFactory;\n const msgFilter = opts?.msgFilter ?? defaultMsgFilter;\n return async function debugLoggerPlugin(config) {\n // Preferred name as a placeholder; replaced with the resolved process name\n // in `beforeStart`, before anything is logged.\n let name: string = config.name ?? \"actor\";\n const log = deferredLogger(factory, () => name);\n\n let result = mergeConfigs(config, {\n methods: { ...config.methods },\n $decorate: { log },\n });\n\n result = mergeConfigs(result, {\n beforeStart() {\n name = this.name;\n },\n afterStart() {\n log.lifecycle(\"started\");\n },\n beforeEnd(reason: unknown) {\n log.lifecycle(\"stopping\", reason);\n },\n afterEnd(reason: unknown) {\n log.lifecycle(\"stopped\", reason);\n },\n onChildExit(childName: string) {\n log.lifecycle(\"child-exited\", childName);\n },\n onError(err: unknown) {\n log.error(`${(err as Error)?.message ?? err}`);\n },\n onMessage(msg: Message, sender: SenderInfo) {\n if (ignoreSet.has(msg.type)) return;\n const m = msgFilter ? msgFilter(msg) : msg;\n if (m) log.msg(m, { sender, direction: \"in\" });\n },\n onEmit(msg: Message, sender: SenderInfo) {\n if (ignoreSet.has(msg.type)) return;\n const m = msgFilter ? msgFilter(msg) : msg;\n if (m) log.msg(m, { sender, direction: \"out\" });\n },\n });\n\n return result;\n };\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { d as AnyProcess } from "../types-Dbe4BSPC.js";
2
- import { d as ActorPlugin } from "../hooks-Dnmr7Ain.js";
1
+ import { d as AnyProcess } from "../types-BsynPeOf.js";
2
+ import { d as ActorPlugin } from "../hooks-DDlJQJi_.js";
3
3
  //#region src/plugins/tree-introspection.d.ts
4
4
  declare module "../index" {
5
5
  interface ActorReflection {
@@ -1,4 +1,4 @@
1
- import { a as ProcessFn, f as AsyncProcess, n as ExitMessage, o as SenderInfo, r as Message } from "./types-Dbe4BSPC.js";
1
+ import { a as ProcessFn, f as AsyncProcess, n as ExitMessage, o as SenderInfo, r as Message } from "./types-BsynPeOf.js";
2
2
  //#region src/process.d.ts
3
3
  /** @deprecated Use {@link spawnAsync} instead. */
4
4
  declare function spawn<A, S, IM extends Message = Message, OM extends Message = ExitMessage>(fn: ProcessFn<A, S, IM, OM>, pname: string, tp?: (m: OM, from: SenderInfo) => void): (a: A) => Process<A, S, IM, OM>;
@@ -11,4 +11,4 @@ declare class Process<A, S, IM extends Message, OM extends Message> extends Asyn
11
11
  }
12
12
  //#endregion
13
13
  export { spawn as n, Process as t };
14
- //# sourceMappingURL=process-BTC8JV8_.d.ts.map
14
+ //# sourceMappingURL=process-C9Gb0qKx.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"process-BTC8JV8_.d.ts","names":[],"sources":["../src/process.ts"],"mappings":";;;iBAQgB,MAAM,GAAG,GAAG,WAAW,UAAU,SAAS,WAAW,UAAU,aAC7E,IAAI,UAAU,GAAG,GAAG,IAAI,KACxB,eACA,MAAM,GAAG,IAAI,MAAM,uBACjB,GAAG,MAAM,QAAQ,GAAG,GAAG,IAAI;;;cAMzB,QAAQ,GAAG,GAAG,WAAW,SAAS,WAAW,iBAAiB,aAAa,GAAG,GAAG,IAAI;EACzF,YAAY,IAAI,UAAU,GAAG,GAAG,IAAI,KAAK,eAAe,MAAM,GAAG,IAAI,MAAM;EAI3E,MAAM,GAAG;EAIT,QAAQ"}
1
+ {"version":3,"file":"process-C9Gb0qKx.d.ts","names":[],"sources":["../src/process.ts"],"mappings":";;;iBAQgB,MAAM,GAAG,GAAG,WAAW,UAAU,SAAS,WAAW,UAAU,aAC7E,IAAI,UAAU,GAAG,GAAG,IAAI,KACxB,eACA,MAAM,GAAG,IAAI,MAAM,uBACjB,GAAG,MAAM,QAAQ,GAAG,GAAG,IAAI;;;cAMzB,QAAQ,GAAG,GAAG,WAAW,SAAS,WAAW,iBAAiB,aAAa,GAAG,GAAG,IAAI;EACzF,YAAY,IAAI,UAAU,GAAG,GAAG,IAAI,KAAK,eAAe,MAAM,GAAG,IAAI,MAAM;EAI3E,MAAM,GAAG;EAIT,QAAQ"}
@@ -1,6 +1,6 @@
1
- import { r as Message } from "../types-Dbe4BSPC.js";
2
- import { _ as ReflectionOptions, h as MethodOptions, l as ActorDefinition, p as HandlerOptions } from "../hooks-Dnmr7Ain.js";
3
- import { a as isMsg, i as isInit, n as StringTransport, o as isProto, r as isExit, s as isState, t as Channel } from "../channel-Dakf3HAG.js";
1
+ import { r as Message } from "../types-BsynPeOf.js";
2
+ import { _ as ReflectionOptions, h as MethodOptions, l as ActorDefinition, p as HandlerOptions } from "../hooks-DDlJQJi_.js";
3
+ import { a as isMsg, i as isInit, n as StringTransport, o as isProto, r as isExit, s as isState, t as Channel } from "../channel-CwvNcxhn.js";
4
4
  //#region src/remote/server.d.ts
5
5
  type Spawner = () => Promise<Channel>;
6
6
  declare function makeSender(fromName: string, parentName: string | null, parentId: symbol | null): {
@@ -1,4 +1,4 @@
1
- import { a as remoteClient, c as isExit, d as isProto, f as isState, i as json1Channel, l as isInit, n as decode, o as makeSender, r as encode, s as serveRemoteActor, t as VERSION, u as isMsg } from "../json1-tKb32fT6.js";
1
+ import { a as remoteClient, c as isExit, d as isProto, f as isState, i as json1Channel, l as isInit, n as decode, o as makeSender, r as encode, s as serveRemoteActor, t as VERSION, u as isMsg } from "../json1-BHNbVSW_.js";
2
2
  //#region src/remote/transports/websocket.ts
3
3
  /** WHATWG WebSocket readyState: OPEN. */
4
4
  const WS_OPEN = 1;
@@ -1,6 +1,6 @@
1
- import { r as Message } from "../types-Dbe4BSPC.js";
2
- import { _ as ReflectionOptions, h as MethodOptions, l as ActorDefinition, p as HandlerOptions } from "../hooks-Dnmr7Ain.js";
3
- import { n as StringTransport, t as Channel } from "../channel-Dakf3HAG.js";
1
+ import { r as Message } from "../types-BsynPeOf.js";
2
+ import { _ as ReflectionOptions, h as MethodOptions, l as ActorDefinition, p as HandlerOptions } from "../hooks-DDlJQJi_.js";
3
+ import { n as StringTransport, t as Channel } from "../channel-CwvNcxhn.js";
4
4
  import { FileHandle } from "node:fs/promises";
5
5
  //#region src/remote/transports/fifo.d.ts
6
6
  declare class FifoUtf8NlineTransport implements StringTransport {
@@ -1,4 +1,4 @@
1
- import { a as remoteClient, d as isProto, i as json1Channel, s as serveRemoteActor, t as VERSION } from "../json1-tKb32fT6.js";
1
+ import { a as remoteClient, d as isProto, i as json1Channel, s as serveRemoteActor, t as VERSION } from "../json1-BHNbVSW_.js";
2
2
  import { open, unlink } from "node:fs/promises";
3
3
  import { createReadStream, createWriteStream } from "node:fs";
4
4
  import * as readline from "node:readline";
@@ -1,5 +1,5 @@
1
- import { f as AsyncProcess, r as Message } from "../types-Dbe4BSPC.js";
2
- import { d as ActorPlugin } from "../hooks-Dnmr7Ain.js";
1
+ import { f as AsyncProcess, r as Message } from "../types-BsynPeOf.js";
2
+ import { d as ActorPlugin } from "../hooks-DDlJQJi_.js";
3
3
  //#region src/testing/msg-matcher.d.ts
4
4
  type Matcher<M extends Message> = (msg: M, history: M[]) => boolean;
5
5
  type MatchSpec<M extends Message> = Matcher<M> | Partial<M> | Array<Partial<M>>;
@@ -215,10 +215,14 @@ type ProcessCtx<Args, State, IM extends Message, OM extends Message> = {
215
215
  parentId: symbol | null;
216
216
  sendSelf: (msg: IM | StopMessage) => void;
217
217
  toParent: ProcessMessageCb<OM>;
218
+ /** Fire this process's state subscribers now (no message round-trip).
219
+ * Used when something outside the dispatch loop — e.g. a remote $state
220
+ * frame — mutates `state` and the change must still be observed. */
221
+ notify: () => void;
218
222
  /** Invoked by the runtime after the process emits EXIT to its parent.
219
223
  * Best-effort teardown that must not delay the exit signal. */
220
224
  afterExit?: () => Promise<void> | void;
221
225
  } & Pick<AsyncProcess<Args, State, IM, OM, {}>, "fork" | "forkSync" | "children" | "orphans" | "adopt" | "monitor">;
222
226
  //#endregion
223
227
  export { ProcessFn as a, StopMessage as c, AnyProcess as d, AsyncProcess as f, ProcessCtx as i, WithSender as l, spawnAsync as m, ExitMessage as n, SenderInfo as o, runDispatchAsync as p, Message as r, SenderOrigin as s, AsyncProcessFn as t, WithoutSender as u };
224
- //# sourceMappingURL=types-Dbe4BSPC.d.ts.map
228
+ //# sourceMappingURL=types-BsynPeOf.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types-Dbe4BSPC.d.ts","names":[],"sources":["../src/process.async.ts","../src/types.ts"],"mappings":";KAuBK;KAIA,aAAa,MAAM,KAAK,MAAM;KAC9B;;;;;;iBAOkB,iBAAiB,GACtC,cACA,IAAI,aAAa,IACjB,UAAS,SACT,uBACC,2BAA2B;;;KAazB,gBAAgB,UAAU,YAAY,KAAK,GAAG,MAAM;;;;;;;;;cAa5C,aACX,MACA,OACA,kBAAkB,SAClB,mBAAmB,SACnB;;EAGA,aAAa;EACb,YAAY,eAAe,MAAM,OAAO,WAAW;EACnD;;UAEQ;EACR;EACA,OAAO;UAEC;;UAEA;UACA;;EAER,UAAU,MAAM,+BAA+B,SAAS;;EAExD,SAAS,MAAM,+BAA+B,SAAS;UAC/C;;UAEA;;UAEA;;UAEA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;EAER,YACE,IAAI,eAAe,MAAM,OAAO,WAAW,aAC3C,eACA,WAAW,gBAAgB;;EAmB7B,SAAS;;;;;EAUT,MAAM,MAAM,MAAM,4BAA4B;;UA8C/B;EAkCf,KAAK,WAAW,YAAY,gBAAgB,SAAS,gBAAgB,SACnE,IAAI,eAAe,WAAW,YAAY,SAAS,UACnD,iBACE,MAAM,cAAc,aAAa,WAAW,YAAY,SAAS;EASrE,SAAS,WAAW,YAAY,gBAAgB,SAAS,gBAAgB,WACvE,IAAI,UAAU,WAAW,YAAY,SAAS,UAC9C,iBACE,MAAM,cAAc,aAAa,WAAW,YAAY,SAAS;YAMrD,WAAW;;UAsBb;UAYN;;EAYR,cAAc,KAAK;;EAMnB,KAAK,KAAK,YAAY,aAAa,OAAO;;EAE1C,KAAK,cAAc,WAAW,YAAY;;;;;;EAmB1C;UAKQ;EAYR;MAII;EAIJ,UAAU,oBAAoB,IAAI,gBAAgB;EAClD,UAAU,kBAAkB,IAAI;;EAEhC,UAAU,IAAI;UAkBN;;;;;;;EAaR;EAMA;;;;;;;;;;;;;;;EAmBA,UAAU;IAAS;;;;;;;;;;;;;;EA8Cb,KAAK;IAAS;IAAiB,OAAO;MAAe;;;;;EAmC3D,QAAQ;;;;;;EAwBR,QAAQ,WAAW,YAAY,gBAAgB,SAAS,gBAAgB,SACtE,OAAO,aAAa,WAAW,YAAY,SAAS;;;;;;EActD,MAAM,WAAW,YAAY,gBAAgB,SAAS,gBAAgB,SACpE,OAAO,aAAa,WAAW,YAAY,SAAS;;UAa9C;;UAiBA;;;UASA;;UAUA;;UAeA;;UAcA;;;;;;EAkBR;;KAQU,aAAa,+BAA+B,SAAS;;;;;iBAOjD,WACd,MACA,OACA,kBAAkB,UAAU,SAC5B,mBAAmB,UAAU,aAE7B,IAAI,eAAe,MAAM,OAAO,WAAW,aAC3C,eACA,WAAW,gBAAgB,aAC3B,4BACA,4BACE,MAAM,SAAS,aAAa,MAAM,OAAO,WAAW;;;;;UCrnBvC;EACf;;;UAMe;EACf;EACA;;;;;KAQU,WAAW,UAAU,YAAY,GAAG;;KAGpC,cAAc,UAAU,mBAAmB;;;KAM3C;EACV;;;EAGA,UAAU,MAAM;;KAGN;EACV;;KAKU,UAAU,MAAM,OAAO,kBAAkB,SAAS,mBAAmB,YAC/E,KAAK,WAAW,MAAM,OAAO,WAAW,aACxC,MAAM,SACH,UAAU,oBAAoB,WAAW,YAAY;KAI9C,eACV,MACA,OACA,kBAAkB,UAAU,SAC5B,mBAAmB,UAAU,YAE7B,KAAK,WAAW,MAAM,OAAO,WAAW,aACxC,MAAM,SACH,eAAe,oBAAoB,WAAW,YAAY;;;KAMnD,eAAe,6BAA6B,SAAS;KAI5D,iBAAiB,MAAM,KAAK;;KAerB,WAAW,MAAM,OAAO,WAAW,SAAS,WAAW;EACjE;EACA;EACA;EACA;EACA,WAAW,KAAK,KAAK;EACrB,UAAU,iBAAiB;;;EAG3B,kBAAkB;IAChB,KACF,aAAa,MAAM,OAAO,IAAI"}
1
+ {"version":3,"file":"types-BsynPeOf.d.ts","names":[],"sources":["../src/process.async.ts","../src/types.ts"],"mappings":";KAuBK;KAIA,aAAa,MAAM,KAAK,MAAM;KAC9B;;;;;;iBAOkB,iBAAiB,GACtC,cACA,IAAI,aAAa,IACjB,UAAS,SACT,uBACC,2BAA2B;;;KAazB,gBAAgB,UAAU,YAAY,KAAK,GAAG,MAAM;;;;;;;;;cAa5C,aACX,MACA,OACA,kBAAkB,SAClB,mBAAmB,SACnB;;EAGA,aAAa;EACb,YAAY,eAAe,MAAM,OAAO,WAAW;EACnD;;UAEQ;EACR;EACA,OAAO;UAEC;;UAEA;UACA;;EAER,UAAU,MAAM,+BAA+B,SAAS;;EAExD,SAAS,MAAM,+BAA+B,SAAS;UAC/C;;UAEA;;UAEA;;UAEA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;EAER,YACE,IAAI,eAAe,MAAM,OAAO,WAAW,aAC3C,eACA,WAAW,gBAAgB;;EAmB7B,SAAS;;;;;EAUT,MAAM,MAAM,MAAM,4BAA4B;;UAiD/B;EAkCf,KAAK,WAAW,YAAY,gBAAgB,SAAS,gBAAgB,SACnE,IAAI,eAAe,WAAW,YAAY,SAAS,UACnD,iBACE,MAAM,cAAc,aAAa,WAAW,YAAY,SAAS;EASrE,SAAS,WAAW,YAAY,gBAAgB,SAAS,gBAAgB,WACvE,IAAI,UAAU,WAAW,YAAY,SAAS,UAC9C,iBACE,MAAM,cAAc,aAAa,WAAW,YAAY,SAAS;YAMrD,WAAW;;UAsBb;UAYN;;EAYR,cAAc,KAAK;;EAMnB,KAAK,KAAK,YAAY,aAAa,OAAO;;EAE1C,KAAK,cAAc,WAAW,YAAY;;;;;;EAmB1C;UAKQ;EAYR;MAII;EAIJ,UAAU,oBAAoB,IAAI,gBAAgB;EAClD,UAAU,kBAAkB,IAAI;;EAEhC,UAAU,IAAI;UAkBN;;;;;;;EAaR;EAMA;;;;;;;;;;;;;;;EAmBA,UAAU;IAAS;;;;;;;;;;;;;;EA8Cb,KAAK;IAAS;IAAiB,OAAO;MAAe;;;;;EAmC3D,QAAQ;;;;;;EAwBR,QAAQ,WAAW,YAAY,gBAAgB,SAAS,gBAAgB,SACtE,OAAO,aAAa,WAAW,YAAY,SAAS;;;;;;EActD,MAAM,WAAW,YAAY,gBAAgB,SAAS,gBAAgB,SACpE,OAAO,aAAa,WAAW,YAAY,SAAS;;UAa9C;;UAiBA;;;UASA;;UAUA;;UAeA;;UAcA;;;;;;EAkBR;;KAQU,aAAa,+BAA+B,SAAS;;;;;iBAOjD,WACd,MACA,OACA,kBAAkB,UAAU,SAC5B,mBAAmB,UAAU,aAE7B,IAAI,eAAe,MAAM,OAAO,WAAW,aAC3C,eACA,WAAW,gBAAgB,aAC3B,4BACA,4BACE,MAAM,SAAS,aAAa,MAAM,OAAO,WAAW;;;;;UCxnBvC;EACf;;;UAMe;EACf;EACA;;;;;KAQU,WAAW,UAAU,YAAY,GAAG;;KAGpC,cAAc,UAAU,mBAAmB;;;KAM3C;EACV;;;EAGA,UAAU,MAAM;;KAGN;EACV;;KAKU,UAAU,MAAM,OAAO,kBAAkB,SAAS,mBAAmB,YAC/E,KAAK,WAAW,MAAM,OAAO,WAAW,aACxC,MAAM,SACH,UAAU,oBAAoB,WAAW,YAAY;KAI9C,eACV,MACA,OACA,kBAAkB,UAAU,SAC5B,mBAAmB,UAAU,YAE7B,KAAK,WAAW,MAAM,OAAO,WAAW,aACxC,MAAM,SACH,eAAe,oBAAoB,WAAW,YAAY;;;KAMnD,eAAe,6BAA6B,SAAS;KAI5D,iBAAiB,MAAM,KAAK;;KAerB,WAAW,MAAM,OAAO,WAAW,SAAS,WAAW;EACjE;EACA;EACA;EACA;EACA,WAAW,KAAK,KAAK;EACrB,UAAU,iBAAiB;;;;EAI3B;;;EAGA,kBAAkB;IAChB,KACF,aAAa,MAAM,OAAO,IAAI"}
package/dist/xfetch.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { i as ProcessCtx, l as WithSender, n as ExitMessage } from "./types-Dbe4BSPC.js";
2
- import { t as Process } from "./process-BTC8JV8_.js";
1
+ import { i as ProcessCtx, l as WithSender, n as ExitMessage } from "./types-BsynPeOf.js";
2
+ import { t as Process } from "./process-C9Gb0qKx.js";
3
3
  //#region src/xfetch.d.ts
4
4
  /** State of an in-flight or completed fetch. */
5
5
  type FetchState<T> = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "posipaki",
3
- "version": "0.28.0",
3
+ "version": "0.30.0",
4
4
  "homepage": "https://posipaki-docs.muromec.nl/",
5
5
  "repository": {
6
6
  "type": "git",
@@ -44,7 +44,7 @@
44
44
  },
45
45
  "scripts": {
46
46
  "build": "bash scripts/build.sh",
47
- "test": "vitest run",
47
+ "test": "bash scripts/test.sh",
48
48
  "test:watch": "vitest",
49
49
  "lint": "oxlint"
50
50
  },
@@ -1 +0,0 @@
1
- {"version":3,"file":"define-actor-Dg5_koH3.js","names":[],"sources":["../src/adapters.ts","../src/process.async.ts","../src/define-actor.ts"],"sourcesContent":["import type { ProcessFn, AsyncProcessFn, Message } from \"./types.js\";\n\nexport function asyncify<A, S, IM extends Message, OM extends Message>(\n fn: ProcessFn<A, S, IM, OM>,\n): AsyncProcessFn<A, S, IM, OM> {\n return async function* (ctx, args) {\n yield* fn(ctx, args) as any;\n };\n}\n","import { defer, makeWaiter, debugLog, withTimeout } from \"./util.js\";\nimport type { DeferredCall, Waiter } from \"./util.js\";\nimport type {\n Message,\n WithSender,\n SenderInfo,\n ExitMessage,\n StopMessage,\n ProcessCtx,\n AsyncProcessFn,\n ProcessFn,\n} from \"./types.js\";\nimport { asyncify } from \"./adapters.js\";\n\n// ---- types ------------------------------------------------------------------\n\n/** An async iterator over process state. Receives `WithSender<InMessage | StopMessage>`. */\ntype AsyncProcessGenerator<ProcessState, InMessage extends Message> = AsyncGenerator<\n ProcessState | null,\n void,\n WithSender<InMessage | StopMessage>\n>;\n\ntype NotifyFn = () => void;\n\n// ---- runDispatchAsync -------------------------------------------------------\n\ntype AsyncReducer<M> = (msg: M) => Promise<void>;\ntype ReadyFn = () => boolean;\n\n/**\n * Async equivalent of `runDispatch`. Loops, yielding `null` and feeding\n * each incoming message to an `async` reducer. Exits when `readyFn()`\n * returns true.\n */\nexport async function* runDispatchAsync<M>(\n name: string,\n fn: AsyncReducer<M>,\n readyFn: ReadyFn = () => false,\n debugLevel = false,\n): AsyncGenerator<null, void, M> {\n let msg: M;\n while (!readyFn()) {\n msg = yield null;\n debugLog(debugLevel, \"msg\", name, \" <- \", msg);\n await fn(msg);\n }\n}\n\n// ---- AsyncProcess -----------------------------------------------------------\n\n/** A subscriber to this process's message channel: receives the message and\n * its sender separately (not a `WithSender` tuple). */\ntype MessageCallback<M extends Message> = (msg: M, from: SenderInfo) => void;\n\n/** How long a parent waits for a child to stop before continuing shutdown. */\nconst CHILD_STOP_TIMEOUT_MS = 1_000;\n\n/**\n * A process driven by an async generator. Functionally identical to\n * {@link Process} but supports `await` inside reducers.\n *\n * Messages are processed **one at a time** — if a tick is already\n * in-flight, new messages are buffered and processed when the current\n * tick completes.\n */\nexport class AsyncProcess<\n Args,\n State,\n InMessage extends Message,\n OutMessage extends Message,\n ReflectionMethods extends object,\n> {\n /** Reflection methods. Empty by default — defineActor fills in configured methods. */\n $reflection: ReflectionMethods = {} as ReflectionMethods;\n pgenerator: AsyncProcessFn<Args, State, InMessage, OutMessage>;\n pname: string;\n /** Subscribers to this process's message channel (`ctx.toParent`). */\n private messageSubscribers: Array<MessageCallback<OutMessage>> = [];\n id: symbol;\n state: State | null;\n\n private current: AsyncProcessGenerator<State, InMessage> | null = null;\n /** Every buffered message carries sender provenance. */\n private buffer: Array<WithSender<InMessage | StopMessage>> = [];\n private nextTick: DeferredCall | null = null;\n /** Child processes forked from this one (any fork method). */\n children: Array<AsyncProcess<unknown, unknown, Message, Message, {}>> = [];\n /** Children inherited from a child that exited (see ctx-orphans proposal). */\n orphans: Array<AsyncProcess<unknown, unknown, Message, Message, {}>> = [];\n private stateSubscribers: Array<NotifyFn> = [];\n /** Unsubscribe handles for outgoing message subscriptions (monitor only). */\n private pvtOutgoingSubscriptions: Array<() => void> = [];\n /** Unsubscribe handles for adopt (ownership) subscriptions, keyed by child id. */\n private pvtAdoptUnsubs: Map<symbol, () => void> = new Map();\n /** Live buffer while this process is an unowned orphan mid-handoff. */\n private pvtPending: Array<WithSender<Message>> | null = null;\n /** Unsubscribe for the collector currently buffering into pvtPending. */\n private pvtCollectorUnsub: (() => void) | null = null;\n private exitWaiter: Waiter;\n private pvtIsPaused: boolean = false;\n private pvtDead: boolean = false;\n private pvtTickInProgress: boolean = false;\n private pvtExitReject: ((e: unknown) => void) | null = null;\n private pvtReady!: Waiter;\n private pvtResolveReady!: () => void;\n\n constructor(\n fn: AsyncProcessFn<Args, State, InMessage, OutMessage>,\n pname: string,\n toParent?: MessageCallback<OutMessage>,\n ) {\n this.pgenerator = fn;\n this.pname = pname;\n if (toParent) this.messageSubscribers.push(toParent);\n this.id = Symbol(pname);\n this.state = null;\n this.exitWaiter = makeWaiter();\n this.pvtReady = makeWaiter();\n this.pvtResolveReady = this.pvtReady.resolve;\n }\n\n /** Compact handle for `util.inspect` — actor state often holds process\n * references, and dumping the internals would be unreadable. */\n [Symbol.for(\"nodejs.util.inspect.custom\")](): string {\n return `AsyncProcess<${this.pname}>`;\n }\n\n /** Promise that resolves once the initial state is available. */\n ready(): Promise<void> {\n return this.pvtReady.promise;\n }\n\n // ---- lifecycle ------------------------------------------------------------\n\n /**\n * Kick off the async generator. The first `yield` sets the initial\n * state; for async generators this happens in a microtask.\n */\n start(arg0: Args, parentName?: string | null, parentId?: symbol | null) {\n const selfCtx: SenderInfo = { fromName: this.pname, fromId: this.id };\n\n const ctx: ProcessCtx<Args, State, InMessage, OutMessage | ExitMessage> = {\n pname: this.pname,\n id: this.id,\n parentName: parentName ?? null,\n parentId: parentId ?? null,\n fork: this.fork.bind(this),\n forkSync: this.forkSync.bind(this),\n children: this.children,\n orphans: this.orphans,\n adopt: this.adopt.bind(this),\n monitor: this.monitor.bind(this),\n sendSelf: (msg) => {\n this.send([msg, selfCtx]);\n },\n toParent: (msg) => {\n this.messageSubscribers.forEach((cb) => cb(msg as OutMessage, selfCtx));\n },\n };\n\n this.current = this.pvtWatchExit(ctx, arg0);\n void this.current.next().then((ret: IteratorResult<State | null, void>) => {\n this.state = ret.value ?? null;\n this.pvtResolveReady();\n if (ret.done) {\n this.exitWaiter.resolve();\n return;\n }\n // Advance past the initial yield so the pvtWatchExit generator\n // runs its finally block (EXIT/STOP) and the inner generator\n // enters its dispatch loop.\n const advance: WithSender<InMessage | StopMessage> = [\n { type: \"__ADVANCE__\" } as InMessage,\n {\n fromName: \"__internal__\",\n fromId: Symbol(\"__internal__\"),\n } as SenderInfo,\n ];\n this.pvtEatResult(this.current!.next(advance));\n });\n return this;\n }\n\n /** Wrap the user's generator so EXIT/STOP logic fires on completion. */\n private async *pvtWatchExit(\n ctx: ProcessCtx<Args, State, InMessage, OutMessage | ExitMessage>,\n arg0: Args,\n ): AsyncProcessGenerator<State, InMessage> {\n try {\n yield* this.pgenerator(ctx, arg0);\n } finally {\n // Cascade: stop every child (nice) and collect the refusers as orphans.\n const orphans: Array<AnyProcess> = [...this.orphans];\n const parentSender: SenderInfo = { fromName: this.pname, fromId: this.id };\n const stopPromises = this.children.map(async (child) => {\n const stopped = await child.stop({ from: parentSender });\n if (!stopped) {\n orphans.push(child);\n console.warn(\n `posipaki: child \"${child.pname}\" did not stop within ${CHILD_STOP_TIMEOUT_MS}ms; continuing shutdown`,\n );\n }\n });\n\n await Promise.all(stopPromises);\n // Hand surviving children and inherited orphans up to the parent for adoption (see ctx-orphans proposal).\n // In-process only.\n this.pvtPrepareHandoff(orphans);\n ctx.toParent({ type: \"EXIT\", orphans });\n // Unsubscribe from children/monitored processes so a dead parent\n // doesn't keep receiving their messages (handoff collectors stay on the orphans).\n this.pvtUnsubscribeAll();\n if (ctx.afterExit) await ctx.afterExit();\n }\n }\n\n // ---- fork -----------------------------------------------------------------\n\n fork<ChildArgs, ChildState, ChildIM extends Message, ChildOM extends Message>(\n fn: AsyncProcessFn<ChildArgs, ChildState, ChildIM, ChildOM>,\n pname: string,\n ): (args: ChildArgs) => AsyncProcess<ChildArgs, ChildState, ChildIM, ChildOM, {}> {\n return (args: ChildArgs) => {\n const child = new AsyncProcess<ChildArgs, ChildState, ChildIM, ChildOM, {}>(fn, pname);\n this.adopt(child);\n child.start(args, this.pname, this.id);\n return child;\n };\n }\n\n forkSync<ChildArgs, ChildState, ChildIM extends Message, ChildOM extends InMessage>(\n fn: ProcessFn<ChildArgs, ChildState, ChildIM, ChildOM>,\n pname: string,\n ): (args: ChildArgs) => AsyncProcess<ChildArgs, ChildState, ChildIM, ChildOM, {}> {\n return this.fork(asyncify(fn), pname);\n }\n\n // ---- message processing ---------------------------------------------------\n\n protected async pvtTick(): Promise<void> {\n if (!this.current || this.pvtTickInProgress) return;\n\n this.pvtTickInProgress = true;\n try {\n let msgAndSender: WithSender<InMessage | StopMessage> | undefined;\n let ret: IteratorResult<State | null, void> | null = null;\n while ((msgAndSender = this.buffer.shift()) !== undefined) {\n ret = await this.pvtSafeNext(msgAndSender);\n if (!ret || ret.done) break;\n }\n this.notify();\n this.pvtEatResult(ret);\n } catch (e) {\n this.pvtExitReject?.(e);\n this.pvtExitReject = null;\n } finally {\n this.pvtTickInProgress = false;\n }\n }\n\n /** Call `.next()` and redirect unhandled rejections. */\n private async pvtSafeNext(\n msgAndSender: WithSender<InMessage | StopMessage>,\n ): Promise<IteratorResult<State | null, void> | null> {\n try {\n return await this.current!.next(msgAndSender);\n } catch (e) {\n this.pvtExitReject?.(e);\n this.pvtExitReject = null;\n return { done: true, value: undefined };\n }\n }\n\n private pvtEatResult(\n ret: IteratorResult<State | null, void> | Promise<IteratorResult<State | null, void>> | null,\n ): void {\n if (!ret) return;\n Promise.resolve(ret).then((r) => {\n if (r.done) {\n this.exitWaiter.resolve();\n }\n });\n }\n\n /** Broadcast a message to all children. */\n toAllChildren(msg: Message): void {\n const stamp: SenderInfo = { fromName: this.pname, fromId: this.id };\n this.children.forEach((p) => p.send([msg, stamp] as WithSender<Message>));\n }\n\n /** Stamp and enqueue a message from a named sender (external API). */\n send(msg: InMessage | StopMessage, from?: SenderInfo): void;\n /** Enqueue a pre-stamped message (internal: fromChild, toAllChildren). */\n send(msgAndSender: WithSender<InMessage | StopMessage>): void;\n send(\n msgOrTuple: InMessage | StopMessage | WithSender<InMessage | StopMessage>,\n from?: SenderInfo,\n ): void {\n if (this.pvtDead) return;\n if (\"type\" in msgOrTuple) {\n this.buffer.push([msgOrTuple as InMessage | StopMessage, from as SenderInfo]);\n } else {\n this.buffer.push(msgOrTuple as WithSender<InMessage | StopMessage>);\n }\n this.pvtScheduleTick();\n }\n\n /**\n * Synchronously flush the buffer. For sync processes use {@link Process.tick};\n * for async processes this is **not guaranteed** to process everything\n * immediately if reducers contain `await`. Prefer `send()` + `await proc.wait()`.\n */\n tick(): void {\n this.nextTick?.flush();\n this.nextTick = null;\n }\n\n private pvtScheduleTick(): void {\n if (this.pvtIsPaused || this.pvtDead) return;\n\n this.nextTick?.cancel();\n this.nextTick = defer(() => {\n this.nextTick = null;\n void this.pvtTick();\n });\n }\n\n // ---- subscribers ----------------------------------------------------------\n\n notify(): void {\n this.stateSubscribers.forEach((f) => f());\n }\n\n get isListenedTo(): boolean {\n return this.stateSubscribers.length > 0;\n }\n\n subscribe(channel: \"message\", cb: MessageCallback<OutMessage>): () => void;\n subscribe(channel: \"state\", cb: NotifyFn): () => void;\n /** @deprecated Use `subscribe(\"state\", cb)`. */\n subscribe(cb: NotifyFn): () => void;\n subscribe(\n channelOrCb: \"message\" | \"state\" | NotifyFn,\n cb?: MessageCallback<OutMessage> | NotifyFn,\n ): () => void {\n if (typeof channelOrCb === \"function\") {\n return this.subscribe(\"state\", channelOrCb);\n }\n if (channelOrCb === \"message\") {\n const fn = cb as MessageCallback<OutMessage>;\n this.messageSubscribers.push(fn);\n return () => this.pvtUnsubscribe(this.messageSubscribers, fn);\n }\n const fn = cb as NotifyFn;\n this.stateSubscribers.push(fn);\n return () => this.pvtUnsubscribe(this.stateSubscribers, fn);\n }\n\n private pvtUnsubscribe<T>(list: Array<T>, fn: T): void {\n const idx = list.indexOf(fn);\n if (idx >= 0) list.splice(idx, 1);\n }\n\n // ---- pause / resume -------------------------------------------------------\n\n /**\n * Freeze dispatch: no further ticks are scheduled, so the process stops\n * *processing* incoming messages. This is half-working as a \"quiesce\"\n * primitive — it does not stop the process from *emitting* via async\n * callbacks (timers, fetch) that bypass the dispatch loop.\n */\n pause(): void {\n this.nextTick?.cancel();\n this.nextTick = null;\n this.pvtIsPaused = true;\n }\n\n resume(): void {\n this.pvtIsPaused = false;\n this.pvtScheduleTick();\n }\n\n /**\n * Hard-kill this process: abandon the generator without running its\n * `finally` (no EXIT, no STOP cascade), drop the inbox and observers,\n * unsubscribe from children/monitors, and settle `wait()`/`ready()`.\n *\n * There is nothing to observe afterward — callers remove the process from\n * their `children`/`orphans` lists imperatively. Does not cascade to this\n * process's own children; they are abandoned (force-stop them separately if\n * owned).\n *\n * Best-effort: an idle generator (suspended at `yield`) is abandoned\n * cleanly; a generator mid-`await` completes its `finally` when that await\n * settles, because JS offers no way to cancel a pending promise.\n */\n forceStop(opts?: { cascade?: boolean }): void {\n if (this.pvtDead) return;\n this.pvtDead = true;\n\n // Abandon the generator so its finally block never runs.\n this.current = null;\n\n // Drop the inbox and stop scheduling.\n this.buffer.length = 0;\n this.nextTick?.cancel();\n this.nextTick = null;\n\n // Release incoming observers and outgoing subscriptions.\n this.messageSubscribers.length = 0;\n this.stateSubscribers.length = 0;\n this.pvtUnsubscribeAll();\n // Drop any handoff state this process carried as an unowned orphan.\n this.unparent();\n\n // Settle waiters.\n this.pvtResolveReady();\n this.exitWaiter.resolve();\n this.pvtExitReject = null;\n\n if (opts?.cascade) {\n // Stop the children too, starting with the nice stop (fire-and-forget:\n // the hard kill itself does not block on their graceful exit).\n const selfSender: SenderInfo = { fromName: this.pname, fromId: this.id };\n for (const child of this.children) {\n void child.stop({ force: true, from: selfSender }).catch(() => {});\n }\n }\n }\n\n /**\n * Stop this process. Sends STOP (the nice way — the generator cooperates\n * and its `finally` runs) and awaits on a best-effort basis.\n *\n * With `{ force: true }`, when the process refuses (does not exit within the\n * timeout) it escalates: fires `generator.return()` *without awaiting* (throw\n * the generator away for GC to find), cascades to children with the same\n * ladder, then hard-kills itself.\n *\n * Resolves `true` if the process stopped (gracefully or forced), `false` if\n * it refused and `force` was not requested.\n */\n async stop(opts?: { force?: boolean; from?: SenderInfo }): Promise<boolean> {\n if (this.pvtDead) return true;\n\n this.send({ type: \"STOP\" } as StopMessage, opts?.from);\n\n try {\n await withTimeout(this.wait(), CHILD_STOP_TIMEOUT_MS, \"stop\");\n return true;\n } catch (e) {\n if ((e as Error)?.message !== \"Timeout:stop\") throw e;\n // refused to stop within the timeout\n }\n\n if (!opts?.force) return false;\n\n // Escalate: give the finally a chance to run (fire-and-forget), but do not\n // block on it — the process may be stuck awaiting a dead promise.\n void this.current?.return(undefined);\n\n // Cascade to children with the same ladder, stamped from this process.\n const selfSender: SenderInfo = { fromName: this.pname, fromId: this.id };\n await Promise.all(\n [...this.children].map((child) => child.stop({ force: true, from: selfSender })),\n );\n\n this.forceStop();\n return true;\n }\n\n // ---- waiting --------------------------------------------------------------\n\n /**\n * Returns a promise that resolves when the generator completes, or\n * rejects if an unhandled error occurs during message processing.\n */\n wait(): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n this.pvtExitReject = reject;\n\n this.exitWaiter.promise.then(\n () => {\n this.pvtExitReject = null;\n resolve();\n },\n (e) => {\n this.pvtExitReject = null;\n reject(e);\n },\n );\n });\n }\n\n // ---- child messages -------------------------------------------------------\n\n /**\n * Tap another process's message channel: every message it emits is fed\n * into this process's incoming queue. No ownership — the sender's EXIT\n * does not touch `children`/`orphans`.\n */\n monitor<ChildArgs, ChildState, ChildIM extends Message, ChildOM extends Message>(\n child: AsyncProcess<ChildArgs, ChildState, ChildIM, ChildOM, {}>,\n ): () => void {\n const unsub = child.subscribe(\"message\", (msg, from) => {\n this.send([msg, from] as WithSender<InMessage | StopMessage>);\n });\n this.pvtOutgoingSubscriptions.push(unsub);\n return unsub;\n }\n\n /**\n * Claim another process as a child: its messages are routed here and its\n * EXIT removes it from `children` (collecting its orphans). Generalizes\n * what `fork` does — used for both spawning and orphan adoption.\n */\n adopt<ChildArgs, ChildState, ChildIM extends Message, ChildOM extends Message>(\n child: AsyncProcess<ChildArgs, ChildState, ChildIM, ChildOM, {}>,\n ): () => void {\n this.children.push(child as unknown as AnyProcess);\n const unsub = child.subscribe(\"message\", (msg, from) => {\n this.pvtChildMessage(msg, from);\n });\n this.pvtAdoptUnsubs.set(child.id, unsub);\n // Lossless handoff: drain a pending buffer left by the previous parent.\n this.pvtDrainPending(child as unknown as AnyProcess);\n return unsub;\n }\n\n /** Handles a child's emitted message: EXIT cleanup + forward to the queue. */\n private pvtChildMessage(msg: Message, sender: SenderInfo): void {\n if (msg.type === \"EXIT\") {\n // sender.fromId === child's id (stamped by the child's ctx.toParent)\n // Mutate in place so ctx.children (a live reference) stays consistent.\n const idx = this.children.findIndex((p) => p.id === sender.fromId);\n if (idx >= 0) this.children.splice(idx, 1);\n const orphans = (msg as ExitMessage).orphans;\n if (orphans && orphans.length > 0) {\n this.orphans.push(...orphans);\n }\n }\n this.send([msg, sender] as WithSender<InMessage | StopMessage>);\n }\n\n // ---- orphan handoff -------------------------------------------------------\n\n /** Unsubscribe from all outgoing subscriptions (monitors + adopt). */\n private pvtUnsubscribeAll(): void {\n for (const unsub of this.pvtOutgoingSubscriptions) unsub();\n this.pvtOutgoingSubscriptions = [];\n for (const unsub of this.pvtAdoptUnsubs.values()) unsub();\n this.pvtAdoptUnsubs.clear();\n }\n\n /** Prepare surviving children and inherited orphans for a lossless handoff:\n * recover undrained messages and install a collector on each orphan. */\n private pvtPrepareHandoff(orphans: Array<AnyProcess>): void {\n for (const orphan of orphans) {\n this.pvtBackFeed(orphan);\n if (!orphan.pvtCollectorUnsub) {\n this.pvtSwapToCollector(orphan);\n }\n }\n }\n\n /** Recover messages the orphan emitted into my inbox that I never drained. */\n private pvtBackFeed(orphan: AnyProcess): void {\n const fromOrphan: Array<WithSender<Message>> = [];\n this.buffer = this.buffer.filter((entry) => {\n if (entry[1].fromId === orphan.id) {\n fromOrphan.push(entry);\n return false;\n }\n return true;\n });\n if (fromOrphan.length === 0) return;\n if (!orphan.pvtPending) orphan.pvtPending = [];\n orphan.pvtPending.unshift(...fromOrphan);\n }\n\n /** Replace my ownership subscription to `orphan` with a handoff collector. */\n private pvtSwapToCollector(orphan: AnyProcess): void {\n const mine = this.pvtAdoptUnsubs.get(orphan.id);\n if (mine) {\n mine();\n this.pvtAdoptUnsubs.delete(orphan.id);\n }\n if (!orphan.pvtPending) orphan.pvtPending = [];\n const pending = orphan.pvtPending;\n orphan.pvtCollectorUnsub = orphan.subscribe(\"message\", (msg, from) => {\n pending.push([msg, from]);\n });\n }\n\n /** Drain a handed-off orphan's pending buffer into my inbox (lossless adopt). */\n private pvtDrainPending(orphan: AnyProcess): void {\n if (orphan.pvtCollectorUnsub) {\n orphan.pvtCollectorUnsub();\n orphan.pvtCollectorUnsub = null;\n }\n const pending = orphan.pvtPending;\n if (!pending) return;\n orphan.pvtPending = null;\n for (const [msg, from] of pending) {\n this.pvtChildMessage(msg, from);\n }\n }\n\n /**\n * Drop this process's handoff state (collector + pending buffer) without\n * stopping it. Used by `onOrphan`'s \"unparent\" decision: the orphan keeps\n * running and stays in the orphans list, but its in-flight buffer is gone.\n */\n unparent(): void {\n if (this.pvtCollectorUnsub) {\n this.pvtCollectorUnsub();\n this.pvtCollectorUnsub = null;\n }\n this.pvtPending = null;\n }\n}\nexport type AnyProcess = AsyncProcess<unknown, unknown, Message, Message, {}>;\n// ---- spawnAsync -------------------------------------------------------------\n\n/**\n * Spawn a new async process. Accepts both sync and async process\n * functions — sync ones are automatically wrapped with {@link asyncify}.\n */\nexport function spawnAsync<\n Args,\n State,\n InMessage extends Message = Message,\n OutMessage extends Message = ExitMessage,\n>(\n fn: AsyncProcessFn<Args, State, InMessage, OutMessage>,\n pname: string,\n toParent?: MessageCallback<OutMessage>,\n parentName?: string | null,\n parentId?: symbol | null,\n): (args: Args) => AsyncProcess<Args, State, InMessage, OutMessage, {}> {\n return (args: Args) => {\n const proc = new AsyncProcess<Args, State, InMessage, OutMessage, {}>(fn, pname, toParent);\n proc.start(args, parentName, parentId);\n return proc;\n };\n}\n","// ── defineActor — high-level actor wrapper ───────────────────────────────────\n//\n// Compiles a declarative config into an AsyncProcessFn. Built on top of\n// the existing runDispatchAsync / spawnAsync primitives.\n//\nimport { type AsyncProcess, runDispatchAsync, spawnAsync, AnyProcess } from \"./process.async.js\";\nimport type {\n WithSender,\n SenderInfo,\n AsyncProcessFn,\n Message,\n ExitMessage,\n ProcessCtx,\n} from \"./types.js\";\nimport type {\n ActorDefinition,\n ActorConfig,\n ActorContext,\n MethodOptions,\n ActorMessages,\n HandlerOptions,\n HandlerFn,\n ReflectionOptions,\n AnyConfig,\n HidePrivate,\n} from \"./actor-types.js\";\nimport { STOP_SENTINEL } from \"./actor-types.js\";\nimport { ActorDecorated, type ActorPlugin, ActorReflection, callHook } from \"./hooks.js\";\n\nexport function defineMessages<OutMsg extends Message = Message>(): ActorMessages<OutMsg> {\n return undefined as unknown as ActorMessages<OutMsg>;\n}\n\nfunction hidePrivate<T>(value: T): HidePrivate<T> {\n if (value && typeof value === \"object\" && \"private\" in value && \"public\" in value) {\n return value.public as HidePrivate<T>;\n }\n return value as HidePrivate<T>;\n}\n\nfunction resolvePlugins(\n raw: ActorPlugin[] | ((parents: ActorPlugin[]) => ActorPlugin[]) | undefined,\n parentPlugins?: ActorPlugin[],\n addPlugins?: ActorPlugin[],\n): ActorPlugin[] {\n const resolved = !raw\n ? parentPlugins\n ? [...parentPlugins]\n : []\n : Array.isArray(raw)\n ? [...raw]\n : raw(parentPlugins ?? []);\n\n const combined = addPlugins ? [...resolved, ...addPlugins] : resolved;\n\n // Deduplicate by function name\n const seen = new Set<string>();\n return combined.filter((p) => {\n const name = p.name;\n if (!name) {\n console.warn(\"posipaki: plugin has no name, dedup won't work\");\n return true;\n }\n if (seen.has(name)) return false;\n seen.add(name);\n return true;\n });\n}\n\nasync function assembleActor<C>(\n config: C,\n plugins: ActorPlugin[],\n addPlugins?: ActorPlugin[],\n): Promise<C> {\n // Work with the default ActorPlugin type internally, cast back on return\n let cur = config as AnyConfig;\n for (const p of plugins) {\n try {\n cur = await p(cur);\n } catch (e: unknown) {\n console.error(`[assembleActor] plugin \"${p.name || \"?\"}\" failed:`, e);\n }\n }\n cur.resolvedPlugins = plugins;\n if (addPlugins) cur.addPlugins = addPlugins;\n return cur as C;\n}\n\nexport function defineActor<\n Args,\n InternalState,\n InMsg extends Message,\n OutMsg extends Message,\n Methods extends MethodOptions,\n Handlers extends HandlerOptions<InMsg>,\n ReflectionMethods extends ReflectionOptions,\n>(\n config: ActorConfig<Args, InternalState, InMsg, OutMsg, Methods, Handlers, ReflectionMethods>,\n): ActorDefinition<Args, InternalState, InMsg, OutMsg, ReflectionMethods> {\n const actorCtxMap = new Map<\n symbol,\n ActorContext<Args, InternalState, InMsg, OutMsg, Methods, Handlers, ReflectionMethods>\n >();\n\n function makeRuntime(\n assembly: ActorConfig<Args, InternalState, InMsg, OutMsg, Methods, Handlers, ReflectionMethods>,\n ): AsyncProcessFn<Args, HidePrivate<InternalState>, InMsg, OutMsg> {\n return async function* (\n ctx,\n args,\n ): AsyncGenerator<HidePrivate<InternalState | null>, void, WithSender<InMsg>> {\n let done = false;\n let exitReason: unknown;\n let rawState: InternalState = undefined as unknown as InternalState;\n\n const decorated = new Map();\n const self: ActorContext<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods & ActorReflection\n > = {\n ctx,\n ...((assembly.methods || {}) as Methods),\n ...((assembly.$decorate || {}) as ActorDecorated),\n reflection: {} as ReflectionMethods & ActorReflection,\n state: rawState,\n name: ctx.pname,\n id: ctx.id,\n async emit(msg: OutMsg) {\n await callHook(assembly.onEmit, undefined, self, msg, {\n fromName: ctx.pname,\n fromId: ctx.id,\n });\n ctx.toParent(msg);\n },\n agreeToStop() {\n exitReason = \"stopped\";\n done = true;\n },\n exit(reason: unknown) {\n exitReason = reason;\n done = true;\n },\n $child: {} as Record<string, AnyProcess>,\n decorators: {},\n fork: async <A, S, IM extends Message, OM extends InMsg, R extends ReflectionOptions>(\n childActor: ActorDefinition<A, S, IM, OM, R>,\n childArgs?: A,\n forkOpts?: { name?: string; addPlugins?: ActorPlugin[] },\n ): Promise<AsyncProcess<A, HidePrivate<S>, IM, OM, R & ActorReflection>> => {\n let child: AsyncProcess<A, HidePrivate<S>, IM, OM, R & ActorReflection>;\n const childName =\n forkOpts?.name ?? childActor?.name ?? `child-${Object.keys(self.$child).length}`;\n const treeName = `${ctx.pname}:${childName}`;\n const childAddPlugins = [...(assembly.addPlugins || []), ...(forkOpts?.addPlugins || [])];\n child = await childActor.spawnAsChild(ctx, childArgs!, {\n name: treeName,\n parentPlugins: assembly.resolvedPlugins || [],\n ...(childAddPlugins.length ? { addPlugins: childAddPlugins } : {}),\n });\n self.$child[child.pname] = child as unknown as AnyProcess;\n return child;\n },\n };\n actorCtxMap.set(ctx.id, self);\n ctx.afterExit = async () => {\n await callHook(assembly.afterEnd, assembly.onError, self, exitReason);\n };\n\n for (const [k, v] of decorated) {\n (self as Record<string, unknown>)[k] = v;\n }\n\n await callHook(\n assembly.beforeStart,\n assembly.onError,\n self as ActorContext<\n Args,\n never, // state not set yet\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods & ActorReflection\n >,\n );\n\n if (assembly.setup) {\n rawState = await assembly.setup.call(\n self as ActorContext<\n Args,\n never, // break inference cycle here\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods & ActorReflection\n >,\n args,\n );\n } else {\n rawState = null as InternalState;\n }\n self.state = rawState;\n yield hidePrivate(rawState);\n await callHook(assembly.afterStart, assembly.onError, self);\n\n yield* runDispatchAsync<WithSender<InMsg | ExitMessage>>(\n ctx.pname,\n async (stamped) => {\n const [msg, sender] = stamped;\n if (msg.type === \"STOP\") {\n if (assembly.onStopRequested) {\n await callHook(assembly.onStopRequested, assembly.onError, self);\n // Hook may call agreeToStop(). If not, actor keeps running.\n } else {\n exitReason = \"stopped\";\n done = true;\n }\n return;\n }\n if (msg.type === \"EXIT\") {\n // FIXME: process name are user-specified\n // and should not be used for indexing so\n // we don't get into name conflicts\n const childName = sender.fromName;\n if (childName && self.$child[childName]) {\n delete self.$child[childName];\n }\n await callHook(\n assembly.onChildExit,\n assembly.onError,\n self,\n childName,\n msg as ExitMessage,\n );\n // Orphan policy: a child that exits may leave still-running\n // grandchildren behind (see ctx-orphans / orphan-policy).\n const orphans = (msg as ExitMessage).orphans;\n if (orphans && orphans.length > 0) {\n for (const orphan of orphans) {\n // Default when no hook is defined: hard-kill the orphan.\n const decision = assembly.onOrphan\n ? await callHook(assembly.onOrphan, assembly.onError, self, orphan)\n : \"force-stop\";\n if (decision === \"adopt\") {\n ctx.adopt(orphan);\n const idx = ctx.orphans.indexOf(orphan);\n if (idx >= 0) ctx.orphans.splice(idx, 1);\n self.$child[orphan.pname] = orphan;\n } else if (decision === \"force-stop\") {\n orphan.forceStop({ cascade: true });\n const idx = ctx.orphans.indexOf(orphan);\n if (idx >= 0) ctx.orphans.splice(idx, 1);\n } else if (decision === \"unparent\") {\n orphan.unparent();\n }\n // 'leave' (or undefined) → do nothing; it propagates on exit.\n }\n }\n }\n let hookStopped = false;\n if (msg.type !== \"STOP\" && msg.type !== \"EXIT\" && assembly.onMessage) {\n const result = await callHook(\n assembly.onMessage,\n assembly.onError,\n self,\n msg as InMsg,\n sender,\n );\n if (result === STOP_SENTINEL) hookStopped = true;\n }\n if (msg.type !== \"STOP\" && !hookStopped) {\n const handler =\n ((assembly.handlers || ({} as Handlers))[\n msg.type as keyof Handlers\n ] as HandlerFn<InMsg>) || assembly.onUnhandled;\n\n await callHook(handler, assembly.onError, self, msg as InMsg, sender);\n }\n },\n () => done,\n );\n\n await callHook(assembly.beforeEnd, assembly.onError, self, exitReason);\n };\n }\n\n type ReflectableProcess = {\n id: symbol;\n $reflection: Record<string, Function>;\n };\n function attachReflection(\n proc: ReflectableProcess,\n reflectionMethods: ReflectionMethods | undefined,\n ): void {\n if (!reflectionMethods) return;\n const self = actorCtxMap.get(proc.id);\n const refl = proc.$reflection as Record<string, Function>;\n for (const [k, m] of Object.entries(reflectionMethods)) {\n refl[k] = m.bind(self);\n }\n }\n\n return {\n fn: makeRuntime(config),\n name: config.name,\n pvtPluginsRaw: config.plugins,\n inMessages: config.inMessages,\n outMessages: config.outMessages,\n async spawn(\n args: Args,\n opts?: {\n name?: string;\n toParent?: (msg: OutMsg, from: SenderInfo) => void;\n addPlugins?: ActorPlugin[];\n parentName?: string | null;\n parentId?: symbol | null;\n },\n ): Promise<\n AsyncProcess<\n Args,\n HidePrivate<InternalState>,\n InMsg,\n OutMsg,\n ReflectionMethods & ActorReflection\n >\n > {\n const plugs = resolvePlugins(config.plugins, undefined, opts?.addPlugins);\n const assembly = await assembleActor(config, plugs, opts?.addPlugins);\n const runtime = makeRuntime(assembly);\n const proc = spawnAsync(\n runtime,\n opts?.name ?? assembly.name ?? \"actor\",\n opts?.toParent,\n opts?.parentName,\n opts?.parentId,\n )(args);\n attachReflection(proc, assembly.$reflectionMethods as ReflectionMethods);\n return proc as AsyncProcess<\n Args,\n HidePrivate<InternalState>,\n InMsg,\n OutMsg,\n ReflectionMethods & ActorReflection\n >;\n },\n async spawnAsChild(\n ctx: ProcessCtx<unknown, unknown, OutMsg, Message>,\n args: Args,\n opts?: {\n name?: string;\n parentPlugins?: ActorPlugin[];\n addPlugins?: ActorPlugin[];\n },\n ) {\n const plugs = resolvePlugins(config.plugins, opts?.parentPlugins, opts?.addPlugins);\n const assembly = await assembleActor(config, plugs, opts?.addPlugins);\n const runtime = makeRuntime(assembly);\n const proc = ctx.fork(runtime, opts?.name ?? assembly.name ?? \"child\")(args);\n attachReflection(proc, assembly.$reflectionMethods as ReflectionMethods);\n return proc as AsyncProcess<\n Args,\n HidePrivate<InternalState>,\n InMsg,\n OutMsg,\n ReflectionMethods & ActorReflection\n >;\n },\n };\n}\n"],"mappings":"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"}