posipaki 0.21.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { a as ProcessCtx, d as WithSender, m as AsyncProcess, n as ExitMessage, p as AnyProcess, r as Message, s as SenderInfo, t as AsyncProcessFn } from "./types-DYAxWeSM.js";
1
+ import { a as ProcessCtx, m as AsyncProcess, n as ExitMessage, p as AnyProcess, r as Message, s as SenderInfo, t as AsyncProcessFn } from "./types-BzM4YqJj.js";
2
2
 
3
3
  //#region src/actor-types.d.ts
4
4
  type ActorMessages<M extends Message> = {
@@ -27,7 +27,7 @@ interface ActorDefinition<Args, InternalState, InMsg extends Message, OutMsg ext
27
27
  /** Spawn this actor as a standalone process. */
28
28
  spawn(args: Args, opts?: {
29
29
  name?: string;
30
- toParent?: (msg: WithSender<OutMsg>) => void;
30
+ toParent?: (msg: OutMsg, from: SenderInfo) => void;
31
31
  addPlugins?: ActorPlugin[];
32
32
  }): Promise<AsyncProcess<Args, HidePrivate<InternalState>, InMsg, OutMsg, ReflectionMethods & ActorReflection>>;
33
33
  /** Spawn this actor as a child of the calling process.
@@ -152,4 +152,4 @@ type Hook<T, I extends unknown[], O> = (this: T, ...args: I) => O;
152
152
  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>;
153
153
  //#endregion
154
154
  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 };
155
- //# sourceMappingURL=hooks-fgRvVnDj.d.ts.map
155
+ //# sourceMappingURL=hooks-D6qtxITh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks-D6qtxITh.d.ts","names":[],"sources":["../src/actor-types.ts","../src/hooks.ts"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"hooks-V-PEPJHv.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 {\n SenderInfo,\n WithSender,\n AsyncProcessFn,\n Message,\n ProcessCtx,\n ExitMessage,\n} 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> =\n 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: WithSender<OutMsg>) => void;\n addPlugins?: ActorPlugin[];\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}\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> = ThisType<\n ActorContext<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods & ActorReflection\n >\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\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 Methods,\n Handlers,\n ReflectionMethods & ActorReflection\n >,\n ) => void | Promise<void>;\n setup?: (\n this: ActorContext<\n Args,\n never,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods & ActorReflection\n >,\n args: Args,\n ) => Promise<InternalState> | InternalState;\n afterStart?: () => void | Promise<void>;\n onStopRequested?: () => HookResult | Promise<HookResult>;\n beforeEnd?: (reason?: unknown) => HookResult | Promise<HookResult>;\n afterEnd?: (reason?: unknown) => HookResult | Promise<HookResult>;\n onError?: (error?: unknown) => HookResult | Promise<HookResult>;\n onEmit?: (\n msg: OutMsg,\n sender: SenderInfo,\n ) => HookResult | Promise<HookResult>;\n\n onMessage?: (\n msg: InMsg,\n sender: SenderInfo,\n ) => HookResult | Promise<HookResult>;\n\n onUnhandled?: (msg: Message, sender: SenderInfo) => void | Promise<void>;\n\n onChildExit?: (\n name: string,\n reason: ExitMessage,\n ) => HookResult | Promise<HookResult>;\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};\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// ── hook function types ──────────────────────────────────────────────────\n\n/** Return type of onMessage hooks: void (continue) or sentinel (stop). */\nexport type HookResult = void | typeof STOP_SENTINEL;\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<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods\n >\n > &\n ReflectionMethods;\n exit: (reason?: unknown) => void;\n\n $child: Record<string, AnyProcess>;\n\n fork<\n A,\n S,\n IM extends Message,\n OM extends InMsg,\n R extends ReflectionOptions,\n >(\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","// ── 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 { STOP_SENTINEL, stopPropagation } from \"./actor-types.js\";\nimport type {\n HookResult,\n ActorPlugin,\n PluginTransform,\n AnyConfig,\n} from \"./actor-types.js\";\n\n// ── stop propagation sentinel ────────────────────────────────────────────\n\n// Re-exports from actor-types.ts (backward compatibility)\nexport { STOP_SENTINEL, stopPropagation };\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:\n | ((this: TThis, ...args: TArgs) => HookResult | Promise<HookResult>)\n | 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>(base: C, overlay: Partial<C>): 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 (\n this: unknown,\n ...args: unknown[]\n ) => 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 try {\n await eh(e);\n } catch {}\n } else {\n throw e;\n }\n }\n }\n return undefined;\n}\n"],"mappings":";;AAsOA,MAAa,gBAAgB,OAAO,0BAA0B;;AAG9D,MAAa,wBAA8C;;;;;;;;;;;;;;;;;ACpL3D,SAAgB,UACd,UAGA,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,aAAkC,MAAS,SAAwB;CACjF,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,GAIF;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,IACF,IAAI;GACF,MAAM,GAAG,CAAC;EACZ,QAAQ,CAAC;OAET,MAAM;CAEV;AAGJ"}
1
+ {"version":3,"file":"hooks-V-PEPJHv.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 {\n SenderInfo,\n AsyncProcessFn,\n Message,\n ProcessCtx,\n ExitMessage,\n} 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> =\n 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 },\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}\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> = ThisType<\n ActorContext<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods & ActorReflection\n >\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\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 Methods,\n Handlers,\n ReflectionMethods & ActorReflection\n >,\n ) => void | Promise<void>;\n setup?: (\n this: ActorContext<\n Args,\n never,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods & ActorReflection\n >,\n args: Args,\n ) => Promise<InternalState> | InternalState;\n afterStart?: () => void | Promise<void>;\n onStopRequested?: () => HookResult | Promise<HookResult>;\n beforeEnd?: (reason?: unknown) => HookResult | Promise<HookResult>;\n afterEnd?: (reason?: unknown) => HookResult | Promise<HookResult>;\n onError?: (error?: unknown) => HookResult | Promise<HookResult>;\n onEmit?: (\n msg: OutMsg,\n sender: SenderInfo,\n ) => HookResult | Promise<HookResult>;\n\n onMessage?: (\n msg: InMsg,\n sender: SenderInfo,\n ) => HookResult | Promise<HookResult>;\n\n onUnhandled?: (msg: Message, sender: SenderInfo) => void | Promise<void>;\n\n onChildExit?: (\n name: string,\n reason: ExitMessage,\n ) => HookResult | Promise<HookResult>;\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};\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// ── hook function types ──────────────────────────────────────────────────\n\n/** Return type of onMessage hooks: void (continue) or sentinel (stop). */\nexport type HookResult = void | typeof STOP_SENTINEL;\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<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods\n >\n > &\n ReflectionMethods;\n exit: (reason?: unknown) => void;\n\n $child: Record<string, AnyProcess>;\n\n fork<\n A,\n S,\n IM extends Message,\n OM extends InMsg,\n R extends ReflectionOptions,\n >(\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","// ── 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 { STOP_SENTINEL, stopPropagation } from \"./actor-types.js\";\nimport type {\n HookResult,\n ActorPlugin,\n PluginTransform,\n AnyConfig,\n} from \"./actor-types.js\";\n\n// ── stop propagation sentinel ────────────────────────────────────────────\n\n// Re-exports from actor-types.ts (backward compatibility)\nexport { STOP_SENTINEL, stopPropagation };\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:\n | ((this: TThis, ...args: TArgs) => HookResult | Promise<HookResult>)\n | 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>(base: C, overlay: Partial<C>): 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 (\n this: unknown,\n ...args: unknown[]\n ) => 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 try {\n await eh(e);\n } catch {}\n } else {\n throw e;\n }\n }\n }\n return undefined;\n}\n"],"mappings":";;AAqOA,MAAa,gBAAgB,OAAO,0BAA0B;;AAG9D,MAAa,wBAA8C;;;;;;;;;;;;;;;;;ACnL3D,SAAgB,UACd,UAGA,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,aAAkC,MAAS,SAAwB;CACjF,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,GAIF;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,IACF,IAAI;GACF,MAAM,GAAG,CAAC;EACZ,QAAQ,CAAC;OAET,MAAM;CAEV;AAGJ"}
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-fgRvVnDj.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-D6qtxITh.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 ProcessCtx, c as SenderOrigin, d as WithSender, f as WithoutSender, g as spawnAsync, h as runDispatchAsync, i as PipeState, l as StopMessage, m as AsyncProcess, n as ExitMessage, o as ProcessFn, p as AnyProcess, r as Message, s as SenderInfo, t as AsyncProcessFn, u as SupervisorState } from "./types-DYAxWeSM.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-fgRvVnDj.js";
3
- import { n as spawn, r as runDispatch, t as Process } from "./process-CECMMHyR.js";
1
+ import { a as ProcessCtx, c as SenderOrigin, d as WithSender, f as WithoutSender, g as spawnAsync, h as runDispatchAsync, i as PipeState, l as StopMessage, m as AsyncProcess, n as ExitMessage, o as ProcessFn, p as AnyProcess, r as Message, s as SenderInfo, t as AsyncProcessFn, u as SupervisorState } from "./types-BzM4YqJj.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-D6qtxITh.js";
3
+ import { n as spawn, r as runDispatch, t as Process } from "./process-YKyZJOvg.js";
4
4
 
5
5
  //#region src/adapters.d.ts
6
6
  declare function asyncify<A, S, IM extends Message, OM extends Message>(fn: ProcessFn<A, S, IM, OM>): AsyncProcessFn<A, S, IM, OM>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/adapters.ts","../src/define-actor.ts"],"mappings":";;;;;iBAEgB,QAAA,kBAA0B,OAAA,aAAoB,OAAA,EAC5D,EAAA,EAAI,SAAA,CAAU,CAAA,EAAG,CAAA,EAAG,EAAA,EAAI,EAAA,IACvB,cAAA,CAAe,CAAA,EAAG,CAAA,EAAG,EAAA,EAAI,EAAA;;;iBCkCZ,cAAA,gBACC,OAAA,GAAU,OAAA,KACtB,aAAA,CAAc,MAAA;AAAA,iBA4DH,WAAA,oCAGA,OAAA,iBACC,OAAA,kBACC,aAAA,mBACC,cAAA,CAAe,KAAA,6BACN,iBAAA,EAE1B,MAAA,EAAQ,WAAA,CACN,IAAA,EACA,aAAA,EACA,KAAA,EACA,MAAA,EACA,OAAA,EACA,QAAA,EACA,iBAAA,IAED,eAAA,CAAgB,IAAA,EAAM,aAAA,EAAe,KAAA,EAAO,MAAA,EAAQ,iBAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/adapters.ts","../src/define-actor.ts"],"mappings":";;;;;iBAEgB,QAAA,kBAA0B,OAAA,aAAoB,OAAA,EAC5D,EAAA,EAAI,SAAA,CAAU,CAAA,EAAG,CAAA,EAAG,EAAA,EAAI,EAAA,IACvB,cAAA,CAAe,CAAA,EAAG,CAAA,EAAG,EAAA,EAAI,EAAA;;;iBCmCZ,cAAA,gBACC,OAAA,GAAU,OAAA,KACtB,aAAA,CAAc,MAAA;AAAA,iBA4DH,WAAA,oCAGA,OAAA,iBACC,OAAA,kBACC,aAAA,mBACC,cAAA,CAAe,KAAA,6BACN,iBAAA,EAE1B,MAAA,EAAQ,WAAA,CACN,IAAA,EACA,aAAA,EACA,KAAA,EACA,MAAA,EACA,OAAA,EACA,QAAA,EACA,iBAAA,IAED,eAAA,CAAgB,IAAA,EAAM,aAAA,EAAe,KAAA,EAAO,MAAA,EAAQ,iBAAA"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  import { i as runDispatch } from "./util-FmOqPdg-.js";
2
- import { a as AsyncProcess, c as asyncify, i as spawn, n as defineMessages, o as runDispatchAsync, r as Process, s as spawnAsync, t as defineActor } from "./src-DeIF0clC.js";
2
+ import { a as AsyncProcess, c as asyncify, i as spawn, n as defineMessages, o as runDispatchAsync, r as Process, s as spawnAsync, t as defineActor } from "./src-fhiwGw91.js";
3
3
  import { a as stopPropagation, n as chainHook, r as mergeConfigs, t as callHook } from "./hooks-V-PEPJHv.js";
4
4
  export { AsyncProcess, Process, asyncify, callHook, chainHook, defineActor, defineMessages, mergeConfigs, runDispatch, runDispatchAsync, spawn, spawnAsync, stopPropagation };
package/dist/pipe.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { n as ExitMessage, o as ProcessFn, r as Message } from "./types-DYAxWeSM.js";
1
+ import { n as ExitMessage, o as ProcessFn, r as Message } from "./types-BzM4YqJj.js";
2
2
 
3
3
  //#region src/pipe.d.ts
4
4
  /**
@@ -1,5 +1,5 @@
1
- import { r as Message } from "../types-DYAxWeSM.js";
2
- import { d as ActorPlugin } from "../hooks-fgRvVnDj.js";
1
+ import { r as Message } from "../types-BzM4YqJj.js";
2
+ import { d as ActorPlugin } from "../hooks-D6qtxITh.js";
3
3
 
4
4
  //#region src/plugins/debug-logger.d.ts
5
5
  declare module "../index" {
@@ -1,4 +1,4 @@
1
- import { d as ActorPlugin } from "../hooks-fgRvVnDj.js";
1
+ import { d as ActorPlugin } from "../hooks-D6qtxITh.js";
2
2
 
3
3
  //#region src/plugins/tree-introspection.d.ts
4
4
  declare module "../index" {
@@ -1,4 +1,4 @@
1
- import { d as WithSender, m as AsyncProcess, n as ExitMessage, o as ProcessFn, r as Message } from "./types-DYAxWeSM.js";
1
+ import { m as AsyncProcess, n as ExitMessage, o as ProcessFn, r as Message, s as SenderInfo } from "./types-BzM4YqJj.js";
2
2
 
3
3
  //#region src/util.d.ts
4
4
  type ReducerClosure<M> = (msg: M) => void;
@@ -20,14 +20,14 @@ declare function runDispatch<M>(name: string, fn: ReducerClosure<M>, readyFn?: R
20
20
  //#endregion
21
21
  //#region src/process.d.ts
22
22
  /** @deprecated Use {@link spawnAsync} instead. */
