logixia 2.0.10 → 2.1.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.
Files changed (190) hide show
  1. package/README.md +2 -1
  2. package/dist/{async-context-Dv0bmPC-.js → async-context-Dgl3ZLyb.js} +4 -4
  3. package/dist/{async-context-Dv0bmPC-.js.map → async-context-Dgl3ZLyb.js.map} +1 -1
  4. package/dist/{async-context-COuvmwsS.mjs → async-context-fBqC5lNc.mjs} +3 -3
  5. package/dist/{async-context-COuvmwsS.mjs.map → async-context-fBqC5lNc.mjs.map} +1 -1
  6. package/dist/{azure-monitor.transport-CbSHOnNX.d.mts → azure-monitor.transport-C5VjvREZ.d.mts} +2 -2
  7. package/dist/{azure-monitor.transport-CbSHOnNX.d.mts.map → azure-monitor.transport-C5VjvREZ.d.mts.map} +1 -1
  8. package/dist/{azure-monitor.transport-Bvf7Xegt.d.ts → azure-monitor.transport-CyHDjHS-.d.ts} +2 -2
  9. package/dist/{azure-monitor.transport-Bvf7Xegt.d.ts.map → azure-monitor.transport-CyHDjHS-.d.ts.map} +1 -1
  10. package/dist/{azure-monitor.transport-Coz5Gesu.mjs → azure-monitor.transport-DGiacfvT.mjs} +19 -8
  11. package/dist/{azure-monitor.transport-Coz5Gesu.mjs.map → azure-monitor.transport-DGiacfvT.mjs.map} +1 -1
  12. package/dist/{azure-monitor.transport-D6ryi8rA.js → azure-monitor.transport-DX3fuK2t.js} +19 -8
  13. package/dist/{azure-monitor.transport-D6ryi8rA.js.map → azure-monitor.transport-DX3fuK2t.js.map} +1 -1
  14. package/dist/azure.d.mts +1 -1
  15. package/dist/azure.d.ts +1 -1
  16. package/dist/azure.js +1 -1
  17. package/dist/azure.mjs +1 -1
  18. package/dist/{batch-buffer-CFzKnuNZ.js → batch-buffer-BLmVvJAZ.js} +11 -7
  19. package/dist/{batch-buffer-CFzKnuNZ.js.map → batch-buffer-BLmVvJAZ.js.map} +1 -1
  20. package/dist/{batch-buffer-CQUWDMYq.mjs → batch-buffer-CM-lK_Qy.mjs} +11 -7
  21. package/dist/{batch-buffer-CQUWDMYq.mjs.map → batch-buffer-CM-lK_Qy.mjs.map} +1 -1
  22. package/dist/browser.d.mts +2 -0
  23. package/dist/browser.d.mts.map +1 -1
  24. package/dist/browser.d.ts +2 -0
  25. package/dist/browser.d.ts.map +1 -1
  26. package/dist/browser.js +42 -13
  27. package/dist/browser.js.map +1 -1
  28. package/dist/browser.mjs +42 -13
  29. package/dist/browser.mjs.map +1 -1
  30. package/dist/{builder-Bj3mDeBw.mjs → builder-CA_dokb4.mjs} +246 -101
  31. package/dist/builder-CA_dokb4.mjs.map +1 -0
  32. package/dist/{builder-BLIStsCK.js → builder-jMlVYaQa.js} +256 -111
  33. package/dist/builder-jMlVYaQa.js.map +1 -0
  34. package/dist/cli/index.js +21 -16
  35. package/dist/cloudwatch.d.mts +1 -1
  36. package/dist/cloudwatch.d.ts +1 -1
  37. package/dist/cloudwatch.js +1 -1
  38. package/dist/cloudwatch.mjs +1 -1
  39. package/dist/{cloudwatch.transport-Cr1aeTGj.mjs → cloudwatch.transport-Cr0fEpko.mjs} +24 -9
  40. package/dist/{cloudwatch.transport-Cr1aeTGj.mjs.map → cloudwatch.transport-Cr0fEpko.mjs.map} +1 -1
  41. package/dist/{cloudwatch.transport-CQyT6U91.d.ts → cloudwatch.transport-DdSjUWvu.d.ts} +2 -2
  42. package/dist/{cloudwatch.transport-CQyT6U91.d.ts.map → cloudwatch.transport-DdSjUWvu.d.ts.map} +1 -1
  43. package/dist/{cloudwatch.transport-D4G5xYfG.js → cloudwatch.transport-Lst1Bbmr.js} +24 -9
  44. package/dist/{cloudwatch.transport-D4G5xYfG.js.map → cloudwatch.transport-Lst1Bbmr.js.map} +1 -1
  45. package/dist/{cloudwatch.transport-CjVrI6S4.d.mts → cloudwatch.transport-_hS7Mcc5.d.mts} +2 -2
  46. package/dist/{cloudwatch.transport-CjVrI6S4.d.mts.map → cloudwatch.transport-_hS7Mcc5.d.mts.map} +1 -1
  47. package/dist/correlation.js +3 -3
  48. package/dist/correlation.mjs +3 -3
  49. package/dist/{coerce.utils-C1C5sIX0.js → csv.utils-CbVHY1pd.js} +24 -1
  50. package/dist/csv.utils-CbVHY1pd.js.map +1 -0
  51. package/dist/{coerce.utils-B_rEudCn.mjs → csv.utils-ZdxSod5g.mjs} +19 -2
  52. package/dist/csv.utils-ZdxSod5g.mjs.map +1 -0
  53. package/dist/{entry-fields-CVwoQplO.js → entry-fields-BSLkzw18.js} +3 -3
  54. package/dist/{entry-fields-CVwoQplO.js.map → entry-fields-BSLkzw18.js.map} +1 -1
  55. package/dist/{entry-fields-DNTKQxoU.mjs → entry-fields-J1OBi24o.mjs} +2 -2
  56. package/dist/{entry-fields-DNTKQxoU.mjs.map → entry-fields-J1OBi24o.mjs.map} +1 -1
  57. package/dist/gcp.d.mts +1 -1
  58. package/dist/gcp.d.ts +1 -1
  59. package/dist/gcp.js +1 -1
  60. package/dist/gcp.mjs +1 -1
  61. package/dist/{gcp.transport-CVuRpchl.js → gcp.transport-5-ZIjN8r.js} +18 -9
  62. package/dist/{gcp.transport-CVuRpchl.js.map → gcp.transport-5-ZIjN8r.js.map} +1 -1
  63. package/dist/{gcp.transport-D9SdLPwP.d.mts → gcp.transport-C8VJiEM7.d.mts} +2 -2
  64. package/dist/{gcp.transport-D9SdLPwP.d.mts.map → gcp.transport-C8VJiEM7.d.mts.map} +1 -1
  65. package/dist/{gcp.transport-BCIvdFV-.d.ts → gcp.transport-Ct0BtKFo.d.ts} +2 -2
  66. package/dist/{gcp.transport-BCIvdFV-.d.ts.map → gcp.transport-Ct0BtKFo.d.ts.map} +1 -1
  67. package/dist/{gcp.transport-LLK2bw2-.mjs → gcp.transport-Cw3Qke85.mjs} +18 -9
  68. package/dist/{gcp.transport-LLK2bw2-.mjs.map → gcp.transport-Cw3Qke85.mjs.map} +1 -1
  69. package/dist/{index-BAkPHp5D.d.mts → index-B3ajtXJd.d.mts} +2 -2
  70. package/dist/{index-BAkPHp5D.d.mts.map → index-B3ajtXJd.d.mts.map} +1 -1
  71. package/dist/{index-e7LowmAu.d.ts → index-oqD3WNxf.d.ts} +2 -2
  72. package/dist/{index-e7LowmAu.d.ts.map → index-oqD3WNxf.d.ts.map} +1 -1
  73. package/dist/index.d.mts +8 -7
  74. package/dist/index.d.mts.map +1 -1
  75. package/dist/index.d.ts +8 -7
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/index.js +44 -26
  78. package/dist/index.js.map +1 -1
  79. package/dist/index.mjs +34 -17
  80. package/dist/index.mjs.map +1 -1
  81. package/dist/{logitron-logger-DVUdgmBY.d.ts → logitron-logger-Csn3e6Qu.d.ts} +2 -2
  82. package/dist/{logitron-logger-DVUdgmBY.d.ts.map → logitron-logger-Csn3e6Qu.d.ts.map} +1 -1
  83. package/dist/{logitron-logger-DoWmMjYB.d.mts → logitron-logger-fMOkXr8H.d.mts} +2 -2
  84. package/dist/{logitron-logger-DoWmMjYB.d.mts.map → logitron-logger-fMOkXr8H.d.mts.map} +1 -1
  85. package/dist/middleware.d.mts +1 -1
  86. package/dist/middleware.d.mts.map +1 -1
  87. package/dist/middleware.d.ts +1 -1
  88. package/dist/middleware.d.ts.map +1 -1
  89. package/dist/middleware.js +12 -7
  90. package/dist/middleware.js.map +1 -1
  91. package/dist/middleware.mjs +11 -6
  92. package/dist/middleware.mjs.map +1 -1
  93. package/dist/nest.d.mts +51 -18
  94. package/dist/nest.d.mts.map +1 -1
  95. package/dist/nest.d.ts +51 -18
  96. package/dist/nest.d.ts.map +1 -1
  97. package/dist/nest.js +207 -65
  98. package/dist/nest.js.map +1 -1
  99. package/dist/nest.mjs +202 -60
  100. package/dist/nest.mjs.map +1 -1
  101. package/dist/{otel-ChnVYRLA.js → otel-8ypFGG19.js} +452 -120
  102. package/dist/otel-8ypFGG19.js.map +1 -0
  103. package/dist/{otel-DOuwGPCd.mjs → otel-b-s2QbY4.mjs} +450 -118
  104. package/dist/otel-b-s2QbY4.mjs.map +1 -0
  105. package/dist/own-property-BWkibepN.js +40 -0
  106. package/dist/own-property-BWkibepN.js.map +1 -0
  107. package/dist/own-property-CjFw9qwZ.mjs +29 -0
  108. package/dist/own-property-CjFw9qwZ.mjs.map +1 -0
  109. package/dist/{request-trace-ByujsUZk.js → request-trace-C7kXMjx5.js} +5 -6
  110. package/dist/{request-trace-ByujsUZk.js.map → request-trace-C7kXMjx5.js.map} +1 -1
  111. package/dist/{request-trace-BgNykH9M.mjs → request-trace-Dekcnenb.mjs} +5 -6
  112. package/dist/{request-trace-BgNykH9M.mjs.map → request-trace-Dekcnenb.mjs.map} +1 -1
  113. package/dist/{safe-stringify--7gbe95n.mjs → safe-stringify-B5p5ktFe.mjs} +2 -2
  114. package/dist/{safe-stringify--7gbe95n.mjs.map → safe-stringify-B5p5ktFe.mjs.map} +1 -1
  115. package/dist/{safe-stringify-CN7icp8S.js → safe-stringify-J3sh-7YM.js} +5 -5
  116. package/dist/{safe-stringify-CN7icp8S.js.map → safe-stringify-J3sh-7YM.js.map} +1 -1
  117. package/dist/{search-DPwTKPve.d.ts → search-B-hJe2N-.d.mts} +9 -8
  118. package/dist/{search-D-8HJADE.d.mts.map → search-B-hJe2N-.d.mts.map} +1 -1
  119. package/dist/{search-D-8HJADE.d.mts → search-BlKBLm5D.d.ts} +9 -8
  120. package/dist/{search-DPwTKPve.d.ts.map → search-BlKBLm5D.d.ts.map} +1 -1
  121. package/dist/{search-DAXKE-P9.mjs → search-CTR4XNHq.mjs} +91 -44
  122. package/dist/search-CTR4XNHq.mjs.map +1 -0
  123. package/dist/{search-CRjhHxe9.js → search-_qx4YzRP.js} +94 -47
  124. package/dist/search-_qx4YzRP.js.map +1 -0
  125. package/dist/search.d.mts +1 -1
  126. package/dist/search.d.ts +1 -1
  127. package/dist/search.js +1 -1
  128. package/dist/search.mjs +1 -1
  129. package/dist/{secret-config-BvFl2dC8.js → secret-config--cVTOWwp.js} +6 -5
  130. package/dist/{secret-config-BvFl2dC8.js.map → secret-config--cVTOWwp.js.map} +1 -1
  131. package/dist/{secret-config-ByGq7kJd.mjs → secret-config-GKmb15Me.mjs} +3 -2
  132. package/dist/{secret-config-ByGq7kJd.mjs.map → secret-config-GKmb15Me.mjs.map} +1 -1
  133. package/dist/{sensitive-names-o__1PUUR.mjs → sensitive-names-BiBM6R1X.mjs} +2 -28
  134. package/dist/sensitive-names-BiBM6R1X.mjs.map +1 -0
  135. package/dist/{sensitive-names-CHMowujD.js → sensitive-names-NiKIRhp5.js} +5 -37
  136. package/dist/sensitive-names-NiKIRhp5.js.map +1 -0
  137. package/dist/{slack.transport-BDyENuR0.d.mts → slack.transport-5OPL7H3u.d.mts} +76 -3
  138. package/dist/slack.transport-5OPL7H3u.d.mts.map +1 -0
  139. package/dist/{slack.transport-C6E0l4kw.d.ts → slack.transport-BFpBD_Ri.d.ts} +76 -3
  140. package/dist/slack.transport-BFpBD_Ri.d.ts.map +1 -0
  141. package/dist/{slack.transport-zLQ9MGxS.js → slack.transport-Cpx5fKga.js} +272 -21
  142. package/dist/slack.transport-Cpx5fKga.js.map +1 -0
  143. package/dist/{slack.transport-CSj1j0_X.mjs → slack.transport-Qwj9WkrJ.mjs} +267 -22
  144. package/dist/slack.transport-Qwj9WkrJ.mjs.map +1 -0
  145. package/dist/testing.d.mts +1 -1
  146. package/dist/testing.d.ts +1 -1
  147. package/dist/{transport.types-CzJq4IrF.d.ts → transport.types-B1ejJJP6.d.mts} +6 -1
  148. package/dist/transport.types-B1ejJJP6.d.mts.map +1 -0
  149. package/dist/{transport.types-CzJq4IrF.d.mts → transport.types-B1ejJJP6.d.ts} +6 -1
  150. package/dist/transport.types-B1ejJJP6.d.ts.map +1 -0
  151. package/dist/transports.d.mts +61 -11
  152. package/dist/transports.d.mts.map +1 -1
  153. package/dist/transports.d.ts +61 -11
  154. package/dist/transports.d.ts.map +1 -1
  155. package/dist/transports.js +7 -6
  156. package/dist/transports.mjs +7 -7
  157. package/dist/worker-entry.js +200 -52
  158. package/dist/worker.d.mts +1 -1
  159. package/dist/worker.d.ts +1 -1
  160. package/dist/worker.js +1 -1
  161. package/dist/worker.mjs +1 -1
  162. package/dist/{worker.transport-B9mCQSM1.d.ts → worker.transport-B7olL1Uh.d.ts} +12 -2
  163. package/dist/worker.transport-B7olL1Uh.d.ts.map +1 -0
  164. package/dist/{worker.transport-D78xhNhB.mjs → worker.transport-BHnWDXPH.mjs} +59 -13
  165. package/dist/worker.transport-BHnWDXPH.mjs.map +1 -0
  166. package/dist/{worker.transport-DQDv1nAJ.js → worker.transport-C7jNGhev.js} +59 -13
  167. package/dist/worker.transport-C7jNGhev.js.map +1 -0
  168. package/dist/{worker.transport-Bl8lFRck.d.mts → worker.transport-DnU0_9Bd.d.mts} +12 -2
  169. package/dist/worker.transport-DnU0_9Bd.d.mts.map +1 -0
  170. package/package.json +10 -3
  171. package/dist/builder-BLIStsCK.js.map +0 -1
  172. package/dist/builder-Bj3mDeBw.mjs.map +0 -1
  173. package/dist/coerce.utils-B_rEudCn.mjs.map +0 -1
  174. package/dist/coerce.utils-C1C5sIX0.js.map +0 -1
  175. package/dist/otel-ChnVYRLA.js.map +0 -1
  176. package/dist/otel-DOuwGPCd.mjs.map +0 -1
  177. package/dist/search-CRjhHxe9.js.map +0 -1
  178. package/dist/search-DAXKE-P9.mjs.map +0 -1
  179. package/dist/sensitive-names-CHMowujD.js.map +0 -1
  180. package/dist/sensitive-names-o__1PUUR.mjs.map +0 -1
  181. package/dist/slack.transport-BDyENuR0.d.mts.map +0 -1
  182. package/dist/slack.transport-C6E0l4kw.d.ts.map +0 -1
  183. package/dist/slack.transport-CSj1j0_X.mjs.map +0 -1
  184. package/dist/slack.transport-zLQ9MGxS.js.map +0 -1
  185. package/dist/transport.types-CzJq4IrF.d.mts.map +0 -1
  186. package/dist/transport.types-CzJq4IrF.d.ts.map +0 -1
  187. package/dist/worker.transport-B9mCQSM1.d.ts.map +0 -1
  188. package/dist/worker.transport-Bl8lFRck.d.mts.map +0 -1
  189. package/dist/worker.transport-D78xhNhB.mjs.map +0 -1
  190. package/dist/worker.transport-DQDv1nAJ.js.map +0 -1
