{
  "package": "@arki/log",
  "version": "0.3.0",
  "entries": [
    {
      "subpath": ".",
      "name": "buffer",
      "kind": "function",
      "signature": "export declare function buffer(sink: Sink, options?: { readonly maxRecords?: number; readonly flushIntervalMs?: number; readonly overflow?: 'drop-oldest' | 'drop-newest'; }): Sink;",
      "jsdocSummary": "Batches records and writes them to `sink` every `flushIntervalMs`, in order. When `maxRecords` are waiting, `overflow` says which record is dropped."
    },
    {
      "subpath": ".",
      "name": "CategoryRule",
      "kind": "type",
      "signature": "export type CategoryRule<C extends string> = { readonly level?: LevelName; readonly channels?: readonly C[]; /** `false`: start from no channels instead of the parent's. */ readonly inherit?: boolean; };",
      "jsdocSummary": "A rule for one category and its descendants (RFC §8.1)."
    },
    {
      "subpath": ".",
      "name": "Censor",
      "kind": "type",
      "signature": "export type Censor = string | ((value: Value, path: string) => Value);",
      "jsdocSummary": ""
    },
    {
      "subpath": ".",
      "name": "ChannelName",
      "kind": "type",
      "signature": "export type ChannelName = Register extends { logging: Configured<infer C>; } ? C : string;",
      "jsdocSummary": "The app's channel names once `Register` is declared; any string before that."
    },
    {
      "subpath": ".",
      "name": "configure",
      "kind": "function",
      "signature": "export declare function configure<const C extends string>(config: LogConfig<C>, options?: ConfigureOptions): Configured<C>;",
      "jsdocSummary": "Configures the default instance, once, at the app entry. A second call throws `ARKI_LOG_E001`, unless it comes from the same `owner` (a dev server re-running the entry)."
    },
    {
      "subpath": ".",
      "name": "Configured",
      "kind": "type",
      "signature": "export type Configured<C extends string> = { readonly [CHANNELS]?: C; flush(): Promise<void>; /** Flushes, then closes every sink. The instance is then unconfigured again. */ close(options?: { readonly timeoutMs?: number; }): Promise<void>; /** Swaps the configuration atomically; the old sinks that are not reused drain and close. */ reconfigure<const D extends string>(config: LogConfig<D>): Promise<void>; };",
      "jsdocSummary": "The handle `configure()` returns (RFC §8.1)."
    },
    {
      "subpath": ".",
      "name": "ConfigureOptions",
      "kind": "type",
      "signature": "export type ConfigureOptions = { /** * Who configures, usually the entry's `import.meta.url`. When the same owner * calls `configure()` again (a dev server re-running the entry), the new setup * replaces the old one and the old handle goes stale. Any other second call * still throws `ARKI_LOG_E001`. */ readonly owner?: string; };",
      "jsdocSummary": "Options for `configure()`."
    },
    {
      "subpath": ".",
      "name": "consoleSink",
      "kind": "function",
      "signature": "export declare function consoleSink(options?: { readonly format?: Formatter; }): Sink;",
      "jsdocSummary": "Writes to `console`. With `format`, each record is one formatted line. Without it (browser mode), the message is followed by the fields object and the error, so devtools can expand them."
    },
    {
      "subpath": ".",
      "name": "ContextStore",
      "kind": "type",
      "signature": "export type ContextStore = { get(): Fields | undefined; run<R>(fields: Fields, fn: () => R): R; };",
      "jsdocSummary": "Where scoped context (`withContext`) lives. The core ships a synchronous store; `@arki/log/node` ships `asyncContext()`."
    },
    {
      "subpath": ".",
      "name": "createLogging",
      "kind": "function",
      "signature": "export declare function createLogging(): Logging;",
      "jsdocSummary": "A private logging instance with the same functions as the default one (RFC §8.1)."
    },
    {
      "subpath": ".",
      "name": "deduplicate",
      "kind": "function",
      "signature": "export declare function deduplicate(sink: Sink, options?: { readonly windowMs?: number; readonly key?: (record: LogRecord) => string; }): Sink;",
      "jsdocSummary": "Writes the same record (by `key`, default level + category + template) once per `windowMs`. When the window closes, a summary record says how many were suppressed."
    },
    {
      "subpath": ".",
      "name": "dropWhen",
      "kind": "function",
      "signature": "export declare function dropWhen(predicate: (record: LogRecord) => boolean): Processor;",
      "jsdocSummary": "Drops records the predicate matches."
    },
    {
      "subpath": ".",
      "name": "enrich",
      "kind": "function",
      "signature": "export declare function enrich(fn: (record: LogRecord) => Fields): Processor;",
      "jsdocSummary": "Adds fields from `fn`. Never overwrites a key the record already has."
    },
    {
      "subpath": ".",
      "name": "EnvSettings",
      "kind": "type",
      "signature": "export type EnvSettings = { /** `LOG_LEVEL`: replaces `default.level`. */ readonly level?: LevelName; /** `DEBUG`: categories lowered to `debug`, and categories excluded with `-`. `''` is the root. */ readonly debug?: { readonly include: readonly string[]; readonly exclude: readonly string[]; }; /** `NO_COLOR`: `false` when set. Pass it to `pretty({ colors })`; formatters do not read config. */ readonly colors?: boolean; };",
      "jsdocSummary": "Settings read from the environment by `fromEnv()` in `@arki/log/node` (RFC §8.5)."
    },
    {
      "subpath": ".",
      "name": "FailureLike",
      "kind": "type",
      "signature": "export type FailureLike = { readonly code: string; readonly message: string; readonly data: unknown; readonly status: number; readonly remediation: string | undefined; readonly cause?: unknown; readonly '~failure': true; };",
      "jsdocSummary": "A failure value from `@arki/failure`, by shape: `@arki/log` keeps zero dependencies, so it knows a failure by its `'~failure'` brand. Logged as a field, it prints `code`, `message`, `status`, `data`, `remediation` and its cause chain as `causes`."
    },
    {
      "subpath": ".",
      "name": "FieldInput",
      "kind": "type",
      "signature": "export type FieldInput = Fields | (() => Fields);",
      "jsdocSummary": "Fields, or a synchronous thunk that builds them only when the level is enabled (RFC §5.4)."
    },
    {
      "subpath": ".",
      "name": "Fields",
      "kind": "type",
      "signature": "export type Fields = Readonly<Record<string, Value>>;",
      "jsdocSummary": "One field map per record, as in OpenTelemetry."
    },
    {
      "subpath": ".",
      "name": "FieldsArg",
      "kind": "type",
      "signature": "export type FieldsArg<T extends string, Bound extends string> = string extends T ? [fields?: FieldInput] : [Exclude<PlaceholderNames<T>, Bound>] extends [never] ? [fields?: FieldInput] : [ fields: PlaceholderFields<Exclude<PlaceholderNames<T>, Bound>> | (() => PlaceholderFields<Exclude<PlaceholderNames<T>, Bound>>) ];",
      "jsdocSummary": "The fields argument of a log call. A placeholder must be satisfied by the call's fields or by fields already bound with `.with()` (the `Bound` keys). A template typed as plain `string` accepts any fields."
    },
    {
      "subpath": ".",
      "name": "fingersCrossed",
      "kind": "function",
      "signature": "export declare function fingersCrossed(sink: Sink, options?: { readonly triggerAt?: LevelName; readonly captureFrom?: LevelName; readonly maxRecords?: number; readonly scope?: 'context' | 'global'; }): Sink;",
      "jsdocSummary": "Monolog's fingers-crossed handler (RFC §7.1). Records from `captureFrom` up are kept in a bounded ring. A record at `triggerAt` or above writes the ring in order, then itself; later records in that scope pass straight through. With `scope: 'context'` there is one ring per `withContext` scope (records outside any scope share the global ring); a scope that ends without an error leaves its ring to be garbage-collected."
    },
    {
      "subpath": ".",
      "name": "Formatter",
      "kind": "type",
      "signature": "export type Formatter = (record: LogRecord) => string;",
      "jsdocSummary": "Turns a record into one line of text."
    },
    {
      "subpath": ".",
      "name": "getLogger",
      "kind": "function",
      "signature": "export declare function getLogger(category?: string): Logger;",
      "jsdocSummary": "A logger for a `:`-separated category; no argument is the root category `''`. Safe at module scope."
    },
    {
      "subpath": ".",
      "name": "json",
      "kind": "function",
      "signature": "export declare function json(): Formatter;",
      "jsdocSummary": "One JSON object per record: `time`, `level`, `levelName`, `category`, `template`, `message`, then `eventName`, `body`, `fields`, `error`, trace ids and `resource` when present. Bound fields are written from JSON cached once per `.with()`. When layers share a key, the merged map is written instead, so every key appears once (RFC §5.2 precedence)."
    },
    {
      "subpath": ".",
      "name": "Level",
      "kind": "variable",
      "signature": "export declare const Level: { readonly trace: 1; readonly debug: 5; readonly info: 9; readonly warn: 13; readonly error: 17; readonly fatal: 21; };",
      "jsdocSummary": "The six levels, with their OpenTelemetry severity numbers (RFC §4)."
    },
    {
      "subpath": ".",
      "name": "LevelInput",
      "kind": "type",
      "signature": "export type LevelInput = LevelName | number;",
      "jsdocSummary": "A level name, or an OpenTelemetry severity number from 1 to 24."
    },
    {
      "subpath": ".",
      "name": "LevelName",
      "kind": "type",
      "signature": "export type LevelName = keyof typeof Level;",
      "jsdocSummary": ""
    },
    {
      "subpath": ".",
      "name": "lineSink",
      "kind": "function",
      "signature": "export declare function lineSink(write: (line: string) => void, options?: { readonly format?: Formatter; }): Sink;",
      "jsdocSummary": "Formats each record (JSON by default) and hands the line to `write`."
    },
    {
      "subpath": ".",
      "name": "LOG_ERROR_CODES",
      "kind": "variable",
      "signature": "export declare const LOG_ERROR_CODES: { /** * `configure()` ran a second time on the same logging instance. * * @fix Call `configure()` once at the app entry, with `{ owner: import.meta.url }` so a dev re-run of the entry is allowed. Use `reconfigure()` on its handle to change the setup. * @verify bun run test -- src/core/logging.test.ts */ readonly alreadyConfigured: 'ARKI_LOG_E001'; /** * A category rule or `to()` names a channel that `configure({ channels })` does not define. * * @fix Add the channel to `configure({ channels })`, or use one of the defined names. * @verify bun run test -- src/core/logging.test.ts */ readonly unknownChannel: 'ARKI_LOG_E002'; /** * A level is neither one of the six names nor a severity number from 1 to 24. * * @fix Use `trace`, `debug`, `info`, `warn`, `error` or `fatal`, or a number from 1 to 24. * @verify bun run test -- src/core/logging.test.ts */ readonly invalidLevel: 'ARKI_LOG_E003'; /** * `fakeLog()` ran while another fake was active, or `configure()` ran while a fake owns the instance. * * @fix Restore the active fake first with `restore()` or `using`. Keep one fake at a time. * @verify bun run test -- src/testing/fake.test.ts */ readonly fakeActive: 'ARKI_LOG_E004'; /** * `reconfigure()` was called on a handle that no longer owns the configuration. * * @fix Use the handle returned by the latest `configure()` call. * @verify bun run test -- src/core/logging.test.ts */ readonly staleHandle: 'ARKI_LOG_E005'; };",
      "jsdocSummary": "Coded errors for mistakes in logging setup. A log call itself never throws these unless it is given a level that does not exist."
    },
    {
      "subpath": ".",
      "name": "LogConfig",
      "kind": "type",
      "signature": "export type LogConfig<C extends string> = { readonly channels: Readonly<Record<C, Sink>>; readonly default: { readonly level: LevelName; readonly channels: readonly NoInfer<C>[]; }; readonly categories?: Readonly<Record<string, CategoryRule<NoInfer<C>>>>; readonly processors?: readonly Processor[]; readonly resource?: Fields; readonly context?: ContextStore; readonly trace?: TraceSource; readonly env?: EnvSettings; };",
      "jsdocSummary": "The argument of `configure()` (RFC §8.1)."
    },
    {
      "subpath": ".",
      "name": "LogError",
      "kind": "class",
      "signature": "export declare class LogError extends Error { readonly code: LogErrorCode; readonly remediation: string; constructor(args: { readonly code: LogErrorCode; readonly message: string; readonly remediation: string; }); }",
      "jsdocSummary": ""
    },
    {
      "subpath": ".",
      "name": "LogErrorCode",
      "kind": "type",
      "signature": "export type LogErrorCode = (typeof LOG_ERROR_CODES)[keyof typeof LOG_ERROR_CODES];",
      "jsdocSummary": ""
    },
    {
      "subpath": ".",
      "name": "LogEvent",
      "kind": "type",
      "signature": "export type LogEvent = { readonly level: LevelInput; readonly eventName: string; readonly body?: Value; readonly fields?: Fields; };",
      "jsdocSummary": "A structured event (RFC §5.5)."
    },
    {
      "subpath": ".",
      "name": "logfmt",
      "kind": "function",
      "signature": "export declare function logfmt(): Formatter;",
      "jsdocSummary": "`key=value` pairs: `time`, `level`, `category`, `msg`, then fields, `error` and trace ids."
    },
    {
      "subpath": ".",
      "name": "Logger",
      "kind": "type",
      "signature": "export type Logger<Bound extends string = never> = { readonly category: string; trace<T extends string>(template: T, ...fields: FieldsArg<T, Bound>): void; debug<T extends string>(template: T, ...fields: FieldsArg<T, Bound>): void; info<T extends string>(template: T, ...fields: FieldsArg<T, Bound>): void; warn<T extends string>(template: T, ...fields: FieldsArg<T, Bound>): void; error<T extends string>(template: T, ...fields: FieldsArg<T, Bound>): void; /** Logs an error; the template is the error's message. */ error(error: Error, fields?: FieldInput): void; fatal<T extends string>(template: T, ...fields: FieldsArg<T, Bound>): void; /** Logs an error; the template is the error's message. It only writes; it never exits. */ fatal(error: Error, fields?: FieldInput): void; log<T extends string>(level: LevelInput, template: T, ...fields: FieldsArg<T, Bound>): void; isEnabled(level: LevelInput): boolean; emit(event: LogEvent): void; /** A logger with bound fields. The original is unchanged. */ with<F extends Fields>(fields: F): Logger<Bound | (keyof F & string)>; /** Extends the category path: `'arki:kv'` → `'arki:kv:redis'`. */ child(name: string): Logger<Bound>; /** Stamps this trace on every record. */ withTrace(trace: TraceContext): Logger<Bound>; /** Sends records only to these channels, instead of the category's channels. */ to(...channels: readonly [ChannelName, ...ChannelName[]]): Logger<Bound>; };",
      "jsdocSummary": "A logger (RFC §3). `Bound` holds the keys bound with `.with()`, which satisfy placeholders."
    },
    {
      "subpath": ".",
      "name": "Logging",
      "kind": "type",
      "signature": "export type Logging = { getLogger(category?: string): Logger; configure<const C extends string>(config: LogConfig<C>, options?: ConfigureOptions): Configured<C>; withContext<R>(fields: Fields, fn: () => R): R; shareContext(fields: Fields): void; };",
      "jsdocSummary": "A logging instance: the default one behind the global functions, or a private one from `createLogging()`."
    },
    {
      "subpath": ".",
      "name": "LogRecord",
      "kind": "type",
      "signature": "export type LogRecord = Readonly<{ /** Epoch milliseconds. */ time: number; /** 1..24 (OTel SeverityNumber). */ level: number; /** OTel SeverityText. */ levelName: LevelName; category: string; /** `''` for `emit()`. */ template: string; eventName?: string; body?: Value; fields: Fields; error?: Error; traceId?: string; spanId?: string; traceFlags?: number; resource: Fields; /** Renders the template on first call, then memoised. */ message(): string; }>;",
      "jsdocSummary": "The record handed to processors, sinks and formatters (RFC §5.6)."
    },
    {
      "subpath": ".",
      "name": "maskSecrets",
      "kind": "function",
      "signature": "export declare function maskSecrets(values: () => readonly string[], options?: { readonly censor?: string; }): Processor;",
      "jsdocSummary": "Replaces every occurrence of a known secret value, wherever it appears: the template, string fields at any depth, the serialised error, the body. `redact` hides values at known paths; this hides known values at any path, for a secret that was revealed and then logged by hand. `values` is read per record, so secrets loaded after `configure()` are covered too."
    },
    {
      "subpath": ".",
      "name": "memorySink",
      "kind": "function",
      "signature": "export declare function memorySink(): MemorySink;",
      "jsdocSummary": ""
    },
    {
      "subpath": ".",
      "name": "MemorySink",
      "kind": "type",
      "signature": "export type MemorySink = Sink & { readonly records: readonly LogRecord[]; clear(): void; };",
      "jsdocSummary": "A sink that keeps records in memory."
    },
    {
      "subpath": ".",
      "name": "MIN_SECRET_LENGTH",
      "kind": "variable",
      "signature": "export declare const MIN_SECRET_LENGTH = 8;",
      "jsdocSummary": "Values shorter than this are never masked: too likely to match ordinary text."
    },
    {
      "subpath": ".",
      "name": "PlaceholderNames",
      "kind": "type",
      "signature": "export type PlaceholderNames<T extends string, Acc extends string = never> = T extends `${string}{${infer Rest}` ? Rest extends `{${infer After}` ? PlaceholderNames<After, Acc> : Rest extends `${infer Name}}${infer After}` ? Name extends '' | `${string}{${string}` ? PlaceholderNames<Rest, Acc> : PlaceholderNames<After, Acc | Name> : Acc : Acc;",
      "jsdocSummary": "The placeholder names in a literal template. `{{` is a literal brace; `{}` and a name that contains `{` are not placeholders. Tail-recursive, so long templates do not hit the instantiation-depth limit. Mirrors `parseTemplate`."
    },
    {
      "subpath": ".",
      "name": "pretty",
      "kind": "function",
      "signature": "export declare function pretty(options?: { readonly colors?: boolean; }): Formatter;",
      "jsdocSummary": "Human output: `12:00:00.123 INFO arki:kv connecting to db.local pool=main`. Placeholder values are highlighted; fields not used by the template follow. Errors print their stack and cause chain. Colors are off unless asked for."
    },
    {
      "subpath": ".",
      "name": "Processor",
      "kind": "type",
      "signature": "export type Processor = (record: LogRecord) => LogRecord | null;",
      "jsdocSummary": "Returns the record (or a changed copy from `updateRecord`), or `null` to drop it."
    },
    {
      "subpath": ".",
      "name": "RecordChanges",
      "kind": "type",
      "signature": "export type RecordChanges = { readonly time?: number; readonly level?: number; readonly template?: string; readonly eventName?: string; readonly body?: Value; readonly fields?: Fields; readonly error?: Error | undefined; };",
      "jsdocSummary": "What `updateRecord` may change."
    },
    {
      "subpath": ".",
      "name": "redact",
      "kind": "function",
      "signature": "export declare function redact(paths: readonly string[], options?: { readonly censor?: Censor; }): Processor;",
      "jsdocSummary": "Replaces the values at dot paths (RFC §7). `*` matches one level of keys or array items (`'*.token'`). Paths are matched against the fields and the serialised error. The copy renders its message from the redacted fields, so a secret never reaches the message text."
    },
    {
      "subpath": ".",
      "name": "Register",
      "kind": "interface",
      "signature": "export interface Register { }",
      "jsdocSummary": "Register your app's logging handle to type-check channel names in `to()` (RFC §8.4):"
    },
    {
      "subpath": ".",
      "name": "renderTemplate",
      "kind": "function",
      "signature": "export declare function renderTemplate(template: string, fields: Fields): string;",
      "jsdocSummary": "Renders a template. A placeholder with no value (absent or `undefined`) stays `{name}`."
    },
    {
      "subpath": ".",
      "name": "serializeError",
      "kind": "function",
      "signature": "export declare function serializeError(error: Error): Fields;",
      "jsdocSummary": "Turns an `Error` into plain fields (RFC §5.3): `name`, `message`, `stack`, `code`, own enumerable fields, the `cause` chain and `AggregateError.errors`. Depth and cycles are bounded. Own accessors are never called, except the engine's `stack`, `name` and `message`, which are read inside `try`."
    },
    {
      "subpath": ".",
      "name": "serializeFailure",
      "kind": "function",
      "signature": "export declare function serializeFailure(failure: FailureLike): Fields;",
      "jsdocSummary": "Turns a failure from `@arki/failure` into plain fields: `code`, `message`, `status`, `data`, `remediation`, and `causes`, its cause chain as a list from nearest to root. A link is a failure's fields or an error's fields; an error's own causes join the same list. The list stops after {@link MAX_CAUSE_LINKS} links (`'[MaxDepth]'`) or at a cycle (`'[Circular]'`)."
    },
    {
      "subpath": ".",
      "name": "shareContext",
      "kind": "function",
      "signature": "export declare function shareContext(fields: Fields): void;",
      "jsdocSummary": "App-wide fields on every record. Later calls add to (and override) earlier ones."
    },
    {
      "subpath": ".",
      "name": "Sink",
      "kind": "type",
      "signature": "export type Sink = { write(record: LogRecord): void; flush?(): void | Promise<void>; close?(): void | Promise<void>; /** The sink's own floor. */ level?: LevelName; /** The sink's own processors, run after the global ones. */ processors?: readonly Processor[]; /** * Records from this level up reach this sink even when the category's level is higher. * Set by `fingersCrossed`; it never lowers other sinks' levels. */ captureFrom?: LevelName; };",
      "jsdocSummary": "An output (RFC §7). `write` is synchronous; a sink that does async IO buffers inside itself."
    },
    {
      "subpath": ".",
      "name": "TraceContext",
      "kind": "type",
      "signature": "export type TraceContext = { readonly traceId: string; readonly spanId: string; readonly traceFlags?: number; };",
      "jsdocSummary": "A trace context stamped on a record."
    },
    {
      "subpath": ".",
      "name": "TraceSource",
      "kind": "type",
      "signature": "export type TraceSource = () => TraceContext | undefined;",
      "jsdocSummary": "Reads the active trace when a record is built (`@arki/log/otel` provides one)."
    },
    {
      "subpath": ".",
      "name": "updateRecord",
      "kind": "function",
      "signature": "export declare function updateRecord(record: LogRecord, changes: RecordChanges): LogRecord;",
      "jsdocSummary": "A copy of a record with some parts replaced, for processors. The copy renders its message from its own fields, so a redacted value never reaches `message()`."
    },
    {
      "subpath": ".",
      "name": "Value",
      "kind": "type",
      "signature": "export type Value = string | number | boolean | null | undefined | bigint | Date | Error | FailureLike | readonly Value[] | { readonly [key: string]: Value; };",
      "jsdocSummary": "A field value (RFC §5.2)."
    },
    {
      "subpath": ".",
      "name": "withContext",
      "kind": "function",
      "signature": "export declare function withContext<R>(fields: Fields, fn: () => R): R;",
      "jsdocSummary": "Runs `fn` with fields every record inside carries. Async code needs `asyncContext()` installed."
    },
    {
      "subpath": "./node",
      "name": "asyncContext",
      "kind": "function",
      "signature": "export declare function asyncContext(): ContextStore;",
      "jsdocSummary": "A context store on `AsyncLocalStorage`: `withContext` scopes survive `await`."
    },
    {
      "subpath": "./node",
      "name": "file",
      "kind": "function",
      "signature": "export declare function file(options: { readonly path: string; readonly format?: Formatter; }): Sink;",
      "jsdocSummary": "Appends lines (JSON by default) to a file, opened when this is called."
    },
    {
      "subpath": "./node",
      "name": "fromEnv",
      "kind": "function",
      "signature": "export declare function fromEnv(env?: Readonly<Record<string, string | undefined>>): { readonly env: EnvSettings; };",
      "jsdocSummary": "Reads the environment, only when called (RFC §8.5): `LOG_LEVEL` (the default level), `DEBUG` (`arki:kv:*,-arki:kv:noisy`: each match lowers that category to `debug`; `-` excludes) and `NO_COLOR`. Spread the result into `configure()`."
    },
    {
      "subpath": "./node",
      "name": "stderr",
      "kind": "function",
      "signature": "export declare function stderr(options?: FdSinkOptions): Sink;",
      "jsdocSummary": "Writes lines (JSON by default) to standard error."
    },
    {
      "subpath": "./node",
      "name": "stdout",
      "kind": "function",
      "signature": "export declare function stdout(options?: FdSinkOptions): Sink;",
      "jsdocSummary": "Writes lines (JSON by default) to standard output."
    },
    {
      "subpath": "./otel",
      "name": "otelSink",
      "kind": "function",
      "signature": "export declare function otelSink(loggerProvider: LoggerProvider): Sink;",
      "jsdocSummary": "A sink that sends records to the OpenTelemetry Logs API. Each record keeps its severity, its rendered message (or its structured body for `emit()`), its fields as attributes plus `log.category` and `log.template`, its trace ids, and the configured resource fields (as attributes; a record's own fields win on a clash)."
    },
    {
      "subpath": "./otel",
      "name": "otelTrace",
      "kind": "function",
      "signature": "export declare function otelTrace(): TraceSource;",
      "jsdocSummary": "A trace source that reads the active span from `@opentelemetry/api` when a record is built. Pass it as `configure({ trace: otelTrace() })`."
    },
    {
      "subpath": "./testing",
      "name": "CapturedRecord",
      "kind": "type",
      "signature": "export type CapturedRecord = { readonly record: LogRecord; readonly channels: readonly string[]; };",
      "jsdocSummary": "A record and the channel names it was routed to."
    },
    {
      "subpath": "./testing",
      "name": "fakeLog",
      "kind": "function",
      "signature": "export declare function fakeLog(): FakeLog;",
      "jsdocSummary": "Takes over the default instance: level `trace`, every category captured, no sink written. `restore()` (or `using`) gives it back. One fake at a time per process; a second one throws `ARKI_LOG_E004`."
    },
    {
      "subpath": "./testing",
      "name": "FakeLog",
      "kind": "type",
      "signature": "export type FakeLog = { /** Every record, from every category, at every level. */ readonly records: readonly LogRecord[]; /** Every record with the channels it was routed to (`to()`, else the configured category rule). */ readonly captured: readonly CapturedRecord[]; assertLogged(match: RecordMatch): void; assertNotLogged(match: RecordMatch): void; assertSentTo(channel: string, match?: RecordMatch): void; /** Gives the default instance back, with its configuration as it was. */ restore(): void; [Symbol.dispose](): void; };",
      "jsdocSummary": ""
    },
    {
      "subpath": "./testing",
      "name": "LogAssertionError",
      "kind": "class",
      "signature": "export declare class LogAssertionError extends Error { constructor(message: string); }",
      "jsdocSummary": ""
    },
    {
      "subpath": "./testing",
      "name": "RecordMatch",
      "kind": "type",
      "signature": "export type RecordMatch = { readonly level?: LevelName; readonly category?: string; readonly template?: string; readonly message?: string; readonly eventName?: string; readonly fields?: Fields; };",
      "jsdocSummary": "What a captured record must match. Every given part must match; `fields` matches a subset."
    }
  ],
  "groups": [],
  "errorCodes": [
    "ARKI_LOG_E001",
    "ARKI_LOG_E002",
    "ARKI_LOG_E003",
    "ARKI_LOG_E004",
    "ARKI_LOG_E005"
  ]
}
