@monochromatic-dev/module-logger 0.2.0 → 0.4.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 (64) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +53 -13
  3. package/dist/final/neutral/browser.d.mts +60 -0
  4. package/dist/final/neutral/browser.mjs +1 -0
  5. package/dist/final/neutral/index.d.mts +359 -596
  6. package/dist/final/neutral/index.mjs +2 -3
  7. package/dist/final/neutral/indexed-db-hsIfv7Cv.mjs +2 -0
  8. package/dist/final/neutral/types-BkkBXgY3.d.mts +76 -0
  9. package/dist/final/node/file-CRGb1hDK.mjs +1 -0
  10. package/dist/final/node/index.d.mts +359 -596
  11. package/dist/final/node/index.mjs +3 -3
  12. package/dist/final/node/node.d.mts +103 -0
  13. package/dist/final/node/node.mjs +1 -0
  14. package/dist/final/node/types-BkkBXgY3.d.mts +76 -0
  15. package/package.json +19 -4
  16. package/src/artifact-platform-split.unit.test.ts +140 -0
  17. package/src/browser.ts +14 -0
  18. package/src/create-logger.ts +183 -183
  19. package/src/create-logger.unit.test.ts +112 -112
  20. package/src/default-sinks.neutral.ts +47 -0
  21. package/src/default-sinks.node.ts +43 -0
  22. package/src/error-format.ts +23 -23
  23. package/src/index.ts +1 -4
  24. package/src/logger.ts +76 -51
  25. package/src/node.ts +23 -0
  26. package/src/restricted-global-scope.unit.test.ts +101 -0
  27. package/src/sink/console-control-chars.ts +64 -64
  28. package/src/sink/console-control-chars.unit.test.ts +14 -14
  29. package/src/sink/console.ts +194 -194
  30. package/src/sink/console.unit.test.ts +18 -18
  31. package/src/sink/file.ts +136 -140
  32. package/src/sink/file.unit.test.ts +19 -26
  33. package/src/sink/index.ts +4 -7
  34. package/src/sink/indexed-db-util.ts +42 -42
  35. package/src/sink/indexed-db.browser.test.ts +7 -7
  36. package/src/sink/indexed-db.ts +109 -109
  37. package/src/sink/indexed-db.unit.test.ts +5 -13
  38. package/src/sink/local-storage-key.ts +73 -73
  39. package/src/sink/local-storage-key.unit.test.ts +8 -8
  40. package/src/sink/local-storage-quota.ts +37 -37
  41. package/src/sink/local-storage-quota.unit.test.ts +8 -8
  42. package/src/sink/local-storage-store.ts +113 -113
  43. package/src/sink/local-storage-store.unit.test.ts +35 -35
  44. package/src/sink/local-storage.ts +72 -72
  45. package/src/sink/local-storage.unit.test.ts +27 -27
  46. package/src/sink/noop.ts +20 -20
  47. package/src/sink/noop.unit.test.ts +1 -1
  48. package/src/sink/opfs.browser.test.ts +7 -7
  49. package/src/sink/opfs.ts +62 -62
  50. package/src/sink/opfs.unit.test.ts +5 -13
  51. package/src/sink/record-buffer.ts +84 -84
  52. package/src/sink/record-buffer.unit.test.ts +20 -20
  53. package/src/sink/session-storage-quota.ts +34 -34
  54. package/src/sink/session-storage-quota.unit.test.ts +8 -8
  55. package/src/sink/session-storage-store.ts +72 -72
  56. package/src/sink/session-storage.ts +48 -48
  57. package/src/sink/session-storage.unit.test.ts +39 -39
  58. package/src/sink/web-storage-quota-error.ts +22 -22
  59. package/src/sink/web-storage-quota-error.unit.test.ts +2 -2
  60. package/src/sink/web-storage-runtime.ts +24 -24
  61. package/src/startup.unit.test.ts +18 -18
  62. package/src/tagged.ts +35 -35
  63. package/src/tagged.unit.test.ts +8 -8
  64. package/src/types.ts +39 -39
@@ -9,41 +9,41 @@ import type {
9
9
  } from './types.ts';
