@monochromatic-dev/module-logger 0.1.0 → 0.3.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 (63) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +58 -12
  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 +366 -572
  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 +366 -572
  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 -5
  16. package/src/artifact-platform-split.unit.test.ts +140 -0
  17. package/src/browser.ts +14 -0
  18. package/src/create-logger.ts +249 -151
  19. package/src/create-logger.unit.test.ts +527 -75
  20. package/src/default-sinks.neutral.ts +34 -0
  21. package/src/default-sinks.node.ts +32 -0
  22. package/src/error-format.ts +23 -23
  23. package/src/index.ts +2 -0
  24. package/src/logger.ts +23 -50
  25. package/src/node.ts +23 -0
  26. package/src/sink/console-control-chars.ts +64 -64
  27. package/src/sink/console-control-chars.unit.test.ts +14 -14
  28. package/src/sink/console.ts +194 -194
  29. package/src/sink/console.unit.test.ts +18 -18
  30. package/src/sink/file.ts +136 -140
  31. package/src/sink/file.unit.test.ts +19 -26
  32. package/src/sink/index.ts +4 -7
  33. package/src/sink/indexed-db-util.ts +42 -42
  34. package/src/sink/indexed-db.browser.test.ts +7 -7
  35. package/src/sink/indexed-db.ts +109 -109
  36. package/src/sink/indexed-db.unit.test.ts +5 -13
  37. package/src/sink/local-storage-key.ts +73 -73
  38. package/src/sink/local-storage-key.unit.test.ts +8 -8
  39. package/src/sink/local-storage-quota.ts +37 -37
  40. package/src/sink/local-storage-quota.unit.test.ts +8 -8
  41. package/src/sink/local-storage-store.ts +113 -113
  42. package/src/sink/local-storage-store.unit.test.ts +35 -35
  43. package/src/sink/local-storage.ts +72 -72
  44. package/src/sink/local-storage.unit.test.ts +27 -27
  45. package/src/sink/noop.ts +20 -20
  46. package/src/sink/noop.unit.test.ts +1 -1
  47. package/src/sink/opfs.browser.test.ts +7 -7
  48. package/src/sink/opfs.ts +62 -62
  49. package/src/sink/opfs.unit.test.ts +5 -13
  50. package/src/sink/record-buffer.ts +84 -84
  51. package/src/sink/record-buffer.unit.test.ts +20 -20
  52. package/src/sink/session-storage-quota.ts +34 -34
  53. package/src/sink/session-storage-quota.unit.test.ts +8 -8
  54. package/src/sink/session-storage-store.ts +72 -72
  55. package/src/sink/session-storage.ts +48 -48
  56. package/src/sink/session-storage.unit.test.ts +39 -39
  57. package/src/sink/web-storage-quota-error.ts +22 -22
  58. package/src/sink/web-storage-quota-error.unit.test.ts +2 -2
  59. package/src/sink/web-storage-runtime.ts +24 -24
  60. package/src/startup.unit.test.ts +18 -18
  61. package/src/tagged.ts +35 -35
  62. package/src/tagged.unit.test.ts +8 -8
  63. package/src/types.ts +39 -39
@@ -8,20 +8,20 @@ import type {
8
8
  } from '../types.ts';
9
9
 
10
10
  /**
11
- * Sentinel for an uncomputed `verboseCache` slot. A unique `Symbol` rather
12
- * than `null`: the `no-nullish-union` rule bans a nullish "absent" arm, and
13
- * a real `boolean` value is the computed state this must stay distinct from.
11
+ Sentinel for an uncomputed `verboseCache` slot. A unique `Symbol` rather
12
+ than `null`: the `no-nullish-union` rule bans a nullish "absent" arm, and
13
+ a real `boolean` value is the computed state this must stay distinct from.
14
14
  */
15
15
  const VERBOSE_UNCOMPUTED = Symbol('logger:verbose-detection-uncomputed',);
16
16
 
17
17
  /**
18
- * Levels silenced by default unless verbose mode is active.
19
- *
20
- * @example
21
- * ```ts
22
- * SILENT_LEVELS.has('trace'); // true
23
- * SILENT_LEVELS.has('info'); // false
24
- * ```
18
+ Levels silenced by default unless verbose mode is active.
19
+
20
+ @example
21
+ ```ts
22
+ SILENT_LEVELS.has('trace'); // true
23
+ SILENT_LEVELS.has('info'); // false
24
+ ```
25
25
  */
