posipaki 0.37.1 → 0.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{client-Cg_MlE0m.d.ts → client-C5QmGQ6G.d.ts} +14 -4
- package/dist/{client-Cg_MlE0m.d.ts.map → client-C5QmGQ6G.d.ts.map} +1 -1
- package/dist/define-actor-jG-OgJng.js +196 -0
- package/dist/define-actor-jG-OgJng.js.map +1 -0
- package/dist/{hooks-gmAsdJBN.d.ts → hooks-C5S7GIX_.d.ts} +6 -3
- package/dist/hooks-C5S7GIX_.d.ts.map +1 -0
- package/dist/hooks-CgXhmY4r.js.map +1 -1
- package/dist/hooks.d.ts +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/{json1-DYq9g7im.js → json1-CPFT4wEX.js} +206 -6
- package/dist/json1-CPFT4wEX.js.map +1 -0
- package/dist/plugins/debug-logger.d.ts +2 -2
- package/dist/plugins/tree-introspection.d.ts +24 -4
- package/dist/plugins/tree-introspection.d.ts.map +1 -1
- package/dist/plugins/tree-introspection.js +47 -4
- package/dist/plugins/tree-introspection.js.map +1 -1
- package/dist/{process-DjRQSZef.d.ts → process-RsCsXWC1.d.ts} +2 -2
- package/dist/{process-DjRQSZef.d.ts.map → process-RsCsXWC1.d.ts.map} +1 -1
- package/dist/{define-actor-CZysIKH4.js → process.async-js1t-fd8.js} +3 -186
- package/dist/process.async-js1t-fd8.js.map +1 -0
- package/dist/remote/index.d.ts +71 -5
- package/dist/remote/index.d.ts.map +1 -1
- package/dist/remote/index.js +2 -2
- package/dist/remote/node.d.ts +3 -3
- package/dist/remote/node.js +2 -2
- package/dist/testing/index.d.ts +2 -2
- package/dist/{types-DDc-stle.d.ts → types-BuI2bfi4.d.ts} +9 -1
- package/dist/{types-DDc-stle.d.ts.map → types-BuI2bfi4.d.ts.map} +1 -1
- package/dist/{version-98a9sol-.js → version-C-ToFw8V.js} +2 -2
- package/dist/{version-98a9sol-.js.map → version-C-ToFw8V.js.map} +1 -1
- package/dist/xfetch.d.ts +2 -2
- package/package.json +1 -1
- package/dist/define-actor-CZysIKH4.js.map +0 -1
- package/dist/hooks-gmAsdJBN.d.ts.map +0 -1
- package/dist/json1-DYq9g7im.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as Message } from "./types-
|
|
2
|
-
import { h as MethodOptions, l as ActorDefinition, p as HandlerOptions, v as ReflectionOptions } from "./hooks-
|
|
1
|
+
import { r as Message } from "./types-BuI2bfi4.js";
|
|
2
|
+
import { h as MethodOptions, l as ActorDefinition, p as HandlerOptions, v as ReflectionOptions } from "./hooks-C5S7GIX_.js";
|
|
3
3
|
//#region src/remote/channel.d.ts
|
|
4
4
|
interface StringTransport {
|
|
5
5
|
send(frame: string): void | Promise<void>;
|
|
@@ -54,7 +54,17 @@ declare function isRelease(msg: Record<string, unknown>): msg is {
|
|
|
54
54
|
//#endregion
|
|
55
55
|
//#region src/remote/client.d.ts
|
|
56
56
|
type ClientSpawner<Args> = (args: Args) => Promise<Channel>;
|
|
57
|
+
/**
|
|
58
|
+
* Why a proxy ends when the wire under it goes.
|
|
59
|
+
*
|
|
60
|
+
* The far side is *unreachable*, which is not the same as ended: the handles that came across are
|
|
61
|
+
* still here and still readable, and what the far process left behind is still what it left behind.
|
|
62
|
+
* But nothing it says can arrive and nothing here can reach it, and that is news of its own — so the
|
|
63
|
+
* proxy ends with this reason rather than sitting there silent. Whoever forked the proxy hears it
|
|
64
|
+
* where it hears everything else about a child, in `onChildExit`.
|
|
65
|
+
*/
|
|
66
|
+
declare const CHANNEL_LOST = "channel-lost";
|
|
57
67
|
declare function remoteClient<Args, State, InMsg extends Message, OutMsg extends Message, Methods extends MethodOptions = MethodOptions, Handlers extends HandlerOptions<InMsg> = HandlerOptions<InMsg>, R extends ReflectionOptions = ReflectionOptions>(name: string, spawner: ClientSpawner<Args>): ActorDefinition<Args, State, InMsg, OutMsg, R>;
|
|
58
68
|
//#endregion
|
|
59
|
-
export {
|
|
60
|
-
//# sourceMappingURL=client-
|
|
69
|
+
export { StreamKind as a, isInit as c, isProto as d, isRelease as f, isStop as h, Channel as i, isMsg as l, isState as m, ClientSpawner as n, StringTransport as o, isResume as p, remoteClient as r, isExit as s, CHANNEL_LOST as t, isPause as u };
|
|
70
|
+
//# sourceMappingURL=client-C5QmGQ6G.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-
|
|
1
|
+
{"version":3,"file":"client-C5QmGQ6G.d.ts","names":[],"sources":["../src/remote/channel.ts","../src/remote/client.ts"],"mappings":";;;UAgBiB;EACf,KAAK,uBAAuB;EAC5B,UAAU,UAAU;EACpB;;EAEA,QAAQ;EACR,SAAS;;UAGM;EACf,KAAK,OAAO,iCAAiC;EAC7C,UAAU,UAAU,OAAO;EAC3B;;EAEA,QAAQ;EACR,SAAS;;iBA6CK,QAAQ,KAAK,0BAA0B;EAAS;;iBAGhD,OAAO,KAAK,0BAA0B;EAAS,OAAO;;iBAGtD,QAAQ,KAAK,0BAA0B;EAAS,QAAQ;;iBAGxD,MACd,KAAK,0BACJ;EAAS;IAAQ;IAAkB,MAAM;;;iBAG5B,OACd,KAAK,0BACJ;EAAS;IAAS;IAAc;;;KAavB;iBA+BI,OAAO,KAAK,0BAA0B;EAAS,OAAO;;iBAGtD,QAAQ,KAAK,0BAA0B;EAAS,QAAQ;;iBAGxD,SAAS,KAAK,0BAA0B;EAAS,SAAS;;iBAG1D,UAAU,KAAK,0BAA0B;EAAS,UAAU;;;;KCtGhE,cAAc,SAAS,MAAM,SAAS,QAAQ;;;;;;;;;;cAY7C;iBAEG,aACd,MACA,OACA,cAAc,SACd,eAAe,SACf,gBAAgB,gBAAgB,eAChC,iBAAiB,eAAe,SAAS,eAAe,QACxD,UAAU,oBAAoB,mBAE9B,cACA,SAAS,cAAc,QACtB,gBAAgB,MAAM,OAAO,OAAO,QAAQ"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { a as spawnAsync, i as runDispatchAsync } from "./process.async-js1t-fd8.js";
|
|
2
|
+
import { a as STOP_SENTINEL, i as PROPAGATE_SENTINEL, t as callHook } from "./hooks-CgXhmY4r.js";
|
|
3
|
+
//#region src/define-actor.ts
|
|
4
|
+
function defineMessages() {}
|
|
5
|
+
function hidePrivate(value) {
|
|
6
|
+
if (value && typeof value === "object" && "private" in value && "public" in value) return value.public;
|
|
7
|
+
return value;
|
|
8
|
+
}
|
|
9
|
+
function resolvePlugins(raw, parentPlugins, addPlugins) {
|
|
10
|
+
const resolved = !raw ? parentPlugins ? [...parentPlugins] : [] : Array.isArray(raw) ? [...raw] : raw(parentPlugins ?? []);
|
|
11
|
+
const combined = addPlugins ? [...resolved, ...addPlugins] : resolved;
|
|
12
|
+
const seen = /* @__PURE__ */ new Set();
|
|
13
|
+
return combined.filter((p) => {
|
|
14
|
+
const name = p.name;
|
|
15
|
+
if (!name) {
|
|
16
|
+
console.warn("posipaki: plugin has no name, dedup won't work");
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
if (seen.has(name)) return false;
|
|
20
|
+
seen.add(name);
|
|
21
|
+
return true;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
async function assembleActor(config, plugins, addPlugins) {
|
|
25
|
+
let cur = config;
|
|
26
|
+
for (const p of plugins) try {
|
|
27
|
+
cur = await p(cur);
|
|
28
|
+
} catch (e) {
|
|
29
|
+
console.error(`[assembleActor] plugin "${p.name || "?"}" failed:`, e);
|
|
30
|
+
}
|
|
31
|
+
cur.resolvedPlugins = plugins;
|
|
32
|
+
if (addPlugins) cur.addPlugins = addPlugins;
|
|
33
|
+
return cur;
|
|
34
|
+
}
|
|
35
|
+
function defineActor(config) {
|
|
36
|
+
const actorCtxMap = /* @__PURE__ */ new Map();
|
|
37
|
+
function makeRuntime(assembly) {
|
|
38
|
+
return async function* (ctx, args) {
|
|
39
|
+
let done = false;
|
|
40
|
+
let exitReason;
|
|
41
|
+
let rawState = void 0;
|
|
42
|
+
/**
|
|
43
|
+
* End this actor, and write the reason down twice: the hooks (`beforeEnd`, `afterEnd`) read
|
|
44
|
+
* the local copy, and the EXIT the parent receives carries it as well. An exit that says
|
|
45
|
+
* only *that* something ended leaves the parent to guess — and a stop that was agreed to, a
|
|
46
|
+
* wire that closed (`CHANNEL_LOST`) and a child that finished are three different things to
|
|
47
|
+
* whoever has to react.
|
|
48
|
+
*/
|
|
49
|
+
const endWith = (reason, wake = false) => {
|
|
50
|
+
exitReason = reason;
|
|
51
|
+
ctx.exitReason = reason;
|
|
52
|
+
done = true;
|
|
53
|
+
if (wake) ctx.wake();
|
|
54
|
+
};
|
|
55
|
+
const decorated = /* @__PURE__ */ new Map();
|
|
56
|
+
const self = {
|
|
57
|
+
ctx,
|
|
58
|
+
...assembly.methods || {},
|
|
59
|
+
...assembly.$decorate || {},
|
|
60
|
+
reflection: {},
|
|
61
|
+
state: rawState,
|
|
62
|
+
name: ctx.pname,
|
|
63
|
+
id: ctx.id,
|
|
64
|
+
async emit(msg) {
|
|
65
|
+
await callHook(assembly.onEmit, void 0, self, msg, {
|
|
66
|
+
fromName: ctx.pname,
|
|
67
|
+
fromId: ctx.id
|
|
68
|
+
});
|
|
69
|
+
ctx.toParent(msg);
|
|
70
|
+
},
|
|
71
|
+
agreeToStop() {
|
|
72
|
+
endWith("stopped");
|
|
73
|
+
},
|
|
74
|
+
exit(reason) {
|
|
75
|
+
endWith(reason, true);
|
|
76
|
+
},
|
|
77
|
+
$child: {},
|
|
78
|
+
decorators: {},
|
|
79
|
+
fork: async (childActor, childArgs, forkOpts) => {
|
|
80
|
+
let child;
|
|
81
|
+
const childName = forkOpts?.name ?? childActor?.name ?? `child-${Object.keys(self.$child).length}`;
|
|
82
|
+
const treeName = `${ctx.pname}:${childName}`;
|
|
83
|
+
const childAddPlugins = [...assembly.addPlugins || [], ...forkOpts?.addPlugins || []];
|
|
84
|
+
child = await childActor.spawnAsChild(ctx, childArgs, {
|
|
85
|
+
name: treeName,
|
|
86
|
+
parentPlugins: assembly.resolvedPlugins || [],
|
|
87
|
+
...childAddPlugins.length ? { addPlugins: childAddPlugins } : {}
|
|
88
|
+
});
|
|
89
|
+
self.$child[child.pname] = child;
|
|
90
|
+
return child;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
actorCtxMap.set(ctx.id, self);
|
|
94
|
+
/**
|
|
95
|
+
* Lifecycle hooks are the actor's own control flow: if one throws, the
|
|
96
|
+
* state machine is half-applied, so the error is fatal — `onError` still
|
|
97
|
+
* observes it (a logger logs it), but it cannot absorb it. The actor goes
|
|
98
|
+
* down and its parent still gets the EXIT, instead of staying up with
|
|
99
|
+
* nothing left to do.
|
|
100
|
+
*
|
|
101
|
+
* Message hooks and handlers are not forced either way: they are called
|
|
102
|
+
* with `onError` itself, and its *return value* decides — nothing means
|
|
103
|
+
* "handled, carry on" (the default, and what an observing logger
|
|
104
|
+
* returns), `propagateError()` means "not handled", and the actor goes
|
|
105
|
+
* down with the same EXIT.
|
|
106
|
+
*/
|
|
107
|
+
const hookErrorHandler = async (e) => {
|
|
108
|
+
try {
|
|
109
|
+
await assembly.onError?.call(self, e);
|
|
110
|
+
} catch {}
|
|
111
|
+
return PROPAGATE_SENTINEL;
|
|
112
|
+
};
|
|
113
|
+
ctx.afterExit = async () => {
|
|
114
|
+
await callHook(assembly.afterEnd, hookErrorHandler, self, exitReason);
|
|
115
|
+
};
|
|
116
|
+
for (const [k, v] of decorated) self[k] = v;
|
|
117
|
+
await callHook(assembly.beforeStart, hookErrorHandler, self);
|
|
118
|
+
if (assembly.setup) rawState = await assembly.setup.call(self, args);
|
|
119
|
+
else rawState = null;
|
|
120
|
+
self.state = rawState;
|
|
121
|
+
yield hidePrivate(rawState);
|
|
122
|
+
await callHook(assembly.afterStart, hookErrorHandler, self);
|
|
123
|
+
yield* runDispatchAsync(ctx.pname, async (stamped) => {
|
|
124
|
+
const [msg, sender] = stamped;
|
|
125
|
+
if (msg.type === "__ADVANCE__") return;
|
|
126
|
+
if (msg.type === "STOP") {
|
|
127
|
+
if (assembly.onStopRequested) await callHook(assembly.onStopRequested, hookErrorHandler, self);
|
|
128
|
+
else endWith("stopped");
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (msg.type === "EXIT") {
|
|
132
|
+
const childName = sender.fromName;
|
|
133
|
+
if (childName && self.$child[childName]) delete self.$child[childName];
|
|
134
|
+
await callHook(assembly.onChildExit, hookErrorHandler, self, childName, msg, msg.reason);
|
|
135
|
+
const orphans = msg.orphans;
|
|
136
|
+
if (orphans && orphans.length > 0) for (const orphan of orphans) {
|
|
137
|
+
const decision = assembly.onOrphan ? await callHook(assembly.onOrphan, hookErrorHandler, self, orphan) : "force-stop";
|
|
138
|
+
if (decision === "adopt") {
|
|
139
|
+
ctx.adopt(orphan);
|
|
140
|
+
const idx = ctx.orphans.indexOf(orphan);
|
|
141
|
+
if (idx >= 0) ctx.orphans.splice(idx, 1);
|
|
142
|
+
self.$child[orphan.pname] = orphan;
|
|
143
|
+
} else if (decision === "force-stop") {
|
|
144
|
+
orphan.forceStop({ cascade: true });
|
|
145
|
+
const idx = ctx.orphans.indexOf(orphan);
|
|
146
|
+
if (idx >= 0) ctx.orphans.splice(idx, 1);
|
|
147
|
+
} else if (decision === "unparent") orphan.unparent();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
let hookStopped = false;
|
|
151
|
+
if (msg.type !== "STOP" && msg.type !== "EXIT" && assembly.onMessage) {
|
|
152
|
+
if (await callHook(assembly.onMessage, assembly.onError, self, msg, sender) === STOP_SENTINEL) hookStopped = true;
|
|
153
|
+
}
|
|
154
|
+
if (msg.type !== "STOP" && !hookStopped) {
|
|
155
|
+
const handler = (assembly.handlers || {})[msg.type] || assembly.onUnhandled;
|
|
156
|
+
await callHook(handler, assembly.onError, self, msg, sender);
|
|
157
|
+
}
|
|
158
|
+
}, () => done);
|
|
159
|
+
await callHook(assembly.beforeEnd, hookErrorHandler, self, exitReason);
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function attachReflection(proc, reflectionMethods) {
|
|
163
|
+
const self = actorCtxMap.get(proc.id);
|
|
164
|
+
if (self) proc.$reflection = self.reflection;
|
|
165
|
+
if (!reflectionMethods) return;
|
|
166
|
+
const refl = proc.$reflection;
|
|
167
|
+
const written = Object.entries(reflectionMethods);
|
|
168
|
+
for (const [k, m] of written) refl[k] = async (...args) => await m.apply(self, args);
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
fn: makeRuntime(config),
|
|
172
|
+
name: config.name,
|
|
173
|
+
pvtPluginsRaw: config.plugins,
|
|
174
|
+
inMessages: config.inMessages,
|
|
175
|
+
outMessages: config.outMessages,
|
|
176
|
+
async spawn(args, opts) {
|
|
177
|
+
const assembly = await assembleActor(config, resolvePlugins(config.plugins, void 0, opts?.addPlugins), opts?.addPlugins);
|
|
178
|
+
const runtime = makeRuntime(assembly);
|
|
179
|
+
const proc = spawnAsync(runtime, opts?.name ?? assembly.name ?? "actor", opts?.toParent, opts?.parentName, opts?.parentId)(args);
|
|
180
|
+
attachReflection(proc, assembly.$reflectionMethods);
|
|
181
|
+
if (opts?.awaitReady !== false) await proc.ready();
|
|
182
|
+
return proc;
|
|
183
|
+
},
|
|
184
|
+
async spawnAsChild(ctx, args, opts) {
|
|
185
|
+
const assembly = await assembleActor(config, resolvePlugins(config.plugins, opts?.parentPlugins, opts?.addPlugins), opts?.addPlugins);
|
|
186
|
+
const runtime = makeRuntime(assembly);
|
|
187
|
+
const proc = ctx.fork(runtime, opts?.name ?? assembly.name ?? "child")(args);
|
|
188
|
+
attachReflection(proc, assembly.$reflectionMethods);
|
|
189
|
+
return proc;
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
//#endregion
|
|
194
|
+
export { defineMessages as n, defineActor as t };
|
|
195
|
+
|
|
196
|
+
//# sourceMappingURL=define-actor-jG-OgJng.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-actor-jG-OgJng.js","names":[],"sources":["../src/define-actor.ts"],"sourcesContent":["// ── defineActor — high-level actor wrapper ───────────────────────────────────\n//\n// Compiles a declarative config into an AsyncProcessFn. Built on top of\n// the existing runDispatchAsync / spawnAsync primitives.\n//\nimport {\n type AsyncProcess,\n runDispatchAsync,\n spawnAsync,\n AnyProcess,\n INTERNAL_ADVANCE,\n} from \"./process.async.js\";\nimport type {\n WithSender,\n SenderInfo,\n AsyncProcessFn,\n Message,\n ExitMessage,\n ProcessCtx,\n} from \"./types.js\";\nimport type {\n ActorDefinition,\n ActorConfig,\n ActorContext,\n MethodOptions,\n ActorMessages,\n HandlerOptions,\n HandlerFn,\n ReflectionOptions,\n AnyConfig,\n HidePrivate,\n} from \"./actor-types.js\";\nimport { STOP_SENTINEL, PROPAGATE_SENTINEL } from \"./actor-types.js\";\nimport { ActorDecorated, type ActorPlugin, ActorReflection, callHook } from \"./hooks.js\";\n\nexport function defineMessages<OutMsg extends Message = Message>(): ActorMessages<OutMsg> {\n return undefined as unknown as ActorMessages<OutMsg>;\n}\n\nfunction hidePrivate<T>(value: T): HidePrivate<T> {\n if (value && typeof value === \"object\" && \"private\" in value && \"public\" in value) {\n return value.public as HidePrivate<T>;\n }\n return value as HidePrivate<T>;\n}\n\nfunction resolvePlugins(\n raw: ActorPlugin[] | ((parents: ActorPlugin[]) => ActorPlugin[]) | undefined,\n parentPlugins?: ActorPlugin[],\n addPlugins?: ActorPlugin[],\n): ActorPlugin[] {\n const resolved = !raw\n ? parentPlugins\n ? [...parentPlugins]\n : []\n : Array.isArray(raw)\n ? [...raw]\n : raw(parentPlugins ?? []);\n\n const combined = addPlugins ? [...resolved, ...addPlugins] : resolved;\n\n // Deduplicate by function name\n const seen = new Set<string>();\n return combined.filter((p) => {\n const name = p.name;\n if (!name) {\n console.warn(\"posipaki: plugin has no name, dedup won't work\");\n return true;\n }\n if (seen.has(name)) return false;\n seen.add(name);\n return true;\n });\n}\n\nasync function assembleActor<C>(\n config: C,\n plugins: ActorPlugin[],\n addPlugins?: ActorPlugin[],\n): Promise<C> {\n // Work with the default ActorPlugin type internally, cast back on return\n let cur = config as AnyConfig;\n for (const p of plugins) {\n try {\n cur = await p(cur);\n } catch (e: unknown) {\n console.error(`[assembleActor] plugin \"${p.name || \"?\"}\" failed:`, e);\n }\n }\n cur.resolvedPlugins = plugins;\n if (addPlugins) cur.addPlugins = addPlugins;\n return cur as C;\n}\n\nexport function defineActor<\n Args,\n InternalState,\n InMsg extends Message,\n OutMsg extends Message,\n Methods extends MethodOptions,\n Handlers extends HandlerOptions<InMsg>,\n ReflectionMethods extends ReflectionOptions,\n>(\n config: ActorConfig<Args, InternalState, InMsg, OutMsg, Methods, Handlers, ReflectionMethods>,\n): ActorDefinition<Args, InternalState, InMsg, OutMsg, ReflectionMethods> {\n const actorCtxMap = new Map<\n symbol,\n ActorContext<Args, InternalState, InMsg, OutMsg, Methods, Handlers, ReflectionMethods>\n >();\n\n function makeRuntime(\n assembly: ActorConfig<Args, InternalState, InMsg, OutMsg, Methods, Handlers, ReflectionMethods>,\n ): AsyncProcessFn<Args, HidePrivate<InternalState>, InMsg, OutMsg> {\n return async function* (\n ctx,\n args,\n ): AsyncGenerator<HidePrivate<InternalState | null>, void, WithSender<InMsg>> {\n let done = false;\n let exitReason: unknown;\n let rawState: InternalState = undefined as unknown as InternalState;\n\n /**\n * End this actor, and write the reason down twice: the hooks (`beforeEnd`, `afterEnd`) read\n * the local copy, and the EXIT the parent receives carries it as well. An exit that says\n * only *that* something ended leaves the parent to guess — and a stop that was agreed to, a\n * wire that closed (`CHANNEL_LOST`) and a child that finished are three different things to\n * whoever has to react.\n */\n const endWith = (reason: unknown, wake = false): void => {\n exitReason = reason;\n ctx.exitReason = reason;\n done = true;\n // The loop only re-reads `done` when it is resumed: an idle actor is\n // parked at its dispatch yield and would sit there forever.\n if (wake) ctx.wake();\n };\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 endWith(\"stopped\");\n },\n exit(reason: unknown) {\n endWith(reason, true);\n },\n $child: {} as Record<string, AnyProcess>,\n decorators: {},\n fork: async <A, S, IM extends Message, OM extends InMsg, R extends ReflectionOptions>(\n childActor: ActorDefinition<A, S, IM, OM, R>,\n childArgs?: A,\n forkOpts?: { name?: string; addPlugins?: ActorPlugin[] },\n ): Promise<AsyncProcess<A, HidePrivate<S>, IM, OM, R & ActorReflection>> => {\n let child: AsyncProcess<A, HidePrivate<S>, IM, OM, R & ActorReflection>;\n const childName =\n forkOpts?.name ?? childActor?.name ?? `child-${Object.keys(self.$child).length}`;\n const treeName = `${ctx.pname}:${childName}`;\n const childAddPlugins = [...(assembly.addPlugins || []), ...(forkOpts?.addPlugins || [])];\n child = await childActor.spawnAsChild(ctx, childArgs!, {\n name: treeName,\n parentPlugins: assembly.resolvedPlugins || [],\n ...(childAddPlugins.length ? { addPlugins: childAddPlugins } : {}),\n });\n self.$child[child.pname] = child as unknown as AnyProcess;\n return child;\n },\n };\n actorCtxMap.set(ctx.id, self);\n /**\n * Lifecycle hooks are the actor's own control flow: if one throws, the\n * state machine is half-applied, so the error is fatal — `onError` still\n * observes it (a logger logs it), but it cannot absorb it. The actor goes\n * down and its parent still gets the EXIT, instead of staying up with\n * nothing left to do.\n *\n * Message hooks and handlers are not forced either way: they are called\n * with `onError` itself, and its *return value* decides — nothing means\n * \"handled, carry on\" (the default, and what an observing logger\n * returns), `propagateError()` means \"not handled\", and the actor goes\n * down with the same EXIT.\n */\n const hookErrorHandler = async (e: unknown): Promise<unknown> => {\n try {\n await assembly.onError?.call(self, e);\n } catch {\n // An error in the error handler must not mask the original one.\n }\n return PROPAGATE_SENTINEL;\n };\n ctx.afterExit = async () => {\n await callHook(assembly.afterEnd, hookErrorHandler, self, exitReason);\n };\n\n for (const [k, v] of decorated) {\n (self as Record<string, unknown>)[k] = v;\n }\n\n await callHook(\n assembly.beforeStart,\n hookErrorHandler,\n self as ActorContext<\n Args,\n never, // state not set yet\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods & ActorReflection\n >,\n );\n\n if (assembly.setup) {\n rawState = await assembly.setup.call(\n self as ActorContext<\n Args,\n never, // break inference cycle here\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods & ActorReflection\n >,\n args,\n );\n } else {\n rawState = null as InternalState;\n }\n self.state = rawState;\n yield hidePrivate(rawState);\n await callHook(assembly.afterStart, hookErrorHandler, self);\n\n yield* runDispatchAsync<WithSender<InMsg | ExitMessage>>(\n ctx.pname,\n async (stamped) => {\n const [msg, sender] = stamped;\n if (msg.type === INTERNAL_ADVANCE) return; // framework traffic, not a message\n if (msg.type === \"STOP\") {\n if (assembly.onStopRequested) {\n await callHook(assembly.onStopRequested, hookErrorHandler, self);\n // Hook may call agreeToStop(). If not, actor keeps running.\n } else {\n endWith(\"stopped\");\n }\n return;\n }\n if (msg.type === \"EXIT\") {\n // FIXME: process name are user-specified\n // and should not be used for indexing so\n // we don't get into name conflicts\n const childName = sender.fromName;\n if (childName && self.$child[childName]) {\n delete self.$child[childName];\n }\n await callHook(\n assembly.onChildExit,\n hookErrorHandler,\n self,\n childName,\n msg as ExitMessage,\n (msg as ExitMessage).reason,\n );\n // Orphan policy: a child that exits may leave still-running\n // grandchildren behind (see ctx-orphans / orphan-policy).\n const orphans = (msg as ExitMessage).orphans;\n if (orphans && orphans.length > 0) {\n for (const orphan of orphans) {\n // Default when no hook is defined: hard-kill the orphan.\n const decision = assembly.onOrphan\n ? await callHook(assembly.onOrphan, hookErrorHandler, self, orphan)\n : \"force-stop\";\n if (decision === \"adopt\") {\n ctx.adopt(orphan);\n const idx = ctx.orphans.indexOf(orphan);\n if (idx >= 0) ctx.orphans.splice(idx, 1);\n self.$child[orphan.pname] = orphan;\n } else if (decision === \"force-stop\") {\n orphan.forceStop({ cascade: true });\n const idx = ctx.orphans.indexOf(orphan);\n if (idx >= 0) ctx.orphans.splice(idx, 1);\n } else if (decision === \"unparent\") {\n orphan.unparent();\n }\n // 'leave' (or undefined) → do nothing; it propagates on exit.\n }\n }\n }\n let hookStopped = false;\n if (msg.type !== \"STOP\" && msg.type !== \"EXIT\" && assembly.onMessage) {\n const result = await callHook(\n assembly.onMessage,\n assembly.onError,\n self,\n msg as InMsg,\n sender,\n );\n if (result === STOP_SENTINEL) hookStopped = true;\n }\n if (msg.type !== \"STOP\" && !hookStopped) {\n const handler =\n ((assembly.handlers || ({} as Handlers))[\n msg.type as keyof Handlers\n ] as HandlerFn<InMsg>) || assembly.onUnhandled;\n\n await callHook(handler, assembly.onError, self, msg as InMsg, sender);\n }\n },\n () => done,\n );\n\n await callHook(assembly.beforeEnd, hookErrorHandler, self, exitReason);\n };\n }\n\n type ReflectableProcess = {\n id: symbol;\n $reflection: Record<string, Function>;\n };\n function attachReflection(\n proc: ReflectableProcess,\n reflectionMethods: ReflectionMethods | undefined,\n ): void {\n const self = actorCtxMap.get(proc.id);\n if (self) {\n // One object under two names: the surface the handle exposes as\n // `$reflection` and the one the actor's own hooks see as `reflection`.\n // Handing the same object to both is what lets a method be added after\n // assembly — the first caller that needs that is a remote peer saying\n // which methods it can answer.\n proc.$reflection = self.reflection as unknown as Record<string, Function>;\n }\n if (!reflectionMethods) return;\n const refl = proc.$reflection as Record<string, Function>;\n // The declared contract is `ReflectionMethod`, whose parameters are `never`\n // because nothing is called through it; this is the one place that calls\n // what it describes.\n const written = Object.entries(reflectionMethods) as Array<\n [string, (...args: unknown[]) => unknown]\n >;\n for (const [k, m] of written) {\n // A promise whatever the method was written as, so a caller reads the same\n // call the same way whether the actor is here or behind a wire.\n refl[k] = async (...args: unknown[]) => await m.apply(self, args);\n }\n }\n\n return {\n fn: makeRuntime(config),\n name: config.name,\n pvtPluginsRaw: config.plugins,\n inMessages: config.inMessages,\n outMessages: config.outMessages,\n async spawn(\n args: Args,\n opts?: {\n name?: string;\n toParent?: (msg: OutMsg, from: SenderInfo) => void;\n addPlugins?: ActorPlugin[];\n parentName?: string | null;\n parentId?: symbol | null;\n /**\n * Resolve only once the initial state is available. Default `true`:\n * a spawned process is safe to send to when `spawn()` returns. Pass\n * `false` for the raw handle — the caller then has to `await\n * proc.ready()` itself before sending anything it wants handled.\n */\n awaitReady?: boolean;\n },\n ): Promise<\n AsyncProcess<\n Args,\n HidePrivate<InternalState>,\n InMsg,\n OutMsg,\n ReflectionMethods & ActorReflection\n >\n > {\n const plugs = resolvePlugins(config.plugins, undefined, opts?.addPlugins);\n const assembly = await assembleActor(config, plugs, opts?.addPlugins);\n const runtime = makeRuntime(assembly);\n const proc = spawnAsync(\n runtime,\n opts?.name ?? assembly.name ?? \"actor\",\n opts?.toParent,\n opts?.parentName,\n opts?.parentId,\n )(args);\n attachReflection(proc, assembly.$reflectionMethods as ReflectionMethods);\n if (opts?.awaitReady !== false) await proc.ready();\n return proc as AsyncProcess<\n Args,\n HidePrivate<InternalState>,\n InMsg,\n OutMsg,\n ReflectionMethods & ActorReflection\n >;\n },\n async spawnAsChild(\n ctx: ProcessCtx<unknown, unknown, OutMsg, Message>,\n args: Args,\n opts?: {\n name?: string;\n parentPlugins?: ActorPlugin[];\n addPlugins?: ActorPlugin[];\n },\n ) {\n const plugs = resolvePlugins(config.plugins, opts?.parentPlugins, opts?.addPlugins);\n const assembly = await assembleActor(config, plugs, opts?.addPlugins);\n const runtime = makeRuntime(assembly);\n const proc = ctx.fork(runtime, opts?.name ?? assembly.name ?? \"child\")(args);\n attachReflection(proc, assembly.$reflectionMethods as ReflectionMethods);\n return proc as AsyncProcess<\n Args,\n HidePrivate<InternalState>,\n InMsg,\n OutMsg,\n ReflectionMethods & ActorReflection\n >;\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { d as AnyProcess, f as AsyncProcess, i as ProcessCtx, n as ExitMessage, o as SenderInfo, r as Message, t as AsyncProcessFn } from "./types-
|
|
1
|
+
import { d as AnyProcess, f as AsyncProcess, i as ProcessCtx, n as ExitMessage, o as SenderInfo, r as Message, t as AsyncProcessFn } from "./types-BuI2bfi4.js";
|
|
2
2
|
//#region src/actor-types.d.ts
|
|
3
3
|
type ActorMessages<M extends Message> = {
|
|
4
4
|
__tag_messages: M;
|
|
@@ -97,7 +97,10 @@ type ActorConfig<Args, InternalState, InMsg extends Message, OutMsg extends Mess
|
|
|
97
97
|
onEmit?: (msg: OutMsg, sender: SenderInfo) => HookResult | Promise<HookResult>;
|
|
98
98
|
onMessage?: (msg: InMsg, sender: SenderInfo) => HookResult | Promise<HookResult>;
|
|
99
99
|
onUnhandled?: (msg: Message, sender: SenderInfo) => void | Promise<void>;
|
|
100
|
-
|
|
100
|
+
/** A child ended. `exit` is what it sent — its orphans travel there — and `reason` is what it
|
|
101
|
+
* ended *for*: the value `exit(reason)` was given, `"stopped"` for a stop that was agreed to,
|
|
102
|
+
* `CHANNEL_LOST` when the wire under a proxy went, or undefined when nobody asked. */
|
|
103
|
+
onChildExit?: (name: string, exit: ExitMessage, reason: unknown) => HookResult | Promise<HookResult>;
|
|
101
104
|
/** Fires for each orphan a child leaves behind (in its EXIT). Return the
|
|
102
105
|
* policy: `'adopt'` (promote to a child, draining its buffer), `'force-stop'`
|
|
103
106
|
* (hard-kill), `'unparent'` (drop its buffer, keep it running in `orphans`),
|
|
@@ -210,4 +213,4 @@ type Hook<T, I extends unknown[], O> = (this: T, ...args: I) => O;
|
|
|
210
213
|
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>;
|
|
211
214
|
//#endregion
|
|
212
215
|
export { stopPropagation as S, PluginTransform as _, chainHook as a, SpawnedFrom as b, ActorContext as c, ActorPlugin as d, HandlerFn as f, PROPAGATE_SENTINEL as g, MethodOptions as h, callHook as i, ActorDefinition as l, HookResult as m, ActorReflection as n, mergeConfigs as o, HandlerOptions as p, Hook as r, ActorConfig as s, ActorDecorated as t, ActorMessages as u, ReflectionOptions as v, propagateError as x, STOP_SENTINEL as y };
|
|
213
|
-
//# sourceMappingURL=hooks-
|
|
216
|
+
//# sourceMappingURL=hooks-C5S7GIX_.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks-C5S7GIX_.d.ts","names":[],"sources":["../src/actor-types.ts","../src/hooks.ts"],"mappings":";;KAWY,cAAc,UAAU;EAClC,gBAAgB;;UAED;GACd,cAAc;;KAEL,UAAU,cAAc,YAClC,KAAK,OACL,QAAQ,sBACE;KACA,eAAe,cAAc,WAAW,QAE/C,KAAK,gBAAgB,UAAU,QAAQ;EAAS,MAAM;;;;;;;;;;;KAa/C,uBAAuB,kBAAkB;;;UAGpC;GACd,eAAe;;KAEN,OAAO,MAAM;EAAS,QAAQ;EAAK,SAAS;;KAC5C,YAAY,KAAK,UAAU,2BAA2B,cAAc;KAEpE,YAAY,UAAU,4CAChC,UAAU,sBAAsB,SAAS,SAAS,UAAU,UAAU,KAClE,aAAa,GAAG,YAAY,IAAI,IAAI,IAAI,IAAI;UAGjC,gBACf,MACA,eACA,cAAc,SACd,eAAe,SACf,0BAA0B;EAE1B,IAAI,eAAe,MAAM,YAAY,gBAAgB,OAAO;;EAE5D;;EAEA,gBAAgB,gBAAgB;;EAEhC,MACE,MAAM,MACN;IACE;IACA,YAAY,KAAK,QAAQ,MAAM;IAC/B,aAAa;IACb;IACA;;IAEA;MAED,QACD,aACE,MACA,YAAY,gBACZ,OACA,QACA,oBAAoB;;;;EAMxB,aAAa,YAAY,SACvB,KAAK,6BAA6B,QAAQ,MAC1C,MAAM,MACN;IACE;IACA,gBAAgB;IAChB,aAAa;MAEd,QACD,aACE,MACA,YAAY,gBACZ,OACA,QACA,oBAAoB;EAGxB,YAAY,cAAc;EAC1B,aAAa,cAAc;;;;;;;;;KASjB,YACV,MACA,eACA,cAAc,SACd,eAAe,SACf,gBAAgB,eAChB,iBAAiB,eAAe,QAChC,0BAA0B;;EAG1B;EACA,UAAU,gBAAgB;;;EAG1B,aAAa;;;;EAIb,kBAAkB;EAClB,cAAc,cAAc;EAC5B,aAAa,cAAc;;;;EAI3B,eACE,MAAM,aACJ,aAEA,OACA,QACA,eACA,UACA,oBAAoB,4BAEZ;;EAGZ,SACE,MAAM,aACJ,aAEA,OACA,QACA,eACA,UACA,oBAAoB,kBAEtB,MAAM,SACH,QAAQ,iBAAiB;EAE9B,0BAA0B;EAE1B,wBAAwB,aAAa,QAAQ;EAE7C,aAAa,qBAAqB,aAAa,QAAQ;;;;;;EAOvD,YAAY,qBAAqB,aAAa,QAAQ;EAEtD,WAAW,oBAAoB,aAAa,cAAc,QAAQ,aAAa;EAE/E,UAAU,KAAK,QAAQ,QAAQ,eAAe,aAAa,QAAQ;EAEnE,aAAa,KAAK,OAAO,QAAQ,eAAe,aAAa,QAAQ;EAErE,eAAe,KAAK,SAAS,QAAQ,sBAAsB;;;;EAK3D,eACE,cACA,MAAM,aACN,oBACG,aAAa,QAAQ;;;;;;EAO1B,YAAY,QAAQ,eAAe,wBAAwB,QAAQ;EAEnE,UAAU,WACR,SACE,aACE,MACA,eACA,OACA,QACA,SACA,UACA,oBAAoB;EAI1B,UAAU,UACR,SACE,aACE,MACA,eACA,OACA,QACA,SACA,UACA,oBAAoB;EAG1B,qBAAqB,oBACnB,SACE,aACE,MACA,eACA,OACA,QACA,SACA,UACA,kBAAkB;EAIxB,YAAY,QAAQ;IAClB,SACF,aAAa,MAAM,eAAe,OAAO,QAAQ,SAAS,UAAU,oBAAoB;KAE9E,YAAY,8BAGtB,SACA,SACA,eACA,eAAe,UACf;;cAMW;;cAGA,8BAA6B;;;;;;;;cAS7B;;cAGA,6BAA4B;;KAG7B,4BAA4B;;KAK5B,2BAA2B;;KAG3B;;KAIA,YAAY,IAAI,cAAc,QAAQ,MAAM,IAAI,QAAQ;;KAGxD,mBAAmB,eAAe,kBAAkB;KAEpD,aACV,MACA,eACA,cAAc,SACd,eAAe,SACf,gBAAgB,eAChB,iBAAiB,eAAe,QAChC,0BAA0B,qBACxB,UACF;EACE,OAAO;EACP;EACA;EAEA,OAAO,KAAK;EACZ;EAEA,YAAY,SACV,aAAa,MAAM,eAAe,OAAO,QAAQ,SAAS,UAAU,sBAEpE;EACF,OAAO;EAEP,QAAQ,eAAe;EAEvB,KAAK,GAAG,GAAG,WAAW,SAAS,WAAW,OAAO,UAAU,mBACzD,OAAO,gBAAgB,GAAG,GAAG,IAAI,IAAI,IACrC,OAAO,GACP;IACE;IACA,aAAa;MAEd,QAAQ,aAAa,GAAG,YAAY,IAAI,IAAI,IAAI,IAAI;EAEvD,KAAK,WAAW,MAAM,YAAY,gBAAgB,OAAO;;;;;;KASjD,eAAe,KAAK,UAAU,kBAClC,YACA,qBACA,cAAc,eACd,eAAe,eACf,gBAAgB,qBAChB,gBACA,0BAA0B,qBAE9B,aACE,MACA,eACA,OACA,QACA,SACA,iBAAiB,eAAe,SAAS,WAAW,eAAe,QACnE,oBAAoB;;;;;;;;;;;;;;;UCpTT;;;UAGA,wBAAwB;;;;;;;;;;;;;;;iBAkBzB,UAAU,OAAO,yBAC/B,YAAY,MAAM,UAAU,MAAM,UAAU,aAAa,QAAQ,0BACjE,SAAS,MAAM,UAAU,MAAM,UAAU,aAAa,QAAQ,eAC5D,MAAM,UAAU,MAAM,UAAU,aAAa,QAAQ;;;;;;;;;;;;;;;;;;;iBA6BzC,aAAa,UAAU,WACrC,MAAM,GACN,SAAS,QAAQ,KAAK,SAAS,eAAe,MAC7C;KA0BS,KAAK,GAAG,qBAAqB,MAAM,MAAM,MAAM,MAAM,MAAM;iBAEjD,SAAS,GAAG,qBAAqB,GACrD,IAAI,KAAK,GAAG,GAAG,gBACf,MAAM,qCACN,SAAS,MACN,MAAM,IACR,QAAQ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks-CgXhmY4r.js","names":[],"sources":["../src/actor-types.ts","../src/hooks.ts"],"sourcesContent":["// ── defineActor types ────────────────────────────────────────────────────────\n//\n// Shared between define-actor.ts (implementation) and consumers that want\n// to reference the config/context/definition shapes without importing the\n// implementation module directly.\n\nimport type { SenderInfo, AsyncProcessFn, Message, ProcessCtx, ExitMessage } from \"./types.js\";\nimport type { ActorDecorated, ActorReflection } from \"./hooks.js\";\nimport type { AnyProcess, AsyncProcess } from \"./process.async.js\";\n\n// Internal marker do not use\nexport type ActorMessages<M extends Message> = {\n __tag_messages: M;\n};\nexport interface MethodOptions {\n [key: string]: Function;\n}\nexport type HandlerFn<InMsg extends Message> = (\n msg: InMsg,\n sender: SenderInfo,\n) => void | Promise<void>;\nexport type HandlerOptions<InMsg extends Message> = Omit<\n {\n [K in InMsg[\"type\"]]: HandlerFn<Extract<InMsg, { type: K }>>;\n },\n \"STOP\"\n>;\n/**\n * A reflection method, async by contract: it answers with a promise, even when\n * it has the answer already. The same call has to read the same way whether the\n * actor is here or behind a wire, and a caller that had to know which of the two\n * it was holding would be reading the shape of the deployment, not the answer.\n *\n * The parameters are `never` because nothing is called through this type — it is\n * the contract every declared method is checked against.\n */\nexport type ReflectionMethod = (...args: never[]) => Promise<unknown>;\n/** The reflection surface a process exposes: named methods, each of them async\n * by {@link ReflectionMethod}'s contract. */\nexport interface ReflectionOptions {\n [name: string]: ReflectionMethod;\n}\nexport type Paired<Priv, Pub> = { public: Pub; private: Priv };\nexport type HidePrivate<T> = T extends Paired<unknown, unknown> ? T[\"public\"] : T;\n\nexport type SpawnedFrom<T extends ActorDefinition<any, any, any, any, any>> =\n T extends ActorDefinition<infer A, infer S, infer IM, infer OM, infer R>\n ? AsyncProcess<A, HidePrivate<S>, IM, OM, R & ActorReflection>\n : never;\n\nexport interface ActorDefinition<\n Args,\n InternalState,\n InMsg extends Message,\n OutMsg extends Message,\n ReflectionMethods extends ReflectionOptions,\n> {\n fn: AsyncProcessFn<Args, HidePrivate<InternalState>, InMsg, OutMsg>;\n /** Preferred process name (from config.name). */\n name?: string;\n /** Raw plugin config (array or transform). Resolved at fork time. @internal */\n pvtPluginsRaw?: ActorPlugin[] | PluginTransform;\n /** Spawn this actor as a standalone process. */\n spawn(\n args: Args,\n opts?: {\n name?: string;\n toParent?: (msg: OutMsg, from: SenderInfo) => void;\n addPlugins?: ActorPlugin[];\n parentName?: string | null;\n parentId?: symbol | null;\n /** Wait for the initial state before resolving. Default `true`. */\n awaitReady?: boolean;\n },\n ): Promise<\n AsyncProcess<\n Args,\n HidePrivate<InternalState>,\n InMsg,\n OutMsg,\n ReflectionMethods & ActorReflection\n >\n >;\n /** Spawn this actor as a child of the calling process.\n * `ctx` must be able to fork children that emit `OutMsg` — i.e. the\n * parent's in-message is a supertype of this actor's out-message. */\n spawnAsChild<PMO extends Message>(\n ctx: ProcessCtx<unknown, unknown, OutMsg, PMO>,\n args: Args,\n opts?: {\n name?: string;\n parentPlugins?: ActorPlugin[];\n addPlugins?: ActorPlugin[];\n },\n ): Promise<\n AsyncProcess<\n Args,\n HidePrivate<InternalState>,\n InMsg,\n OutMsg,\n ReflectionMethods & ActorReflection\n >\n >;\n inMessages: ActorMessages<InMsg> | undefined;\n outMessages: ActorMessages<OutMsg> | undefined;\n}\n/**\n * The config object as a user writes it.\n *\n * Hooks take their `this` from the `ThisType` at the end of this type: a per-hook\n * annotation erases the inferred methods surface. `beforeStart` and `setup` keep\n * one, for the state.\n */\nexport type ActorConfig<\n Args,\n InternalState,\n InMsg extends Message,\n OutMsg extends Message,\n Methods extends MethodOptions,\n Handlers extends HandlerOptions<InMsg>,\n ReflectionMethods extends ReflectionOptions,\n> = {\n /** Preferred process name. Used by ctx.fork() when no explicit name is given. */\n name?: string;\n plugins?: ActorPlugin[] | PluginTransform;\n /** Non-overridable plugins added at spawn time (spawn/fork opts).\n * Set by the framework during assembly, not by user config. @internal */\n addPlugins?: ActorPlugin[];\n /** Resolved plugin chain (raw config transformed against parent plugins).\n * Set by the framework during assembly, replacing `plugins` (the raw form).\n * @internal */\n resolvedPlugins?: ActorPlugin[];\n outMessages?: ActorMessages<OutMsg>;\n inMessages?: ActorMessages<InMsg>;\n /** Fires once `self` is built, before `setup`. State is not yet set\n * (`this.state` is `never`). Use for registering the process/ctx before\n * any child is forked in `setup`. */\n beforeStart?: (\n this: ActorContext<\n Args,\n never,\n InMsg,\n OutMsg,\n MethodOptions,\n Handlers,\n ReflectionMethods & ActorReflection\n >,\n ) => void | Promise<void>;\n\n /** `this.state` is `never`: the returned value is the state. */\n setup?: (\n this: ActorContext<\n Args,\n never,\n InMsg,\n OutMsg,\n MethodOptions,\n Handlers,\n ReflectionMethods & ActorReflection\n >,\n args: Args,\n ) => Promise<InternalState> | InternalState;\n\n afterStart?: () => void | Promise<void>;\n\n onStopRequested?: () => HookResult | Promise<HookResult>;\n\n beforeEnd?: (reason?: unknown) => HookResult | Promise<HookResult>;\n\n /**\n * Runs once the actor has ended — after its EXIT. It is *not* called when the\n * actor never started (`setup()` or a pre-start hook threw): the state is\n * typed as present here, and an actor that never got one has nothing to end.\n */\n afterEnd?: (reason?: unknown) => HookResult | Promise<HookResult>;\n\n onError?: (error?: unknown) => HookResult | ErrorResult | Promise<HookResult | ErrorResult>;\n\n onEmit?: (msg: OutMsg, sender: SenderInfo) => HookResult | Promise<HookResult>;\n\n onMessage?: (msg: InMsg, sender: SenderInfo) => HookResult | Promise<HookResult>;\n\n onUnhandled?: (msg: Message, sender: SenderInfo) => void | Promise<void>;\n\n onChildExit?: (name: string, reason: ExitMessage) => HookResult | Promise<HookResult>;\n\n /** Fires for each orphan a child leaves behind (in its EXIT). Return the\n * policy: `'adopt'` (promote to a child, draining its buffer), `'force-stop'`\n * (hard-kill), `'unparent'` (drop its buffer, keep it running in `orphans`),\n * or `'leave'` (keep buffering, propagate up on my exit). When no `onOrphan`\n * is defined, the default is `'force-stop'`. */\n onOrphan?: (orphan: AnyProcess) => OrphanDecision | void | Promise<OrphanDecision | void>;\n\n handlers: Handlers &\n ThisType<\n ActorContext<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods & ActorReflection\n >\n >;\n\n methods?: Methods &\n ThisType<\n ActorContext<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods & ActorReflection\n >\n >;\n $reflectionMethods?: ReflectionMethods &\n ThisType<\n ActorContext<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ActorReflection & ActorReflection\n >\n >;\n // for plugin use only\n $decorate?: Partial<ActorDecorated>;\n} & ThisType<\n ActorContext<Args, InternalState, InMsg, OutMsg, Methods, Handlers, ReflectionMethods & ActorReflection>\n>;\nexport type AnyConfig = ActorConfig<\n unknown,\n unknown,\n Message,\n Message,\n MethodOptions,\n HandlerOptions<Message>,\n ReflectionOptions\n>;\n\n// ── stop propagation sentinel ────────────────────────────────────────────\n\n/** Returned by onMessage hooks to prevent further dispatch. */\nexport const STOP_SENTINEL = Symbol(\"posipaki.stopPropagation\");\n\n/** Type-safe sentinel for short-circuiting onMessage hooks. */\nexport const stopPropagation = (): typeof STOP_SENTINEL => STOP_SENTINEL;\n\n/**\n * Returned by an `onError` handler that only *observed* the error — logged it,\n * counted it — and did not handle it. The framework then lets the error\n * propagate: the actor still goes down and its parent still gets the EXIT.\n * Without this an observing handler (the bundled debug logger is one) silently\n * turns a broken lifecycle hook into a survivor with nothing left to do.\n */\nexport const PROPAGATE_SENTINEL = Symbol(\"posipaki.propagateError\");\n\n/** Type-safe sentinel for an onError handler that did not handle the error. */\nexport const propagateError = (): typeof PROPAGATE_SENTINEL => PROPAGATE_SENTINEL;\n\n/** Return type of onError handlers: void (handled) or sentinel (not handled). */\nexport type ErrorResult = void | typeof PROPAGATE_SENTINEL;\n\n// ── hook function types ──────────────────────────────────────────────────\n\n/** Return type of onMessage hooks: void (continue) or sentinel (stop). */\nexport type HookResult = void | typeof STOP_SENTINEL;\n\n/** Decision returned by `onOrphan` for how to handle an inherited orphan. */\nexport type OrphanDecision = \"adopt\" | \"force-stop\" | \"unparent\" | \"leave\";\n// ── plugin types ─────────────────────────────────────────────────────────\n\n/** A reusable unit of actor behaviour. */\nexport type ActorPlugin<C = AnyConfig> = (config: C) => C | Promise<C>;\n\n/** Transform parent plugins into child plugins. */\nexport type PluginTransform = (parentPlugins: ActorPlugin[]) => ActorPlugin[];\n\nexport type ActorContext<\n Args,\n InternalState,\n InMsg extends Message,\n OutMsg extends Message,\n Methods extends MethodOptions,\n Handlers extends HandlerOptions<InMsg>,\n ReflectionMethods extends ReflectionOptions,\n> = Methods &\n ActorDecorated & {\n state: InternalState;\n name: string;\n id: symbol;\n\n emit: (msg: OutMsg) => void;\n agreeToStop: () => void;\n\n reflection: ThisType<\n ActorContext<Args, InternalState, InMsg, OutMsg, Methods, Handlers, ReflectionMethods>\n > &\n ReflectionMethods;\n exit: (reason?: unknown) => void;\n\n $child: Record<string, AnyProcess>;\n\n fork<A, S, IM extends Message, OM extends InMsg, R extends ReflectionOptions>(\n actor: ActorDefinition<A, S, IM, OM, R>,\n args?: A,\n opts?: {\n name?: string;\n addPlugins?: ActorPlugin[];\n },\n ): Promise<AsyncProcess<A, HidePrivate<S>, IM, OM, R & ActorReflection>>;\n\n ctx: ProcessCtx<Args, HidePrivate<InternalState>, InMsg, OutMsg>;\n };\n\n\n\n/**\n * The context a config's hooks are typed against, for a `Partial<>` overlay:\n * a mapped type drops the marker `ActorConfig` carries.\n */\nexport type ActorContextOf<C> = C extends ActorConfig<\n infer Args,\n infer InternalState,\n infer InMsg extends Message,\n infer OutMsg extends Message,\n infer Methods extends MethodOptions,\n infer Handlers,\n infer ReflectionMethods extends ReflectionOptions\n>\n ? ActorContext<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers extends HandlerOptions<InMsg> ? Handlers : HandlerOptions<InMsg>,\n ReflectionMethods & ActorReflection\n >\n : never;\n","// ── Lifecycle Hooks ──────────────────────────────────────────────────────\n//\n// Extends ProcessCtx and defineActor with observable lifecycle hooks.\n// Hooks are additive — multiple callbacks can register for the same hook\n// point, and they fire in registration order.\n\nimport {\n STOP_SENTINEL,\n stopPropagation,\n PROPAGATE_SENTINEL,\n propagateError,\n} from \"./actor-types.js\";\nimport type {\n HookResult,\n ActorPlugin,\n PluginTransform,\n AnyConfig,\n ActorContextOf,\n ReflectionOptions,\n} from \"./actor-types.js\";\n\n// ── stop propagation sentinel ────────────────────────────────────────────\n\n// Re-exports from actor-types.ts (backward compatibility)\nexport { STOP_SENTINEL, stopPropagation, PROPAGATE_SENTINEL, propagateError };\nexport type { HookResult, ActorPlugin, PluginTransform };\n\n// ── type augmentation (Fastify-style) ────────────────────────────────────\n\n/**\n * Interface that plugins can augment via declaration merging.\n * Plugins ship a .d.ts that adds properties to this interface,\n * making them available on `this` in handlers and methods.\n *\n * Example (in a plugin's .d.ts):\n * declare module 'posipaki' {\n * interface ActorDecorated {\n * log: Logger;\n * }\n * }\n */\nexport interface ActorDecorated {}\n/** Reflection methods plugins and the framework add to every actor. Merged by\n * declaration, and held to {@link ReflectionOptions}' contract: async. */\nexport interface ActorReflection extends ReflectionOptions {}\n\n// ── chainHook ────────────────────────────────────────────────────────────\n\n/**\n * Compose two lifecycle hooks so that `plugin` fires first.\n *\n * If `plugin` returns the STOP_SENTINEL (via stopPropagation()),\n * `existing` is skipped entirely and the sentinel propagates.\n * Otherwise `existing` fires and its return value is used.\n *\n * Typical use in a plugin:\n * (cfg) => ({ ...cfg, onStart: chainHook(cfg.onStart, myOnStart) })\n *\n * @param existing - the current hook on the config (may be undefined)\n * @param plugin - the new hook to prepend\n * @returns a composed hook suitable for ActorConfig\n */\nexport function chainHook<TThis, TArgs extends unknown[]>(\n existing: ((this: TThis, ...args: TArgs) => HookResult | Promise<HookResult>) | undefined,\n plugin: (this: TThis, ...args: TArgs) => HookResult | Promise<HookResult>,\n): (this: TThis, ...args: TArgs) => HookResult | Promise<HookResult> {\n if (!existing) return plugin;\n return async function (this: TThis, ...args: TArgs): Promise<HookResult> {\n const result = await plugin.call(this, ...args);\n if (result === STOP_SENTINEL) return result;\n return await existing.call(this, ...args);\n } as (this: TThis, ...args: TArgs) => HookResult | Promise<HookResult>;\n}\n\n// ── mergeConfigs ─────────────────────────────────────────────────────────\n\n/**\n * Merge an overlay config into a base config, auto-chaining every on* hook.\n *\n * Each key in `overlay` that starts with \"on\" followed by an uppercase\n * letter (onStart, onMessage, onEmit, etc.) is composed via chainHook()\n * so that the overlay hook fires before the base hook, and stopPropagation\n * is respected.\n *\n * Typical use in a plugin:\n * return mergeConfigs(cfg, {\n * onStart() { this.log.info('starting'); },\n * beforeEnd() { this.log.info('stopping'); },\n * });\n *\n * @param base - the existing config (ActorConfig)\n * @param overlay - new hook implementations to prepend\n * @returns a new config with hooks chained\n */\nexport function mergeConfigs<C extends AnyConfig>(\n base: C,\n overlay: Partial<C> & ThisType<ActorContextOf<C>>,\n): C {\n const result = { ...base } as Record<string, unknown>;\n for (const key of Object.keys(overlay as Record<string, unknown>)) {\n const val = (overlay as Record<string, unknown>)[key];\n if (typeof val === \"function\" && /^(on|after|before)[A-Z]/.test(key)) {\n result[key] = chainHook(\n (base as Record<string, unknown>)[key] as (\n this: unknown,\n ...args: unknown[]\n ) => HookResult | Promise<HookResult>,\n val as (this: unknown, ...args: unknown[]) => HookResult | Promise<HookResult>,\n );\n } else {\n result[key] = val;\n }\n }\n result.$reflectionMethods = {};\n Object.assign(\n result.$reflectionMethods as object,\n \"$reflectionMethods\" in base ? base.$reflectionMethods : {},\n \"$reflectionMethods\" in overlay ? overlay.$reflectionMethods : {},\n );\n\n return result as unknown as C;\n}\n\nexport type Hook<T, I extends unknown[], O> = (this: T, ...args: I) => O;\n\nexport async function callHook<T, I extends unknown[], O>(\n fn: Hook<T, I, O> | undefined,\n eh: ((e: unknown) => unknown) | undefined,\n thisArg: T,\n ...args: I\n): Promise<O | undefined> {\n if (fn) {\n try {\n return await fn.call(thisArg, ...args);\n } catch (e) {\n if (eh) {\n let decision: unknown;\n try {\n decision = await eh(e);\n } catch {\n // An error inside the error handler must not mask the original one.\n }\n // An observing handler says so by returning the sentinel: the error it\n // did not handle keeps propagating, so the actor still goes down.\n if (decision === PROPAGATE_SENTINEL) throw e;\n } else {\n throw e;\n }\n }\n }\n return undefined;\n}\n"],"mappings":";;AAwPA,MAAa,gBAAgB,OAAO,0BAA0B;;AAG9D,MAAa,wBAA8C;;;;;;;;AAS3D,MAAa,qBAAqB,OAAO,yBAAyB;;AAGlE,MAAa,uBAAkD;;;;;;;;;;;;;;;;;ACzM/D,SAAgB,UACd,UACA,QACmE;CACnE,IAAI,CAAC,UAAU,OAAO;CACtB,OAAO,eAA6B,GAAG,MAAkC;EACvE,MAAM,SAAS,MAAM,OAAO,KAAK,MAAM,GAAG,IAAI;EAC9C,IAAI,WAAW,eAAe,OAAO;EACrC,OAAO,MAAM,SAAS,KAAK,MAAM,GAAG,IAAI;CAC1C;AACF;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,aACd,MACA,SACG;CACH,MAAM,SAAS,EAAE,GAAG,KAAK;CACzB,KAAK,MAAM,OAAO,OAAO,KAAK,OAAkC,GAAG;EACjE,MAAM,MAAO,QAAoC;EACjD,IAAI,OAAO,QAAQ,cAAc,0BAA0B,KAAK,GAAG,GACjE,OAAO,OAAO,UACX,KAAiC,MAIlC,GACF;OAEA,OAAO,OAAO;CAElB;CACA,OAAO,qBAAqB,CAAC;CAC7B,OAAO,OACL,OAAO,oBACP,wBAAwB,OAAO,KAAK,qBAAqB,CAAC,GAC1D,wBAAwB,UAAU,QAAQ,qBAAqB,CAAC,CAClE;CAEA,OAAO;AACT;AAIA,eAAsB,SACpB,IACA,IACA,SACA,GAAG,MACqB;CACxB,IAAI,IACF,IAAI;EACF,OAAO,MAAM,GAAG,KAAK,SAAS,GAAG,IAAI;CACvC,SAAS,GAAG;EACV,IAAI,IAAI;GACN,IAAI;GACJ,IAAI;IACF,WAAW,MAAM,GAAG,CAAC;GACvB,QAAQ,CAER;GAGA,IAAI,aAAa,oBAAoB,MAAM;EAC7C,OACE,MAAM;CAEV;AAGJ"}
|
|
1
|
+
{"version":3,"file":"hooks-CgXhmY4r.js","names":[],"sources":["../src/actor-types.ts","../src/hooks.ts"],"sourcesContent":["// ── defineActor types ────────────────────────────────────────────────────────\n//\n// Shared between define-actor.ts (implementation) and consumers that want\n// to reference the config/context/definition shapes without importing the\n// implementation module directly.\n\nimport type { SenderInfo, AsyncProcessFn, Message, ProcessCtx, ExitMessage } from \"./types.js\";\nimport type { ActorDecorated, ActorReflection } from \"./hooks.js\";\nimport type { AnyProcess, AsyncProcess } from \"./process.async.js\";\n\n// Internal marker do not use\nexport type ActorMessages<M extends Message> = {\n __tag_messages: M;\n};\nexport interface MethodOptions {\n [key: string]: Function;\n}\nexport type HandlerFn<InMsg extends Message> = (\n msg: InMsg,\n sender: SenderInfo,\n) => void | Promise<void>;\nexport type HandlerOptions<InMsg extends Message> = Omit<\n {\n [K in InMsg[\"type\"]]: HandlerFn<Extract<InMsg, { type: K }>>;\n },\n \"STOP\"\n>;\n/**\n * A reflection method, async by contract: it answers with a promise, even when\n * it has the answer already. The same call has to read the same way whether the\n * actor is here or behind a wire, and a caller that had to know which of the two\n * it was holding would be reading the shape of the deployment, not the answer.\n *\n * The parameters are `never` because nothing is called through this type — it is\n * the contract every declared method is checked against.\n */\nexport type ReflectionMethod = (...args: never[]) => Promise<unknown>;\n/** The reflection surface a process exposes: named methods, each of them async\n * by {@link ReflectionMethod}'s contract. */\nexport interface ReflectionOptions {\n [name: string]: ReflectionMethod;\n}\nexport type Paired<Priv, Pub> = { public: Pub; private: Priv };\nexport type HidePrivate<T> = T extends Paired<unknown, unknown> ? T[\"public\"] : T;\n\nexport type SpawnedFrom<T extends ActorDefinition<any, any, any, any, any>> =\n T extends ActorDefinition<infer A, infer S, infer IM, infer OM, infer R>\n ? AsyncProcess<A, HidePrivate<S>, IM, OM, R & ActorReflection>\n : never;\n\nexport interface ActorDefinition<\n Args,\n InternalState,\n InMsg extends Message,\n OutMsg extends Message,\n ReflectionMethods extends ReflectionOptions,\n> {\n fn: AsyncProcessFn<Args, HidePrivate<InternalState>, InMsg, OutMsg>;\n /** Preferred process name (from config.name). */\n name?: string;\n /** Raw plugin config (array or transform). Resolved at fork time. @internal */\n pvtPluginsRaw?: ActorPlugin[] | PluginTransform;\n /** Spawn this actor as a standalone process. */\n spawn(\n args: Args,\n opts?: {\n name?: string;\n toParent?: (msg: OutMsg, from: SenderInfo) => void;\n addPlugins?: ActorPlugin[];\n parentName?: string | null;\n parentId?: symbol | null;\n /** Wait for the initial state before resolving. Default `true`. */\n awaitReady?: boolean;\n },\n ): Promise<\n AsyncProcess<\n Args,\n HidePrivate<InternalState>,\n InMsg,\n OutMsg,\n ReflectionMethods & ActorReflection\n >\n >;\n /** Spawn this actor as a child of the calling process.\n * `ctx` must be able to fork children that emit `OutMsg` — i.e. the\n * parent's in-message is a supertype of this actor's out-message. */\n spawnAsChild<PMO extends Message>(\n ctx: ProcessCtx<unknown, unknown, OutMsg, PMO>,\n args: Args,\n opts?: {\n name?: string;\n parentPlugins?: ActorPlugin[];\n addPlugins?: ActorPlugin[];\n },\n ): Promise<\n AsyncProcess<\n Args,\n HidePrivate<InternalState>,\n InMsg,\n OutMsg,\n ReflectionMethods & ActorReflection\n >\n >;\n inMessages: ActorMessages<InMsg> | undefined;\n outMessages: ActorMessages<OutMsg> | undefined;\n}\n/**\n * The config object as a user writes it.\n *\n * Hooks take their `this` from the `ThisType` at the end of this type: a per-hook\n * annotation erases the inferred methods surface. `beforeStart` and `setup` keep\n * one, for the state.\n */\nexport type ActorConfig<\n Args,\n InternalState,\n InMsg extends Message,\n OutMsg extends Message,\n Methods extends MethodOptions,\n Handlers extends HandlerOptions<InMsg>,\n ReflectionMethods extends ReflectionOptions,\n> = {\n /** Preferred process name. Used by ctx.fork() when no explicit name is given. */\n name?: string;\n plugins?: ActorPlugin[] | PluginTransform;\n /** Non-overridable plugins added at spawn time (spawn/fork opts).\n * Set by the framework during assembly, not by user config. @internal */\n addPlugins?: ActorPlugin[];\n /** Resolved plugin chain (raw config transformed against parent plugins).\n * Set by the framework during assembly, replacing `plugins` (the raw form).\n * @internal */\n resolvedPlugins?: ActorPlugin[];\n outMessages?: ActorMessages<OutMsg>;\n inMessages?: ActorMessages<InMsg>;\n /** Fires once `self` is built, before `setup`. State is not yet set\n * (`this.state` is `never`). Use for registering the process/ctx before\n * any child is forked in `setup`. */\n beforeStart?: (\n this: ActorContext<\n Args,\n never,\n InMsg,\n OutMsg,\n MethodOptions,\n Handlers,\n ReflectionMethods & ActorReflection\n >,\n ) => void | Promise<void>;\n\n /** `this.state` is `never`: the returned value is the state. */\n setup?: (\n this: ActorContext<\n Args,\n never,\n InMsg,\n OutMsg,\n MethodOptions,\n Handlers,\n ReflectionMethods & ActorReflection\n >,\n args: Args,\n ) => Promise<InternalState> | InternalState;\n\n afterStart?: () => void | Promise<void>;\n\n onStopRequested?: () => HookResult | Promise<HookResult>;\n\n beforeEnd?: (reason?: unknown) => HookResult | Promise<HookResult>;\n\n /**\n * Runs once the actor has ended — after its EXIT. It is *not* called when the\n * actor never started (`setup()` or a pre-start hook threw): the state is\n * typed as present here, and an actor that never got one has nothing to end.\n */\n afterEnd?: (reason?: unknown) => HookResult | Promise<HookResult>;\n\n onError?: (error?: unknown) => HookResult | ErrorResult | Promise<HookResult | ErrorResult>;\n\n onEmit?: (msg: OutMsg, sender: SenderInfo) => HookResult | Promise<HookResult>;\n\n onMessage?: (msg: InMsg, sender: SenderInfo) => HookResult | Promise<HookResult>;\n\n onUnhandled?: (msg: Message, sender: SenderInfo) => void | Promise<void>;\n\n /** A child ended. `exit` is what it sent — its orphans travel there — and `reason` is what it\n * ended *for*: the value `exit(reason)` was given, `\"stopped\"` for a stop that was agreed to,\n * `CHANNEL_LOST` when the wire under a proxy went, or undefined when nobody asked. */\n onChildExit?: (\n name: string,\n exit: ExitMessage,\n reason: unknown,\n ) => HookResult | Promise<HookResult>;\n\n /** Fires for each orphan a child leaves behind (in its EXIT). Return the\n * policy: `'adopt'` (promote to a child, draining its buffer), `'force-stop'`\n * (hard-kill), `'unparent'` (drop its buffer, keep it running in `orphans`),\n * or `'leave'` (keep buffering, propagate up on my exit). When no `onOrphan`\n * is defined, the default is `'force-stop'`. */\n onOrphan?: (orphan: AnyProcess) => OrphanDecision | void | Promise<OrphanDecision | void>;\n\n handlers: Handlers &\n ThisType<\n ActorContext<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods & ActorReflection\n >\n >;\n\n methods?: Methods &\n ThisType<\n ActorContext<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ReflectionMethods & ActorReflection\n >\n >;\n $reflectionMethods?: ReflectionMethods &\n ThisType<\n ActorContext<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers,\n ActorReflection & ActorReflection\n >\n >;\n // for plugin use only\n $decorate?: Partial<ActorDecorated>;\n} & ThisType<\n ActorContext<Args, InternalState, InMsg, OutMsg, Methods, Handlers, ReflectionMethods & ActorReflection>\n>;\nexport type AnyConfig = ActorConfig<\n unknown,\n unknown,\n Message,\n Message,\n MethodOptions,\n HandlerOptions<Message>,\n ReflectionOptions\n>;\n\n// ── stop propagation sentinel ────────────────────────────────────────────\n\n/** Returned by onMessage hooks to prevent further dispatch. */\nexport const STOP_SENTINEL = Symbol(\"posipaki.stopPropagation\");\n\n/** Type-safe sentinel for short-circuiting onMessage hooks. */\nexport const stopPropagation = (): typeof STOP_SENTINEL => STOP_SENTINEL;\n\n/**\n * Returned by an `onError` handler that only *observed* the error — logged it,\n * counted it — and did not handle it. The framework then lets the error\n * propagate: the actor still goes down and its parent still gets the EXIT.\n * Without this an observing handler (the bundled debug logger is one) silently\n * turns a broken lifecycle hook into a survivor with nothing left to do.\n */\nexport const PROPAGATE_SENTINEL = Symbol(\"posipaki.propagateError\");\n\n/** Type-safe sentinel for an onError handler that did not handle the error. */\nexport const propagateError = (): typeof PROPAGATE_SENTINEL => PROPAGATE_SENTINEL;\n\n/** Return type of onError handlers: void (handled) or sentinel (not handled). */\nexport type ErrorResult = void | typeof PROPAGATE_SENTINEL;\n\n// ── hook function types ──────────────────────────────────────────────────\n\n/** Return type of onMessage hooks: void (continue) or sentinel (stop). */\nexport type HookResult = void | typeof STOP_SENTINEL;\n\n/** Decision returned by `onOrphan` for how to handle an inherited orphan. */\nexport type OrphanDecision = \"adopt\" | \"force-stop\" | \"unparent\" | \"leave\";\n// ── plugin types ─────────────────────────────────────────────────────────\n\n/** A reusable unit of actor behaviour. */\nexport type ActorPlugin<C = AnyConfig> = (config: C) => C | Promise<C>;\n\n/** Transform parent plugins into child plugins. */\nexport type PluginTransform = (parentPlugins: ActorPlugin[]) => ActorPlugin[];\n\nexport type ActorContext<\n Args,\n InternalState,\n InMsg extends Message,\n OutMsg extends Message,\n Methods extends MethodOptions,\n Handlers extends HandlerOptions<InMsg>,\n ReflectionMethods extends ReflectionOptions,\n> = Methods &\n ActorDecorated & {\n state: InternalState;\n name: string;\n id: symbol;\n\n emit: (msg: OutMsg) => void;\n agreeToStop: () => void;\n\n reflection: ThisType<\n ActorContext<Args, InternalState, InMsg, OutMsg, Methods, Handlers, ReflectionMethods>\n > &\n ReflectionMethods;\n exit: (reason?: unknown) => void;\n\n $child: Record<string, AnyProcess>;\n\n fork<A, S, IM extends Message, OM extends InMsg, R extends ReflectionOptions>(\n actor: ActorDefinition<A, S, IM, OM, R>,\n args?: A,\n opts?: {\n name?: string;\n addPlugins?: ActorPlugin[];\n },\n ): Promise<AsyncProcess<A, HidePrivate<S>, IM, OM, R & ActorReflection>>;\n\n ctx: ProcessCtx<Args, HidePrivate<InternalState>, InMsg, OutMsg>;\n };\n\n\n\n/**\n * The context a config's hooks are typed against, for a `Partial<>` overlay:\n * a mapped type drops the marker `ActorConfig` carries.\n */\nexport type ActorContextOf<C> = C extends ActorConfig<\n infer Args,\n infer InternalState,\n infer InMsg extends Message,\n infer OutMsg extends Message,\n infer Methods extends MethodOptions,\n infer Handlers,\n infer ReflectionMethods extends ReflectionOptions\n>\n ? ActorContext<\n Args,\n InternalState,\n InMsg,\n OutMsg,\n Methods,\n Handlers extends HandlerOptions<InMsg> ? Handlers : HandlerOptions<InMsg>,\n ReflectionMethods & ActorReflection\n >\n : never;\n","// ── Lifecycle Hooks ──────────────────────────────────────────────────────\n//\n// Extends ProcessCtx and defineActor with observable lifecycle hooks.\n// Hooks are additive — multiple callbacks can register for the same hook\n// point, and they fire in registration order.\n\nimport {\n STOP_SENTINEL,\n stopPropagation,\n PROPAGATE_SENTINEL,\n propagateError,\n} from \"./actor-types.js\";\nimport type {\n HookResult,\n ActorPlugin,\n PluginTransform,\n AnyConfig,\n ActorContextOf,\n ReflectionOptions,\n} from \"./actor-types.js\";\n\n// ── stop propagation sentinel ────────────────────────────────────────────\n\n// Re-exports from actor-types.ts (backward compatibility)\nexport { STOP_SENTINEL, stopPropagation, PROPAGATE_SENTINEL, propagateError };\nexport type { HookResult, ActorPlugin, PluginTransform };\n\n// ── type augmentation (Fastify-style) ────────────────────────────────────\n\n/**\n * Interface that plugins can augment via declaration merging.\n * Plugins ship a .d.ts that adds properties to this interface,\n * making them available on `this` in handlers and methods.\n *\n * Example (in a plugin's .d.ts):\n * declare module 'posipaki' {\n * interface ActorDecorated {\n * log: Logger;\n * }\n * }\n */\nexport interface ActorDecorated {}\n/** Reflection methods plugins and the framework add to every actor. Merged by\n * declaration, and held to {@link ReflectionOptions}' contract: async. */\nexport interface ActorReflection extends ReflectionOptions {}\n\n// ── chainHook ────────────────────────────────────────────────────────────\n\n/**\n * Compose two lifecycle hooks so that `plugin` fires first.\n *\n * If `plugin` returns the STOP_SENTINEL (via stopPropagation()),\n * `existing` is skipped entirely and the sentinel propagates.\n * Otherwise `existing` fires and its return value is used.\n *\n * Typical use in a plugin:\n * (cfg) => ({ ...cfg, onStart: chainHook(cfg.onStart, myOnStart) })\n *\n * @param existing - the current hook on the config (may be undefined)\n * @param plugin - the new hook to prepend\n * @returns a composed hook suitable for ActorConfig\n */\nexport function chainHook<TThis, TArgs extends unknown[]>(\n existing: ((this: TThis, ...args: TArgs) => HookResult | Promise<HookResult>) | undefined,\n plugin: (this: TThis, ...args: TArgs) => HookResult | Promise<HookResult>,\n): (this: TThis, ...args: TArgs) => HookResult | Promise<HookResult> {\n if (!existing) return plugin;\n return async function (this: TThis, ...args: TArgs): Promise<HookResult> {\n const result = await plugin.call(this, ...args);\n if (result === STOP_SENTINEL) return result;\n return await existing.call(this, ...args);\n } as (this: TThis, ...args: TArgs) => HookResult | Promise<HookResult>;\n}\n\n// ── mergeConfigs ─────────────────────────────────────────────────────────\n\n/**\n * Merge an overlay config into a base config, auto-chaining every on* hook.\n *\n * Each key in `overlay` that starts with \"on\" followed by an uppercase\n * letter (onStart, onMessage, onEmit, etc.) is composed via chainHook()\n * so that the overlay hook fires before the base hook, and stopPropagation\n * is respected.\n *\n * Typical use in a plugin:\n * return mergeConfigs(cfg, {\n * onStart() { this.log.info('starting'); },\n * beforeEnd() { this.log.info('stopping'); },\n * });\n *\n * @param base - the existing config (ActorConfig)\n * @param overlay - new hook implementations to prepend\n * @returns a new config with hooks chained\n */\nexport function mergeConfigs<C extends AnyConfig>(\n base: C,\n overlay: Partial<C> & ThisType<ActorContextOf<C>>,\n): C {\n const result = { ...base } as Record<string, unknown>;\n for (const key of Object.keys(overlay as Record<string, unknown>)) {\n const val = (overlay as Record<string, unknown>)[key];\n if (typeof val === \"function\" && /^(on|after|before)[A-Z]/.test(key)) {\n result[key] = chainHook(\n (base as Record<string, unknown>)[key] as (\n this: unknown,\n ...args: unknown[]\n ) => HookResult | Promise<HookResult>,\n val as (this: unknown, ...args: unknown[]) => HookResult | Promise<HookResult>,\n );\n } else {\n result[key] = val;\n }\n }\n result.$reflectionMethods = {};\n Object.assign(\n result.$reflectionMethods as object,\n \"$reflectionMethods\" in base ? base.$reflectionMethods : {},\n \"$reflectionMethods\" in overlay ? overlay.$reflectionMethods : {},\n );\n\n return result as unknown as C;\n}\n\nexport type Hook<T, I extends unknown[], O> = (this: T, ...args: I) => O;\n\nexport async function callHook<T, I extends unknown[], O>(\n fn: Hook<T, I, O> | undefined,\n eh: ((e: unknown) => unknown) | undefined,\n thisArg: T,\n ...args: I\n): Promise<O | undefined> {\n if (fn) {\n try {\n return await fn.call(thisArg, ...args);\n } catch (e) {\n if (eh) {\n let decision: unknown;\n try {\n decision = await eh(e);\n } catch {\n // An error inside the error handler must not mask the original one.\n }\n // An observing handler says so by returning the sentinel: the error it\n // did not handle keeps propagating, so the actor still goes down.\n if (decision === PROPAGATE_SENTINEL) throw e;\n } else {\n throw e;\n }\n }\n }\n return undefined;\n}\n"],"mappings":";;AA+PA,MAAa,gBAAgB,OAAO,0BAA0B;;AAG9D,MAAa,wBAA8C;;;;;;;;AAS3D,MAAa,qBAAqB,OAAO,yBAAyB;;AAGlE,MAAa,uBAAkD;;;;;;;;;;;;;;;;;AChN/D,SAAgB,UACd,UACA,QACmE;CACnE,IAAI,CAAC,UAAU,OAAO;CACtB,OAAO,eAA6B,GAAG,MAAkC;EACvE,MAAM,SAAS,MAAM,OAAO,KAAK,MAAM,GAAG,IAAI;EAC9C,IAAI,WAAW,eAAe,OAAO;EACrC,OAAO,MAAM,SAAS,KAAK,MAAM,GAAG,IAAI;CAC1C;AACF;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,aACd,MACA,SACG;CACH,MAAM,SAAS,EAAE,GAAG,KAAK;CACzB,KAAK,MAAM,OAAO,OAAO,KAAK,OAAkC,GAAG;EACjE,MAAM,MAAO,QAAoC;EACjD,IAAI,OAAO,QAAQ,cAAc,0BAA0B,KAAK,GAAG,GACjE,OAAO,OAAO,UACX,KAAiC,MAIlC,GACF;OAEA,OAAO,OAAO;CAElB;CACA,OAAO,qBAAqB,CAAC;CAC7B,OAAO,OACL,OAAO,oBACP,wBAAwB,OAAO,KAAK,qBAAqB,CAAC,GAC1D,wBAAwB,UAAU,QAAQ,qBAAqB,CAAC,CAClE;CAEA,OAAO;AACT;AAIA,eAAsB,SACpB,IACA,IACA,SACA,GAAG,MACqB;CACxB,IAAI,IACF,IAAI;EACF,OAAO,MAAM,GAAG,KAAK,SAAS,GAAG,IAAI;CACvC,SAAS,GAAG;EACV,IAAI,IAAI;GACN,IAAI;GACJ,IAAI;IACF,WAAW,MAAM,GAAG,CAAC;GACvB,QAAQ,CAER;GAGA,IAAI,aAAa,oBAAoB,MAAM;EAC7C,OACE,MAAM;CAEV;AAGJ"}
|
package/dist/hooks.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { S as stopPropagation, _ as PluginTransform, a as chainHook, d as ActorPlugin, g as PROPAGATE_SENTINEL, i as callHook, m as HookResult, n as ActorReflection, o as mergeConfigs, r as Hook, t as ActorDecorated, x as propagateError, y as STOP_SENTINEL } from "./hooks-
|
|
1
|
+
import { S as stopPropagation, _ as PluginTransform, a as chainHook, d as ActorPlugin, g as PROPAGATE_SENTINEL, i as callHook, m as HookResult, n as ActorReflection, o as mergeConfigs, r as Hook, t as ActorDecorated, x as propagateError, y as STOP_SENTINEL } from "./hooks-C5S7GIX_.js";
|
|
2
2
|
export { ActorDecorated, type ActorPlugin, ActorReflection, Hook, type HookResult, PROPAGATE_SENTINEL, type PluginTransform, STOP_SENTINEL, callHook, chainHook, mergeConfigs, propagateError, stopPropagation };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { a as ProcessFn, c as StopMessage, d as AnyProcess, f as AsyncProcess, i as ProcessCtx, l as WithSender, m as spawnAsync, n as ExitMessage, o as SenderInfo, p as runDispatchAsync, r as Message, s as SenderOrigin, t as AsyncProcessFn, u as WithoutSender } from "./types-
|
|
2
|
-
import { S as stopPropagation, _ as PluginTransform, a as chainHook, b as SpawnedFrom, c as ActorContext, d as ActorPlugin, f as HandlerFn, h as MethodOptions, i as callHook, l as ActorDefinition, m as HookResult, n as ActorReflection, o as mergeConfigs, p as HandlerOptions, s as ActorConfig, t as ActorDecorated, u as ActorMessages, v as ReflectionOptions, x as propagateError } from "./hooks-
|
|
3
|
-
import { n as spawn, t as Process } from "./process-
|
|
1
|
+
import { a as ProcessFn, c as StopMessage, d as AnyProcess, f as AsyncProcess, i as ProcessCtx, l as WithSender, m as spawnAsync, n as ExitMessage, o as SenderInfo, p as runDispatchAsync, r as Message, s as SenderOrigin, t as AsyncProcessFn, u as WithoutSender } from "./types-BuI2bfi4.js";
|
|
2
|
+
import { S as stopPropagation, _ as PluginTransform, a as chainHook, b as SpawnedFrom, c as ActorContext, d as ActorPlugin, f as HandlerFn, h as MethodOptions, i as callHook, l as ActorDefinition, m as HookResult, n as ActorReflection, o as mergeConfigs, p as HandlerOptions, s as ActorConfig, t as ActorDecorated, u as ActorMessages, v as ReflectionOptions, x as propagateError } from "./hooks-C5S7GIX_.js";
|
|
3
|
+
import { n as spawn, t as Process } from "./process-RsCsXWC1.js";
|
|
4
4
|
//#region src/util.d.ts
|
|
5
5
|
type ReducerClosure<M> = (msg: M) => void;
|
|
6
6
|
type ReadyFn = () => boolean;
|
|
@@ -20,7 +20,7 @@ declare function defineActor<Args, InternalState, InMsg extends Message, OutMsg
|
|
|
20
20
|
//#endregion
|
|
21
21
|
//#region src/version.d.ts
|
|
22
22
|
/** posipaki's release version. Must equal package.json's `version`. */
|
|
23
|
-
declare const LIB_VERSION = "0.
|
|
23
|
+
declare const LIB_VERSION = "0.39.0";
|
|
24
24
|
//#endregion
|
|
25
25
|
export { type ActorConfig, type ActorContext, type ActorDecorated, type ActorDefinition, type ActorPlugin, type ActorReflection, type AnyProcess, AsyncProcess, type AsyncProcessFn, type ExitMessage, type HandlerFn, type HandlerOptions, type HookResult, LIB_VERSION, type Message, type MethodOptions, type PluginTransform, Process, type ProcessCtx, type ProcessFn, type SenderInfo, type SenderOrigin, type SpawnedFrom, type StopMessage, type WithSender, type WithoutSender, asyncify, callHook, chainHook, defineActor, defineMessages, mergeConfigs, propagateError, runDispatch, runDispatchAsync, spawn, spawnAsync, stopPropagation };
|
|
26
26
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { i as runDispatch } from "./util-Brtfgv68.js";
|
|
2
|
-
import { a as
|
|
2
|
+
import { a as spawnAsync, i as runDispatchAsync, o as asyncify, t as AsyncProcess } from "./process.async-js1t-fd8.js";
|
|
3
3
|
import { n as chainHook, o as propagateError, r as mergeConfigs, s as stopPropagation, t as callHook } from "./hooks-CgXhmY4r.js";
|
|
4
|
-
import { t as
|
|
4
|
+
import { n as defineMessages, t as defineActor } from "./define-actor-jG-OgJng.js";
|
|
5
|
+
import { t as LIB_VERSION } from "./version-C-ToFw8V.js";
|
|
5
6
|
//#region src/process.ts
|
|
6
7
|
/** @deprecated Use {@link spawnAsync} instead. */
|
|
7
8
|
function spawn(fn, pname, tp) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/process.ts","../src/index.ts"],"sourcesContent":["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<A, S, IM extends Message = Message, OM extends Message = ExitMessage>(\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<A, S, IM extends Message, OM extends Message> extends AsyncProcess<A, S, IM, OM, {}> {\n constructor(fn: ProcessFn<A, S, IM, OM>, pname: string, tp?: (m: OM, from: SenderInfo) => void) {\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","/**\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 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, propagateError, mergeConfigs, chainHook, callHook } from \"./hooks.js\";\nexport type {\n HookResult,\n ActorPlugin,\n ActorDecorated,\n ActorReflection,\n PluginTransform,\n} from \"./hooks.js\";\nexport { LIB_VERSION } from \"./version.js\";\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/process.ts","../src/index.ts"],"sourcesContent":["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<A, S, IM extends Message = Message, OM extends Message = ExitMessage>(\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<A, S, IM extends Message, OM extends Message> extends AsyncProcess<A, S, IM, OM, {}> {\n constructor(fn: ProcessFn<A, S, IM, OM>, pname: string, tp?: (m: OM, from: SenderInfo) => void) {\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","/**\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 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, propagateError, mergeConfigs, chainHook, callHook } from \"./hooks.js\";\nexport type {\n HookResult,\n ActorPlugin,\n ActorDecorated,\n ActorReflection,\n PluginTransform,\n} from \"./hooks.js\";\nexport { LIB_VERSION } from \"./version.js\";\n"],"mappings":";;;;;;;AAQA,SAAgB,MACd,IACA,OACA,IACiC;CACjC,QAAQ,MAAS,IAAI,QAAQ,IAAI,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC;AACrD;;;AAIA,IAAM,UAAN,cAAoE,aAA+B;CACjG,YAAY,IAA6B,OAAe,IAAwC;EAC9F,MAAM,SAAS,EAAE,GAAG,OAAO,EAAE;CAC/B;CAEA,MAAM,GAAM;EACV,MAAM,MAAM,CAAC;EACb,OAAO;CACT;CACA,OAAsB;EACpB,OAAO,MAAM,QAAQ;CACvB;AACF"}
|