@monochromatic-dev/module-logger 0.2.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 (62) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +33 -8
  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 +360 -594
  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 +360 -594
  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 +18 -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 +34 -0
  21. package/src/default-sinks.node.ts +32 -0
  22. package/src/error-format.ts +23 -23
  23. package/src/logger.ts +23 -50
  24. package/src/node.ts +23 -0
  25. package/src/sink/console-control-chars.ts +64 -64
  26. package/src/sink/console-control-chars.unit.test.ts +14 -14
  27. package/src/sink/console.ts +194 -194
  28. package/src/sink/console.unit.test.ts +18 -18
  29. package/src/sink/file.ts +136 -140
  30. package/src/sink/file.unit.test.ts +19 -26
  31. package/src/sink/index.ts +4 -7
  32. package/src/sink/indexed-db-util.ts +42 -42
  33. package/src/sink/indexed-db.browser.test.ts +7 -7
  34. package/src/sink/indexed-db.ts +109 -109
  35. package/src/sink/indexed-db.unit.test.ts +5 -13
  36. package/src/sink/local-storage-key.ts +73 -73
  37. package/src/sink/local-storage-key.unit.test.ts +8 -8
  38. package/src/sink/local-storage-quota.ts +37 -37
  39. package/src/sink/local-storage-quota.unit.test.ts +8 -8
  40. package/src/sink/local-storage-store.ts +113 -113
  41. package/src/sink/local-storage-store.unit.test.ts +35 -35
  42. package/src/sink/local-storage.ts +72 -72
  43. package/src/sink/local-storage.unit.test.ts +27 -27
  44. package/src/sink/noop.ts +20 -20
  45. package/src/sink/noop.unit.test.ts +1 -1
  46. package/src/sink/opfs.browser.test.ts +7 -7
  47. package/src/sink/opfs.ts +62 -62
  48. package/src/sink/opfs.unit.test.ts +5 -13
  49. package/src/sink/record-buffer.ts +84 -84
  50. package/src/sink/record-buffer.unit.test.ts +20 -20
  51. package/src/sink/session-storage-quota.ts +34 -34
  52. package/src/sink/session-storage-quota.unit.test.ts +8 -8
  53. package/src/sink/session-storage-store.ts +72 -72
  54. package/src/sink/session-storage.ts +48 -48
  55. package/src/sink/session-storage.unit.test.ts +39 -39
  56. package/src/sink/web-storage-quota-error.ts +22 -22
  57. package/src/sink/web-storage-quota-error.unit.test.ts +2 -2
  58. package/src/sink/web-storage-runtime.ts +24 -24
  59. package/src/startup.unit.test.ts +18 -18
  60. package/src/tagged.ts +35 -35
  61. package/src/tagged.unit.test.ts +8 -8
  62. package/src/types.ts +39 -39
@@ -1,161 +1,85 @@
1
- import { stat as stat$1 } from "node:fs/promises";
2
- import { dirname as dirname$1, join as join$1 } from "node:path";
3
- //#region src/types.d.ts
4
- /**
5
- * Log severity levels ordered from least to most severe.
6
- */
7
- type Level = "debug" | "error" | "fatal" | "info" | "trace" | "warn";
8
- /**
9
- * Structured log record written to sinks.
10
- */
11
- type LogRecord = {
12
- readonly level: Level;
13
- readonly message: string;
14
- readonly timestamp: number;
15
- };
16
- /**
17
- * Optional drain hook for sinks that buffer records internally.
18
- * Called via logger-level {@link Logger.flush} to force buffered work
19
- * through before a process exit, critical error boundary, or assertion.
20
- *
21
- * Always async: sinks whose drain is synchronous return an
22
- * already-resolved promise so callers `await` uniformly. A `void` arm is
23
- * not used; under the `no-optional-escape` rule `T | void` is a banned
24
- * fake-optional encoding, and there is no real synchronous value to carry.
25
- */
26
- type SinkFlush = () => Promise<void>;
27
- /**
28
- * Verification function that checks if a sink backend is available.
29
- * May run setup side effects (resolving a log path, opening a writable
30
- * stream) and reports whether the backend is usable. A sink whose
31
- * verification resolves `false` (or rejects) is dropped by the logger and
32
- * receives no further records.
33
- *
34
- * Always async, matching `write` and `flush`: a synchronous check returns an
35
- * already-resolved promise (`Promise.resolve(check)`) so the logger awaits
36
- * verification uniformly with no sync/async branch.
37
- */
38
- type Verify = () => Promise<boolean>;
39
- /**
40
- * Sink that receives log records. A sink is a self-describing adapter: it
41
- * carries everything the logger must know to use it, namely how to
42
- * `verify` its backend is available, how to `write` a record, and
43
- * optionally how to `flush` buffered work. Holding `verify` on the sink
44
- * (rather than as a sibling export the logger pairs by hand) lets the
45
- * logger treat a registry as a plain `Sink[]` and lets a test supply one
46
- * self-contained fake.
47
- *
48
- * Sinks that buffer records (e.g. microtask-batched console) may
49
- * expose a `flush` hook so callers can force emission on demand.
50
- *
51
- * `write` is always async: a synchronous sink does its work eagerly and
52
- * returns an already-resolved promise, so the logger observes a uniform
53
- * `Promise<void>`. A rejected write is handled per sink and does not
54
- * disable the backend; only a failed `verify` drops a sink. A `void` arm
55
- * is not used, for the reason stated on {@link SinkFlush}.
56
- */
57
- type Sink = {
58
- readonly flush?: SinkFlush;
59
- readonly verify: Verify;
60
- readonly write: (record: LogRecord) => Promise<void>;
61
- };
62
- /**
63
- * Logger interface with 6 log levels plus `flush` for startup and sink drains.
64
- * `flush()` resolves once startup verification has completed, tracked sink
65
- * writes have settled, and every available sink's own {@link SinkFlush} hook
66
- * has settled. Safe to call even when no sink buffers.
67
- */
68
- type Logger = {
69
- readonly debug: (message: string) => void;
70
- readonly error: (message: string) => void;
71
- readonly fatal: (message: string) => void;
72
- readonly flush: () => Promise<void>;
73
- readonly info: (message: string) => void;
74
- readonly trace: (message: string) => void;
75
- readonly warn: (message: string) => void;
76
- };
77
- //#endregion
1
+ import { a as SinkFlush, i as Sink, n as LogRecord, o as Verify, r as Logger, t as Level } from "./types-BkkBXgY3.mjs";
78
2
  //#region src/create-logger.d.ts