10
10
 
11
11
  /**
12
- * Default `flush()` deadline in milliseconds. Measured on 2026-09-06: a
13
- * default logger flushing 100 records through the console and file sinks
14
- * settles in about 2 ms locally, so this leaves three orders of magnitude for
15
- * a slow but working backend while still bounding shutdown on a wedged one.
16
- * Override per logger through the `flushDeadlineMs` option of
17
- * {@link createLogger}.
12
+ Default `flush()` deadline in milliseconds. Measured on 2026-09-06: a
13
+ default logger flushing 100 records through the console and file sinks
14
+ settles in about 2 ms locally, so this leaves three orders of magnitude for
15
+ a slow but working backend while still bounding shutdown on a wedged one.
16
+ Override per logger through the `flushDeadlineMs` option of
17
+ {@link createLogger}.
18
18
  */
19
19
  export const DEFAULT_FLUSH_DEADLINE_MS = 5_000;
20
20
 
21
21
  /**
22
- * Default per-sink `verify()` time limit in milliseconds. Measured on
23
- * 2026-09-06: the default logger's five shipped verifies complete together in
24
- * about 2.4 ms locally, so this leaves three orders of magnitude for a slow
25
- * but working backend probe (a network filesystem, a busy IndexedDB) while a
26
- * verify that never answers (a hung mount, an IndexedDB open blocked by
27
- * another tab) can no longer stall startup. Override per logger through the
28
- * `verifyTimeoutMs` option of {@link createLogger}.
22
+ Default per-sink `verify()` time limit in milliseconds. Measured on
23
+ 2026-09-06: the default logger's five shipped verifies complete together in
24
+ about 2.4 ms locally, so this leaves three orders of magnitude for a slow
25
+ but working backend probe (a network filesystem, a busy IndexedDB) while a
26
+ verify that never answers (a hung mount, an IndexedDB open blocked by
27
+ another tab) can no longer stall startup. Override per logger through the
28
+ `verifyTimeoutMs` option of {@link createLogger}.
29
29
  */
30
30
  export const DEFAULT_VERIFY_TIMEOUT_MS = 5_000;
31
31
 
32
32
  /**
33
- * Most records the logger buffers before its sinks have verified. Startup
34
- * lasts at most {@link DEFAULT_VERIFY_TIMEOUT_MS}, so this bounds the memory a
35
- * burst during that window can claim; on overflow the oldest buffered record
36
- * is dropped so the newest (usually most diagnostic) context survives, and
37
- * one synthetic `warn` record naming the dropped count is written to every
38
- * available sink once initialization completes.
33
+ Most records the logger buffers before its sinks have verified. Startup
34
+ lasts at most {@link DEFAULT_VERIFY_TIMEOUT_MS}, so this bounds the memory a
35
+ burst during that window can claim; on overflow the oldest buffered record
36
+ is dropped so the newest (usually most diagnostic) context survives, and
37
+ one synthetic `warn` record naming the dropped count is written to every
38
+ available sink once initialization completes.
39
39
  */
40
40
  export const STARTUP_BUFFER_CAP = 10_000;
41
41
 
42
42
  /**
43
- * Sink paired with its current availability inside one logger instance.
44
- * Availability starts `false` (not-yet-verified reads as unavailable,
45
- * identical to a verified failure) and flips `true` once the sink's own
46
- * `verify` confirms its backend.
43
+ Sink paired with its current availability inside one logger instance.
44
+ Availability starts `false` (not-yet-verified reads as unavailable,
45
+ identical to a verified failure) and flips `true` once the sink's own
46
+ `verify` confirms its backend.
47
47
  */