@@ -1,4 +1,4 @@
1
- const require_secret_config = require("./secret-config-BvFl2dC8.js");
1
+ const require_secret_config = require("./secret-config--cVTOWwp.js");
2
2
  const require_internal_log = require("./internal-log-DwqTjhpb.js");
3
3
  let node_path = require("node:path");
4
4
  node_path = require_secret_config.__toESM(node_path);
@@ -43,25 +43,56 @@ let node_worker_threads = require("node:worker_threads");
43
43
  * thread, completely removing JSON serialization and I/O from the main event loop.
44
44
  */
45
45
  var WorkerTransport = class {
46
+ name = "worker";
47
+ level;
48
+ batchSize = 1;
49
+ flushInterval = 0;
50
+ worker = null;
51
+ ready = false;
52
+ buffer = [];
53
+ bufferSize;
54
+ restarts = 0;
55
+ maxRestarts;
56
+ config;
57
+ /** Pending restart-backoff timer, so close() can cancel a queued restart. */
58
+ restartTimer = null;
59
+ /** Set once close() begins, so a worker 'exit' no longer triggers a restart. */
60
+ closing = false;
61
+ /** Writes have been posted since the last flush; keeps the beforeExit flush from looping. */
62
+ dirty = false;
63
+ /** Run once the worker reports ready, used when the process wants to exit before that. */
64
+ onReady;
65
+ /** Max time to wait for the worker's 'flushed' ack before giving up. */
66
+ FLUSH_TIMEOUT_MS = 5e3;
67
+ /** Max time to wait for a graceful worker exit before force-terminating. */
68
+ SHUTDOWN_TIMEOUT_MS = 5e3;
46
69
  constructor(config) {
47
- this.name = "worker";
48
- this.batchSize = 1;
49
- this.flushInterval = 0;
50
- this.worker = null;
51
- this.ready = false;
52
- this.buffer = [];
53
- this.restarts = 0;
54
- this.restartTimer = null;
55
- this.closing = false;
56
- this.FLUSH_TIMEOUT_MS = 5e3;
57
- this.SHUTDOWN_TIMEOUT_MS = 5e3;
58
70
  this.config = config;
59
71
  this.bufferSize = config.bufferSize ?? 1e3;
60
72
  this.maxRestarts = config.maxRestarts ?? 3;
61
73
  this.level = config.level;
62
74
  require_secret_config.protectSecrets(this, ["config"]);
63
75
  this.startWorker();
76
+ process.on("beforeExit", this.flushForExit);
64
77
  }
78
+ /**
79
+ * The worker is unref'd so it never keeps the process alive on its own; the
80
+ * trade-off is that lines still queued on it would be lost when the event loop
81
+ * drains. On beforeExit, re-ref the worker until it acknowledges a flush.
82
+ */
83
+ flushForExit = () => {
84
+ var _worker$ref;
85
+ const worker = this.worker;
86
+ if (!worker || this.closing || !this.dirty) return;
87
+ (_worker$ref = worker.ref) === null || _worker$ref === void 0 || _worker$ref.call(worker);
88
+ const timer = setTimeout(() => worker.unref(), this.FLUSH_TIMEOUT_MS);
89
+ const done = () => {
90
+ clearTimeout(timer);
91
+ worker.unref();
92
+ };
93
+ if (this.ready) this.flush().finally(done);
94
+ else this.onReady = () => void this.flush().finally(done);
95
+ };
65
96
  startWorker() {
66
97
  try {
67
98
  this.worker = new node_worker_threads.Worker(this.workerFile(), { workerData: {
@@ -73,6 +104,9 @@ var WorkerTransport = class {
73
104
  if (msg.type === "ready") {
74
105
  this.ready = true;
75
106
  this.drainBuffer();
107
+ const onReady = this.onReady;
108
+ this.onReady = void 0;
109
+ onReady === null || onReady === void 0 || onReady();
76
110
  } else if (msg.type === "error" || msg.type === "write-error") require_internal_log.internalError(`WorkerTransport [${this.config.transportType}]: ${msg.error ?? "unknown"}`);
77
111
  });
78
112
  this.worker.on("error", (err) => {
@@ -85,6 +119,7 @@ var WorkerTransport = class {
85
119
  this.handleWorkerExit();
86
120
  }
87
121
  });
122
+ this.worker.unref();
88
123
  } catch (err) {
89
124
  require_internal_log.internalError("WorkerTransport failed to start", err);
90
125
  }
@@ -116,6 +151,7 @@ var WorkerTransport = class {
116
151
  }
117
152
  }
118
153
  write(entry) {
154
+ this.dirty = true;
119
155
  if (this.ready && this.worker) this.worker.postMessage({
120
156
  type: "write",
121
157
  entry
@@ -129,18 +165,25 @@ var WorkerTransport = class {
129
165
  }
130
166
  }
131
167
  async flush() {
168
+ var _worker$ref2;
132
169
  if (!this.ready || !this.worker) return;
133
170
  const worker = this.worker;
171
+ this.dirty = false;
172
+ (_worker$ref2 = worker.ref) === null || _worker$ref2 === void 0 || _worker$ref2.call(worker);
134
173
  return new Promise((resolve) => {
135
174
  const timer = setTimeout(() => {
175
+ var _worker$unref;
136
176
  worker.off("message", handler);
177
+ (_worker$unref = worker.unref) === null || _worker$unref === void 0 || _worker$unref.call(worker);
137
178
  resolve();
138
179
  }, this.FLUSH_TIMEOUT_MS);
139
180
  if (timer.unref) timer.unref();
140
181
  const handler = (msg) => {
141
182
  if (msg.type === "flushed") {
183
+ var _worker$unref2;
142
184
  clearTimeout(timer);
143
185
  worker.off("message", handler);
186
+ (_worker$unref2 = worker.unref) === null || _worker$unref2 === void 0 || _worker$unref2.call(worker);
144
187
  resolve();
145
188
  }
146
189
  };
@@ -156,7 +199,9 @@ var WorkerTransport = class {
156
199
  * graceful exit, leaking the worker thread and dropping its buffered logs.
157
200
  */
158
201
  async close() {
202
+ var _worker$ref3;
159
203
  this.closing = true;
204
+ process.removeListener("beforeExit", this.flushForExit);
160
205
  if (this.restartTimer) {
161
206
  clearTimeout(this.restartTimer);
162
207
  this.restartTimer = null;
@@ -166,6 +211,7 @@ var WorkerTransport = class {
166
211
  this.worker = null;
167
212
  this.drainBufferTo(worker);
168
213
  worker.postMessage({ type: "shutdown" });
214
+ (_worker$ref3 = worker.ref) === null || _worker$ref3 === void 0 || _worker$ref3.call(worker);
169
215
  await new Promise((resolve) => {
170
216
  const timer = setTimeout(() => {
171
217
  worker.terminate().finally(() => resolve());
@@ -198,4 +244,4 @@ Object.defineProperty(exports, "WorkerTransport", {
198
244
  }
199
245
  });
200
246
 
201
- //# sourceMappingURL=worker.transport-DQDv1nAJ.js.map
247
+ //# sourceMappingURL=worker.transport-C7jNGhev.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.transport-C7jNGhev.js","names":["Worker","path"],"sources":["../src/transports/worker.transport.ts"],"sourcesContent":["/**\n * logixia — Worker Thread Transport\n *\n * Offloads JSON serialization and all I/O to a Node.js worker thread,\n * completely eliminating any event-loop impact from logging. The main thread\n * only posts a raw message to the worker — it never calls JSON.stringify or\n * any I/O syscalls on the hot path.\n *\n * Architecture:\n * Main thread → MessageChannel → Worker thread → Wrapped transport\n *\n * The worker runs an ordinary logixia transport (file, database, console…)\n * inside its own event loop. If the worker crashes it is restarted automatically\n * (up to `maxRestarts` times) and buffered messages are replayed.\n *\n * @example\n * ```ts\n * import { WorkerTransport } from 'logixia/worker';\n *\n * const logger = createLogger({\n * transports: {\n * // Run file transport inside a worker thread — zero event-loop impact\n * custom: [\n * new WorkerTransport({\n * transportType: 'file',\n * transportConfig: { filename: 'app.log', dirname: './logs' },\n * bufferSize: 500,\n * maxRestarts: 3,\n * }),\n * ],\n * },\n * });\n * ```\n */\n\nimport path from 'node:path';\nimport { Worker } from 'node:worker_threads';\n\nimport type { ITransport, TransportLogEntry } from '../types/transport.types';\nimport { internalError, internalWarn } from '../utils/internal-log';\nimport { protectSecrets } from './secret-config';\n\nexport interface WorkerTransportConfig {\n /**\n * Which built-in logixia transport to run inside the worker thread.\n * The worker resolves the correct module automatically.\n */\n transportType: 'file' | 'database' | 'console';\n /** Config forwarded verbatim to the wrapped transport constructor. */\n transportConfig: Record<string, unknown>;\n /**\n * Max log entries to buffer in the main thread while the worker is starting\n * or restarting. Entries beyond this limit are dropped with a warning.\n * @default 1000\n */\n bufferSize?: number;\n /**\n * How many times to restart the worker if it crashes unexpectedly.\n * @default 3\n */\n maxRestarts?: number;\n /**\n * Custom level severities (`levelOptions.levels`) the wrapped transport's own\n * `level` is compared against inside the worker. Built-in levels need no entry.\n */\n levels?: Record<string, number>;\n /**\n * Log level filter — only entries at or above this level are forwarded.\n * Useful for routing only errors to an expensive transport in a worker.\n */\n level?: string;\n}\n\n/**\n * Transport that runs a wrapped transport inside a dedicated Node.js worker\n * thread, completely removing JSON serialization and I/O from the main event loop.\n */\nexport class WorkerTransport implements ITransport {\n public readonly name = 'worker';\n public readonly level: string | undefined;\n public readonly batchSize = 1;\n public readonly flushInterval = 0;\n\n private worker: Worker | null = null;\n private ready = false;\n private readonly buffer: TransportLogEntry[] = [];\n private readonly bufferSize: number;\n private restarts = 0;\n private readonly maxRestarts: number;\n private readonly config: WorkerTransportConfig;\n /** Pending restart-backoff timer, so close() can cancel a queued restart. */\n private restartTimer: NodeJS.Timeout | null = null;\n /** Set once close() begins, so a worker 'exit' no longer triggers a restart. */\n private closing = false;\n /** Writes have been posted since the last flush; keeps the beforeExit flush from looping. */\n private dirty = false;\n /** Run once the worker reports ready, used when the process wants to exit before that. */\n private onReady: (() => void) | undefined;\n /** Max time to wait for the worker's 'flushed' ack before giving up. */\n private readonly FLUSH_TIMEOUT_MS = 5000;\n /** Max time to wait for a graceful worker exit before force-terminating. */\n private readonly SHUTDOWN_TIMEOUT_MS = 5000;\n\n constructor(config: WorkerTransportConfig) {\n this.config = config;\n this.bufferSize = config.bufferSize ?? 1000;\n this.maxRestarts = config.maxRestarts ?? 3;\n this.level = config.level;\n protectSecrets(this, ['config']);\n this.startWorker();\n process.on('beforeExit', this.flushForExit);\n }\n\n /**\n * The worker is unref'd so it never keeps the process alive on its own; the\n * trade-off is that lines still queued on it would be lost when the event loop\n * drains. On beforeExit, re-ref the worker until it acknowledges a flush.\n */\n private readonly flushForExit = (): void => {\n const worker = this.worker;\n if (!worker || this.closing || !this.dirty) return;\n worker.ref?.();\n const timer = setTimeout(() => worker.unref(), this.FLUSH_TIMEOUT_MS);\n const done = (): void => {\n clearTimeout(timer);\n worker.unref();\n };\n if (this.ready) {\n void this.flush().finally(done);\n } else {\n this.onReady = () => void this.flush().finally(done);\n }\n };\n\n private startWorker(): void {\n try {\n this.worker = new Worker(this.workerFile(), {\n workerData: {\n transportType: this.config.transportType,\n transportConfig: this.config.transportConfig,\n levels: this.config.levels,\n },\n });\n\n this.worker.on('message', (msg: { type: string; error?: string }) => {\n if (msg.type === 'ready') {\n this.ready = true;\n this.drainBuffer();\n const onReady = this.onReady;\n this.onReady = undefined;\n onReady?.();\n } else if (msg.type === 'error' || msg.type === 'write-error') {\n internalError(\n `WorkerTransport [${this.config.transportType}]: ${msg.error ?? 'unknown'}`\n );\n }\n });\n\n this.worker.on('error', (err) => {\n internalError('WorkerTransport worker error', err);\n this.handleWorkerExit();\n });\n\n this.worker.on('exit', (code) => {\n if (code !== 0) {\n internalWarn(`WorkerTransport worker exited with code ${code}`);\n this.handleWorkerExit();\n }\n });\n\n // After the listeners: adding a 'message' listener re-refs the worker's port.\n this.worker.unref();\n } catch (err) {\n internalError('WorkerTransport failed to start', err);\n }\n }\n\n /** The worker entry is always built as CommonJS, next to this module's output. */\n protected workerFile(): string {\n return path.join(__dirname, 'worker-entry.js');\n }\n\n private handleWorkerExit(): void {\n this.ready = false;\n // Don't resurrect a worker we're intentionally shutting down — close() sets\n // `closing` and nulls the worker, so a late 'exit'/'error' event must not\n // queue a restart (which would spawn a fresh leaked thread post-shutdown).\n if (this.closing) return;\n if (this.restarts < this.maxRestarts) {\n this.restarts++;\n internalWarn(`WorkerTransport restarting (attempt ${this.restarts}/${this.maxRestarts})`);\n // Small backoff before restart. unref() so a perpetually-failing worker's\n // pending restart never keeps the process alive on its own.\n this.restartTimer = setTimeout(() => {\n this.restartTimer = null;\n this.startWorker();\n }, 500 * this.restarts);\n if (this.restartTimer.unref) this.restartTimer.unref();\n } else {\n internalError(\n `WorkerTransport exhausted ${this.maxRestarts} restart attempts — transport disabled`\n );\n }\n }\n\n private drainBuffer(): void {\n while (this.buffer.length > 0 && this.ready && this.worker) {\n const entry = this.buffer.shift();\n if (entry) {\n this.worker.postMessage({ type: 'write', entry });\n }\n }\n }\n\n write(entry: TransportLogEntry): void {\n this.dirty = true;\n if (this.ready && this.worker) {\n this.worker.postMessage({ type: 'write', entry });\n } else {\n if (this.buffer.length >= this.bufferSize) {\n internalWarn('WorkerTransport buffer full — dropping oldest entry');\n this.buffer.shift();\n }\n this.buffer.push(entry);\n }\n }\n\n async flush(): Promise<void> {\n if (!this.ready || !this.worker) return;\n const worker = this.worker;\n this.dirty = false;\n // Unref'd between flushes; ref'd here so an awaited flush() keeps the process alive.\n worker.ref?.();\n return new Promise<void>((resolve) => {\n // Time-box the flush: if the worker dies or restarts before answering,\n // the 'flushed' message would never arrive and this promise would hang\n // forever, blocking shutdown until the force-exit timer kills the process\n // (losing everything). Resolve on timeout so close() can still terminate.\n const timer = setTimeout(() => {\n worker.off('message', handler);\n worker.unref?.();\n resolve();\n }, this.FLUSH_TIMEOUT_MS);\n if (timer.unref) timer.unref();\n\n const handler = (msg: { type: string }) => {\n if (msg.type === 'flushed') {\n clearTimeout(timer);\n worker.off('message', handler);\n worker.unref?.();\n resolve();\n }\n };\n worker.on('message', handler);\n worker.postMessage({ type: 'flush' });\n });\n }\n\n /**\n * Flush the worker's buffer and terminate the thread on shutdown.\n *\n * This MUST be named close() — TransportManager.close() invokes\n * transport.close(), so a method named only shutdown() was never called on\n * graceful exit, leaking the worker thread and dropping its buffered logs.\n */\n async close(): Promise<void> {\n // Stop the restart loop first: cancel any queued backoff restart and flag\n // that further worker exits are expected (so handleWorkerExit no-ops).\n this.closing = true;\n process.removeListener('beforeExit', this.flushForExit);\n if (this.restartTimer) {\n clearTimeout(this.restartTimer);\n this.restartTimer = null;\n }\n\n if (!this.worker) return;\n const worker = this.worker;\n this.worker = null;\n\n // Push any locally-buffered (pre-ready) entries first: the worker's port\n // queues them until its listener attaches, so they are handled before the\n // shutdown message, which flushes the wrapped transport and exits.\n this.drainBufferTo(worker);\n worker.postMessage({ type: 'shutdown' });\n // The worker is unref'd, so hold the process open until it has drained and exited.\n worker.ref?.();\n\n await new Promise<void>((resolve) => {\n // Don't wait forever for a wedged worker — terminate() it after a timeout.\n const timer = setTimeout(() => {\n worker.terminate().finally(() => resolve());\n }, this.SHUTDOWN_TIMEOUT_MS);\n if (timer.unref) timer.unref();\n\n worker.once('exit', () => {\n clearTimeout(timer);\n resolve();\n });\n });\n }\n\n /** Back-compat alias — prefer close(). */\n async shutdown(): Promise<void> {\n await this.close();\n }\n\n private drainBufferTo(worker: Worker): void {\n while (this.buffer.length > 0) {\n const entry = this.buffer.shift();\n if (entry) worker.postMessage({ type: 'write', entry });\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6EA,IAAa,kBAAb,MAAmD;CACjD,OAAuB;CACvB;CACA,YAA4B;CAC5B,gBAAgC;CAEhC,SAAgC;CAChC,QAAgB;CAChB,SAA+C,CAAC;CAChD;CACA,WAAmB;CACnB;CACA;;CAEA,eAA8C;;CAE9C,UAAkB;;CAElB,QAAgB;;CAEhB;;CAEA,mBAAoC;;CAEpC,sBAAuC;CAEvC,YAAY,QAA+B;EACzC,KAAK,SAAS;EACd,KAAK,aAAa,OAAO,cAAc;EACvC,KAAK,cAAc,OAAO,eAAe;EACzC,KAAK,QAAQ,OAAO;EACpB,sBAAA,eAAe,MAAM,CAAC,QAAQ,CAAC;EAC/B,KAAK,YAAY;EACjB,QAAQ,GAAG,cAAc,KAAK,YAAY;CAC5C;;;;;;CAOA,qBAA4C;;EAC1C,MAAM,SAAS,KAAK;EACpB,IAAI,CAAC,UAAU,KAAK,WAAW,CAAC,KAAK,OAAO;EAC5C,CAAA,cAAA,OAAO,SAAA,QAAA,gBAAA,KAAA,KAAA,YAAA,KAAA,MAAM;EACb,MAAM,QAAQ,iBAAiB,OAAO,MAAM,GAAG,KAAK,gBAAgB;EACpE,MAAM,aAAmB;GACvB,aAAa,KAAK;GAClB,OAAO,MAAM;EACf;EACA,IAAI,KAAK,OACP,KAAU,MAAM,CAAC,CAAC,QAAQ,IAAI;OAE9B,KAAK,gBAAgB,KAAK,KAAK,MAAM,CAAC,CAAC,QAAQ,IAAI;CAEvD;CAEA,cAA4B;EAC1B,IAAI;GACF,KAAK,SAAS,IAAIA,oBAAAA,OAAO,KAAK,WAAW,GAAG,EAC1C,YAAY;IACV,eAAe,KAAK,OAAO;IAC3B,iBAAiB,KAAK,OAAO;IAC7B,QAAQ,KAAK,OAAO;GACtB,EACF,CAAC;GAED,KAAK,OAAO,GAAG,YAAY,QAA0C;IACnE,IAAI,IAAI,SAAS,SAAS;KACxB,KAAK,QAAQ;KACb,KAAK,YAAY;KACjB,MAAM,UAAU,KAAK;KACrB,KAAK,UAAU,KAAA;KACf,YAAA,QAAA,YAAA,KAAA,KAAA,QAAU;IACZ,OAAO,IAAI,IAAI,SAAS,WAAW,IAAI,SAAS,eAC9C,qBAAA,cACE,oBAAoB,KAAK,OAAO,cAAc,KAAK,IAAI,SAAS,WAClE;GAEJ,CAAC;GAED,KAAK,OAAO,GAAG,UAAU,QAAQ;IAC/B,qBAAA,cAAc,gCAAgC,GAAG;IACjD,KAAK,iBAAiB;GACxB,CAAC;GAED,KAAK,OAAO,GAAG,SAAS,SAAS;IAC/B,IAAI,SAAS,GAAG;KACd,qBAAA,aAAa,2CAA2C,MAAM;KAC9D,KAAK,iBAAiB;IACxB;GACF,CAAC;GAGD,KAAK,OAAO,MAAM;EACpB,SAAS,KAAK;GACZ,qBAAA,cAAc,mCAAmC,GAAG;EACtD;CACF;;CAGA,aAA+B;EAC7B,OAAOC,UAAAA,QAAK,KAAK,WAAW,iBAAiB;CAC/C;CAEA,mBAAiC;EAC/B,KAAK,QAAQ;EAIb,IAAI,KAAK,SAAS;EAClB,IAAI,KAAK,WAAW,KAAK,aAAa;GACpC,KAAK;GACL,qBAAA,aAAa,uCAAuC,KAAK,SAAS,GAAG,KAAK,YAAY,EAAE;GAGxF,KAAK,eAAe,iBAAiB;IACnC,KAAK,eAAe;IACpB,KAAK,YAAY;GACnB,GAAG,MAAM,KAAK,QAAQ;GACtB,IAAI,KAAK,aAAa,OAAO,KAAK,aAAa,MAAM;EACvD,OACE,qBAAA,cACE,6BAA6B,KAAK,YAAY,uCAChD;CAEJ;CAEA,cAA4B;EAC1B,OAAO,KAAK,OAAO,SAAS,KAAK,KAAK,SAAS,KAAK,QAAQ;GAC1D,MAAM,QAAQ,KAAK,OAAO,MAAM;GAChC,IAAI,OACF,KAAK,OAAO,YAAY;IAAE,MAAM;IAAS;GAAM,CAAC;EAEpD;CACF;CAEA,MAAM,OAAgC;EACpC,KAAK,QAAQ;EACb,IAAI,KAAK,SAAS,KAAK,QACrB,KAAK,OAAO,YAAY;GAAE,MAAM;GAAS;EAAM,CAAC;OAC3C;GACL,IAAI,KAAK,OAAO,UAAU,KAAK,YAAY;IACzC,qBAAA,aAAa,qDAAqD;IAClE,KAAK,OAAO,MAAM;GACpB;GACA,KAAK,OAAO,KAAK,KAAK;EACxB;CACF;CAEA,MAAM,QAAuB;;EAC3B,IAAI,CAAC,KAAK,SAAS,CAAC,KAAK,QAAQ;EACjC,MAAM,SAAS,KAAK;EACpB,KAAK,QAAQ;EAEb,CAAA,eAAA,OAAO,SAAA,QAAA,iBAAA,KAAA,KAAA,aAAA,KAAA,MAAM;EACb,OAAO,IAAI,SAAe,YAAY;GAKpC,MAAM,QAAQ,iBAAiB;;IAC7B,OAAO,IAAI,WAAW,OAAO;IAC7B,CAAA,gBAAA,OAAO,WAAA,QAAA,kBAAA,KAAA,KAAA,cAAA,KAAA,MAAQ;IACf,QAAQ;GACV,GAAG,KAAK,gBAAgB;GACxB,IAAI,MAAM,OAAO,MAAM,MAAM;GAE7B,MAAM,WAAW,QAA0B;IACzC,IAAI,IAAI,SAAS,WAAW;;KAC1B,aAAa,KAAK;KAClB,OAAO,IAAI,WAAW,OAAO;KAC7B,CAAA,iBAAA,OAAO,WAAA,QAAA,mBAAA,KAAA,KAAA,eAAA,KAAA,MAAQ;KACf,QAAQ;IACV;GACF;GACA,OAAO,GAAG,WAAW,OAAO;GAC5B,OAAO,YAAY,EAAE,MAAM,QAAQ,CAAC;EACtC,CAAC;CACH;;;;;;;;CASA,MAAM,QAAuB;;EAG3B,KAAK,UAAU;EACf,QAAQ,eAAe,cAAc,KAAK,YAAY;EACtD,IAAI,KAAK,cAAc;GACrB,aAAa,KAAK,YAAY;GAC9B,KAAK,eAAe;EACtB;EAEA,IAAI,CAAC,KAAK,QAAQ;EAClB,MAAM,SAAS,KAAK;EACpB,KAAK,SAAS;EAKd,KAAK,cAAc,MAAM;EACzB,OAAO,YAAY,EAAE,MAAM,WAAW,CAAC;EAEvC,CAAA,eAAA,OAAO,SAAA,QAAA,iBAAA,KAAA,KAAA,aAAA,KAAA,MAAM;EAEb,MAAM,IAAI,SAAe,YAAY;GAEnC,MAAM,QAAQ,iBAAiB;IAC7B,OAAO,UAAU,CAAC,CAAC,cAAc,QAAQ,CAAC;GAC5C,GAAG,KAAK,mBAAmB;GAC3B,IAAI,MAAM,OAAO,MAAM,MAAM;GAE7B,OAAO,KAAK,cAAc;IACxB,aAAa,KAAK;IAClB,QAAQ;GACV,CAAC;EACH,CAAC;CACH;;CAGA,MAAM,WAA0B;EAC9B,MAAM,KAAK,MAAM;CACnB;CAEA,cAAsB,QAAsB;EAC1C,OAAO,KAAK,OAAO,SAAS,GAAG;GAC7B,MAAM,QAAQ,KAAK,OAAO,MAAM;GAChC,IAAI,OAAO,OAAO,YAAY;IAAE,MAAM;IAAS;GAAM,CAAC;EACxD;CACF;AACF"}
@@ -1,4 +1,4 @@
1
- import { _ as TransportLogEntry, d as ITransport } from "./transport.types-CzJq4IrF.mjs";
1
+ import { _ as TransportLogEntry, d as ITransport } from "./transport.types-B1ejJJP6.mjs";
2
2
  interface WorkerTransportConfig {
3
3
  /**
4
4
  * Which built-in logixia transport to run inside the worker thread.
@@ -49,11 +49,21 @@ declare class WorkerTransport implements ITransport {
49
49
  private restartTimer;
50
50
  /** Set once close() begins, so a worker 'exit' no longer triggers a restart. */
51
51
  private closing;
52
+ /** Writes have been posted since the last flush; keeps the beforeExit flush from looping. */
53
+ private dirty;
54
+ /** Run once the worker reports ready, used when the process wants to exit before that. */
55
+ private onReady;
52
56
  /** Max time to wait for the worker's 'flushed' ack before giving up. */
53
57
  private readonly FLUSH_TIMEOUT_MS;
54
58
  /** Max time to wait for a graceful worker exit before force-terminating. */
55
59
  private readonly SHUTDOWN_TIMEOUT_MS;
56
60
  constructor(config: WorkerTransportConfig);
61
+ /**
62
+ * The worker is unref'd so it never keeps the process alive on its own; the
63
+ * trade-off is that lines still queued on it would be lost when the event loop
64
+ * drains. On beforeExit, re-ref the worker until it acknowledges a flush.
65
+ */
66
+ private readonly flushForExit;
57
67
  private startWorker;
58
68
  /** The worker entry is always built as CommonJS, next to this module's output. */
59
69
  protected workerFile(): string;
@@ -74,4 +84,4 @@ declare class WorkerTransport implements ITransport {
74
84
  private drainBufferTo;
75
85
  }
76
86
  export { WorkerTransportConfig as n, WorkerTransport as t };
77
- //# sourceMappingURL=worker.transport-Bl8lFRck.d.mts.map
87
+ //# sourceMappingURL=worker.transport-DnU0_9Bd.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.transport-DnU0_9Bd.d.mts","names":[],"sources":["../src/transports/worker.transport.ts"],"mappings":";UA0CiB;;;;;EAKf;;EAEA,iBAAiB;;;;;;EAMjB;;;;;EAKA;;;;;EAKA,SAAS;;;;;EAKT;;;;;;cAOW,2BAA2B;WACtB;WACA;WACA;WACA;UAER;UACA;mBACS;mBACA;UACT;mBACS;mBACA;;UAET;;UAEA;;UAEA;;UAEA;;mBAES;;mBAEA;EAEL,YAAA,QAAQ;;;;;;mBAeH;UAgBT;;YA4CE;UAIF;UAuBA;EASR,MAAM,OAAO;EAaP,SAAS;;;;;;;;EAsCT,SAAS;;EAqCT,YAAY;UAIV"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "logixia",
3
- "version": "2.0.10",
4
- "description": "Async-first TypeScript logger for Node, NestJS and the edge: request tracing, redaction, OpenTelemetry/OTLP export, file/database/cloud transports, sampling and log search. Winston/Pino alternative.",
3
+ "version": "2.1.0",
4
+ "description": "TypeScript logger for Node.js, NestJS and edge runtimes: structured JSON logs, request trace IDs, redaction, OpenTelemetry/OTLP and cloud transports. Pino/Winston alternative.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",
@@ -171,6 +171,7 @@
171
171
  "dev:intelligent-search": "ts-node -P tsconfig.examples.json --transpile-only -r ./examples/register.js examples/intelligent-search.ts",
172
172
  "benchmark": "npm run build && node benchmarks/run.mjs",
173
173
  "check:browser": "node --experimental-vm-modules --no-warnings scripts/check-browser-entry.mjs",
174
+ "check:dist": "node scripts/check-dist-runtime.mjs",
174
175
  "check:exports": "node scripts/check-exports.mjs",
175
176
  "check:optional-peers": "node scripts/check-optional-peers.mjs",
176
177
  "size": "size-limit",
@@ -216,7 +217,13 @@
216
217
  "log-rotation",
217
218
  "log-search",
218
219
  "prometheus",
219
- "observability"
220
+ "observability",
221
+ "nodejs-logger",
222
+ "json-logger",
223
+ "log-redaction",
224
+ "pii",
225
+ "bun",
226
+ "nodejs"
220
227
  ],
221
228
  "author": {
222
229
  "name": "Sanjeev Sharma",