79
3
  /**
80
- * Default `flush()` deadline in milliseconds. Measured on 2026-09-06: a
81
- * default logger flushing 100 records through the console and file sinks
82
- * settles in about 2 ms locally, so this leaves three orders of magnitude for
83
- * a slow but working backend while still bounding shutdown on a wedged one.
84
- * Override per logger through the `flushDeadlineMs` option of
85
- * {@link createLogger}.
86
- */
4
+ Default `flush()` deadline in milliseconds. Measured on 2026-09-06: a
5
+ default logger flushing 100 records through the console and file sinks
6
+ settles in about 2 ms locally, so this leaves three orders of magnitude for
7
+ a slow but working backend while still bounding shutdown on a wedged one.
8
+ Override per logger through the `flushDeadlineMs` option of
9
+ {@link createLogger}.
10
+ */
87
11
  export declare const DEFAULT_FLUSH_DEADLINE_MS = 5e3;
88
12
  /**
89
- * Default per-sink `verify()` time limit in milliseconds. Measured on
90
- * 2026-09-06: the default logger's five shipped verifies complete together in
91
- * about 2.4 ms locally, so this leaves three orders of magnitude for a slow
92
- * but working backend probe (a network filesystem, a busy IndexedDB) while a
93
- * verify that never answers (a hung mount, an IndexedDB open blocked by
94
- * another tab) can no longer stall startup. Override per logger through the
95
- * `verifyTimeoutMs` option of {@link createLogger}.
96
- */
13
+ Default per-sink `verify()` time limit in milliseconds. Measured on
14
+ 2026-09-06: the default logger's five shipped verifies complete together in
15
+ about 2.4 ms locally, so this leaves three orders of magnitude for a slow
16
+ but working backend probe (a network filesystem, a busy IndexedDB) while a
17
+ verify that never answers (a hung mount, an IndexedDB open blocked by
18
+ another tab) can no longer stall startup. Override per logger through the
19
+ `verifyTimeoutMs` option of {@link createLogger}.
20
+ */
97
21
  export declare const DEFAULT_VERIFY_TIMEOUT_MS = 5e3;
98
22
  /**
99
- * Most records the logger buffers before its sinks have verified. Startup
100
- * lasts at most {@link DEFAULT_VERIFY_TIMEOUT_MS}, so this bounds the memory a
101
- * burst during that window can claim; on overflow the oldest buffered record
102
- * is dropped so the newest (usually most diagnostic) context survives, and
103
- * one synthetic `warn` record naming the dropped count is written to every
104
- * available sink once initialization completes.
105
- */
23
+ Most records the logger buffers before its sinks have verified. Startup
24
+ lasts at most {@link DEFAULT_VERIFY_TIMEOUT_MS}, so this bounds the memory a
25
+ burst during that window can claim; on overflow the oldest buffered record
26
+ is dropped so the newest (usually most diagnostic) context survives, and
27
+ one synthetic `warn` record naming the dropped count is written to every
28
+ available sink once initialization completes.
29
+ */
106
30
  export declare const STARTUP_BUFFER_CAP = 1e4;