23
- declare function spawn<A, S, IM extends Message = Message, OM extends Message = ExitMessage>(fn: ProcessFn<A, S, IM, OM>, pname: string, tp?: (m: WithSender<OM>) => void): (a: A) => Process<A, S, IM, OM>;
23
+ 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>;
24
24
  /** @deprecated Use {@link AsyncProcess} instead. Sync processes are
25
25
  * wrapped via asyncify internally; spawnAsync handles both. */
26
26
  declare class Process<A, S, IM extends Message, OM extends Message> extends AsyncProcess<A, S, IM, OM, {}> {
27
- constructor(fn: ProcessFn<A, S, IM, OM>, pname: string, tp?: (m: WithSender<OM>) => void);
27
+ constructor(fn: ProcessFn<A, S, IM, OM>, pname: string, tp?: (m: OM, from: SenderInfo) => void);
28
28
  start(a: A): this;
29
29
  tick(): Promise<void>;
30
30
  }
31
31
  //#endregion
32
32
  export { spawn as n, runDispatch as r, Process as t };
33
- //# sourceMappingURL=process-CECMMHyR.d.ts.map
33
+ //# sourceMappingURL=process-YKyZJOvg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-YKyZJOvg.d.ts","names":[],"sources":["../src/util.ts","../src/process.ts"],"mappings":";;;KAOK,cAAA,OAAqB,GAAA,EAAK,CAAC;AAAA,KAC3B,OAAA;;;;;;iBAQK,WAAA,IACR,IAAA,UACA,EAAA,EAAI,cAAA,CAAe,CAAA,GACnB,OAAA,GAAS,OAAA,EACT,UAAA,aACC,SAAA,aAAsB,CAAA;AAdO;AAAA;;;;AACpB;AACC;;;;;iBCDG,KAAA,kBAGH,OAAA,GAAU,OAAA,aACV,OAAA,GAAU,WAAA,EAErB,EAAA,EAAI,SAAA,CAAU,CAAA,EAAG,CAAA,EAAG,EAAA,EAAI,EAAA,GACxB,KAAA,UACA,EAAA,IAAM,CAAA,EAAG,EAAA,EAAI,IAAA,EAAM,UAAA,aACjB,CAAA,EAAG,CAAA,KAAM,OAAA,CAAQ,CAAA,EAAG,CAAA,EAAG,EAAA,EAAI,EAAA;;;cAMzB,OAAA,kBAGO,OAAA,aACA,OAAA,UACH,YAAA,CAAa,CAAA,EAAG,CAAA,EAAG,EAAA,EAAI,EAAA;cAE7B,EAAA,EAAI,SAAA,CAAU,CAAA,EAAG,CAAA,EAAG,EAAA,EAAI,EAAA,GACxB,KAAA,UACA,EAAA,IAAM,CAAA,EAAG,EAAA,EAAI,IAAA,EAAM,UAAA;EAKrB,KAAA,CAAM,CAAA,EAAG,CAAA;EAIT,IAAA,IAAQ,OAAA;AAAA"}
@@ -1,5 +1,5 @@
1
- import { r as Message, t as AsyncProcessFn } from "../types-DYAxWeSM.js";
2
- import { _ as ReflectionOptions, h as MethodOptions, l as ActorDefinition, p as HandlerOptions } from "../hooks-fgRvVnDj.js";
1
+ import { r as Message, t as AsyncProcessFn } from "../types-BzM4YqJj.js";
2
+ import { _ as ReflectionOptions, h as MethodOptions, l as ActorDefinition, p as HandlerOptions } from "../hooks-D6qtxITh.js";
3
3
  import { FileHandle } from "node:fs/promises";
4
4
 
5
5
  //#region src/remote/child.d.ts
@@ -1,4 +1,4 @@
1
- import { s as spawnAsync, t as defineActor } from "../src-DeIF0clC.js";
1
+ import { s as spawnAsync, t as defineActor } from "../src-fhiwGw91.js";
2
2
  import { a as stopPropagation } from "../hooks-V-PEPJHv.js";
3
3
  import { open, unlink } from "node:fs/promises";
4
4
  import { createReadStream } from "node:fs";
@@ -192,8 +192,7 @@ async function runChild(fn) {
192
192
  ctx.parentId = parentId;
193
193
  return yield* fn(ctx, args);
194
194
  };
