posipaki 0.35.2 → 0.37.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{client-C4LZE65N.d.ts → client-Cg_MlE0m.d.ts} +17 -4
- package/dist/client-Cg_MlE0m.d.ts.map +1 -0
- package/dist/{define-actor-DqOW2StX.js → define-actor-CZysIKH4.js} +18 -4
- package/dist/define-actor-CZysIKH4.js.map +1 -0
- package/dist/hooks-CgXhmY4r.js.map +1 -1
- package/dist/{hooks-Dj59y_jN.d.ts → hooks-gmAsdJBN.d.ts} +20 -4
- package/dist/hooks-gmAsdJBN.d.ts.map +1 -0
- package/dist/hooks.d.ts +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/dist/json1-DYq9g7im.js +1124 -0
- package/dist/json1-DYq9g7im.js.map +1 -0
- package/dist/plugins/debug-logger.d.ts +2 -2
- package/dist/plugins/tree-introspection.d.ts +6 -6
- package/dist/plugins/tree-introspection.d.ts.map +1 -1
- package/dist/plugins/tree-introspection.js +5 -5
- package/dist/plugins/tree-introspection.js.map +1 -1
- package/dist/{process-pZDxIjLA.d.ts → process-DjRQSZef.d.ts} +2 -2
- package/dist/{process-pZDxIjLA.d.ts.map → process-DjRQSZef.d.ts.map} +1 -1
- package/dist/remote/index.d.ts +169 -8
- package/dist/remote/index.d.ts.map +1 -1
- package/dist/remote/index.js +2 -2
- package/dist/remote/node.d.ts +3 -3
- package/dist/remote/node.js +2 -2
- package/dist/testing/index.d.ts +2 -2
- package/dist/{types-CsE8xK3a.d.ts → types-DDc-stle.d.ts} +4 -2
- package/dist/types-DDc-stle.d.ts.map +1 -0
- package/dist/{version-0mlM8dbC.js → version-98a9sol-.js} +2 -2
- package/dist/{version-0mlM8dbC.js.map → version-98a9sol-.js.map} +1 -1
- package/dist/xfetch.d.ts +2 -2
- package/package.json +1 -1
- package/dist/client-C4LZE65N.d.ts.map +0 -1
- package/dist/define-actor-DqOW2StX.js.map +0 -1
- package/dist/hooks-Dj59y_jN.d.ts.map +0 -1
- package/dist/json1-DzPx9oX3.js +0 -200
- package/dist/json1-DzPx9oX3.js.map +0 -1
- package/dist/types-CsE8xK3a.d.ts.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as Message } from "./types-
|
|
2
|
-
import { h as MethodOptions, l as ActorDefinition, p as HandlerOptions, v as ReflectionOptions } from "./hooks-
|
|
1
|
+
import { r as Message } from "./types-DDc-stle.js";
|
|
2
|
+
import { h as MethodOptions, l as ActorDefinition, p as HandlerOptions, v as ReflectionOptions } from "./hooks-gmAsdJBN.js";
|
|
3
3
|
//#region src/remote/channel.d.ts
|
|
4
4
|
interface StringTransport {
|
|
5
5
|
send(frame: string): void | Promise<void>;
|
|
@@ -38,10 +38,23 @@ declare function isExit(msg: Record<string, unknown>): msg is {
|
|
|
38
38
|
state: unknown;
|
|
39
39
|
};
|
|
40
40
|
};
|
|
41
|
+
type StreamKind = "message" | "state" | "exit";
|
|
42
|
+
declare function isStop(msg: Record<string, unknown>): msg is {
|
|
43
|
+
$stop: Record<string, unknown>;
|
|
44
|
+
};
|
|
45
|
+
declare function isPause(msg: Record<string, unknown>): msg is {
|
|
46
|
+
$pause: Record<string, unknown>;
|
|
47
|
+
};
|
|
48
|
+
declare function isResume(msg: Record<string, unknown>): msg is {
|
|
49
|
+
$resume: Record<string, unknown>;
|
|
50
|
+
};
|
|
51
|
+
declare function isRelease(msg: Record<string, unknown>): msg is {
|
|
52
|
+
$release: Record<string, unknown>;
|
|
53
|
+
};
|
|
41
54
|
//#endregion
|
|
42
55
|
//#region src/remote/client.d.ts
|
|
43
56
|
type ClientSpawner<Args> = (args: Args) => Promise<Channel>;
|
|
44
57
|
declare function remoteClient<Args, State, InMsg extends Message, OutMsg extends Message, Methods extends MethodOptions = MethodOptions, Handlers extends HandlerOptions<InMsg> = HandlerOptions<InMsg>, R extends ReflectionOptions = ReflectionOptions>(name: string, spawner: ClientSpawner<Args>): ActorDefinition<Args, State, InMsg, OutMsg, R>;
|
|
45
58
|
//#endregion
|
|
46
|
-
export {
|
|
47
|
-
//# sourceMappingURL=client-
|
|
59
|
+
export { StringTransport as a, isMsg as c, isRelease as d, isResume as f, StreamKind as i, isPause as l, isStop as m, remoteClient as n, isExit as o, isState as p, Channel as r, isInit as s, ClientSpawner as t, isProto as u };
|
|
60
|
+
//# sourceMappingURL=client-Cg_MlE0m.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-Cg_MlE0m.d.ts","names":[],"sources":["../src/remote/channel.ts","../src/remote/client.ts"],"mappings":";;;UAgBiB;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;;iBA6CK,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;;;KAavB;iBA+BI,OAAO,KAAK,0BAA0B;EAAS,OAAO;;iBAGtD,QAAQ,KAAK,0BAA0B;EAAS,QAAQ;;iBAGxD,SAAS,KAAK,0BAA0B;EAAS,SAAS;;iBAG1D,UAAU,KAAK,0BAA0B;EAAS,UAAU;;;;KCtGhE,cAAc,SAAS,MAAM,SAAS,QAAQ;iBAG1C,aACd,MACA,OACA,cAAc,SACd,eAAe,SACf,gBAAgB,gBAAgB,eAChC,iBAAiB,eAAe,SAAS,eAAe,QACxD,UAAU,oBAAoB,mBAE9B,cACA,SAAS,cAAc,QACtB,gBAAgB,MAAM,OAAO,OAAO,QAAQ"}
|
|
@@ -496,6 +496,18 @@ var AsyncProcess = class AsyncProcess {
|
|
|
496
496
|
}
|
|
497
497
|
};
|
|
498
498
|
/**
|
|
499
|
+
* Whether a value is a process, judged by what it holds rather than by which
|
|
500
|
+
* class built it. `instanceof` would answer about the bundle, not the value: a
|
|
501
|
+
* build that inlines its own copy of this class per entry point (one dist file
|
|
502
|
+
* importing the core, another doing the same) has two constructors for one kind
|
|
503
|
+
* of thing, and a process from one is not an instance of the other.
|
|
504
|
+
*/
|
|
505
|
+
function isProcess(value) {
|
|
506
|
+
if (typeof value !== "object" || value === null) return false;
|
|
507
|
+
const candidate = value;
|
|
508
|
+
return typeof candidate.pname === "string" && typeof candidate.id === "symbol" && typeof candidate.send === "function" && typeof candidate.fork === "function";
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
499
511
|
* Spawn a new async process. Accepts both sync and async process
|
|
500
512
|
* functions — sync ones are automatically wrapped with {@link asyncify}.
|
|
501
513
|
*/
|
|
@@ -660,10 +672,12 @@ function defineActor(config) {
|
|
|
660
672
|
};
|
|
661
673
|
}
|
|
662
674
|
function attachReflection(proc, reflectionMethods) {
|
|
663
|
-
if (!reflectionMethods) return;
|
|
664
675
|
const self = actorCtxMap.get(proc.id);
|
|
676
|
+
if (self) proc.$reflection = self.reflection;
|
|
677
|
+
if (!reflectionMethods) return;
|
|
665
678
|
const refl = proc.$reflection;
|
|
666
|
-
|
|
679
|
+
const written = Object.entries(reflectionMethods);
|
|
680
|
+
for (const [k, m] of written) refl[k] = async (...args) => await m.apply(self, args);
|
|
667
681
|
}
|
|
668
682
|
return {
|
|
669
683
|
fn: makeRuntime(config),
|
|
@@ -688,6 +702,6 @@ function defineActor(config) {
|
|
|
688
702
|
};
|
|
689
703
|
}
|
|
690
704
|
//#endregion
|
|
691
|
-
export {
|
|
705
|
+
export { runDispatchAsync as a, isProcess as i, defineMessages as n, spawnAsync as o, AsyncProcess as r, asyncify as s, defineActor as t };
|
|
692
706
|
|
|
693
|
-
//# sourceMappingURL=define-actor-
|
|
707
|
+
//# sourceMappingURL=define-actor-CZysIKH4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-actor-CZysIKH4.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/**\n * Framework-internal traffic: a message no actor ever sees. Used to resume the\n * generator without delivering anything — `start()` uses it to move past the\n * initial yield, and `wake()` to give a parked dispatch loop one chance to\n * notice that it is done. Actors skip it before any hook or handler runs.\n */\nexport const INTERNAL_ADVANCE = \"__ADVANCE__\";\n\n/** Sender stamp for the messages above. */\nconst internalSender = (): SenderInfo => ({\n fromName: \"__internal__\",\n fromId: Symbol(\"__internal__\"),\n});\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\n * methods, each wrapped so calling one answers with a promise whatever the\n * method was written as. */\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 /**\n * Set once the initial state exists. An actor whose start failed never got\n * one: it is dead on arrival, and its end-of-life hooks must not run against\n * a state that never arrived (see `pvtStartFailed`).\n */\n private pvtStarted: boolean = false;\n private pvtTickInProgress: boolean = false;\n /** True once the initial state has been delivered and `start()` has advanced\n * the generator into its dispatch loop. Until then no tick may run: the\n * generator is still suspended at the initial yield, which belongs to\n * `start()` and would swallow a message handed to it (see `start()`). */\n private pvtDispatchLive: 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 // `ready()` carries a failed start to whoever awaited it. A caller that\n // never awaited it must not turn that into an unhandled rejection.\n void this.pvtReady.promise.catch(() => {});\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 wake: () => {\n this.pvtWake();\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(\n (ret: IteratorResult<State | null, void>) => {\n this.state = ret.value ?? null;\n this.pvtStarted = true;\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: INTERNAL_ADVANCE } as InMessage,\n internalSender(),\n ];\n // Only now may a tick feed the generator. Anything that arrived while\n // we were still setting up waited in the buffer: no tick is pending for\n // it (they were all held back), so schedule one.\n this.pvtDispatchLive = true;\n this.pvtEatResult(this.current!.next(advance));\n if (this.buffer.length > 0) this.pvtScheduleTick();\n },\n // The generator threw before its first yield: setup() — or a hook that\n // runs before it — failed, so there is no state and nothing to dispatch.\n (e: unknown) => this.pvtStartFailed(e),\n );\n return this;\n }\n\n /**\n * The process never started: its first `next()` rejected before any state\n * existed. The failure *is* the outcome, so `ready()` carries it — `spawn()`\n * waits on `ready()`, which is what turns a spawner that fails into a spawn\n * that fails, with its own error intact. Whoever is already parked in\n * `wait()` is told as well; a later `wait()` sees the process as ended.\n */\n private pvtStartFailed(e: unknown): void {\n this.pvtDead = true;\n // Abandon the generator: it is already finished (it threw), but nothing\n // may tick it again.\n this.current = null;\n this.buffer.length = 0;\n this.nextTick?.cancel();\n this.nextTick = null;\n this.pvtUnsubscribeAll();\n\n this.pvtReady.reject(e);\n this.pvtExitReject?.(e);\n this.pvtExitReject = null;\n this.exitWaiter.resolve();\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 // An actor that never got a state never started, and `afterEnd` is handed\n // a context whose state is typed as present: running it there means every\n // implementation that reads `this.state` trips over an undefined one —\n // and swaps the caller's error for its own TypeError.\n if (ctx.afterExit && this.pvtStarted) 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 /**\n * Give a parked dispatch loop one chance to notice a flag that was set from\n * outside it. Clearing `done` is not enough on its own: an idle process is\n * suspended at its dispatch yield, and nothing re-reads the flag until\n * something resumes it. A stop that arrives as a message (STOP) resumes the\n * loop by itself; this is for the paths that do not.\n */\n pvtWake(): void {\n if (this.pvtDead || !this.pvtDispatchLive) return;\n // The loop is running right now: it re-checks the flag as soon as the\n // reducer returns, so a wake-up message would only sit in the buffer.\n if (this.pvtTickInProgress) return;\n this.send([{ type: INTERNAL_ADVANCE } as InMessage, internalSender()]);\n }\n\n protected async pvtTick(): Promise<void> {\n // A message that arrives before the initial state is delivered is kept in\n // the buffer, not fed to the generator: the generator is still suspended at\n // its initial yield, and the value sent to that yield is discarded — the\n // message would be lost and `start()`'s advance would take its place.\n if (!this.current || !this.pvtDispatchLive || 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\n/**\n * Whether a value is a process, judged by what it holds rather than by which\n * class built it. `instanceof` would answer about the bundle, not the value: a\n * build that inlines its own copy of this class per entry point (one dist file\n * importing the core, another doing the same) has two constructors for one kind\n * of thing, and a process from one is not an instance of the other.\n */\nexport function isProcess(value: unknown): value is AnyProcess {\n if (typeof value !== \"object\" || value === null) return false;\n const candidate = value as Partial<AnyProcess>;\n return (\n typeof candidate.pname === \"string\" &&\n typeof candidate.id === \"symbol\" &&\n typeof candidate.send === \"function\" &&\n typeof candidate.fork === \"function\"\n );\n}\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 {\n type AsyncProcess,\n runDispatchAsync,\n spawnAsync,\n AnyProcess,\n INTERNAL_ADVANCE,\n} 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, PROPAGATE_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 // The loop only re-reads `done` when it is resumed: an idle actor is\n // parked at its dispatch yield and would sit there forever.\n ctx.wake();\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 /**\n * Lifecycle hooks are the actor's own control flow: if one throws, the\n * state machine is half-applied, so the error is fatal — `onError` still\n * observes it (a logger logs it), but it cannot absorb it. The actor goes\n * down and its parent still gets the EXIT, instead of staying up with\n * nothing left to do.\n *\n * Message hooks and handlers are not forced either way: they are called\n * with `onError` itself, and its *return value* decides — nothing means\n * \"handled, carry on\" (the default, and what an observing logger\n * returns), `propagateError()` means \"not handled\", and the actor goes\n * down with the same EXIT.\n */\n const hookErrorHandler = async (e: unknown): Promise<unknown> => {\n try {\n await assembly.onError?.call(self, e);\n } catch {\n // An error in the error handler must not mask the original one.\n }\n return PROPAGATE_SENTINEL;\n };\n ctx.afterExit = async () => {\n await callHook(assembly.afterEnd, hookErrorHandler, 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 hookErrorHandler,\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, hookErrorHandler, self);\n\n yield* runDispatchAsync<WithSender<InMsg | ExitMessage>>(\n ctx.pname,\n async (stamped) => {\n const [msg, sender] = stamped;\n if (msg.type === INTERNAL_ADVANCE) return; // framework traffic, not a message\n if (msg.type === \"STOP\") {\n if (assembly.onStopRequested) {\n await callHook(assembly.onStopRequested, hookErrorHandler, 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 hookErrorHandler,\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, hookErrorHandler, 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, hookErrorHandler, 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 const self = actorCtxMap.get(proc.id);\n if (self) {\n // One object under two names: the surface the handle exposes as\n // `$reflection` and the one the actor's own hooks see as `reflection`.\n // Handing the same object to both is what lets a method be added after\n // assembly — the first caller that needs that is a remote peer saying\n // which methods it can answer.\n proc.$reflection = self.reflection as unknown as Record<string, Function>;\n }\n if (!reflectionMethods) return;\n const refl = proc.$reflection as Record<string, Function>;\n // The declared contract is `ReflectionMethod`, whose parameters are `never`\n // because nothing is called through it; this is the one place that calls\n // what it describes.\n const written = Object.entries(reflectionMethods) as Array<\n [string, (...args: unknown[]) => unknown]\n >;\n for (const [k, m] of written) {\n // A promise whatever the method was written as, so a caller reads the same\n // call the same way whether the actor is here or behind a wire.\n refl[k] = async (...args: unknown[]) => await m.apply(self, args);\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 * Resolve only once the initial state is available. Default `true`:\n * a spawned process is safe to send to when `spawn()` returns. Pass\n * `false` for the raw handle — the caller then has to `await\n * proc.ready()` itself before sending anything it wants handled.\n */\n awaitReady?: boolean;\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 if (opts?.awaitReady !== false) await proc.ready();\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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks-CgXhmY4r.js","names":[],"sources":["../src/actor-types.ts","../src/hooks.ts"],"sourcesContent":["// ── defineActor types ────────────────────────────────────────────────────────\n//\n// Shared between define-actor.ts (implementation) and consumers that want\n// to reference the config/context/definition shapes without importing the\n// implementation module directly.\n\nimport type { SenderInfo, AsyncProcessFn, Message, ProcessCtx, ExitMessage } from \"./types.js\";\nimport type { ActorDecorated, ActorReflection } from \"./hooks.js\";\nimport type { AnyProcess, AsyncProcess } from \"./process.async.js\";\n\n// Internal marker do not use\nexport type ActorMessages<M extends Message> = {\n __tag_messages: M;\n};\nexport interface MethodOptions {\n [key: string]: Function;\n}\nexport type HandlerFn<InMsg extends Message> = (\n msg: InMsg,\n sender: SenderInfo,\n) => void | Promise<void>;\nexport type HandlerOptions<InMsg extends Message> = Omit<\n {\n [K in InMsg[\"type\"]]: HandlerFn<Extract<InMsg, { type: K }>>;\n },\n \"STOP\"\n>;\nexport type ReflectionMethod = (...args: unknown[]) => unknown;\nexport interface ReflectionOptions {}\nexport type Paired<Priv, Pub> = { public: Pub; private: Priv };\nexport type HidePrivate<T> = T extends Paired<unknown, unknown> ? T[\"public\"] : T;\n\nexport type SpawnedFrom<T extends ActorDefinition<any, any, any, any, any>> =\n T extends ActorDefinition<infer A, infer S, infer IM, infer OM, infer R>\n ? AsyncProcess<A, HidePrivate<S>, IM, OM, R & ActorReflection>\n : never;\n\nexport interface ActorDefinition<\n Args,\n InternalState,\n InMsg extends Message,\n OutMsg extends Message,\n ReflectionMethods extends ReflectionOptions,\n> {\n fn: AsyncProcessFn<Args, HidePrivate<InternalState>, InMsg, OutMsg>;\n /** Preferred process name (from config.name). */\n name?: string;\n /** Raw plugin config (array or transform). Resolved at fork time. @internal */\n pvtPluginsRaw?: ActorPlugin[] | PluginTransform;\n /** Spawn this actor as a standalone process. */\n 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 /** Wait for the initial state before resolving. Default `true`. */\n awaitReady?: boolean;\n },\n ): Promise<\n AsyncProcess<\n Args,\n HidePrivate<InternalState>,\n InMsg,\n OutMsg,\n ReflectionMethods & ActorReflection\n >\n >;\n /** Spawn this actor as a child of the calling process.\n * `ctx` must be able to fork children that emit `OutMsg` — i.e. the\n * parent's in-message is a supertype of this actor's out-message. */\n spawnAsChild<PMO extends Message>(\n ctx: ProcessCtx<unknown, unknown, OutMsg, PMO>,\n args: Args,\n opts?: {\n name?: string;\n parentPlugins?: ActorPlugin[];\n addPlugins?: ActorPlugin[];\n },\n ): Promise<\n AsyncProcess<\n Args,\n HidePrivate<InternalState>,\n InMsg,\n OutMsg,\n ReflectionMethods & ActorReflection\n >\n >;\n inMessages: ActorMessages<InMsg> | undefined;\n outMessages: ActorMessages<OutMsg> | undefined;\n}\n/**\n * The config object as a user writes it.\n *\n * Hooks take their `this` from the `ThisType` at the end of this type: a per-hook\n * annotation erases the inferred methods surface. `beforeStart` and `setup` keep\n * one, for the state.\n */\nexport type ActorConfig<\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 /** Preferred process name. Used by ctx.fork() when no explicit name is given. */\n name?: string;\n plugins?: ActorPlugin[] | PluginTransform;\n /** Non-overridable plugins added at spawn time (spawn/fork opts).\n * Set by the framework during assembly, not by user config. @internal */\n addPlugins?: ActorPlugin[];\n /** Resolved plugin chain (raw config transformed against parent plugins).\n * Set by the framework during assembly, replacing `plugins` (the raw form).\n * @internal */\n resolvedPlugins?: ActorPlugin[];\n outMessages?: ActorMessages<OutMsg>;\n inMessages?: ActorMessages<InMsg>;\n /** Fires once `self` is built, before `setup`. State is not yet set\n * (`this.state` is `never`). Use for registering the process/ctx before\n * any child is forked in `setup`. */\n beforeStart?: (\n this: ActorContext<\n Args,\n never,\n InMsg,\n OutMsg,\n MethodOptions,\n Handlers,\n ReflectionMethods & ActorReflection\n >,\n ) => void | Promise<void>;\n\n /** `this.state` is `never`: the returned value is the state. */\n setup?: (\n this: ActorContext<\n Args,\n never,\n InMsg,\n OutMsg,\n MethodOptions,\n Handlers,\n ReflectionMethods & ActorReflection\n >,\n args: Args,\n ) => Promise<InternalState> | InternalState;\n\n afterStart?: () => void | Promise<void>;\n\n onStopRequested?: () => HookResult | Promise<HookResult>;\n\n beforeEnd?: (reason?: unknown) => HookResult | Promise<HookResult>;\n\n /**\n * Runs once the actor has ended — after its EXIT. It is *not* called when the\n * actor never started (`setup()` or a pre-start hook threw): the state is\n * typed as present here, and an actor that never got one has nothing to end.\n */\n afterEnd?: (reason?: unknown) => HookResult | Promise<HookResult>;\n\n onError?: (error?: unknown) => HookResult | ErrorResult | Promise<HookResult | ErrorResult>;\n\n onEmit?: (msg: OutMsg, sender: SenderInfo) => HookResult | Promise<HookResult>;\n\n onMessage?: (msg: InMsg, sender: SenderInfo) => HookResult | Promise<HookResult>;\n\n onUnhandled?: (msg: Message, sender: SenderInfo) => void | Promise<void>;\n\n onChildExit?: (name: string, reason: ExitMessage) => HookResult | Promise<HookResult>;\n\n /** Fires for each orphan a child leaves behind (in its EXIT). Return the\n * policy: `'adopt'` (promote to a child, draining its buffer), `'force-stop'`\n * (hard-kill), `'unparent'` (drop its buffer, keep it running in `orphans`),\n * or `'leave'` (keep buffering, propagate up on my exit). When no `onOrphan`\n * is defined, the default is `'force-stop'`. */\n onOrphan?: (orphan: AnyProcess) => OrphanDecision | void | Promise<OrphanDecision | void>;\n\n handlers: Handlers &\n ThisType<\n ActorContext<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods & ActorReflection\n >\n >;\n\n methods?: Methods &\n ThisType<\n ActorContext<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods & ActorReflection\n >\n >;\n $reflectionMethods?: ReflectionMethods &\n ThisType<\n ActorContext<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ActorReflection & ActorReflection\n >\n >;\n // for plugin use only\n $decorate?: Partial<ActorDecorated>;\n} & ThisType<\n ActorContext<Args, InternalState, InMsg, OutMsg, Methods, Handlers, ReflectionMethods & ActorReflection>\n>;\nexport type AnyConfig = ActorConfig<\n unknown,\n unknown,\n Message,\n Message,\n MethodOptions,\n HandlerOptions<Message>,\n ReflectionOptions\n>;\n\n// ── stop propagation sentinel ────────────────────────────────────────────\n\n/** Returned by onMessage hooks to prevent further dispatch. */\nexport const STOP_SENTINEL = Symbol(\"posipaki.stopPropagation\");\n\n/** Type-safe sentinel for short-circuiting onMessage hooks. */\nexport const stopPropagation = (): typeof STOP_SENTINEL => STOP_SENTINEL;\n\n/**\n * Returned by an `onError` handler that only *observed* the error — logged it,\n * counted it — and did not handle it. The framework then lets the error\n * propagate: the actor still goes down and its parent still gets the EXIT.\n * Without this an observing handler (the bundled debug logger is one) silently\n * turns a broken lifecycle hook into a survivor with nothing left to do.\n */\nexport const PROPAGATE_SENTINEL = Symbol(\"posipaki.propagateError\");\n\n/** Type-safe sentinel for an onError handler that did not handle the error. */\nexport const propagateError = (): typeof PROPAGATE_SENTINEL => PROPAGATE_SENTINEL;\n\n/** Return type of onError handlers: void (handled) or sentinel (not handled). */\nexport type ErrorResult = void | typeof PROPAGATE_SENTINEL;\n\n// ── hook function types ──────────────────────────────────────────────────\n\n/** Return type of onMessage hooks: void (continue) or sentinel (stop). */\nexport type HookResult = void | typeof STOP_SENTINEL;\n\n/** Decision returned by `onOrphan` for how to handle an inherited orphan. */\nexport type OrphanDecision = \"adopt\" | \"force-stop\" | \"unparent\" | \"leave\";\n// ── plugin types ─────────────────────────────────────────────────────────\n\n/** A reusable unit of actor behaviour. */\nexport type ActorPlugin<C = AnyConfig> = (config: C) => C | Promise<C>;\n\n/** Transform parent plugins into child plugins. */\nexport type PluginTransform = (parentPlugins: ActorPlugin[]) => ActorPlugin[];\n\nexport type ActorContext<\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> = Methods &\n ActorDecorated & {\n state: InternalState;\n name: string;\n id: symbol;\n\n emit: (msg: OutMsg) => void;\n agreeToStop: () => void;\n\n reflection: ThisType<\n ActorContext<Args, InternalState, InMsg, OutMsg, Methods, Handlers, ReflectionMethods>\n > &\n ReflectionMethods;\n exit: (reason?: unknown) => void;\n\n $child: Record<string, AnyProcess>;\n\n fork<A, S, IM extends Message, OM extends InMsg, R extends ReflectionOptions>(\n actor: ActorDefinition<A, S, IM, OM, R>,\n args?: A,\n opts?: {\n name?: string;\n addPlugins?: ActorPlugin[];\n },\n ): Promise<AsyncProcess<A, HidePrivate<S>, IM, OM, R & ActorReflection>>;\n\n ctx: ProcessCtx<Args, HidePrivate<InternalState>, InMsg, OutMsg>;\n };\n\n\n\n/**\n * The context a config's hooks are typed against, for a `Partial<>` overlay:\n * a mapped type drops the marker `ActorConfig` carries.\n */\nexport type ActorContextOf<C> = C extends ActorConfig<\n infer Args,\n infer InternalState,\n infer InMsg extends Message,\n infer OutMsg extends Message,\n infer Methods extends MethodOptions,\n infer Handlers,\n infer ReflectionMethods extends ReflectionOptions\n>\n ? ActorContext<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers extends HandlerOptions<InMsg> ? Handlers : HandlerOptions<InMsg>,\n ReflectionMethods & ActorReflection\n >\n : never;\n","// ── Lifecycle Hooks ──────────────────────────────────────────────────────\n//\n// Extends ProcessCtx and defineActor with observable lifecycle hooks.\n// Hooks are additive — multiple callbacks can register for the same hook\n// point, and they fire in registration order.\n\nimport {\n STOP_SENTINEL,\n stopPropagation,\n PROPAGATE_SENTINEL,\n propagateError,\n} from \"./actor-types.js\";\nimport type {\n HookResult,\n ActorPlugin,\n PluginTransform,\n AnyConfig,\n ActorContextOf,\n} from \"./actor-types.js\";\n\n// ── stop propagation sentinel ────────────────────────────────────────────\n\n// Re-exports from actor-types.ts (backward compatibility)\nexport { STOP_SENTINEL, stopPropagation, PROPAGATE_SENTINEL, propagateError };\nexport type { HookResult, ActorPlugin, PluginTransform };\n\n// ── type augmentation (Fastify-style) ────────────────────────────────────\n\n/**\n * Interface that plugins can augment via declaration merging.\n * Plugins ship a .d.ts that adds properties to this interface,\n * making them available on `this` in handlers and methods.\n *\n * Example (in a plugin's .d.ts):\n * declare module 'posipaki' {\n * interface ActorDecorated {\n * log: Logger;\n * }\n * }\n */\nexport interface ActorDecorated {}\nexport interface ActorReflection {}\n\n// ── chainHook ────────────────────────────────────────────────────────────\n\n/**\n * Compose two lifecycle hooks so that `plugin` fires first.\n *\n * If `plugin` returns the STOP_SENTINEL (via stopPropagation()),\n * `existing` is skipped entirely and the sentinel propagates.\n * Otherwise `existing` fires and its return value is used.\n *\n * Typical use in a plugin:\n * (cfg) => ({ ...cfg, onStart: chainHook(cfg.onStart, myOnStart) })\n *\n * @param existing - the current hook on the config (may be undefined)\n * @param plugin - the new hook to prepend\n * @returns a composed hook suitable for ActorConfig\n */\nexport function chainHook<TThis, TArgs extends unknown[]>(\n existing: ((this: TThis, ...args: TArgs) => HookResult | Promise<HookResult>) | undefined,\n plugin: (this: TThis, ...args: TArgs) => HookResult | Promise<HookResult>,\n): (this: TThis, ...args: TArgs) => HookResult | Promise<HookResult> {\n if (!existing) return plugin;\n return async function (this: TThis, ...args: TArgs): Promise<HookResult> {\n const result = await plugin.call(this, ...args);\n if (result === STOP_SENTINEL) return result;\n return await existing.call(this, ...args);\n } as (this: TThis, ...args: TArgs) => HookResult | Promise<HookResult>;\n}\n\n// ── mergeConfigs ─────────────────────────────────────────────────────────\n\n/**\n * Merge an overlay config into a base config, auto-chaining every on* hook.\n *\n * Each key in `overlay` that starts with \"on\" followed by an uppercase\n * letter (onStart, onMessage, onEmit, etc.) is composed via chainHook()\n * so that the overlay hook fires before the base hook, and stopPropagation\n * is respected.\n *\n * Typical use in a plugin:\n * return mergeConfigs(cfg, {\n * onStart() { this.log.info('starting'); },\n * beforeEnd() { this.log.info('stopping'); },\n * });\n *\n * @param base - the existing config (ActorConfig)\n * @param overlay - new hook implementations to prepend\n * @returns a new config with hooks chained\n */\nexport function mergeConfigs<C extends AnyConfig>(\n base: C,\n overlay: Partial<C> & ThisType<ActorContextOf<C>>,\n): C {\n const result = { ...base } as Record<string, unknown>;\n for (const key of Object.keys(overlay as Record<string, unknown>)) {\n const val = (overlay as Record<string, unknown>)[key];\n if (typeof val === \"function\" && /^(on|after|before)[A-Z]/.test(key)) {\n result[key] = chainHook(\n (base as Record<string, unknown>)[key] as (\n this: unknown,\n ...args: unknown[]\n ) => HookResult | Promise<HookResult>,\n val as (this: unknown, ...args: unknown[]) => HookResult | Promise<HookResult>,\n );\n } else {\n result[key] = val;\n }\n }\n result.$reflectionMethods = {};\n Object.assign(\n result.$reflectionMethods as object,\n \"$reflectionMethods\" in base ? base.$reflectionMethods : {},\n \"$reflectionMethods\" in overlay ? overlay.$reflectionMethods : {},\n );\n\n return result as unknown as C;\n}\n\nexport type Hook<T, I extends unknown[], O> = (this: T, ...args: I) => O;\n\nexport async function callHook<T, I extends unknown[], O>(\n fn: Hook<T, I, O> | undefined,\n eh: ((e: unknown) => unknown) | undefined,\n thisArg: T,\n ...args: I\n): Promise<O | undefined> {\n if (fn) {\n try {\n return await fn.call(thisArg, ...args);\n } catch (e) {\n if (eh) {\n let decision: unknown;\n try {\n decision = await eh(e);\n } catch {\n // An error inside the error handler must not mask the original one.\n }\n // An observing handler says so by returning the sentinel: the error it\n // did not handle keeps propagating, so the actor still goes down.\n if (decision === PROPAGATE_SENTINEL) throw e;\n } else {\n throw e;\n }\n }\n }\n return undefined;\n}\n"],"mappings":";;AA2OA,MAAa,gBAAgB,OAAO,0BAA0B;;AAG9D,MAAa,wBAA8C;;;;;;;;AAS3D,MAAa,qBAAqB,OAAO,yBAAyB;;AAGlE,MAAa,uBAAkD;;;;;;;;;;;;;;;;;AC/L/D,SAAgB,UACd,UACA,QACmE;CACnE,IAAI,CAAC,UAAU,OAAO;CACtB,OAAO,eAA6B,GAAG,MAAkC;EACvE,MAAM,SAAS,MAAM,OAAO,KAAK,MAAM,GAAG,IAAI;EAC9C,IAAI,WAAW,eAAe,OAAO;EACrC,OAAO,MAAM,SAAS,KAAK,MAAM,GAAG,IAAI;CAC1C;AACF;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,aACd,MACA,SACG;CACH,MAAM,SAAS,EAAE,GAAG,KAAK;CACzB,KAAK,MAAM,OAAO,OAAO,KAAK,OAAkC,GAAG;EACjE,MAAM,MAAO,QAAoC;EACjD,IAAI,OAAO,QAAQ,cAAc,0BAA0B,KAAK,GAAG,GACjE,OAAO,OAAO,UACX,KAAiC,MAIlC,GACF;OAEA,OAAO,OAAO;CAElB;CACA,OAAO,qBAAqB,CAAC;CAC7B,OAAO,OACL,OAAO,oBACP,wBAAwB,OAAO,KAAK,qBAAqB,CAAC,GAC1D,wBAAwB,UAAU,QAAQ,qBAAqB,CAAC,CAClE;CAEA,OAAO;AACT;AAIA,eAAsB,SACpB,IACA,IACA,SACA,GAAG,MACqB;CACxB,IAAI,IACF,IAAI;EACF,OAAO,MAAM,GAAG,KAAK,SAAS,GAAG,IAAI;CACvC,SAAS,GAAG;EACV,IAAI,IAAI;GACN,IAAI;GACJ,IAAI;IACF,WAAW,MAAM,GAAG,CAAC;GACvB,QAAQ,CAER;GAGA,IAAI,aAAa,oBAAoB,MAAM;EAC7C,OACE,MAAM;CAEV;AAGJ"}
|
|
1
|
+
{"version":3,"file":"hooks-CgXhmY4r.js","names":[],"sources":["../src/actor-types.ts","../src/hooks.ts"],"sourcesContent":["// ── defineActor types ────────────────────────────────────────────────────────\n//\n// Shared between define-actor.ts (implementation) and consumers that want\n// to reference the config/context/definition shapes without importing the\n// implementation module directly.\n\nimport type { SenderInfo, AsyncProcessFn, Message, ProcessCtx, ExitMessage } from \"./types.js\";\nimport type { ActorDecorated, ActorReflection } from \"./hooks.js\";\nimport type { AnyProcess, AsyncProcess } from \"./process.async.js\";\n\n// Internal marker do not use\nexport type ActorMessages<M extends Message> = {\n __tag_messages: M;\n};\nexport interface MethodOptions {\n [key: string]: Function;\n}\nexport type HandlerFn<InMsg extends Message> = (\n msg: InMsg,\n sender: SenderInfo,\n) => void | Promise<void>;\nexport type HandlerOptions<InMsg extends Message> = Omit<\n {\n [K in InMsg[\"type\"]]: HandlerFn<Extract<InMsg, { type: K }>>;\n },\n \"STOP\"\n>;\n/**\n * A reflection method, async by contract: it answers with a promise, even when\n * it has the answer already. The same call has to read the same way whether the\n * actor is here or behind a wire, and a caller that had to know which of the two\n * it was holding would be reading the shape of the deployment, not the answer.\n *\n * The parameters are `never` because nothing is called through this type — it is\n * the contract every declared method is checked against.\n */\nexport type ReflectionMethod = (...args: never[]) => Promise<unknown>;\n/** The reflection surface a process exposes: named methods, each of them async\n * by {@link ReflectionMethod}'s contract. */\nexport interface ReflectionOptions {\n [name: string]: ReflectionMethod;\n}\nexport type Paired<Priv, Pub> = { public: Pub; private: Priv };\nexport type HidePrivate<T> = T extends Paired<unknown, unknown> ? T[\"public\"] : T;\n\nexport type SpawnedFrom<T extends ActorDefinition<any, any, any, any, any>> =\n T extends ActorDefinition<infer A, infer S, infer IM, infer OM, infer R>\n ? AsyncProcess<A, HidePrivate<S>, IM, OM, R & ActorReflection>\n : never;\n\nexport interface ActorDefinition<\n Args,\n InternalState,\n InMsg extends Message,\n OutMsg extends Message,\n ReflectionMethods extends ReflectionOptions,\n> {\n fn: AsyncProcessFn<Args, HidePrivate<InternalState>, InMsg, OutMsg>;\n /** Preferred process name (from config.name). */\n name?: string;\n /** Raw plugin config (array or transform). Resolved at fork time. @internal */\n pvtPluginsRaw?: ActorPlugin[] | PluginTransform;\n /** Spawn this actor as a standalone process. */\n 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 /** Wait for the initial state before resolving. Default `true`. */\n awaitReady?: boolean;\n },\n ): Promise<\n AsyncProcess<\n Args,\n HidePrivate<InternalState>,\n InMsg,\n OutMsg,\n ReflectionMethods & ActorReflection\n >\n >;\n /** Spawn this actor as a child of the calling process.\n * `ctx` must be able to fork children that emit `OutMsg` — i.e. the\n * parent's in-message is a supertype of this actor's out-message. */\n spawnAsChild<PMO extends Message>(\n ctx: ProcessCtx<unknown, unknown, OutMsg, PMO>,\n args: Args,\n opts?: {\n name?: string;\n parentPlugins?: ActorPlugin[];\n addPlugins?: ActorPlugin[];\n },\n ): Promise<\n AsyncProcess<\n Args,\n HidePrivate<InternalState>,\n InMsg,\n OutMsg,\n ReflectionMethods & ActorReflection\n >\n >;\n inMessages: ActorMessages<InMsg> | undefined;\n outMessages: ActorMessages<OutMsg> | undefined;\n}\n/**\n * The config object as a user writes it.\n *\n * Hooks take their `this` from the `ThisType` at the end of this type: a per-hook\n * annotation erases the inferred methods surface. `beforeStart` and `setup` keep\n * one, for the state.\n */\nexport type ActorConfig<\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 /** Preferred process name. Used by ctx.fork() when no explicit name is given. */\n name?: string;\n plugins?: ActorPlugin[] | PluginTransform;\n /** Non-overridable plugins added at spawn time (spawn/fork opts).\n * Set by the framework during assembly, not by user config. @internal */\n addPlugins?: ActorPlugin[];\n /** Resolved plugin chain (raw config transformed against parent plugins).\n * Set by the framework during assembly, replacing `plugins` (the raw form).\n * @internal */\n resolvedPlugins?: ActorPlugin[];\n outMessages?: ActorMessages<OutMsg>;\n inMessages?: ActorMessages<InMsg>;\n /** Fires once `self` is built, before `setup`. State is not yet set\n * (`this.state` is `never`). Use for registering the process/ctx before\n * any child is forked in `setup`. */\n beforeStart?: (\n this: ActorContext<\n Args,\n never,\n InMsg,\n OutMsg,\n MethodOptions,\n Handlers,\n ReflectionMethods & ActorReflection\n >,\n ) => void | Promise<void>;\n\n /** `this.state` is `never`: the returned value is the state. */\n setup?: (\n this: ActorContext<\n Args,\n never,\n InMsg,\n OutMsg,\n MethodOptions,\n Handlers,\n ReflectionMethods & ActorReflection\n >,\n args: Args,\n ) => Promise<InternalState> | InternalState;\n\n afterStart?: () => void | Promise<void>;\n\n onStopRequested?: () => HookResult | Promise<HookResult>;\n\n beforeEnd?: (reason?: unknown) => HookResult | Promise<HookResult>;\n\n /**\n * Runs once the actor has ended — after its EXIT. It is *not* called when the\n * actor never started (`setup()` or a pre-start hook threw): the state is\n * typed as present here, and an actor that never got one has nothing to end.\n */\n afterEnd?: (reason?: unknown) => HookResult | Promise<HookResult>;\n\n onError?: (error?: unknown) => HookResult | ErrorResult | Promise<HookResult | ErrorResult>;\n\n onEmit?: (msg: OutMsg, sender: SenderInfo) => HookResult | Promise<HookResult>;\n\n onMessage?: (msg: InMsg, sender: SenderInfo) => HookResult | Promise<HookResult>;\n\n onUnhandled?: (msg: Message, sender: SenderInfo) => void | Promise<void>;\n\n onChildExit?: (name: string, reason: ExitMessage) => HookResult | Promise<HookResult>;\n\n /** Fires for each orphan a child leaves behind (in its EXIT). Return the\n * policy: `'adopt'` (promote to a child, draining its buffer), `'force-stop'`\n * (hard-kill), `'unparent'` (drop its buffer, keep it running in `orphans`),\n * or `'leave'` (keep buffering, propagate up on my exit). When no `onOrphan`\n * is defined, the default is `'force-stop'`. */\n onOrphan?: (orphan: AnyProcess) => OrphanDecision | void | Promise<OrphanDecision | void>;\n\n handlers: Handlers &\n ThisType<\n ActorContext<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods & ActorReflection\n >\n >;\n\n methods?: Methods &\n ThisType<\n ActorContext<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods & ActorReflection\n >\n >;\n $reflectionMethods?: ReflectionMethods &\n ThisType<\n ActorContext<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ActorReflection & ActorReflection\n >\n >;\n // for plugin use only\n $decorate?: Partial<ActorDecorated>;\n} & ThisType<\n ActorContext<Args, InternalState, InMsg, OutMsg, Methods, Handlers, ReflectionMethods & ActorReflection>\n>;\nexport type AnyConfig = ActorConfig<\n unknown,\n unknown,\n Message,\n Message,\n MethodOptions,\n HandlerOptions<Message>,\n ReflectionOptions\n>;\n\n// ── stop propagation sentinel ────────────────────────────────────────────\n\n/** Returned by onMessage hooks to prevent further dispatch. */\nexport const STOP_SENTINEL = Symbol(\"posipaki.stopPropagation\");\n\n/** Type-safe sentinel for short-circuiting onMessage hooks. */\nexport const stopPropagation = (): typeof STOP_SENTINEL => STOP_SENTINEL;\n\n/**\n * Returned by an `onError` handler that only *observed* the error — logged it,\n * counted it — and did not handle it. The framework then lets the error\n * propagate: the actor still goes down and its parent still gets the EXIT.\n * Without this an observing handler (the bundled debug logger is one) silently\n * turns a broken lifecycle hook into a survivor with nothing left to do.\n */\nexport const PROPAGATE_SENTINEL = Symbol(\"posipaki.propagateError\");\n\n/** Type-safe sentinel for an onError handler that did not handle the error. */\nexport const propagateError = (): typeof PROPAGATE_SENTINEL => PROPAGATE_SENTINEL;\n\n/** Return type of onError handlers: void (handled) or sentinel (not handled). */\nexport type ErrorResult = void | typeof PROPAGATE_SENTINEL;\n\n// ── hook function types ──────────────────────────────────────────────────\n\n/** Return type of onMessage hooks: void (continue) or sentinel (stop). */\nexport type HookResult = void | typeof STOP_SENTINEL;\n\n/** Decision returned by `onOrphan` for how to handle an inherited orphan. */\nexport type OrphanDecision = \"adopt\" | \"force-stop\" | \"unparent\" | \"leave\";\n// ── plugin types ─────────────────────────────────────────────────────────\n\n/** A reusable unit of actor behaviour. */\nexport type ActorPlugin<C = AnyConfig> = (config: C) => C | Promise<C>;\n\n/** Transform parent plugins into child plugins. */\nexport type PluginTransform = (parentPlugins: ActorPlugin[]) => ActorPlugin[];\n\nexport type ActorContext<\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> = Methods &\n ActorDecorated & {\n state: InternalState;\n name: string;\n id: symbol;\n\n emit: (msg: OutMsg) => void;\n agreeToStop: () => void;\n\n reflection: ThisType<\n ActorContext<Args, InternalState, InMsg, OutMsg, Methods, Handlers, ReflectionMethods>\n > &\n ReflectionMethods;\n exit: (reason?: unknown) => void;\n\n $child: Record<string, AnyProcess>;\n\n fork<A, S, IM extends Message, OM extends InMsg, R extends ReflectionOptions>(\n actor: ActorDefinition<A, S, IM, OM, R>,\n args?: A,\n opts?: {\n name?: string;\n addPlugins?: ActorPlugin[];\n },\n ): Promise<AsyncProcess<A, HidePrivate<S>, IM, OM, R & ActorReflection>>;\n\n ctx: ProcessCtx<Args, HidePrivate<InternalState>, InMsg, OutMsg>;\n };\n\n\n\n/**\n * The context a config's hooks are typed against, for a `Partial<>` overlay:\n * a mapped type drops the marker `ActorConfig` carries.\n */\nexport type ActorContextOf<C> = C extends ActorConfig<\n infer Args,\n infer InternalState,\n infer InMsg extends Message,\n infer OutMsg extends Message,\n infer Methods extends MethodOptions,\n infer Handlers,\n infer ReflectionMethods extends ReflectionOptions\n>\n ? ActorContext<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers extends HandlerOptions<InMsg> ? Handlers : HandlerOptions<InMsg>,\n ReflectionMethods & ActorReflection\n >\n : never;\n","// ── Lifecycle Hooks ──────────────────────────────────────────────────────\n//\n// Extends ProcessCtx and defineActor with observable lifecycle hooks.\n// Hooks are additive — multiple callbacks can register for the same hook\n// point, and they fire in registration order.\n\nimport {\n STOP_SENTINEL,\n stopPropagation,\n PROPAGATE_SENTINEL,\n propagateError,\n} from \"./actor-types.js\";\nimport type {\n HookResult,\n ActorPlugin,\n PluginTransform,\n AnyConfig,\n ActorContextOf,\n ReflectionOptions,\n} from \"./actor-types.js\";\n\n// ── stop propagation sentinel ────────────────────────────────────────────\n\n// Re-exports from actor-types.ts (backward compatibility)\nexport { STOP_SENTINEL, stopPropagation, PROPAGATE_SENTINEL, propagateError };\nexport type { HookResult, ActorPlugin, PluginTransform };\n\n// ── type augmentation (Fastify-style) ────────────────────────────────────\n\n/**\n * Interface that plugins can augment via declaration merging.\n * Plugins ship a .d.ts that adds properties to this interface,\n * making them available on `this` in handlers and methods.\n *\n * Example (in a plugin's .d.ts):\n * declare module 'posipaki' {\n * interface ActorDecorated {\n * log: Logger;\n * }\n * }\n */\nexport interface ActorDecorated {}\n/** Reflection methods plugins and the framework add to every actor. Merged by\n * declaration, and held to {@link ReflectionOptions}' contract: async. */\nexport interface ActorReflection extends ReflectionOptions {}\n\n// ── chainHook ────────────────────────────────────────────────────────────\n\n/**\n * Compose two lifecycle hooks so that `plugin` fires first.\n *\n * If `plugin` returns the STOP_SENTINEL (via stopPropagation()),\n * `existing` is skipped entirely and the sentinel propagates.\n * Otherwise `existing` fires and its return value is used.\n *\n * Typical use in a plugin:\n * (cfg) => ({ ...cfg, onStart: chainHook(cfg.onStart, myOnStart) })\n *\n * @param existing - the current hook on the config (may be undefined)\n * @param plugin - the new hook to prepend\n * @returns a composed hook suitable for ActorConfig\n */\nexport function chainHook<TThis, TArgs extends unknown[]>(\n existing: ((this: TThis, ...args: TArgs) => HookResult | Promise<HookResult>) | undefined,\n plugin: (this: TThis, ...args: TArgs) => HookResult | Promise<HookResult>,\n): (this: TThis, ...args: TArgs) => HookResult | Promise<HookResult> {\n if (!existing) return plugin;\n return async function (this: TThis, ...args: TArgs): Promise<HookResult> {\n const result = await plugin.call(this, ...args);\n if (result === STOP_SENTINEL) return result;\n return await existing.call(this, ...args);\n } as (this: TThis, ...args: TArgs) => HookResult | Promise<HookResult>;\n}\n\n// ── mergeConfigs ─────────────────────────────────────────────────────────\n\n/**\n * Merge an overlay config into a base config, auto-chaining every on* hook.\n *\n * Each key in `overlay` that starts with \"on\" followed by an uppercase\n * letter (onStart, onMessage, onEmit, etc.) is composed via chainHook()\n * so that the overlay hook fires before the base hook, and stopPropagation\n * is respected.\n *\n * Typical use in a plugin:\n * return mergeConfigs(cfg, {\n * onStart() { this.log.info('starting'); },\n * beforeEnd() { this.log.info('stopping'); },\n * });\n *\n * @param base - the existing config (ActorConfig)\n * @param overlay - new hook implementations to prepend\n * @returns a new config with hooks chained\n */\nexport function mergeConfigs<C extends AnyConfig>(\n base: C,\n overlay: Partial<C> & ThisType<ActorContextOf<C>>,\n): C {\n const result = { ...base } as Record<string, unknown>;\n for (const key of Object.keys(overlay as Record<string, unknown>)) {\n const val = (overlay as Record<string, unknown>)[key];\n if (typeof val === \"function\" && /^(on|after|before)[A-Z]/.test(key)) {\n result[key] = chainHook(\n (base as Record<string, unknown>)[key] as (\n this: unknown,\n ...args: unknown[]\n ) => HookResult | Promise<HookResult>,\n val as (this: unknown, ...args: unknown[]) => HookResult | Promise<HookResult>,\n );\n } else {\n result[key] = val;\n }\n }\n result.$reflectionMethods = {};\n Object.assign(\n result.$reflectionMethods as object,\n \"$reflectionMethods\" in base ? base.$reflectionMethods : {},\n \"$reflectionMethods\" in overlay ? overlay.$reflectionMethods : {},\n );\n\n return result as unknown as C;\n}\n\nexport type Hook<T, I extends unknown[], O> = (this: T, ...args: I) => O;\n\nexport async function callHook<T, I extends unknown[], O>(\n fn: Hook<T, I, O> | undefined,\n eh: ((e: unknown) => unknown) | undefined,\n thisArg: T,\n ...args: I\n): Promise<O | undefined> {\n if (fn) {\n try {\n return await fn.call(thisArg, ...args);\n } catch (e) {\n if (eh) {\n let decision: unknown;\n try {\n decision = await eh(e);\n } catch {\n // An error inside the error handler must not mask the original one.\n }\n // An observing handler says so by returning the sentinel: the error it\n // did not handle keeps propagating, so the actor still goes down.\n if (decision === PROPAGATE_SENTINEL) throw e;\n } else {\n throw e;\n }\n }\n }\n return undefined;\n}\n"],"mappings":";;AAwPA,MAAa,gBAAgB,OAAO,0BAA0B;;AAG9D,MAAa,wBAA8C;;;;;;;;AAS3D,MAAa,qBAAqB,OAAO,yBAAyB;;AAGlE,MAAa,uBAAkD;;;;;;;;;;;;;;;;;ACzM/D,SAAgB,UACd,UACA,QACmE;CACnE,IAAI,CAAC,UAAU,OAAO;CACtB,OAAO,eAA6B,GAAG,MAAkC;EACvE,MAAM,SAAS,MAAM,OAAO,KAAK,MAAM,GAAG,IAAI;EAC9C,IAAI,WAAW,eAAe,OAAO;EACrC,OAAO,MAAM,SAAS,KAAK,MAAM,GAAG,IAAI;CAC1C;AACF;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,aACd,MACA,SACG;CACH,MAAM,SAAS,EAAE,GAAG,KAAK;CACzB,KAAK,MAAM,OAAO,OAAO,KAAK,OAAkC,GAAG;EACjE,MAAM,MAAO,QAAoC;EACjD,IAAI,OAAO,QAAQ,cAAc,0BAA0B,KAAK,GAAG,GACjE,OAAO,OAAO,UACX,KAAiC,MAIlC,GACF;OAEA,OAAO,OAAO;CAElB;CACA,OAAO,qBAAqB,CAAC;CAC7B,OAAO,OACL,OAAO,oBACP,wBAAwB,OAAO,KAAK,qBAAqB,CAAC,GAC1D,wBAAwB,UAAU,QAAQ,qBAAqB,CAAC,CAClE;CAEA,OAAO;AACT;AAIA,eAAsB,SACpB,IACA,IACA,SACA,GAAG,MACqB;CACxB,IAAI,IACF,IAAI;EACF,OAAO,MAAM,GAAG,KAAK,SAAS,GAAG,IAAI;CACvC,SAAS,GAAG;EACV,IAAI,IAAI;GACN,IAAI;GACJ,IAAI;IACF,WAAW,MAAM,GAAG,CAAC;GACvB,QAAQ,CAER;GAGA,IAAI,aAAa,oBAAoB,MAAM;EAC7C,OACE,MAAM;CAEV;AAGJ"}
|
|
@@ -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-
|
|
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-DDc-stle.js";
|
|
2
2
|
//#region src/actor-types.d.ts
|
|
3
3
|
type ActorMessages<M extends Message> = {
|
|
4
4
|
__tag_messages: M;
|
|
@@ -10,7 +10,21 @@ type HandlerFn<InMsg extends Message> = (msg: InMsg, sender: SenderInfo) => void
|
|
|
10
10
|
type HandlerOptions<InMsg extends Message> = Omit<{ [K in InMsg["type"]]: HandlerFn<Extract<InMsg, {
|
|
11
11
|
type: K;
|
|
12
12
|
}>>; }, "STOP">;
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* A reflection method, async by contract: it answers with a promise, even when
|
|
15
|
+
* it has the answer already. The same call has to read the same way whether the
|
|
16
|
+
* actor is here or behind a wire, and a caller that had to know which of the two
|
|
17
|
+
* it was holding would be reading the shape of the deployment, not the answer.
|
|
18
|
+
*
|
|
19
|
+
* The parameters are `never` because nothing is called through this type — it is
|
|
20
|
+
* the contract every declared method is checked against.
|
|
21
|
+
*/
|
|
22
|
+
type ReflectionMethod = (...args: never[]) => Promise<unknown>;
|
|
23
|
+
/** The reflection surface a process exposes: named methods, each of them async
|
|
24
|
+
* by {@link ReflectionMethod}'s contract. */
|
|
25
|
+
interface ReflectionOptions {
|
|
26
|
+
[name: string]: ReflectionMethod;
|
|
27
|
+
}
|
|
14
28
|
type Paired<Priv, Pub> = {
|
|
15
29
|
public: Pub;
|
|
16
30
|
private: Priv;
|
|
@@ -155,7 +169,9 @@ type ActorContextOf<C> = C extends ActorConfig<infer Args, infer InternalState,
|
|
|
155
169
|
* }
|
|
156
170
|
*/
|
|
157
171
|
interface ActorDecorated {}
|
|
158
|
-
|
|
172
|
+
/** Reflection methods plugins and the framework add to every actor. Merged by
|
|
173
|
+
* declaration, and held to {@link ReflectionOptions}' contract: async. */
|
|
174
|
+
interface ActorReflection extends ReflectionOptions {}
|
|
159
175
|
/**
|
|
160
176
|
* Compose two lifecycle hooks so that `plugin` fires first.
|
|
161
177
|
*
|
|
@@ -194,4 +210,4 @@ type Hook<T, I extends unknown[], O> = (this: T, ...args: I) => O;
|
|
|
194
210
|
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>;
|
|
195
211
|
//#endregion
|
|
196
212
|
export { stopPropagation as S, PluginTransform as _, chainHook as a, SpawnedFrom as b, ActorContext as c, ActorPlugin as d, HandlerFn as f, PROPAGATE_SENTINEL 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, ReflectionOptions as v, propagateError as x, STOP_SENTINEL as y };
|
|
197
|
-
//# sourceMappingURL=hooks-
|
|
213
|
+
//# sourceMappingURL=hooks-gmAsdJBN.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks-gmAsdJBN.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 { S as stopPropagation, _ as PluginTransform, a as chainHook, d as ActorPlugin, g as PROPAGATE_SENTINEL, i as callHook, m as HookResult, n as ActorReflection, o as mergeConfigs, r as Hook, t as ActorDecorated, x as propagateError, y as STOP_SENTINEL } from "./hooks-
|
|
1
|
+
import { S as stopPropagation, _ as PluginTransform, a as chainHook, d as ActorPlugin, g as PROPAGATE_SENTINEL, i as callHook, m as HookResult, n as ActorReflection, o as mergeConfigs, r as Hook, t as ActorDecorated, x as propagateError, y as STOP_SENTINEL } from "./hooks-gmAsdJBN.js";
|
|
2
2
|
export { ActorDecorated, type ActorPlugin, ActorReflection, Hook, type HookResult, PROPAGATE_SENTINEL, type PluginTransform, STOP_SENTINEL, callHook, chainHook, mergeConfigs, propagateError, 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-
|
|
2
|
-
import { S as stopPropagation, _ as PluginTransform, a as chainHook, b as SpawnedFrom, c as ActorContext, d as ActorPlugin, f as HandlerFn, 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, v as ReflectionOptions, x as propagateError } from "./hooks-
|
|
3
|
-
import { n as spawn, t as Process } from "./process-
|
|
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-DDc-stle.js";
|
|
2
|
+
import { S as stopPropagation, _ as PluginTransform, a as chainHook, b as SpawnedFrom, c as ActorContext, d as ActorPlugin, f as HandlerFn, 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, v as ReflectionOptions, x as propagateError } from "./hooks-gmAsdJBN.js";
|
|
3
|
+
import { n as spawn, t as Process } from "./process-DjRQSZef.js";
|
|
4
4
|
//#region src/util.d.ts
|
|
5
5
|
type ReducerClosure<M> = (msg: M) => void;
|
|
6
6
|
type ReadyFn = () => boolean;
|
|
@@ -20,7 +20,7 @@ declare function defineActor<Args, InternalState, InMsg extends Message, OutMsg
|
|
|
20
20
|
//#endregion
|
|
21
21
|
//#region src/version.d.ts
|
|
22
22
|
/** posipaki's release version. Must equal package.json's `version`. */
|
|
23
|
-
declare const LIB_VERSION = "0.
|
|
23
|
+
declare const LIB_VERSION = "0.37.1";
|
|
24
24
|
//#endregion
|
|
25
25
|
export { type ActorConfig, type ActorContext, type ActorDecorated, type ActorDefinition, type ActorPlugin, type ActorReflection, type AnyProcess, AsyncProcess, type AsyncProcessFn, type ExitMessage, type HandlerFn, type HandlerOptions, type HookResult, LIB_VERSION, type Message, type MethodOptions, type PluginTransform, Process, type ProcessCtx, type ProcessFn, type SenderInfo, type SenderOrigin, type SpawnedFrom, type StopMessage, type WithSender, type WithoutSender, asyncify, callHook, chainHook, defineActor, defineMessages, mergeConfigs, propagateError, runDispatch, runDispatchAsync, spawn, spawnAsync, stopPropagation };
|
|
26
26
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { i as runDispatch } from "./util-Brtfgv68.js";
|
|
2
|
-
import { a as
|
|
2
|
+
import { a as runDispatchAsync, n as defineMessages, o as spawnAsync, r as AsyncProcess, s as asyncify, t as defineActor } from "./define-actor-CZysIKH4.js";
|
|
3
3
|
import { n as chainHook, o as propagateError, r as mergeConfigs, s as stopPropagation, t as callHook } from "./hooks-CgXhmY4r.js";
|
|
4
|
-
import { t as LIB_VERSION } from "./version-
|
|
4
|
+
import { t as LIB_VERSION } from "./version-98a9sol-.js";
|
|
5
5
|
//#region src/process.ts
|
|
6
6
|
/** @deprecated Use {@link spawnAsync} instead. */
|
|
7
7
|
function spawn(fn, pname, tp) {
|