lograil 0.1.0 → 0.1.4

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.
Files changed (149) hide show
  1. package/CHANGELOG.md +105 -1
  2. package/README.md +3 -1
  3. package/dist/cjs/context/async-context.browser.d.ts +1 -7
  4. package/dist/cjs/context/async-context.browser.d.ts.map +1 -1
  5. package/dist/cjs/context/async-context.browser.js +4 -1
  6. package/dist/cjs/context/async-context.browser.js.map +1 -1
  7. package/dist/cjs/context/context.js +1 -1
  8. package/dist/cjs/context/context.js.map +1 -1
  9. package/dist/cjs/core/logger.d.ts +20 -16
  10. package/dist/cjs/core/logger.d.ts.map +1 -1
  11. package/dist/cjs/core/logger.js +115 -48
  12. package/dist/cjs/core/logger.js.map +1 -1
  13. package/dist/cjs/pipeline/formatter.d.ts.map +1 -1
  14. package/dist/cjs/pipeline/formatter.js +64 -31
  15. package/dist/cjs/pipeline/formatter.js.map +1 -1
  16. package/dist/cjs/pipeline/pipeline.d.ts.map +1 -1
  17. package/dist/cjs/pipeline/pipeline.js +2 -1
  18. package/dist/cjs/pipeline/pipeline.js.map +1 -1
  19. package/dist/cjs/pipeline/processor.d.ts.map +1 -1
  20. package/dist/cjs/pipeline/processor.js +18 -6
  21. package/dist/cjs/pipeline/processor.js.map +1 -1
  22. package/dist/cjs/pipeline/sampler.d.ts.map +1 -1
  23. package/dist/cjs/pipeline/sampler.js +5 -0
  24. package/dist/cjs/pipeline/sampler.js.map +1 -1
  25. package/dist/cjs/plugin/manager.d.ts.map +1 -1
  26. package/dist/cjs/plugin/manager.js +9 -1
  27. package/dist/cjs/plugin/manager.js.map +1 -1
  28. package/dist/cjs/plugin/otel-trace.d.ts.map +1 -1
  29. package/dist/cjs/plugin/otel-trace.js +4 -7
  30. package/dist/cjs/plugin/otel-trace.js.map +1 -1
  31. package/dist/cjs/runtime/electron-binding.d.ts +4 -0
  32. package/dist/cjs/runtime/electron-binding.d.ts.map +1 -1
  33. package/dist/cjs/runtime/electron-binding.js +24 -2
  34. package/dist/cjs/runtime/electron-binding.js.map +1 -1
  35. package/dist/cjs/runtime/electron.d.ts.map +1 -1
  36. package/dist/cjs/runtime/electron.js +7 -1
  37. package/dist/cjs/runtime/electron.js.map +1 -1
  38. package/dist/cjs/runtime/process-lifecycle.d.ts.map +1 -1
  39. package/dist/cjs/runtime/process-lifecycle.js +11 -0
  40. package/dist/cjs/runtime/process-lifecycle.js.map +1 -1
  41. package/dist/cjs/transport/cluster-ipc.d.ts +2 -0
  42. package/dist/cjs/transport/cluster-ipc.d.ts.map +1 -1
  43. package/dist/cjs/transport/cluster-ipc.js +53 -5
  44. package/dist/cjs/transport/cluster-ipc.js.map +1 -1
  45. package/dist/cjs/transport/console.d.ts.map +1 -1
  46. package/dist/cjs/transport/console.js +10 -9
  47. package/dist/cjs/transport/console.js.map +1 -1
  48. package/dist/cjs/transport/electron-ipc.d.ts +4 -17
  49. package/dist/cjs/transport/electron-ipc.d.ts.map +1 -1
  50. package/dist/cjs/transport/electron-ipc.js +42 -73
  51. package/dist/cjs/transport/electron-ipc.js.map +1 -1
  52. package/dist/cjs/transport/file.d.ts +10 -4
  53. package/dist/cjs/transport/file.d.ts.map +1 -1
  54. package/dist/cjs/transport/file.js +28 -8
  55. package/dist/cjs/transport/file.js.map +1 -1
  56. package/dist/cjs/transport/live.d.ts +2 -1
  57. package/dist/cjs/transport/live.d.ts.map +1 -1
  58. package/dist/cjs/transport/live.js +4 -1
  59. package/dist/cjs/transport/live.js.map +1 -1
  60. package/dist/cjs/transport/otlp.d.ts +1 -1
  61. package/dist/cjs/transport/otlp.d.ts.map +1 -1
  62. package/dist/cjs/transport/otlp.js +24 -21
  63. package/dist/cjs/transport/otlp.js.map +1 -1
  64. package/dist/cjs/transport/worker-ipc.d.ts +3 -0
  65. package/dist/cjs/transport/worker-ipc.d.ts.map +1 -1
  66. package/dist/cjs/transport/worker-ipc.js +76 -8
  67. package/dist/cjs/transport/worker-ipc.js.map +1 -1
  68. package/dist/cjs/types.d.ts +16 -5
  69. package/dist/cjs/types.d.ts.map +1 -1
  70. package/dist/cjs/types.js +5 -1
  71. package/dist/cjs/types.js.map +1 -1
  72. package/dist/esm/context/async-context.browser.d.ts +1 -7
  73. package/dist/esm/context/async-context.browser.d.ts.map +1 -1
  74. package/dist/esm/context/async-context.browser.js +4 -1
  75. package/dist/esm/context/async-context.browser.js.map +1 -1
  76. package/dist/esm/context/context.js +1 -1
  77. package/dist/esm/context/context.js.map +1 -1
  78. package/dist/esm/core/logger.d.ts +20 -16
  79. package/dist/esm/core/logger.d.ts.map +1 -1
  80. package/dist/esm/core/logger.js +115 -48
  81. package/dist/esm/core/logger.js.map +1 -1
  82. package/dist/esm/pipeline/formatter.d.ts.map +1 -1
  83. package/dist/esm/pipeline/formatter.js +64 -31
  84. package/dist/esm/pipeline/formatter.js.map +1 -1
  85. package/dist/esm/pipeline/pipeline.d.ts.map +1 -1
  86. package/dist/esm/pipeline/pipeline.js +2 -1
  87. package/dist/esm/pipeline/pipeline.js.map +1 -1
  88. package/dist/esm/pipeline/processor.d.ts.map +1 -1
  89. package/dist/esm/pipeline/processor.js +18 -6
  90. package/dist/esm/pipeline/processor.js.map +1 -1
  91. package/dist/esm/pipeline/sampler.d.ts.map +1 -1
  92. package/dist/esm/pipeline/sampler.js +5 -0
  93. package/dist/esm/pipeline/sampler.js.map +1 -1
  94. package/dist/esm/plugin/manager.d.ts.map +1 -1
  95. package/dist/esm/plugin/manager.js +9 -1
  96. package/dist/esm/plugin/manager.js.map +1 -1
  97. package/dist/esm/plugin/otel-trace.d.ts.map +1 -1
  98. package/dist/esm/plugin/otel-trace.js +4 -7
  99. package/dist/esm/plugin/otel-trace.js.map +1 -1
  100. package/dist/esm/runtime/electron-binding.d.ts +4 -0
  101. package/dist/esm/runtime/electron-binding.d.ts.map +1 -1
  102. package/dist/esm/runtime/electron-binding.js +24 -2
  103. package/dist/esm/runtime/electron-binding.js.map +1 -1
  104. package/dist/esm/runtime/electron.d.ts.map +1 -1
  105. package/dist/esm/runtime/electron.js +7 -1
  106. package/dist/esm/runtime/electron.js.map +1 -1
  107. package/dist/esm/runtime/process-lifecycle.d.ts.map +1 -1
  108. package/dist/esm/runtime/process-lifecycle.js +11 -0
  109. package/dist/esm/runtime/process-lifecycle.js.map +1 -1
  110. package/dist/esm/transport/cluster-ipc.d.ts +2 -0
  111. package/dist/esm/transport/cluster-ipc.d.ts.map +1 -1
  112. package/dist/esm/transport/cluster-ipc.js +52 -5
  113. package/dist/esm/transport/cluster-ipc.js.map +1 -1
  114. package/dist/esm/transport/console.d.ts.map +1 -1
  115. package/dist/esm/transport/console.js +10 -9
  116. package/dist/esm/transport/console.js.map +1 -1
  117. package/dist/esm/transport/electron-ipc.d.ts +4 -17
  118. package/dist/esm/transport/electron-ipc.d.ts.map +1 -1
  119. package/dist/esm/transport/electron-ipc.js +42 -71
  120. package/dist/esm/transport/electron-ipc.js.map +1 -1
  121. package/dist/esm/transport/file.d.ts +10 -4
  122. package/dist/esm/transport/file.d.ts.map +1 -1
  123. package/dist/esm/transport/file.js +28 -8
  124. package/dist/esm/transport/file.js.map +1 -1
  125. package/dist/esm/transport/live.d.ts +2 -1
  126. package/dist/esm/transport/live.d.ts.map +1 -1
  127. package/dist/esm/transport/live.js +4 -1
  128. package/dist/esm/transport/live.js.map +1 -1
  129. package/dist/esm/transport/otlp.d.ts +1 -1
  130. package/dist/esm/transport/otlp.d.ts.map +1 -1
  131. package/dist/esm/transport/otlp.js +24 -21
  132. package/dist/esm/transport/otlp.js.map +1 -1
  133. package/dist/esm/transport/worker-ipc.d.ts +3 -0
  134. package/dist/esm/transport/worker-ipc.d.ts.map +1 -1
  135. package/dist/esm/transport/worker-ipc.js +75 -8
  136. package/dist/esm/transport/worker-ipc.js.map +1 -1
  137. package/dist/esm/types.d.ts +16 -5
  138. package/dist/esm/types.d.ts.map +1 -1
  139. package/dist/esm/types.js +5 -1
  140. package/dist/esm/types.js.map +1 -1
  141. package/package.json +12 -3
  142. package/dist/cjs/transport/rotating-file.d.ts +0 -67
  143. package/dist/cjs/transport/rotating-file.d.ts.map +0 -1
  144. package/dist/cjs/transport/rotating-file.js +0 -179
  145. package/dist/cjs/transport/rotating-file.js.map +0 -1
  146. package/dist/esm/transport/rotating-file.d.ts +0 -67
  147. package/dist/esm/transport/rotating-file.d.ts.map +0 -1
  148. package/dist/esm/transport/rotating-file.js +0 -175
  149. package/dist/esm/transport/rotating-file.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -4,8 +4,107 @@ All notable changes to this project are documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). This file is generated from git history by `scripts/gen-changelog.mjs` (run via `yarn changelog`) and refreshed automatically on each release.