26
26
  const SILENT_LEVELS: ReadonlySet<string> = new Set([
27
27
  'debug',
@@ -29,28 +29,28 @@ const SILENT_LEVELS: ReadonlySet<string> = new Set([
29
29
  ],);
30
30
 
31
31
  /**
32
- * Detects verbose mode from environment variables, process arguments,
33
- * and runtime environment.
34
- * Checks `process.env.MONOCHROMATIC_VERBOSE`, `process.argv` for `--verbose`,
35
- * and whether the runtime is a browser.
36
- * Browser environments enable verbose by default because DevTools
37
- * already provides its own log-level filtering, making logger-side
38
- * suppression redundant. Each check is individually guarded
39
- * so unavailable globals never cause throws.
40
- *
41
- * @returns Whether verbose output is enabled.
42
- *
43
- * @example
44
- * ```ts
45
- * // With MONOCHROMATIC_VERBOSE=true in environment
46
- * detectVerbose(); // true
47
- * ```
48
- *
49
- * @example
50
- * ```ts
51
- * // In a browser environment (window is defined)
52
- * detectVerbose(); // true
53
- * ```
32
+ Detects verbose mode from environment variables, process arguments,
33
+ and runtime environment.
34
+ Checks `process.env.MONOCHROMATIC_VERBOSE`, `process.argv` for `--verbose`,
35
+ and whether the runtime is a browser.
36
+ Browser environments enable verbose by default because DevTools
37
+ already provides its own log-level filtering, making logger-side
38
+ suppression redundant. Each check is individually guarded
39
+ so unavailable globals never cause throws.
40
+
41
+ @returns Whether verbose output is enabled.
42
+
43
+ @example
44
+ ```ts
45
+ // With MONOCHROMATIC_VERBOSE=true in environment
46
+ detectVerbose(); // true
47
+ ```
48
+
49
+ @example
50
+ ```ts
51
+ // In a browser environment (window is defined)
52
+ detectVerbose(); // true
53
+ ```
54
54
  */
55
55
  function detectVerbose(): boolean {
56
56
  try {
@@ -101,22 +101,22 @@ function detectVerbose(): boolean {
101
101
  }
102
102
 
103
103
  /**
104
- * Detects explicit warn suppression via the `MONOCHROMATIC_WARN` environment
105
- * variable.
106
- *
107
- * Setting `MONOCHROMATIC_WARN=false` drops `warn`-level records, for machine-protocol
108
- * consumers (such as a stdin/stdout codec) whose output streams must stay clean
109
- * on success. Only the exact string `'false'` suppresses; any other value, or an
110
- * absent variable, leaves `warn` enabled. Read on each call (not memoized) so a
111
- * host can toggle it between logs.
112
- *
113
- * @returns Whether `warn`-level records are suppressed.
114
- *
115
- * @example
116
- * ```ts
117
- * // With MONOCHROMATIC_WARN=false in environment
118
- * isWarnSuppressed(); // true
119
- * ```
104
+ Detects explicit warn suppression via the `MONOCHROMATIC_WARN` environment
105
+ variable.
106
+
107
+ Setting `MONOCHROMATIC_WARN=false` drops `warn`-level records, for machine-protocol
108
+ consumers (such as a stdin/stdout codec) whose output streams must stay clean
109
+ on success. Only the exact string `'false'` suppresses; any other value, or an
110
+ absent variable, leaves `warn` enabled. Read on each call (not memoized) so a
111
+ host can toggle it between logs.
112
+
113
+ @returns Whether `warn`-level records are suppressed.
114
+
115
+ @example
116
+ ```ts
117
+ // With MONOCHROMATIC_WARN=false in environment
118
+ isWarnSuppressed(); // true
119
+ ```
120
120
  */
121
121
  function isWarnSuppressed(): boolean {
122
122
  try {
@@ -134,11 +134,11 @@ function isWarnSuppressed(): boolean {
134
134
  }
135
135
 
136
136
  /**
137
- * Maps log levels to the name of the console method that handles them.
138
- * Names rather than function references so tests (and other hot patches)
139
- * that replace `console.info` etc. after module load still see their
140
- * replacement when the sink flushes. `debug` uses this mapping only when
141
- * process stderr is unavailable, preserving browser `console.debug` output.
137
+ Maps log levels to the name of the console method that handles them.
138
+ Names rather than function references so tests (and other hot patches)
139
+ that replace `console.info` etc. after module load still see their
140
+ replacement when the sink flushes. `debug` uses this mapping only when
141
+ process stderr is unavailable, preserving browser `console.debug` output.
142
142
  */
143
143
  const LEVEL_TO_CONSOLE_METHOD: Record<Level,
144
144
  'debug' | 'error' | 'info' | 'trace' | 'warn'> = {
@@ -151,19 +151,19 @@ const LEVEL_TO_CONSOLE_METHOD: Record<Level,
151
151
  };
152
152
 
153
153
  /**
154
- * Formats a single log record into the display string used by console output.
155
- * The message passes through {@link neutralizeControlCharacters} first, so a
156
- * terminal never receives a control sequence smuggled inside log text.
157
- *
158
- * @param record - Record to format.
159
- *
160
- * @returns Formatted line of the shape `[level] [iso] message`.
161
- *
162
- * @example
163
- * ```ts
164
- * formatRecord({ level: 'info', message: 'hi', timestamp: 0 });
165
- * // => '[info] [1970-01-01T00:00:00.000Z] hi'
166
- * ```
154
+ Formats a single log record into the display string used by console output.
155
+ The message passes through {@link neutralizeControlCharacters} first, so a
156
+ terminal never receives a control sequence smuggled inside log text.
157
+
158
+ @param record - Record to format.
159
+
160
+ @returns Formatted line of the shape `[level] [iso] message`.
161
+
162
+ @example
163
+ ```ts
164
+ formatRecord({ level: 'info', message: 'hi', timestamp: 0 });
165
+ // => '[info] [1970-01-01T00:00:00.000Z] hi'
166
+ ```
167
167
  */
168
168
  function formatRecord(record: LogRecord,): string {
169
169
  return `[${record.level}] [${
@@ -173,17 +173,17 @@ function formatRecord(record: LogRecord,): string {
173
173
  }
174
174
 
175
175
  /**
176
- * Detects whether process stderr can receive debug records directly. Kept
177
- * separate from writing so availability checks can still require
178
- * `console.debug` when stderr is unavailable and browser fallback is needed.
179
- *
180
- * @returns Whether process stderr exposes a callable `write` method.
181
- *
182
- * @example
183
- * ```ts
184
- * hasProcessStderr();
185
- * // => true in Node.js and Bun processes
186
- * ```
176
+ Detects whether process stderr can receive debug records directly. Kept
177
+ separate from writing so availability checks can still require
178
+ `console.debug` when stderr is unavailable and browser fallback is needed.
179
+
180
+ @returns Whether process stderr exposes a callable `write` method.
181
+
182
+ @example
183
+ ```ts
184
+ hasProcessStderr();
185
+ // => true in Node.js and Bun processes
186
+ ```
187
187
  */
188
188
  function hasProcessStderr(): boolean {
189
189
  try {
@@ -204,19 +204,19 @@ function hasProcessStderr(): boolean {
204
204
  }
205
205
 
206
206
  /**
207
- * Writes a formatted debug run to process stderr when the host exposes a
208
- * process stream. Falling back to `console.debug` keeps browser and restricted
209
- * runtimes working when `process` is absent or unusable.
210
- *
211
- * @param text - Formatted debug run text that should stay off stdout.
212
- *
213
- * @returns Whether process stderr accepted the debug run.
214
- *
215
- * @example
216
- * ```ts
217
- * writeDebugRunToProcessStderr('[debug] [1970-01-01T00:00:00.000Z] hi');
218
- * // => true when process.stderr.write is available
219
- * ```
207
+ Writes a formatted debug run to process stderr when the host exposes a
208
+ process stream. Falling back to `console.debug` keeps browser and restricted
209
+ runtimes working when `process` is absent or unusable.
210
+
211
+ @param text - Formatted debug run text that should stay off stdout.
212
+
213
+ @returns Whether process stderr accepted the debug run.
214
+
215
+ @example
216
+ ```ts
217
+ writeDebugRunToProcessStderr('[debug] [1970-01-01T00:00:00.000Z] hi');
218
+ // => true when process.stderr.write is available
219
+ ```
220
220
  */
221
221
  function writeDebugRunToProcessStderr(text: string,): boolean {
222
222
  try {
@@ -237,20 +237,20 @@ function writeDebugRunToProcessStderr(text: string,): boolean {
237
237
  }
238
238
 
239
239
  /**
240
- * Emits a contiguous run of same-level records as a single console call,
241
- * joining formatted lines with `\n`. Debug records write to process stderr
242
- * when `process.stderr.write` is available, keeping stdout clean in CLI hosts.
243
- *
244
- * @param records - Records that all share `level`.
245
- *
246
- * @param level - Shared severity level whose mapped `console.*` receives
247
- * the joined text.
248
- *
249
- * @example
250
- * ```ts
251
- * emitRun({ records: [{ level: 'info', message: 'a', timestamp: 0 }], level: 'info' });
252
- * // calls console.info('[info] [1970-01-01T00:00:00.000Z] a')
253
- * ```
240
+ Emits a contiguous run of same-level records as a single console call,
241
+ joining formatted lines with `\n`. Debug records write to process stderr
242
+ when `process.stderr.write` is available, keeping stdout clean in CLI hosts.
243
+
244
+ @param records - Records that all share `level`.
245
+
246
+ @param level - Shared severity level whose mapped `console.*` receives
247
+ the joined text.
248
+
249
+ @example
250
+ ```ts
251
+ emitRun({ records: [{ level: 'info', message: 'a', timestamp: 0 }], level: 'info' });
252
+ // calls console.info('[info] [1970-01-01T00:00:00.000Z] a')
253
+ ```
254
254
  */
255
255
  function emitRun(
256
256
  {
@@ -262,7 +262,7 @@ function emitRun(
262
262
  },
263
263
  ): void {
264
264
  /**
265
- * Joined run text; one `\n`-separated string per console call so a long run becomes a single grouped entry rather than N separate ones.
265
+ Joined run text; one `\n`-separated string per console call so a long run becomes a single grouped entry rather than N separate ones.
266
266
  */
267
267
  const text = records
268
268
  .map(function formatOne(r,) {
@@ -273,11 +273,11 @@ function emitRun(
273
273
  return;
274
274
  try {
275
275
  /**
276
- * Name (not the function reference) of the matching `console.*` method; resolved lazily so post-import hot patches still apply.
276
+ Name (not the function reference) of the matching `console.*` method; resolved lazily so post-import hot patches still apply.
277
277
  */
278
278
  const method = LEVEL_TO_CONSOLE_METHOD[level];
279
279
  /**
280
- * Resolved console method looked up by name; may be missing or non-callable in stripped runtimes, which the guard handles.
280
+ Resolved console method looked up by name; may be missing or non-callable in stripped runtimes, which the guard handles.
281
281
  */
282
282
  const consoleFn = console[method];
283
283
  if ((typeof consoleFn) === 'function') {
@@ -296,9 +296,9 @@ function emitRun(
296
296
  }
297
297
 
298
298
  /**
299
- * A contiguous slice of buffered records that share one level. Built by
300
- * {@link groupRuns} and consumed by {@link flushBuffer} to emit one
301
- * `console.*` call per slice.
299
+ A contiguous slice of buffered records that share one level. Built by
300
+ {@link groupRuns} and consumed by {@link flushBuffer} to emit one
301
+ `console.*` call per slice.
302
302
  */
303
303
  type Run = {
304
304
  level: Level;
@@ -306,24 +306,24 @@ type Run = {
306
306
  };
307
307
 
308
308
  /**
309
- * Groups a record sequence into contiguous same-level runs. Each input
310
- * record is appended to the trailing run when its level matches, otherwise
311
- * a new run is opened. A reduce-based collapse keeps the cursor (run head
312
- * and span) out of mutable function-body locals.
313
- *
314
- * @param records - Buffered records in arrival order.
315
- *
316
- * @returns Ordered list of runs covering every input record exactly once.
317
- *
318
- * @example
319
- * ```ts
320
- * groupRuns([
321
- * { level: 'debug', message: 'a', timestamp: 0 },
322
- * { level: 'debug', message: 'b', timestamp: 0 },
323
- * { level: 'warn', message: 'c', timestamp: 0 },
324
- * ]);
325
- * // => [{ level: 'debug', records: [a, b] }, { level: 'warn', records: [c] }]
326
- * ```
309
+ Groups a record sequence into contiguous same-level runs. Each input
310
+ record is appended to the trailing run when its level matches, otherwise
311
+ a new run is opened. A reduce-based collapse keeps the cursor (run head
312
+ and span) out of mutable function-body locals.
313
+
314
+ @param records - Buffered records in arrival order.
315
+
316
+ @returns Ordered list of runs covering every input record exactly once.
317
+
318
+ @example
319
+ ```ts
320
+ groupRuns([
321
+ { level: 'debug', message: 'a', timestamp: 0 },
322
+ { level: 'debug', message: 'b', timestamp: 0 },
323
+ { level: 'warn', message: 'c', timestamp: 0 },
324
+ ]);
325
+ // => [{ level: 'debug', records: [a, b] }, { level: 'warn', records: [c] }]
326
+ ```
327
327
  */
328
328
  function groupRuns(records: readonly LogRecord[],): Run[] {
329
329
  return records.reduce<Run[]>(
@@ -332,7 +332,7 @@ function groupRuns(records: readonly LogRecord[],): Run[] {
332
332
  record,
333
333
  ) {
334
334
  /**
335
- * Trailing run being extended; new same-level records append onto it, otherwise a fresh run is opened.
335
+ Trailing run being extended; new same-level records append onto it, otherwise a fresh run is opened.
336
336
  */
337
337
  const tail = runs.at(-1,);
338
338
  if ((tail !== undefined) && (tail.level
@@ -353,21 +353,21 @@ function groupRuns(records: readonly LogRecord[],): Run[] {
353
353
  }
354
354
 
355
355
  /**
356
- * Verifies console is available and microtask scheduling is supported.
357
- * `queueMicrotask` is the batching primitive; without it there is no
358
- * ordering guarantee that preserves "end of current sync frame" semantics,
359
- * so the sink reports itself unavailable instead of falling back to an
360
- * inferior scheduler. Stateless: the logger calls this once and owns the
361
- * resulting availability.
362
- *
363
- * @returns Whether console logging is available.
364
- *
365
- * @example
366
- * ```ts
367
- * if (await verifyConsole()) {
368
- * // console usable
369
- * }
370
- * ```
356
+ Verifies console is available and microtask scheduling is supported.
357
+ `queueMicrotask` is the batching primitive; without it there is no
358
+ ordering guarantee that preserves "end of current sync frame" semantics,
359
+ so the sink reports itself unavailable instead of falling back to an
360
+ inferior scheduler. Stateless: the logger calls this once and owns the
361
+ resulting availability.
362
+
363
+ @returns Whether console logging is available.
364
+
365
+ @example
366
+ ```ts
367
+ if (await verifyConsole()) {
368
+ // console usable
369
+ }
370
+ ```
371
371
  */
372
372
  function verifyConsole(): Promise<boolean> {
373
373
  try {
@@ -375,8 +375,8 @@ function verifyConsole(): Promise<boolean> {
375
375
  return Promise.resolve(false,);
376
376
 
377
377
  /**
378
- * Sample console method used only to check that debug has an output path:
379
- * process runtimes use stderr, while fallback runtimes need `console.debug`.
378
+ Sample console method used only to check that debug has an output path:
379
+ process runtimes use stderr, while fallback runtimes need `console.debug`.
380
380
  */
381
381
  const testFn = hasProcessStderr() ? console.info : console.debug;
382
382
  if ((typeof testFn) !== 'function')
@@ -397,29 +397,29 @@ function verifyConsole(): Promise<boolean> {
397
397
  }
398
398
 
399
399
  /**
400
- * Builds a microtask-batched console sink. The pending buffer, schedule flag,
401
- * and memoized verbose detection live in this instance's closure (no
402
- * module-global state), so independent loggers and tests stay isolated with
403
- * no reset hook. Collapses contiguous same-level runs into single `console.*`
404
- * calls, sharply reducing console-panel overhead when an instrumented path
405
- * emits many records per sync frame.
406
- *
407
- * @returns Sink that writes formatted lines to `console.*`, except
408
- * process-hosted debug records write to stderr.
409
- *
410
- * @example
411
- * ```ts
412
- * const { logger } = createLogger({ sinks: [createConsoleSink()] });
413
- * logger.info('server started');
414
- * ```
400
+ Builds a microtask-batched console sink. The pending buffer, schedule flag,
401
+ and memoized verbose detection live in this instance's closure (no
402
+ module-global state), so independent loggers and tests stay isolated with
403
+ no reset hook. Collapses contiguous same-level runs into single `console.*`
404
+ calls, sharply reducing console-panel overhead when an instrumented path
405
+ emits many records per sync frame.
406
+
407
+ @returns Sink that writes formatted lines to `console.*`, except
408
+ process-hosted debug records write to stderr.
409
+
410
+ @example
411
+ ```ts
412
+ const { logger } = createLogger({ sinks: [createConsoleSink()] });
413
+ logger.info('server started');
414
+ ```
415
415
  */
416
416
  export function createConsoleSink(): Sink {
417
417
  /**
418
- * Instance-local console-sink state. `buffer` holds records awaiting the
419
- * next microtask flush; `scheduled` guards against redundant
420
- * `queueMicrotask` calls within one sync frame; `verboseCache` memoizes
421
- * verbose detection (the sentinel means not yet computed) so a host can
422
- * mutate `process.env.MONOCHROMATIC_VERBOSE` before the first log and still be seen.
418
+ Instance-local console-sink state. `buffer` holds records awaiting the
419
+ next microtask flush; `scheduled` guards against redundant
420
+ `queueMicrotask` calls within one sync frame; `verboseCache` memoizes
421
+ verbose detection (the sentinel means not yet computed) so a host can
422
+ mutate `process.env.MONOCHROMATIC_VERBOSE` before the first log and still be seen.
423
423
  */
424
424
  const state: {
425
425
  buffer: LogRecord[];
@@ -432,22 +432,22 @@ export function createConsoleSink(): Sink {
432
432
  };
433
433
 
434
434
  /**
435
- * Reads the memoized verbose flag, evaluating via {@link detectVerbose} on
436
- * first call. Lazy rather than at construction so tests (and hosts) can
437
- * mutate `process.env.MONOCHROMATIC_VERBOSE` between construction and first log without a
438
- * stale cache.
439
- *
440
- * @returns Whether verbose logging is enabled for this process.
435
+ Reads the memoized verbose flag, evaluating via {@link detectVerbose} on
436
+ first call. Lazy rather than at construction so tests (and hosts) can
437
+ mutate `process.env.MONOCHROMATIC_VERBOSE` between construction and first log without a
438
+ stale cache.
439
+
440
+ @returns Whether verbose logging is enabled for this process.
441
441
  */
442
442
  function getVerbose(): boolean {
443
443
  /**
444
- * Cached verbose flag; the sentinel means detection has not run yet.
444
+ Cached verbose flag; the sentinel means detection has not run yet.
445
445
  */
446
446
  const cached = state.verboseCache;
447
447
  if (cached !== VERBOSE_UNCOMPUTED)
448
448
  return cached;
449
449
  /**
450
- * Computed verbose flag, stored so subsequent reads skip detection.
450
+ Computed verbose flag, stored so subsequent reads skip detection.
451
451
  */
452
452
  const computed = detectVerbose();
453
453
  state.verboseCache = computed;
@@ -455,13 +455,13 @@ export function createConsoleSink(): Sink {
455
455
  }
456
456
 
457
457
  /**
458
- * Drains the buffer, collapsing contiguous same-level runs (via
459
- * {@link groupRuns}) into single console calls emitted by {@link emitRun}.
460
- * A sequence `[debug, debug, warn, debug]` becomes three calls:
461
- * `process.stderr.write` (two lines joined), `console.warn`, then
462
- * `process.stderr.write` under process runtimes. Typical instrumented
463
- * functions use a single level throughout, so most flushes collapse to one
464
- * call.
458
+ Drains the buffer, collapsing contiguous same-level runs (via
459
+ {@link groupRuns}) into single console calls emitted by {@link emitRun}.
460
+ A sequence `[debug, debug, warn, debug]` becomes three calls:
461
+ `process.stderr.write` (two lines joined), `console.warn`, then
462
+ `process.stderr.write` under process runtimes. Typical instrumented
463
+ functions use a single level throughout, so most flushes collapse to one
464
+ call.
465
465
  */
466
466
  function flushBuffer(): void {
467
467
  state.scheduled = false;
@@ -471,10 +471,10 @@ export function createConsoleSink(): Sink {
471
471
  return;
472
472
 
473
473
  /**
474
- * Snapshot of buffered records drained before the loop.
475
- *
476
- * Using `splice(0)` empties the buffer atomically so any record enqueued
477
- * during emission lands in the next flush rather than this one.
474
+ Snapshot of buffered records drained before the loop.
475
+
476
+ Using `splice(0)` empties the buffer atomically so any record enqueued
477
+ during emission lands in the next flush rather than this one.
478
478
  */
479
479
  const records = state.buffer
480
480
  .splice(0,);
@@ -487,12 +487,12 @@ export function createConsoleSink(): Sink {
487
487
  }
488
488
 
489
489
  /**
490
- * Enqueues a record for microtask-batched emission. Silently discards
491
- * `debug`/`trace` unless {@link getVerbose} reports verbose mode is active
492
- * (via `MONOCHROMATIC_VERBOSE=true` env var, `--verbose` argv, or browser environment), and
493
- * drops `warn` when {@link isWarnSuppressed}.
494
- *
495
- * @param record - Log record to write.
490
+ Enqueues a record for microtask-batched emission. Silently discards
491
+ `debug`/`trace` unless {@link getVerbose} reports verbose mode is active
492
+ (via `MONOCHROMATIC_VERBOSE=true` env var, `--verbose` argv, or browser environment), and
493
+ drops `warn` when {@link isWarnSuppressed}.
494
+
495
+ @param record - Log record to write.
496
496
  */
497
497
  function write(record: LogRecord,): Promise<void> {
498
498
  if ((!getVerbose()) && SILENT_LEVELS
@@ -514,9 +514,9 @@ export function createConsoleSink(): Sink {
514
514
  }
515
515
 
516
516
  /**
517
- * Forces any buffered records through to the console immediately via
518
- * {@link flushBuffer}. Returns an already-resolved promise so call sites
519
- * await uniformly with async sinks. Safe to call when the buffer is empty.
517
+ Forces any buffered records through to the console immediately via
518
+ {@link flushBuffer}. Returns an already-resolved promise so call sites
519
+ await uniformly with async sinks. Safe to call when the buffer is empty.
520
520
  */
521
521
  function flush(): Promise<void> {
522
522
  flushBuffer();
@@ -9,17 +9,17 @@ import {
9
9
  } from '@monochromatic-dev/module-logger';
10
10
 
11
11
  /**
12
- * Sink factories under test, read from the built artifact's `sinks` namespace.
12
+ Sink factories under test, read from the built artifact's `sinks` namespace.
13
13
  */
14
14
  const {
15
15
  createConsoleSink,
16
16
  } = sinks;
17
17
 
18
18
  /**
19
- * Awaits two microtask hops so any pending `queueMicrotask(flushBuffer)`
20
- * has definitely fired and the buffer is drained before the next assertion.
21
- * One hop would often be enough, but two is cheap insurance against timing
22
- * skew from the harness itself.
19
+ Awaits two microtask hops so any pending `queueMicrotask(flushBuffer)`
20
+ has definitely fired and the buffer is drained before the next assertion.
21
+ One hop would often be enough, but two is cheap insurance against timing
22
+ skew from the harness itself.
23
23
  */
24
24
  async function waitForFlush(): Promise<void> {
25
25
  await Promise.resolve();
@@ -27,14 +27,14 @@ async function waitForFlush(): Promise<void> {
27
27
  }
28
28
 
29
29
  /**
30
- * Builds a `LogRecord` with a fixed timestamp so the formatted output
31
- * is stable across test runs.
32
- *
33
- * @param level - Severity level.
34
- *
35
- * @param message - Message body.
36
- *
37
- * @returns A complete `LogRecord`.
30
+ Builds a `LogRecord` with a fixed timestamp so the formatted output
31
+ is stable across test runs.
32
+
33
+ @param level - Severity level.
34
+
35
+ @param message - Message body.
36
+
37
+ @returns A complete `LogRecord`.
38
38
  */
39
39
  function record(
40
40
  {
@@ -53,11 +53,11 @@ function record(
53
53
  }
54
54
 
55
55
  /**
56
- * Appends `--verbose` to `process.argv` and removes it again when the returned
57
- * value goes out of `using` scope, so a verbose-detection test cannot leak the
58
- * flag into the sibling test that asserts the silenced default.
59
- *
60
- * @returns Disposable that restores `process.argv` on scope exit.
56
+ Appends `--verbose` to `process.argv` and removes it again when the returned
57
+ value goes out of `using` scope, so a verbose-detection test cannot leak the
58
+ flag into the sibling test that asserts the silenced default.
59
+
60
+ @returns Disposable that restores `process.argv` on scope exit.
61
61
  */
62
62
  function withVerboseArgv(): Disposable {
63
63
  process.argv