@logtape/logtape 2.4.0-dev.865 → 2.4.0-dev.879
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/config.d.cts +15 -5
- package/dist/config.d.cts.map +1 -1
- package/dist/config.d.ts +15 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/logger.cjs +37 -3
- package/dist/logger.d.cts.map +1 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +37 -3
- package/dist/logger.js.map +1 -1
- package/dist/scoped-config.cjs +20 -2
- package/dist/scoped-config.d.cts +1 -1
- package/dist/scoped-config.d.cts.map +1 -1
- package/dist/scoped-config.d.ts +1 -1
- package/dist/scoped-config.d.ts.map +1 -1
- package/dist/scoped-config.js +20 -2
- package/dist/scoped-config.js.map +1 -1
- package/package.json +1 -1
package/dist/config.d.cts
CHANGED
|
@@ -60,16 +60,26 @@ interface LoggerConfig<TSinkId extends string, TFilterId extends string> {
|
|
|
60
60
|
*/
|
|
61
61
|
sinks?: TSinkId[];
|
|
62
62
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
63
|
+
* How to combine the logger's sinks with its ancestors' sinks.
|
|
64
|
+
*
|
|
65
|
+
* If `inherit`, the sinks that the parent would use for a record's level
|
|
66
|
+
* are used along with the specified sinks. The parent's `lowestLevel`
|
|
67
|
+
* continues to apply to the inherited sinks.
|
|
68
|
+
*
|
|
69
|
+
* If `override`, only the specified sinks are used.
|
|
70
|
+
*
|
|
71
|
+
* If `forward`, every ancestor's configured sinks are used along with the
|
|
72
|
+
* specified sinks, ignoring each ancestor's `lowestLevel` (including
|
|
73
|
+
* `null`); only this logger's own `lowestLevel` applies. An ancestor
|
|
74
|
+
* configured with `parentSinks: "override"` forms a boundary: its own
|
|
75
|
+
* sinks are still inherited, but nothing beyond it. Repeated references
|
|
76
|
+
* to the same sink are not deduplicated. Available since 2.4.0.
|
|
67
77
|
*
|
|
68
78
|
* The default is `inherit`.
|
|
69
79
|
* @default "inherit"
|
|
70
80
|
* @since 0.6.0
|
|
71
81
|
*/
|
|
72
|
-
parentSinks?: "inherit" | "override";
|
|
82
|
+
parentSinks?: "inherit" | "override" | "forward";
|
|
73
83
|
/**
|
|
74
84
|
* The filter identifiers to use. If no filters are specified, the logger
|
|
75
85
|
* uses the filters from the nearest ancestor that has them. Specifying one
|
package/dist/config.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.cts","names":[],"sources":["../src/config.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;AAkBA;AAAuB,UAAN,MAAM,CAAA,gBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,CAAA;EAAA;;;;EAUK,KAAE,EALrB,MAKqB,CALd,OAKc,EALL,IAKK,CAAA;EAAU;;;;EAKjB,OAMqB,CAAA,EAXhC,MAWgC,CAXzB,SAWyB,EAXd,UAWc,CAAA;EAAM;AAAP;AAkB3C;EAAwB,OAAA,EAxBb,YAwBa,CAxBA,OAwBA,EAxBS,SAwBT,CAAA,EAAA;EAAA;;;AACN;EAEb,mBAAA,CAAA,EArBmB,mBAqBD,CArBqB,MAqBrB,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA;EAAA;;;EAAuC,KAC1D,CAAA,EAAA,OAAA;AAAO;AAKX;;;;;
|
|
1
|
+
{"version":3,"file":"config.d.cts","names":[],"sources":["../src/config.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;AAkBA;AAAuB,UAAN,MAAM,CAAA,gBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,CAAA;EAAA;;;;EAUK,KAAE,EALrB,MAKqB,CALd,OAKc,EALL,IAKK,CAAA;EAAU;;;;EAKjB,OAMqB,CAAA,EAXhC,MAWgC,CAXzB,SAWyB,EAXd,UAWc,CAAA;EAAM;AAAP;AAkB3C;EAAwB,OAAA,EAxBb,YAwBa,CAxBA,OAwBA,EAxBS,SAwBT,CAAA,EAAA;EAAA;;;AACN;EAEb,mBAAA,CAAA,EArBmB,mBAqBD,CArBqB,MAqBrB,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA;EAAA;;;EAAuC,KAC1D,CAAA,EAAA,OAAA;AAAO;AAKX;;;;;AAkDwB;AAkJxB;;;;AAGU,KAhNE,YAgNF,CAAA,gBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,GA/MR,gBA+MQ,CA/MS,OA+MT,EA/MkB,SA+MlB,CAAA;KA7ML,kBA6MkC,CAAA,OAAA,CAAA,GA7MJ,OA6MI,SA7MY,WA6MZ,CAAA,OAAA,CAAA,GAAA,KAAA,GA5MnC,OA4MmC;AAAO;AAsD9C;;AACiB,UA9PA,YA8PA,CAAA,gBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,CAAA;EAAO;;AAAR;AAyChB;EAAgC,QAAA,EAAA,MAAA,GAAA,MAAA,EAAA;EAAA;;;EAKV,KACJ,CAAA,EAhSR,OAgSQ,EAAA;EAAO;;;AACf;AAsDV;;;;;;;;;AAOqB;AAiMrB;AAOA;AAYA;AAoBA;AAkCA;AAoKA;;;;;;;;YA9uBY;;;;;;gBAOI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkJM,oEAGZ,OAAO,SAAS,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsDvB,wEACN,OAAO,SAAS;;;;;;;;;;;;;;iBAyCJ,8EAKZ,aAAa,SAAS,4BACd,UACf,QAAQ,QAAQ;;;;;;;;;;;;iBAsDH,kFAKN,aAAa,SAAS,4BACd,mBAAmB,WAClC,mBAAmB;;;;;iBAiMN,SAAA,CAAA,GAAa;;;;iBAOP,KAAA,CAAA,GAAS;;;;;;iBAYf,SAAA,CAAA;;;;iBAoBM,OAAA,CAAA,GAAW;;;;;;iBAkCjB,WAAA,CAAA;;;;cAoKH,WAAA,SAAoB,KAAK"}
|
package/dist/config.d.ts
CHANGED
|
@@ -60,16 +60,26 @@ interface LoggerConfig<TSinkId extends string, TFilterId extends string> {
|
|
|
60
60
|
*/
|
|
61
61
|
sinks?: TSinkId[];
|
|
62
62
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
63
|
+
* How to combine the logger's sinks with its ancestors' sinks.
|
|
64
|
+
*
|
|
65
|
+
* If `inherit`, the sinks that the parent would use for a record's level
|
|
66
|
+
* are used along with the specified sinks. The parent's `lowestLevel`
|
|
67
|
+
* continues to apply to the inherited sinks.
|
|
68
|
+
*
|
|
69
|
+
* If `override`, only the specified sinks are used.
|
|
70
|
+
*
|
|
71
|
+
* If `forward`, every ancestor's configured sinks are used along with the
|
|
72
|
+
* specified sinks, ignoring each ancestor's `lowestLevel` (including
|
|
73
|
+
* `null`); only this logger's own `lowestLevel` applies. An ancestor
|
|
74
|
+
* configured with `parentSinks: "override"` forms a boundary: its own
|
|
75
|
+
* sinks are still inherited, but nothing beyond it. Repeated references
|
|
76
|
+
* to the same sink are not deduplicated. Available since 2.4.0.
|
|
67
77
|
*
|
|
68
78
|
* The default is `inherit`.
|
|
69
79
|
* @default "inherit"
|
|
70
80
|
* @since 0.6.0
|
|
71
81
|
*/
|
|
72
|
-
parentSinks?: "inherit" | "override";
|
|
82
|
+
parentSinks?: "inherit" | "override" | "forward";
|
|
73
83
|
/**
|
|
74
84
|
* The filter identifiers to use. If no filters are specified, the logger
|
|
75
85
|
* uses the filters from the nearest ancestor that has them. Specifying one
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","names":[],"sources":["../src/config.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;AAkBA;AAAuB,UAAN,MAAM,CAAA,gBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,CAAA;EAAA;;;;EAUK,KAAE,EALrB,MAKqB,CALd,OAKc,EALL,IAKK,CAAA;EAAU;;;;EAKjB,OAMqB,CAAA,EAXhC,MAWgC,CAXzB,SAWyB,EAXd,UAWc,CAAA;EAAM;AAAP;AAkB3C;EAAwB,OAAA,EAxBb,YAwBa,CAxBA,OAwBA,EAxBS,SAwBT,CAAA,EAAA;EAAA;;;AACN;EAEb,mBAAA,CAAA,EArBmB,mBAqBD,CArBqB,MAqBrB,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA;EAAA;;;EAAuC,KAC1D,CAAA,EAAA,OAAA;AAAO;AAKX;;;;;
|
|
1
|
+
{"version":3,"file":"config.d.ts","names":[],"sources":["../src/config.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;AAkBA;AAAuB,UAAN,MAAM,CAAA,gBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,CAAA;EAAA;;;;EAUK,KAAE,EALrB,MAKqB,CALd,OAKc,EALL,IAKK,CAAA;EAAU;;;;EAKjB,OAMqB,CAAA,EAXhC,MAWgC,CAXzB,SAWyB,EAXd,UAWc,CAAA;EAAM;AAAP;AAkB3C;EAAwB,OAAA,EAxBb,YAwBa,CAxBA,OAwBA,EAxBS,SAwBT,CAAA,EAAA;EAAA;;;AACN;EAEb,mBAAA,CAAA,EArBmB,mBAqBD,CArBqB,MAqBrB,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA;EAAA;;;EAAuC,KAC1D,CAAA,EAAA,OAAA;AAAO;AAKX;;;;;AAkDwB;AAkJxB;;;;AAGU,KAhNE,YAgNF,CAAA,gBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,GA/MR,gBA+MQ,CA/MS,OA+MT,EA/MkB,SA+MlB,CAAA;KA7ML,kBA6MkC,CAAA,OAAA,CAAA,GA7MJ,OA6MI,SA7MY,WA6MZ,CAAA,OAAA,CAAA,GAAA,KAAA,GA5MnC,OA4MmC;AAAO;AAsD9C;;AACiB,UA9PA,YA8PA,CAAA,gBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,CAAA;EAAO;;AAAR;AAyChB;EAAgC,QAAA,EAAA,MAAA,GAAA,MAAA,EAAA;EAAA;;;EAKV,KACJ,CAAA,EAhSR,OAgSQ,EAAA;EAAO;;;AACf;AAsDV;;;;;;;;;AAOqB;AAiMrB;AAOA;AAYA;AAoBA;AAkCA;AAoKA;;;;;;;;YA9uBY;;;;;;gBAOI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkJM,oEAGZ,OAAO,SAAS,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsDvB,wEACN,OAAO,SAAS;;;;;;;;;;;;;;iBAyCJ,8EAKZ,aAAa,SAAS,4BACd,UACf,QAAQ,QAAQ;;;;;;;;;;;;iBAsDH,kFAKN,aAAa,SAAS,4BACd,mBAAmB,WAClC,mBAAmB;;;;;iBAiMN,SAAA,CAAA,GAAa;;;;iBAOP,KAAA,CAAA,GAAS;;;;;;iBAYf,SAAA,CAAA;;;;iBAoBM,OAAA,CAAA,GAAW;;;;;;iBAkCjB,WAAA,CAAA;;;;cAoKH,WAAA,SAAoB,KAAK"}
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","names":["currentConfig: Config<string, string> | null","activeScopedConfigs: Set<CompiledScopedConfig>","strongRefs: Set<LoggerImpl>","filterDisposables: Set<Disposable>","sinkDisposables: Set<Disposable>","asyncFilterDisposables: Set<AsyncDisposable>","asyncSinkDisposables: Set<AsyncDisposable>","unregisterDisposeHook: (() => void) | undefined","cfg: LoggerConfig<TSinkId, TFilterId>","allowAsync: boolean","config: Config<TSinkId, TFilterId>","config: ScopedConfig<TSinkId, TFilterId>","callback: () => TResult","result: Awaited<TResult>","callbackError: unknown","callback: () => SyncCallbackResult<TResult>","result: SyncCallbackResult<TResult>","value: unknown","scopedConfig: CompiledScopedConfig","disposables: Set<Disposable | AsyncDisposable>","errors: unknown[]","functionName: string","callback: () => Promise<T>","callback: () => T","disposables: Set<Disposable>","disposables: Set<AsyncDisposable>","promises: PromiseLike<void>[]","promises: readonly PromiseLike<void>[]","errors: readonly unknown[]","message: string"],"sources":["../src/config.ts"],"sourcesContent":["import type { ContextLocalStorage } from \"./context.ts\";\nimport { type FilterLike, toFilter } from \"./filter.ts\";\nimport type { LogLevel } from \"./level.ts\";\nimport { LoggerImpl } from \"./logger.ts\";\nimport {\n type CompiledScopedConfig,\n compileScopedConfig,\n disposeScopedConfig,\n disposeScopedConfigSync,\n runWithScopedConfig,\n type ScopedConfigLike,\n throwCombinedErrors,\n} from \"./scoped-config.ts\";\nimport { getConsoleSink, type Sink } from \"./sink.ts\";\n\n/**\n * A configuration for the loggers.\n */\nexport interface Config<TSinkId extends string, TFilterId extends string> {\n /**\n * The sinks to use. The keys are the sink identifiers, and the values are\n * {@link Sink}s.\n */\n sinks: Record<TSinkId, Sink>;\n /**\n * The filters to use. The keys are the filter identifiers, and the values\n * are either {@link Filter}s or {@link LogLevel}s.\n */\n filters?: Record<TFilterId, FilterLike>;\n\n /**\n * The loggers to configure.\n */\n loggers: LoggerConfig<TSinkId, TFilterId>[];\n\n /**\n * The context-local storage to use for implicit contexts.\n * @since 0.7.0\n */\n contextLocalStorage?: ContextLocalStorage<Record<string, unknown>>;\n\n /**\n * Whether to reset the configuration before applying this one.\n */\n reset?: boolean;\n}\n\n/**\n * A scoped configuration for the current execution context.\n *\n * Unlike {@link Config}, this type does not include `reset` or\n * `contextLocalStorage`. Scoped configuration changes only the logging policy\n * for a callback; the context-local storage must already be initialized by the\n * process-global configuration.\n *\n * @since 2.3.0\n */\nexport type ScopedConfig<TSinkId extends string, TFilterId extends string> =\n ScopedConfigLike<TSinkId, TFilterId>;\n\ntype SyncCallbackResult<TResult> = TResult extends PromiseLike<unknown> ? never\n : TResult;\n\n/**\n * A logger configuration.\n */\nexport interface LoggerConfig<\n TSinkId extends string,\n TFilterId extends string,\n> {\n /**\n * The category of the logger. If a string, it is equivalent to an array\n * with one element.\n */\n category: string | string[];\n\n /**\n * The sink identifiers to use.\n */\n sinks?: TSinkId[];\n\n /**\n * Whether to inherit the sinks that the parent would use for a record's\n * level. If `inherit`, those sinks are used along with the specified sinks.\n * The parent's `lowestLevel` continues to apply to the inherited sinks. If\n * `override`, only the specified sinks are used.\n *\n * The default is `inherit`.\n * @default \"inherit\"\n * @since 0.6.0\n */\n parentSinks?: \"inherit\" | \"override\";\n\n /**\n * The filter identifiers to use. If no filters are specified, the logger\n * uses the filters from the nearest ancestor that has them. Specifying one\n * or more filters replaces the inherited filters instead of combining with\n * them.\n */\n filters?: TFilterId[];\n\n /**\n * The lowest log level to accept. If `null`, the logger will reject all\n * records.\n * @since 0.8.0\n */\n lowestLevel?: LogLevel | null;\n}\n\n/**\n * The current configuration, if any. Otherwise, `null`.\n */\nlet currentConfig: Config<string, string> | null = null;\nlet activeScopedConfigCount = 0;\nconst activeScopedConfigs: Set<CompiledScopedConfig> = new Set();\nlet globalConfigMutationInProgress = false;\n\n/**\n * Strong references to the loggers.\n * This is to prevent the loggers from being garbage collected so that their\n * sinks and filters are not removed.\n */\nconst strongRefs: Set<LoggerImpl> = new Set();\n\n/**\n * Sync filter disposables to dispose when resetting the configuration.\n */\nconst filterDisposables: Set<Disposable> = new Set();\n\n/**\n * Sync sink disposables to dispose when resetting the configuration.\n */\nconst sinkDisposables: Set<Disposable> = new Set();\n\n/**\n * Async filter disposables to dispose when resetting the configuration.\n */\nconst asyncFilterDisposables: Set<AsyncDisposable> = new Set();\n\n/**\n * Async sink disposables to dispose when resetting the configuration.\n */\nconst asyncSinkDisposables: Set<AsyncDisposable> = new Set();\n\nlet unregisterDisposeHook: (() => void) | undefined;\n\n/**\n * Check if a config is for the meta logger.\n */\nfunction isLoggerConfigMeta<TSinkId extends string, TFilterId extends string>(\n cfg: LoggerConfig<TSinkId, TFilterId>,\n): boolean {\n const category = Array.isArray(cfg.category) ? cfg.category : [cfg.category];\n return category.length === 0 ||\n (category.length === 1 && category[0] === \"logtape\") ||\n (category.length === 2 &&\n category[0] === \"logtape\" &&\n category[1] === \"meta\");\n}\n\nfunction registerDisposeHook(allowAsync: boolean): void {\n unregisterDisposeHook?.();\n unregisterDisposeHook = undefined;\n\n const handler = allowAsync ? disposeInternal : disposeSyncInternal;\n\n if (\n // deno-lint-ignore no-explicit-any\n typeof (globalThis as any).EdgeRuntime !== \"string\" &&\n \"process\" in globalThis &&\n !(\"Deno\" in globalThis)\n ) {\n // deno-lint-ignore no-explicit-any\n const proc = (globalThis as any).process;\n // Use bracket notation to avoid static analysis detection in Edge Runtime.\n const onMethod = proc?.[\"on\"];\n if (typeof onMethod === \"function\") {\n onMethod.call(proc, \"exit\", handler);\n unregisterDisposeHook = () => {\n const offMethod = proc?.[\"off\"] ?? proc?.[\"removeListener\"];\n if (typeof offMethod === \"function\") {\n offMethod.call(proc, \"exit\", handler);\n }\n };\n return;\n }\n }\n\n // Some edge runtimes expose neither process.on() nor addEventListener().\n // In those environments users can still call dispose()/disposeSync() manually.\n // deno-lint-ignore no-explicit-any\n const addEventListenerMethod = (globalThis as any).addEventListener;\n if (typeof addEventListenerMethod !== \"function\") return;\n // deno-lint-ignore no-explicit-any\n const removeEventListenerMethod = (globalThis as any).removeEventListener;\n\n if (\"Deno\" in globalThis) {\n addEventListenerMethod.call(globalThis, \"unload\", handler);\n if (typeof removeEventListenerMethod === \"function\") {\n unregisterDisposeHook = () => {\n removeEventListenerMethod.call(globalThis, \"unload\", handler);\n };\n }\n } else {\n addEventListenerMethod.call(globalThis, \"pagehide\", handler);\n if (typeof removeEventListenerMethod === \"function\") {\n unregisterDisposeHook = () => {\n removeEventListenerMethod.call(globalThis, \"pagehide\", handler);\n };\n }\n }\n}\n\n/**\n * Configure the loggers with the specified configuration.\n *\n * Note that if the given sinks or filters are disposable, they will be\n * disposed when the configuration is reset, or when the process exits.\n *\n * @example\n * ```typescript\n * await configure({\n * sinks: {\n * console: getConsoleSink(),\n * },\n * filters: {\n * slow: (log) =>\n * \"duration\" in log.properties &&\n * log.properties.duration as number > 1000,\n * },\n * loggers: [\n * {\n * category: \"my-app\",\n * sinks: [\"console\"],\n * lowestLevel: \"info\",\n * },\n * {\n * category: [\"my-app\", \"sql\"],\n * filters: [\"slow\"],\n * lowestLevel: \"debug\",\n * },\n * {\n * category: \"logtape\",\n * sinks: [\"console\"],\n * lowestLevel: \"error\",\n * },\n * ],\n * });\n * ```\n *\n * @param config The configuration.\n */\nexport async function configure<\n TSinkId extends string,\n TFilterId extends string,\n>(config: Config<TSinkId, TFilterId>): Promise<void> {\n await runGlobalConfigMutation(\"configure()\", async () => {\n if (currentConfig != null && !config.reset) {\n throw new ConfigError(\n \"Already configured; if you want to reset, turn on the reset flag.\",\n );\n }\n await disposeInternal();\n resetInternal();\n try {\n configureInternal(config, true);\n } catch (e) {\n if (e instanceof ConfigError) {\n await disposeInternal();\n resetInternal();\n }\n throw e;\n }\n });\n}\n\n/**\n * Configure sync loggers with the specified configuration.\n *\n * Note that if the given sinks or filters are disposable, they will be\n * disposed when the configuration is reset, or when the process exits.\n *\n * Also note that passing async sinks or filters will throw. If\n * necessary use {@link resetSync} or {@link disposeSync}.\n *\n * @example\n * ```typescript\n * configureSync({\n * sinks: {\n * console: getConsoleSink(),\n * },\n * loggers: [\n * {\n * category: \"my-app\",\n * sinks: [\"console\"],\n * lowestLevel: \"info\",\n * },\n * {\n * category: \"logtape\",\n * sinks: [\"console\"],\n * lowestLevel: \"error\",\n * },\n * ],\n * });\n * ```\n *\n * @param config The configuration.\n * @since 0.9.0\n */\nexport function configureSync<TSinkId extends string, TFilterId extends string>(\n config: Config<TSinkId, TFilterId>,\n): void {\n runGlobalConfigMutationSync(\"configureSync()\", () => {\n if (currentConfig != null && !config.reset) {\n throw new ConfigError(\n \"Already configured; if you want to reset, turn on the reset flag.\",\n );\n }\n if (asyncFilterDisposables.size > 0 || asyncSinkDisposables.size > 0) {\n throw new ConfigError(\n \"Previously configured async disposables are still active. \" +\n \"Use configure() instead or explicitly dispose them using dispose().\",\n );\n }\n disposeSyncInternal();\n resetInternal();\n try {\n configureInternal(config, false);\n } catch (e) {\n if (e instanceof ConfigError) {\n disposeSyncInternal();\n resetInternal();\n }\n throw e;\n }\n });\n}\n\n/**\n * Runs a callback with a LogTape configuration scoped to the current execution\n * context.\n *\n * The process-global configuration must already provide\n * `contextLocalStorage`. The scoped configuration fully overrides global\n * logger routing while the callback and its async work run.\n *\n * @param config The scoped configuration.\n * @param callback The callback to run.\n * @returns The callback's resolved return value.\n * @since 2.3.0\n */\nexport async function withConfig<\n TSinkId extends string,\n TFilterId extends string,\n TResult,\n>(\n config: ScopedConfig<TSinkId, TFilterId>,\n callback: () => TResult,\n): Promise<Awaited<TResult>> {\n const contextLocalStorage = getConfiguredContextLocalStorage(\"withConfig()\");\n const scopedConfig = compileScopedConfig(\n config,\n true,\n (message) => new ConfigError(message),\n );\n\n let result: Awaited<TResult>;\n let callbackError: unknown;\n let callbackFailed = false;\n activeScopedConfigCount++;\n activeScopedConfigs.add(scopedConfig);\n try {\n result = await runWithScopedConfig(\n contextLocalStorage,\n scopedConfig,\n callback,\n );\n } catch (error) {\n callbackFailed = true;\n callbackError = error;\n }\n\n try {\n await disposeScopedConfig(\n scopedConfig,\n getRetainedDisposables(scopedConfig),\n );\n } catch (disposeError) {\n if (callbackFailed) {\n throwCombinedErrors(callbackError, disposeError);\n }\n throw disposeError;\n } finally {\n activeScopedConfigs.delete(scopedConfig);\n activeScopedConfigCount--;\n }\n\n if (callbackFailed) throw callbackError;\n return result!;\n}\n\n/**\n * Runs a synchronous callback with a LogTape configuration scoped to the\n * current execution context.\n *\n * The scoped configuration must not contain async disposable sinks or filters.\n *\n * @param config The scoped configuration.\n * @param callback The callback to run.\n * @returns The callback's return value.\n * @since 2.3.0\n */\nexport function withConfigSync<\n TSinkId extends string,\n TFilterId extends string,\n TResult,\n>(\n config: ScopedConfig<TSinkId, TFilterId>,\n callback: () => SyncCallbackResult<TResult>,\n): SyncCallbackResult<TResult> {\n const contextLocalStorage = getConfiguredContextLocalStorage(\n \"withConfigSync()\",\n );\n const scopedConfig = compileScopedConfig(\n config,\n false,\n (message) => new ConfigError(message),\n );\n\n let result: SyncCallbackResult<TResult>;\n let callbackError: unknown;\n let callbackFailed = false;\n activeScopedConfigCount++;\n activeScopedConfigs.add(scopedConfig);\n try {\n result = runWithScopedConfig(contextLocalStorage, scopedConfig, callback);\n if (isThenable(result)) {\n void Promise.resolve(result).catch(() => {});\n callbackFailed = true;\n callbackError = new ConfigError(\n \"withConfigSync() callback must not return a promise. \" +\n \"Use withConfig() for async callbacks.\",\n );\n }\n } catch (error) {\n callbackFailed = true;\n callbackError = error;\n }\n\n try {\n disposeScopedConfigSync(scopedConfig, getRetainedDisposables(scopedConfig));\n } catch (disposeError) {\n if (callbackFailed) {\n throwCombinedErrors(callbackError, disposeError);\n }\n throw disposeError;\n } finally {\n activeScopedConfigs.delete(scopedConfig);\n activeScopedConfigCount--;\n }\n\n if (callbackFailed) throw callbackError;\n return result!;\n}\n\nfunction isThenable(value: unknown): value is PromiseLike<unknown> {\n return value != null &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n \"then\" in value &&\n typeof value.then === \"function\";\n}\n\nfunction getGlobalDisposables(): ReadonlySet<Disposable | AsyncDisposable> {\n return new Set<Disposable | AsyncDisposable>([\n ...filterDisposables,\n ...asyncFilterDisposables,\n ...sinkDisposables,\n ...asyncSinkDisposables,\n ]);\n}\n\nfunction getRetainedDisposables(\n scopedConfig: CompiledScopedConfig,\n): ReadonlySet<Disposable | AsyncDisposable> {\n const disposables = new Set<Disposable | AsyncDisposable>(\n getGlobalDisposables(),\n );\n for (const activeScopedConfig of activeScopedConfigs) {\n if (activeScopedConfig === scopedConfig || activeScopedConfig.disposed) {\n continue;\n }\n addScopedConfigDisposables(disposables, activeScopedConfig);\n }\n return disposables;\n}\n\nfunction addScopedConfigDisposables(\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 configureInternal<\n TSinkId extends string,\n TFilterId extends string,\n>(config: Config<TSinkId, TFilterId>, allowAsync: boolean): void {\n currentConfig = config;\n\n let metaConfigured = false;\n const configuredCategories = new Set<string>();\n\n for (const cfg of config.loggers) {\n if (isLoggerConfigMeta(cfg)) {\n metaConfigured = true;\n }\n\n // Check for duplicate logger categories\n const categoryKey = Array.isArray(cfg.category)\n ? JSON.stringify(cfg.category)\n : JSON.stringify([cfg.category]);\n if (configuredCategories.has(categoryKey)) {\n throw new ConfigError(\n `Duplicate logger configuration for category: ${categoryKey}. ` +\n `Each category can only be configured once.`,\n );\n }\n configuredCategories.add(categoryKey);\n\n const logger = LoggerImpl.getLogger(cfg.category);\n for (const sinkId of cfg.sinks ?? []) {\n const sink = config.sinks[sinkId];\n if (!sink) {\n throw new ConfigError(`Sink not found: ${sinkId}.`);\n }\n logger.sinks.push(sink);\n }\n logger.parentSinks = cfg.parentSinks ?? \"inherit\";\n if (cfg.lowestLevel !== undefined) {\n logger.lowestLevel = cfg.lowestLevel;\n }\n for (const filterId of cfg.filters ?? []) {\n const filter = config.filters?.[filterId];\n if (filter === undefined) {\n throw new ConfigError(`Filter not found: ${filterId}.`);\n }\n logger.filters.push(toFilter(filter));\n }\n strongRefs.add(logger);\n }\n\n LoggerImpl.getLogger().contextLocalStorage = config.contextLocalStorage;\n\n for (const sink of Object.values<Sink>(config.sinks)) {\n if (Symbol.asyncDispose in sink) {\n if (allowAsync) asyncSinkDisposables.add(sink as AsyncDisposable);\n else {\n throw new ConfigError(\n \"Async disposables cannot be used with configureSync().\",\n );\n }\n }\n if (Symbol.dispose in sink) sinkDisposables.add(sink as Disposable);\n }\n\n for (const filter of Object.values<FilterLike>(config.filters ?? {})) {\n if (filter == null || typeof filter === \"string\") continue;\n if (Symbol.asyncDispose in filter) {\n if (allowAsync) asyncFilterDisposables.add(filter as AsyncDisposable);\n else {\n throw new ConfigError(\n \"Async disposables cannot be used with configureSync().\",\n );\n }\n asyncSinkDisposables.delete(filter as AsyncDisposable);\n }\n if (Symbol.dispose in filter) {\n filterDisposables.add(filter as Disposable);\n sinkDisposables.delete(filter as Disposable);\n }\n }\n\n registerDisposeHook(allowAsync);\n const meta = LoggerImpl.getLogger([\"logtape\", \"meta\"]);\n if (!metaConfigured) {\n meta.sinks.push(getConsoleSink());\n }\n\n meta.info(\n \"LogTape loggers are configured. Note that LogTape itself uses the meta \" +\n \"logger, which has category {metaLoggerCategory}. The meta logger is \" +\n \"used to log internal diagnostics such as sink exceptions. \" +\n \"It's recommended to configure the meta logger with a separate sink \" +\n \"so that you can easily notice if logging itself fails or is \" +\n \"misconfigured. To turn off this message, configure the meta logger \" +\n \"with higher log levels than {dismissLevel}. See also \" +\n \"<https://logtape.org/manual/categories#meta-logger>.\",\n { metaLoggerCategory: [\"logtape\", \"meta\"], dismissLevel: \"info\" },\n );\n}\n\n/**\n * Get the current configuration, if any. Otherwise, `null`.\n * @returns The current configuration, if any. Otherwise, `null`.\n */\nexport function getConfig(): Config<string, string> | null {\n return currentConfig;\n}\n\n/**\n * Reset the configuration. Mostly for testing purposes.\n */\nexport async function reset(): Promise<void> {\n await runGlobalConfigMutation(\"reset()\", async () => {\n await disposeInternal();\n resetInternal();\n });\n}\n\n/**\n * Reset the configuration. Mostly for testing purposes. Will not clear async\n * sinks, only use with sync sinks. Use {@link reset} if you have async sinks.\n * @since 0.9.0\n */\nexport function resetSync(): void {\n runGlobalConfigMutationSync(\"resetSync()\", () => {\n disposeSyncInternal();\n resetInternal();\n });\n}\n\nfunction resetInternal(): void {\n unregisterDisposeHook?.();\n unregisterDisposeHook = undefined;\n const rootLogger = LoggerImpl.getLogger([]);\n rootLogger.resetDescendants();\n delete rootLogger.contextLocalStorage;\n strongRefs.clear();\n currentConfig = null;\n}\n\n/**\n * Dispose of the disposables.\n */\nexport async function dispose(): Promise<void> {\n await runGlobalConfigMutation(\"dispose()\", disposeInternal);\n}\n\nasync function disposeInternal(): Promise<void> {\n const errors: unknown[] = [];\n try {\n disposeSyncFilters();\n } catch (error) {\n errors.push(error);\n }\n try {\n await disposeAsyncFilters();\n } catch (error) {\n errors.push(error);\n }\n try {\n disposeSyncSinks();\n } catch (error) {\n errors.push(error);\n }\n try {\n await disposeAsyncSinks();\n } catch (error) {\n errors.push(error);\n }\n throwDisposeErrors(errors);\n}\n\n/**\n * Dispose of the sync disposables. Async disposables will be untouched,\n * use {@link dispose} if you have async sinks.\n * @since 0.9.0\n */\nexport function disposeSync(): void {\n runGlobalConfigMutationSync(\"disposeSync()\", disposeSyncInternal);\n}\n\nfunction disposeSyncInternal(): void {\n const errors: unknown[] = [];\n try {\n disposeSyncFilters();\n } catch (error) {\n errors.push(error);\n }\n try {\n disposeSyncSinks();\n } catch (error) {\n errors.push(error);\n }\n throwDisposeErrors(errors);\n}\n\nfunction getConfiguredContextLocalStorage(\n functionName: string,\n): ContextLocalStorage<Record<string, unknown>> {\n if (globalConfigMutationInProgress) {\n throw new ConfigError(\n `${functionName} cannot be called while LogTape is being reconfigured.`,\n );\n }\n if (currentConfig == null) {\n throw new ConfigError(\n `${functionName} requires LogTape to be configured first.`,\n );\n }\n const contextLocalStorage = LoggerImpl.getLogger().contextLocalStorage;\n if (contextLocalStorage == null) {\n throw new ConfigError(\n `${functionName} requires Config.contextLocalStorage to be configured.`,\n );\n }\n return contextLocalStorage;\n}\n\nasync function runGlobalConfigMutation<T>(\n functionName: string,\n callback: () => Promise<T>,\n): Promise<T> {\n assertCanMutateGlobalConfig(functionName);\n globalConfigMutationInProgress = true;\n try {\n return await callback();\n } finally {\n globalConfigMutationInProgress = false;\n }\n}\n\nfunction runGlobalConfigMutationSync<T>(\n functionName: string,\n callback: () => T,\n): T {\n assertCanMutateGlobalConfig(functionName);\n globalConfigMutationInProgress = true;\n try {\n return callback();\n } finally {\n globalConfigMutationInProgress = false;\n }\n}\n\nfunction assertCanMutateGlobalConfig(functionName: string): void {\n if (globalConfigMutationInProgress) {\n throw new ConfigError(\n `${functionName} cannot be called while LogTape is being reconfigured.`,\n );\n }\n assertNoScopedConfig(functionName);\n}\n\nfunction assertNoScopedConfig(functionName: string): void {\n if (activeScopedConfigCount > 0) {\n throw new ConfigError(\n `${functionName} cannot be called while a scoped configuration is ` +\n \"active. Use nested withConfig() instead.\",\n );\n }\n}\n\nfunction disposeSyncFilters(): void {\n disposeSyncDisposables(filterDisposables);\n}\n\nfunction disposeSyncSinks(): void {\n disposeSyncDisposables(sinkDisposables);\n}\n\nfunction disposeSyncDisposables(disposables: Set<Disposable>): void {\n const errors: unknown[] = [];\n try {\n for (const disposable of disposables) {\n try {\n disposable[Symbol.dispose]();\n } catch (error) {\n errors.push(error);\n } finally {\n disposables.delete(disposable);\n }\n }\n } finally {\n disposables.clear();\n }\n throwDisposeErrors(errors);\n}\n\nasync function disposeAsyncFilters(): Promise<void> {\n await disposeAsyncDisposables(asyncFilterDisposables);\n}\n\nasync function disposeAsyncSinks(): Promise<void> {\n await disposeAsyncDisposables(asyncSinkDisposables);\n}\n\nasync function disposeAsyncDisposables(\n disposables: Set<AsyncDisposable>,\n): Promise<void> {\n const promises: PromiseLike<void>[] = [];\n try {\n for (const disposable of disposables) {\n try {\n promises.push(Promise.resolve(disposable[Symbol.asyncDispose]()));\n } catch (error) {\n promises.push(Promise.reject(error));\n } finally {\n disposables.delete(disposable);\n }\n }\n } finally {\n disposables.clear();\n }\n await settleDisposePromises(promises);\n}\n\nasync function settleDisposePromises(\n promises: readonly PromiseLike<void>[],\n): Promise<void> {\n const results = await Promise.allSettled(promises);\n throwDisposeErrors(\n results\n .filter((result): result is PromiseRejectedResult =>\n result.status === \"rejected\"\n )\n .map((result) => result.reason),\n );\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 resources.\",\n );\n}\n\n/**\n * A configuration error.\n */\nexport class ConfigError extends Error {\n /**\n * Constructs a new configuration error.\n * @param message The error message.\n */\n constructor(message: string) {\n super(message);\n this.name = \"ConfigError\";\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"config.js","names":["currentConfig: Config<string, string> | null","activeScopedConfigs: Set<CompiledScopedConfig>","strongRefs: Set<LoggerImpl>","filterDisposables: Set<Disposable>","sinkDisposables: Set<Disposable>","asyncFilterDisposables: Set<AsyncDisposable>","asyncSinkDisposables: Set<AsyncDisposable>","unregisterDisposeHook: (() => void) | undefined","cfg: LoggerConfig<TSinkId, TFilterId>","allowAsync: boolean","config: Config<TSinkId, TFilterId>","config: ScopedConfig<TSinkId, TFilterId>","callback: () => TResult","result: Awaited<TResult>","callbackError: unknown","callback: () => SyncCallbackResult<TResult>","result: SyncCallbackResult<TResult>","value: unknown","scopedConfig: CompiledScopedConfig","disposables: Set<Disposable | AsyncDisposable>","errors: unknown[]","functionName: string","callback: () => Promise<T>","callback: () => T","disposables: Set<Disposable>","disposables: Set<AsyncDisposable>","promises: PromiseLike<void>[]","promises: readonly PromiseLike<void>[]","errors: readonly unknown[]","message: string"],"sources":["../src/config.ts"],"sourcesContent":["import type { ContextLocalStorage } from \"./context.ts\";\nimport { type FilterLike, toFilter } from \"./filter.ts\";\nimport type { LogLevel } from \"./level.ts\";\nimport { LoggerImpl } from \"./logger.ts\";\nimport {\n type CompiledScopedConfig,\n compileScopedConfig,\n disposeScopedConfig,\n disposeScopedConfigSync,\n runWithScopedConfig,\n type ScopedConfigLike,\n throwCombinedErrors,\n} from \"./scoped-config.ts\";\nimport { getConsoleSink, type Sink } from \"./sink.ts\";\n\n/**\n * A configuration for the loggers.\n */\nexport interface Config<TSinkId extends string, TFilterId extends string> {\n /**\n * The sinks to use. The keys are the sink identifiers, and the values are\n * {@link Sink}s.\n */\n sinks: Record<TSinkId, Sink>;\n /**\n * The filters to use. The keys are the filter identifiers, and the values\n * are either {@link Filter}s or {@link LogLevel}s.\n */\n filters?: Record<TFilterId, FilterLike>;\n\n /**\n * The loggers to configure.\n */\n loggers: LoggerConfig<TSinkId, TFilterId>[];\n\n /**\n * The context-local storage to use for implicit contexts.\n * @since 0.7.0\n */\n contextLocalStorage?: ContextLocalStorage<Record<string, unknown>>;\n\n /**\n * Whether to reset the configuration before applying this one.\n */\n reset?: boolean;\n}\n\n/**\n * A scoped configuration for the current execution context.\n *\n * Unlike {@link Config}, this type does not include `reset` or\n * `contextLocalStorage`. Scoped configuration changes only the logging policy\n * for a callback; the context-local storage must already be initialized by the\n * process-global configuration.\n *\n * @since 2.3.0\n */\nexport type ScopedConfig<TSinkId extends string, TFilterId extends string> =\n ScopedConfigLike<TSinkId, TFilterId>;\n\ntype SyncCallbackResult<TResult> = TResult extends PromiseLike<unknown> ? never\n : TResult;\n\n/**\n * A logger configuration.\n */\nexport interface LoggerConfig<\n TSinkId extends string,\n TFilterId extends string,\n> {\n /**\n * The category of the logger. If a string, it is equivalent to an array\n * with one element.\n */\n category: string | string[];\n\n /**\n * The sink identifiers to use.\n */\n sinks?: TSinkId[];\n\n /**\n * How to combine the logger's sinks with its ancestors' sinks.\n *\n * If `inherit`, the sinks that the parent would use for a record's level\n * are used along with the specified sinks. The parent's `lowestLevel`\n * continues to apply to the inherited sinks.\n *\n * If `override`, only the specified sinks are used.\n *\n * If `forward`, every ancestor's configured sinks are used along with the\n * specified sinks, ignoring each ancestor's `lowestLevel` (including\n * `null`); only this logger's own `lowestLevel` applies. An ancestor\n * configured with `parentSinks: \"override\"` forms a boundary: its own\n * sinks are still inherited, but nothing beyond it. Repeated references\n * to the same sink are not deduplicated. Available since 2.4.0.\n *\n * The default is `inherit`.\n * @default \"inherit\"\n * @since 0.6.0\n */\n parentSinks?: \"inherit\" | \"override\" | \"forward\";\n\n /**\n * The filter identifiers to use. If no filters are specified, the logger\n * uses the filters from the nearest ancestor that has them. Specifying one\n * or more filters replaces the inherited filters instead of combining with\n * them.\n */\n filters?: TFilterId[];\n\n /**\n * The lowest log level to accept. If `null`, the logger will reject all\n * records.\n * @since 0.8.0\n */\n lowestLevel?: LogLevel | null;\n}\n\n/**\n * The current configuration, if any. Otherwise, `null`.\n */\nlet currentConfig: Config<string, string> | null = null;\nlet activeScopedConfigCount = 0;\nconst activeScopedConfigs: Set<CompiledScopedConfig> = new Set();\nlet globalConfigMutationInProgress = false;\n\n/**\n * Strong references to the loggers.\n * This is to prevent the loggers from being garbage collected so that their\n * sinks and filters are not removed.\n */\nconst strongRefs: Set<LoggerImpl> = new Set();\n\n/**\n * Sync filter disposables to dispose when resetting the configuration.\n */\nconst filterDisposables: Set<Disposable> = new Set();\n\n/**\n * Sync sink disposables to dispose when resetting the configuration.\n */\nconst sinkDisposables: Set<Disposable> = new Set();\n\n/**\n * Async filter disposables to dispose when resetting the configuration.\n */\nconst asyncFilterDisposables: Set<AsyncDisposable> = new Set();\n\n/**\n * Async sink disposables to dispose when resetting the configuration.\n */\nconst asyncSinkDisposables: Set<AsyncDisposable> = new Set();\n\nlet unregisterDisposeHook: (() => void) | undefined;\n\n/**\n * Check if a config is for the meta logger.\n */\nfunction isLoggerConfigMeta<TSinkId extends string, TFilterId extends string>(\n cfg: LoggerConfig<TSinkId, TFilterId>,\n): boolean {\n const category = Array.isArray(cfg.category) ? cfg.category : [cfg.category];\n return category.length === 0 ||\n (category.length === 1 && category[0] === \"logtape\") ||\n (category.length === 2 &&\n category[0] === \"logtape\" &&\n category[1] === \"meta\");\n}\n\nfunction registerDisposeHook(allowAsync: boolean): void {\n unregisterDisposeHook?.();\n unregisterDisposeHook = undefined;\n\n const handler = allowAsync ? disposeInternal : disposeSyncInternal;\n\n if (\n // deno-lint-ignore no-explicit-any\n typeof (globalThis as any).EdgeRuntime !== \"string\" &&\n \"process\" in globalThis &&\n !(\"Deno\" in globalThis)\n ) {\n // deno-lint-ignore no-explicit-any\n const proc = (globalThis as any).process;\n // Use bracket notation to avoid static analysis detection in Edge Runtime.\n const onMethod = proc?.[\"on\"];\n if (typeof onMethod === \"function\") {\n onMethod.call(proc, \"exit\", handler);\n unregisterDisposeHook = () => {\n const offMethod = proc?.[\"off\"] ?? proc?.[\"removeListener\"];\n if (typeof offMethod === \"function\") {\n offMethod.call(proc, \"exit\", handler);\n }\n };\n return;\n }\n }\n\n // Some edge runtimes expose neither process.on() nor addEventListener().\n // In those environments users can still call dispose()/disposeSync() manually.\n // deno-lint-ignore no-explicit-any\n const addEventListenerMethod = (globalThis as any).addEventListener;\n if (typeof addEventListenerMethod !== \"function\") return;\n // deno-lint-ignore no-explicit-any\n const removeEventListenerMethod = (globalThis as any).removeEventListener;\n\n if (\"Deno\" in globalThis) {\n addEventListenerMethod.call(globalThis, \"unload\", handler);\n if (typeof removeEventListenerMethod === \"function\") {\n unregisterDisposeHook = () => {\n removeEventListenerMethod.call(globalThis, \"unload\", handler);\n };\n }\n } else {\n addEventListenerMethod.call(globalThis, \"pagehide\", handler);\n if (typeof removeEventListenerMethod === \"function\") {\n unregisterDisposeHook = () => {\n removeEventListenerMethod.call(globalThis, \"pagehide\", handler);\n };\n }\n }\n}\n\n/**\n * Configure the loggers with the specified configuration.\n *\n * Note that if the given sinks or filters are disposable, they will be\n * disposed when the configuration is reset, or when the process exits.\n *\n * @example\n * ```typescript\n * await configure({\n * sinks: {\n * console: getConsoleSink(),\n * },\n * filters: {\n * slow: (log) =>\n * \"duration\" in log.properties &&\n * log.properties.duration as number > 1000,\n * },\n * loggers: [\n * {\n * category: \"my-app\",\n * sinks: [\"console\"],\n * lowestLevel: \"info\",\n * },\n * {\n * category: [\"my-app\", \"sql\"],\n * filters: [\"slow\"],\n * lowestLevel: \"debug\",\n * },\n * {\n * category: \"logtape\",\n * sinks: [\"console\"],\n * lowestLevel: \"error\",\n * },\n * ],\n * });\n * ```\n *\n * @param config The configuration.\n */\nexport async function configure<\n TSinkId extends string,\n TFilterId extends string,\n>(config: Config<TSinkId, TFilterId>): Promise<void> {\n await runGlobalConfigMutation(\"configure()\", async () => {\n if (currentConfig != null && !config.reset) {\n throw new ConfigError(\n \"Already configured; if you want to reset, turn on the reset flag.\",\n );\n }\n await disposeInternal();\n resetInternal();\n try {\n configureInternal(config, true);\n } catch (e) {\n if (e instanceof ConfigError) {\n await disposeInternal();\n resetInternal();\n }\n throw e;\n }\n });\n}\n\n/**\n * Configure sync loggers with the specified configuration.\n *\n * Note that if the given sinks or filters are disposable, they will be\n * disposed when the configuration is reset, or when the process exits.\n *\n * Also note that passing async sinks or filters will throw. If\n * necessary use {@link resetSync} or {@link disposeSync}.\n *\n * @example\n * ```typescript\n * configureSync({\n * sinks: {\n * console: getConsoleSink(),\n * },\n * loggers: [\n * {\n * category: \"my-app\",\n * sinks: [\"console\"],\n * lowestLevel: \"info\",\n * },\n * {\n * category: \"logtape\",\n * sinks: [\"console\"],\n * lowestLevel: \"error\",\n * },\n * ],\n * });\n * ```\n *\n * @param config The configuration.\n * @since 0.9.0\n */\nexport function configureSync<TSinkId extends string, TFilterId extends string>(\n config: Config<TSinkId, TFilterId>,\n): void {\n runGlobalConfigMutationSync(\"configureSync()\", () => {\n if (currentConfig != null && !config.reset) {\n throw new ConfigError(\n \"Already configured; if you want to reset, turn on the reset flag.\",\n );\n }\n if (asyncFilterDisposables.size > 0 || asyncSinkDisposables.size > 0) {\n throw new ConfigError(\n \"Previously configured async disposables are still active. \" +\n \"Use configure() instead or explicitly dispose them using dispose().\",\n );\n }\n disposeSyncInternal();\n resetInternal();\n try {\n configureInternal(config, false);\n } catch (e) {\n if (e instanceof ConfigError) {\n disposeSyncInternal();\n resetInternal();\n }\n throw e;\n }\n });\n}\n\n/**\n * Runs a callback with a LogTape configuration scoped to the current execution\n * context.\n *\n * The process-global configuration must already provide\n * `contextLocalStorage`. The scoped configuration fully overrides global\n * logger routing while the callback and its async work run.\n *\n * @param config The scoped configuration.\n * @param callback The callback to run.\n * @returns The callback's resolved return value.\n * @since 2.3.0\n */\nexport async function withConfig<\n TSinkId extends string,\n TFilterId extends string,\n TResult,\n>(\n config: ScopedConfig<TSinkId, TFilterId>,\n callback: () => TResult,\n): Promise<Awaited<TResult>> {\n const contextLocalStorage = getConfiguredContextLocalStorage(\"withConfig()\");\n const scopedConfig = compileScopedConfig(\n config,\n true,\n (message) => new ConfigError(message),\n );\n\n let result: Awaited<TResult>;\n let callbackError: unknown;\n let callbackFailed = false;\n activeScopedConfigCount++;\n activeScopedConfigs.add(scopedConfig);\n try {\n result = await runWithScopedConfig(\n contextLocalStorage,\n scopedConfig,\n callback,\n );\n } catch (error) {\n callbackFailed = true;\n callbackError = error;\n }\n\n try {\n await disposeScopedConfig(\n scopedConfig,\n getRetainedDisposables(scopedConfig),\n );\n } catch (disposeError) {\n if (callbackFailed) {\n throwCombinedErrors(callbackError, disposeError);\n }\n throw disposeError;\n } finally {\n activeScopedConfigs.delete(scopedConfig);\n activeScopedConfigCount--;\n }\n\n if (callbackFailed) throw callbackError;\n return result!;\n}\n\n/**\n * Runs a synchronous callback with a LogTape configuration scoped to the\n * current execution context.\n *\n * The scoped configuration must not contain async disposable sinks or filters.\n *\n * @param config The scoped configuration.\n * @param callback The callback to run.\n * @returns The callback's return value.\n * @since 2.3.0\n */\nexport function withConfigSync<\n TSinkId extends string,\n TFilterId extends string,\n TResult,\n>(\n config: ScopedConfig<TSinkId, TFilterId>,\n callback: () => SyncCallbackResult<TResult>,\n): SyncCallbackResult<TResult> {\n const contextLocalStorage = getConfiguredContextLocalStorage(\n \"withConfigSync()\",\n );\n const scopedConfig = compileScopedConfig(\n config,\n false,\n (message) => new ConfigError(message),\n );\n\n let result: SyncCallbackResult<TResult>;\n let callbackError: unknown;\n let callbackFailed = false;\n activeScopedConfigCount++;\n activeScopedConfigs.add(scopedConfig);\n try {\n result = runWithScopedConfig(contextLocalStorage, scopedConfig, callback);\n if (isThenable(result)) {\n void Promise.resolve(result).catch(() => {});\n callbackFailed = true;\n callbackError = new ConfigError(\n \"withConfigSync() callback must not return a promise. \" +\n \"Use withConfig() for async callbacks.\",\n );\n }\n } catch (error) {\n callbackFailed = true;\n callbackError = error;\n }\n\n try {\n disposeScopedConfigSync(scopedConfig, getRetainedDisposables(scopedConfig));\n } catch (disposeError) {\n if (callbackFailed) {\n throwCombinedErrors(callbackError, disposeError);\n }\n throw disposeError;\n } finally {\n activeScopedConfigs.delete(scopedConfig);\n activeScopedConfigCount--;\n }\n\n if (callbackFailed) throw callbackError;\n return result!;\n}\n\nfunction isThenable(value: unknown): value is PromiseLike<unknown> {\n return value != null &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n \"then\" in value &&\n typeof value.then === \"function\";\n}\n\nfunction getGlobalDisposables(): ReadonlySet<Disposable | AsyncDisposable> {\n return new Set<Disposable | AsyncDisposable>([\n ...filterDisposables,\n ...asyncFilterDisposables,\n ...sinkDisposables,\n ...asyncSinkDisposables,\n ]);\n}\n\nfunction getRetainedDisposables(\n scopedConfig: CompiledScopedConfig,\n): ReadonlySet<Disposable | AsyncDisposable> {\n const disposables = new Set<Disposable | AsyncDisposable>(\n getGlobalDisposables(),\n );\n for (const activeScopedConfig of activeScopedConfigs) {\n if (activeScopedConfig === scopedConfig || activeScopedConfig.disposed) {\n continue;\n }\n addScopedConfigDisposables(disposables, activeScopedConfig);\n }\n return disposables;\n}\n\nfunction addScopedConfigDisposables(\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 configureInternal<\n TSinkId extends string,\n TFilterId extends string,\n>(config: Config<TSinkId, TFilterId>, allowAsync: boolean): void {\n currentConfig = config;\n\n let metaConfigured = false;\n const configuredCategories = new Set<string>();\n\n for (const cfg of config.loggers) {\n if (isLoggerConfigMeta(cfg)) {\n metaConfigured = true;\n }\n\n // Check for duplicate logger categories\n const categoryKey = Array.isArray(cfg.category)\n ? JSON.stringify(cfg.category)\n : JSON.stringify([cfg.category]);\n if (configuredCategories.has(categoryKey)) {\n throw new ConfigError(\n `Duplicate logger configuration for category: ${categoryKey}. ` +\n `Each category can only be configured once.`,\n );\n }\n configuredCategories.add(categoryKey);\n\n const logger = LoggerImpl.getLogger(cfg.category);\n for (const sinkId of cfg.sinks ?? []) {\n const sink = config.sinks[sinkId];\n if (!sink) {\n throw new ConfigError(`Sink not found: ${sinkId}.`);\n }\n logger.sinks.push(sink);\n }\n logger.parentSinks = cfg.parentSinks ?? \"inherit\";\n if (cfg.lowestLevel !== undefined) {\n logger.lowestLevel = cfg.lowestLevel;\n }\n for (const filterId of cfg.filters ?? []) {\n const filter = config.filters?.[filterId];\n if (filter === undefined) {\n throw new ConfigError(`Filter not found: ${filterId}.`);\n }\n logger.filters.push(toFilter(filter));\n }\n strongRefs.add(logger);\n }\n\n LoggerImpl.getLogger().contextLocalStorage = config.contextLocalStorage;\n\n for (const sink of Object.values<Sink>(config.sinks)) {\n if (Symbol.asyncDispose in sink) {\n if (allowAsync) asyncSinkDisposables.add(sink as AsyncDisposable);\n else {\n throw new ConfigError(\n \"Async disposables cannot be used with configureSync().\",\n );\n }\n }\n if (Symbol.dispose in sink) sinkDisposables.add(sink as Disposable);\n }\n\n for (const filter of Object.values<FilterLike>(config.filters ?? {})) {\n if (filter == null || typeof filter === \"string\") continue;\n if (Symbol.asyncDispose in filter) {\n if (allowAsync) asyncFilterDisposables.add(filter as AsyncDisposable);\n else {\n throw new ConfigError(\n \"Async disposables cannot be used with configureSync().\",\n );\n }\n asyncSinkDisposables.delete(filter as AsyncDisposable);\n }\n if (Symbol.dispose in filter) {\n filterDisposables.add(filter as Disposable);\n sinkDisposables.delete(filter as Disposable);\n }\n }\n\n registerDisposeHook(allowAsync);\n const meta = LoggerImpl.getLogger([\"logtape\", \"meta\"]);\n if (!metaConfigured) {\n meta.sinks.push(getConsoleSink());\n }\n\n meta.info(\n \"LogTape loggers are configured. Note that LogTape itself uses the meta \" +\n \"logger, which has category {metaLoggerCategory}. The meta logger is \" +\n \"used to log internal diagnostics such as sink exceptions. \" +\n \"It's recommended to configure the meta logger with a separate sink \" +\n \"so that you can easily notice if logging itself fails or is \" +\n \"misconfigured. To turn off this message, configure the meta logger \" +\n \"with higher log levels than {dismissLevel}. See also \" +\n \"<https://logtape.org/manual/categories#meta-logger>.\",\n { metaLoggerCategory: [\"logtape\", \"meta\"], dismissLevel: \"info\" },\n );\n}\n\n/**\n * Get the current configuration, if any. Otherwise, `null`.\n * @returns The current configuration, if any. Otherwise, `null`.\n */\nexport function getConfig(): Config<string, string> | null {\n return currentConfig;\n}\n\n/**\n * Reset the configuration. Mostly for testing purposes.\n */\nexport async function reset(): Promise<void> {\n await runGlobalConfigMutation(\"reset()\", async () => {\n await disposeInternal();\n resetInternal();\n });\n}\n\n/**\n * Reset the configuration. Mostly for testing purposes. Will not clear async\n * sinks, only use with sync sinks. Use {@link reset} if you have async sinks.\n * @since 0.9.0\n */\nexport function resetSync(): void {\n runGlobalConfigMutationSync(\"resetSync()\", () => {\n disposeSyncInternal();\n resetInternal();\n });\n}\n\nfunction resetInternal(): void {\n unregisterDisposeHook?.();\n unregisterDisposeHook = undefined;\n const rootLogger = LoggerImpl.getLogger([]);\n rootLogger.resetDescendants();\n delete rootLogger.contextLocalStorage;\n strongRefs.clear();\n currentConfig = null;\n}\n\n/**\n * Dispose of the disposables.\n */\nexport async function dispose(): Promise<void> {\n await runGlobalConfigMutation(\"dispose()\", disposeInternal);\n}\n\nasync function disposeInternal(): Promise<void> {\n const errors: unknown[] = [];\n try {\n disposeSyncFilters();\n } catch (error) {\n errors.push(error);\n }\n try {\n await disposeAsyncFilters();\n } catch (error) {\n errors.push(error);\n }\n try {\n disposeSyncSinks();\n } catch (error) {\n errors.push(error);\n }\n try {\n await disposeAsyncSinks();\n } catch (error) {\n errors.push(error);\n }\n throwDisposeErrors(errors);\n}\n\n/**\n * Dispose of the sync disposables. Async disposables will be untouched,\n * use {@link dispose} if you have async sinks.\n * @since 0.9.0\n */\nexport function disposeSync(): void {\n runGlobalConfigMutationSync(\"disposeSync()\", disposeSyncInternal);\n}\n\nfunction disposeSyncInternal(): void {\n const errors: unknown[] = [];\n try {\n disposeSyncFilters();\n } catch (error) {\n errors.push(error);\n }\n try {\n disposeSyncSinks();\n } catch (error) {\n errors.push(error);\n }\n throwDisposeErrors(errors);\n}\n\nfunction getConfiguredContextLocalStorage(\n functionName: string,\n): ContextLocalStorage<Record<string, unknown>> {\n if (globalConfigMutationInProgress) {\n throw new ConfigError(\n `${functionName} cannot be called while LogTape is being reconfigured.`,\n );\n }\n if (currentConfig == null) {\n throw new ConfigError(\n `${functionName} requires LogTape to be configured first.`,\n );\n }\n const contextLocalStorage = LoggerImpl.getLogger().contextLocalStorage;\n if (contextLocalStorage == null) {\n throw new ConfigError(\n `${functionName} requires Config.contextLocalStorage to be configured.`,\n );\n }\n return contextLocalStorage;\n}\n\nasync function runGlobalConfigMutation<T>(\n functionName: string,\n callback: () => Promise<T>,\n): Promise<T> {\n assertCanMutateGlobalConfig(functionName);\n globalConfigMutationInProgress = true;\n try {\n return await callback();\n } finally {\n globalConfigMutationInProgress = false;\n }\n}\n\nfunction runGlobalConfigMutationSync<T>(\n functionName: string,\n callback: () => T,\n): T {\n assertCanMutateGlobalConfig(functionName);\n globalConfigMutationInProgress = true;\n try {\n return callback();\n } finally {\n globalConfigMutationInProgress = false;\n }\n}\n\nfunction assertCanMutateGlobalConfig(functionName: string): void {\n if (globalConfigMutationInProgress) {\n throw new ConfigError(\n `${functionName} cannot be called while LogTape is being reconfigured.`,\n );\n }\n assertNoScopedConfig(functionName);\n}\n\nfunction assertNoScopedConfig(functionName: string): void {\n if (activeScopedConfigCount > 0) {\n throw new ConfigError(\n `${functionName} cannot be called while a scoped configuration is ` +\n \"active. Use nested withConfig() instead.\",\n );\n }\n}\n\nfunction disposeSyncFilters(): void {\n disposeSyncDisposables(filterDisposables);\n}\n\nfunction disposeSyncSinks(): void {\n disposeSyncDisposables(sinkDisposables);\n}\n\nfunction disposeSyncDisposables(disposables: Set<Disposable>): void {\n const errors: unknown[] = [];\n try {\n for (const disposable of disposables) {\n try {\n disposable[Symbol.dispose]();\n } catch (error) {\n errors.push(error);\n } finally {\n disposables.delete(disposable);\n }\n }\n } finally {\n disposables.clear();\n }\n throwDisposeErrors(errors);\n}\n\nasync function disposeAsyncFilters(): Promise<void> {\n await disposeAsyncDisposables(asyncFilterDisposables);\n}\n\nasync function disposeAsyncSinks(): Promise<void> {\n await disposeAsyncDisposables(asyncSinkDisposables);\n}\n\nasync function disposeAsyncDisposables(\n disposables: Set<AsyncDisposable>,\n): Promise<void> {\n const promises: PromiseLike<void>[] = [];\n try {\n for (const disposable of disposables) {\n try {\n promises.push(Promise.resolve(disposable[Symbol.asyncDispose]()));\n } catch (error) {\n promises.push(Promise.reject(error));\n } finally {\n disposables.delete(disposable);\n }\n }\n } finally {\n disposables.clear();\n }\n await settleDisposePromises(promises);\n}\n\nasync function settleDisposePromises(\n promises: readonly PromiseLike<void>[],\n): Promise<void> {\n const results = await Promise.allSettled(promises);\n throwDisposeErrors(\n results\n .filter((result): result is PromiseRejectedResult =>\n result.status === \"rejected\"\n )\n .map((result) => result.reason),\n );\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 resources.\",\n );\n}\n\n/**\n * A configuration error.\n */\nexport class ConfigError extends Error {\n /**\n * Constructs a new configuration error.\n * @param message The error message.\n */\n constructor(message: string) {\n super(message);\n this.name = \"ConfigError\";\n }\n}\n"],"mappings":"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"}
|
package/dist/logger.cjs
CHANGED
|
@@ -184,6 +184,7 @@ var LoggerImpl = class LoggerImpl {
|
|
|
184
184
|
#parentSinks = "inherit";
|
|
185
185
|
#lowestLevel = "trace";
|
|
186
186
|
#sinkPlanCache = {};
|
|
187
|
+
#forwardPlanCache = void 0;
|
|
187
188
|
static getLogger(category = []) {
|
|
188
189
|
let rootLogger = globalRootLoggerSymbol in globalThis ? globalThis[globalRootLoggerSymbol] ?? null : null;
|
|
189
190
|
if (rootLogger == null) {
|
|
@@ -279,17 +280,46 @@ var LoggerImpl = class LoggerImpl {
|
|
|
279
280
|
getSinkDispatchPlan(level) {
|
|
280
281
|
const cached = this.#sinkPlanCache[level];
|
|
281
282
|
if (cached != null && this.isSinkDispatchPlanFresh(level, cached)) return cached;
|
|
282
|
-
const
|
|
283
|
-
const plan = this.createSinkDispatchPlan(level, parentPlan);
|
|
283
|
+
const plan = this.createSinkDispatchPlan(level, this.resolveParentPlan(level));
|
|
284
284
|
this.#sinkPlanCache[level] = plan;
|
|
285
285
|
return plan;
|
|
286
286
|
}
|
|
287
|
+
resolveParentPlan(level) {
|
|
288
|
+
if (this.parent == null) return void 0;
|
|
289
|
+
if (this.parentSinks === "inherit") return this.parent.getSinkDispatchPlan(level);
|
|
290
|
+
if (this.parentSinks === "forward") return this.parent.getForwardSinkPlan();
|
|
291
|
+
return void 0;
|
|
292
|
+
}
|
|
287
293
|
isSinkDispatchPlanFresh(level, plan) {
|
|
288
294
|
if (plan.lowestLevel !== this.lowestLevel || plan.parentSinks !== this.parentSinks || plan.localSinks.length !== this.sinks.length) return false;
|
|
289
295
|
for (let i = 0; i < plan.localSinks.length; i++) if (plan.localSinks[i] !== this.sinks[i]) return false;
|
|
290
|
-
|
|
296
|
+
return plan.parentPlan === this.resolveParentPlan(level);
|
|
297
|
+
}
|
|
298
|
+
getForwardSinkPlan() {
|
|
299
|
+
const cached = this.#forwardPlanCache;
|
|
300
|
+
if (cached != null && this.isForwardSinkPlanFresh(cached)) return cached;
|
|
301
|
+
const parentPlan = this.parent != null && this.parentSinks !== "override" ? this.parent.getForwardSinkPlan() : void 0;
|
|
302
|
+
const plan = this.createForwardSinkPlan(parentPlan);
|
|
303
|
+
this.#forwardPlanCache = plan;
|
|
304
|
+
return plan;
|
|
305
|
+
}
|
|
306
|
+
isForwardSinkPlanFresh(plan) {
|
|
307
|
+
if (plan.parentSinks !== this.parentSinks || plan.localSinks.length !== this.sinks.length) return false;
|
|
308
|
+
for (let i = 0; i < plan.localSinks.length; i++) if (plan.localSinks[i] !== this.sinks[i]) return false;
|
|
309
|
+
const parentPlan = this.parent != null && this.parentSinks !== "override" ? this.parent.getForwardSinkPlan() : void 0;
|
|
291
310
|
return plan.parentPlan === parentPlan;
|
|
292
311
|
}
|
|
312
|
+
createForwardSinkPlan(parentPlan) {
|
|
313
|
+
const localSinks = [...this.sinks];
|
|
314
|
+
const sinks = parentPlan == null || parentPlan.sinks.length < 1 ? localSinks : [...parentPlan.sinks, ...localSinks];
|
|
315
|
+
return {
|
|
316
|
+
kind: "forward",
|
|
317
|
+
localSinks,
|
|
318
|
+
parentSinks: this.parentSinks,
|
|
319
|
+
parentPlan,
|
|
320
|
+
sinks
|
|
321
|
+
};
|
|
322
|
+
}
|
|
293
323
|
createSinkDispatchPlan(level, parentPlan) {
|
|
294
324
|
const state = {
|
|
295
325
|
localSinks: [...this.sinks],
|
|
@@ -315,6 +345,10 @@ var LoggerImpl = class LoggerImpl {
|
|
|
315
345
|
if (parentPlan != null) {
|
|
316
346
|
if (parentPlan.kind === "one") firstSink = parentPlan.sink;
|
|
317
347
|
else if (parentPlan.kind === "many") sinks = [...parentPlan.sinks];
|
|
348
|
+
else if (parentPlan.kind === "forward") {
|
|
349
|
+
if (parentPlan.sinks.length === 1) firstSink = parentPlan.sinks[0];
|
|
350
|
+
else if (parentPlan.sinks.length > 1) sinks = [...parentPlan.sinks];
|
|
351
|
+
}
|
|
318
352
|
}
|
|
319
353
|
for (const sink of state.localSinks) appendSink(sink);
|
|
320
354
|
if (sinks != null) return {
|
package/dist/logger.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.cts","names":[],"sources":["../src/logger.ts"],"sourcesContent":[],"mappings":";;;;;AAkCA;;;cAhBM,UAkBmB,EAAA,OAAA,MAAA;AAAC;AAU1B;AA4BA;;;;AAA0C,UAxCzB,IAwCyB,CAAA,CAAA,CAAA,CAAA;EAAI,UAvClC,UAAA,CAuCkC,EAAA,IAAA;
|
|
1
|
+
{"version":3,"file":"logger.d.cts","names":[],"sources":["../src/logger.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/logger.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","names":[],"sources":["../src/logger.ts"],"sourcesContent":[],"mappings":";;;;;AAkCA;;;cAhBM,UAkBmB,EAAA,OAAA,MAAA;AAAC;AAU1B;AA4BA;;;;AAA0C,UAxCzB,IAwCyB,CAAA,CAAA,CAAA,CAAA;EAAI,UAvClC,UAAA,CAuCkC,EAAA,IAAA;
|
|
1
|
+
{"version":3,"file":"logger.d.ts","names":[],"sources":["../src/logger.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/logger.js
CHANGED
|
@@ -184,6 +184,7 @@ var LoggerImpl = class LoggerImpl {
|
|
|
184
184
|
#parentSinks = "inherit";
|
|
185
185
|
#lowestLevel = "trace";
|
|
186
186
|
#sinkPlanCache = {};
|
|
187
|
+
#forwardPlanCache = void 0;
|
|
187
188
|
static getLogger(category = []) {
|
|
188
189
|
let rootLogger = globalRootLoggerSymbol in globalThis ? globalThis[globalRootLoggerSymbol] ?? null : null;
|
|
189
190
|
if (rootLogger == null) {
|
|
@@ -279,17 +280,46 @@ var LoggerImpl = class LoggerImpl {
|
|
|
279
280
|
getSinkDispatchPlan(level) {
|
|
280
281
|
const cached = this.#sinkPlanCache[level];
|
|
281
282
|
if (cached != null && this.isSinkDispatchPlanFresh(level, cached)) return cached;
|
|
282
|
-
const
|
|
283
|
-
const plan = this.createSinkDispatchPlan(level, parentPlan);
|
|
283
|
+
const plan = this.createSinkDispatchPlan(level, this.resolveParentPlan(level));
|
|
284
284
|
this.#sinkPlanCache[level] = plan;
|
|
285
285
|
return plan;
|
|
286
286
|
}
|
|
287
|
+
resolveParentPlan(level) {
|
|
288
|
+
if (this.parent == null) return void 0;
|
|
289
|
+
if (this.parentSinks === "inherit") return this.parent.getSinkDispatchPlan(level);
|
|
290
|
+
if (this.parentSinks === "forward") return this.parent.getForwardSinkPlan();
|
|
291
|
+
return void 0;
|
|
292
|
+
}
|
|
287
293
|
isSinkDispatchPlanFresh(level, plan) {
|
|
288
294
|
if (plan.lowestLevel !== this.lowestLevel || plan.parentSinks !== this.parentSinks || plan.localSinks.length !== this.sinks.length) return false;
|
|
289
295
|
for (let i = 0; i < plan.localSinks.length; i++) if (plan.localSinks[i] !== this.sinks[i]) return false;
|
|
290
|
-
|
|
296
|
+
return plan.parentPlan === this.resolveParentPlan(level);
|
|
297
|
+
}
|
|
298
|
+
getForwardSinkPlan() {
|
|
299
|
+
const cached = this.#forwardPlanCache;
|
|
300
|
+
if (cached != null && this.isForwardSinkPlanFresh(cached)) return cached;
|
|
301
|
+
const parentPlan = this.parent != null && this.parentSinks !== "override" ? this.parent.getForwardSinkPlan() : void 0;
|
|
302
|
+
const plan = this.createForwardSinkPlan(parentPlan);
|
|
303
|
+
this.#forwardPlanCache = plan;
|
|
304
|
+
return plan;
|
|
305
|
+
}
|
|
306
|
+
isForwardSinkPlanFresh(plan) {
|
|
307
|
+
if (plan.parentSinks !== this.parentSinks || plan.localSinks.length !== this.sinks.length) return false;
|
|
308
|
+
for (let i = 0; i < plan.localSinks.length; i++) if (plan.localSinks[i] !== this.sinks[i]) return false;
|
|
309
|
+
const parentPlan = this.parent != null && this.parentSinks !== "override" ? this.parent.getForwardSinkPlan() : void 0;
|
|
291
310
|
return plan.parentPlan === parentPlan;
|
|
292
311
|
}
|
|
312
|
+
createForwardSinkPlan(parentPlan) {
|
|
313
|
+
const localSinks = [...this.sinks];
|
|
314
|
+
const sinks = parentPlan == null || parentPlan.sinks.length < 1 ? localSinks : [...parentPlan.sinks, ...localSinks];
|
|
315
|
+
return {
|
|
316
|
+
kind: "forward",
|
|
317
|
+
localSinks,
|
|
318
|
+
parentSinks: this.parentSinks,
|
|
319
|
+
parentPlan,
|
|
320
|
+
sinks
|
|
321
|
+
};
|
|
322
|
+
}
|
|
293
323
|
createSinkDispatchPlan(level, parentPlan) {
|
|
294
324
|
const state = {
|
|
295
325
|
localSinks: [...this.sinks],
|
|
@@ -315,6 +345,10 @@ var LoggerImpl = class LoggerImpl {
|
|
|
315
345
|
if (parentPlan != null) {
|
|
316
346
|
if (parentPlan.kind === "one") firstSink = parentPlan.sink;
|
|
317
347
|
else if (parentPlan.kind === "many") sinks = [...parentPlan.sinks];
|
|
348
|
+
else if (parentPlan.kind === "forward") {
|
|
349
|
+
if (parentPlan.sinks.length === 1) firstSink = parentPlan.sinks[0];
|
|
350
|
+
else if (parentPlan.sinks.length > 1) sinks = [...parentPlan.sinks];
|
|
351
|
+
}
|
|
318
352
|
}
|
|
319
353
|
for (const sink of state.localSinks) appendSink(sink);
|
|
320
354
|
if (sinks != null) return {
|