@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
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @monochromatic-dev/module-logger
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - The root entry is now platform-neutral and neither built artifact contains a dynamic `import()`.
8
+ `createFileSink` moved to `@monochromatic-dev/module-logger/node`;
9
+ `createIndexedDbSink` and `createOpfsSink` moved to `@monochromatic-dev/module-logger/browser`.
10
+ The default logger keeps file logging under the `node` export condition and IndexedDB under `default`;
11
+ a Node consumer whose bundler resolves `default` no longer gets file logging.
12
+ Commit `ce38d07`.
13
+
3
14
  ## 0.2.0
4
15
 
5
16
  ### Minor Changes
package/README.md CHANGED
@@ -60,6 +60,17 @@ The published package exposes the built artifact only.
60
60
  The `/ts` source subpath used inside this workspace is stripped at publish time,
61
61
  because Node refuses `.ts` files under `node_modules`.
62
62
 
63
+ The root entry is platform-neutral and is built twice.
64
+ The `node` export condition serves a build whose default logger includes the file sink,
65
+ with static `node:fs/promises` and `node:path` imports,
66
+ and which carries no browser storage code.
67
+ Every other resolution (`default`) serves a build whose default logger includes the IndexedDB sink
68
+ and which references no Node module.
69
+ Neither build contains a dynamic `import()`,
70
+ and a unit test reads every chunk of both builds to keep it that way.
71
+ The root types are identical on both conditions.
72
+ A Node consumer whose bundler resolves the `default` condition gets the neutral build and no file logging.
73
+
63
74
  ## Log levels
64
75
 
65
76
  Six levels,
@@ -188,15 +199,16 @@ That startup buffer holds at most `STARTUP_BUFFER_CAP` records (10000,
188
199
  discards all records;
189
200
  a stand-in that disables logging without removing log calls
190
201
 
191
- Each sink is a factory,
202
+ Each sink is a factory.
203
+ The cross-platform ones,
192
204
  `createConsoleSink()`,
193
- `createFileSink()`,
194
- `createIndexedDbSink()`,
195
- `createOpfsSink()`,
196
- `createSessionStorageSink()`,
205
+ `createSessionStorageSink()`,
197
206
  `createLocalStorageSink()`,
198
207
  and `createNoopSink()`,
199
- exported under the `sinks` namespace.
208
+ are exported under the `sinks` namespace of the root entry.
209
+ `createFileSink()` is exported from `@monochromatic-dev/module-logger/node`,
210
+ and `createIndexedDbSink()` and `createOpfsSink()` from `@monochromatic-dev/module-logger/browser`,
211
+ so importing a platform-only sink is the consumer's own assertion of the platform.
200
212
  A sink instance keeps its own buffers,
201
213
  streams,
202
214
  and counters,
@@ -297,10 +309,11 @@ Raise the flush deadline for a slow but working backend,
297
309
  such as a network filesystem:
298
310
 
299
311
  ```ts
300
- import { createLogger, sinks, } from '@monochromatic-dev/module-logger';
312
+ import { createLogger, } from '@monochromatic-dev/module-logger';
313
+ import { createFileSink, } from '@monochromatic-dev/module-logger/node';
301
314
 
302
315
  const { logger, } = createLogger({
303
- sinks: [sinks.createFileSink(),],
316
+ sinks: [createFileSink(),],
304
317
  flushDeadlineMs: 30_000,
305
318
  verifyTimeoutMs: 30_000,
306
319
  },);
@@ -351,6 +364,7 @@ See [DECISIONS.md](DECISIONS.md) for rationale on:
351
364
  - `flush()` has a deadline
352
365
  - Sinks verify concurrently under a time limit
353
366
  - The startup buffer is bounded and overflow is reported
367
+ - Platform-specific sinks live behind `./node` and `./browser`
354
368
  - Zero-config at import,
355
369
  no configure step (the logtape migration observations)
356
370
 
@@ -369,6 +383,17 @@ See [DECISIONS.md](DECISIONS.md) for rationale on:
369
383
  flush)
370
384
  - `src/logger.ts`:
371
385
  default singleton built by applying `createLogger` to the default sinks
386
+ - `src/node.ts`:
387
+ the `./node` subpath entry,
388
+ `createFileSink()`
389
+ - `src/browser.ts`:
390
+ the `./browser` subpath entry,
391
+ `createIndexedDbSink()` and `createOpfsSink()`
392
+ - `src/default-sinks.node.ts` and `src/default-sinks.neutral.ts`:
393
+ the two default sink lists,
394
+ selected at build time through the `#default-sinks` entry of `package.json` `imports`
395
+ - `src/artifact-platform-split.unit.test.ts`:
396
+ guard that reads every chunk of both builds and rejects dynamic imports and cross-platform leaks
372
397
  - `src/tagged.ts`:
373
398
  `tagged()` wrapper for composable prefixes
374
399
  - `src/sink/console.ts`:
@@ -0,0 +1,60 @@
1
+ import { i as Sink } from "./types-BkkBXgY3.mjs";
2
+ //#region src/sink/indexed-db.d.ts
3
+ /**
4
+ Builds an IndexedDB sink that buffers serialized records through the shared
5
+ {@link createRecordBuffer} policy and persists each newline-joined JSONL
6
+ batch as one string value per transaction, measured at 0.15 µs of
7
+ main-thread enqueue per record on headless Chromium 149 (one `add` per
8
+ 32 KiB batch). The connection lives in this instance's closure (no
9
+ module-global state), so independent loggers and tests never share a
10
+ handle or need a reset hook.
11
+
12
+ Records are readable the moment their transaction settles (DevTools
13
+ Application tab included), survive tab close and browser restart, and
14
+ auto-incremented keys serialize across tabs, so no run-scoped naming is
15
+ needed. Retention trims oldest-first past {@link MAX_STORED_BATCHES}.
16
+ Transactions use the default relaxed durability: relaxed commits reach the
17
+ browser's storage backend promptly and survive renderer crashes, and the
18
+ OS-crash window `durability: 'strict'` would close is the rarest failure
19
+ class, not worth an fsync per batch.
20
+
21
+ Flush triggers (32 KiB in-write cap, `warn`-or-worse severity, 250 ms
22
+ quiet-period deadline, page lifecycle, and the `flush` hook) are the
23
+ buffer's; see {@link createRecordBuffer}. The sink's `flush` hook awaits
24
+ every issued batch transaction before resolving.
25
+
26
+ @returns Sink backed by IndexedDB.
27
+
28
+ @example
29
+ ```ts
30
+ const { logger } = createLogger({ sinks: [createIndexedDbSink()] });
31
+ logger.warn('quota nearing limit');
32
+ ```
33
+ */
34
+ export declare function createIndexedDbSink(): Sink;
35
+ //#endregion
36
+ //#region src/sink/opfs.d.ts
37
+ /**
38
+ Builds an OPFS sink that buffers serialized records through the shared
39
+ {@link createRecordBuffer} policy and appends each newline-joined JSONL
40
+ batch to a per-session file in the Origin Private File System with one
41
+ stream write per batch. The kept-open writable stream lives in this
42
+ instance's closure (no module-global state), so independent loggers and
43
+ tests never share a handle or need a reset hook.
44
+
45
+ Flush triggers (32 KiB in-write cap, `warn`-or-worse severity, 250 ms
46
+ quiet-period deadline, page lifecycle, and the `flush` hook) are the
47
+ buffer's; see {@link createRecordBuffer}. Batch writes queue on the stream
48
+ in issue order, so ordering holds at the batch boundary, and the sink's
49
+ `flush` hook awaits every issued batch before resolving.
50
+
51
+ @returns Sink backed by OPFS.
52
+
53
+ @example
54
+ ```ts
55
+ const { logger } = createLogger({ sinks: [createOpfsSink()] });
56
+ logger.warn('quota nearing limit');
57
+ ```
58
+ */
59
+ export declare function createOpfsSink(): Sink;
60
+ //#endregion
@@ -0,0 +1 @@
1
+ import{n as createRecordBuffer,r as reportLoggerInternalError,t as createIndexedDbSink}from"./indexed-db-hsIfv7Cv.mjs";function createOpfsSink(){let state={},pendingBatchWrites=new Set;async function verify(){try{let opfsRoot=await navigator.storage.getDirectory(),timestamp=new Date().toISOString().replaceAll(`:`,`-`),fileHandle=await opfsRoot.getFileHandle(`monochromatic-${timestamp}.log.jsonl`,{create:!0}),probeWritable=await fileHandle.createWritable({keepExistingData:!0}),testData=`{"test":true,"timestamp":${Date.now()}}\n`;await probeWritable.write(testData),await probeWritable.close();let available=(await(await fileHandle.getFile()).text()).includes(`"test":true`);return available&&(state.writable=await fileHandle.createWritable({keepExistingData:!0})),available}catch(error){let opfsStorage=globalThis.navigator?.storage;return opfsStorage!==void 0&&`getDirectory`in opfsStorage&&reportLoggerInternalError({context:`OPFS sink verification failed`,error}),!1}}async function writeBatch(batch){if(state.writable)try{await state.writable.write(`${batch}\n`)}catch(error){reportLoggerInternalError({context:`OPFS sink record write failed`,error})}}async function removePendingWhenSettled(pending){await pending,pendingBatchWrites.delete(pending)}function handOffBatch(batch){let pending=writeBatch(batch);pendingBatchWrites.add(pending),removePendingWhenSettled(pending)}let buffer=createRecordBuffer({onFlush:handOffBatch});function write(record){return buffer.add({level:record.level,serialized:JSON.stringify(record)}),Promise.resolve()}async function flush(){buffer.drain();let writes=[...pendingBatchWrites];await Promise.all(writes)}return{flush,verify,write}}export{createIndexedDbSink,createOpfsSink};