6
6
 
7
- ## [Unreleased] - 2026-08-29
7
+ ## [v0.1.4] - 2026-09-04
8
8
 
9
+ - chore: 在 package.json 补充 repository、homepage 与 bugs 元信息
10
+ - 0.1.4
11
+ - ci: 升级 actions/setup-node 至 v6,发布环境改用 Node 24 并简化 npm publish
12
+
13
+ ## [v0.1.3] - 2026-09-04
14
+
15
+ - 0.1.3
16
+ - docs: 在 AGENTS.md 新增类型检查章节,记录 typecheck 双命令与常见测试类型陷阱
17
+ - fix: 修复测试类型定义与 OpenTelemetry 类型路径
18
+
19
+ ## [v0.1.2] - 2026-09-04
20
+
21
+ - 0.1.2
22
+ - ci: 移除 Publish 步骤的 NODE_AUTH_TOKEN,改用 npm OIDC 可信发布
23
+ - test: 补充 PluginContext 移除 transport/卸载插件与 setOnLevelCommand 回调接线的用例
24
+ - fix: 处理缺失 Electron 二进制时的错误,返回最小存根以避免运行时崩溃
25
+ - fix: 安全审计修复 8 个隐患问题,补充 10 个回归测试
26
+ - fix: add global deduplication for cluster/worker/electron IPC receivers
27
+ - chore: remove zero-copy IPC path from ElectronIpcTransport and update docs
28
+ - feat: 添加 log 方法作为 info 的别名
29
+ - fix: inject ipcRenderer explicitly in createElectronRuntime renderer path
30
+ - fix: remove invalid buffer transfer arg from electron postMessage calls
31
+ - chore: bump @opentelemetry/api peer dependency to ^1.9.1 and simplify dynamic import
32
+ - Optimize sampler, console, and context for performance improvements (#2)
33
+
34
+ ## [v0.1.1] - 2026-09-02
35
+
36
+ - 0.1.1
37
+ - test: increase timeout for single mode capacity caps no-op test
38
+ - docs: add Glossary page and clarify key terms in guides
39
+ - docs: add per-transport level filtering, clarify scope vs child, fix plugin immutability
40
+ - refactor: rename namespace options to scope for consistency
41
+ - docs: add Context & Metadata guide and cross-link across docs
42
+ - feat: accept non-Error values as error in log entries
43
+ - test: add coverage tests for serialize processors and jsonFormatter, simplify vitest config
44
+ - ci: simplify docs deploy to latest root only, drop versioned docs and versions.json
45
+ - ci: use orphan commits for docs branch deployments
46
+ - Harden logging pipeline edge cases: OTLP flush drain, rotation semantics, plugin rollback, and transport teardown (#1)
47
+ - test: add braces to arrow function callback in signal handler test
48
+ - test: add integration tests for Node runtime cluster and worker_threads
49
+ - test: add coverage for edge cases in printf, formatter, pipeline, serializer, and sampler
50
+ - test: add coverage for edge cases in formatter, lifecycle, processor, and runtime
51
+ - test: add integration tests for LiveTransport replay/buffer and Logger.destroy edge cases
52
+ - test: add process handler cleanup and fix LiveTransport buffer validation
53
+ - fix: properly restore previous onmessage handler and add close to WorkerIpcTransport
54
+ - perf: replace unbounded dispatch promise chain with bounded inflight counter
55
+ - perf: cache namespace filters and share mutable path in redactNode
56
+ - docs: translate pronunciation guide to English
57
+ - docs: add pronunciation guide for lograil
58
+ - fix: correct GitHub repo name in logo URL from electron-logger to lograil
59
+ - fix: update logo image URL to GitHub raw link in README.md
60
+ - chore: update logo SVG design to train wheel motif
61
+
62
+ ## [v0.1.0] - 2026-09-01
63
+
64
+ - chore: add author field to package.json
65
+ - test: remove unused LOG_LEVELS import and _entry helper
66
+ - feat(core): getLevel() returns peer level for cross-process consistency
67
+ - feat(transport): add cross-process log level sync via IPC
68
+ - feat(transport): add FileTransport file inspection API and tests
69
+ - test: align write calls with updated Transport interface signature
70
+ - fix(electron-ipc,core): surface IPC transport errors and guard flush against stalls
71
+ - refactor(transport): align write signatures with Transport interface
72
+ - docs: enable Mermaid support in VitePress docs
73
+ - docs(plugins): expand lifecycle docs with flow diagrams and error handling
74
+ - feat(worker-threads): add automatic log forwarding from workers to main thread
75
+ - feat(node): add cluster support with automatic worker-to-primary log forwarding
76
+ - docs: add runtime-specific guides and update navigation
77
+ - docs(FileTransport): document name option semantics
78
+ - refactor(FileTransport): remove custom fileName option from rotate-size and rotate-time modes
79
+ - feat(runtime): apply disk-safety defaults to default file transports and add maxFilesPerBucket cap
80
+ - feat(FileTransport): split rotate-time buckets by maxSize and trim maxFiles by time bucket
81
+ - docs: document browser bundling and web runtime usage
82
+ - fix(test): ensure dist directory exists before writing browser bundle
83
+ - feat(shims): add browser-compatible Node API shims and enforce their use
84
+ - fix(FileTransport): clarify maxAge semantics, track owned files, and suppress repeated write errors
85
+ - feat(FileTransport): add global capacity caps (maxTotalSize / maxAge) with throttled checks
86
+ - feat(runtime): move Electron log dir to app.getPath('logs'), allow dir override
87
+ - refactor(FileTransport): split 5 modes into isolated Rotator strategies
88
+ - fix(FileTransport): harden single-truncate on Windows and resume rotate-time ring on restart
89
+ - feat: replace RotatingFileTransport with unified FileTransport (5 modes, appName required)
90
+ - docs: reposition as universal logging library with Web/Node/Electron as first-class runtimes, plugins for other platforms
91
+ - docs: document runtime lifecycle hooks and Electron app quit events
92
+ - feat: wire runtime lifecycle hooks and cover Electron app quit events
93
+ - ci(test): harden verify.yml, lift coverage past 90% and fix otel-trace crash
94
+ - feat: lightweight child/scope loggers and printf-style message formatting
95
+ - perf: eliminate per-call allocations on hot path and fix transport queue leak
96
+ - style(theme): flatten version map
97
+ - fix(core): flush logs on exit with timeout safety
98
+ - docs(agents): add documentation wording guidelines
99
+ - docs(guide): add Introduction chapter covering what/why/when and core concepts
100
+ - docs(transport): restructure LiveTransport guide into entity vs formatted-string rendering
101
+ - fix(test): close loggers before removing temp dir in node-file integration
102
+ - feat(transport): add LiveTransport for in-process log streaming
103
+ - fix(ci): pass boolean input only on workflow_dispatch
104
+ - ci: add coverage thresholds and CI coverage gate
105
+ - test: 新增分层集成测试(Node 落盘 / Web jsdom / Electron 真实 IPC)
106
+ - docs: 用更口语化的措辞重写文档术语
107
+ - docs: 补充项目文档并修正迁移/排查表述
9
108
  - fix(docs): 更新 GitHub 链接以指向正确的仓库
10
109
  - feat: define immutable LogEntry contract and zero-copy IPC transfer
11
110
  - feat(logger): 添加异步插件拦截顺序处理,确保传输队列独立,避免阻塞
@@ -36,3 +135,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
36
135
  - feat: init
37
136
  - Create README.md
38
137
 
138
+ [v0.1.0]: https://github.com/axetroy/lograil/compare/v0.1.0...v0.1.0
139
+ [v0.1.1]: https://github.com/axetroy/lograil/compare/v0.1.0...v0.1.1
140
+ [v0.1.2]: https://github.com/axetroy/lograil/compare/v0.1.1...v0.1.2
141
+ [v0.1.3]: https://github.com/axetroy/lograil/compare/v0.1.2...v0.1.3
142
+ [v0.1.4]: https://github.com/axetroy/lograil/compare/v0.1.3...v0.1.4
package/README.md CHANGED
@@ -1,9 +1,11 @@
1
1
  <div align="center">
2
- <img src="./logo.svg" alt="lograil" width="128" height="128" />
2
+ <img src="https://raw.githubusercontent.com/axetroy/lograil/refs/heads/main/logo.svg" alt="lograil" width="128" height="128" />
3
3
  </div>
4
4
 
5
5
  # lograil
6
6
 
7
+ **Pronunciation**: /lɒɡ-reɪl/ (log-rail)
8
+
7
9
  Structured, secure logging for **Web**, **Node.js**, and **Electron** — three first-class runtimes, one zero-config `logger`, pluggable transports, filters, processors, formatters, and plugins. Extend to any other platform through the plugin and runtime-adapter APIs.
8
10
 
9
11
  The same `import { logger } from 'lograil'` works untouched in every runtime. On Electron, the main process writes logs to the console **and** daily rotating files, and renderer logs are forwarded over IPC automatically; on Node it persists to a rotating file by default; in the browser it speaks the console and any remote transport you add.
@@ -1,10 +1,4 @@
1
- export type AmbientContext = Record<string, unknown>;
2
- /**
3
- * Browser / non-Node stub. `AsyncLocalStorage` is unavailable here, so ambient
4
- * context is a no-op — logs are unaffected and no context propagates. The real
5
- * implementation (`async-context.ts`) is selected over this file in Node builds
6
- * via the `browser` field in `package.json`.
7
- */
1
+ import type { AmbientContext } from './async-context.js';
8
2
  export declare const asyncContext: {
9
3
  run<T>(fn: () => T, _context: AmbientContext): T;
10
4
  runAsync<T>(fn: () => Promise<T>, _context: AmbientContext): Promise<T>;
@@ -1 +1 @@
1
- {"version":3,"file":"async-context.browser.d.ts","sourceRoot":"","sources":["../../../src/context/async-context.browser.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAErD;;;;;GAKG;AACH,eAAO,MAAM,YAAY;QACnB,CAAC,MAAM,MAAM,CAAC,YAAY,cAAc,GAAG,CAAC;aAGvC,CAAC,MAAM,MAAM,OAAO,CAAC,CAAC,CAAC,YAAY,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;WAGhE,cAAc;iBAGR,OAAO;CAGrB,CAAC;AAEF,0FAA0F;AAC1F,wBAAgB,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,cAAc,GAAG,CAAC,CAE1E"}
1
+ {"version":3,"file":"async-context.browser.d.ts","sourceRoot":"","sources":["../../../src/context/async-context.browser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAWzD,eAAO,MAAM,YAAY;QACnB,CAAC,MAAM,MAAM,CAAC,YAAY,cAAc,GAAG,CAAC;aAGvC,CAAC,MAAM,MAAM,OAAO,CAAC,CAAC,CAAC,YAAY,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;WAGhE,cAAc;iBAGR,OAAO;CAGrB,CAAC;AAEF,0FAA0F;AAC1F,wBAAgB,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,cAAc,GAAG,CAAC,CAE1E"}
@@ -8,6 +8,9 @@ exports.runWithContext = runWithContext;
8
8
  * implementation (`async-context.ts`) is selected over this file in Node builds
9
9
  * via the `browser` field in `package.json`.
10
10
  */
11
+ // Shared frozen empty object returned when no async store is active, so the
12
+ // common (no ambient context) path allocates nothing on every `get()`.
13
+ const EMPTY_AMBIENT = Object.freeze({});
11
14
  exports.asyncContext = {
12
15
  run(fn, _context) {
13
16
  return fn();
@@ -16,7 +19,7 @@ exports.asyncContext = {
16
19
  return fn();
17
20
  },
18
21
  get() {
19
- return {};
22
+ return EMPTY_AMBIENT;
20
23
  },
21
24
  supported() {
22
25
  return false;
@@ -1 +1 @@
1
- {"version":3,"file":"async-context.browser.js","sourceRoot":"","sources":["../../../src/context/async-context.browser.ts"],"names":[],"mappings":";;;AAwBA,wCAEC;AAxBD;;;;;GAKG;AACU,QAAA,YAAY,GAAG;IAC1B,GAAG,CAAI,EAAW,EAAE,QAAwB;QAC1C,OAAO,EAAE,EAAE,CAAC;IACd,CAAC;IACD,QAAQ,CAAI,EAAoB,EAAE,QAAwB;QACxD,OAAO,EAAE,EAAE,CAAC;IACd,CAAC;IACD,GAAG;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,SAAS;QACP,OAAO,KAAK,CAAC;IACf,CAAC;CACF,CAAC;AAEF,0FAA0F;AAC1F,SAAgB,cAAc,CAAI,EAAW,EAAE,QAAwB;IACrE,OAAO,EAAE,EAAE,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"async-context.browser.js","sourceRoot":"","sources":["../../../src/context/async-context.browser.ts"],"names":[],"mappings":";;;AA2BA,wCAEC;AA3BD;;;;;GAKG;AACH,4EAA4E;AAC5E,uEAAuE;AACvE,MAAM,aAAa,GAAmB,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAC3C,QAAA,YAAY,GAAG;IAC1B,GAAG,CAAI,EAAW,EAAE,QAAwB;QAC1C,OAAO,EAAE,EAAE,CAAC;IACd,CAAC;IACD,QAAQ,CAAI,EAAoB,EAAE,QAAwB;QACxD,OAAO,EAAE,EAAE,CAAC;IACd,CAAC;IACD,GAAG;QACD,OAAO,aAAa,CAAC;IACvB,CAAC;IACD,SAAS;QACP,OAAO,KAAK,CAAC;IACf,CAAC;CACF,CAAC;AAEF,0FAA0F;AAC1F,SAAgB,cAAc,CAAI,EAAW,EAAE,QAAwB;IACrE,OAAO,EAAE,EAAE,CAAC;AACd,CAAC"}
@@ -32,7 +32,7 @@ function createContextStore(initial) {
32
32
  // Avoid cloning (and allocating) when the store is empty — the shared
33
33
  // frozen object can never be mutated by callers.
34
34
  for (const _k in data)
35
- return { ...data };
35
+ return Object.assign({}, data);
36
36
  return EMPTY_CONTEXT;
37
37
  },
38
38
  set(key, value) {
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/context/context.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AA4BH,sCAGC;AAED,gDA6BC;AA7CD,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,CAA4B,CAAC;AAEnE;;;;;GAKG;AACU,QAAA,YAAY,GAAG,aAAa,CAAC;AAE1C,uDAAuD;AACvD,SAAgB,aAAa,CAAC,CAA0B;IACtD,KAAK,MAAM,EAAE,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACjC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,kBAAkB,CAAC,OAAiC;IAClE,IAAI,IAAI,GAA4B,EAAE,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC;IAE3D,MAAM,KAAK,GAAiB;QAC1B,GAAG;YACD,sEAAsE;YACtE,iDAAiD;YACjD,KAAK,MAAM,EAAE,IAAI,IAAI;gBAAE,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC;YAC1C,OAAO,aAAa,CAAC;QACvB,CAAC;QACD,GAAG,CAAC,GAAG,EAAE,KAAK;YACZ,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACpB,CAAC;QACD,KAAK,CAAC,MAAM;YACV,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,CAAC,GAAG;YACR,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;QACD,KAAK;YACH,IAAI,GAAG,EAAE,CAAC;QACZ,CAAC;QACD,KAAK;YACH,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC;KACF,CAAC;IAEF,OAAO,KAAK,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/context/context.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AA4BH,sCAGC;AAED,gDA6BC;AA7CD,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,CAA4B,CAAC;AAEnE;;;;;GAKG;AACU,QAAA,YAAY,GAAG,aAAa,CAAC;AAE1C,uDAAuD;AACvD,SAAgB,aAAa,CAAC,CAA0B;IACtD,KAAK,MAAM,EAAE,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACjC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,kBAAkB,CAAC,OAAiC;IAClE,IAAI,IAAI,GAA4B,EAAE,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC;IAE3D,MAAM,KAAK,GAAiB;QAC1B,GAAG;YACD,sEAAsE;YACtE,iDAAiD;YACjD,KAAK,MAAM,EAAE,IAAI,IAAI;gBAAE,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YACtD,OAAO,aAAa,CAAC;QACvB,CAAC;QACD,GAAG,CAAC,GAAG,EAAE,KAAK;YACZ,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACpB,CAAC;QACD,KAAK,CAAC,MAAM;YACV,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,CAAC,GAAG;YACR,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;QACD,KAAK;YACH,IAAI,GAAG,EAAE,CAAC;QACZ,CAAC;QACD,KAAK;YACH,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC;KACF,CAAC;IAEF,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -42,9 +42,9 @@ export interface LoggerOptions {
42
42
  /**
43
43
  * Maximum time (ms) to spend flushing on process exit (`beforeExit`,
44
44
  * `SIGINT`, `SIGTERM`) before giving up and letting the process exit, so a
45
- * stalled transport flush can never hang shutdown. Default `2000`.
45
+ * stalled transport flush can never hang shutdown. Default `2000`.\
46
46
  */
47
- exitFlushTimeoutMs?: number;
47
+ flushTimeoutMs?: number;
48
48
  /** Optional scope / namespace for this logger. */
49
49
  scope?: string;
50
50
  /** Runtime adapter. Auto-detected when omitted. */
@@ -69,17 +69,17 @@ export interface LoggerOptions {
69
69
  */
70
70
  levelEnvVar?: string | null;
71
71
  /**
72
- * Scope/namespace filter. A comma- or space-separated list of glob patterns
72
+ * Scope filter. A comma- or space-separated list of glob patterns
73
73
  * (with `*` wildcards); a leading `-` excludes. Only entries whose `scope`
74
- * matches are emitted. Read automatically from `namespaceEnvVar` when omitted.
74
+ * matches are emitted. Read automatically from `scopeFilterEnvVar` when omitted.
75
75
  */
76
- namespaceFilter?: string | string[];
76
+ scopeFilter?: string | string[];
77
77
  /**
78
- * Environment variable whose value supplies the namespace filter when
79
- * `namespaceFilter` is not set. Defaults to `"LOGRAIL_DEBUG"`. Set to `null`
78
+ * Environment variable whose value supplies the scope filter when
79
+ * `scopeFilter` is not set. Defaults to `"LOGRAIL_DEBUG"`. Set to `null`
80
80
  * to disable.
81
81
  */
82
- namespaceEnvVar?: string | null;
82
+ scopeFilterEnvVar?: string | null;
83
83
  }
84
84
  /**
85
85
  * Internal options passed by `scope`/`child` to build a **lightweight** child
@@ -115,12 +115,14 @@ export declare class Logger implements LoggerMethods {
115
115
  private parent?;
116
116
  private levelOverride?;
117
117
  /**
118
- * Sequences the async plugin-interception step so entries are processed in
119
- * emit order. Transport writes fan out to their own per-transport queues
120
- * (see `transportQueues`), so a slow/blocked transport can never stall the
121
- * others or this front queue.
118
+ * Bounded async queue for plugin interception. Tracks in-flight entries so
119
+ * `flush()` and `destroy()` know when all interceptions are done without
120
+ * letting the dispatch chain grow unboundedly (each push would append a
121
+ * `.then()` to an ever-longer Promise chain).
122
122
  */
123
- private dispatchQueue;
123
+ private dispatchInflight;
124
+ private dispatchDrain;
125
+ private dispatchDrainResolve;
124
126
  /** Independent async-write queue per transport. */
125
127
  private transportQueues;
126
128
  private destroyed;
@@ -130,9 +132,9 @@ export declare class Logger implements LoggerMethods {
130
132
  private removeProcessHandlers?;
131
133
  private onLoggerError?;
132
134
  private writeTimeoutMs;
133
- private exitFlushTimeoutMs;
135
+ private flushTimeoutMs;
134
136
  private _exiting;
135
- private namespaceFilter?;
137
+ private scopeFilter?;
136
138
  /** True for loggers created via `scope`/`child` (share the parent's plumbing). */
137
139
  private isChild;
138
140
  /** Cached peer process level. When set, takes precedence over local `level` in `getLevel()`. */
@@ -209,6 +211,8 @@ export declare class Logger implements LoggerMethods {
209
211
  trace: LogFn;
210
212
  debug: LogFn;
211
213
  info: LogFn;
214
+ /** Alias for {@link info}. */
215
+ log: LogFn;
212
216
  warn: LogFn;
213
217
  error: LogFn;
214
218
  fatal: LogFn;
@@ -241,7 +245,7 @@ export declare class Logger implements LoggerMethods {
241
245
  * exit the process) without risking a hang on a stalled transport.
242
246
  */
243
247
  private flushWithTimeout;
244
- /** Set the max time (ms) to flush on process exit before giving up. */
248
+ /** Set the max time (ms) to flush before process exit before giving up. */
245
249
  setExitFlushTimeout(ms: number): this;
246
250
  /** Get the current exit-flush timeout (ms). */
247
251
  getExitFlushTimeout(): number;
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/core/logger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/core/logger.ts"],"names":[],"mappings":"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"}
@@ -32,6 +32,15 @@ function isoFromMs(ms) {
32
32
  TIME_DATE.setTime(ms);
33
33
  return `${pad(TIME_DATE.getUTCFullYear(), 4)}-${pad(TIME_DATE.getUTCMonth() + 1, 2)}-${pad(TIME_DATE.getUTCDate(), 2)}T${pad(TIME_DATE.getUTCHours(), 2)}:${pad(TIME_DATE.getUTCMinutes(), 2)}:${pad(TIME_DATE.getUTCSeconds(), 2)}.${pad(TIME_DATE.getUTCMilliseconds(), 3)}Z`;
34
34
  }
35
+ /** Cache compiled namespace filters by normalized input to avoid recompiling regexes on every call. */
36
+ const nsFilterCache = new Map();
37
+ function serializeNsInput(input) {
38
+ if (!input)
39
+ return '';
40
+ if (Array.isArray(input))
41
+ return input.join(',');
42
+ return input;
43
+ }
35
44
  function escapeRegex(s) {
36
45
  return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
37
46
  }
@@ -48,22 +57,34 @@ function toPattern(token) {
48
57
  * `undefined` (no filtering).
49
58
  */
50
59
  function compileNamespaceFilter(input) {
51
- if (!input || (Array.isArray(input) && input.length === 0))
52
- return undefined;
53
- const tokens = (Array.isArray(input) ? input : input.split(/[ ,]+/))
54
- .map((t) => t.trim())
55
- .filter(Boolean);
56
- if (tokens.length === 0)
57
- return undefined;
58
- const includes = [];
59
- const excludes = [];
60
- for (const token of tokens) {
61
- if (token.startsWith('-'))
62
- excludes.push(toPattern(token.slice(1)));
63
- else
64
- includes.push(toPattern(token));
60
+ const key = serializeNsInput(input);
61
+ if (nsFilterCache.has(key))
62
+ return nsFilterCache.get(key);
63
+ let result;
64
+ if (!input || (Array.isArray(input) && input.length === 0)) {
65
+ result = undefined;
66
+ }
67
+ else {
68
+ const tokens = (Array.isArray(input) ? input : input.split(/[ ,]+/))
69
+ .map((t) => t.trim())
70
+ .filter(Boolean);
71
+ if (tokens.length === 0) {
72
+ result = undefined;
73
+ }
74
+ else {
75
+ const includes = [];
76
+ const excludes = [];
77
+ for (const token of tokens) {
78
+ if (token.startsWith('-'))
79
+ excludes.push(toPattern(token.slice(1)));
80
+ else
81
+ includes.push(toPattern(token));
82
+ }
83
+ result = { includes, excludes };
84
+ }
65
85
  }
66
- return { includes, excludes };
86
+ nsFilterCache.set(key, result);
87
+ return result;
67
88
  }
68
89
  function matchesNamespace(scope, filter) {
69
90
  if (!filter)
@@ -106,12 +127,14 @@ function getNodeProcess() {
106
127
  class Logger {
107
128
  constructor(options = {}) {
108
129
  /**
109
- * Sequences the async plugin-interception step so entries are processed in
110
- * emit order. Transport writes fan out to their own per-transport queues
111
- * (see `transportQueues`), so a slow/blocked transport can never stall the
112
- * others or this front queue.
130
+ * Bounded async queue for plugin interception. Tracks in-flight entries so
131
+ * `flush()` and `destroy()` know when all interceptions are done without
132
+ * letting the dispatch chain grow unboundedly (each push would append a
133
+ * `.then()` to an ever-longer Promise chain).
113
134
  */
114
- this.dispatchQueue = Promise.resolve();
135
+ this.dispatchInflight = 0;
136
+ this.dispatchDrain = null;
137
+ this.dispatchDrainResolve = undefined;
115
138
  /** Independent async-write queue per transport. */
116
139
  this.transportQueues = new Map();
117
140
  this.destroyed = false;
@@ -126,6 +149,8 @@ class Logger {
126
149
  this.trace = (message, ...args) => this.emit('trace', message, args);
127
150
  this.debug = (message, ...args) => this.emit('debug', message, args);
128
151
  this.info = (message, ...args) => this.emit('info', message, args);
152
+ /** Alias for {@link info}. */
153
+ this.log = (message, ...args) => this.emit('info', message, args);
129
154
  this.warn = (message, ...args) => this.emit('warn', message, args);
130
155
  this.error = (message, ...args) => this.emit('error', message, args);
131
156
  this.fatal = (message, ...args) => this.emit('fatal', message, args);
@@ -153,11 +178,11 @@ class Logger {
153
178
  this.level = (0, types_js_1.normalizeLevel)(levelInput);
154
179
  this.originalLevel = this.level;
155
180
  this.scopeName = options.scope;
156
- const nsInput = options.namespaceFilter ??
157
- (options.namespaceEnvVar === null
181
+ const nsInput = options.scopeFilter ??
182
+ (options.scopeFilterEnvVar === null
158
183
  ? undefined
159
- : readEnvVar(options.namespaceEnvVar ?? 'LOGRAIL_DEBUG'));
160
- this.namespaceFilter = compileNamespaceFilter(nsInput);
184
+ : readEnvVar(options.scopeFilterEnvVar ?? 'LOGRAIL_DEBUG'));
185
+ this.scopeFilter = compileNamespaceFilter(nsInput);
161
186
  // On the Electron main process, receive renderer logs over IPC.
162
187
  if (this.runtime.attachReceiver) {
163
188
  this.detachReceiver = this.runtime.attachReceiver((entry) => this.ingestEntry(entry));
@@ -169,7 +194,7 @@ class Logger {
169
194
  this.attachExitHandlers();
170
195
  this.onLoggerError = options.onError;
171
196
  this.writeTimeoutMs = options.writeTimeoutMs ?? 5000;
172
- this.exitFlushTimeoutMs = options.exitFlushTimeoutMs ?? 2000;
197
+ this.flushTimeoutMs = options.flushTimeoutMs ?? 2000;
173
198
  // Wire the pipeline/plugin error sinks into the unified handler.
174
199
  this.pipeline.onError = (err, info) => this.reportError(info.phase, err, info.entry);
175
200
  this.plugins.onError = (name, err, entry) => this.reportError('plugin', err, entry, name);
@@ -187,13 +212,13 @@ class Logger {
187
212
  this.pipeline = parent.pipeline;
188
213
  this.plugins = parent.plugins;
189
214
  this.transports = parent.transports;
190
- this.namespaceFilter = parent.namespaceFilter;
215
+ this.scopeFilter = parent.scopeFilter;
191
216
  this.context = opts.context ?? (0, index_js_3.createContextStore)();
192
217
  this.scopeName = opts.scope;
193
218
  // Only a root logger owns the shared plugin error sink; children inherit it.
194
219
  this.onLoggerError = parent.onLoggerError;
195
220
  this.writeTimeoutMs = parent.writeTimeoutMs;
196
- this.exitFlushTimeoutMs = parent.exitFlushTimeoutMs;
221
+ this.flushTimeoutMs = parent.flushTimeoutMs;
197
222
  if (opts.levelOverride !== undefined)
198
223
  this.levelOverride = opts.levelOverride;
199
224
  }
@@ -207,7 +232,7 @@ class Logger {
207
232
  return;
208
233
  if (entry.level < this.getLevel())
209
234
  return;
210
- if (!matchesNamespace(entry.scope, this.namespaceFilter))
235
+ if (!matchesNamespace(entry.scope, this.scopeFilter))
211
236
  return;
212
237
  this.dispatch(entry);
213
238
  }
@@ -258,9 +283,22 @@ class Logger {
258
283
  }
259
284
  removeTransport(name) {
260
285
  const removed = this.transports.filter((t) => t.name === name);
261
- for (const t of removed)
262
- this.transportQueues.delete(t);
263
286
  this.transports = this.transports.filter((t) => t.name !== name);
287
+ for (const transport of removed) {
288
+ const prev = this.transportQueues.get(transport) ?? Promise.resolve();
289
+ const teardown = prev
290
+ .then(async () => {
291
+ if (transport.flush)
292
+ await this.guardFlush(transport.flush.bind(transport));
293
+ if (transport.close)
294
+ await Promise.resolve(transport.close());
295
+ })
296
+ .catch((err) => this.reportError('transport', err, undefined, transport.name))
297
+ .finally(() => {
298
+ this.transportQueues.delete(transport);
299
+ });
300
+ this.transportQueues.set(transport, teardown);
301
+ }
264
302
  }
265
303
  /** Unregister a plugin by name at runtime. */
266
304
  unregisterPlugin(name) {
@@ -348,7 +386,7 @@ class Logger {
348
386
  const levelValue = types_js_1.LOG_LEVELS[levelName];
349
387
  if (levelValue < this.getLevel())
350
388
  return;
351
- if (!matchesNamespace(this.scopeName, this.namespaceFilter))
389
+ if (!matchesNamespace(this.scopeName, this.scopeFilter))
352
390
  return;
353
391
  const entry = this.buildEntry(levelName, levelValue, message, args);
354
392
  const processed = this.pipeline.process(entry);
@@ -364,13 +402,29 @@ class Logger {
364
402
  */
365
403
  dispatch(entry) {
366
404
  if (this.plugins.hasEntryInterceptors()) {
367
- const p = this.plugins.intercept(entry).then((intercepted) => {
405
+ // Create or reset the drain promise eagerly so that `flush()` callers
406
+ // always have a non-null promise to await, even if they arrive before
407
+ // the current batch of in-flight interceptions completes.
408
+ this.dispatchDrain = new Promise((resolve) => {
409
+ this.dispatchDrainResolve = resolve;
410
+ });
411
+ this.dispatchInflight++;
412
+ this.plugins
413
+ .intercept(entry)
414
+ .then((intercepted) => {
368
415
  if (intercepted)
369
416
  this.writeToTransports(intercepted);
417
+ })
418
+ .catch((err) => this.reportError('plugin', err))
419
+ .finally(() => {
420
+ this.dispatchInflight--;
421
+ if (this.dispatchInflight === 0) {
422
+ const resolve = this.dispatchDrainResolve;
423
+ this.dispatchDrain = null;
424
+ this.dispatchDrainResolve = undefined;
425
+ resolve?.();
426
+ }
370
427
  });
371
- this.dispatchQueue = this.dispatchQueue
372
- .then(() => p)
373
- .catch((err) => this.reportError('plugin', err));
374
428
  return;
375
429
  }
376
430
  this.writeToTransports(entry);
@@ -416,7 +470,9 @@ class Logger {
416
470
  rest = [message, ...args];
417
471
  }
418
472
  if (!error) {
419
- error = rest.find((a) => a instanceof Error);
473
+ error =
474
+ rest.find((a) => a instanceof Error) ??
475
+ rest.find((a) => typeof a === 'string' && a.length > 0);
420
476
  }
421
477
  const now = this.runtime.now();
422
478
  const ts = typeof now === 'number' ? now : new Date(now).getTime();
@@ -503,7 +559,7 @@ class Logger {
503
559
  }
504
560
  /** Await a transport's async `flush`, but never let it stall teardown. */
505
561
  guardFlush(p) {
506
- if (!this.writeTimeoutMs)
562
+ if (!this.flushTimeoutMs)
507
563
  return Promise.resolve();
508
564
  const result = p();
509
565
  if (!result || typeof result.then !== 'function')
@@ -521,7 +577,8 @@ class Logger {
521
577
  async flush() {
522
578
  // Let in-flight interception finish so every scheduled write has been
523
579
  // enqueued onto its transport's own queue.
524
- await this.dispatchQueue;
580
+ if (this.dispatchInflight > 0)
581
+ await this.dispatchDrain;
525
582
  // Aggregate all per-transport async-write queues. `allSettled` means a
526
583
  // rejected/errored transport queue never rejects flush; a stalled one is
527
584
  // bounded by `writeTimeoutMs` via `guardWrite`.
@@ -552,15 +609,15 @@ class Logger {
552
609
  this.flush().then(done, done);
553
610
  });
554
611
  }
555
- /** Set the max time (ms) to flush on process exit before giving up. */
612
+ /** Set the max time (ms) to flush before process exit before giving up. */
556
613
  setExitFlushTimeout(ms) {
557
614
  if (Number.isFinite(ms) && ms >= 0)
558
- this.exitFlushTimeoutMs = ms;
615
+ this.flushTimeoutMs = ms;
559
616
  return this;
560
617
  }
561
618
  /** Get the current exit-flush timeout (ms). */
562
619
  getExitFlushTimeout() {
563
- return this.exitFlushTimeoutMs;
620
+ return this.flushTimeoutMs;
564
621
  }
565
622
  // ---- Process integration ----
566
623
  /**
@@ -577,7 +634,7 @@ class Logger {
577
634
  // adapters that don't supply lifecycle hooks (e.g. custom test runtimes).
578
635
  const lc = this.runtime.lifecycle;
579
636
  if (lc) {
580
- const ms = this.exitFlushTimeoutMs;
637
+ const ms = this.flushTimeoutMs;
581
638
  const detach = lc.onFlushBeforeExit(() => {
582
639
  void this.flushWithTimeout(ms);
583
640
  });
@@ -592,7 +649,7 @@ class Logger {
592
649
  const proc = getNodeProcess();
593
650
  if (!proc)
594
651
  return;
595
- const ms = this.exitFlushTimeoutMs;
652
+ const ms = this.flushTimeoutMs;
596
653
  // On normal exit the event loop is about to empty: flush pending writes.
597
654
  // `beforeExit` re-fires as long as async writes keep the loop alive, so the
598
655
  // queue keeps draining until empty (bounded by `ms` if a sink stalls).
@@ -619,6 +676,14 @@ class Logger {
619
676
  proc.on('beforeExit', onBeforeExit);
620
677
  proc.on('SIGINT', onSigInt);
621
678
  proc.on('SIGTERM', onSigTerm);
679
+ // Windows does not emit `SIGTERM`. Register `SIGBREAK` (Ctrl+Break) as a
680
+ // best-effort fallback so `autoFlushOnExit` has a signal hook on that
681
+ // platform. In practice taskkill / OS shutdown kills without emitting any
682
+ // Node signal, so no handler can cover that path — the `beforeExit` hook
683
+ // is the only portable shutdown flush mechanism.
684
+ if (process.platform === 'win32') {
685
+ proc.on('SIGBREAK', onSigInt);
686
+ }
622
687
  this.processHandlersAttached = true;
623
688
  const prev = this.removeProcessHandlers;
624
689
  this.removeProcessHandlers = () => {
@@ -643,7 +708,7 @@ class Logger {
643
708
  // fall back to the direct `process` binding below, which is a no-op there.
644
709
  const lc = this.runtime.lifecycle;
645
710
  if (lc?.onUncaughtError) {
646
- const ms = this.exitFlushTimeoutMs;
711
+ const ms = this.flushTimeoutMs;
647
712
  const detach = lc.onUncaughtError((err) => {
648
713
  this.fatal(err);
649
714
  return this.flushWithTimeout(ms);
@@ -661,11 +726,11 @@ class Logger {
661
726
  return;
662
727
  const onUncaught = (err) => {
663
728
  this.fatal(err);
664
- void this.flushWithTimeout(this.exitFlushTimeoutMs).finally(() => proc.exit(1));
729
+ void this.flushWithTimeout(this.flushTimeoutMs).finally(() => proc.exit(1));
665
730
  };
666
731
  const onRejection = (reason) => {
667
732
  this.fatal(reason);
668
- void this.flushWithTimeout(this.exitFlushTimeoutMs).finally(() => proc.exit(1));
733
+ void this.flushWithTimeout(this.flushTimeoutMs).finally(() => proc.exit(1));
669
734
  };
670
735
  proc.on('uncaughtException', onUncaught);
671
736
  proc.on('unhandledRejection', onRejection);
@@ -730,7 +795,7 @@ class Logger {
730
795
  // Flush pending writes before tearing down transports, so buffered logs
731
796
  // are not lost. Bounded by the exit-flush timeout so a stalled sink can
732
797
  // never hang teardown.
733
- await this.flushWithTimeout(this.exitFlushTimeoutMs).catch(() => { });
798
+ await this.flushWithTimeout(this.flushTimeoutMs).catch(() => { });
734
799
  await this.plugins.destroy().catch(() => { });
735
800
  this.detachReceiver?.();
736
801
  this.peerLevel = undefined;
@@ -744,7 +809,9 @@ class Logger {
744
809
  }
745
810
  }
746
811
  this.transportQueues.clear();
747
- this.dispatchQueue = Promise.resolve();
812
+ this.dispatchInflight = 0;
813
+ this.dispatchDrain = null;
814
+ this.dispatchDrainResolve = undefined;
748
815
  }
749
816
  }
750
817
  exports.Logger = Logger;