@logtape/logtape
Advanced tools
+21
-2
@@ -24,2 +24,3 @@ const require_filter = require('./filter.cjs'); | ||
| const asyncDisposables = /* @__PURE__ */ new Set(); | ||
| let unregisterDisposeHook; | ||
| /** | ||
@@ -33,2 +34,4 @@ * Check if a config is for the meta logger. | ||
| function registerDisposeHook(allowAsync) { | ||
| unregisterDisposeHook?.(); | ||
| unregisterDisposeHook = void 0; | ||
| const handler = allowAsync ? dispose : disposeSync; | ||
@@ -40,2 +43,6 @@ if (typeof globalThis.EdgeRuntime !== "string" && "process" in globalThis && !("Deno" in globalThis)) { | ||
| onMethod.call(proc, "exit", handler); | ||
| unregisterDisposeHook = () => { | ||
| const offMethod = proc?.["off"] ?? proc?.["removeListener"]; | ||
| if (typeof offMethod === "function") offMethod.call(proc, "exit", handler); | ||
| }; | ||
| return; | ||
@@ -46,4 +53,14 @@ } | ||
| if (typeof addEventListenerMethod !== "function") return; | ||
| if ("Deno" in globalThis) addEventListenerMethod.call(globalThis, "unload", handler); | ||
| else addEventListenerMethod.call(globalThis, "pagehide", handler); | ||
| const removeEventListenerMethod = globalThis.removeEventListener; | ||
| if ("Deno" in globalThis) { | ||
| addEventListenerMethod.call(globalThis, "unload", handler); | ||
| if (typeof removeEventListenerMethod === "function") unregisterDisposeHook = () => { | ||
| removeEventListenerMethod.call(globalThis, "unload", handler); | ||
| }; | ||
| } else { | ||
| addEventListenerMethod.call(globalThis, "pagehide", handler); | ||
| if (typeof removeEventListenerMethod === "function") unregisterDisposeHook = () => { | ||
| removeEventListenerMethod.call(globalThis, "pagehide", handler); | ||
| }; | ||
| } | ||
| } | ||
@@ -211,2 +228,4 @@ /** | ||
| function resetInternal() { | ||
| unregisterDisposeHook?.(); | ||
| unregisterDisposeHook = void 0; | ||
| const rootLogger = require_logger.LoggerImpl.getLogger([]); | ||
@@ -213,0 +232,0 @@ rootLogger.resetDescendants(); |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"config.d.cts","names":[],"sources":["../src/config.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AASA;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;AAW3C;EAA6B,OAAA,EAjBlB,YAiBkB,CAjBL,OAiBK,EAjBI,SAiBJ,CAAA,EAAA;EAAA;;;AAoCL;EA8GF,mBAAS,CAAA,EA7JP,mBA6JO,CA7Ja,MA6Jb,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA;EAAA;;;EAGI,KAAzB,CAAA,EAAA,OAAA;;AAAoC;AAgD9C;;AACiB,UAtMA,YAsMA,CAAA,gBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,CAAA;EAAO;;AAAR;AAwHhB;EAOsB,QAAK,EAAA,MAAA,GAAI,MAAA,EAAO;EAUtB;AAgBhB;AAeA;EAQa,KAAA,CAAA,EAzWH,OAyWe,EAAA;;;;;;;;;;;;;;YAzVb;;;;;;gBAOI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8GM,oEAGZ,OAAO,SAAS,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgDvB,wEACN,OAAO,SAAS;;;;;iBAwHV,SAAA,CAAA,GAAa;;;;iBAOP,KAAA,CAAA,GAAS;;;;;;iBAUf,SAAA,CAAA;;;;iBAgBM,OAAA,CAAA,GAAW;;;;;;iBAejB,WAAA,CAAA;;;;cAQH,WAAA,SAAoB,KAAK"} | ||
| {"version":3,"file":"config.d.cts","names":[],"sources":["../src/config.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AASA;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;AAW3C;EAA6B,OAAA,EAjBlB,YAiBkB,CAjBL,OAiBK,EAjBI,SAiBJ,CAAA,EAAA;EAAA;;;AAoCL;EAqIF,mBAAS,CAAA,EApLP,mBAoLO,CApLa,MAoLb,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA;EAAA;;;EAGI,KAAzB,CAAA,EAAA,OAAA;;AAAoC;AAgD9C;;AACiB,UA7NA,YA6NA,CAAA,gBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,CAAA;EAAO;;AAAR;AAwHhB;EAOsB,QAAK,EAAA,MAAA,GAAI,MAAA,EAAO;EAUtB;AAkBhB;AAeA;EAQa,KAAA,CAAA,EAlYH,OAkYe,EAAA;;;;;;;;;;;;;;YAlXb;;;;;;gBAOI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqIM,oEAGZ,OAAO,SAAS,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgDvB,wEACN,OAAO,SAAS;;;;;iBAwHV,SAAA,CAAA,GAAa;;;;iBAOP,KAAA,CAAA,GAAS;;;;;;iBAUf,SAAA,CAAA;;;;iBAkBM,OAAA,CAAA,GAAW;;;;;;iBAejB,WAAA,CAAA;;;;cAQH,WAAA,SAAoB,KAAK"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"config.d.ts","names":[],"sources":["../src/config.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AASA;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;AAW3C;EAA6B,OAAA,EAjBlB,YAiBkB,CAjBL,OAiBK,EAjBI,SAiBJ,CAAA,EAAA;EAAA;;;AAoCL;EA8GF,mBAAS,CAAA,EA7JP,mBA6JO,CA7Ja,MA6Jb,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA;EAAA;;;EAGI,KAAzB,CAAA,EAAA,OAAA;;AAAoC;AAgD9C;;AACiB,UAtMA,YAsMA,CAAA,gBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,CAAA;EAAO;;AAAR;AAwHhB;EAOsB,QAAK,EAAA,MAAA,GAAI,MAAA,EAAO;EAUtB;AAgBhB;AAeA;EAQa,KAAA,CAAA,EAzWH,OAyWe,EAAA;;;;;;;;;;;;;;YAzVb;;;;;;gBAOI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8GM,oEAGZ,OAAO,SAAS,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgDvB,wEACN,OAAO,SAAS;;;;;iBAwHV,SAAA,CAAA,GAAa;;;;iBAOP,KAAA,CAAA,GAAS;;;;;;iBAUf,SAAA,CAAA;;;;iBAgBM,OAAA,CAAA,GAAW;;;;;;iBAejB,WAAA,CAAA;;;;cAQH,WAAA,SAAoB,KAAK"} | ||
| {"version":3,"file":"config.d.ts","names":[],"sources":["../src/config.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AASA;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;AAW3C;EAA6B,OAAA,EAjBlB,YAiBkB,CAjBL,OAiBK,EAjBI,SAiBJ,CAAA,EAAA;EAAA;;;AAoCL;EAqIF,mBAAS,CAAA,EApLP,mBAoLO,CApLa,MAoLb,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA;EAAA;;;EAGI,KAAzB,CAAA,EAAA,OAAA;;AAAoC;AAgD9C;;AACiB,UA7NA,YA6NA,CAAA,gBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,CAAA;EAAO;;AAAR;AAwHhB;EAOsB,QAAK,EAAA,MAAA,GAAI,MAAA,EAAO;EAUtB;AAkBhB;AAeA;EAQa,KAAA,CAAA,EAlYH,OAkYe,EAAA;;;;;;;;;;;;;;YAlXb;;;;;;gBAOI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqIM,oEAGZ,OAAO,SAAS,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgDvB,wEACN,OAAO,SAAS;;;;;iBAwHV,SAAA,CAAA,GAAa;;;;iBAOP,KAAA,CAAA,GAAS;;;;;;iBAUf,SAAA,CAAA;;;;iBAkBM,OAAA,CAAA,GAAW;;;;;;iBAejB,WAAA,CAAA;;;;cAQH,WAAA,SAAoB,KAAK"} |
+21
-2
@@ -24,2 +24,3 @@ import { toFilter } from "./filter.js"; | ||
| const asyncDisposables = /* @__PURE__ */ new Set(); | ||
| let unregisterDisposeHook; | ||
| /** | ||
@@ -33,2 +34,4 @@ * Check if a config is for the meta logger. | ||
| function registerDisposeHook(allowAsync) { | ||
| unregisterDisposeHook?.(); | ||
| unregisterDisposeHook = void 0; | ||
| const handler = allowAsync ? dispose : disposeSync; | ||
@@ -40,2 +43,6 @@ if (typeof globalThis.EdgeRuntime !== "string" && "process" in globalThis && !("Deno" in globalThis)) { | ||
| onMethod.call(proc, "exit", handler); | ||
| unregisterDisposeHook = () => { | ||
| const offMethod = proc?.["off"] ?? proc?.["removeListener"]; | ||
| if (typeof offMethod === "function") offMethod.call(proc, "exit", handler); | ||
| }; | ||
| return; | ||
@@ -46,4 +53,14 @@ } | ||
| if (typeof addEventListenerMethod !== "function") return; | ||
| if ("Deno" in globalThis) addEventListenerMethod.call(globalThis, "unload", handler); | ||
| else addEventListenerMethod.call(globalThis, "pagehide", handler); | ||
| const removeEventListenerMethod = globalThis.removeEventListener; | ||
| if ("Deno" in globalThis) { | ||
| addEventListenerMethod.call(globalThis, "unload", handler); | ||
| if (typeof removeEventListenerMethod === "function") unregisterDisposeHook = () => { | ||
| removeEventListenerMethod.call(globalThis, "unload", handler); | ||
| }; | ||
| } else { | ||
| addEventListenerMethod.call(globalThis, "pagehide", handler); | ||
| if (typeof removeEventListenerMethod === "function") unregisterDisposeHook = () => { | ||
| removeEventListenerMethod.call(globalThis, "pagehide", handler); | ||
| }; | ||
| } | ||
| } | ||
@@ -211,2 +228,4 @@ /** | ||
| function resetInternal() { | ||
| unregisterDisposeHook?.(); | ||
| unregisterDisposeHook = void 0; | ||
| const rootLogger = LoggerImpl.getLogger([]); | ||
@@ -213,0 +232,0 @@ rootLogger.resetDescendants(); |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"config.js","names":["currentConfig: Config<string, string> | null","strongRefs: Set<LoggerImpl>","disposables: Set<Disposable>","asyncDisposables: Set<AsyncDisposable>","cfg: LoggerConfig<TSinkId, TFilterId>","allowAsync: boolean","config: Config<TSinkId, TFilterId>","promises: PromiseLike<void>[]","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 { 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 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 parent's sinks. If `inherit`, the parent's sinks\n * are used along with the specified sinks. If `override`, the parent's\n * sinks are not used, and 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.\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;\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 * Disposables to dispose when resetting the configuration.\n */\nconst disposables: Set<Disposable> = new Set();\n\n/**\n * Async disposables to dispose when resetting the configuration.\n */\nconst asyncDisposables: Set<AsyncDisposable> = new Set();\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 const handler = allowAsync ? dispose : disposeSync;\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 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\n if (\"Deno\" in globalThis) {\n addEventListenerMethod.call(globalThis, \"unload\", handler);\n } else {\n addEventListenerMethod.call(globalThis, \"pagehide\", handler);\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 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 reset();\n try {\n configureInternal(config, true);\n } catch (e) {\n if (e instanceof ConfigError) await reset();\n throw e;\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 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 (asyncDisposables.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 resetSync();\n try {\n configureInternal(config, false);\n } catch (e) {\n if (e instanceof ConfigError) resetSync();\n throw e;\n }\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) asyncDisposables.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) disposables.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) asyncDisposables.add(filter as AsyncDisposable);\n else {\n throw new ConfigError(\n \"Async disposables cannot be used with configureSync().\",\n );\n }\n }\n if (Symbol.dispose in filter) disposables.add(filter as Disposable);\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 dispose();\n resetInternal();\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 disposeSync();\n resetInternal();\n}\n\nfunction resetInternal(): void {\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 disposeSync();\n const promises: PromiseLike<void>[] = [];\n for (const disposable of asyncDisposables) {\n promises.push(disposable[Symbol.asyncDispose]());\n asyncDisposables.delete(disposable);\n }\n await Promise.all(promises);\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 for (const disposable of disposables) disposable[Symbol.dispose]();\n disposables.clear();\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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"} | ||
| {"version":3,"file":"config.js","names":["currentConfig: Config<string, string> | null","strongRefs: Set<LoggerImpl>","disposables: Set<Disposable>","asyncDisposables: Set<AsyncDisposable>","unregisterDisposeHook: (() => void) | undefined","cfg: LoggerConfig<TSinkId, TFilterId>","allowAsync: boolean","config: Config<TSinkId, TFilterId>","promises: PromiseLike<void>[]","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 { 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 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 parent's sinks. If `inherit`, the parent's sinks\n * are used along with the specified sinks. If `override`, the parent's\n * sinks are not used, and 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.\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;\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 * Disposables to dispose when resetting the configuration.\n */\nconst disposables: Set<Disposable> = new Set();\n\n/**\n * Async disposables to dispose when resetting the configuration.\n */\nconst asyncDisposables: 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 ? dispose : disposeSync;\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 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 reset();\n try {\n configureInternal(config, true);\n } catch (e) {\n if (e instanceof ConfigError) await reset();\n throw e;\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 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 (asyncDisposables.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 resetSync();\n try {\n configureInternal(config, false);\n } catch (e) {\n if (e instanceof ConfigError) resetSync();\n throw e;\n }\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) asyncDisposables.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) disposables.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) asyncDisposables.add(filter as AsyncDisposable);\n else {\n throw new ConfigError(\n \"Async disposables cannot be used with configureSync().\",\n );\n }\n }\n if (Symbol.dispose in filter) disposables.add(filter as Disposable);\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 dispose();\n resetInternal();\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 disposeSync();\n resetInternal();\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 disposeSync();\n const promises: PromiseLike<void>[] = [];\n for (const disposable of asyncDisposables) {\n promises.push(disposable[Symbol.asyncDispose]());\n asyncDisposables.delete(disposable);\n }\n await Promise.all(promises);\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 for (const disposable of disposables) disposable[Symbol.dispose]();\n disposables.clear();\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
-1
| { | ||
| "name": "@logtape/logtape", | ||
| "version": "2.0.16", | ||
| "version": "2.0.17", | ||
| "description": "Unobtrusive logging library with zero dependencies—library-first design for Deno/Node.js/Bun/browsers/edge", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
594156
0.47%7287
0.52%