107
31
  /**
108
- * Builds a multi-sink logger over the supplied sink adapters. All
109
- * orchestration (per-sink availability, startup buffering and replay,
110
- * in-flight write tracking, and flush) lives here; the exported default
111
- * `logger` is just this factory applied to the default sink set, and tests
112
- * apply it to fake sinks to exercise the orchestration directly.
113
- *
114
- * Verification runs eagerly at construction and never blocks callers:
115
- * records emitted while an async sink is still verifying buffer internally
116
- * and replay to that sink the moment it verifies. Every sink verifies
117
- * concurrently under its own time limit (`verifyTimeoutMs`, default
118
- * {@link DEFAULT_VERIFY_TIMEOUT_MS}), so one backend that never answers
119
- * cannot starve the others or keep the logger from initializing. A sink
120
- * whose `verify` resolves `false`, throws, or runs past the limit is dropped
121
- * and receives no records; an answer that arrives after the limit is
122
- * ignored. A rejected `write` is the sink's own concern and does not disable
123
- * the backend.
124
- *
125
- * `flush()` always resolves: one deadline (`flushDeadlineMs`, default
126
- * {@link DEFAULT_FLUSH_DEADLINE_MS}) wraps startup verification, the
127
- * in-flight write drain, and every sink flush hook together. When it elapses
128
- * the logger reports one breadcrumb, abandons the tracked writes from its
129
- * view (the sinks expose no cancellation, so the underlying work continues),
130
- * and resolves, so a wedged backend cannot hang a shutdown.
131
- *
132
- * @param sinks - Sink adapters to fan each record out to, in priority order.
133
- *
134
- * @param flushDeadlineMs - Milliseconds one `flush()` may take before it
135
- * resolves anyway; raise it for slow but working backends such as network
136
- * filesystems.
137
- *
138
- * @param verifyTimeoutMs - Milliseconds one sink's `verify()` may take before
139
- * the sink counts as unavailable; raise it for a slow but working probe.
140
- *
141
- * @returns Logger plus its eager `initPromise`; callers need not await
142
- * `initPromise` before logging, since startup records replay on verify.
143
- *
144
- * @example
145
- * ```ts
146
- * const { logger } = createLogger({ sinks: [createConsoleSink()] });
147
- * logger.info('ready');
148
- * await logger.flush();
149
- * ```
150
- *
151
- * @example
152
- * ```ts
153
- * const { logger } = createLogger({
154
- * sinks: [createFileSink()],
155
- * flushDeadlineMs: 30_000,
156
- * });
157
- * ```
158
- */
32
+ Builds a multi-sink logger over the supplied sink adapters. All
33
+ orchestration (per-sink availability, startup buffering and replay,
34
+ in-flight write tracking, and flush) lives here; the exported default
35
+ `logger` is just this factory applied to the default sink set, and tests
36
+ apply it to fake sinks to exercise the orchestration directly.
37
+
38
+ Verification runs eagerly at construction and never blocks callers:
39
+ records emitted while an async sink is still verifying buffer internally
40
+ and replay to that sink the moment it verifies. Every sink verifies
41
+ concurrently under its own time limit (`verifyTimeoutMs`, default
42
+ {@link DEFAULT_VERIFY_TIMEOUT_MS}), so one backend that never answers
43
+ cannot starve the others or keep the logger from initializing. A sink
44
+ whose `verify` resolves `false`, throws, or runs past the limit is dropped
45
+ and receives no records; an answer that arrives after the limit is
46
+ ignored. A rejected `write` is the sink's own concern and does not disable
47
+ the backend.
48
+
49
+ `flush()` always resolves: one deadline (`flushDeadlineMs`, default
50
+ {@link DEFAULT_FLUSH_DEADLINE_MS}) wraps startup verification, the
51
+ in-flight write drain, and every sink flush hook together. When it elapses
52
+ the logger reports one breadcrumb, abandons the tracked writes from its
53
+ view (the sinks expose no cancellation, so the underlying work continues),
54
+ and resolves, so a wedged backend cannot hang a shutdown.
55
+
56
+ @param sinks - Sink adapters to fan each record out to, in priority order.
57
+
58
+ @param flushDeadlineMs - Milliseconds one `flush()` may take before it
59
+ resolves anyway; raise it for slow but working backends such as network
60
+ filesystems.
61
+
62
+ @param verifyTimeoutMs - Milliseconds one sink's `verify()` may take before
63
+ the sink counts as unavailable; raise it for a slow but working probe.
64
+
65
+ @returns Logger plus its eager `initPromise`; callers need not await
66
+ `initPromise` before logging, since startup records replay on verify.
67
+
68
+ @example
69
+ ```ts
70
+ const { logger } = createLogger({ sinks: [createConsoleSink()] });
71
+ logger.info('ready');
72
+ await logger.flush();
73
+ ```
74
+
75
+ @example
76
+ ```ts
77
+ const { logger } = createLogger({
78
+ sinks: [createFileSink()],
79
+ flushDeadlineMs: 30_000,
80
+ });
81
+ ```
82
+ */
159
83
  export declare function createLogger({ sinks, flushDeadlineMs, verifyTimeoutMs }: {
160
84
  readonly sinks: readonly Sink[];
161
85
  readonly flushDeadlineMs?: number;
@@ -167,310 +91,152 @@ export declare function createLogger({ sinks, flushDeadlineMs, verifyTimeoutMs }
167
91
  //#endregion
168
92
  //#region src/logger.d.ts
169
93
  /**
170
- * Eager readiness promise. Consumers do not need to await this before logging;
171
- * {@link Logger.flush} awaits it internally, and startup records replay to
172
- * async sinks as they become available.
173
- */
94
+ Eager readiness promise. Consumers do not need to await this before logging;
95
+ {@link Logger.flush} awaits it internally, and startup records replay to
96
+ async sinks as they become available.
97
+ */
174
98
  export declare const initPromise: Promise<void>;
175
99
  /**
176
- * Multi-sink logger that writes to all available backends.
177
- * Startup records replay to async sinks that verify after the log call.
178
- * Log calls throw only when initialization proves no backend is available,
179
- * which the console sink prevents in every supported runtime.
180
- *
181
- * @example
182
- * ```ts
183
- * import { logger, } from '\@monochromatic-dev/module-logger/logger';
184
- *
185
- * logger.error('unexpected shutdown',);
186
- * await logger.flush();
187
- * ```
188
- */
100
+ Multi-sink logger that writes to all available backends.
101
+ Startup records replay to async sinks that verify after the log call.
102
+ Log calls throw only when initialization proves no backend is available,
103
+ which the console sink prevents in every supported runtime.
104
+
105
+ @example
106
+ ```ts
107
+ import { logger, } from '\@monochromatic-dev/module-logger/logger';
108
+
109
+ logger.error('unexpected shutdown',);
110
+ await logger.flush();
111
+ ```
112
+ */
189
113
  export declare const logger: Logger;
190
114
  //#endregion
191
115
  //#region src/sink/console.d.ts
192
116
  /**
193
- * Builds a microtask-batched console sink. The pending buffer, schedule flag,
194
- * and memoized verbose detection live in this instance's closure (no
195
- * module-global state), so independent loggers and tests stay isolated with
196
- * no reset hook. Collapses contiguous same-level runs into single `console.*`
197
- * calls, sharply reducing console-panel overhead when an instrumented path
198
- * emits many records per sync frame.
199
- *
200
- * @returns Sink that writes formatted lines to `console.*`, except
201
- * process-hosted debug records write to stderr.
202
- *
203
- * @example
204
- * ```ts
205
- * const { logger } = createLogger({ sinks: [createConsoleSink()] });
206
- * logger.info('server started');
207
- * ```
208
- */
117
+ Builds a microtask-batched console sink. The pending buffer, schedule flag,
118
+ and memoized verbose detection live in this instance's closure (no
119
+ module-global state), so independent loggers and tests stay isolated with
120
+ no reset hook. Collapses contiguous same-level runs into single `console.*`
121
+ calls, sharply reducing console-panel overhead when an instrumented path
122
+ emits many records per sync frame.
123
+
124
+ @returns Sink that writes formatted lines to `console.*`, except
125
+ process-hosted debug records write to stderr.
126
+
127
+ @example
128
+ ```ts
129
+ const { logger } = createLogger({ sinks: [createConsoleSink()] });
130
+ logger.info('server started');
131
+ ```
132
+ */
209
133
  declare function createConsoleSink(): Sink;
210
134
  //#endregion
211
- //#region src/error-format.d.ts
212
- /**
213
- * Reports a logger-internal caught value without going back through logger
214
- * sinks, formatting it via {@link caughtValueText}.
215
- *
216
- * @param context - Human-readable operation that caught the value.
217
- *
218
- * @param error - Caught value to include in the diagnostic.
219
- *
220
- * @mutates error - `caughtValueText` may invoke string-conversion hooks.
221
- *
222
- * @example
223
- * ```ts
224
- * reportLoggerInternalError({
225
- * context: 'console sink verify failed',
226
- * error: new Error('blocked'),
227
- * });
228
- * ```
229
- */
230
- declare function reportLoggerInternalError({ context, error }: {
231
- readonly context: string;
232
- readonly error: unknown;
233
- }): void;
234
- //#endregion
235
- //#region src/sink/file.d.ts
236
- /**
237
- * Sentinel returned by {@link findNodeModulesUp} when no ancestor directory
238
- * contains a `node_modules`. A unique symbol so it never collides with a real
239
- * path string the walk might otherwise return, keeping the result free of a
240
- * banned `string | undefined` union.
241
- *
242
- * @example
243
- * ```ts
244
- * const dir = await findNodeModulesUp({ cwd, stat, dirname, join });
245
- * if (dir === NO_NODE_MODULES_FOUND) {
246
- * // no ancestor project root
247
- * }
248
- * ```
249
- */
250
- declare const NO_NODE_MODULES_FOUND: unique symbol;
251
- /**
252
- * Walks up from `cwd` to find the nearest ancestor directory containing a
253
- * `node_modules` subdirectory, returning that subdirectory's absolute path.
254
- *
255
- * Using find-up rather than cwd-relative placement keeps log directories
256
- * anchored to the project the caller actually belongs to. Without this,
257
- * scripts invoked from build output (e.g. `dist/`) or other stray cwds
258
- * would create `node_modules/.monochromatic/` inside those trees, polluting
259
- * shipped artifacts.
260
- *
261
- * Exported primarily so `index.unit.test.ts` can exercise both the hit
262
- * and miss paths directly with an injected `stat`.
263
- *
264
- * @param cwd - starting directory for the upward search
265
- *
266
- * @param stat - `node:fs/promises` stat (injected so the dynamic
267
- * import stays in one place)
268
- *
269
- * @param dirname - `node:path` dirname
270
- *
271
- * @param join - `node:path` join
272
- *
273
- * @param reportError - logger fault reporter injected for deterministic tests
274
- *
275
- * @returns absolute path to the nearest ancestor `node_modules`, or
276
- * {@link NO_NODE_MODULES_FOUND} when no ancestor contains one
277
- *
278
- * @example
279
- * ```ts
280
- * const dir = await findNodeModulesUp({ cwd: process.cwd(), stat, dirname, join });
281
- * ```
282
- */
283
- declare function findNodeModulesUp({ cwd, stat, dirname, join, reportError }: {
284
- readonly cwd: string;
285
- readonly stat: typeof stat$1;
286
- readonly dirname: typeof dirname$1;
287
- readonly join: typeof join$1;
288
- readonly reportError?: typeof reportLoggerInternalError;
289
- }): Promise<string | typeof NO_NODE_MODULES_FOUND>;
290
- /**
291
- * Builds a file sink that appends JSONL records to the nearest ancestor
292
- * `node_modules/.monochromatic/{timestamp}.log.jsonl` (resolved once during
293
- * verification). The resolved path, the cached `appendFile`, and the
294
- * verification memo live in this instance's closure (no module-global state),
295
- * so independent loggers and tests never share a log file or need a reset
296
- * hook. No `flush` hook: each `write` awaits `appendFile` directly, so there
297
- * is no buffered state to drain.
298
- *
299
- * @returns Sink backed by `node:fs/promises`.
300
- *
301
- * @example
302
- * ```ts
303
- * const { logger } = createLogger({ sinks: [createFileSink()] });
304
- * logger.error('unhandled rejection');
305
- * await logger.flush();
306
- * ```
307
- */
308
- declare function createFileSink(): Sink;
309
- //#endregion
310
- //#region src/sink/indexed-db.d.ts
311
- /**
312
- * Builds an IndexedDB sink that buffers serialized records through the shared
313
- * {@link createRecordBuffer} policy and persists each newline-joined JSONL
314
- * batch as one string value per transaction, measured at 0.15 µs of
315
- * main-thread enqueue per record on headless Chromium 149 (one `add` per
316
- * 32 KiB batch). The connection lives in this instance's closure (no
317
- * module-global state), so independent loggers and tests never share a
318
- * handle or need a reset hook.
319
- *
320
- * Records are readable the moment their transaction settles (DevTools
321
- * Application tab included), survive tab close and browser restart, and
322
- * auto-incremented keys serialize across tabs, so no run-scoped naming is
323
- * needed. Retention trims oldest-first past {@link MAX_STORED_BATCHES}.
324
- * Transactions use the default relaxed durability: relaxed commits reach the
325
- * browser's storage backend promptly and survive renderer crashes, and the
326
- * OS-crash window `durability: 'strict'` would close is the rarest failure
327
- * class, not worth an fsync per batch.
328
- *
329
- * Flush triggers (32 KiB in-write cap, `warn`-or-worse severity, 250 ms
330
- * quiet-period deadline, page lifecycle, and the `flush` hook) are the
331
- * buffer's; see {@link createRecordBuffer}. The sink's `flush` hook awaits
332
- * every issued batch transaction before resolving.
333
- *
334
- * @returns Sink backed by IndexedDB.
335
- *
336
- * @example
337
- * ```ts
338
- * const { logger } = createLogger({ sinks: [createIndexedDbSink()] });
339
- * logger.warn('quota nearing limit');
340
- * ```
341
- */
342
- declare function createIndexedDbSink(): Sink;
343
- //#endregion
344
135
  //#region src/sink/local-storage.d.ts
345
136
  /**
346
- * Builds a localStorage sink that buffers serialized records through the
347
- * shared {@link createRecordBuffer} policy and persists each newline-joined
348
- * JSONL batch under a run-scoped counter-incremented key through
349
- * {@link createLocalStorageStore}. One uniform write path runs on every
350
- * runtime; no per-runtime mode exists. Flush triggers (32 KiB in-write cap,
351
- * `warn`-or-worse severity, 250 ms quiet-period deadline, page lifecycle,
352
- * and the `flush` hook) are the buffer's; see {@link createRecordBuffer}.
353
- *
354
- * Unlike the sessionStorage sink, whose store dies with the tab, this sink's
355
- * batches survive tab close and browser restart, bounded by oldest-first
356
- * eviction at half the localStorage quota; that makes it the web storage sink
357
- * whose records remain inspectable after a full crash-and-restart.
358
- *
359
- * @returns Sink backed by web `localStorage`.
360
- *
361
- * @example
362
- * ```ts
363
- * const { logger } = createLogger({ sinks: [createLocalStorageSink()] });
364
- * logger.info('user signed in'); // buffered
365
- * logger.warn('quota near'); // flushes both records in one batch
366
- * ```
367
- */
137
+ Builds a localStorage sink that buffers serialized records through the
138
+ shared {@link createRecordBuffer} policy and persists each newline-joined
139
+ JSONL batch under a run-scoped counter-incremented key through
140
+ {@link createLocalStorageStore}. One uniform write path runs on every
141
+ runtime; no per-runtime mode exists. Flush triggers (32 KiB in-write cap,
142
+ `warn`-or-worse severity, 250 ms quiet-period deadline, page lifecycle,
143
+ and the `flush` hook) are the buffer's; see {@link createRecordBuffer}.
144
+
145
+ Unlike the sessionStorage sink, whose store dies with the tab, this sink's
146
+ batches survive tab close and browser restart, bounded by oldest-first
147
+ eviction at half the localStorage quota; that makes it the web storage sink
148
+ whose records remain inspectable after a full crash-and-restart.
149
+
150
+ @returns Sink backed by web `localStorage`.
151
+
152
+ @example
153
+ ```ts
154
+ const { logger } = createLogger({ sinks: [createLocalStorageSink()] });
155
+ logger.info('user signed in'); // buffered
156
+ logger.warn('quota near'); // flushes both records in one batch
157
+ ```
158
+ */
368
159
  declare function createLocalStorageSink(): Sink;
369
160
  //#endregion
370
161
  //#region src/sink/noop.d.ts
371
162
  /**
372
- * Builds a noop sink that discards every record and always verifies as
373
- * available. Stateless, so the returned adapters share the same functions;
374
- * the factory shape merely matches the other sinks. Useful as a stand-in
375
- * that disables logging without removing log calls.
376
- *
377
- * @returns Sink that discards all records and exposes no `flush` (nothing
378
- * is buffered).
379
- *
380
- * @example
381
- * ```ts
382
- * const { logger } = createLogger({ sinks: [createNoopSink()] });
383
- * logger.info('goes nowhere');
384
- * ```
385
- */
163
+ Builds a noop sink that discards every record and always verifies as
164
+ available. Stateless, so the returned adapters share the same functions;
165
+ the factory shape merely matches the other sinks. Useful as a stand-in
166
+ that disables logging without removing log calls.
167
+
168
+ @returns Sink that discards all records and exposes no `flush` (nothing
169
+ is buffered).
170
+
171
+ @example
172
+ ```ts
173
+ const { logger } = createLogger({ sinks: [createNoopSink()] });
174
+ logger.info('goes nowhere');
175
+ ```
176
+ */
386
177
  declare function createNoopSink(): Sink;
387
178
  //#endregion
388
- //#region src/sink/opfs.d.ts
389
- /**
390
- * Builds an OPFS sink that buffers serialized records through the shared
391
- * {@link createRecordBuffer} policy and appends each newline-joined JSONL
392
- * batch to a per-session file in the Origin Private File System with one
393
- * stream write per batch. The kept-open writable stream lives in this
394
- * instance's closure (no module-global state), so independent loggers and
395
- * tests never share a handle or need a reset hook.
396
- *
397
- * Flush triggers (32 KiB in-write cap, `warn`-or-worse severity, 250 ms
398
- * quiet-period deadline, page lifecycle, and the `flush` hook) are the
399
- * buffer's; see {@link createRecordBuffer}. Batch writes queue on the stream
400
- * in issue order, so ordering holds at the batch boundary, and the sink's
401
- * `flush` hook awaits every issued batch before resolving.
402
- *
403
- * @returns Sink backed by OPFS.
404
- *
405
- * @example
406
- * ```ts
407
- * const { logger } = createLogger({ sinks: [createOpfsSink()] });
408
- * logger.warn('quota nearing limit');
409
- * ```
410
- */
411
- declare function createOpfsSink(): Sink;
412
- //#endregion
413
179
  //#region src/sink/session-storage.d.ts
414
180
  /**
415
- * Builds a sessionStorage sink that buffers serialized records through the
416
- * shared {@link createRecordBuffer} policy and persists each newline-joined
417
- * JSONL batch under a counter-incremented key through
418
- * {@link createSessionStorageStore}. One uniform write path runs on every
419
- * runtime; no per-runtime mode exists. Flush triggers (32 KiB in-write cap,
420
- * `warn`-or-worse severity, 250 ms quiet-period deadline, page lifecycle,
421
- * and the `flush` hook) are the buffer's; see {@link createRecordBuffer}.
422
- *
423
- * @returns Sink backed by web `sessionStorage`.
424
- *
425
- * @example
426
- * ```ts
427
- * const { logger } = createLogger({ sinks: [createSessionStorageSink()] });
428
- * logger.info('user signed in'); // buffered
429
- * logger.warn('quota near'); // flushes both records in one batch
430
- * ```
431
- */
181
+ Builds a sessionStorage sink that buffers serialized records through the
182
+ shared {@link createRecordBuffer} policy and persists each newline-joined
183
+ JSONL batch under a counter-incremented key through
184
+ {@link createSessionStorageStore}. One uniform write path runs on every
185
+ runtime; no per-runtime mode exists. Flush triggers (32 KiB in-write cap,
186
+ `warn`-or-worse severity, 250 ms quiet-period deadline, page lifecycle,
187
+ and the `flush` hook) are the buffer's; see {@link createRecordBuffer}.
188
+
189
+ @returns Sink backed by web `sessionStorage`.
190
+
191
+ @example
192
+ ```ts
193
+ const { logger } = createLogger({ sinks: [createSessionStorageSink()] });
194
+ logger.info('user signed in'); // buffered
195
+ logger.warn('quota near'); // flushes both records in one batch
196
+ ```
197
+ */
432
198
  declare function createSessionStorageSink(): Sink;
433
199
  declare namespace index_d_exports {
434
- export { NO_NODE_MODULES_FOUND, createConsoleSink, createFileSink, createIndexedDbSink, createLocalStorageSink, createNoopSink, createOpfsSink, createSessionStorageSink, findNodeModulesUp };
200
+ export { createConsoleSink, createLocalStorageSink, createNoopSink, createSessionStorageSink };
435
201
  }
436
202
  //#endregion
437
203
  //#region src/tagged.d.ts
438
204
  /**
439
- * Wraps a logger so every message is prefixed with `[tag] `.
440
- * Callers typically pass `myFn.name` as tag to keep prefixes
441
- * in sync with refactors.
442
- *
443
- * @param tag - Prefix string inserted before each message
444
- *
445
- * @param l - Base logger to wrap; defaults to the module-level {@link logger}
446
- * singleton
447
- *
448
- * @returns Logger whose methods prepend `[tag] ` to every message
449
- *
450
- * @example
451
- * ```ts
452
- * import { tagged } from '\@monochromatic-dev/module-logger/tagged';
453
- *
454
- * function handleRequest({ l }: { l: Logger }): void {
455
- * l.info('received');
456
- * }
457
- *
458
- * handleRequest({ l: tagged({ tag: handleRequest.name }) });
459
- * // logs: [handleRequest] received
460
- * ```
461
- *
462
- * @example
463
- * ```ts
464
- * // Composing tags: the outermost wrap (`l2` here) prepends to the message
465
- * // last, so its tag ends up rightmost. The innermost wrap (`l1`) hits the
466
- * // underlying logger first, so its tag is leftmost. The chain reads
467
- * // root-first: outer wrap = inner tag position.
468
- * const l1 = tagged({ tag: 'http' });
469
- * const l2 = tagged({ tag: 'retry', l: l1 });
470
- * l2.info('attempt 3');
471
- * // logs: [http] [retry] attempt 3
472
- * ```
473
- */
205
+ Wraps a logger so every message is prefixed with `[tag] `.
206
+ Callers typically pass `myFn.name` as tag to keep prefixes
207
+ in sync with refactors.
208
+
209
+ @param tag - Prefix string inserted before each message
210
+
211
+ @param l - Base logger to wrap; defaults to the module-level {@link logger}
212
+ singleton
213
+
214
+ @returns Logger whose methods prepend `[tag] ` to every message
215
+
216
+ @example
217
+ ```ts
218
+ import { tagged } from '\@monochromatic-dev/module-logger/tagged';
219
+
220
+ function handleRequest({ l }: { l: Logger }): void {
221
+ l.info('received');
222
+ }
223
+
224
+ handleRequest({ l: tagged({ tag: handleRequest.name }) });
225
+ // logs: [handleRequest] received
226
+ ```
227
+
228
+ @example
229
+ ```ts
230
+ // Composing tags: the outermost wrap (`l2` here) prepends to the message
231
+ // last, so its tag ends up rightmost. The innermost wrap (`l1`) hits the
232
+ // underlying logger first, so its tag is leftmost. The chain reads
233
+ // root-first: outer wrap = inner tag position.
234
+ const l1 = tagged({ tag: 'http' });
235
+ const l2 = tagged({ tag: 'retry', l: l1 });
236
+ l2.info('attempt 3');
237
+ // logs: [http] [retry] attempt 3
238
+ ```
239
+ */
474
240
  export declare function tagged({ tag, l }: {
475
241
  readonly l?: Logger;
476
242
  readonly tag: string;
@@ -478,31 +244,31 @@ export declare function tagged({ tag, l }: {
478
244
  //#endregion
479
245
  //#region src/sink/console-control-chars.d.ts
480
246
  /**
481
- * Neutralizes terminal control characters in console-bound text. One linear
482
- * pass over the code points: each neutralized control becomes a `\uXXXX`
483
- * escape, everything else is copied through, and newline and tab pass
484
- * untouched. Well-formed and malformed escape sequences get no
485
- * special treatment because the introducer byte itself is neutralized, so a
486
- * trailing lone ESC, an unterminated OSC, and a nested ESC all lose their
487
- * teeth the same way.
488
- *
489
- * @param text - Message text destined for `console.*` or `process.stderr`.
490
- *
491
- * @returns Text with every neutralized control rendered as `\uXXXX`.
492
- *
493
- * @example
494
- * ```ts
495
- * neutralizeControlCharacters('title:\u001B]0;x\u0007 ok\n\tnext');
496
- * // => 'title:\\u001B]0;x\\u0007 ok\n\tnext'
497
- * ```
498
- */
247
+ Neutralizes terminal control characters in console-bound text. One linear
248
+ pass over the code points: each neutralized control becomes a `\uXXXX`
249
+ escape, everything else is copied through, and newline and tab pass
250
+ untouched. Well-formed and malformed escape sequences get no
251
+ special treatment because the introducer byte itself is neutralized, so a
252
+ trailing lone ESC, an unterminated OSC, and a nested ESC all lose their
253
+ teeth the same way.
254
+
255
+ @param text - Message text destined for `console.*` or `process.stderr`.
256
+
257
+ @returns Text with every neutralized control rendered as `\uXXXX`.
258
+
259
+ @example
260
+ ```ts
261
+ neutralizeControlCharacters('title:\u001B]0;x\u0007 ok\n\tnext');
262
+ // => 'title:\\u001B]0;x\\u0007 ok\n\tnext'
263
+ ```
264
+ */
499
265
  declare function neutralizeControlCharacters(text: string): string;
500
266
  //#endregion
501
267
  //#region src/sink/local-storage-key.d.ts
502
268
  /**
503
- * Parsed identity of one owned localStorage entry, used to order eviction
504
- * across runs.
505
- */
269
+ Parsed identity of one owned localStorage entry, used to order eviction
270
+ across runs.
271
+ */
506
272
  type ParsedLogKey = {
507
273
  readonly key: string;
508
274
  readonly stamp: number;
@@ -510,64 +276,64 @@ type ParsedLogKey = {
510
276
  readonly index: number;
511
277
  };
512
278
  /**
513
- * Builds the namespaced localStorage key for one batch slot of one run.
514
- *
515
- * @param stamp - Run creation time ordering runs oldest-first.
516
- *
517
- * @param nonce - Same-millisecond disambiguator between concurrent tabs.
518
- *
519
- * @param index - Zero-based batch slot within the run.
520
- *
521
- * @returns Key such as `monochromatic.log.1753000000000.a1b2.3`.
522
- *
523
- * @example
524
- * ```ts
525
- * buildLogKey({ stamp: 1753000000000, nonce: 'a1b2', index: 3 });
526
- * ```
527
- */
279
+ Builds the namespaced localStorage key for one batch slot of one run.
280
+
281
+ @param stamp - Run creation time ordering runs oldest-first.
282
+
283
+ @param nonce - Same-millisecond disambiguator between concurrent tabs.
284
+
285
+ @param index - Zero-based batch slot within the run.
286
+
287
+ @returns Key such as `monochromatic.log.1753000000000.a1b2.3`.
288
+
289
+ @example
290
+ ```ts
291
+ buildLogKey({ stamp: 1753000000000, nonce: 'a1b2', index: 3 });
292
+ ```
293
+ */
528
294
  declare function buildLogKey({ stamp, nonce, index }: {
529
295
  readonly stamp: number;
530
296
  readonly nonce: string;
531
297
  readonly index: number;
532
298
  }): string;
533
299
  /**
534
- * Parses a localStorage key back into its run identity, or reports it foreign
535
- * by leaving `parsed` absent. Parsing is strict (exact prefix, exactly the
536
- * identity segment count, digit-shaped stamp and index, non-empty nonce)
537
- * because eviction trusts this to never classify a host application's key, or
538
- * the sessionStorage sink's flat `monochromatic.log.{n}` shape, as evictable.
539
- *
540
- * @param key - Candidate localStorage key.
541
- *
542
- * @returns Wrapper whose `parsed` property is present only for an owned key.
543
- *
544
- * @example
545
- * ```ts
546
- * parseLogKey('monochromatic.log.1753000000000.a1b2.3').parsed; // ParsedLogKey
547
- * parseLogKey('monochromatic.log.5').parsed; // undefined: sessionStorage shape
548
- * ```
549
- */
300
+ Parses a localStorage key back into its run identity, or reports it foreign
301
+ by leaving `parsed` absent. Parsing is strict (exact prefix, exactly the
302
+ identity segment count, digit-shaped stamp and index, non-empty nonce)
303
+ because eviction trusts this to never classify a host application's key, or
304
+ the sessionStorage sink's flat `monochromatic.log.{n}` shape, as evictable.
305
+
306
+ @param key - Candidate localStorage key.
307
+
308
+ @returns Wrapper whose `parsed` property is present only for an owned key.
309
+
310
+ @example
311
+ ```ts
312
+ parseLogKey('monochromatic.log.1753000000000.a1b2.3').parsed; // ParsedLogKey
313
+ parseLogKey('monochromatic.log.5').parsed; // undefined: sessionStorage shape
314
+ ```
315
+ */
550
316
  declare function parseLogKey(key: string): {
551
317
  readonly parsed?: ParsedLogKey;
552
318
  };
553
319
  /**
554
- * Orders parsed keys oldest-first for eviction: by run stamp, then by nonce
555
- * (an arbitrary but stable tiebreak between same-millisecond runs), then by
556
- * batch index within the run.
557
- *
558
- * @param first - Parsed key compared first.
559
- *
560
- * @param second - Parsed key compared second.
561
- *
562
- * @returns Negative when `first` is older, positive when newer, zero on ties.
563
- *
564
- * @example
565
- * ```ts
566
- * entries.toSorted(function byOldestFirst(first, second) {
567
- * return compareLogKeys({ first, second });
568
- * });
569
- * ```
570
- */
320
+ Orders parsed keys oldest-first for eviction: by run stamp, then by nonce
321
+ (an arbitrary but stable tiebreak between same-millisecond runs), then by
322
+ batch index within the run.
323
+
324
+ @param first - Parsed key compared first.
325
+
326
+ @param second - Parsed key compared second.
327
+
328
+ @returns Negative when `first` is older, positive when newer, zero on ties.
329
+
330
+ @example
331
+ ```ts
332
+ entries.toSorted(function byOldestFirst(first, second) {
333
+ return compareLogKeys({ first, second });
334
+ });
335
+ ```
336
+ */
571
337
  declare function compareLogKeys({ first, second }: {
572
338
  readonly first: ParsedLogKey;
573
339
  readonly second: ParsedLogKey;
@@ -575,86 +341,86 @@ declare function compareLogKeys({ first, second }: {
575
341
  //#endregion
576
342
  //#region src/sink/local-storage-quota.d.ts
577
343
  /**
578
- * Detects the current runtime's default localStorage quota in UTF-16 code
579
- * units, or `Number.POSITIVE_INFINITY` when the runtime is unrecognized so the
580
- * caller leaves its footprint uncapped and relies on reactive eviction alone.
581
- *
582
- * @returns Total quota in code units, or `Number.POSITIVE_INFINITY` if unknown.
583
- *
584
- * @example
585
- * ```ts
586
- * const capChars = detectLocalStorageQuotaChars() / 2; // half the total
587
- * ```
588
- */
344
+ Detects the current runtime's default localStorage quota in UTF-16 code
345
+ units, or `Number.POSITIVE_INFINITY` when the runtime is unrecognized so the
346
+ caller leaves its footprint uncapped and relies on reactive eviction alone.
347
+
348
+ @returns Total quota in code units, or `Number.POSITIVE_INFINITY` if unknown.
349
+
350
+ @example
351
+ ```ts
352
+ const capChars = detectLocalStorageQuotaChars() / 2; // half the total
353
+ ```
354
+ */
589
355
  declare function detectLocalStorageQuotaChars(): number;
590
356
  //#endregion
591
357
  //#region src/sink/local-storage-store.d.ts
592
358
  /**
593
- * Builds the persistence engine behind the localStorage sink: each `persist`
594
- * lands one already-serialized batch under a run-scoped counter-incremented
595
- * key, with proactive and reactive quota eviction. Run identity and counters
596
- * live in this instance's closure (no module-global state), so independent
597
- * sinks and tests never share keys or need a reset hook.
598
- *
599
- * Unlike sessionStorage, localStorage is shared by every tab of the origin and
600
- * survives restarts, so this engine differs from the sessionStorage engine in
601
- * two ways. Keys carry a run identity (see `local-storage-key.ts`), so
602
- * concurrent tabs never collide on a counter. And on its first persist the
603
- * engine adopts every strictly-parsed entry left by other runs into its
604
- * footprint tally, evicting those oldest-first before its own entries;
605
- * without that, leftovers from dead sessions would fill the store until no
606
- * run could ever write again. Adoption is deferred to first persist rather
607
- * than construction so building the default sink set never touches
608
- * `globalThis.localStorage` on runtimes where the sink never verifies (plain
609
- * Node warns on mere access). Keys that fail the strict parse, including the
610
- * host application's, are never counted and never evicted.
611
- *
612
- * The engine caps its own footprint (adopted entries included) at half the
613
- * runtime's localStorage quota, proactively dropping oldest-first, and
614
- * reactively drops again if the real store still overflows; see
615
- * {@link createLocalStorageStore.persist}.
616
- *
617
- * @returns Engine exposing `persist` for one batch value per call.
618
- *
619
- * @example
620
- * ```ts
621
- * const store = createLocalStorageStore();
622
- * store.persist('{"level":"info","message":"hi","timestamp":0}');
623
- * ```
624
- */
359
+ Builds the persistence engine behind the localStorage sink: each `persist`
360
+ lands one already-serialized batch under a run-scoped counter-incremented
361
+ key, with proactive and reactive quota eviction. Run identity and counters
362
+ live in this instance's closure (no module-global state), so independent
363
+ sinks and tests never share keys or need a reset hook.
364
+
365
+ Unlike sessionStorage, localStorage is shared by every tab of the origin and
366
+ survives restarts, so this engine differs from the sessionStorage engine in
367
+ two ways. Keys carry a run identity (see `local-storage-key.ts`), so
368
+ concurrent tabs never collide on a counter. And on its first persist the
369
+ engine adopts every strictly-parsed entry left by other runs into its
370
+ footprint tally, evicting those oldest-first before its own entries;
371
+ without that, leftovers from dead sessions would fill the store until no
372
+ run could ever write again. Adoption is deferred to first persist rather
373
+ than construction so building the default sink set never touches
374
+ `globalThis.localStorage` on runtimes where the sink never verifies (plain
375
+ Node warns on mere access). Keys that fail the strict parse, including the
376
+ host application's, are never counted and never evicted.
377
+
378
+ The engine caps its own footprint (adopted entries included) at half the
379
+ runtime's localStorage quota, proactively dropping oldest-first, and
380
+ reactively drops again if the real store still overflows; see
381
+ {@link createLocalStorageStore.persist}.
382
+
383
+ @returns Engine exposing `persist` for one batch value per call.
384
+
385
+ @example
386
+ ```ts
387
+ const store = createLocalStorageStore();
388
+ store.persist('{"level":"info","message":"hi","timestamp":0}');
389
+ ```
390
+ */
625
391
  declare function createLocalStorageStore(): {
626
392
  readonly persist: (batch: string) => void;
627
393
  };
628
394
  //#endregion
629
395
  //#region src/sink/record-buffer.d.ts
630
396
  /**
631
- * Builds the buffering stage shared by batch-persisting sinks: serialized
632
- * records accumulate and leave as one newline-joined JSONL batch through
633
- * `onFlush`. One uniform policy runs on every runtime; no per-runtime mode
634
- * exists.
635
- *
636
- * A batch flushes synchronously from inside `add` when it reaches
637
- * {@link FLUSH_BUFFER_CAP_CHARS} or when the record's severity is `warn` or
638
- * worse, by timer after {@link FLUSH_DEADLINE_MS} of quiet, on `pagehide`
639
- * and on the document becoming hidden (where those events exist), and on
640
- * `drain`. The byte-cap and severity flushes run on the caller's stack, so
641
- * neither a synchronous workload nor a wedged main thread can accumulate
642
- * more than one cap of unhanded records. When an addition would breach the
643
- * cap, the existing entries flush first so an oversized record's downstream
644
- * failure can only ever drop that record, never its batch-mates.
645
- *
646
- * @param onFlush - Backend handoff receiving each newline-joined batch;
647
- * called synchronously from whichever trigger fires, in record order.
648
- *
649
- * @returns Buffer exposing `add` for records and `drain` for forced flushes.
650
- *
651
- * @example
652
- * ```ts
653
- * const buffer = createRecordBuffer({ onFlush: (batch) => store.persist(batch) });
654
- * buffer.add({ level: 'info', serialized: JSON.stringify(record) });
655
- * buffer.drain();
656
- * ```
657
- */
397
+ Builds the buffering stage shared by batch-persisting sinks: serialized
398
+ records accumulate and leave as one newline-joined JSONL batch through
399
+ `onFlush`. One uniform policy runs on every runtime; no per-runtime mode
400
+ exists.
401
+
402
+ A batch flushes synchronously from inside `add` when it reaches
403
+ {@link FLUSH_BUFFER_CAP_CHARS} or when the record's severity is `warn` or
404
+ worse, by timer after {@link FLUSH_DEADLINE_MS} of quiet, on `pagehide`
405
+ and on the document becoming hidden (where those events exist), and on
406
+ `drain`. The byte-cap and severity flushes run on the caller's stack, so
407
+ neither a synchronous workload nor a wedged main thread can accumulate
408
+ more than one cap of unhanded records. When an addition would breach the
409
+ cap, the existing entries flush first so an oversized record's downstream
410
+ failure can only ever drop that record, never its batch-mates.
411
+
412
+ @param onFlush - Backend handoff receiving each newline-joined batch;
413
+ called synchronously from whichever trigger fires, in record order.
414
+
415
+ @returns Buffer exposing `add` for records and `drain` for forced flushes.
416
+
417
+ @example
418
+ ```ts
419
+ const buffer = createRecordBuffer({ onFlush: (batch) => store.persist(batch) });
420
+ buffer.add({ level: 'info', serialized: JSON.stringify(record) });
421
+ buffer.drain();
422
+ ```
423
+ */
658
424
  declare function createRecordBuffer({ onFlush }: {
659
425
  readonly onFlush: (batch: string) => void;
660
426
  }): {
@@ -667,35 +433,35 @@ declare function createRecordBuffer({ onFlush }: {
667
433
  //#endregion
668
434
  //#region src/sink/session-storage-quota.d.ts
669
435
  /**
670
- * Detects the current runtime's default sessionStorage quota in UTF-16 code
671
- * units, or `Number.POSITIVE_INFINITY` when the runtime is unrecognized so the
672
- * caller leaves its footprint uncapped and relies on reactive eviction alone.
673
- *
674
- * @returns Total quota in code units, or `Number.POSITIVE_INFINITY` if unknown.
675
- *
676
- * @example
677
- * ```ts
678
- * const capChars = detectSessionStorageQuotaChars() / 2; // half the total
679
- * ```
680
- */
436
+ Detects the current runtime's default sessionStorage quota in UTF-16 code
437
+ units, or `Number.POSITIVE_INFINITY` when the runtime is unrecognized so the
438
+ caller leaves its footprint uncapped and relies on reactive eviction alone.
439
+
440
+ @returns Total quota in code units, or `Number.POSITIVE_INFINITY` if unknown.
441
+
442
+ @example
443
+ ```ts
444
+ const capChars = detectSessionStorageQuotaChars() / 2; // half the total
445
+ ```
446
+ */
681
447
  declare function detectSessionStorageQuotaChars(): number;
682
448
  //#endregion
683
449
  //#region src/sink/web-storage-quota-error.d.ts
684
450
  /**
685
- * Reports whether a caught `setItem` value is a storage quota overflow, so
686
- * eviction reclaims space only for a full store and never for an unrelated
687
- * write fault such as a disabled-storage `SecurityError`.
688
- *
689
- * @param error - Caught value from a `setItem` failure.
690
- *
691
- * @returns Whether `error` names a quota overflow.
692
- *
693
- * @example
694
- * ```ts
695
- * try { sessionStorage.setItem(k, v); }
696
- * catch (error: unknown) { if (isQuotaExceededError(error)) evictOldest(); }
697
- * ```
698
- */
451
+ Reports whether a caught `setItem` value is a storage quota overflow, so
452
+ eviction reclaims space only for a full store and never for an unrelated
453
+ write fault such as a disabled-storage `SecurityError`.
454
+
455
+ @param error - Caught value from a `setItem` failure.
456
+
457
+ @returns Whether `error` names a quota overflow.
458
+
459
+ @example
460
+ ```ts
461
+ try { sessionStorage.setItem(k, v); }
462
+ catch (error: unknown) { if (isQuotaExceededError(error)) evictOldest(); }
463
+ ```
464
+ */
699
465
  declare function isQuotaExceededError(error: unknown): boolean;
700
466
  //#endregion
701
467
  export { type Level, type LogRecord, type Logger, type Sink, type SinkFlush, type Verify, buildLogKey as _buildLogKey, compareLogKeys as _compareLogKeys, createLocalStorageStore as _createLocalStorageStore, createRecordBuffer as _createRecordBuffer, detectLocalStorageQuotaChars as _detectLocalStorageQuotaChars, detectSessionStorageQuotaChars as _detectSessionStorageQuotaChars, isQuotaExceededError as _isQuotaExceededError, neutralizeControlCharacters as _neutralizeControlCharacters, parseLogKey as _parseLogKey, index_d_exports as sinks };