48
48
  type SinkEntry = {
49
49
  available: boolean;
@@ -51,12 +51,12 @@ type SinkEntry = {
51
51
  };
52
52
 
53
53
  /**
54
- * Awaits one sink write so `flush()` can observe its settling. A rejected
55
- * write is swallowed here via {@link reportLoggerInternalError} (the sink
56
- * owns its own write-error handling) and does not disable the sink: one
57
- * transient failure must not retire a backend for the rest of the run.
58
- *
59
- * @param writePromise - Promise returned by the sink write call.
54
+ Awaits one sink write so `flush()` can observe its settling. A rejected
55
+ write is swallowed here via {@link reportLoggerInternalError} (the sink
56
+ owns its own write-error handling) and does not disable the sink: one
57
+ transient failure must not retire a backend for the rest of the run.
58
+
59
+ @param writePromise - Promise returned by the sink write call.
60
60
  */
61
61
  async function trackWrite(
62
62
  { writePromise, }: { readonly writePromise: Promise<void>; },
@@ -73,56 +73,56 @@ async function trackWrite(
73
73
  }
74
74
 
75
75
  /**
76
- * Builds a multi-sink logger over the supplied sink adapters. All
77
- * orchestration (per-sink availability, startup buffering and replay,
78
- * in-flight write tracking, and flush) lives here; the exported default
79
- * `logger` is just this factory applied to the default sink set, and tests
80
- * apply it to fake sinks to exercise the orchestration directly.
81
- *
82
- * Verification runs eagerly at construction and never blocks callers:
83
- * records emitted while an async sink is still verifying buffer internally
84
- * and replay to that sink the moment it verifies. Every sink verifies
85
- * concurrently under its own time limit (`verifyTimeoutMs`, default
86
- * {@link DEFAULT_VERIFY_TIMEOUT_MS}), so one backend that never answers
87
- * cannot starve the others or keep the logger from initializing. A sink
88
- * whose `verify` resolves `false`, throws, or runs past the limit is dropped
89
- * and receives no records; an answer that arrives after the limit is
90
- * ignored. A rejected `write` is the sink's own concern and does not disable
91
- * the backend.
92
- *
93
- * `flush()` always resolves: one deadline (`flushDeadlineMs`, default
94
- * {@link DEFAULT_FLUSH_DEADLINE_MS}) wraps startup verification, the
95
- * in-flight write drain, and every sink flush hook together. When it elapses
96
- * the logger reports one breadcrumb, abandons the tracked writes from its
97
- * view (the sinks expose no cancellation, so the underlying work continues),
98
- * and resolves, so a wedged backend cannot hang a shutdown.
99
- *
100
- * @param sinks - Sink adapters to fan each record out to, in priority order.
101
- *
102
- * @param flushDeadlineMs - Milliseconds one `flush()` may take before it
103
- * resolves anyway; raise it for slow but working backends such as network
104
- * filesystems.
105
- *
106
- * @param verifyTimeoutMs - Milliseconds one sink's `verify()` may take before
107
- * the sink counts as unavailable; raise it for a slow but working probe.
108
- *
109
- * @returns Logger plus its eager `initPromise`; callers need not await
110
- * `initPromise` before logging, since startup records replay on verify.
111
- *
112
- * @example
113
- * ```ts
114
- * const { logger } = createLogger({ sinks: [createConsoleSink()] });
115
- * logger.info('ready');
116
- * await logger.flush();
117
- * ```
118
- *
119
- * @example
120
- * ```ts
121
- * const { logger } = createLogger({
122
- * sinks: [createFileSink()],
123
- * flushDeadlineMs: 30_000,
124
- * });
125
- * ```
76
+ Builds a multi-sink logger over the supplied sink adapters. All
77
+ orchestration (per-sink availability, startup buffering and replay,
78
+ in-flight write tracking, and flush) lives here; the exported default
79
+ `logger` is just this factory applied to the default sink set, and tests
80
+ apply it to fake sinks to exercise the orchestration directly.
81
+
82
+ Verification runs eagerly at construction and never blocks callers:
83
+ records emitted while an async sink is still verifying buffer internally
84
+ and replay to that sink the moment it verifies. Every sink verifies
85
+ concurrently under its own time limit (`verifyTimeoutMs`, default
86
+ {@link DEFAULT_VERIFY_TIMEOUT_MS}), so one backend that never answers
87
+ cannot starve the others or keep the logger from initializing. A sink
88
+ whose `verify` resolves `false`, throws, or runs past the limit is dropped
89
+ and receives no records; an answer that arrives after the limit is
90
+ ignored. A rejected `write` is the sink's own concern and does not disable
91
+ the backend.
92
+
93
+ `flush()` always resolves: one deadline (`flushDeadlineMs`, default
94
+ {@link DEFAULT_FLUSH_DEADLINE_MS}) wraps startup verification, the
95
+ in-flight write drain, and every sink flush hook together. When it elapses
96
+ the logger reports one breadcrumb, abandons the tracked writes from its
97
+ view (the sinks expose no cancellation, so the underlying work continues),
98
+ and resolves, so a wedged backend cannot hang a shutdown.
99
+
100
+ @param sinks - Sink adapters to fan each record out to, in priority order.
101
+
102
+ @param flushDeadlineMs - Milliseconds one `flush()` may take before it
103
+ resolves anyway; raise it for slow but working backends such as network
104
+ filesystems.
105
+
106
+ @param verifyTimeoutMs - Milliseconds one sink's `verify()` may take before
107
+ the sink counts as unavailable; raise it for a slow but working probe.
108
+
109
+ @returns Logger plus its eager `initPromise`; callers need not await
110
+ `initPromise` before logging, since startup records replay on verify.
111
+
112
+ @example
113
+ ```ts
114
+ const { logger } = createLogger({ sinks: [createConsoleSink()] });
115
+ logger.info('ready');
116
+ await logger.flush();
117
+ ```
118
+
119
+ @example
120
+ ```ts
121
+ const { logger } = createLogger({
122
+ sinks: [createFileSink()],
123
+ flushDeadlineMs: 30_000,
124
+ });
125
+ ```
126
126
  */
127
127
  export function createLogger(
128
128
  {
@@ -139,7 +139,7 @@ export function createLogger(
139
139
  readonly logger: Logger;
140
140
  } {
141
141
  /**
142
- * Per-sink availability for this logger instance, indexed by startup order.
142
+ Per-sink availability for this logger instance, indexed by startup order.
143
143
  */
144
144
  const entries: SinkEntry[] = sinks.map(function toEntry(sink,): SinkEntry {
145
145
  return {
@@ -149,26 +149,26 @@ export function createLogger(
149
149
  },);
150
150
 
151
151
  /**
152
- * Log records emitted before every sink has completed startup verification.
153
- * Records stay here only during initialization; each sink that later
154
- * verifies as available receives a replay, while already-available sinks
155
- * still receive writes immediately.
152
+ Log records emitted before every sink has completed startup verification.
153
+ Records stay here only during initialization; each sink that later
154
+ verifies as available receives a replay, while already-available sinks
155
+ still receive writes immediately.
156
156
  */
157
157
  const startupRecords: LogRecord[] = [];
158
158
 
159
159
  /**
160
- * Sink writes currently in flight. Logger-level `flush()` drains these so
161
- * sinks without their own flush hook, such as file writes, still settle
162
- * before the flush resolves.
160
+ Sink writes currently in flight. Logger-level `flush()` drains these so
161
+ sinks without their own flush hook, such as file writes, still settle
162
+ before the flush resolves.
163
163
  */
164
164
  const pendingWrites = new Set<Promise<void>>();
165
165
 
166
166
  /**
167
- * Instance-local aggregate flags. `initialized` flips true once the eager
168
- * `initialize()` settles; `hasAvailableSink` reflects whether any sink
169
- * survives verification and is recomputed by `recomputeAvailability`;
170
- * `droppedStartupRecords` counts startup-buffer overflow drops for the
171
- * post-initialization marker record.
167
+ Instance-local aggregate flags. `initialized` flips true once the eager
168
+ `initialize()` settles; `hasAvailableSink` reflects whether any sink
169
+ survives verification and is recomputed by `recomputeAvailability`;
170
+ `droppedStartupRecords` counts startup-buffer overflow drops for the
171
+ post-initialization marker record.
172
172
  */
173
173
  const state: {
174
174
  droppedStartupRecords: number;
@@ -181,11 +181,11 @@ export function createLogger(
181
181
  };
182
182
 
183
183
  /**
184
- * Buffers a pre-initialization record under {@link STARTUP_BUFFER_CAP},
185
- * dropping the oldest buffered record (and counting the drop) when the cap
186
- * is reached.
187
- *
188
- * @param record - Record logged before every sink has verified.
184
+ Buffers a pre-initialization record under {@link STARTUP_BUFFER_CAP},
185
+ dropping the oldest buffered record (and counting the drop) when the cap
186
+ is reached.
187
+
188
+ @param record - Record logged before every sink has verified.
189
189
  */
190
190
  function bufferStartupRecord({ record, }: { readonly record: LogRecord; },): void {
191
191
  if (startupRecords.length >= STARTUP_BUFFER_CAP) {
@@ -196,7 +196,7 @@ export function createLogger(
196
196
  }
197
197
 
198
198
  /**
199
- * Recomputes aggregate availability after a sink entry's flag flips.
199
+ Recomputes aggregate availability after a sink entry's flag flips.
200
200
  */
201
201
  function recomputeAvailability(): void {
202
202
  state.hasAvailableSink = entries.some(function isAvailable(entry,) {
@@ -205,17 +205,17 @@ export function createLogger(
205
205
  }
206
206
 
207
207
  /**
208
- * Reads a sink entry by startup-order index.
209
- *
210
- * @param entryIndex - Sink entry index from the construction-time order.
211
- *
212
- * @returns Sink entry at that index.
213
- *
214
- * @throws Error when index no longer maps to a sink entry.
208
+ Reads a sink entry by startup-order index.
209
+
210
+ @param entryIndex - Sink entry index from the construction-time order.
211
+
212
+ @returns Sink entry at that index.
213
+
214
+ @throws Error when index no longer maps to a sink entry.
215
215
  */
216
216
  function getSinkEntry({ entryIndex, }: { readonly entryIndex: number; },): SinkEntry {
217
217
  /**
218
- * Sink entry read from startup-order storage; undefined means the caller supplied an invalid index.
218
+ Sink entry read from startup-order storage; undefined means the caller supplied an invalid index.
219
219
  */
220
220
  const entry = entries[entryIndex];
221
221
  if (entry === undefined)
@@ -225,15 +225,15 @@ export function createLogger(
225
225
  }
226
226
 
227
227
  /**
228
- * Marks a sink unavailable after its verification fails or throws. Write
229
- * failures never reach here: a rejected write is the sink's own concern and
230
- * leaves the backend available, so one transient hiccup does not retire it.
231
- *
232
- * @param entryIndex - Sink entry index whose backend failed verification.
228
+ Marks a sink unavailable after its verification fails or throws. Write
229
+ failures never reach here: a rejected write is the sink's own concern and
230
+ leaves the backend available, so one transient hiccup does not retire it.
231
+
232
+ @param entryIndex - Sink entry index whose backend failed verification.
233
233
  */
234
234
  function markEntryUnavailable({ entryIndex, }: { readonly entryIndex: number; },): void {
235
235
  /**
236
- * Mutable sink entry being disabled.
236
+ Mutable sink entry being disabled.
237
237
  */
238
238
  const entry = getSinkEntry({ entryIndex, },);
239
239
  entry.available = false;
@@ -241,9 +241,9 @@ export function createLogger(
241
241
  }
242
242
 
243
243
  /**
244
- * Removes a tracked sink write from {@link pendingWrites} once it settles.
245
- *
246
- * @param trackedWrite - Promise returned by {@link trackWrite}.
244
+ Removes a tracked sink write from {@link pendingWrites} once it settles.
245
+
246
+ @param trackedWrite - Promise returned by {@link trackWrite}.
247
247
  */
248
248
  async function removePendingWriteWhenSettled(
249
249
  { trackedWrite, }: { readonly trackedWrite: Promise<void>; },
@@ -253,11 +253,11 @@ export function createLogger(
253
253
  }
254
254
 
255
255
  /**
256
- * Sends a record to one sink, recording the write so `flush()` can await it.
257
- *
258
- * @param entryIndex - Available sink entry index to receive the record.
259
- *
260
- * @param record - Log record to deliver.
256
+ Sends a record to one sink, recording the write so `flush()` can await it.
257
+
258
+ @param entryIndex - Available sink entry index to receive the record.
259
+
260
+ @param record - Log record to deliver.
261
261
  */
262
262
  function writeRecordToEntry(
263
263
  {
@@ -270,11 +270,11 @@ export function createLogger(
270
270
  ): void {
271
271
  try {
272
272
  /**
273
- * Sink entry receiving the record.
273
+ Sink entry receiving the record.
274
274
  */
275
275
  const entry = getSinkEntry({ entryIndex, },);
276
276
  /**
277
- * Monitored sink write; resolves even when the underlying write rejects, because {@link trackWrite} swallows rejection.
277
+ Monitored sink write; resolves even when the underlying write rejects, because {@link trackWrite} swallows rejection.
278
278
  */
279
279
  const trackedWrite = trackWrite({
280
280
  writePromise: entry.sink
@@ -292,9 +292,9 @@ export function createLogger(
292
292
  }
293
293
 
294
294
  /**
295
- * Replays buffered startup records to a sink that just became available.
296
- *
297
- * @param entryIndex - Newly available sink entry index.
295
+ Replays buffered startup records to a sink that just became available.
296
+
297
+ @param entryIndex - Newly available sink entry index.
298
298
  */
299
299
  function replayStartupRecordsToEntry({ entryIndex, }: { readonly entryIndex: number; },): void {
300
300
  startupRecords.forEach(function replayStartupRecord(record,) {
@@ -306,12 +306,12 @@ export function createLogger(
306
306
  }
307
307
 
308
308
  /**
309
- * Applies a verification result to a sink and replays startup records on
310
- * success.
311
- *
312
- * @param entryIndex - Sink entry index whose verification completed.
313
- *
314
- * @param available - Whether the backend verified successfully.
309
+ Applies a verification result to a sink and replays startup records on
310
+ success.
311
+
312
+ @param entryIndex - Sink entry index whose verification completed.
313
+
314
+ @param available - Whether the backend verified successfully.
315
315
  */
316
316
  function setEntryAvailability(
317
317
  {
@@ -323,7 +323,7 @@ export function createLogger(
323
323
  },
324
324
  ): void {
325
325
  /**
326
- * Sink entry whose availability is changing.
326
+ Sink entry whose availability is changing.
327
327
  */
328
328
  const entry = getSinkEntry({ entryIndex, },);
329
329
  entry.available = available;
@@ -333,18 +333,18 @@ export function createLogger(
333
333
  }
334
334
 
335
335
  /**
336
- * Runs one sink's verification under the verify time limit and records the
337
- * result, replaying buffered startup records to it on success. A rejected
338
- * verification, a synchronous throw from the verifier, or a verify that
339
- * runs past `verifyTimeoutMs` drops the sink; a late answer after the limit
340
- * is never observed, so it cannot flip availability afterwards.
341
- *
342
- * @param entryIndex - Sink entry index to verify.
336
+ Runs one sink's verification under the verify time limit and records the
337
+ result, replaying buffered startup records to it on success. A rejected
338
+ verification, a synchronous throw from the verifier, or a verify that
339
+ runs past `verifyTimeoutMs` drops the sink; a late answer after the limit
340
+ is never observed, so it cannot flip availability afterwards.
341
+
342
+ @param entryIndex - Sink entry index to verify.
343
343
  */
344
344
  async function verifyAndApply({ entryIndex, }: { readonly entryIndex: number; },): Promise<void> {
345
345
  try {
346
346
  /**
347
- * Sink entry whose verifier is about to run.
347
+ Sink entry whose verifier is about to run.
348
348
  */
349
349
  const entry = getSinkEntry({ entryIndex, },);
350
350
  setEntryAvailability({
@@ -367,19 +367,19 @@ export function createLogger(
367
367
  }
368
368
 
369
369
  /**
370
- * Writes one synthetic `warn` record to every available sink when the
371
- * startup buffer overflowed, so the loss is never silent. Runs once, after
372
- * initialization, when the dropped count is known and final.
370
+ Writes one synthetic `warn` record to every available sink when the
371
+ startup buffer overflowed, so the loss is never silent. Runs once, after
372
+ initialization, when the dropped count is known and final.
373
373
  */
374
374
  function emitDroppedStartupMarker(): void {
375
375
  /**
376
- * Records dropped from the startup buffer; zero means nothing to report.
376
+ Records dropped from the startup buffer; zero means nothing to report.
377
377
  */
378
378
  const dropped = state.droppedStartupRecords;
379
379
  if (dropped === 0)
380
380
  return;
381
381
  /**
382
- * Marker record naming the loss; the noun agrees with the count.
382
+ Marker record naming the loss; the noun agrees with the count.
383
383
  */
384
384
  const marker: LogRecord = {
385
385
  level: 'warn',
@@ -400,14 +400,14 @@ export function createLogger(
400
400
  }
401
401
 
402
402
  /**
403
- * Initializes all sink backends by verifying their availability. Runs once
404
- * at construction. Every verifier runs concurrently, each under the verify
405
- * time limit, so one backend that never answers cannot starve the rest or
406
- * keep `initialized` from flipping. Completion order does not affect
407
- * correctness: a record's immediate-write set (sinks already available when
408
- * it was logged) and its replay set (sinks that become available later) are
409
- * disjoint, so each available sink receives each record exactly once
410
- * whichever verify settles first.
403
+ Initializes all sink backends by verifying their availability. Runs once
404
+ at construction. Every verifier runs concurrently, each under the verify
405
+ time limit, so one backend that never answers cannot starve the rest or
406
+ keep `initialized` from flipping. Completion order does not affect
407
+ correctness: a record's immediate-write set (sinks already available when
408
+ it was logged) and its replay set (sinks that become available later) are
409
+ disjoint, so each available sink receives each record exactly once
410
+ whichever verify settles first.
411
411
  */
412
412
  async function initialize(): Promise<void> {
413
413
  if (state.initialized)
@@ -428,29 +428,29 @@ export function createLogger(
428
428
  }
429
429
 
430
430
  /**
431
- * Eager readiness promise. Consumers do not need to await this before
432
- * logging; `flush()` awaits it internally, and startup records replay to
433
- * async sinks as they become available.
431
+ Eager readiness promise. Consumers do not need to await this before
432
+ logging; `flush()` awaits it internally, and startup records replay to
433
+ async sinks as they become available.
434
434
  */
435
435
  const initPromise: Promise<void> = initialize();
436
436
 
437
437
  /**
438
- * Drains every currently tracked sink write.
438
+ Drains every currently tracked sink write.
439
439
  */
440
440
  async function drainPendingWrites(): Promise<void> {
441
441
  /**
442
- * Snapshot of tracked writes at flush time.
442
+ Snapshot of tracked writes at flush time.
443
443
  */
444
444
  const writes = [...pendingWrites,];
445
445
  await Promise.all(writes,);
446
446
  }
447
447
 
448
448
  /**
449
- * Creates a logging method for the specified severity level.
450
- *
451
- * @param level - Log severity level for messages from this method.
452
- *
453
- * @returns Logging function for the given level.
449
+ Creates a logging method for the specified severity level.
450
+
451
+ @param level - Log severity level for messages from this method.
452
+
453
+ @returns Logging function for the given level.
454
454
  */
455
455
  function createMethod(level: Level,): (message: string,) => void {
456
456
  return function logAtLevel(message: string,): void {
@@ -459,7 +459,7 @@ export function createLogger(
459
459
  throw new Error('No logging backends available',);
460
460
 
461
461
  /**
462
- * Shared LogRecord forwarded to every available sink; built once per call so all sinks see the same timestamp.
462
+ Shared LogRecord forwarded to every available sink; built once per call so all sinks see the same timestamp.
463
463
  */
464
464
  const record: LogRecord = {
465
465
  level,
@@ -471,7 +471,7 @@ export function createLogger(
471
471
  bufferStartupRecord({ record, },);
472
472
 
473
473
  /**
474
- * Indices of sinks that survived verification; recomputed per call so a sink dropped at verify time is excluded next time.
474
+ Indices of sinks that survived verification; recomputed per call so a sink dropped at verify time is excluded next time.
475
475
  */
476
476
  const availableIndices = entries
477
477
  .map(function indexEntry(
@@ -495,8 +495,8 @@ export function createLogger(
495
495
  }
496
496
 
497
497
  /**
498
- * Runs every available sink's own `flush` hook. A rejecting hook marks that
499
- * sink unavailable and does not fail the aggregate.
498
+ Runs every available sink's own `flush` hook. A rejecting hook marks that
499
+ sink unavailable and does not fail the aggregate.
500
500
  */
501
501
  async function runSinkFlushHooks(): Promise<void> {
502
502
  await Promise.all(
@@ -505,7 +505,7 @@ export function createLogger(
505
505
  entryIndex,
506
506
  ) {
507
507
  /**
508
- * Optional sink-supplied flush hook; absent when the sink writes synchronously and needs no draining.
508
+ Optional sink-supplied flush hook; absent when the sink writes synchronously and needs no draining.
509
509
  */
510
510
  const sinkFlush = entry.sink
511
511
  .flush;
@@ -526,11 +526,11 @@ export function createLogger(
526
526
  }
527
527
 
528
528
  /**
529
- * Drains startup verification, in-flight sink writes (via
530
- * {@link drainPendingWrites}), and every sink flush hook (via
531
- * {@link runSinkFlushHooks}) in order. Never rejects on its own: every
532
- * inner failure is already reported and swallowed, so the only way this
533
- * stays pending is a verify, write, or hook that never settles.
529
+ Drains startup verification, in-flight sink writes (via
530
+ {@link drainPendingWrites}), and every sink flush hook (via
531
+ {@link runSinkFlushHooks}) in order. Never rejects on its own: every
532
+ inner failure is already reported and swallowed, so the only way this
533
+ stays pending is a verify, write, or hook that never settles.
534
534
  */
535
535
  async function drainEverything(): Promise<void> {
536
536
  await initPromise;
@@ -539,21 +539,21 @@ export function createLogger(
539
539
  }
540
540
 
541
541
  /**
542
- * Drops every tracked write from the logger's view after the flush deadline
543
- * elapsed. The tracked wrappers keep their own rejection handling, so a
544
- * late settlement can neither surface as an unhandled rejection nor stall
545
- * the next `flush()`. The underlying sink work is not cancelled: sinks
546
- * expose no cancellation signal.
542
+ Drops every tracked write from the logger's view after the flush deadline
543
+ elapsed. The tracked wrappers keep their own rejection handling, so a
544
+ late settlement can neither surface as an unhandled rejection nor stall
545
+ the next `flush()`. The underlying sink work is not cancelled: sinks
546
+ expose no cancellation signal.
547
547
  */
548
548
  function abandonPendingWrites(): void {
549
549
  pendingWrites.clear();
550
550
  }
551
551
 
552
552
  /**
553
- * Runs {@link drainEverything} under the flush deadline. Resolves once all
554
- * tracked writes and hooks have settled, or once `flushDeadlineMs` elapses,
555
- * whichever comes first; a deadline hit reports one breadcrumb and abandons
556
- * the tracked writes so shutdown proceeds.
553
+ Runs {@link drainEverything} under the flush deadline. Resolves once all
554
+ tracked writes and hooks have settled, or once `flushDeadlineMs` elapses,
555
+ whichever comes first; a deadline hit reports one breadcrumb and abandons
556
+ the tracked writes so shutdown proceeds.
557
557
  */
558
558
  async function flushAll(): Promise<void> {
559
559
  try {
@@ -573,7 +573,7 @@ export function createLogger(
573
573
  }
574
574
 
575
575
  /**
576
- * Multi-sink logger that writes to all available backends.
576
+ Multi-sink logger that writes to all available backends.
577
577
  */
578
578
  const logger: Logger = {
579
579
  debug: createMethod('debug',),