195
- const proc = spawnAsync(wrappedFn, "remote", (msgWithSender) => {
196
- const [msg, sender] = msgWithSender;
195
+ const proc = spawnAsync(wrappedFn, "remote", (msg, sender) => {
197
196
  transport.send(encode("$msg", {
198
197
  type: msg.type,
199
198
  fromName: sender.fromName,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/remote/fifo.ts","../../src/remote/protocol.ts","../../src/remote/child.ts","../../src/remote/host.ts","../../src/remote/define.ts"],"sourcesContent":["// ── FIFO transport ─────────────────────────────────────────────────────────\n//\n// Newline-delimited UTF-8 over named fifos. Strict handler lifecycle:\n// onMessage() throws if a handler is already set; call removeHandler() first.\n\nimport { open, type FileHandle } from \"node:fs/promises\";\nimport { createReadStream, type ReadStream } from \"node:fs\";\nimport * as readline from \"node:readline\";\n\nexport class FifoUtf8NlineTransport {\n private readFd: FileHandle | null;\n private writeFd: FileHandle | null;\n private rl: readline.Interface | null;\n private rs: ReadStream | null;\n private pvtOnMessage: ((line: string) => void) | null = null;\n private closed = false;\n private pvtError: Error | null = null;\n private pvtWriter: FifoUtf8NlineTransport | null = null;\n\n private constructor(opts: {\n readFd?: FileHandle;\n writeFd?: FileHandle;\n }) {\n this.readFd = opts.readFd ?? null;\n this.writeFd = opts.writeFd ?? null;\n\n if (this.readFd) {\n this.rs = createReadStream(\"\", {\n fd: this.readFd.fd,\n encoding: \"utf-8\",\n autoClose: false,\n });\n this.rl = readline.createInterface({ input: this.rs });\n\n this.rl.on(\"line\", (line) => {\n if (this.pvtOnMessage && !this.closed) this.pvtOnMessage(line);\n });\n\n this.rl.on(\"close\", () => { this.closed = true; });\n\n this.rs.on(\"error\", (err: Error) => {\n this.pvtError = err;\n if (!this.closed) this.closed = true;\n });\n\n this.rl.on(\"error\", (err: Error) => {\n this.pvtError = err;\n if (!this.closed) this.closed = true;\n });\n } else {\n this.rs = null;\n this.rl = null;\n }\n }\n\n // ── factories ──────────────────────────────────────────────────────────\n\n private static async openReader(path: string): Promise<FifoUtf8NlineTransport> {\n const readFd = await open(path, \"r\");\n return new FifoUtf8NlineTransport({ readFd });\n }\n\n private static async openWriter(path: string): Promise<FifoUtf8NlineTransport> {\n const writeFd = await open(path, \"w\");\n return new FifoUtf8NlineTransport({ writeFd });\n }\n\n static fromFds(readFd: FileHandle, writeFd: FileHandle): FifoUtf8NlineTransport {\n return new FifoUtf8NlineTransport({ readFd, writeFd });\n }\n\n // ── bidirectional connection ───────────────────────────────────────────\n\n private attachWriter(w: FifoUtf8NlineTransport): void {\n this.pvtWriter = w;\n }\n\n /**\n * Start opening a bidirectional connection. Opens readPath for reading\n * in the background, returns a promise. The caller should do whatever\n * setup is needed to unblock the read (e.g. spawn a process that opens\n * readPath for writing), then await the returned transport.\n *\n * Once the read completes, writePath is opened for writing automatically.\n */\n static beginConnect(\n readPath: string,\n writePath: string,\n ): { transport: Promise<FifoUtf8NlineTransport> } {\n const readerPromise = FifoUtf8NlineTransport.openReader(readPath);\n\n const transport = readerPromise.then(async (reader) => {\n const writer = await FifoUtf8NlineTransport.openWriter(writePath);\n reader.attachWriter(writer);\n return reader;\n });\n\n return { transport };\n }\n\n /**\n * Open a bidirectional connection. Opens writePath for writing first\n * (unblocking the peer's read), starts reading readPath in the\n * background, then awaits both.\n *\n * Use this when you are the side that responds to the peer's beginConnect\n * (i.e. you don't need to interleave any setup between the read and write\n * opens).\n */\n static async connect(\n readPath: string,\n writePath: string,\n ): Promise<FifoUtf8NlineTransport> {\n const readerPromise = FifoUtf8NlineTransport.openReader(readPath);\n const writer = await FifoUtf8NlineTransport.openWriter(writePath);\n const reader = await readerPromise;\n reader.attachWriter(writer);\n return reader;\n }\n\n // ── public API ─────────────────────────────────────────────────────────\n\n get canSend(): boolean {\n if (this.pvtWriter) return this.pvtWriter.canSend;\n return this.writeFd !== null && !this.closed;\n }\n\n onMessage(handler: (line: string) => void): void {\n if (this.closed) throw new Error(\"FifoUtf8NlineTransport: closed\");\n if (this.readFd === null) throw new Error(\"FifoUtf8NlineTransport: not a reader\");\n if (this.pvtOnMessage !== null) {\n throw new Error(\"FifoUtf8NlineTransport: handler already set — call removeHandler() first\");\n }\n this.pvtOnMessage = handler;\n }\n\n removeHandler(): ((line: string) => void) | null {\n const prev = this.pvtOnMessage;\n this.pvtOnMessage = null;\n return prev;\n }\n\n get hasHandler(): boolean {\n return this.pvtOnMessage !== null;\n }\n\n get lastError(): Error | null {\n return this.pvtError;\n }\n\n async send(line: string): Promise<void> {\n if (this.pvtWriter) return this.pvtWriter.send(line);\n if (this.closed) throw new Error(\"FifoUtf8NlineTransport: closed\");\n if (this.writeFd === null) throw new Error(\"FifoUtf8NlineTransport: not a writer\");\n if (!line.endsWith(\"\\n\")) line += \"\\n\";\n await this.writeFd.write(line);\n }\n\n async close(): Promise<void> {\n if (this.closed) return;\n this.closed = true;\n if (this.rl) this.rl.close();\n if (this.rs) this.rs.destroy();\n if (this.readFd) { try { await this.readFd.close(); } catch {} }\n if (this.writeFd) { try { await this.writeFd.close(); } catch {} }\n if (this.pvtWriter) { await this.pvtWriter.close(); }\n }\n}\n","// ── Wire protocol ──────────────────────────────────────────────────────────\n//\n// NDJSON wire protocol: one JSON object per line.\n// child → host: $proto, $state, $msg, $exit\n// host → child: $init, $msg\n\nexport const PROTO_VERSION = \"ndjson.v1\";\n\nexport function encode(key: string, value: unknown): string {\n return JSON.stringify({ [key]: value }) + \"\\n\";\n}\n\nexport function decode(line: string): Record<string, unknown> {\n return JSON.parse(line);\n}\n\n// ── type 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(msg: Record<string, unknown>): msg is { $msg: { type: string; fromName: string; body: unknown } } {\n return \"$msg\" in msg;\n}\nexport function isExit(msg: Record<string, unknown>): msg is { $exit: { code: number; state: unknown } } {\n return \"$exit\" in msg;\n}\n","// ── Child-side adapter ─────────────────────────────────────────────────────\n//\n// Wraps a posipaki actor in a CLI process that speaks the wire protocol over\n// two unidirectional named fifos.\n\nimport type { AsyncProcessFn, Message } from \"../types.js\";\nimport { FifoUtf8NlineTransport } from \"./fifo.js\";\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}\nimport { encode, decode, isInit, isMsg, PROTO_VERSION } from \"./protocol.js\";\nimport { spawnAsync } from \"../index.js\";\n\nexport async function runChild<\n Args,\n State,\n InMsg extends Message,\n OutMsg extends Message,\n>(fn: AsyncProcessFn<Args, State, InMsg, OutMsg>): Promise<void> {\n const fifoIn = process.argv\n .find((a) => a.startsWith(\"--fifo-in=\"))\n ?.slice(\"--fifo-in=\".length);\n const fifoOut = process.argv\n .find((a) => a.startsWith(\"--fifo-out=\"))\n ?.slice(\"--fifo-out=\".length);\n\n if (!fifoIn || !fifoOut) {\n console.error(\"child: --fifo-in=<path> and --fifo-out=<path> required\");\n process.exit(1);\n }\n\n const transport = await FifoUtf8NlineTransport.connect(fifoOut, fifoIn);\n\n // 1. Send protocol version\n await transport.send(encode(\"$proto\", PROTO_VERSION));\n\n // 2. Wait for $init\n const initMsg = await new Promise<Record<string, unknown>>((resolve) => {\n transport.onMessage((line) => {\n const msg = decode(line);\n if (isInit(msg)) resolve(msg.$init);\n });\n });\n transport.removeHandler();\n\n const parentName = (initMsg.parentName as string) ?? null;\n const parentIdName = (initMsg.parentIdName as string) ?? null;\n const parentId = parentIdName ? Symbol.for(parentIdName) : null;\n const { parentName: _pn, parentIdName: _pid, ...initArgs } = initMsg;\n\n // 3. Spawn the actor\n const wrappedFn: typeof fn = async function* (ctx, args) {\n (ctx as Record<string, unknown>).parentName = parentName;\n (ctx as Record<string, unknown>).parentId = parentId;\n return yield* fn(ctx, args);\n };\n\n const proc = spawnAsync(wrappedFn, \"remote\", (msgWithSender) => {\n const [msg, sender] = msgWithSender;\n transport\n .send(\n encode(\"$msg\", {\n type: msg.type,\n fromName: sender.fromName,\n body: msg,\n }),\n )\n .catch(() => {});\n })(initArgs as unknown as Args);\n await proc.ready();\n\n // 4. Send initial state\n await transport.send(encode(\"$state\", proc.state as Record<string, unknown>));\n\n // 5. Subscribe to state changes\n proc.subscribe(() => {\n transport\n .send(encode(\"$state\", proc.state as Record<string, unknown>))\n .catch(() => {});\n });\n\n // 6. Forward incoming messages to the actor\n transport.onMessage((line) => {\n const msg = decode(line);\n if (isMsg(msg)) {\n const { fromName, body } = msg.$msg;\n proc.send(body as InMsg, { fromName, fromId: Symbol() });\n }\n });\n\n // 7. On actor exit, send $exit\n const shutdown = async (code: number) => {\n await transport.send(encode(\"$exit\", { code, state: proc.state }));\n transport.close();\n process.exit(code);\n };\n proc.wait().then(\n () => shutdown(0),\n (err: unknown) => {\n console.error(\"child actor error:\", err);\n shutdown(1);\n },\n );\n}\n","// ── Host-side adapter ──────────────────────────────────────────────────────\n//\n// commandConnector: spawns a child process and bridges the wire protocol.\n// Connector wrappers (bunConnector, nodeConnector, defaultConnector) produce\n// the command array from a script path.\n\nimport { spawn, execSync, type ChildProcess } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { unlink } from \"node:fs/promises\";\nimport { FifoUtf8NlineTransport } from \"./fifo.js\";\nimport { encode, decode, isProto, isState, isMsg, isExit, PROTO_VERSION } from \"./protocol.js\";\nimport type { Message } from \"../types.js\";\n\n// ── types ──────────────────────────────────────────────────────────────────\n\nexport interface CommandSpawnOptions<Args = Record<string, unknown>> {\n command: string[];\n args: Args;\n parentName?: string;\n}\n\nexport interface RemoteProxy<\n State = unknown,\n InMsg extends Message = Message,\n OutMsg extends Message = Message,\n> {\n readonly state: State;\n ready(): Promise<void>;\n send(msg: InMsg): void;\n wait(): Promise<{ code: number | null; state: State }>;\n onMessage(handler: (msg: OutMsg) => void): void;\n}\n\n/** A connector takes a command and returns a RemoteProxy. */\nexport type Connector<\n State = unknown,\n InMsg extends Message = Message,\n OutMsg extends Message = Message,\n> = (opts: CommandSpawnOptions) => Promise<RemoteProxy<State, InMsg, OutMsg>>;\n\n// ── commandConnector ───────────────────────────────────────────────────────\n\nexport async function spawnRemote<\n State = unknown,\n InMsg extends Message = Message,\n OutMsg extends Message = Message,\n Args = Record<string, unknown>,\n>(\n opts: CommandSpawnOptions<Args>,\n): Promise<RemoteProxy<State, InMsg, OutMsg>> {\n const basePath = join(tmpdir(), `posipaki-${randomUUID()}`);\n\n execSync(`mkfifo \"${basePath}.in\"`);\n execSync(`mkfifo \"${basePath}.out\"`);\n\n const setup = FifoUtf8NlineTransport.beginConnect(basePath + \".in\", basePath + \".out\");\n\n const childCmd = [\n ...opts.command,\n `--fifo-in=${basePath + \".in\"}`,\n `--fifo-out=${basePath + \".out\"}`,\n ];\n const childProc: ChildProcess = spawn(childCmd[0], childCmd.slice(1), {\n cwd: process.cwd(),\n stdio: [\"inherit\", \"inherit\", \"inherit\"],\n });\n\n const transport = await setup.transport;\n\n // ── handshake ───────────────────────────────────────────────────────\n const protoLine = await new Promise<string>((resolve) => {\n transport.onMessage((line) => resolve(line));\n });\n const protoMsg = decode(protoLine);\n if (!isProto(protoMsg) || protoMsg.$proto !== PROTO_VERSION) {\n throw new Error(`unsupported protocol: ${protoLine.slice(0, 50)}`);\n }\n transport.removeHandler();\n\n await transport.send(encode(\"$init\", {\n ...opts.args as Record<string, unknown>,\n parentName: opts.parentName ?? \"host\",\n parentIdName: opts.parentName ?? \"host\",\n }));\n\n let currentState: Record<string, unknown> = {};\n await new Promise<void>((resolve) => {\n transport.onMessage((line) => {\n const msg = decode(line);\n if (isState(msg)) {\n Object.assign(currentState, msg.$state as Record<string, unknown>);\n resolve();\n }\n });\n });\n transport.removeHandler();\n\n // ── persistent handler ──────────────────────────────────────────────\n let msgHandler: ((msg: OutMsg) => void) | null = null;\n let exitResolver: ((value: { 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 transport.onMessage((line) => {\n const msg = decode(line);\n if (isState(msg)) {\n Object.assign(currentState, msg.$state as Record<string, unknown>);\n } else if (isMsg(msg)) {\n msgHandler?.(msg.$msg.body as OutMsg);\n } else if (isExit(msg)) {\n if (exitResolver) {\n exitResolver({ code: msg.$exit.code, state: msg.$exit.state as State });\n exitResolver = null;\n }\n cleanup();\n }\n });\n\n // ── cleanup ─────────────────────────────────────────────────────────\n let cleaned = false;\n const cleanup = () => {\n if (cleaned) return;\n cleaned = true;\n transport.close();\n unlink(basePath + \".in\").catch(() => {});\n unlink(basePath + \".out\").catch(() => {});\n };\n\n childProc.on(\"exit\", (code) => {\n if (exitResolver) {\n exitResolver({ code, state: currentState as State });\n exitResolver = null;\n }\n cleanup();\n });\n\n return {\n get state(): State { return currentState as State; },\n async ready() {},\n send(msg: InMsg) {\n const from = opts.parentName ?? \"host\";\n transport.send(encode(\"$msg\", { type: msg.type, fromName: from, body: msg }));\n },\n async wait() { return exitPromise; },\n onMessage(handler: (msg: OutMsg) => void) { msgHandler = handler; },\n };\n}\n\n// ── connector wrappers ─────────────────────────────────────────────────────\n\nfunction scriptConnector(\n runner: string,\n runnerArgs: string[],\n): (scriptPath: string) => Connector {\n return (scriptPath: string) => {\n return ((opts: CommandSpawnOptions) => {\n return commandConnector({\n ...opts,\n command: [runner, ...runnerArgs, scriptPath, ...opts.command],\n });\n }) as Connector;\n };\n}\n\n/** Spawn via `bun run <script>`. */\nexport const bunConnector = scriptConnector(\"bun\", [\"run\"]);\n\n/** Spawn via `node <script>`. */\nexport const nodeConnector = scriptConnector(\"node\", []);\n\n/**\n * Auto-detect: prefers `bun run` if the script is a .ts file and bun is\n * the current runtime, otherwise falls back to `node`.\n */\nexport function defaultConnector(scriptPath: string): Connector {\n // Check if we're running under bun\n const isBun = typeof (globalThis as any).Bun !== \"undefined\";\n const isTs = scriptPath.endsWith(\".ts\");\n if (isBun && isTs) return bunConnector(scriptPath);\n return nodeConnector(scriptPath);\n}\n\n// ── alias ───────────────────────────────────────────────────────────────────\n\nexport const commandConnector = spawnRemote;\n","// ── defineRemoteActor ──────────────────────────────────────────────────────\n//\n// Wraps an ActorDefinition so that when spawned, it runs in a child process\n// over two named fifos. Returns { actor, runRemoteRoot, isRemoteRoot }.\n//\n// Uses defineActor's setup hook to spawn the remote child before the first\n// yield, so proc.ready() shows the live remote state — same as local spawn.\n\nimport { fileURLToPath } from \"node:url\";\nimport { createHash } from \"node:crypto\";\nimport type { Message } from \"../types.js\";\nimport type {\n HandlerOptions,\n MethodOptions,\n ReflectionOptions,\n} from \"../actor-types.js\";\nimport { defineActor } from \"../define-actor.js\";\nimport { stopPropagation } from \"../hooks.js\";\nimport type { HookResult } from \"../hooks.js\";\nimport { runChild } from \"./child.js\";\nimport { type Connector, defaultConnector } from \"./host.js\";\nimport type { RemoteProxy } from \"./host.js\";\nimport type { ActorDefinition } from \"../actor-types.js\";\n\nexport interface RemoteActorOptions {\n manual?: boolean;\n connector?: Connector;\n}\n\nexport interface RemoteActorBundle<\n Args,\n State,\n InMsg extends Message,\n OutMsg extends Message,\n ReflectionMethods extends ReflectionOptions,\n> {\n actor: ActorDefinition<Args, State, InMsg, OutMsg, ReflectionMethods>;\n runRemoteRoot(): Promise<void>;\n isRemoteRoot: boolean;\n}\n\nfunction pathHash(path: string): string {\n return createHash(\"sha256\").update(path).digest(\"hex\").slice(0, 12);\n}\n\nconst MARKER_PREFIX = \"--remote=\";\n\nexport function defineRemoteActor<\n Args,\n State,\n InMsg extends Message,\n OutMsg extends Message,\n Methods extends MethodOptions,\n Handlers extends HandlerOptions<InMsg>,\n Reflection extends ReflectionOptions,\n>(\n actor: ActorDefinition<Args, State, InMsg, OutMsg, Reflection>,\n url: string,\n opts: RemoteActorOptions = {},\n): RemoteActorBundle<Args, State, InMsg, OutMsg, Reflection> {\n const scriptPath = fileURLToPath(url);\n const marker = `${MARKER_PREFIX}${pathHash(scriptPath)}`;\n const isRemoteRoot = !opts.manual && process.argv.includes(marker);\n\n if (isRemoteRoot) {\n runChild(actor.fn);\n }\n\n const proxyDef = defineActor<\n Args,\n { public: State; private: { remote: RemoteProxy<State, InMsg, OutMsg> } },\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n Reflection\n >({\n name: actor.name ?? \"actor\",\n inMessages: actor.inMessages,\n outMessages: actor.outMessages,\n handlers: {} as unknown as Handlers,\n async setup(args: Args) {\n const connect = opts.connector ?? defaultConnector(scriptPath);\n const remote = (await connect({\n command: [marker],\n args: args as Record<string, unknown>,\n })) as RemoteProxy<State, InMsg, OutMsg>;\n remote.onMessage((msg: OutMsg) => {\n this.emit(msg);\n });\n return {\n public: remote.state,\n private: { remote },\n };\n },\n async onMessage(msg: InMsg): Promise<HookResult> {\n this.state.private.remote?.send(msg);\n return stopPropagation();\n },\n async onStopRequested() {\n if (this.state.private.remote) {\n this.state.private.remote.send({ type: \"STOP\" } as InMsg);\n await this.state.private.remote.wait();\n }\n this.agreeToStop();\n },\n });\n\n return {\n actor: proxyDef as ActorDefinition<Args, State, InMsg, OutMsg, Reflection>,\n runRemoteRoot() {\n return runChild(actor.fn);\n },\n isRemoteRoot,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/remote/fifo.ts","../../src/remote/protocol.ts","../../src/remote/child.ts","../../src/remote/host.ts","../../src/remote/define.ts"],"sourcesContent":["// ── FIFO transport ─────────────────────────────────────────────────────────\n//\n// Newline-delimited UTF-8 over named fifos. Strict handler lifecycle:\n// onMessage() throws if a handler is already set; call removeHandler() first.\n\nimport { open, type FileHandle } from \"node:fs/promises\";\nimport { createReadStream, type ReadStream } from \"node:fs\";\nimport * as readline from \"node:readline\";\n\nexport class FifoUtf8NlineTransport {\n private readFd: FileHandle | null;\n private writeFd: FileHandle | null;\n private rl: readline.Interface | null;\n private rs: ReadStream | null;\n private pvtOnMessage: ((line: string) => void) | null = null;\n private closed = false;\n private pvtError: Error | null = null;\n private pvtWriter: FifoUtf8NlineTransport | null = null;\n\n private constructor(opts: {\n readFd?: FileHandle;\n writeFd?: FileHandle;\n }) {\n this.readFd = opts.readFd ?? null;\n this.writeFd = opts.writeFd ?? null;\n\n if (this.readFd) {\n this.rs = createReadStream(\"\", {\n fd: this.readFd.fd,\n encoding: \"utf-8\",\n autoClose: false,\n });\n this.rl = readline.createInterface({ input: this.rs });\n\n this.rl.on(\"line\", (line) => {\n if (this.pvtOnMessage && !this.closed) this.pvtOnMessage(line);\n });\n\n this.rl.on(\"close\", () => { this.closed = true; });\n\n this.rs.on(\"error\", (err: Error) => {\n this.pvtError = err;\n if (!this.closed) this.closed = true;\n });\n\n this.rl.on(\"error\", (err: Error) => {\n this.pvtError = err;\n if (!this.closed) this.closed = true;\n });\n } else {\n this.rs = null;\n this.rl = null;\n }\n }\n\n // ── factories ──────────────────────────────────────────────────────────\n\n private static async openReader(path: string): Promise<FifoUtf8NlineTransport> {\n const readFd = await open(path, \"r\");\n return new FifoUtf8NlineTransport({ readFd });\n }\n\n private static async openWriter(path: string): Promise<FifoUtf8NlineTransport> {\n const writeFd = await open(path, \"w\");\n return new FifoUtf8NlineTransport({ writeFd });\n }\n\n static fromFds(readFd: FileHandle, writeFd: FileHandle): FifoUtf8NlineTransport {\n return new FifoUtf8NlineTransport({ readFd, writeFd });\n }\n\n // ── bidirectional connection ───────────────────────────────────────────\n\n private attachWriter(w: FifoUtf8NlineTransport): void {\n this.pvtWriter = w;\n }\n\n /**\n * Start opening a bidirectional connection. Opens readPath for reading\n * in the background, returns a promise. The caller should do whatever\n * setup is needed to unblock the read (e.g. spawn a process that opens\n * readPath for writing), then await the returned transport.\n *\n * Once the read completes, writePath is opened for writing automatically.\n */\n static beginConnect(\n readPath: string,\n writePath: string,\n ): { transport: Promise<FifoUtf8NlineTransport> } {\n const readerPromise = FifoUtf8NlineTransport.openReader(readPath);\n\n const transport = readerPromise.then(async (reader) => {\n const writer = await FifoUtf8NlineTransport.openWriter(writePath);\n reader.attachWriter(writer);\n return reader;\n });\n\n return { transport };\n }\n\n /**\n * Open a bidirectional connection. Opens writePath for writing first\n * (unblocking the peer's read), starts reading readPath in the\n * background, then awaits both.\n *\n * Use this when you are the side that responds to the peer's beginConnect\n * (i.e. you don't need to interleave any setup between the read and write\n * opens).\n */\n static async connect(\n readPath: string,\n writePath: string,\n ): Promise<FifoUtf8NlineTransport> {\n const readerPromise = FifoUtf8NlineTransport.openReader(readPath);\n const writer = await FifoUtf8NlineTransport.openWriter(writePath);\n const reader = await readerPromise;\n reader.attachWriter(writer);\n return reader;\n }\n\n // ── public API ─────────────────────────────────────────────────────────\n\n get canSend(): boolean {\n if (this.pvtWriter) return this.pvtWriter.canSend;\n return this.writeFd !== null && !this.closed;\n }\n\n onMessage(handler: (line: string) => void): void {\n if (this.closed) throw new Error(\"FifoUtf8NlineTransport: closed\");\n if (this.readFd === null) throw new Error(\"FifoUtf8NlineTransport: not a reader\");\n if (this.pvtOnMessage !== null) {\n throw new Error(\"FifoUtf8NlineTransport: handler already set — call removeHandler() first\");\n }\n this.pvtOnMessage = handler;\n }\n\n removeHandler(): ((line: string) => void) | null {\n const prev = this.pvtOnMessage;\n this.pvtOnMessage = null;\n return prev;\n }\n\n get hasHandler(): boolean {\n return this.pvtOnMessage !== null;\n }\n\n get lastError(): Error | null {\n return this.pvtError;\n }\n\n async send(line: string): Promise<void> {\n if (this.pvtWriter) return this.pvtWriter.send(line);\n if (this.closed) throw new Error(\"FifoUtf8NlineTransport: closed\");\n if (this.writeFd === null) throw new Error(\"FifoUtf8NlineTransport: not a writer\");\n if (!line.endsWith(\"\\n\")) line += \"\\n\";\n await this.writeFd.write(line);\n }\n\n async close(): Promise<void> {\n if (this.closed) return;\n this.closed = true;\n if (this.rl) this.rl.close();\n if (this.rs) this.rs.destroy();\n if (this.readFd) { try { await this.readFd.close(); } catch {} }\n if (this.writeFd) { try { await this.writeFd.close(); } catch {} }\n if (this.pvtWriter) { await this.pvtWriter.close(); }\n }\n}\n","// ── Wire protocol ──────────────────────────────────────────────────────────\n//\n// NDJSON wire protocol: one JSON object per line.\n// child → host: $proto, $state, $msg, $exit\n// host → child: $init, $msg\n\nexport const PROTO_VERSION = \"ndjson.v1\";\n\nexport function encode(key: string, value: unknown): string {\n return JSON.stringify({ [key]: value }) + \"\\n\";\n}\n\nexport function decode(line: string): Record<string, unknown> {\n return JSON.parse(line);\n}\n\n// ── type 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(msg: Record<string, unknown>): msg is { $msg: { type: string; fromName: string; body: unknown } } {\n return \"$msg\" in msg;\n}\nexport function isExit(msg: Record<string, unknown>): msg is { $exit: { code: number; state: unknown } } {\n return \"$exit\" in msg;\n}\n","// ── Child-side adapter ─────────────────────────────────────────────────────\n//\n// Wraps a posipaki actor in a CLI process that speaks the wire protocol over\n// two unidirectional named fifos.\n\nimport type { AsyncProcessFn, Message } from \"../types.js\";\nimport { FifoUtf8NlineTransport } from \"./fifo.js\";\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}\nimport { encode, decode, isInit, isMsg, PROTO_VERSION } from \"./protocol.js\";\nimport { spawnAsync } from \"../index.js\";\n\nexport async function runChild<\n Args,\n State,\n InMsg extends Message,\n OutMsg extends Message,\n>(fn: AsyncProcessFn<Args, State, InMsg, OutMsg>): Promise<void> {\n const fifoIn = process.argv\n .find((a) => a.startsWith(\"--fifo-in=\"))\n ?.slice(\"--fifo-in=\".length);\n const fifoOut = process.argv\n .find((a) => a.startsWith(\"--fifo-out=\"))\n ?.slice(\"--fifo-out=\".length);\n\n if (!fifoIn || !fifoOut) {\n console.error(\"child: --fifo-in=<path> and --fifo-out=<path> required\");\n process.exit(1);\n }\n\n const transport = await FifoUtf8NlineTransport.connect(fifoOut, fifoIn);\n\n // 1. Send protocol version\n await transport.send(encode(\"$proto\", PROTO_VERSION));\n\n // 2. Wait for $init\n const initMsg = await new Promise<Record<string, unknown>>((resolve) => {\n transport.onMessage((line) => {\n const msg = decode(line);\n if (isInit(msg)) resolve(msg.$init);\n });\n });\n transport.removeHandler();\n\n const parentName = (initMsg.parentName as string) ?? null;\n const parentIdName = (initMsg.parentIdName as string) ?? null;\n const parentId = parentIdName ? Symbol.for(parentIdName) : null;\n const { parentName: _pn, parentIdName: _pid, ...initArgs } = initMsg;\n\n // 3. Spawn the actor\n const wrappedFn: typeof fn = async function* (ctx, args) {\n (ctx as Record<string, unknown>).parentName = parentName;\n (ctx as Record<string, unknown>).parentId = parentId;\n return yield* fn(ctx, args);\n };\n\n const proc = spawnAsync(wrappedFn, \"remote\", (msg, sender) => {\n transport\n .send(\n encode(\"$msg\", {\n type: msg.type,\n fromName: sender.fromName,\n body: msg,\n }),\n )\n .catch(() => {});\n })(initArgs as unknown as Args);\n await proc.ready();\n\n // 4. Send initial state\n await transport.send(encode(\"$state\", proc.state as Record<string, unknown>));\n\n // 5. Subscribe to state changes\n proc.subscribe(() => {\n transport\n .send(encode(\"$state\", proc.state as Record<string, unknown>))\n .catch(() => {});\n });\n\n // 6. Forward incoming messages to the actor\n transport.onMessage((line) => {\n const msg = decode(line);\n if (isMsg(msg)) {\n const { fromName, body } = msg.$msg;\n proc.send(body as InMsg, { fromName, fromId: Symbol() });\n }\n });\n\n // 7. On actor exit, send $exit\n const shutdown = async (code: number) => {\n await transport.send(encode(\"$exit\", { code, state: proc.state }));\n transport.close();\n process.exit(code);\n };\n proc.wait().then(\n () => shutdown(0),\n (err: unknown) => {\n console.error(\"child actor error:\", err);\n shutdown(1);\n },\n );\n}\n","// ── Host-side adapter ──────────────────────────────────────────────────────\n//\n// commandConnector: spawns a child process and bridges the wire protocol.\n// Connector wrappers (bunConnector, nodeConnector, defaultConnector) produce\n// the command array from a script path.\n\nimport { spawn, execSync, type ChildProcess } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { unlink } from \"node:fs/promises\";\nimport { FifoUtf8NlineTransport } from \"./fifo.js\";\nimport { encode, decode, isProto, isState, isMsg, isExit, PROTO_VERSION } from \"./protocol.js\";\nimport type { Message } from \"../types.js\";\n\n// ── types ──────────────────────────────────────────────────────────────────\n\nexport interface CommandSpawnOptions<Args = Record<string, unknown>> {\n command: string[];\n args: Args;\n parentName?: string;\n}\n\nexport interface RemoteProxy<\n State = unknown,\n InMsg extends Message = Message,\n OutMsg extends Message = Message,\n> {\n readonly state: State;\n ready(): Promise<void>;\n send(msg: InMsg): void;\n wait(): Promise<{ code: number | null; state: State }>;\n onMessage(handler: (msg: OutMsg) => void): void;\n}\n\n/** A connector takes a command and returns a RemoteProxy. */\nexport type Connector<\n State = unknown,\n InMsg extends Message = Message,\n OutMsg extends Message = Message,\n> = (opts: CommandSpawnOptions) => Promise<RemoteProxy<State, InMsg, OutMsg>>;\n\n// ── commandConnector ───────────────────────────────────────────────────────\n\nexport async function spawnRemote<\n State = unknown,\n InMsg extends Message = Message,\n OutMsg extends Message = Message,\n Args = Record<string, unknown>,\n>(\n opts: CommandSpawnOptions<Args>,\n): Promise<RemoteProxy<State, InMsg, OutMsg>> {\n const basePath = join(tmpdir(), `posipaki-${randomUUID()}`);\n\n execSync(`mkfifo \"${basePath}.in\"`);\n execSync(`mkfifo \"${basePath}.out\"`);\n\n const setup = FifoUtf8NlineTransport.beginConnect(basePath + \".in\", basePath + \".out\");\n\n const childCmd = [\n ...opts.command,\n `--fifo-in=${basePath + \".in\"}`,\n `--fifo-out=${basePath + \".out\"}`,\n ];\n const childProc: ChildProcess = spawn(childCmd[0], childCmd.slice(1), {\n cwd: process.cwd(),\n stdio: [\"inherit\", \"inherit\", \"inherit\"],\n });\n\n const transport = await setup.transport;\n\n // ── handshake ───────────────────────────────────────────────────────\n const protoLine = await new Promise<string>((resolve) => {\n transport.onMessage((line) => resolve(line));\n });\n const protoMsg = decode(protoLine);\n if (!isProto(protoMsg) || protoMsg.$proto !== PROTO_VERSION) {\n throw new Error(`unsupported protocol: ${protoLine.slice(0, 50)}`);\n }\n transport.removeHandler();\n\n await transport.send(encode(\"$init\", {\n ...opts.args as Record<string, unknown>,\n parentName: opts.parentName ?? \"host\",\n parentIdName: opts.parentName ?? \"host\",\n }));\n\n let currentState: Record<string, unknown> = {};\n await new Promise<void>((resolve) => {\n transport.onMessage((line) => {\n const msg = decode(line);\n if (isState(msg)) {\n Object.assign(currentState, msg.$state as Record<string, unknown>);\n resolve();\n }\n });\n });\n transport.removeHandler();\n\n // ── persistent handler ──────────────────────────────────────────────\n let msgHandler: ((msg: OutMsg) => void) | null = null;\n let exitResolver: ((value: { 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 transport.onMessage((line) => {\n const msg = decode(line);\n if (isState(msg)) {\n Object.assign(currentState, msg.$state as Record<string, unknown>);\n } else if (isMsg(msg)) {\n msgHandler?.(msg.$msg.body as OutMsg);\n } else if (isExit(msg)) {\n if (exitResolver) {\n exitResolver({ code: msg.$exit.code, state: msg.$exit.state as State });\n exitResolver = null;\n }\n cleanup();\n }\n });\n\n // ── cleanup ─────────────────────────────────────────────────────────\n let cleaned = false;\n const cleanup = () => {\n if (cleaned) return;\n cleaned = true;\n transport.close();\n unlink(basePath + \".in\").catch(() => {});\n unlink(basePath + \".out\").catch(() => {});\n };\n\n childProc.on(\"exit\", (code) => {\n if (exitResolver) {\n exitResolver({ code, state: currentState as State });\n exitResolver = null;\n }\n cleanup();\n });\n\n return {\n get state(): State { return currentState as State; },\n async ready() {},\n send(msg: InMsg) {\n const from = opts.parentName ?? \"host\";\n transport.send(encode(\"$msg\", { type: msg.type, fromName: from, body: msg }));\n },\n async wait() { return exitPromise; },\n onMessage(handler: (msg: OutMsg) => void) { msgHandler = handler; },\n };\n}\n\n// ── connector wrappers ─────────────────────────────────────────────────────\n\nfunction scriptConnector(\n runner: string,\n runnerArgs: string[],\n): (scriptPath: string) => Connector {\n return (scriptPath: string) => {\n return ((opts: CommandSpawnOptions) => {\n return commandConnector({\n ...opts,\n command: [runner, ...runnerArgs, scriptPath, ...opts.command],\n });\n }) as Connector;\n };\n}\n\n/** Spawn via `bun run <script>`. */\nexport const bunConnector = scriptConnector(\"bun\", [\"run\"]);\n\n/** Spawn via `node <script>`. */\nexport const nodeConnector = scriptConnector(\"node\", []);\n\n/**\n * Auto-detect: prefers `bun run` if the script is a .ts file and bun is\n * the current runtime, otherwise falls back to `node`.\n */\nexport function defaultConnector(scriptPath: string): Connector {\n // Check if we're running under bun\n const isBun = typeof (globalThis as any).Bun !== \"undefined\";\n const isTs = scriptPath.endsWith(\".ts\");\n if (isBun && isTs) return bunConnector(scriptPath);\n return nodeConnector(scriptPath);\n}\n\n// ── alias ───────────────────────────────────────────────────────────────────\n\nexport const commandConnector = spawnRemote;\n","// ── defineRemoteActor ──────────────────────────────────────────────────────\n//\n// Wraps an ActorDefinition so that when spawned, it runs in a child process\n// over two named fifos. Returns { actor, runRemoteRoot, isRemoteRoot }.\n//\n// Uses defineActor's setup hook to spawn the remote child before the first\n// yield, so proc.ready() shows the live remote state — same as local spawn.\n\nimport { fileURLToPath } from \"node:url\";\nimport { createHash } from \"node:crypto\";\nimport type { Message } from \"../types.js\";\nimport type {\n HandlerOptions,\n MethodOptions,\n ReflectionOptions,\n} from \"../actor-types.js\";\nimport { defineActor } from \"../define-actor.js\";\nimport { stopPropagation } from \"../hooks.js\";\nimport type { HookResult } from \"../hooks.js\";\nimport { runChild } from \"./child.js\";\nimport { type Connector, defaultConnector } from \"./host.js\";\nimport type { RemoteProxy } from \"./host.js\";\nimport type { ActorDefinition } from \"../actor-types.js\";\n\nexport interface RemoteActorOptions {\n manual?: boolean;\n connector?: Connector;\n}\n\nexport interface RemoteActorBundle<\n Args,\n State,\n InMsg extends Message,\n OutMsg extends Message,\n ReflectionMethods extends ReflectionOptions,\n> {\n actor: ActorDefinition<Args, State, InMsg, OutMsg, ReflectionMethods>;\n runRemoteRoot(): Promise<void>;\n isRemoteRoot: boolean;\n}\n\nfunction pathHash(path: string): string {\n return createHash(\"sha256\").update(path).digest(\"hex\").slice(0, 12);\n}\n\nconst MARKER_PREFIX = \"--remote=\";\n\nexport function defineRemoteActor<\n Args,\n State,\n InMsg extends Message,\n OutMsg extends Message,\n Methods extends MethodOptions,\n Handlers extends HandlerOptions<InMsg>,\n Reflection extends ReflectionOptions,\n>(\n actor: ActorDefinition<Args, State, InMsg, OutMsg, Reflection>,\n url: string,\n opts: RemoteActorOptions = {},\n): RemoteActorBundle<Args, State, InMsg, OutMsg, Reflection> {\n const scriptPath = fileURLToPath(url);\n const marker = `${MARKER_PREFIX}${pathHash(scriptPath)}`;\n const isRemoteRoot = !opts.manual && process.argv.includes(marker);\n\n if (isRemoteRoot) {\n runChild(actor.fn);\n }\n\n const proxyDef = defineActor<\n Args,\n { public: State; private: { remote: RemoteProxy<State, InMsg, OutMsg> } },\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n Reflection\n >({\n name: actor.name ?? \"actor\",\n inMessages: actor.inMessages,\n outMessages: actor.outMessages,\n handlers: {} as unknown as Handlers,\n async setup(args: Args) {\n const connect = opts.connector ?? defaultConnector(scriptPath);\n const remote = (await connect({\n command: [marker],\n args: args as Record<string, unknown>,\n })) as RemoteProxy<State, InMsg, OutMsg>;\n remote.onMessage((msg: OutMsg) => {\n this.emit(msg);\n });\n return {\n public: remote.state,\n private: { remote },\n };\n },\n async onMessage(msg: InMsg): Promise<HookResult> {\n this.state.private.remote?.send(msg);\n return stopPropagation();\n },\n async onStopRequested() {\n if (this.state.private.remote) {\n this.state.private.remote.send({ type: \"STOP\" } as InMsg);\n await this.state.private.remote.wait();\n }\n this.agreeToStop();\n },\n });\n\n return {\n actor: proxyDef as ActorDefinition<Args, State, InMsg, OutMsg, Reflection>,\n runRemoteRoot() {\n return runChild(actor.fn);\n },\n isRemoteRoot,\n };\n}\n"],"mappings":"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"}
@@ -21,7 +21,6 @@ async function* runDispatchAsync(name, fn, readyFn = () => false, debugLevel = f
21
21
  await fn(msg);
22
22
  }
23
23
  }
24
- const noop = () => null;
25
24
  /** How long a parent waits for a child to stop before continuing shutdown. */
26
25
  const CHILD_STOP_TIMEOUT_MS = 1e3;
27
26
  /**
@@ -35,18 +34,21 @@ const CHILD_STOP_TIMEOUT_MS = 1e3;
35
34
  var AsyncProcess = class AsyncProcess {
36
35
  constructor(fn, pname, toParent) {
37
36
  this.$reflection = {};
37
+ this.messageSubscribers = [];
38
38
  this.current = null;
39
39
  this.buffer = [];
40
40
  this.nextTick = null;
41
41
  this.children = [];
42
42
  this.orphans = [];
43
- this.subscribers = [];
43
+ this.stateSubscribers = [];
44
+ this.pvtOutgoingSubscriptions = [];
44
45
  this.pvtIsPaused = false;
46
+ this.pvtDead = false;
45
47
  this.pvtTickInProgress = false;
46
48
  this.pvtExitReject = null;
47
49
  this.pgenerator = fn;
48
50
  this.pname = pname;
49
- this.toParent = toParent || noop;
51
+ if (toParent) this.messageSubscribers.push(toParent);
50
52
  this.id = Symbol(pname);
51
53
  this.state = null;
52
54
  this.exitWaiter = makeWaiter();
@@ -75,11 +77,13 @@ var AsyncProcess = class AsyncProcess {
75
77
  forkSync: this.forkSync.bind(this),
76
78
  children: this.children,
77
79
  orphans: this.orphans,
80
+ adopt: this.adopt.bind(this),
81
+ monitor: this.monitor.bind(this),
78
82
  sendSelf: (msg) => {
79
83
  this.send([msg, selfCtx]);
80
84
  },
81
85
  toParent: (msg) => {
82
- this.toParent([msg, selfCtx]);
86
+ this.messageSubscribers.forEach((cb) => cb(msg, selfCtx));
83
87
  }
84
88
  };
85
89
  this.current = this.pvtWatchExit(ctx, arg0);
@@ -103,13 +107,13 @@ var AsyncProcess = class AsyncProcess {
103
107
  try {
104
108
  yield* this.pgenerator(ctx, arg0);
105
109
  } finally {
106
- this.toAllChildren({ type: "STOP" });
107
110
  const orphans = [...this.orphans];
111
+ const parentSender = {
112
+ fromName: this.pname,
113
+ fromId: this.id
114
+ };
108
115
  const stopPromises = this.children.map(async (child) => {
109
- try {
110
- await withTimeout(child.wait(), CHILD_STOP_TIMEOUT_MS, "childStop");
111
- } catch (e) {
112
- if (e?.message !== "Timeout:childStop") throw e;
116
+ if (!await child.stop({ from: parentSender })) {
113
117
  orphans.push(child);
114
118
  console.warn(`posipaki: child "${child.pname}" did not stop within ${CHILD_STOP_TIMEOUT_MS}ms; continuing shutdown`);
115
119
  }
@@ -119,13 +123,15 @@ var AsyncProcess = class AsyncProcess {
119
123
  type: "EXIT",
120
124
  orphans
121
125
  });
126
+ for (const unsub of this.pvtOutgoingSubscriptions) unsub();
127
+ this.pvtOutgoingSubscriptions = [];
122
128
  if (ctx.afterExit) await ctx.afterExit();
123
129
  }
124
130
  }
125
131
  fork(fn, pname) {
126
132
  return (args) => {
127
- const child = new AsyncProcess(fn, pname, this.fromChild.bind(this));
128
- this.children.push(child);
133
+ const child = new AsyncProcess(fn, pname);
134
+ this.adopt(child);
129
135
  child.start(args, this.pname, this.id);
130
136
  return child;
131
137
  };
@@ -180,6 +186,7 @@ var AsyncProcess = class AsyncProcess {
180
186
  this.children.forEach((p) => p.send([msg, stamp]));
181
187
  }
182
188
  send(msgOrTuple, from) {
189
+ if (this.pvtDead) return;
183
190
  if ("type" in msgOrTuple) this.buffer.push([msgOrTuple, from]);
184
191
  else this.buffer.push(msgOrTuple);
185
192
  this.pvtScheduleTick();
@@ -194,7 +201,7 @@ var AsyncProcess = class AsyncProcess {
194
201
  this.nextTick = null;
195
202
  }
196
203
  pvtScheduleTick() {
197
- if (this.pvtIsPaused) return;
204
+ if (this.pvtIsPaused || this.pvtDead) return;
198
205
  this.nextTick?.cancel();
199
206
  this.nextTick = defer(() => {
200
207
  this.nextTick = null;
@@ -202,19 +209,32 @@ var AsyncProcess = class AsyncProcess {
202
209
  });
203
210
  }
204
211
  notify() {
205
- this.subscribers.forEach((f) => f());
212
+ this.stateSubscribers.forEach((f) => f());
206
213
  }
207
214
  get isListenedTo() {
208
- return this.subscribers.length > 0;
209
- }
210
- subscribe(f) {
211
- this.subscribers.push(f);
212
- return () => {
213
- const idx = this.subscribers.indexOf(f);
214
- if (idx < 0) return;
215
- this.subscribers.splice(idx, 1);
216
- };
215
+ return this.stateSubscribers.length > 0;
216
+ }
217
+ subscribe(channelOrCb, cb) {
218
+ if (typeof channelOrCb === "function") return this.subscribe("state", channelOrCb);
219
+ if (channelOrCb === "message") {
220
+ const fn = cb;
221
+ this.messageSubscribers.push(fn);
222
+ return () => this.pvtUnsubscribe(this.messageSubscribers, fn);
223
+ }
224
+ const fn = cb;
225
+ this.stateSubscribers.push(fn);
226
+ return () => this.pvtUnsubscribe(this.stateSubscribers, fn);
227
+ }
228
+ pvtUnsubscribe(list, fn) {
229
+ const idx = list.indexOf(fn);
230
+ if (idx >= 0) list.splice(idx, 1);
217
231
  }
232
+ /**
233
+ * Freeze dispatch: no further ticks are scheduled, so the process stops
234
+ * *processing* incoming messages. This is half-working as a "quiesce"
235
+ * primitive — it does not stop the process from *emitting* via async
236
+ * callbacks (timers, fetch) that bypass the dispatch loop.
237
+ */
218
238
  pause() {
219
239
  this.nextTick?.cancel();
220
240
  this.nextTick = null;
@@ -225,6 +245,79 @@ var AsyncProcess = class AsyncProcess {
225
245
  this.pvtScheduleTick();
226
246
  }
227
247
  /**
248
+ * Hard-kill this process: abandon the generator without running its
249
+ * `finally` (no EXIT, no STOP cascade), drop the inbox and observers,
250
+ * unsubscribe from children/monitors, and settle `wait()`/`ready()`.
251
+ *
252
+ * There is nothing to observe afterward — callers remove the process from
253
+ * their `children`/`orphans` lists imperatively. Does not cascade to this
254
+ * process's own children; they are abandoned (force-stop them separately if
255
+ * owned).
256
+ *
257
+ * Best-effort: an idle generator (suspended at `yield`) is abandoned
258
+ * cleanly; a generator mid-`await` completes its `finally` when that await
259
+ * settles, because JS offers no way to cancel a pending promise.
260
+ */
261
+ forceStop(opts) {
262
+ if (this.pvtDead) return;
263
+ this.pvtDead = true;
264
+ this.current = null;
265
+ this.buffer.length = 0;
266
+ this.nextTick?.cancel();
267
+ this.nextTick = null;
268
+ this.messageSubscribers.length = 0;
269
+ this.stateSubscribers.length = 0;
270
+ for (const unsub of this.pvtOutgoingSubscriptions) unsub();
271
+ this.pvtOutgoingSubscriptions = [];
272
+ this.pvtResolveReady();
273
+ this.exitWaiter.resolve();
274
+ this.pvtExitReject = null;
275
+ if (opts?.cascade) {
276
+ const selfSender = {
277
+ fromName: this.pname,
278
+ fromId: this.id
279
+ };
280
+ for (const child of this.children) child.stop({
281
+ force: true,
282
+ from: selfSender
283
+ }).catch(() => {});
284
+ }
285
+ }
286
+ /**
287
+ * Stop this process. Sends STOP (the nice way — the generator cooperates
288
+ * and its `finally` runs) and awaits on a best-effort basis.
289
+ *
290
+ * With `{ force: true }`, when the process refuses (does not exit within the
291
+ * timeout) it escalates: fires `generator.return()` *without awaiting* (throw
292
+ * the generator away for GC to find), cascades to children with the same
293
+ * ladder, then hard-kills itself.
294
+ *
295
+ * Resolves `true` if the process stopped (gracefully or forced), `false` if
296
+ * it refused and `force` was not requested.
297
+ */
298
+ async stop(opts) {
299
+ if (this.pvtDead) return true;
300
+ this.send({ type: "STOP" }, opts?.from);
301
+ try {
302
+ await withTimeout(this.wait(), CHILD_STOP_TIMEOUT_MS, "stop");
303
+ return true;
304
+ } catch (e) {
305
+ if (e?.message !== "Timeout:stop") throw e;
306
+ }
307
+ if (!opts?.force) return false;
308
+ this.current?.return(void 0);
309
+ const selfSender = {
310
+ fromName: this.pname,
311
+ fromId: this.id
312
+ };
313
+ await Promise.all([...this.children].map((child) => child.stop({
314
+ force: true,
315
+ from: selfSender
316
+ })));
317
+ this.forceStop();
318
+ return true;
319
+ }
320
+ /**
228
321
  * Returns a promise that resolves when the generator completes, or
229
322
  * rejects if an unhandled error occurs during message processing.
230
323
  */
@@ -240,16 +333,40 @@ var AsyncProcess = class AsyncProcess {
240
333
  });
241
334
  });
242
335
  }
243
- /** Relays a child's message to this process. The message already carries
244
- * sender provenance (stamped by the child's `ctx.toParent` wrapper). */
245
- fromChild(msgAndSender) {
246
- const [msg, sender] = msgAndSender;
336
+ /**
337
+ * Tap another process's message channel: every message it emits is fed
338
+ * into this process's incoming queue. No ownership — the sender's EXIT
339
+ * does not touch `children`/`orphans`.
340
+ */
341
+ monitor(child) {
342
+ const unsub = child.subscribe("message", (msg, from) => {
343
+ this.send([msg, from]);
344
+ });
345
+ this.pvtOutgoingSubscriptions.push(unsub);
346
+ return unsub;
347
+ }
348
+ /**
349
+ * Claim another process as a child: its messages are routed here and its
350
+ * EXIT removes it from `children` (collecting its orphans). Generalizes
351
+ * what `fork` does — used for both spawning and orphan adoption.
352
+ */
353
+ adopt(child) {
354
+ this.children.push(child);
355
+ const unsub = child.subscribe("message", (msg, from) => {
356
+ this.pvtChildMessage(msg, from);
357
+ });
358
+ this.pvtOutgoingSubscriptions.push(unsub);
359
+ return unsub;
360
+ }
361
+ /** Handles a child's emitted message: EXIT cleanup + forward to the queue. */
362
+ pvtChildMessage(msg, sender) {
247
363
  if (msg.type === "EXIT") {
248
- this.children = this.children.filter((p) => p.id !== sender.fromId);
364
+ const idx = this.children.findIndex((p) => p.id === sender.fromId);
365
+ if (idx >= 0) this.children.splice(idx, 1);
249
366
  const orphans = msg.orphans;
250
367
  if (orphans && orphans.length > 0) this.orphans.push(...orphans);
251
368
  }
252
- this.send(msgAndSender);
369
+ this.send([msg, sender]);
253
370
  }
254
371
  };
255
372
  /**
@@ -437,4 +554,4 @@ function defineActor(config) {
437
554
  //#endregion
438
555
  export { AsyncProcess as a, asyncify as c, spawn as i, defineMessages as n, runDispatchAsync as o, Process as r, spawnAsync as s, defineActor as t };
439
556
 
440
- //# sourceMappingURL=src-DeIF0clC.js.map
557
+ //# sourceMappingURL=src-fhiwGw91.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"src-fhiwGw91.js","names":[],"sources":["../src/adapters.ts","../src/process.async.ts","../src/process.ts","../src/define-actor.ts","../src/index.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<\n ProcessState,\n InMessage extends Message,\n> = 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\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<\n AsyncProcess<unknown, unknown, Message, Message, {}>\n > = [];\n /** Children inherited from a child that exited (see ctx-orphans proposal). */\n orphans: Array<\n AsyncProcess<unknown, unknown, Message, Message, {}>\n > = [];\n private stateSubscribers: Array<NotifyFn> = [];\n /** Unsubscribe handles for outgoing message subscriptions (adopt/monitor). */\n private pvtOutgoingSubscriptions: Array<() => void> = [];\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 /** 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 ctx.toParent({ type: \"EXIT\", orphans });\n // Unsubscribe from children/monitored processes so a dead parent\n // doesn't keep receiving their messages.\n for (const unsub of this.pvtOutgoingSubscriptions) unsub();\n this.pvtOutgoingSubscriptions = [];\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 ): (\n args: ChildArgs,\n ) => AsyncProcess<ChildArgs, ChildState, ChildIM, ChildOM, {}> {\n return (args: ChildArgs) => {\n const child = new AsyncProcess<\n ChildArgs,\n ChildState,\n ChildIM,\n ChildOM,\n {}\n >(fn, pname);\n this.adopt(child);\n child.start(args, this.pname, this.id);\n return child;\n };\n }\n\n forkSync<\n ChildArgs,\n ChildState,\n ChildIM extends Message,\n ChildOM extends InMessage,\n >(\n fn: ProcessFn<ChildArgs, ChildState, ChildIM, ChildOM>,\n pname: string,\n ): (\n args: ChildArgs,\n ) => 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:\n | IteratorResult<State | null, void>\n | Promise<IteratorResult<State | null, void>>\n | 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([\n msgOrTuple as InMessage | StopMessage,\n from as SenderInfo,\n ]);\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 for (const unsub of this.pvtOutgoingSubscriptions) unsub();\n this.pvtOutgoingSubscriptions = [];\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.pvtOutgoingSubscriptions.push(unsub);\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}\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): (args: Args) => AsyncProcess<Args, State, InMessage, OutMessage, {}> {\n return (args: Args) => {\n const proc = new AsyncProcess<Args, State, InMessage, OutMessage, {}>(\n fn,\n pname,\n toParent,\n );\n proc.start(args);\n return proc;\n };\n}\n","import { AsyncProcess } from \"./process.async.js\";\nimport { asyncify } from \"./adapters.js\";\nimport type { Message, SenderInfo, ExitMessage, ProcessFn } from \"./types.js\";\n\nexport type { Message, ProcessFn, ProcessCtx } from \"./types.js\";\nexport { runDispatch } from \"./util.js\";\n\n/** @deprecated Use {@link spawnAsync} instead. */\nexport function spawn<\n A,\n S,\n IM extends Message = Message,\n OM extends Message = ExitMessage,\n>(\n fn: ProcessFn<A, S, IM, OM>,\n pname: string,\n tp?: (m: OM, from: SenderInfo) => void,\n): (a: A) => Process<A, S, IM, OM> {\n return (a: A) => new Process(fn, pname, tp).start(a);\n}\n\n/** @deprecated Use {@link AsyncProcess} instead. Sync processes are\n * wrapped via asyncify internally; spawnAsync handles both. */\nclass Process<\n A,\n S,\n IM extends Message,\n OM extends Message,\n> extends AsyncProcess<A, S, IM, OM, {}> {\n constructor(\n fn: ProcessFn<A, S, IM, OM>,\n pname: string,\n tp?: (m: OM, from: SenderInfo) => void,\n ) {\n super(asyncify(fn), pname, tp);\n }\n\n start(a: A) {\n super.start(a);\n return this;\n }\n tick(): Promise<void> {\n return super.pvtTick();\n }\n}\n\nexport { Process };\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} 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 {\n ActorDecorated,\n type ActorPlugin,\n ActorReflection,\n callHook,\n} from \"./hooks.js\";\n\nexport function defineMessages<\n OutMsg extends Message = Message,\n>(): ActorMessages<OutMsg> {\n return undefined as unknown as ActorMessages<OutMsg>;\n}\n\nfunction hidePrivate<T>(value: T): HidePrivate<T> {\n if (\n value &&\n typeof value === \"object\" &&\n \"private\" in value &&\n \"public\" in value\n ) {\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 =\n !raw ? (parentPlugins ? [...parentPlugins] : [])\n : Array.isArray(raw) ? [...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>(config: C, plugins: ActorPlugin[], addPlugins?: ActorPlugin[]): 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(\n `[assembleActor] plugin \"${p.name || \"?\"}\" failed:`,\n e,\n );\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<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods\n >,\n): ActorDefinition<Args, InternalState, InMsg, OutMsg, ReflectionMethods> {\n const actorCtxMap = new Map<\n symbol,\n ActorContext<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods\n >\n >();\n\n function makeRuntime(\n assembly: ActorConfig<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods\n >,\n ): AsyncProcessFn<Args, HidePrivate<InternalState>, InMsg, OutMsg> {\n return async function* (\n ctx,\n args,\n ): AsyncGenerator<\n HidePrivate<InternalState | null>,\n void,\n WithSender<InMsg>\n > {\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 <\n A,\n S,\n IM extends Message,\n OM extends InMsg,\n R extends ReflectionOptions,\n >(\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 ??\n childActor?.name ??\n `child-${Object.keys(self.$child).length}`;\n const treeName = `${ctx.pname}:${childName}`;\n const childAddPlugins = [\n ...(assembly.addPlugins || []),\n ...(forkOpts?.addPlugins || []),\n ];\n child = await childActor.spawnAsChild(\n ctx,\n childArgs!,\n {\n name: treeName,\n parentPlugins: assembly.resolvedPlugins || [],\n ...(childAddPlugins.length ? { addPlugins: childAddPlugins } : {}),\n },\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 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 }\n let hookStopped = false;\n if (\n msg.type !== \"STOP\" &&\n msg.type !== \"EXIT\" &&\n assembly.onMessage\n ) {\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(\n handler,\n assembly.onError,\n self,\n msg as InMsg,\n sender,\n );\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 },\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(runtime, opts?.name ?? assembly.name ?? \"actor\", opts?.toParent)(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","/**\n * Posipaki — Erlang-inspired lightweight actor processes built on\n * generator functions. Processes communicate via message-passing,\n * can fork children, and expose their state reactively.\n *\n * @module\n */\n\nimport { Process, spawn } from \"./process.js\";\nimport { runDispatch } from \"./util.js\";\nimport { AsyncProcess, spawnAsync, runDispatchAsync } from \"./process.async.js\";\nimport { asyncify } from \"./adapters.js\";\n\nexport { Process, spawn, runDispatch };\nexport { AsyncProcess, spawnAsync, runDispatchAsync, asyncify };\nexport type { AnyProcess } from \"./process.async.js\";\n\nexport type {\n Message,\n WithSender,\n WithoutSender,\n ExitMessage,\n StopMessage,\n ProcessFn,\n ProcessCtx,\n AsyncProcessFn,\n PipeState,\n SupervisorState,\n SenderOrigin,\n SenderInfo,\n} from \"./types.js\";\n\nexport { defineActor, defineMessages } from \"./define-actor.js\";\nexport type {\n ActorDefinition,\n SpawnedFrom,\n ActorConfig,\n ActorContext,\n MethodOptions,\n HandlerOptions,\n HandlerFn,\n} from \"./actor-types.js\";\n\n// ── hooks ─────────────────────────────────────────────────────────────────\n\nexport { stopPropagation, mergeConfigs, chainHook, callHook } from \"./hooks.js\";\nexport type {\n HookResult,\n ActorPlugin,\n ActorDecorated,\n ActorReflection,\n PluginTransform,\n} from \"./hooks.js\";\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { a as ProcessCtx, d as WithSender, n as ExitMessage, o as ProcessFn } from "./types-DYAxWeSM.js";
2
- import { t as Process } from "./process-CECMMHyR.js";
1
+ import { a as ProcessCtx, d as WithSender, n as ExitMessage, o as ProcessFn } from "./types-BzM4YqJj.js";
2
+ import { t as Process } from "./process-YKyZJOvg.js";
3
3
 
4
4
  //#region src/supervisor.d.ts
5
5
  type SupMsg = ExitMessage | RunMsg | StopMsg | ErrorMsg | OkMsg;
@@ -1,5 +1,5 @@
1
- import { r as Message } from "../types-DYAxWeSM.js";
2
- import { d as ActorPlugin } from "../hooks-fgRvVnDj.js";
1
+ import { r as Message } from "../types-BzM4YqJj.js";
2
+ import { d as ActorPlugin } from "../hooks-D6qtxITh.js";
3
3
 
4
4
  //#region src/testing/msg-matcher.d.ts
5
5
  type Matcher<M extends Message> = (msg: M, history: M[]) => boolean;
@@ -8,7 +8,9 @@ type ReadyFn = () => boolean;
8
8
  * returns true.
9
9
  */
10
10
  declare function runDispatchAsync<M>(name: string, fn: AsyncReducer<M>, readyFn?: ReadyFn, debugLevel?: boolean): AsyncGenerator<null, void, M>;
11
- type ProcessMessageCb$1<M> = (msg: M) => void;
11
+ /** A subscriber to this process's message channel: receives the message and
12
+ * its sender separately (not a `WithSender` tuple). */
13
+ type MessageCallback<M extends Message> = (msg: M, from: SenderInfo) => void;
12
14
  /**
13
15
  * A process driven by an async generator. Functionally identical to
14
16
  * {@link Process} but supports `await` inside reducers.
@@ -22,8 +24,8 @@ declare class AsyncProcess<Args, State, InMessage extends Message, OutMessage ex
22
24
  $reflection: ReflectionMethods;
23
25
  pgenerator: AsyncProcessFn<Args, State, InMessage, OutMessage>;
24
26
  pname: string;
25
- /** Called for every message sent via `ctx.toParent`. Receives `WithSender<OutMessage>`. */
26
- toParent: ProcessMessageCb$1<WithSender<OutMessage>>;
27
+ /** Subscribers to this process's message channel (`ctx.toParent`). */
28
+ private messageSubscribers;
27
29
  id: symbol;
28
30
  state: State | null;
29
31
  private current;
@@ -34,14 +36,17 @@ declare class AsyncProcess<Args, State, InMessage extends Message, OutMessage ex
34
36
  children: Array<AsyncProcess<unknown, unknown, Message, Message, {}>>;
35
37
  /** Children inherited from a child that exited (see ctx-orphans proposal). */
36
38
  orphans: Array<AsyncProcess<unknown, unknown, Message, Message, {}>>;
37
- private subscribers;
39
+ private stateSubscribers;
40
+ /** Unsubscribe handles for outgoing message subscriptions (adopt/monitor). */
41
+ private pvtOutgoingSubscriptions;
38
42
  private exitWaiter;
39
43
  private pvtIsPaused;
44
+ private pvtDead;
40
45
  private pvtTickInProgress;
41
46
  private pvtExitReject;
42
47
  private pvtReady;
43
48
  private pvtResolveReady;
44
- constructor(fn: AsyncProcessFn<Args, State, InMessage, OutMessage>, pname: string, toParent: ProcessMessageCb$1<WithSender<OutMessage>> | undefined);
49
+ constructor(fn: AsyncProcessFn<Args, State, InMessage, OutMessage>, pname: string, toParent?: MessageCallback<OutMessage>);
45
50
  /** Promise that resolves once the initial state is available. */
46
51
  ready(): Promise<void>;
47
52
  /**
@@ -72,24 +77,78 @@ declare class AsyncProcess<Args, State, InMessage extends Message, OutMessage ex
72
77
  private pvtScheduleTick;
73
78
  notify(): void;
74
79
  get isListenedTo(): boolean;
75
- subscribe(f: NotifyFn): () => void;
80
+ subscribe(channel: "message", cb: MessageCallback<OutMessage>): () => void;
81
+ subscribe(channel: "state", cb: NotifyFn): () => void;
82
+ /** @deprecated Use `subscribe("state", cb)`. */
83
+ subscribe(cb: NotifyFn): () => void;
84
+ private pvtUnsubscribe;
85
+ /**
86
+ * Freeze dispatch: no further ticks are scheduled, so the process stops
87
+ * *processing* incoming messages. This is half-working as a "quiesce"
88
+ * primitive — it does not stop the process from *emitting* via async
89
+ * callbacks (timers, fetch) that bypass the dispatch loop.
90
+ */
76
91
  pause(): void;
77
92
  resume(): void;
93
+ /**
94
+ * Hard-kill this process: abandon the generator without running its
95
+ * `finally` (no EXIT, no STOP cascade), drop the inbox and observers,
96
+ * unsubscribe from children/monitors, and settle `wait()`/`ready()`.
97
+ *
98
+ * There is nothing to observe afterward — callers remove the process from
99
+ * their `children`/`orphans` lists imperatively. Does not cascade to this
100
+ * process's own children; they are abandoned (force-stop them separately if
101
+ * owned).
102
+ *
103
+ * Best-effort: an idle generator (suspended at `yield`) is abandoned
104
+ * cleanly; a generator mid-`await` completes its `finally` when that await
105
+ * settles, because JS offers no way to cancel a pending promise.
106
+ */
107
+ forceStop(opts?: {
108
+ cascade?: boolean;
109
+ }): void;
110
+ /**
111
+ * Stop this process. Sends STOP (the nice way — the generator cooperates
112
+ * and its `finally` runs) and awaits on a best-effort basis.
113
+ *
114
+ * With `{ force: true }`, when the process refuses (does not exit within the
115
+ * timeout) it escalates: fires `generator.return()` *without awaiting* (throw
116
+ * the generator away for GC to find), cascades to children with the same
117
+ * ladder, then hard-kills itself.
118
+ *
119
+ * Resolves `true` if the process stopped (gracefully or forced), `false` if
120
+ * it refused and `force` was not requested.
121
+ */
122
+ stop(opts?: {
123
+ force?: boolean;
124
+ from?: SenderInfo;
125
+ }): Promise<boolean>;
78
126
  /**
79
127
  * Returns a promise that resolves when the generator completes, or
80
128
  * rejects if an unhandled error occurs during message processing.
81
129
  */
82
130
  wait(): Promise<void>;
83
- /** Relays a child's message to this process. The message already carries
84
- * sender provenance (stamped by the child's `ctx.toParent` wrapper). */
85
- private fromChild;
131
+ /**
132
+ * Tap another process's message channel: every message it emits is fed
133
+ * into this process's incoming queue. No ownership — the sender's EXIT
134
+ * does not touch `children`/`orphans`.
135
+ */
136
+ monitor<ChildArgs, ChildState, ChildIM extends Message, ChildOM extends Message>(child: AsyncProcess<ChildArgs, ChildState, ChildIM, ChildOM, {}>): () => void;
137
+ /**
138
+ * Claim another process as a child: its messages are routed here and its
139
+ * EXIT removes it from `children` (collecting its orphans). Generalizes
140
+ * what `fork` does — used for both spawning and orphan adoption.
141
+ */
142
+ adopt<ChildArgs, ChildState, ChildIM extends Message, ChildOM extends Message>(child: AsyncProcess<ChildArgs, ChildState, ChildIM, ChildOM, {}>): () => void;
143
+ /** Handles a child's emitted message: EXIT cleanup + forward to the queue. */
144
+ private pvtChildMessage;
86
145
  }
87
146
  type AnyProcess = AsyncProcess<unknown, unknown, Message, Message, {}>;
88
147
  /**
89
148
  * Spawn a new async process. Accepts both sync and async process
90
149
  * functions — sync ones are automatically wrapped with {@link asyncify}.
91
150
  */
92
- declare function spawnAsync<Args, State, InMessage extends Message = Message, OutMessage extends Message = ExitMessage>(fn: AsyncProcessFn<Args, State, InMessage, OutMessage>, pname: string, toParent?: ProcessMessageCb$1<WithSender<OutMessage>>): (args: Args) => AsyncProcess<Args, State, InMessage, OutMessage, {}>;
151
+ declare function spawnAsync<Args, State, InMessage extends Message = Message, OutMessage extends Message = ExitMessage>(fn: AsyncProcessFn<Args, State, InMessage, OutMessage>, pname: string, toParent?: MessageCallback<OutMessage>): (args: Args) => AsyncProcess<Args, State, InMessage, OutMessage, {}>;
93
152
  //#endregion
94
153
  //#region src/types.d.ts
95
154
  /** Base message type. All messages must include a `type` field
@@ -138,7 +197,7 @@ type ProcessCtx<Args, State, IM extends Message, OM extends Message> = {
138
197
  /** Invoked by the runtime after the process emits EXIT to its parent.
139
198
  * Best-effort teardown that must not delay the exit signal. */
140
199
  afterExit?: () => Promise<void> | void;
141
- } & Pick<AsyncProcess<Args, State, IM, OM, {}>, "fork" | "forkSync" | "children" | "orphans">;
200
+ } & Pick<AsyncProcess<Args, State, IM, OM, {}>, "fork" | "forkSync" | "children" | "orphans" | "adopt" | "monitor">;
142
201
  /** State yielded by the pipe process. */
