@logtape/logtape 2.3.0-dev.809 → 2.3.0-dev.811
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/dist/scoped-config.cjs
CHANGED
|
@@ -13,6 +13,7 @@ function compileScopedConfig(config, allowAsync, createError) {
|
|
|
13
13
|
if (!isObjectLike(config)) throw createError("Configuration must be an object.");
|
|
14
14
|
if (!isObjectLike(config.sinks)) throw createError("Configuration must include a sinks object.");
|
|
15
15
|
if (!Array.isArray(config.loggers)) throw createError("Configuration must include a loggers array.");
|
|
16
|
+
if (config.filters !== void 0 && !isObjectLike(config.filters)) throw createError("Configuration filters must be an object.");
|
|
16
17
|
const nodes = /* @__PURE__ */ new Map();
|
|
17
18
|
const configuredCategories = /* @__PURE__ */ new Set();
|
|
18
19
|
for (const logger of config.loggers) {
|
package/dist/scoped-config.js
CHANGED
|
@@ -13,6 +13,7 @@ function compileScopedConfig(config, allowAsync, createError) {
|
|
|
13
13
|
if (!isObjectLike(config)) throw createError("Configuration must be an object.");
|
|
14
14
|
if (!isObjectLike(config.sinks)) throw createError("Configuration must include a sinks object.");
|
|
15
15
|
if (!Array.isArray(config.loggers)) throw createError("Configuration must include a loggers array.");
|
|
16
|
+
if (config.filters !== void 0 && !isObjectLike(config.filters)) throw createError("Configuration filters must be an object.");
|
|
16
17
|
const nodes = /* @__PURE__ */ new Map();
|
|
17
18
|
const configuredCategories = /* @__PURE__ */ new Set();
|
|
18
19
|
for (const logger of config.loggers) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scoped-config.js","names":["scopedConfigSymbol: unique symbol","defaultScopedLogger: CompiledScopedLogger","config: ScopedConfigLike<TSinkId, TFilterId>","allowAsync: boolean","createError: (message: string) => Error","sinks: Sink[]","sinkIds: readonly TSinkId[]","filters: ((record: LogRecord) => boolean)[]","filterIds: readonly TFilterId[]","contextLocalStorage:\n | ContextLocalStorage<Record<string, unknown>>\n | undefined","contextLocalStorage: ContextLocalStorage<Record<string, unknown>>","scopedConfig: CompiledScopedConfig","callback: () => R","category: readonly string[]","level: LogLevel","record: LogRecord","bypassSinks: Set<Sink> | undefined","emitToSink: (sink: Sink, bypassSinks: Set<Sink> | undefined) => void","retainedDisposables?: ReadonlySet<Disposable | AsyncDisposable>","errors: unknown[]","primary: unknown","secondary: unknown","value: unknown","activeConfig: CompiledScopedConfig | undefined","extraRetained?: ReadonlySet<Disposable | AsyncDisposable>","disposables: Set<Disposable | AsyncDisposable>","category: unknown","length: number","firstSink: Sink | undefined","sinks: Sink[] | undefined","sink: Sink","disposables: Set<Disposable>","retainedDisposables: ReadonlySet<Disposable | AsyncDisposable>","disposables: Set<AsyncDisposable>","disposables: ReadonlySet<TDisposable>","errors: readonly unknown[]","flattened: unknown[]"],"sources":["../src/scoped-config.ts"],"sourcesContent":["import type { ContextLocalStorage } from \"./context.ts\";\nimport { type FilterLike, toFilter } from \"./filter.ts\";\nimport { compareLogLevel, isLogLevel, type LogLevel } from \"./level.ts\";\nimport type { LogRecord } from \"./record.ts\";\nimport type { Sink } from \"./sink.ts\";\n\nexport type ScopedConfigSymbol = typeof scopedConfigSymbol;\n\nexport const scopedConfigSymbol: unique symbol = Symbol.for(\n \"logtape.scopedConfig\",\n);\n\nexport interface ScopedConfigLike<\n TSinkId extends string,\n TFilterId extends string,\n> {\n readonly sinks: Record<TSinkId, Sink>;\n readonly filters?: Record<TFilterId, FilterLike>;\n readonly loggers: readonly ScopedLoggerConfigLike<TSinkId, TFilterId>[];\n}\n\nexport interface ScopedLoggerConfigLike<\n TSinkId extends string,\n TFilterId extends string,\n> {\n readonly category: string | readonly string[];\n readonly sinks?: readonly TSinkId[];\n readonly parentSinks?: \"inherit\" | \"override\";\n readonly filters?: readonly TFilterId[];\n readonly lowestLevel?: LogLevel | null;\n}\n\nexport interface CompiledScopedConfig {\n readonly nodes: ReadonlyMap<string, CompiledScopedLogger>;\n readonly dispatchCache: Map<string, ScopedSinkDispatchPlan>;\n parent: CompiledScopedConfig | undefined;\n disposed: boolean;\n readonly syncFilters: Set<Disposable>;\n readonly asyncFilters: Set<AsyncDisposable>;\n readonly syncSinks: Set<Disposable>;\n readonly asyncSinks: Set<AsyncDisposable>;\n}\n\ninterface CompiledScopedLogger {\n readonly filters: readonly ((record: LogRecord) => boolean)[];\n readonly lowestLevel: LogLevel | null;\n readonly parentSinks: \"inherit\" | \"override\";\n readonly sinks: readonly Sink[];\n}\n\ntype ScopedSinkDispatchPlan =\n | { readonly kind: \"none\" }\n | { readonly kind: \"one\"; readonly sink: Sink }\n | { readonly kind: \"many\"; readonly sinks: readonly Sink[] };\n\nconst defaultScopedLogger: CompiledScopedLogger = {\n filters: [],\n lowestLevel: \"trace\",\n parentSinks: \"inherit\",\n sinks: [],\n};\n\nexport function compileScopedConfig<\n TSinkId extends string,\n TFilterId extends string,\n>(\n config: ScopedConfigLike<TSinkId, TFilterId>,\n allowAsync: boolean,\n createError: (message: string) => Error,\n): CompiledScopedConfig {\n if (!isObjectLike(config)) {\n throw createError(\"Configuration must be an object.\");\n }\n if (!isObjectLike(config.sinks)) {\n throw createError(\"Configuration must include a sinks object.\");\n }\n if (!Array.isArray(config.loggers)) {\n throw createError(\"Configuration must include a loggers array.\");\n }\n\n const nodes = new Map<string, CompiledScopedLogger>();\n const configuredCategories = new Set<string>();\n for (const logger of config.loggers) {\n if (!isObjectLike(logger)) {\n throw createError(\"Logger configuration must be an object.\");\n }\n const loggerConfig = logger as ScopedLoggerConfigLike<TSinkId, TFilterId>;\n const category = normalizeCategory(loggerConfig.category, createError);\n if (\n loggerConfig.sinks !== undefined && !Array.isArray(loggerConfig.sinks)\n ) {\n throw createError(\"Logger sinks must be an array.\");\n }\n if (\n loggerConfig.filters !== undefined &&\n !Array.isArray(loggerConfig.filters)\n ) {\n throw createError(\"Logger filters must be an array.\");\n }\n if (\n loggerConfig.parentSinks !== undefined &&\n loggerConfig.parentSinks !== \"inherit\" &&\n loggerConfig.parentSinks !== \"override\"\n ) {\n throw createError(\n 'Logger parentSinks must be \"inherit\" or \"override\".',\n );\n }\n if (\n loggerConfig.lowestLevel !== undefined &&\n loggerConfig.lowestLevel !== null &&\n !isLogLevel(loggerConfig.lowestLevel)\n ) {\n throw createError(\"Logger lowestLevel must be a log level or null.\");\n }\n const key = categoryKey(category);\n if (configuredCategories.has(key)) {\n throw createError(\n `Duplicate logger configuration for category: ${key}. ` +\n \"Each category can only be configured once.\",\n );\n }\n configuredCategories.add(key);\n\n const sinks: Sink[] = [];\n const sinkIds: readonly TSinkId[] = loggerConfig.sinks ?? [];\n for (const sinkId of sinkIds) {\n const sink = config.sinks[sinkId];\n if (!sink) throw createError(`Sink not found: ${sinkId}.`);\n if (typeof sink !== \"function\") {\n throw createError(`Sink must be a function: ${sinkId}.`);\n }\n sinks.push(sink);\n }\n\n const filters: ((record: LogRecord) => boolean)[] = [];\n const filterIds: readonly TFilterId[] = loggerConfig.filters ?? [];\n for (const filterId of filterIds) {\n const filter = config.filters?.[filterId];\n if (filter === undefined) {\n throw createError(`Filter not found: ${filterId}.`);\n }\n if (!isFilterLike(filter)) {\n throw createError(\n `Filter must be a function, log level, or null: ${filterId}.`,\n );\n }\n filters.push(toFilter(filter));\n }\n\n nodes.set(key, {\n filters,\n lowestLevel: loggerConfig.lowestLevel === undefined\n ? \"trace\"\n : loggerConfig.lowestLevel,\n parentSinks: loggerConfig.parentSinks ?? \"inherit\",\n sinks,\n });\n }\n\n const syncFilters = new Set<Disposable>();\n const asyncFilters = new Set<AsyncDisposable>();\n const syncSinks = new Set<Disposable>();\n const asyncSinks = new Set<AsyncDisposable>();\n\n for (const sink of Object.values<Sink>(config.sinks)) {\n if (!isObjectLike(sink)) continue;\n if (Symbol.asyncDispose in sink) {\n if (!allowAsync) {\n throw createError(\n \"Async disposables cannot be used with withConfigSync().\",\n );\n }\n asyncSinks.add(sink as AsyncDisposable);\n } else if (Symbol.dispose in sink) syncSinks.add(sink as Disposable);\n }\n\n for (const filter of Object.values<FilterLike>(config.filters ?? {})) {\n if (!isObjectLike(filter)) continue;\n if (Symbol.asyncDispose in filter) {\n if (!allowAsync) {\n throw createError(\n \"Async disposables cannot be used with withConfigSync().\",\n );\n }\n asyncFilters.add(filter as AsyncDisposable);\n asyncSinks.delete(filter as AsyncDisposable);\n } else if (Symbol.dispose in filter) {\n syncFilters.add(filter as Disposable);\n syncSinks.delete(filter as Disposable);\n }\n }\n\n return {\n asyncFilters,\n asyncSinks,\n dispatchCache: new Map(),\n disposed: false,\n nodes,\n parent: undefined,\n syncFilters,\n syncSinks,\n };\n}\n\nexport function getCurrentScopedConfig(\n contextLocalStorage:\n | ContextLocalStorage<Record<string, unknown>>\n | undefined,\n): CompiledScopedConfig | undefined {\n const store = contextLocalStorage?.getStore();\n const scopedConfig = (store as Record<ScopedConfigSymbol, unknown> | null)\n ?.[scopedConfigSymbol];\n return isCompiledScopedConfig(scopedConfig)\n ? getActiveScopedConfig(scopedConfig)\n : undefined;\n}\n\nexport function runWithScopedConfig<R>(\n contextLocalStorage: ContextLocalStorage<Record<string, unknown>>,\n scopedConfig: CompiledScopedConfig,\n callback: () => R,\n): R {\n const parentStore = contextLocalStorage.getStore() ?? {};\n scopedConfig.parent = getCurrentScopedConfig(contextLocalStorage);\n return contextLocalStorage.run({\n ...parentStore,\n [scopedConfigSymbol]: scopedConfig,\n } as Record<string, unknown>, callback);\n}\n\nexport function scopedConfigHasSink(\n scopedConfig: CompiledScopedConfig,\n category: readonly string[],\n level: LogLevel,\n): boolean {\n return getScopedSinkDispatchPlan(scopedConfig, category, level).kind !==\n \"none\";\n}\n\nexport function emitWithScopedConfig(\n scopedConfig: CompiledScopedConfig,\n record: LogRecord,\n bypassSinks: Set<Sink> | undefined,\n emitToSink: (sink: Sink, bypassSinks: Set<Sink> | undefined) => void,\n): void {\n const plan = getScopedSinkDispatchPlan(\n scopedConfig,\n record.category,\n record.level,\n );\n if (plan.kind === \"none\") return;\n if (!filterScopedRecord(scopedConfig, record.category, record)) return;\n if (plan.kind === \"one\") {\n if (!bypassSinks?.has(plan.sink)) emitToSink(plan.sink, bypassSinks);\n return;\n }\n for (const sink of plan.sinks) {\n if (bypassSinks?.has(sink)) continue;\n emitToSink(sink, bypassSinks);\n }\n}\n\nexport async function disposeScopedConfig(\n scopedConfig: CompiledScopedConfig,\n retainedDisposables?: ReadonlySet<Disposable | AsyncDisposable>,\n): Promise<void> {\n const parentDisposables = getParentScopedDisposables(\n scopedConfig,\n retainedDisposables,\n );\n scopedConfig.disposed = true;\n const errors: unknown[] = [];\n try {\n disposeSyncDisposables(scopedConfig.syncFilters, parentDisposables);\n } catch (error) {\n errors.push(error);\n }\n try {\n await disposeAsyncDisposables(scopedConfig.asyncFilters, parentDisposables);\n } catch (error) {\n errors.push(error);\n }\n try {\n disposeSyncDisposables(scopedConfig.syncSinks, parentDisposables);\n } catch (error) {\n errors.push(error);\n }\n try {\n await disposeAsyncDisposables(scopedConfig.asyncSinks, parentDisposables);\n } catch (error) {\n errors.push(error);\n }\n throwDisposeErrors(errors);\n}\n\nexport function disposeScopedConfigSync(\n scopedConfig: CompiledScopedConfig,\n retainedDisposables?: ReadonlySet<Disposable | AsyncDisposable>,\n): void {\n const parentDisposables = getParentScopedDisposables(\n scopedConfig,\n retainedDisposables,\n );\n scopedConfig.disposed = true;\n const errors: unknown[] = [];\n try {\n disposeSyncDisposables(scopedConfig.syncFilters, parentDisposables);\n } catch (error) {\n errors.push(error);\n }\n try {\n disposeSyncDisposables(scopedConfig.syncSinks, parentDisposables);\n } catch (error) {\n errors.push(error);\n }\n throwDisposeErrors(errors);\n}\n\nexport function throwCombinedErrors(\n primary: unknown,\n secondary: unknown,\n): never {\n throw new AggregateError(\n flattenErrors(primary, secondary),\n \"Multiple errors occurred while running LogTape scoped configuration.\",\n );\n}\n\nfunction isCompiledScopedConfig(value: unknown): value is CompiledScopedConfig {\n return value != null && typeof value === \"object\" && \"nodes\" in value;\n}\n\nfunction isObjectLike(\n value: unknown,\n): value is object | ((...args: never[]) => unknown) {\n return value != null &&\n (typeof value === \"object\" || typeof value === \"function\");\n}\n\nfunction isFilterLike(value: unknown): value is FilterLike {\n return value == null || typeof value === \"function\" ||\n (typeof value === \"string\" && isLogLevel(value));\n}\n\nfunction getActiveScopedConfig(\n scopedConfig: CompiledScopedConfig,\n): CompiledScopedConfig | undefined {\n let activeConfig: CompiledScopedConfig | undefined = scopedConfig;\n while (activeConfig?.disposed) activeConfig = activeConfig.parent;\n return activeConfig;\n}\n\nfunction getParentScopedDisposables(\n scopedConfig: CompiledScopedConfig,\n extraRetained?: ReadonlySet<Disposable | AsyncDisposable>,\n): ReadonlySet<Disposable | AsyncDisposable> {\n const disposables = new Set<Disposable | AsyncDisposable>(extraRetained);\n let parent = scopedConfig.parent;\n while (parent != null) {\n const activeParent = getActiveScopedConfig(parent);\n if (activeParent == null) break;\n addScopedDisposables(disposables, activeParent);\n parent = activeParent.parent;\n }\n return disposables;\n}\n\nfunction addScopedDisposables(\n disposables: Set<Disposable | AsyncDisposable>,\n scopedConfig: CompiledScopedConfig,\n): void {\n for (const disposable of scopedConfig.syncFilters) {\n disposables.add(disposable);\n }\n for (const disposable of scopedConfig.asyncFilters) {\n disposables.add(disposable);\n }\n for (const disposable of scopedConfig.syncSinks) disposables.add(disposable);\n for (const disposable of scopedConfig.asyncSinks) disposables.add(disposable);\n}\n\nfunction normalizeCategory(\n category: unknown,\n createError: (message: string) => Error,\n): string[] {\n if (typeof category === \"string\") return [category];\n if (!Array.isArray(category)) {\n throw createError(\"Logger category must be a string or array of strings.\");\n }\n if (category.some((part) => typeof part !== \"string\")) {\n throw createError(\"Logger category must only contain strings.\");\n }\n return [...category];\n}\n\nfunction categoryKey(category: readonly string[]): string {\n return JSON.stringify(category);\n}\n\nfunction getScopedSinkDispatchPlan(\n scopedConfig: CompiledScopedConfig,\n category: readonly string[],\n level: LogLevel,\n): ScopedSinkDispatchPlan {\n const cacheKey = `${categoryKey(category)}:${level}`;\n let plan = scopedConfig.dispatchCache.get(cacheKey);\n if (plan == null) {\n plan = getScopedSinkDispatchPlanForPrefix(\n scopedConfig,\n category,\n category.length,\n level,\n );\n scopedConfig.dispatchCache.set(cacheKey, plan);\n }\n return plan;\n}\n\nfunction getScopedSinkDispatchPlanForPrefix(\n scopedConfig: CompiledScopedConfig,\n category: readonly string[],\n length: number,\n level: LogLevel,\n): ScopedSinkDispatchPlan {\n const prefix = category.slice(0, length);\n const logger = scopedConfig.nodes.get(categoryKey(prefix)) ??\n defaultScopedLogger;\n if (\n logger.lowestLevel === null ||\n compareLogLevel(level, logger.lowestLevel) < 0\n ) {\n return { kind: \"none\" };\n }\n\n const parentPlan = length > 0 && logger.parentSinks === \"inherit\"\n ? getScopedSinkDispatchPlanForPrefix(\n scopedConfig,\n category,\n length - 1,\n level,\n )\n : { kind: \"none\" } as const;\n\n let firstSink: Sink | undefined;\n let sinks: Sink[] | undefined;\n const appendSink = (sink: Sink): void => {\n if (sinks != null) {\n sinks.push(sink);\n } else if (firstSink == null) {\n firstSink = sink;\n } else {\n sinks = [firstSink, sink];\n }\n };\n\n if (parentPlan.kind === \"one\") appendSink(parentPlan.sink);\n else if (parentPlan.kind === \"many\") {\n for (const sink of parentPlan.sinks) appendSink(sink);\n }\n for (const sink of logger.sinks) appendSink(sink);\n\n if (sinks != null) return { kind: \"many\", sinks };\n if (firstSink != null) return { kind: \"one\", sink: firstSink };\n return { kind: \"none\" };\n}\n\nfunction filterScopedRecord(\n scopedConfig: CompiledScopedConfig,\n category: readonly string[],\n record: LogRecord,\n): boolean {\n for (let length = category.length; length >= 0; length--) {\n const logger = scopedConfig.nodes.get(\n categoryKey(category.slice(0, length)),\n );\n if (logger == null || logger.filters.length < 1) continue;\n return logger.filters.every((filter) => filter(record));\n }\n return true;\n}\n\nfunction disposeSyncDisposables(\n disposables: Set<Disposable>,\n retainedDisposables: ReadonlySet<Disposable | AsyncDisposable>,\n): void {\n const disposableList = filterRetainedDisposables(\n disposables,\n retainedDisposables,\n );\n const errors: unknown[] = [];\n try {\n for (const disposable of disposableList) {\n try {\n disposable[Symbol.dispose]();\n } catch (error) {\n errors.push(error);\n }\n }\n } finally {\n disposables.clear();\n }\n throwDisposeErrors(errors);\n}\n\nasync function disposeAsyncDisposables(\n disposables: Set<AsyncDisposable>,\n retainedDisposables: ReadonlySet<Disposable | AsyncDisposable>,\n): Promise<void> {\n const disposableList = filterRetainedDisposables(\n disposables,\n retainedDisposables,\n );\n for (const disposable of disposableList) disposables.delete(disposable);\n try {\n const results = await Promise.allSettled(\n disposableList.map((disposable) =>\n Promise.resolve().then(() => disposable[Symbol.asyncDispose]())\n ),\n );\n throwDisposeErrors(\n results\n .filter((result): result is PromiseRejectedResult =>\n result.status === \"rejected\"\n )\n .map((result) => result.reason),\n );\n } finally {\n disposables.clear();\n }\n}\n\nfunction filterRetainedDisposables<\n TDisposable extends Disposable | AsyncDisposable,\n>(\n disposables: ReadonlySet<TDisposable>,\n retainedDisposables: ReadonlySet<Disposable | AsyncDisposable>,\n): TDisposable[] {\n return Array.from(\n disposables,\n ).filter((disposable) => !retainedDisposables.has(disposable));\n}\n\nfunction throwDisposeErrors(errors: readonly unknown[]): void {\n if (errors.length < 1) return;\n if (errors.length === 1) throw errors[0];\n throw new AggregateError(\n errors,\n \"Multiple errors occurred while disposing LogTape scoped resources.\",\n );\n}\n\nfunction flattenErrors(...errors: readonly unknown[]): unknown[] {\n const flattened: unknown[] = [];\n for (const error of errors) {\n if (error instanceof AggregateError) flattened.push(...error.errors);\n else flattened.push(error);\n }\n return flattened;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"scoped-config.js","names":["scopedConfigSymbol: unique symbol","defaultScopedLogger: CompiledScopedLogger","config: ScopedConfigLike<TSinkId, TFilterId>","allowAsync: boolean","createError: (message: string) => Error","sinks: Sink[]","sinkIds: readonly TSinkId[]","filters: ((record: LogRecord) => boolean)[]","filterIds: readonly TFilterId[]","contextLocalStorage:\n | ContextLocalStorage<Record<string, unknown>>\n | undefined","contextLocalStorage: ContextLocalStorage<Record<string, unknown>>","scopedConfig: CompiledScopedConfig","callback: () => R","category: readonly string[]","level: LogLevel","record: LogRecord","bypassSinks: Set<Sink> | undefined","emitToSink: (sink: Sink, bypassSinks: Set<Sink> | undefined) => void","retainedDisposables?: ReadonlySet<Disposable | AsyncDisposable>","errors: unknown[]","primary: unknown","secondary: unknown","value: unknown","activeConfig: CompiledScopedConfig | undefined","extraRetained?: ReadonlySet<Disposable | AsyncDisposable>","disposables: Set<Disposable | AsyncDisposable>","category: unknown","length: number","firstSink: Sink | undefined","sinks: Sink[] | undefined","sink: Sink","disposables: Set<Disposable>","retainedDisposables: ReadonlySet<Disposable | AsyncDisposable>","disposables: Set<AsyncDisposable>","disposables: ReadonlySet<TDisposable>","errors: readonly unknown[]","flattened: unknown[]"],"sources":["../src/scoped-config.ts"],"sourcesContent":["import type { ContextLocalStorage } from \"./context.ts\";\nimport { type FilterLike, toFilter } from \"./filter.ts\";\nimport { compareLogLevel, isLogLevel, type LogLevel } from \"./level.ts\";\nimport type { LogRecord } from \"./record.ts\";\nimport type { Sink } from \"./sink.ts\";\n\nexport type ScopedConfigSymbol = typeof scopedConfigSymbol;\n\nexport const scopedConfigSymbol: unique symbol = Symbol.for(\n \"logtape.scopedConfig\",\n);\n\nexport interface ScopedConfigLike<\n TSinkId extends string,\n TFilterId extends string,\n> {\n readonly sinks: Record<TSinkId, Sink>;\n readonly filters?: Record<TFilterId, FilterLike>;\n readonly loggers: readonly ScopedLoggerConfigLike<TSinkId, TFilterId>[];\n}\n\nexport interface ScopedLoggerConfigLike<\n TSinkId extends string,\n TFilterId extends string,\n> {\n readonly category: string | readonly string[];\n readonly sinks?: readonly TSinkId[];\n readonly parentSinks?: \"inherit\" | \"override\";\n readonly filters?: readonly TFilterId[];\n readonly lowestLevel?: LogLevel | null;\n}\n\nexport interface CompiledScopedConfig {\n readonly nodes: ReadonlyMap<string, CompiledScopedLogger>;\n readonly dispatchCache: Map<string, ScopedSinkDispatchPlan>;\n parent: CompiledScopedConfig | undefined;\n disposed: boolean;\n readonly syncFilters: Set<Disposable>;\n readonly asyncFilters: Set<AsyncDisposable>;\n readonly syncSinks: Set<Disposable>;\n readonly asyncSinks: Set<AsyncDisposable>;\n}\n\ninterface CompiledScopedLogger {\n readonly filters: readonly ((record: LogRecord) => boolean)[];\n readonly lowestLevel: LogLevel | null;\n readonly parentSinks: \"inherit\" | \"override\";\n readonly sinks: readonly Sink[];\n}\n\ntype ScopedSinkDispatchPlan =\n | { readonly kind: \"none\" }\n | { readonly kind: \"one\"; readonly sink: Sink }\n | { readonly kind: \"many\"; readonly sinks: readonly Sink[] };\n\nconst defaultScopedLogger: CompiledScopedLogger = {\n filters: [],\n lowestLevel: \"trace\",\n parentSinks: \"inherit\",\n sinks: [],\n};\n\nexport function compileScopedConfig<\n TSinkId extends string,\n TFilterId extends string,\n>(\n config: ScopedConfigLike<TSinkId, TFilterId>,\n allowAsync: boolean,\n createError: (message: string) => Error,\n): CompiledScopedConfig {\n if (!isObjectLike(config)) {\n throw createError(\"Configuration must be an object.\");\n }\n if (!isObjectLike(config.sinks)) {\n throw createError(\"Configuration must include a sinks object.\");\n }\n if (!Array.isArray(config.loggers)) {\n throw createError(\"Configuration must include a loggers array.\");\n }\n if (config.filters !== undefined && !isObjectLike(config.filters)) {\n throw createError(\"Configuration filters must be an object.\");\n }\n\n const nodes = new Map<string, CompiledScopedLogger>();\n const configuredCategories = new Set<string>();\n for (const logger of config.loggers) {\n if (!isObjectLike(logger)) {\n throw createError(\"Logger configuration must be an object.\");\n }\n const loggerConfig = logger as ScopedLoggerConfigLike<TSinkId, TFilterId>;\n const category = normalizeCategory(loggerConfig.category, createError);\n if (\n loggerConfig.sinks !== undefined && !Array.isArray(loggerConfig.sinks)\n ) {\n throw createError(\"Logger sinks must be an array.\");\n }\n if (\n loggerConfig.filters !== undefined &&\n !Array.isArray(loggerConfig.filters)\n ) {\n throw createError(\"Logger filters must be an array.\");\n }\n if (\n loggerConfig.parentSinks !== undefined &&\n loggerConfig.parentSinks !== \"inherit\" &&\n loggerConfig.parentSinks !== \"override\"\n ) {\n throw createError(\n 'Logger parentSinks must be \"inherit\" or \"override\".',\n );\n }\n if (\n loggerConfig.lowestLevel !== undefined &&\n loggerConfig.lowestLevel !== null &&\n !isLogLevel(loggerConfig.lowestLevel)\n ) {\n throw createError(\"Logger lowestLevel must be a log level or null.\");\n }\n const key = categoryKey(category);\n if (configuredCategories.has(key)) {\n throw createError(\n `Duplicate logger configuration for category: ${key}. ` +\n \"Each category can only be configured once.\",\n );\n }\n configuredCategories.add(key);\n\n const sinks: Sink[] = [];\n const sinkIds: readonly TSinkId[] = loggerConfig.sinks ?? [];\n for (const sinkId of sinkIds) {\n const sink = config.sinks[sinkId];\n if (!sink) throw createError(`Sink not found: ${sinkId}.`);\n if (typeof sink !== \"function\") {\n throw createError(`Sink must be a function: ${sinkId}.`);\n }\n sinks.push(sink);\n }\n\n const filters: ((record: LogRecord) => boolean)[] = [];\n const filterIds: readonly TFilterId[] = loggerConfig.filters ?? [];\n for (const filterId of filterIds) {\n const filter = config.filters?.[filterId];\n if (filter === undefined) {\n throw createError(`Filter not found: ${filterId}.`);\n }\n if (!isFilterLike(filter)) {\n throw createError(\n `Filter must be a function, log level, or null: ${filterId}.`,\n );\n }\n filters.push(toFilter(filter));\n }\n\n nodes.set(key, {\n filters,\n lowestLevel: loggerConfig.lowestLevel === undefined\n ? \"trace\"\n : loggerConfig.lowestLevel,\n parentSinks: loggerConfig.parentSinks ?? \"inherit\",\n sinks,\n });\n }\n\n const syncFilters = new Set<Disposable>();\n const asyncFilters = new Set<AsyncDisposable>();\n const syncSinks = new Set<Disposable>();\n const asyncSinks = new Set<AsyncDisposable>();\n\n for (const sink of Object.values<Sink>(config.sinks)) {\n if (!isObjectLike(sink)) continue;\n if (Symbol.asyncDispose in sink) {\n if (!allowAsync) {\n throw createError(\n \"Async disposables cannot be used with withConfigSync().\",\n );\n }\n asyncSinks.add(sink as AsyncDisposable);\n } else if (Symbol.dispose in sink) syncSinks.add(sink as Disposable);\n }\n\n for (const filter of Object.values<FilterLike>(config.filters ?? {})) {\n if (!isObjectLike(filter)) continue;\n if (Symbol.asyncDispose in filter) {\n if (!allowAsync) {\n throw createError(\n \"Async disposables cannot be used with withConfigSync().\",\n );\n }\n asyncFilters.add(filter as AsyncDisposable);\n asyncSinks.delete(filter as AsyncDisposable);\n } else if (Symbol.dispose in filter) {\n syncFilters.add(filter as Disposable);\n syncSinks.delete(filter as Disposable);\n }\n }\n\n return {\n asyncFilters,\n asyncSinks,\n dispatchCache: new Map(),\n disposed: false,\n nodes,\n parent: undefined,\n syncFilters,\n syncSinks,\n };\n}\n\nexport function getCurrentScopedConfig(\n contextLocalStorage:\n | ContextLocalStorage<Record<string, unknown>>\n | undefined,\n): CompiledScopedConfig | undefined {\n const store = contextLocalStorage?.getStore();\n const scopedConfig = (store as Record<ScopedConfigSymbol, unknown> | null)\n ?.[scopedConfigSymbol];\n return isCompiledScopedConfig(scopedConfig)\n ? getActiveScopedConfig(scopedConfig)\n : undefined;\n}\n\nexport function runWithScopedConfig<R>(\n contextLocalStorage: ContextLocalStorage<Record<string, unknown>>,\n scopedConfig: CompiledScopedConfig,\n callback: () => R,\n): R {\n const parentStore = contextLocalStorage.getStore() ?? {};\n scopedConfig.parent = getCurrentScopedConfig(contextLocalStorage);\n return contextLocalStorage.run({\n ...parentStore,\n [scopedConfigSymbol]: scopedConfig,\n } as Record<string, unknown>, callback);\n}\n\nexport function scopedConfigHasSink(\n scopedConfig: CompiledScopedConfig,\n category: readonly string[],\n level: LogLevel,\n): boolean {\n return getScopedSinkDispatchPlan(scopedConfig, category, level).kind !==\n \"none\";\n}\n\nexport function emitWithScopedConfig(\n scopedConfig: CompiledScopedConfig,\n record: LogRecord,\n bypassSinks: Set<Sink> | undefined,\n emitToSink: (sink: Sink, bypassSinks: Set<Sink> | undefined) => void,\n): void {\n const plan = getScopedSinkDispatchPlan(\n scopedConfig,\n record.category,\n record.level,\n );\n if (plan.kind === \"none\") return;\n if (!filterScopedRecord(scopedConfig, record.category, record)) return;\n if (plan.kind === \"one\") {\n if (!bypassSinks?.has(plan.sink)) emitToSink(plan.sink, bypassSinks);\n return;\n }\n for (const sink of plan.sinks) {\n if (bypassSinks?.has(sink)) continue;\n emitToSink(sink, bypassSinks);\n }\n}\n\nexport async function disposeScopedConfig(\n scopedConfig: CompiledScopedConfig,\n retainedDisposables?: ReadonlySet<Disposable | AsyncDisposable>,\n): Promise<void> {\n const parentDisposables = getParentScopedDisposables(\n scopedConfig,\n retainedDisposables,\n );\n scopedConfig.disposed = true;\n const errors: unknown[] = [];\n try {\n disposeSyncDisposables(scopedConfig.syncFilters, parentDisposables);\n } catch (error) {\n errors.push(error);\n }\n try {\n await disposeAsyncDisposables(scopedConfig.asyncFilters, parentDisposables);\n } catch (error) {\n errors.push(error);\n }\n try {\n disposeSyncDisposables(scopedConfig.syncSinks, parentDisposables);\n } catch (error) {\n errors.push(error);\n }\n try {\n await disposeAsyncDisposables(scopedConfig.asyncSinks, parentDisposables);\n } catch (error) {\n errors.push(error);\n }\n throwDisposeErrors(errors);\n}\n\nexport function disposeScopedConfigSync(\n scopedConfig: CompiledScopedConfig,\n retainedDisposables?: ReadonlySet<Disposable | AsyncDisposable>,\n): void {\n const parentDisposables = getParentScopedDisposables(\n scopedConfig,\n retainedDisposables,\n );\n scopedConfig.disposed = true;\n const errors: unknown[] = [];\n try {\n disposeSyncDisposables(scopedConfig.syncFilters, parentDisposables);\n } catch (error) {\n errors.push(error);\n }\n try {\n disposeSyncDisposables(scopedConfig.syncSinks, parentDisposables);\n } catch (error) {\n errors.push(error);\n }\n throwDisposeErrors(errors);\n}\n\nexport function throwCombinedErrors(\n primary: unknown,\n secondary: unknown,\n): never {\n throw new AggregateError(\n flattenErrors(primary, secondary),\n \"Multiple errors occurred while running LogTape scoped configuration.\",\n );\n}\n\nfunction isCompiledScopedConfig(value: unknown): value is CompiledScopedConfig {\n return value != null && typeof value === \"object\" && \"nodes\" in value;\n}\n\nfunction isObjectLike(\n value: unknown,\n): value is object | ((...args: never[]) => unknown) {\n return value != null &&\n (typeof value === \"object\" || typeof value === \"function\");\n}\n\nfunction isFilterLike(value: unknown): value is FilterLike {\n return value == null || typeof value === \"function\" ||\n (typeof value === \"string\" && isLogLevel(value));\n}\n\nfunction getActiveScopedConfig(\n scopedConfig: CompiledScopedConfig,\n): CompiledScopedConfig | undefined {\n let activeConfig: CompiledScopedConfig | undefined = scopedConfig;\n while (activeConfig?.disposed) activeConfig = activeConfig.parent;\n return activeConfig;\n}\n\nfunction getParentScopedDisposables(\n scopedConfig: CompiledScopedConfig,\n extraRetained?: ReadonlySet<Disposable | AsyncDisposable>,\n): ReadonlySet<Disposable | AsyncDisposable> {\n const disposables = new Set<Disposable | AsyncDisposable>(extraRetained);\n let parent = scopedConfig.parent;\n while (parent != null) {\n const activeParent = getActiveScopedConfig(parent);\n if (activeParent == null) break;\n addScopedDisposables(disposables, activeParent);\n parent = activeParent.parent;\n }\n return disposables;\n}\n\nfunction addScopedDisposables(\n disposables: Set<Disposable | AsyncDisposable>,\n scopedConfig: CompiledScopedConfig,\n): void {\n for (const disposable of scopedConfig.syncFilters) {\n disposables.add(disposable);\n }\n for (const disposable of scopedConfig.asyncFilters) {\n disposables.add(disposable);\n }\n for (const disposable of scopedConfig.syncSinks) disposables.add(disposable);\n for (const disposable of scopedConfig.asyncSinks) disposables.add(disposable);\n}\n\nfunction normalizeCategory(\n category: unknown,\n createError: (message: string) => Error,\n): string[] {\n if (typeof category === \"string\") return [category];\n if (!Array.isArray(category)) {\n throw createError(\"Logger category must be a string or array of strings.\");\n }\n if (category.some((part) => typeof part !== \"string\")) {\n throw createError(\"Logger category must only contain strings.\");\n }\n return [...category];\n}\n\nfunction categoryKey(category: readonly string[]): string {\n return JSON.stringify(category);\n}\n\nfunction getScopedSinkDispatchPlan(\n scopedConfig: CompiledScopedConfig,\n category: readonly string[],\n level: LogLevel,\n): ScopedSinkDispatchPlan {\n const cacheKey = `${categoryKey(category)}:${level}`;\n let plan = scopedConfig.dispatchCache.get(cacheKey);\n if (plan == null) {\n plan = getScopedSinkDispatchPlanForPrefix(\n scopedConfig,\n category,\n category.length,\n level,\n );\n scopedConfig.dispatchCache.set(cacheKey, plan);\n }\n return plan;\n}\n\nfunction getScopedSinkDispatchPlanForPrefix(\n scopedConfig: CompiledScopedConfig,\n category: readonly string[],\n length: number,\n level: LogLevel,\n): ScopedSinkDispatchPlan {\n const prefix = category.slice(0, length);\n const logger = scopedConfig.nodes.get(categoryKey(prefix)) ??\n defaultScopedLogger;\n if (\n logger.lowestLevel === null ||\n compareLogLevel(level, logger.lowestLevel) < 0\n ) {\n return { kind: \"none\" };\n }\n\n const parentPlan = length > 0 && logger.parentSinks === \"inherit\"\n ? getScopedSinkDispatchPlanForPrefix(\n scopedConfig,\n category,\n length - 1,\n level,\n )\n : { kind: \"none\" } as const;\n\n let firstSink: Sink | undefined;\n let sinks: Sink[] | undefined;\n const appendSink = (sink: Sink): void => {\n if (sinks != null) {\n sinks.push(sink);\n } else if (firstSink == null) {\n firstSink = sink;\n } else {\n sinks = [firstSink, sink];\n }\n };\n\n if (parentPlan.kind === \"one\") appendSink(parentPlan.sink);\n else if (parentPlan.kind === \"many\") {\n for (const sink of parentPlan.sinks) appendSink(sink);\n }\n for (const sink of logger.sinks) appendSink(sink);\n\n if (sinks != null) return { kind: \"many\", sinks };\n if (firstSink != null) return { kind: \"one\", sink: firstSink };\n return { kind: \"none\" };\n}\n\nfunction filterScopedRecord(\n scopedConfig: CompiledScopedConfig,\n category: readonly string[],\n record: LogRecord,\n): boolean {\n for (let length = category.length; length >= 0; length--) {\n const logger = scopedConfig.nodes.get(\n categoryKey(category.slice(0, length)),\n );\n if (logger == null || logger.filters.length < 1) continue;\n return logger.filters.every((filter) => filter(record));\n }\n return true;\n}\n\nfunction disposeSyncDisposables(\n disposables: Set<Disposable>,\n retainedDisposables: ReadonlySet<Disposable | AsyncDisposable>,\n): void {\n const disposableList = filterRetainedDisposables(\n disposables,\n retainedDisposables,\n );\n const errors: unknown[] = [];\n try {\n for (const disposable of disposableList) {\n try {\n disposable[Symbol.dispose]();\n } catch (error) {\n errors.push(error);\n }\n }\n } finally {\n disposables.clear();\n }\n throwDisposeErrors(errors);\n}\n\nasync function disposeAsyncDisposables(\n disposables: Set<AsyncDisposable>,\n retainedDisposables: ReadonlySet<Disposable | AsyncDisposable>,\n): Promise<void> {\n const disposableList = filterRetainedDisposables(\n disposables,\n retainedDisposables,\n );\n for (const disposable of disposableList) disposables.delete(disposable);\n try {\n const results = await Promise.allSettled(\n disposableList.map((disposable) =>\n Promise.resolve().then(() => disposable[Symbol.asyncDispose]())\n ),\n );\n throwDisposeErrors(\n results\n .filter((result): result is PromiseRejectedResult =>\n result.status === \"rejected\"\n )\n .map((result) => result.reason),\n );\n } finally {\n disposables.clear();\n }\n}\n\nfunction filterRetainedDisposables<\n TDisposable extends Disposable | AsyncDisposable,\n>(\n disposables: ReadonlySet<TDisposable>,\n retainedDisposables: ReadonlySet<Disposable | AsyncDisposable>,\n): TDisposable[] {\n return Array.from(\n disposables,\n ).filter((disposable) => !retainedDisposables.has(disposable));\n}\n\nfunction throwDisposeErrors(errors: readonly unknown[]): void {\n if (errors.length < 1) return;\n if (errors.length === 1) throw errors[0];\n throw new AggregateError(\n errors,\n \"Multiple errors occurred while disposing LogTape scoped resources.\",\n );\n}\n\nfunction flattenErrors(...errors: readonly unknown[]): unknown[] {\n const flattened: unknown[] = [];\n for (const error of errors) {\n if (error instanceof AggregateError) flattened.push(...error.errors);\n else flattened.push(error);\n }\n return flattened;\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED