@kar-mi/spirit-vale-tools-logging 0.9.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.
package/README.md ADDED
@@ -0,0 +1,70 @@
1
+ # @kar-mi/spirit-vale-tools-logging
2
+
3
+ Session-oriented logging utilities for Spirit Vale tools.
4
+
5
+ > **Internal package.** This package is published only because the domain
6
+ > packages (`combat`, `rewards`) depend on it at runtime; it is
7
+ > installed automatically alongside them and is not a supported public API.
8
+
9
+ ## Install
10
+
11
+ ```sh
12
+ bun add @kar-mi/spirit-vale-tools-logging
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ```ts
18
+ import { createLogSession } from "@kar-mi/spirit-vale-tools-logging";
19
+
20
+ const session = await createLogSession({
21
+ producer: "my-tool",
22
+ streams: ["capture", "combat"],
23
+ });
24
+
25
+ const logger = session.logger("combat");
26
+ logger.log("combat.event", { kind: "damage", amount: 42 });
27
+
28
+ await session.flush(); // records so far are on disk; the session stays usable
29
+ await session.close();
30
+ ```
31
+
32
+ ## Buffering
33
+
34
+ `log()` is synchronous and buffers records into byte-bounded batches, appended through one file
35
+ handle per stream. Tune with `batchBytes` (default 256 KiB), `flushIntervalMs` (default 50 ms), and
36
+ `maxBufferedBytes` (default 8 MiB) on `createLogSession`, or per logger.
37
+
38
+ - `session.flush()` / `logger.flush()` resolve once everything logged before the call is on disk.
39
+ Call it before a process exits by any path other than `close()`.
40
+ - A write failure is reported once through `onWriteError` and rethrown by `flush()`/`close()`, but
41
+ later batches are still attempted — a transient error does not stop logging.
42
+ - Records are only dropped when they would push memory past `maxBufferedBytes` (a stalled disk).
43
+ Each such episode is reported once through `onWriteError`, counted in `logger.stats()`, and the
44
+ logger resumes accepting records as soon as the queue drains. Sequence numbers are assigned before
45
+ the drop, so a dropped record leaves a gap that readers can detect.
46
+
47
+ ```ts
48
+ logger.stats(); // { bufferedBytes, queuedBatches, failed, droppedRecords }
49
+ ```
50
+
51
+ ## Reading
52
+
53
+ `subscribeToLogStream` is the single tail of one stream, shared by every consumer of it: one
54
+ `fs.watch` on the current-stream pointer, one on the active session file, one `JsonlTailReader`,
55
+ and one fallback poll — regardless of how many overlays are attached. The domain packages build
56
+ their followers on it; use it directly only for a stream they do not cover.
57
+
58
+ ```ts
59
+ const subscription = subscribeToLogStream({ stream: "combat" });
60
+ for await (const read of subscription) process(read.lines);
61
+ subscription.close();
62
+ ```
63
+
64
+ `next()` settles only when there is something to report, so an idle stream costs nothing beyond a
65
+ debounced watcher event. `poll()` remains for consumers driving their own clock; unlike `next()` it
66
+ always re-reads the pointer, so it reflects a session switch as of the call. Watcher events on
67
+ Windows can be coalesced or dropped around rotation and rename, so `DEFAULT_STREAM_FALLBACK_POLL_MS`
68
+ bounds how long such a miss can stall a consumer.
69
+
70
+ See the [package guide](https://github.com/kar-mi/spirit-vale-tools/blob/main/docs/packages.md) for registry setup and usage.
@@ -0,0 +1,4 @@
1
+ import type { JsonObject } from "./types.ts";
2
+ /** Structural allowlist for shareable combat records. Returns undefined for diagnostics/unknown records. */
3
+ export declare function sanitizeCombatData(type: string, data: JsonObject): JsonObject | undefined;
4
+ //# sourceMappingURL=combat-sanitizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"combat-sanitizer.d.ts","sourceRoot":"","sources":["../src/combat-sanitizer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAK7C,4GAA4G;AAC5G,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,CAMzF"}
@@ -0,0 +1,16 @@
1
+ export { JsonLinesLogger, activateLogSession, createLogSession, readCurrentLogStream, writeCurrentLogStreamPointer, } from "./logger.ts";
2
+ export { encodeLogRecord, encodeLogStreamHeader, isLogStreamHeader, parseLogRecord, parseLogStreamHeader, } from "./record-codec.ts";
3
+ export type { CreateLogSessionOptions, JsonLinesLoggerOptions, JsonLinesLoggerStats, LoggerTuning, LogWriteFailure, } from "./logger.ts";
4
+ export { sanitizeCombatData } from "./combat-sanitizer.ts";
5
+ export { defaultLogDirectory, currentStreamPointerPath, streamCategoryDirectory, streamSessionPath, } from "./paths.ts";
6
+ export { listLogSessions } from "./sessions.ts";
7
+ export { decimal, isMissing, isRecord, nullableString } from "./predicates.ts";
8
+ export type { LiveLogStatus } from "./predicates.ts";
9
+ export { JsonlTailReader } from "./jsonl-tail-reader.ts";
10
+ export type { JsonlTailReadResult, JsonlTailReaderOptions } from "./jsonl-tail-reader.ts";
11
+ export { LiveLogSessionFollower } from "./session-follower.ts";
12
+ export type { LiveLogLineConsumer, LiveLogSessionFollowerOptions } from "./session-follower.ts";
13
+ export { DEFAULT_STREAM_BATCH_BYTES, DEFAULT_STREAM_DEBOUNCE_MS, DEFAULT_STREAM_FALLBACK_POLL_MS, subscribeToLogStream, } from "./stream-source.ts";
14
+ export type { LogStreamRead, LogStreamSourceOptions, LogStreamSubscription } from "./stream-source.ts";
15
+ export type { CurrentLogStream, JsonData, JsonObject, LogRecord, LogSession, ListedLogSession, LogStream, LogStreamHeader, } from "./types.ts";
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,4BAA4B,GAC7B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,EACd,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,uBAAuB,EACvB,sBAAsB,EACtB,oBAAoB,EACpB,YAAY,EACZ,eAAe,GAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC/E,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAC1F,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,YAAY,EAAE,mBAAmB,EAAE,6BAA6B,EAAE,MAAM,uBAAuB,CAAC;AAChG,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,+BAA+B,EAC/B,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,aAAa,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AACvG,YAAY,EACV,gBAAgB,EAChB,QAAQ,EACR,UAAU,EACV,SAAS,EACT,UAAU,EACV,gBAAgB,EAChB,SAAS,EACT,eAAe,GAChB,MAAM,YAAY,CAAC"}