143
202
  interface PipeState<Params, Result> {
144
203
  params: Params | null;
@@ -152,4 +211,4 @@ interface SupervisorState {
152
211
  }
153
212
  //#endregion
154
213
  export { ProcessCtx as a, SenderOrigin as c, WithSender as d, WithoutSender as f, spawnAsync as g, runDispatchAsync as h, PipeState as i, StopMessage as l, AsyncProcess as m, ExitMessage as n, ProcessFn as o, AnyProcess as p, Message as r, SenderInfo as s, AsyncProcessFn as t, SupervisorState as u };
155
- //# sourceMappingURL=types-DYAxWeSM.d.ts.map
214
+ //# sourceMappingURL=types-BzM4YqJj.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-BzM4YqJj.d.ts","names":[],"sources":["../src/process.async.ts","../src/types.ts"],"mappings":";KA0BK,QAAA;AAAA,KAIA,YAAA,OAAmB,GAAA,EAAK,CAAA,KAAM,OAAO;AAAA,KACrC,OAAA;;AALQ;AAAA;;;iBAYU,gBAAA,IACrB,IAAA,UACA,EAAA,EAAI,YAAA,CAAa,CAAA,GACjB,OAAA,GAAS,OAAA,EACT,UAAA,aACC,cAAA,aAA2B,CAAA;;;KAazB,eAAA,WAA0B,OAAA,KAAY,GAAA,EAAK,CAAA,EAAG,IAAA,EAAM,UAAA;;;AA1Bf;AAAA;;;;AAC9B;cAuCC,YAAA,gCAGO,OAAA,qBACC,OAAA;EApCkB;EAwCrC,WAAA,EAAa,iBAAA;EACb,UAAA,EAAY,cAAA,CAAe,IAAA,EAAM,KAAA,EAAO,SAAA,EAAW,UAAA;EACnD,KAAA;EAvCS;EAAA,QAyCD,kBAAA;EACR,EAAA;EACA,KAAA,EAAO,KAAA;EAAA,QAEC,OAAA;EAhD8B;EAAA,QAkD9B,MAAA;EAAA,QACA,QAAA;EAjDS;EAmDjB,QAAA,EAAU,KAAA,CACR,YAAA,mBAA+B,OAAA,EAAS,OAAA;EAnDjC;EAsDT,OAAA,EAAS,KAAA,CACP,YAAA,mBAA+B,OAAA,EAAS,OAAA;EAAA,QAElC,gBAAA;EAvDP;EAAA,QAyDO,wBAAA;EAAA,QACA,UAAA;EAAA,QACA,WAAA;EAAA,QACA,OAAA;EAAA,QACA,iBAAA;EAAA,QACA,aAAA;EAAA,QACA,QAAA;EAAA,QACA,eAAA;cAGN,EAAA,EAAI,cAAA,CAAe,IAAA,EAAM,KAAA,EAAO,SAAA,EAAW,UAAA,GAC3C,KAAA,UACA,QAAA,GAAW,eAAA,CAAgB,UAAA;EAxDoC;EAqEjE,KAAA,IAAS,OAAA;EArEU;;;;EA+EnB,KAAA,CAAM,IAAA,EAAM,IAAA,EAAM,UAAA,kBAA4B,QAAA;EA/EG;EAAA,QA6HlC,YAAA;EAkCf,IAAA,wCAA4C,OAAA,kBAAyB,OAAA,EACnE,EAAA,EAAI,cAAA,CAAe,SAAA,EAAW,UAAA,EAAY,OAAA,EAAS,OAAA,GACnD,KAAA,YAEA,IAAA,EAAM,SAAA,KACH,YAAA,CAAa,SAAA,EAAW,UAAA,EAAY,OAAA,EAAS,OAAA;EAelD,QAAA,wCAGkB,OAAA,kBACA,SAAA,EAEhB,EAAA,EAAI,SAAA,CAAU,SAAA,EAAW,UAAA,EAAY,OAAA,EAAS,OAAA,GAC9C,KAAA,YAEA,IAAA,EAAM,SAAA,KACH,YAAA,CAAa,SAAA,EAAW,UAAA,EAAY,OAAA,EAAS,OAAA;EAAA,UAMlC,OAAA,IAAW,OAAA;EArLJ;EAAA,QA2MT,WAAA;EAAA,QAYN,YAAA;EA/MK;EA8Nb,aAAA,CAAc,GAAA,EAAK,OAAA;EA7Nc;EAmOjC,IAAA,CAAK,GAAA,EAAK,SAAA,GAAY,WAAA,EAAa,IAAA,GAAO,UAAA;EAnOS;EAqOnD,IAAA,CAAK,YAAA,EAAc,UAAA,CAAW,SAAA,GAAY,WAAA;EAhOnC;;;;;EAsPP,IAAA;EAAA,QAKQ,eAAA;EAYR,MAAA;EAAA,IAII,YAAA;EAIJ,SAAA,CAAU,OAAA,aAAoB,EAAA,EAAI,eAAA,CAAgB,UAAA;EAClD,SAAA,CAAU,OAAA,WAAkB,EAAA,EAAI,QAAA;EAtPE;EAwPlC,SAAA,CAAU,EAAA,EAAI,QAAA;EAAA,QAkBN,cAAA;EAxQqB;;;;;;EAqR7B,KAAA;EAMA,MAAA;EAnL4C;;;;;;;;;;;;;;EAsM5C,SAAA,CAAU,IAAA;IAAS,OAAA;EAAA;EAzKD;;;;;;;;;;;;EAsNZ,IAAA,CAAK,IAAA;IAAS,KAAA;IAAiB,IAAA,GAAO,UAAA;EAAA,IAAe,OAAA;EArG7C;;;;EAwId,IAAA,IAAQ,OAAA;EAwBgE;;;;;EAAxE,OAAA,wCAA+C,OAAA,kBAAyB,OAAA,EACtE,KAAA,EAAO,YAAA,CAAa,SAAA,EAAW,UAAA,EAAY,OAAA,EAAS,OAAA;EAcT;;;;;EAA7C,KAAA,wCAA6C,OAAA,kBAAyB,OAAA,EACpE,KAAA,EAAO,YAAA,CAAa,SAAA,EAAW,UAAA,EAAY,OAAA,EAAS,OAAA;EAA7C;EAAA,QAWD,eAAA;AAAA;AAAA,KAcE,UAAA,GAAa,YAAA,mBAA+B,OAAA,EAAS,OAAA;;;;;iBAOjD,UAAA,gCAGI,OAAA,GAAU,OAAA,qBACT,OAAA,GAAU,WAAA,EAE7B,EAAA,EAAI,cAAA,CAAe,IAAA,EAAM,KAAA,EAAO,SAAA,EAAW,UAAA,GAC3C,KAAA,UACA,QAAA,GAAW,eAAA,CAAgB,UAAA,KACzB,IAAA,EAAM,IAAA,KAAS,YAAA,CAAa,IAAA,EAAM,KAAA,EAAO,SAAA,EAAW,UAAA;;;AAriB3C;;AAAA,UCfI,OAAA;EACf,IAAI;AAAA;;UAMW,UAAA;EACf,QAAA;EACA,MAAM;AAAA;ADUkC;;;AAAA,KCF9B,UAAA,WAAqB,OAAA,KAAY,CAAA,EAAG,UAAA;ADGpC;AAAA,KCAA,aAAA,WAAwB,UAAA,SAAmB,CAAC;;;KAM5C,WAAA;EACV,IAAA;EDGS;;ECAT,OAAA,GAAU,KAAK,CAAC,UAAA;AAAA;AAAA,KAGN,WAAA;EACV,IAAI;AAAA;AAAA,KAKM,SAAA,gCAGQ,OAAA,qBACC,OAAA,KAEnB,GAAA,EAAK,UAAA,CAAW,IAAA,EAAM,KAAA,EAAO,SAAA,EAAW,UAAA,GACxC,IAAA,EAAM,IAAA,KACH,SAAA,CAAU,KAAA,eAAoB,UAAA,CAAW,SAAA,GAAY,WAAA;AAAA,KAI9C,cAAA,gCAGQ,OAAA,GAAU,OAAA,qBACT,OAAA,GAAU,OAAA,KAE7B,GAAA,EAAK,UAAA,CAAW,IAAA,EAAM,KAAA,EAAO,SAAA,EAAW,UAAA,GACxC,IAAA,EAAM,IAAA,KACH,cAAA,CAAe,KAAA,eAAoB,UAAA,CAAW,SAAA,GAAY,WAAA;;;KAMnD,YAAA,GACV,UAAA,mBAA6B,OAAA,EAAS,OAAA;AAAA,KAInC,gBAAA,OAAuB,GAAA,EAAK,CAAC;;;AD/BjC;AAAA,KC4DW,UAAA,yBAAmC,OAAA,aAAoB,OAAA;EACjE,KAAA;EACA,EAAA;EACA,UAAA;EACA,QAAA;EACA,QAAA,GAAW,GAAA,EAAK,EAAA,GAAK,WAAA;EACrB,QAAA,EAAU,gBAAA,CAAiB,EAAA;ED5DR;;EC+DnB,SAAA,SAAkB,OAAA;AAAA,IAChB,IAAA,CAAK,YAAA,CAAa,IAAA,EAAM,KAAA,EAAO,EAAA,EAAI,EAAA;;UAMtB,SAAA;EACf,MAAA,EAAQ,MAAA;EACR,MAAA,EAAQ,MAAM;EACd,OAAA;AAAA;;UAMe,eAAA;EACf,SAAA;EACA,KAAK;AAAA"}
package/dist/xfetch.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { a as ProcessCtx, d as WithSender, n as ExitMessage } from "./types-DYAxWeSM.js";
2
- import { t as Process } from "./process-CECMMHyR.js";
1
+ import { a as ProcessCtx, d as WithSender, n as ExitMessage } from "./types-BzM4YqJj.js";
2
+ import { t as Process } from "./process-YKyZJOvg.js";
3
3
 
4
4
  //#region src/xfetch.d.ts
5
5
  /** State of an in-flight or completed fetch. */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "posipaki",
4
- "version": "0.21.0",
4
+ "version": "0.22.0",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
7
7
  "files": [
@@ -1 +0,0 @@
1
- {"version":3,"file":"hooks-fgRvVnDj.d.ts","names":[],"sources":["../src/actor-types.ts","../src/hooks.ts"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"process-CECMMHyR.d.ts","names":[],"sources":["../src/util.ts","../src/process.ts"],"mappings":";;;KAOK,cAAA,OAAqB,GAAA,EAAK,CAAC;AAAA,KAC3B,OAAA;;;;;;iBAQK,WAAA,IACR,IAAA,UACA,EAAA,EAAI,cAAA,CAAe,CAAA,GACnB,OAAA,GAAS,OAAA,EACT,UAAA,aACC,SAAA,aAAsB,CAAA;AAdO;AAAA;;;;AACpB;AACC;;;;;iBCDG,KAAA,kBAGH,OAAA,GAAU,OAAA,aACV,OAAA,GAAU,WAAA,EAErB,EAAA,EAAI,SAAA,CAAU,CAAA,EAAG,CAAA,EAAG,EAAA,EAAI,EAAA,GACxB,KAAA,UACA,EAAA,IAAM,CAAA,EAAG,UAAA,CAAW,EAAA,cAClB,CAAA,EAAG,CAAA,KAAM,OAAA,CAAQ,CAAA,EAAG,CAAA,EAAG,EAAA,EAAI,EAAA;;;cAMzB,OAAA,kBAGO,OAAA,aACA,OAAA,UACH,YAAA,CAAa,CAAA,EAAG,CAAA,EAAG,EAAA,EAAI,EAAA;cAE7B,EAAA,EAAI,SAAA,CAAU,CAAA,EAAG,CAAA,EAAG,EAAA,EAAI,EAAA,GACxB,KAAA,UACA,EAAA,IAAM,CAAA,EAAG,UAAA,CAAW,EAAA;EAKtB,KAAA,CAAM,CAAA,EAAG,CAAA;EAIT,IAAA,IAAQ,OAAA;AAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"src-DeIF0clC.js","names":[],"sources":["../src/adapters.ts","../src/process.async.ts","../src/process.ts","../src/define-actor.ts","../src/index.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<\n ProcessState,\n InMessage extends Message,\n> = 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\ntype ProcessMessageCb<M> = (msg: M) => void;\n\nconst noop = () => null;\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 /** Called for every message sent via `ctx.toParent`. Receives `WithSender<OutMessage>`. */\n toParent: ProcessMessageCb<WithSender<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<\n AsyncProcess<unknown, unknown, Message, Message, {}>\n > = [];\n /** Children inherited from a child that exited (see ctx-orphans proposal). */\n orphans: Array<\n AsyncProcess<unknown, unknown, Message, Message, {}>\n > = [];\n private subscribers: Array<NotifyFn> = [];\n private exitWaiter: Waiter;\n private pvtIsPaused: 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: ProcessMessageCb<WithSender<OutMessage>> | undefined,\n ) {\n this.pgenerator = fn;\n this.pname = pname;\n this.toParent =\n toParent || (noop as ProcessMessageCb<WithSender<OutMessage>>);\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 /** 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 sendSelf: (msg) => {\n this.send([msg, selfCtx]);\n },\n toParent: (msg) => {\n this.toParent([msg, selfCtx] as WithSender<OutMessage>);\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 and await its generator stopping.\n this.toAllChildren({ type: \"STOP\" });\n\n const orphans: Array<AnyProcess> = [...this.orphans];\n const stopPromises = this.children.map(async (child) => {\n try {\n const ret = await withTimeout(child.wait(), CHILD_STOP_TIMEOUT_MS, 'childStop');\n } catch (e) {\n if ((e as Error)?.message !== 'Timeout:childStop') {\n throw e;\n }\n\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 ctx.toParent({ type: \"EXIT\", orphans });\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 ): (\n args: ChildArgs,\n ) => AsyncProcess<ChildArgs, ChildState, ChildIM, ChildOM, {}> {\n return (args: ChildArgs) => {\n const child = new AsyncProcess<\n ChildArgs,\n ChildState,\n ChildIM,\n ChildOM,\n {}\n >(\n fn,\n pname,\n this.fromChild.bind(this) as unknown as ProcessMessageCb<\n WithSender<ChildOM>\n >,\n );\n this.children.push(\n child as unknown as AsyncProcess<\n unknown,\n unknown,\n Message,\n Message,\n {}\n >,\n );\n child.start(args, this.pname, this.id);\n return child;\n };\n }\n\n forkSync<\n ChildArgs,\n ChildState,\n ChildIM extends Message,\n ChildOM extends InMessage,\n >(\n fn: ProcessFn<ChildArgs, ChildState, ChildIM, ChildOM>,\n pname: string,\n ): (\n args: ChildArgs,\n ) => 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:\n | IteratorResult<State | null, void>\n | Promise<IteratorResult<State | null, void>>\n | 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 (\"type\" in msgOrTuple) {\n this.buffer.push([\n msgOrTuple as InMessage | StopMessage,\n from as SenderInfo,\n ]);\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) 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.subscribers.forEach((f) => f());\n }\n\n get isListenedTo(): boolean {\n return this.subscribers.length > 0;\n }\n\n subscribe(f: NotifyFn): () => void {\n this.subscribers.push(f);\n return () => {\n const idx = this.subscribers.indexOf(f);\n if (idx < 0) return;\n this.subscribers.splice(idx, 1);\n };\n }\n\n // ---- pause / resume -------------------------------------------------------\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 // ---- 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 /** Relays a child's message to this process. The message already carries\n * sender provenance (stamped by the child's `ctx.toParent` wrapper). */\n private fromChild(msgAndSender: WithSender<InMessage | StopMessage>): void {\n const [msg, sender] = msgAndSender;\n if (msg.type === \"EXIT\") {\n // sender.fromId === child's id (set by child's ctx.toParent wrapper)\n this.children = this.children.filter((p) => p.id !== sender.fromId);\n const orphans = (msg as ExitMessage).orphans;\n if (orphans && orphans.length > 0) {\n this.orphans.push(...orphans);\n }\n }\n this.send(msgAndSender);\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?: ProcessMessageCb<WithSender<OutMessage>>,\n): (args: Args) => AsyncProcess<Args, State, InMessage, OutMessage, {}> {\n return (args: Args) => {\n const proc = new AsyncProcess<Args, State, InMessage, OutMessage, {}>(\n fn,\n pname,\n toParent,\n );\n proc.start(args);\n return proc;\n };\n}\n","import { AsyncProcess } from \"./process.async.js\";\nimport { asyncify } from \"./adapters.js\";\nimport type { Message, WithSender, ExitMessage, ProcessFn } from \"./types.js\";\n\nexport type { Message, ProcessFn, ProcessCtx } from \"./types.js\";\nexport { runDispatch } from \"./util.js\";\n\n/** @deprecated Use {@link spawnAsync} instead. */\nexport function spawn<\n A,\n S,\n IM extends Message = Message,\n OM extends Message = ExitMessage,\n>(\n fn: ProcessFn<A, S, IM, OM>,\n pname: string,\n tp?: (m: WithSender<OM>) => void,\n): (a: A) => Process<A, S, IM, OM> {\n return (a: A) => new Process(fn, pname, tp).start(a);\n}\n\n/** @deprecated Use {@link AsyncProcess} instead. Sync processes are\n * wrapped via asyncify internally; spawnAsync handles both. */\nclass Process<\n A,\n S,\n IM extends Message,\n OM extends Message,\n> extends AsyncProcess<A, S, IM, OM, {}> {\n constructor(\n fn: ProcessFn<A, S, IM, OM>,\n pname: string,\n tp?: (m: WithSender<OM>) => void,\n ) {\n super(asyncify(fn), pname, tp);\n }\n\n start(a: A) {\n super.start(a);\n return this;\n }\n tick(): Promise<void> {\n return super.pvtTick();\n }\n}\n\nexport { Process };\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} from \"./process.async.js\";\nimport type {\n WithSender,\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 {\n ActorDecorated,\n type ActorPlugin,\n ActorReflection,\n callHook,\n} from \"./hooks.js\";\n\nexport function defineMessages<\n OutMsg extends Message = Message,\n>(): ActorMessages<OutMsg> {\n return undefined as unknown as ActorMessages<OutMsg>;\n}\n\nfunction hidePrivate<T>(value: T): HidePrivate<T> {\n if (\n value &&\n typeof value === \"object\" &&\n \"private\" in value &&\n \"public\" in value\n ) {\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 =\n !raw ? (parentPlugins ? [...parentPlugins] : [])\n : Array.isArray(raw) ? [...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>(config: C, plugins: ActorPlugin[], addPlugins?: ActorPlugin[]): 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(\n `[assembleActor] plugin \"${p.name || \"?\"}\" failed:`,\n e,\n );\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<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods\n >,\n): ActorDefinition<Args, InternalState, InMsg, OutMsg, ReflectionMethods> {\n const actorCtxMap = new Map<\n symbol,\n ActorContext<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods\n >\n >();\n\n function makeRuntime(\n assembly: ActorConfig<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods\n >,\n ): AsyncProcessFn<Args, HidePrivate<InternalState>, InMsg, OutMsg> {\n return async function* (\n ctx,\n args,\n ): AsyncGenerator<\n HidePrivate<InternalState | null>,\n void,\n WithSender<InMsg>\n > {\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 <\n A,\n S,\n IM extends Message,\n OM extends InMsg,\n R extends ReflectionOptions,\n >(\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 ??\n childActor?.name ??\n `child-${Object.keys(self.$child).length}`;\n const treeName = `${ctx.pname}:${childName}`;\n const childAddPlugins = [\n ...(assembly.addPlugins || []),\n ...(forkOpts?.addPlugins || []),\n ];\n child = await childActor.spawnAsChild(\n ctx,\n childArgs!,\n {\n name: treeName,\n parentPlugins: assembly.resolvedPlugins || [],\n ...(childAddPlugins.length ? { addPlugins: childAddPlugins } : {}),\n },\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 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 }\n let hookStopped = false;\n if (\n msg.type !== \"STOP\" &&\n msg.type !== \"EXIT\" &&\n assembly.onMessage\n ) {\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(\n handler,\n assembly.onError,\n self,\n msg as InMsg,\n sender,\n );\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: WithSender<OutMsg>) => void;\n addPlugins?: ActorPlugin[];\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(runtime, opts?.name ?? assembly.name ?? \"actor\", opts?.toParent)(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","/**\n * Posipaki — Erlang-inspired lightweight actor processes built on\n * generator functions. Processes communicate via message-passing,\n * can fork children, and expose their state reactively.\n *\n * @module\n */\n\nimport { Process, spawn } from \"./process.js\";\nimport { runDispatch } from \"./util.js\";\nimport { AsyncProcess, spawnAsync, runDispatchAsync } from \"./process.async.js\";\nimport { asyncify } from \"./adapters.js\";\n\nexport { Process, spawn, runDispatch };\nexport { AsyncProcess, spawnAsync, runDispatchAsync, asyncify };\nexport type { AnyProcess } from \"./process.async.js\";\n\nexport type {\n Message,\n WithSender,\n WithoutSender,\n ExitMessage,\n StopMessage,\n ProcessFn,\n ProcessCtx,\n AsyncProcessFn,\n PipeState,\n SupervisorState,\n SenderOrigin,\n SenderInfo,\n} from \"./types.js\";\n\nexport { defineActor, defineMessages } from \"./define-actor.js\";\nexport type {\n ActorDefinition,\n SpawnedFrom,\n ActorConfig,\n ActorContext,\n MethodOptions,\n HandlerOptions,\n HandlerFn,\n} from \"./actor-types.js\";\n\n// ── hooks ─────────────────────────────────────────────────────────────────\n\nexport { stopPropagation, mergeConfigs, chainHook, callHook } from \"./hooks.js\";\nexport type {\n HookResult,\n ActorPlugin,\n ActorDecorated,\n ActorReflection,\n PluginTransform,\n} from \"./hooks.js\";\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types-DYAxWeSM.d.ts","names":[],"sources":["../src/process.async.ts","../src/types.ts"],"mappings":"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"}