posipaki 0.29.0 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as Message } from "../types-BsynPeOf.js";
|
|
1
|
+
import { o as SenderInfo, r as Message } from "../types-BsynPeOf.js";
|
|
2
2
|
import { d as ActorPlugin } from "../hooks-DDlJQJi_.js";
|
|
3
3
|
//#region src/plugins/debug-logger.d.ts
|
|
4
4
|
declare module "../index" {
|
|
@@ -9,8 +9,18 @@ declare module "../index" {
|
|
|
9
9
|
interface DebugLogFn {
|
|
10
10
|
(message: string, ...args: unknown[]): void;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Optional context for a logged message. The plugin fills both fields for the
|
|
14
|
+
* traffic it observes; a caller logging a message by hand may omit them.
|
|
15
|
+
*/
|
|
16
|
+
interface MessageLogOpts {
|
|
17
|
+
/** Who sent it. Present for traffic observed by the plugin. */
|
|
18
|
+
sender?: SenderInfo;
|
|
19
|
+
/** Direction: "in" = received by this actor, "out" = emitted by it. */
|
|
20
|
+
direction?: "in" | "out";
|
|
21
|
+
}
|
|
12
22
|
interface MessageLogFn {
|
|
13
|
-
(message: Message): void;
|
|
23
|
+
(message: Message, opts?: MessageLogOpts): void;
|
|
14
24
|
}
|
|
15
25
|
interface LifecycleLogFn {
|
|
16
26
|
(event: string, detail?: unknown): void;
|
|
@@ -53,5 +63,5 @@ declare function defaultMsgFilter(msg: Message): Message;
|
|
|
53
63
|
*/
|
|
54
64
|
declare function debugLogger(opts?: DebugLoggerOpts): ActorPlugin;
|
|
55
65
|
//#endregion
|
|
56
|
-
export { DebugLogFn, DebugLoggerOpts, LifecycleLogFn, Logger, LoggerFactory, MessageLogFn, MsgFilter, debugLogger, defaultMsgFilter };
|
|
66
|
+
export { DebugLogFn, DebugLoggerOpts, LifecycleLogFn, Logger, LoggerFactory, MessageLogFn, MessageLogOpts, MsgFilter, debugLogger, defaultMsgFilter };
|
|
57
67
|
//# sourceMappingURL=debug-logger.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debug-logger.d.ts","names":[],"sources":["../../src/plugins/debug-logger.ts"],"mappings":";;;;YAKY;IACR,KAAK;;;UAIQ;GACd,oBAAoB;;
|
|
1
|
+
{"version":3,"file":"debug-logger.d.ts","names":[],"sources":["../../src/plugins/debug-logger.ts"],"mappings":";;;;YAKY;IACR,KAAK;;;UAIQ;GACd,oBAAoB;;;;;;UAMN;;EAEf,SAAS;;EAET;;UAEe;GACd,SAAS,SAAS,OAAO;;UAEX;GACd,eAAe;;UAGD;EACf,OAAO;EACP,MAAM;EACN,MAAM;EACN,OAAO;EACP,KAAK;EACL,WAAW;;KAED,iBAAiB,iBAAiB;;;;;;KAOlC,aAAa,KAAK,YAAY;UAEzB;;EAEf;EACA,UAAU;;;EAGV,YAAY;;;;;;;iBAYE,iBAAiB,KAAK,UAAU;;;;;;;;iBAsEhC,YAAY,OAAO,kBAAkB"}
|
|
@@ -27,7 +27,7 @@ function defaultMsgFilter(msg) {
|
|
|
27
27
|
function defaultFactory(name) {
|
|
28
28
|
return {
|
|
29
29
|
debug: (...a) => console.debug(`[${name}]`, ...a),
|
|
30
|
-
msg: (msg) => console.debug(`[${name}]
|
|
30
|
+
msg: (msg, opts) => console.debug(`[${name}] ${opts?.direction === "out" ? "→" : "←"} ${msg.type}`, msg),
|
|
31
31
|
info: (...a) => console.info(`[${name}]`, ...a),
|
|
32
32
|
warn: (...a) => console.warn(`[${name}]`, ...a),
|
|
33
33
|
error: (...a) => console.error(`[${name}]`, ...a),
|
|
@@ -35,6 +35,36 @@ function defaultFactory(name) {
|
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
38
|
+
* A logger that is constructed on first use, and rebuilt if the name it is
|
|
39
|
+
* bound to changes.
|
|
40
|
+
*
|
|
41
|
+
* The plugin cannot build its logger eagerly: `config.name` is only a
|
|
42
|
+
* *preferred* name — most actors leave it unset and get their process name
|
|
43
|
+
* assigned by the framework — so binding a logger to it at plugin time files
|
|
44
|
+
* every entry under the fallback name. Deferring construction until the actor
|
|
45
|
+
* has actually started means the factory always receives the resolved name.
|
|
46
|
+
*/
|
|
47
|
+
function deferredLogger(factory, getName) {
|
|
48
|
+
let inner = null;
|
|
49
|
+
let boundTo = null;
|
|
50
|
+
const resolve = () => {
|
|
51
|
+
const name = getName();
|
|
52
|
+
if (!inner || boundTo !== name) {
|
|
53
|
+
inner = factory(name);
|
|
54
|
+
boundTo = name;
|
|
55
|
+
}
|
|
56
|
+
return inner;
|
|
57
|
+
};
|
|
58
|
+
return {
|
|
59
|
+
debug: (msg, ...args) => resolve().debug(msg, ...args),
|
|
60
|
+
info: (msg, ...args) => resolve().info(msg, ...args),
|
|
61
|
+
warn: (msg, ...args) => resolve().warn(msg, ...args),
|
|
62
|
+
error: (msg, ...args) => resolve().error(msg, ...args),
|
|
63
|
+
msg: (msg, opts) => resolve().msg(msg, opts),
|
|
64
|
+
lifecycle: (event, detail) => resolve().lifecycle(event, detail)
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
38
68
|
* A debug/logging plugin that decorates `this.log` and observes the actor
|
|
39
69
|
* lifecycle (started / stopping / stopped / child-exited / error) plus message
|
|
40
70
|
* traffic. Hook registration is no longer gated by `DEBUG` — the supplied
|
|
@@ -46,13 +76,16 @@ function debugLogger(opts) {
|
|
|
46
76
|
const factory = opts?.factory ?? defaultFactory;
|
|
47
77
|
const msgFilter = opts?.msgFilter ?? defaultMsgFilter;
|
|
48
78
|
return async function debugLoggerPlugin(config) {
|
|
49
|
-
|
|
50
|
-
const log = factory(name);
|
|
79
|
+
let name = config.name ?? "actor";
|
|
80
|
+
const log = deferredLogger(factory, () => name);
|
|
51
81
|
let result = mergeConfigs(config, {
|
|
52
82
|
methods: { ...config.methods },
|
|
53
83
|
$decorate: { log }
|
|
54
84
|
});
|
|
55
85
|
result = mergeConfigs(result, {
|
|
86
|
+
beforeStart() {
|
|
87
|
+
name = this.name;
|
|
88
|
+
},
|
|
56
89
|
afterStart() {
|
|
57
90
|
log.lifecycle("started");
|
|
58
91
|
},
|
|
@@ -68,15 +101,21 @@ function debugLogger(opts) {
|
|
|
68
101
|
onError(err) {
|
|
69
102
|
log.error(`${err?.message ?? err}`);
|
|
70
103
|
},
|
|
71
|
-
onMessage(msg) {
|
|
104
|
+
onMessage(msg, sender) {
|
|
72
105
|
if (ignoreSet.has(msg.type)) return;
|
|
73
106
|
const m = msgFilter ? msgFilter(msg) : msg;
|
|
74
|
-
if (m) log.msg(m
|
|
107
|
+
if (m) log.msg(m, {
|
|
108
|
+
sender,
|
|
109
|
+
direction: "in"
|
|
110
|
+
});
|
|
75
111
|
},
|
|
76
|
-
onEmit(msg) {
|
|
112
|
+
onEmit(msg, sender) {
|
|
77
113
|
if (ignoreSet.has(msg.type)) return;
|
|
78
114
|
const m = msgFilter ? msgFilter(msg) : msg;
|
|
79
|
-
if (m) log.
|
|
115
|
+
if (m) log.msg(m, {
|
|
116
|
+
sender,
|
|
117
|
+
direction: "out"
|
|
118
|
+
});
|
|
80
119
|
}
|
|
81
120
|
});
|
|
82
121
|
return result;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debug-logger.js","names":[],"sources":["../../src/plugins/debug-logger.ts"],"sourcesContent":["import type { ActorPlugin } from \"../hooks\";\nimport { mergeConfigs } from \"../hooks\";\nimport type { Message } from \"../types\";\n\ndeclare module \"../index\" {\n interface ActorDecorated {\n log: Logger;\n }\n}\n\nexport interface DebugLogFn {\n (message: string, ...args: unknown[]): void;\n}\nexport interface MessageLogFn {\n (message: Message): void;\n}\nexport interface LifecycleLogFn {\n (event: string, detail?: unknown): void;\n}\n\nexport interface Logger {\n debug: DebugLogFn;\n info: DebugLogFn;\n warn: DebugLogFn;\n error: DebugLogFn;\n msg: MessageLogFn;\n lifecycle: LifecycleLogFn;\n}\nexport type LoggerFactory = (name: string) => Logger;\n\n/**\n * Filter a message before it is logged. Return a (possibly shrunk) message,\n * or `null` to skip it entirely. Used to keep large payloads — a full\n * conversation history, a big tool result — out of the log scroll.\n */\nexport type MsgFilter = (msg: Message) => Message | null;\n\nexport interface DebugLoggerOpts {\n /** Message types to skip entirely (in addition to any `msgFilter`). */\n ignore?: string[];\n factory?: LoggerFactory;\n /** Shrink or skip a message before it is logged via onMessage/onEmit.\n * Defaults to {@link defaultMsgFilter}. */\n msgFilter?: MsgFilter;\n}\n\n/** Fields larger than this are shrunk by {@link defaultMsgFilter}. */\nconst MAX_STRING = 256;\nconst MAX_ARRAY = 16;\n\n/**\n * Default message filter: shrink oversized string/array fields in place so a\n * single message (a full conversation history, a big tool result) can't flood\n * the log. Returns the message unchanged when nothing needs shrinking.\n */\nexport function defaultMsgFilter(msg: Message): Message {\n const src = msg as unknown as Record<string, unknown>;\n const shrunk: Record<string, unknown> = { ...src };\n let changed = false;\n for (const key of Object.keys(src)) {\n const v = src[key];\n if (typeof v === \"string\" && v.length > MAX_STRING) {\n shrunk[key] = `${v.slice(0, MAX_STRING)}… (${v.length} chars)`;\n changed = true;\n } else if (Array.isArray(v) && v.length > MAX_ARRAY) {\n shrunk[key] = `[${v.length} items]`;\n changed = true;\n }\n }\n return changed ? (shrunk as unknown as Message) : msg;\n}\n\nfunction defaultFactory(name: string): Logger {\n return {\n debug: (...a: unknown[]) => console.debug(`[${name}]`, ...a),\n msg: (msg: Message)
|
|
1
|
+
{"version":3,"file":"debug-logger.js","names":[],"sources":["../../src/plugins/debug-logger.ts"],"sourcesContent":["import type { ActorPlugin } from \"../hooks\";\nimport { mergeConfigs } from \"../hooks\";\nimport type { Message, SenderInfo } from \"../types\";\n\ndeclare module \"../index\" {\n interface ActorDecorated {\n log: Logger;\n }\n}\n\nexport interface DebugLogFn {\n (message: string, ...args: unknown[]): void;\n}\n/**\n * Optional context for a logged message. The plugin fills both fields for the\n * traffic it observes; a caller logging a message by hand may omit them.\n */\nexport interface MessageLogOpts {\n /** Who sent it. Present for traffic observed by the plugin. */\n sender?: SenderInfo;\n /** Direction: \"in\" = received by this actor, \"out\" = emitted by it. */\n direction?: \"in\" | \"out\";\n}\nexport interface MessageLogFn {\n (message: Message, opts?: MessageLogOpts): void;\n}\nexport interface LifecycleLogFn {\n (event: string, detail?: unknown): void;\n}\n\nexport interface Logger {\n debug: DebugLogFn;\n info: DebugLogFn;\n warn: DebugLogFn;\n error: DebugLogFn;\n msg: MessageLogFn;\n lifecycle: LifecycleLogFn;\n}\nexport type LoggerFactory = (name: string) => Logger;\n\n/**\n * Filter a message before it is logged. Return a (possibly shrunk) message,\n * or `null` to skip it entirely. Used to keep large payloads — a full\n * conversation history, a big tool result — out of the log scroll.\n */\nexport type MsgFilter = (msg: Message) => Message | null;\n\nexport interface DebugLoggerOpts {\n /** Message types to skip entirely (in addition to any `msgFilter`). */\n ignore?: string[];\n factory?: LoggerFactory;\n /** Shrink or skip a message before it is logged via onMessage/onEmit.\n * Defaults to {@link defaultMsgFilter}. */\n msgFilter?: MsgFilter;\n}\n\n/** Fields larger than this are shrunk by {@link defaultMsgFilter}. */\nconst MAX_STRING = 256;\nconst MAX_ARRAY = 16;\n\n/**\n * Default message filter: shrink oversized string/array fields in place so a\n * single message (a full conversation history, a big tool result) can't flood\n * the log. Returns the message unchanged when nothing needs shrinking.\n */\nexport function defaultMsgFilter(msg: Message): Message {\n const src = msg as unknown as Record<string, unknown>;\n const shrunk: Record<string, unknown> = { ...src };\n let changed = false;\n for (const key of Object.keys(src)) {\n const v = src[key];\n if (typeof v === \"string\" && v.length > MAX_STRING) {\n shrunk[key] = `${v.slice(0, MAX_STRING)}… (${v.length} chars)`;\n changed = true;\n } else if (Array.isArray(v) && v.length > MAX_ARRAY) {\n shrunk[key] = `[${v.length} items]`;\n changed = true;\n }\n }\n return changed ? (shrunk as unknown as Message) : msg;\n}\n\nfunction defaultFactory(name: string): Logger {\n return {\n debug: (...a: unknown[]) => console.debug(`[${name}]`, ...a),\n msg: (msg: Message, opts?: MessageLogOpts) =>\n console.debug(`[${name}] ${opts?.direction === \"out\" ? \"→\" : \"←\"} ${msg.type}`, msg),\n info: (...a: unknown[]) => console.info(`[${name}]`, ...a),\n warn: (...a: unknown[]) => console.warn(`[${name}]`, ...a),\n error: (...a: unknown[]) => console.error(`[${name}]`, ...a),\n lifecycle: (event: string, detail?: unknown) =>\n console.debug(`[${name}] lifecycle ${event}`, detail ?? \"\"),\n };\n}\n\n/**\n * A logger that is constructed on first use, and rebuilt if the name it is\n * bound to changes.\n *\n * The plugin cannot build its logger eagerly: `config.name` is only a\n * *preferred* name — most actors leave it unset and get their process name\n * assigned by the framework — so binding a logger to it at plugin time files\n * every entry under the fallback name. Deferring construction until the actor\n * has actually started means the factory always receives the resolved name.\n */\nfunction deferredLogger(factory: LoggerFactory, getName: () => string): Logger {\n let inner: Logger | null = null;\n let boundTo: string | null = null;\n\n const resolve = (): Logger => {\n const name = getName();\n if (!inner || boundTo !== name) {\n inner = factory(name);\n boundTo = name;\n }\n return inner;\n };\n\n return {\n debug: (msg: string, ...args: unknown[]) => resolve().debug(msg, ...args),\n info: (msg: string, ...args: unknown[]) => resolve().info(msg, ...args),\n warn: (msg: string, ...args: unknown[]) => resolve().warn(msg, ...args),\n error: (msg: string, ...args: unknown[]) => resolve().error(msg, ...args),\n msg: (msg: Message, opts?: MessageLogOpts) => resolve().msg(msg, opts),\n lifecycle: (event: string, detail?: unknown) => resolve().lifecycle(event, detail),\n };\n}\n\n/**\n * A debug/logging plugin that decorates `this.log` and observes the actor\n * lifecycle (started / stopping / stopped / child-exited / error) plus message\n * traffic. Hook registration is no longer gated by `DEBUG` — the supplied\n * factory decides what to actually emit, so a ringbuffer (or anything else)\n * can gate output at runtime.\n */\nexport function debugLogger(opts?: DebugLoggerOpts): ActorPlugin {\n const ignoreSet = new Set(opts?.ignore ?? []);\n const factory = opts?.factory ?? defaultFactory;\n const msgFilter = opts?.msgFilter ?? defaultMsgFilter;\n return async function debugLoggerPlugin(config) {\n // Preferred name as a placeholder; replaced with the resolved process name\n // in `beforeStart`, before anything is logged.\n let name: string = config.name ?? \"actor\";\n const log = deferredLogger(factory, () => name);\n\n let result = mergeConfigs(config, {\n methods: { ...config.methods },\n $decorate: { log },\n });\n\n result = mergeConfigs(result, {\n beforeStart() {\n name = this.name;\n },\n afterStart() {\n log.lifecycle(\"started\");\n },\n beforeEnd(reason: unknown) {\n log.lifecycle(\"stopping\", reason);\n },\n afterEnd(reason: unknown) {\n log.lifecycle(\"stopped\", reason);\n },\n onChildExit(childName: string) {\n log.lifecycle(\"child-exited\", childName);\n },\n onError(err: unknown) {\n log.error(`${(err as Error)?.message ?? err}`);\n },\n onMessage(msg: Message, sender: SenderInfo) {\n if (ignoreSet.has(msg.type)) return;\n const m = msgFilter ? msgFilter(msg) : msg;\n if (m) log.msg(m, { sender, direction: \"in\" });\n },\n onEmit(msg: Message, sender: SenderInfo) {\n if (ignoreSet.has(msg.type)) return;\n const m = msgFilter ? msgFilter(msg) : msg;\n if (m) log.msg(m, { sender, direction: \"out\" });\n },\n });\n\n return result;\n };\n}\n"],"mappings":"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"}
|