@logtape/logtape 2.3.0-dev.805 → 2.3.0-dev.809

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.cjs CHANGED
@@ -9,6 +9,7 @@ const require_sink = require('./sink.cjs');
9
9
  */
10
10
  let currentConfig = null;
11
11
  let activeScopedConfigCount = 0;
12
+ const activeScopedConfigs = /* @__PURE__ */ new Set();
12
13
  let globalConfigMutationInProgress = false;
13
14
  /**
14
15
  * Strong references to the loggers.
@@ -179,6 +180,7 @@ async function withConfig(config, callback) {
179
180
  let callbackError;
180
181
  let callbackFailed = false;
181
182
  activeScopedConfigCount++;
183
+ activeScopedConfigs.add(scopedConfig);
182
184
  try {
183
185
  result = await require_scoped_config.runWithScopedConfig(contextLocalStorage, scopedConfig, callback);
184
186
  } catch (error) {
@@ -186,11 +188,12 @@ async function withConfig(config, callback) {
186
188
  callbackError = error;
187
189
  }
188
190
  try {
189
- await require_scoped_config.disposeScopedConfig(scopedConfig, getGlobalDisposables());
191
+ await require_scoped_config.disposeScopedConfig(scopedConfig, getRetainedDisposables(scopedConfig));
190
192
  } catch (disposeError) {
191
193
  if (callbackFailed) require_scoped_config.throwCombinedErrors(callbackError, disposeError);
192
194
  throw disposeError;
193
195
  } finally {
196
+ activeScopedConfigs.delete(scopedConfig);
194
197
  activeScopedConfigCount--;
195
198
  }
196
199
  if (callbackFailed) throw callbackError;
@@ -214,6 +217,7 @@ function withConfigSync(config, callback) {
214
217
  let callbackError;
215
218
  let callbackFailed = false;
216
219
  activeScopedConfigCount++;
220
+ activeScopedConfigs.add(scopedConfig);
217
221
  try {
218
222
  result = require_scoped_config.runWithScopedConfig(contextLocalStorage, scopedConfig, callback);
219
223
  if (isThenable(result)) {
@@ -226,11 +230,12 @@ function withConfigSync(config, callback) {
226
230
  callbackError = error;
227
231
  }
228
232
  try {
229
- require_scoped_config.disposeScopedConfigSync(scopedConfig, getGlobalDisposables());
233
+ require_scoped_config.disposeScopedConfigSync(scopedConfig, getRetainedDisposables(scopedConfig));
230
234
  } catch (disposeError) {
231
235
  if (callbackFailed) require_scoped_config.throwCombinedErrors(callbackError, disposeError);
232
236
  throw disposeError;
233
237
  } finally {
238
+ activeScopedConfigs.delete(scopedConfig);
234
239
  activeScopedConfigCount--;
235
240
  }
236
241
  if (callbackFailed) throw callbackError;
@@ -247,6 +252,20 @@ function getGlobalDisposables() {
247
252
  ...asyncSinkDisposables
248
253
  ]);
249
254
  }
255
+ function getRetainedDisposables(scopedConfig) {
256
+ const disposables = new Set(getGlobalDisposables());
257
+ for (const activeScopedConfig of activeScopedConfigs) {
258
+ if (activeScopedConfig === scopedConfig || activeScopedConfig.disposed) continue;
259
+ addScopedConfigDisposables(disposables, activeScopedConfig);
260
+ }
261
+ return disposables;
262
+ }
263
+ function addScopedConfigDisposables(disposables, scopedConfig) {
264
+ for (const disposable of scopedConfig.syncFilters) disposables.add(disposable);
265
+ for (const disposable of scopedConfig.asyncFilters) disposables.add(disposable);
266
+ for (const disposable of scopedConfig.syncSinks) disposables.add(disposable);
267
+ for (const disposable of scopedConfig.asyncSinks) disposables.add(disposable);
268
+ }
250
269
  function configureInternal(config, allowAsync) {
251
270
  currentConfig = config;
252
271
  let metaConfigured = false;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.cts","names":[],"sources":["../src/config.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;AAiBA;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;;;;;AAoCwB;AA0HxB;;;;AAGU,KA1KE,YA0KF,CAAA,gBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,GAzKR,gBAyKQ,CAzKS,OAyKT,EAzKkB,SAyKlB,CAAA;KAvKL,kBAuKkC,CAAA,OAAA,CAAA,GAvKJ,OAuKI,SAvKY,WAuKZ,CAAA,OAAA,CAAA,GAAA,KAAA,GAtKnC,OAsKmC;AAAO;AAsD9C;;AACiB,UAxNA,YAwNA,CAAA,gBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,CAAA;EAAO;;AAAR;AAyChB;EAAgC,QAAA,EAAA,MAAA,GAAA,MAAA,EAAA;EAAA;;;EAKV,KACJ,CAAA,EA1PR,OA0PQ,EAAA;EAAO;;;AACf;AAiDV;;;;;EAKsB,WACe,CAAA,EAAA,SAAA,GAAA,UAAA;EAAO;;;EACvB,OAAA,CAAA,EAnST,SAmSS,EAAA;EAkKL;AAOhB;AAYA;AAkBA;AAkCA;EAoKa,WAAA,CAAA,EAzqBG,QAyqBS,GAAQ,IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA/iBX,oEAGZ,OAAO,SAAS,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsDvB,wEACN,OAAO,SAAS;;;;;;;;;;;;;;iBAyCJ,8EAKZ,aAAa,SAAS,4BACd,UACf,QAAQ,QAAQ;;;;;;;;;;;;iBAiDH,kFAKN,aAAa,SAAS,4BACd,mBAAmB,WAClC,mBAAmB;;;;;iBAkKN,SAAA,CAAA,GAAa;;;;iBAOP,KAAA,CAAA,GAAS;;;;;;iBAYf,SAAA,CAAA;;;;iBAkBM,OAAA,CAAA,GAAW;;;;;;iBAkCjB,WAAA,CAAA;;;;cAoKH,WAAA,SAAoB,KAAK"}
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;;;;;AAoCwB;AA2HxB;;;;AAGU,KA3KE,YA2KF,CAAA,gBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,GA1KR,gBA0KQ,CA1KS,OA0KT,EA1KkB,SA0KlB,CAAA;KAxKL,kBAwKkC,CAAA,OAAA,CAAA,GAxKJ,OAwKI,SAxKY,WAwKZ,CAAA,OAAA,CAAA,GAAA,KAAA,GAvKnC,OAuKmC;AAAO;AAsD9C;;AACiB,UAzNA,YAyNA,CAAA,gBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,CAAA;EAAO;;AAAR;AAyChB;EAAgC,QAAA,EAAA,MAAA,GAAA,MAAA,EAAA;EAAA;;;EAKV,KACJ,CAAA,EA3PR,OA2PQ,EAAA;EAAO;;;AACf;AAsDV;;;;;EAKsB,WACe,CAAA,EAAA,SAAA,GAAA,UAAA;EAAO;;;EACvB,OAAA,CAAA,EAzST,SAySS,EAAA;EAiML;AAOhB;AAYA;AAkBA;AAkCA;EAoKa,WAAA,CAAA,EA9sBG,QA8sBS,GAAQ,IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAnlBX,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;;;;iBAkBM,OAAA,CAAA,GAAW;;;;;;iBAkCjB,WAAA,CAAA;;;;cAoKH,WAAA,SAAoB,KAAK"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","names":[],"sources":["../src/config.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;AAiBA;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;;;;;AAoCwB;AA0HxB;;;;AAGU,KA1KE,YA0KF,CAAA,gBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,GAzKR,gBAyKQ,CAzKS,OAyKT,EAzKkB,SAyKlB,CAAA;KAvKL,kBAuKkC,CAAA,OAAA,CAAA,GAvKJ,OAuKI,SAvKY,WAuKZ,CAAA,OAAA,CAAA,GAAA,KAAA,GAtKnC,OAsKmC;AAAO;AAsD9C;;AACiB,UAxNA,YAwNA,CAAA,gBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,CAAA;EAAO;;AAAR;AAyChB;EAAgC,QAAA,EAAA,MAAA,GAAA,MAAA,EAAA;EAAA;;;EAKV,KACJ,CAAA,EA1PR,OA0PQ,EAAA;EAAO;;;AACf;AAiDV;;;;;EAKsB,WACe,CAAA,EAAA,SAAA,GAAA,UAAA;EAAO;;;EACvB,OAAA,CAAA,EAnST,SAmSS,EAAA;EAkKL;AAOhB;AAYA;AAkBA;AAkCA;EAoKa,WAAA,CAAA,EAzqBG,QAyqBS,GAAQ,IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA/iBX,oEAGZ,OAAO,SAAS,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsDvB,wEACN,OAAO,SAAS;;;;;;;;;;;;;;iBAyCJ,8EAKZ,aAAa,SAAS,4BACd,UACf,QAAQ,QAAQ;;;;;;;;;;;;iBAiDH,kFAKN,aAAa,SAAS,4BACd,mBAAmB,WAClC,mBAAmB;;;;;iBAkKN,SAAA,CAAA,GAAa;;;;iBAOP,KAAA,CAAA,GAAS;;;;;;iBAYf,SAAA,CAAA;;;;iBAkBM,OAAA,CAAA,GAAW;;;;;;iBAkCjB,WAAA,CAAA;;;;cAoKH,WAAA,SAAoB,KAAK"}
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;;;;;AAoCwB;AA2HxB;;;;AAGU,KA3KE,YA2KF,CAAA,gBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,GA1KR,gBA0KQ,CA1KS,OA0KT,EA1KkB,SA0KlB,CAAA;KAxKL,kBAwKkC,CAAA,OAAA,CAAA,GAxKJ,OAwKI,SAxKY,WAwKZ,CAAA,OAAA,CAAA,GAAA,KAAA,GAvKnC,OAuKmC;AAAO;AAsD9C;;AACiB,UAzNA,YAyNA,CAAA,gBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,CAAA;EAAO;;AAAR;AAyChB;EAAgC,QAAA,EAAA,MAAA,GAAA,MAAA,EAAA;EAAA;;;EAKV,KACJ,CAAA,EA3PR,OA2PQ,EAAA;EAAO;;;AACf;AAsDV;;;;;EAKsB,WACe,CAAA,EAAA,SAAA,GAAA,UAAA;EAAO;;;EACvB,OAAA,CAAA,EAzST,SAySS,EAAA;EAiML;AAOhB;AAYA;AAkBA;AAkCA;EAoKa,WAAA,CAAA,EA9sBG,QA8sBS,GAAQ,IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAnlBX,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;;;;iBAkBM,OAAA,CAAA,GAAW;;;;;;iBAkCjB,WAAA,CAAA;;;;cAoKH,WAAA,SAAoB,KAAK"}
package/dist/config.js CHANGED
@@ -9,6 +9,7 @@ import { getConsoleSink } from "./sink.js";
9
9
  */
10
10
  let currentConfig = null;
11
11
  let activeScopedConfigCount = 0;
12
+ const activeScopedConfigs = /* @__PURE__ */ new Set();
12
13
  let globalConfigMutationInProgress = false;
13
14
  /**
14
15
  * Strong references to the loggers.
@@ -179,6 +180,7 @@ async function withConfig(config, callback) {
179
180
  let callbackError;
180
181
  let callbackFailed = false;
181
182
  activeScopedConfigCount++;
183
+ activeScopedConfigs.add(scopedConfig);
182
184
  try {
183
185
  result = await runWithScopedConfig(contextLocalStorage, scopedConfig, callback);
184
186
  } catch (error) {
@@ -186,11 +188,12 @@ async function withConfig(config, callback) {
186
188
  callbackError = error;
187
189
  }
188
190
  try {
189
- await disposeScopedConfig(scopedConfig, getGlobalDisposables());
191
+ await disposeScopedConfig(scopedConfig, getRetainedDisposables(scopedConfig));
190
192
  } catch (disposeError) {
191
193
  if (callbackFailed) throwCombinedErrors(callbackError, disposeError);
192
194
  throw disposeError;
193
195
  } finally {
196
+ activeScopedConfigs.delete(scopedConfig);
194
197
  activeScopedConfigCount--;
195
198
  }
196
199
  if (callbackFailed) throw callbackError;
@@ -214,6 +217,7 @@ function withConfigSync(config, callback) {
214
217
  let callbackError;
215
218
  let callbackFailed = false;
216
219
  activeScopedConfigCount++;
220
+ activeScopedConfigs.add(scopedConfig);
217
221
  try {
218
222
  result = runWithScopedConfig(contextLocalStorage, scopedConfig, callback);
219
223
  if (isThenable(result)) {
@@ -226,11 +230,12 @@ function withConfigSync(config, callback) {
226
230
  callbackError = error;
227
231
  }
228
232
  try {
229
- disposeScopedConfigSync(scopedConfig, getGlobalDisposables());
233
+ disposeScopedConfigSync(scopedConfig, getRetainedDisposables(scopedConfig));
230
234
  } catch (disposeError) {
231
235
  if (callbackFailed) throwCombinedErrors(callbackError, disposeError);
232
236
  throw disposeError;
233
237
  } finally {
238
+ activeScopedConfigs.delete(scopedConfig);
234
239
  activeScopedConfigCount--;
235
240
  }
236
241
  if (callbackFailed) throw callbackError;
@@ -247,6 +252,20 @@ function getGlobalDisposables() {
247
252
  ...asyncSinkDisposables
248
253
  ]);
249
254
  }
255
+ function getRetainedDisposables(scopedConfig) {
256
+ const disposables = new Set(getGlobalDisposables());
257
+ for (const activeScopedConfig of activeScopedConfigs) {
258
+ if (activeScopedConfig === scopedConfig || activeScopedConfig.disposed) continue;
259
+ addScopedConfigDisposables(disposables, activeScopedConfig);
260
+ }
261
+ return disposables;
262
+ }
263
+ function addScopedConfigDisposables(disposables, scopedConfig) {
264
+ for (const disposable of scopedConfig.syncFilters) disposables.add(disposable);
265
+ for (const disposable of scopedConfig.asyncFilters) disposables.add(disposable);
266
+ for (const disposable of scopedConfig.syncSinks) disposables.add(disposable);
267
+ for (const disposable of scopedConfig.asyncSinks) disposables.add(disposable);
268
+ }
250
269
  function configureInternal(config, allowAsync) {
251
270
  currentConfig = config;
252
271
  let metaConfigured = false;
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","names":["currentConfig: Config<string, string> | null","strongRefs: Set<LoggerImpl>","filterDisposables: Set<Disposable>","sinkDisposables: Set<Disposable>","asyncFilterDisposables: Set<AsyncDisposable>","asyncSinkDisposables: Set<AsyncDisposable>","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","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 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 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;\nlet activeScopedConfigCount = 0;\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\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 ? 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 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 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 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(scopedConfig, getGlobalDisposables());\n } catch (disposeError) {\n if (callbackFailed) {\n throwCombinedErrors(callbackError, disposeError);\n }\n throw disposeError;\n } finally {\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 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, getGlobalDisposables());\n } catch (disposeError) {\n if (callbackFailed) {\n throwCombinedErrors(callbackError, disposeError);\n }\n throw disposeError;\n } finally {\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 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 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>","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 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;\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\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 ? 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 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 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 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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"}
@@ -16,12 +16,18 @@ function compileScopedConfig(config, allowAsync, createError) {
16
16
  const nodes = /* @__PURE__ */ new Map();
17
17
  const configuredCategories = /* @__PURE__ */ new Set();
18
18
  for (const logger of config.loggers) {
19
- const category = normalizeCategory(logger.category);
19
+ if (!isObjectLike(logger)) throw createError("Logger configuration must be an object.");
20
+ const loggerConfig = logger;
21
+ const category = normalizeCategory(loggerConfig.category, createError);
22
+ if (loggerConfig.sinks !== void 0 && !Array.isArray(loggerConfig.sinks)) throw createError("Logger sinks must be an array.");
23
+ if (loggerConfig.filters !== void 0 && !Array.isArray(loggerConfig.filters)) throw createError("Logger filters must be an array.");
24
+ if (loggerConfig.parentSinks !== void 0 && loggerConfig.parentSinks !== "inherit" && loggerConfig.parentSinks !== "override") throw createError("Logger parentSinks must be \"inherit\" or \"override\".");
25
+ if (loggerConfig.lowestLevel !== void 0 && loggerConfig.lowestLevel !== null && !require_level.isLogLevel(loggerConfig.lowestLevel)) throw createError("Logger lowestLevel must be a log level or null.");
20
26
  const key = categoryKey(category);
21
27
  if (configuredCategories.has(key)) throw createError(`Duplicate logger configuration for category: ${key}. Each category can only be configured once.`);
22
28
  configuredCategories.add(key);
23
29
  const sinks = [];
24
- const sinkIds = logger.sinks ?? [];
30
+ const sinkIds = loggerConfig.sinks ?? [];
25
31
  for (const sinkId of sinkIds) {
26
32
  const sink = config.sinks[sinkId];
27
33
  if (!sink) throw createError(`Sink not found: ${sinkId}.`);
@@ -29,7 +35,7 @@ function compileScopedConfig(config, allowAsync, createError) {
29
35
  sinks.push(sink);
30
36
  }
31
37
  const filters = [];
32
- const filterIds = logger.filters ?? [];
38
+ const filterIds = loggerConfig.filters ?? [];
33
39
  for (const filterId of filterIds) {
34
40
  const filter = config.filters?.[filterId];
35
41
  if (filter === void 0) throw createError(`Filter not found: ${filterId}.`);
@@ -38,8 +44,8 @@ function compileScopedConfig(config, allowAsync, createError) {
38
44
  }
39
45
  nodes.set(key, {
40
46
  filters,
41
- lowestLevel: logger.lowestLevel === void 0 ? "trace" : logger.lowestLevel,
42
- parentSinks: logger.parentSinks ?? "inherit",
47
+ lowestLevel: loggerConfig.lowestLevel === void 0 ? "trace" : loggerConfig.lowestLevel,
48
+ parentSinks: loggerConfig.parentSinks ?? "inherit",
43
49
  sinks
44
50
  });
45
51
  }
@@ -52,8 +58,7 @@ function compileScopedConfig(config, allowAsync, createError) {
52
58
  if (Symbol.asyncDispose in sink) {
53
59
  if (!allowAsync) throw createError("Async disposables cannot be used with withConfigSync().");
54
60
  asyncSinks.add(sink);
55
- }
56
- if (Symbol.dispose in sink) syncSinks.add(sink);
61
+ } else if (Symbol.dispose in sink) syncSinks.add(sink);
57
62
  }
58
63
  for (const filter of Object.values(config.filters ?? {})) {
59
64
  if (!isObjectLike(filter)) continue;
@@ -61,8 +66,7 @@ function compileScopedConfig(config, allowAsync, createError) {
61
66
  if (!allowAsync) throw createError("Async disposables cannot be used with withConfigSync().");
62
67
  asyncFilters.add(filter);
63
68
  asyncSinks.delete(filter);
64
- }
65
- if (Symbol.dispose in filter) {
69
+ } else if (Symbol.dispose in filter) {
66
70
  syncFilters.add(filter);
67
71
  syncSinks.delete(filter);
68
72
  }
@@ -183,8 +187,11 @@ function addScopedDisposables(disposables, scopedConfig) {
183
187
  for (const disposable of scopedConfig.syncSinks) disposables.add(disposable);
184
188
  for (const disposable of scopedConfig.asyncSinks) disposables.add(disposable);
185
189
  }
186
- function normalizeCategory(category) {
187
- return typeof category === "string" ? [category] : [...category];
190
+ function normalizeCategory(category, createError) {
191
+ if (typeof category === "string") return [category];
192
+ if (!Array.isArray(category)) throw createError("Logger category must be a string or array of strings.");
193
+ if (category.some((part) => typeof part !== "string")) throw createError("Logger category must only contain strings.");
194
+ return [...category];
188
195
  }
189
196
  function categoryKey(category) {
190
197
  return JSON.stringify(category);
@@ -232,14 +239,13 @@ function filterScopedRecord(scopedConfig, category, record) {
232
239
  return true;
233
240
  }
234
241
  function disposeSyncDisposables(disposables, retainedDisposables) {
242
+ const disposableList = filterRetainedDisposables(disposables, retainedDisposables);
235
243
  const errors = [];
236
244
  try {
237
- for (const disposable of disposables) try {
238
- if (!retainedDisposables.has(disposable)) disposable[Symbol.dispose]();
245
+ for (const disposable of disposableList) try {
246
+ disposable[Symbol.dispose]();
239
247
  } catch (error) {
240
248
  errors.push(error);
241
- } finally {
242
- disposables.delete(disposable);
243
249
  }
244
250
  } finally {
245
251
  disposables.clear();
@@ -16,12 +16,18 @@ function compileScopedConfig(config, allowAsync, createError) {
16
16
  const nodes = /* @__PURE__ */ new Map();
17
17
  const configuredCategories = /* @__PURE__ */ new Set();
18
18
  for (const logger of config.loggers) {
19
- const category = normalizeCategory(logger.category);
19
+ if (!isObjectLike(logger)) throw createError("Logger configuration must be an object.");
20
+ const loggerConfig = logger;
21
+ const category = normalizeCategory(loggerConfig.category, createError);
22
+ if (loggerConfig.sinks !== void 0 && !Array.isArray(loggerConfig.sinks)) throw createError("Logger sinks must be an array.");
23
+ if (loggerConfig.filters !== void 0 && !Array.isArray(loggerConfig.filters)) throw createError("Logger filters must be an array.");
24
+ if (loggerConfig.parentSinks !== void 0 && loggerConfig.parentSinks !== "inherit" && loggerConfig.parentSinks !== "override") throw createError("Logger parentSinks must be \"inherit\" or \"override\".");
25
+ if (loggerConfig.lowestLevel !== void 0 && loggerConfig.lowestLevel !== null && !isLogLevel(loggerConfig.lowestLevel)) throw createError("Logger lowestLevel must be a log level or null.");
20
26
  const key = categoryKey(category);
21
27
  if (configuredCategories.has(key)) throw createError(`Duplicate logger configuration for category: ${key}. Each category can only be configured once.`);
22
28
  configuredCategories.add(key);
23
29
  const sinks = [];
24
- const sinkIds = logger.sinks ?? [];
30
+ const sinkIds = loggerConfig.sinks ?? [];
25
31
  for (const sinkId of sinkIds) {
26
32
  const sink = config.sinks[sinkId];
27
33
  if (!sink) throw createError(`Sink not found: ${sinkId}.`);
@@ -29,7 +35,7 @@ function compileScopedConfig(config, allowAsync, createError) {
29
35
  sinks.push(sink);
30
36
  }
31
37
  const filters = [];
32
- const filterIds = logger.filters ?? [];
38
+ const filterIds = loggerConfig.filters ?? [];
33
39
  for (const filterId of filterIds) {
34
40
  const filter = config.filters?.[filterId];
35
41
  if (filter === void 0) throw createError(`Filter not found: ${filterId}.`);
@@ -38,8 +44,8 @@ function compileScopedConfig(config, allowAsync, createError) {
38
44
  }
39
45
  nodes.set(key, {
40
46
  filters,
41
- lowestLevel: logger.lowestLevel === void 0 ? "trace" : logger.lowestLevel,
42
- parentSinks: logger.parentSinks ?? "inherit",
47
+ lowestLevel: loggerConfig.lowestLevel === void 0 ? "trace" : loggerConfig.lowestLevel,
48
+ parentSinks: loggerConfig.parentSinks ?? "inherit",
43
49
  sinks
44
50
  });
45
51
  }
@@ -52,8 +58,7 @@ function compileScopedConfig(config, allowAsync, createError) {
52
58
  if (Symbol.asyncDispose in sink) {
53
59
  if (!allowAsync) throw createError("Async disposables cannot be used with withConfigSync().");
54
60
  asyncSinks.add(sink);
55
- }
56
- if (Symbol.dispose in sink) syncSinks.add(sink);
61
+ } else if (Symbol.dispose in sink) syncSinks.add(sink);
57
62
  }
58
63
  for (const filter of Object.values(config.filters ?? {})) {
59
64
  if (!isObjectLike(filter)) continue;
@@ -61,8 +66,7 @@ function compileScopedConfig(config, allowAsync, createError) {
61
66
  if (!allowAsync) throw createError("Async disposables cannot be used with withConfigSync().");
62
67
  asyncFilters.add(filter);
63
68
  asyncSinks.delete(filter);
64
- }
65
- if (Symbol.dispose in filter) {
69
+ } else if (Symbol.dispose in filter) {
66
70
  syncFilters.add(filter);
67
71
  syncSinks.delete(filter);
68
72
  }
@@ -183,8 +187,11 @@ function addScopedDisposables(disposables, scopedConfig) {
183
187
  for (const disposable of scopedConfig.syncSinks) disposables.add(disposable);
184
188
  for (const disposable of scopedConfig.asyncSinks) disposables.add(disposable);
185
189
  }
186
- function normalizeCategory(category) {
187
- return typeof category === "string" ? [category] : [...category];
190
+ function normalizeCategory(category, createError) {
191
+ if (typeof category === "string") return [category];
192
+ if (!Array.isArray(category)) throw createError("Logger category must be a string or array of strings.");
193
+ if (category.some((part) => typeof part !== "string")) throw createError("Logger category must only contain strings.");
194
+ return [...category];
188
195
  }
189
196
  function categoryKey(category) {
190
197
  return JSON.stringify(category);
@@ -232,14 +239,13 @@ function filterScopedRecord(scopedConfig, category, record) {
232
239
  return true;
233
240
  }
234
241
  function disposeSyncDisposables(disposables, retainedDisposables) {
242
+ const disposableList = filterRetainedDisposables(disposables, retainedDisposables);
235
243
  const errors = [];
236
244
  try {
237
- for (const disposable of disposables) try {
238
- if (!retainedDisposables.has(disposable)) disposable[Symbol.dispose]();
245
+ for (const disposable of disposableList) try {
246
+ disposable[Symbol.dispose]();
239
247
  } catch (error) {
240
248
  errors.push(error);
241
- } finally {
242
- disposables.delete(disposable);
243
249
  }
244
250
  } finally {
245
251
  disposables.clear();
@@ -1 +1 @@
1
- {"version":3,"file":"scoped-config.js","names":["scopedConfigSymbol: unique symbol","defaultScopedLogger: CompiledScopedLogger","config: ScopedConfigLike<TSinkId, TFilterId>","allowAsync: boolean","createError: (message: string) => Error","sinks: Sink[]","sinkIds: readonly TSinkId[]","filters: ((record: LogRecord) => boolean)[]","filterIds: readonly TFilterId[]","contextLocalStorage:\n | ContextLocalStorage<Record<string, unknown>>\n | undefined","contextLocalStorage: ContextLocalStorage<Record<string, unknown>>","scopedConfig: CompiledScopedConfig","callback: () => R","category: readonly string[]","level: LogLevel","record: LogRecord","bypassSinks: Set<Sink> | undefined","emitToSink: (sink: Sink, bypassSinks: Set<Sink> | undefined) => void","retainedDisposables?: ReadonlySet<Disposable | AsyncDisposable>","errors: unknown[]","primary: unknown","secondary: unknown","value: unknown","activeConfig: CompiledScopedConfig | undefined","extraRetained?: ReadonlySet<Disposable | AsyncDisposable>","disposables: Set<Disposable | AsyncDisposable>","category: string | readonly string[]","length: number","firstSink: Sink | undefined","sinks: Sink[] | undefined","sink: Sink","disposables: Set<Disposable>","retainedDisposables: ReadonlySet<Disposable | AsyncDisposable>","disposables: Set<AsyncDisposable>","disposables: ReadonlySet<TDisposable>","errors: readonly unknown[]","flattened: unknown[]"],"sources":["../src/scoped-config.ts"],"sourcesContent":["import type { ContextLocalStorage } from \"./context.ts\";\nimport { type FilterLike, toFilter } from \"./filter.ts\";\nimport { compareLogLevel, isLogLevel, type LogLevel } from \"./level.ts\";\nimport type { LogRecord } from \"./record.ts\";\nimport type { Sink } from \"./sink.ts\";\n\nexport type ScopedConfigSymbol = typeof scopedConfigSymbol;\n\nexport const scopedConfigSymbol: unique symbol = Symbol.for(\n \"logtape.scopedConfig\",\n);\n\nexport interface ScopedConfigLike<\n TSinkId extends string,\n TFilterId extends string,\n> {\n readonly sinks: Record<TSinkId, Sink>;\n readonly filters?: Record<TFilterId, FilterLike>;\n readonly loggers: readonly ScopedLoggerConfigLike<TSinkId, TFilterId>[];\n}\n\nexport interface ScopedLoggerConfigLike<\n TSinkId extends string,\n TFilterId extends string,\n> {\n readonly category: string | readonly string[];\n readonly sinks?: readonly TSinkId[];\n readonly parentSinks?: \"inherit\" | \"override\";\n readonly filters?: readonly TFilterId[];\n readonly lowestLevel?: LogLevel | null;\n}\n\nexport interface CompiledScopedConfig {\n readonly nodes: ReadonlyMap<string, CompiledScopedLogger>;\n readonly dispatchCache: Map<string, ScopedSinkDispatchPlan>;\n parent: CompiledScopedConfig | undefined;\n disposed: boolean;\n readonly syncFilters: Set<Disposable>;\n readonly asyncFilters: Set<AsyncDisposable>;\n readonly syncSinks: Set<Disposable>;\n readonly asyncSinks: Set<AsyncDisposable>;\n}\n\ninterface CompiledScopedLogger {\n readonly filters: readonly ((record: LogRecord) => boolean)[];\n readonly lowestLevel: LogLevel | null;\n readonly parentSinks: \"inherit\" | \"override\";\n readonly sinks: readonly Sink[];\n}\n\ntype ScopedSinkDispatchPlan =\n | { readonly kind: \"none\" }\n | { readonly kind: \"one\"; readonly sink: Sink }\n | { readonly kind: \"many\"; readonly sinks: readonly Sink[] };\n\nconst defaultScopedLogger: CompiledScopedLogger = {\n filters: [],\n lowestLevel: \"trace\",\n parentSinks: \"inherit\",\n sinks: [],\n};\n\nexport function compileScopedConfig<\n TSinkId extends string,\n TFilterId extends string,\n>(\n config: ScopedConfigLike<TSinkId, TFilterId>,\n allowAsync: boolean,\n createError: (message: string) => Error,\n): CompiledScopedConfig {\n if (!isObjectLike(config)) {\n throw createError(\"Configuration must be an object.\");\n }\n if (!isObjectLike(config.sinks)) {\n throw createError(\"Configuration must include a sinks object.\");\n }\n if (!Array.isArray(config.loggers)) {\n throw createError(\"Configuration must include a loggers array.\");\n }\n\n const nodes = new Map<string, CompiledScopedLogger>();\n const configuredCategories = new Set<string>();\n for (const logger of config.loggers) {\n const category = normalizeCategory(logger.category);\n const key = categoryKey(category);\n if (configuredCategories.has(key)) {\n throw createError(\n `Duplicate logger configuration for category: ${key}. ` +\n \"Each category can only be configured once.\",\n );\n }\n configuredCategories.add(key);\n\n const sinks: Sink[] = [];\n const sinkIds: readonly TSinkId[] = logger.sinks ?? [];\n for (const sinkId of sinkIds) {\n const sink = config.sinks[sinkId];\n if (!sink) throw createError(`Sink not found: ${sinkId}.`);\n if (typeof sink !== \"function\") {\n throw createError(`Sink must be a function: ${sinkId}.`);\n }\n sinks.push(sink);\n }\n\n const filters: ((record: LogRecord) => boolean)[] = [];\n const filterIds: readonly TFilterId[] = logger.filters ?? [];\n for (const filterId of filterIds) {\n const filter = config.filters?.[filterId];\n if (filter === undefined) {\n throw createError(`Filter not found: ${filterId}.`);\n }\n if (!isFilterLike(filter)) {\n throw createError(\n `Filter must be a function, log level, or null: ${filterId}.`,\n );\n }\n filters.push(toFilter(filter));\n }\n\n nodes.set(key, {\n filters,\n lowestLevel: logger.lowestLevel === undefined\n ? \"trace\"\n : logger.lowestLevel,\n parentSinks: logger.parentSinks ?? \"inherit\",\n sinks,\n });\n }\n\n const syncFilters = new Set<Disposable>();\n const asyncFilters = new Set<AsyncDisposable>();\n const syncSinks = new Set<Disposable>();\n const asyncSinks = new Set<AsyncDisposable>();\n\n for (const sink of Object.values<Sink>(config.sinks)) {\n if (!isObjectLike(sink)) continue;\n if (Symbol.asyncDispose in sink) {\n if (!allowAsync) {\n throw createError(\n \"Async disposables cannot be used with withConfigSync().\",\n );\n }\n asyncSinks.add(sink as AsyncDisposable);\n }\n if (Symbol.dispose in sink) syncSinks.add(sink as Disposable);\n }\n\n for (const filter of Object.values<FilterLike>(config.filters ?? {})) {\n if (!isObjectLike(filter)) continue;\n if (Symbol.asyncDispose in filter) {\n if (!allowAsync) {\n throw createError(\n \"Async disposables cannot be used with withConfigSync().\",\n );\n }\n asyncFilters.add(filter as AsyncDisposable);\n asyncSinks.delete(filter as AsyncDisposable);\n }\n if (Symbol.dispose in filter) {\n syncFilters.add(filter as Disposable);\n syncSinks.delete(filter as Disposable);\n }\n }\n\n return {\n asyncFilters,\n asyncSinks,\n dispatchCache: new Map(),\n disposed: false,\n nodes,\n parent: undefined,\n syncFilters,\n syncSinks,\n };\n}\n\nexport function getCurrentScopedConfig(\n contextLocalStorage:\n | ContextLocalStorage<Record<string, unknown>>\n | undefined,\n): CompiledScopedConfig | undefined {\n const store = contextLocalStorage?.getStore();\n const scopedConfig = (store as Record<ScopedConfigSymbol, unknown> | null)\n ?.[scopedConfigSymbol];\n return isCompiledScopedConfig(scopedConfig)\n ? getActiveScopedConfig(scopedConfig)\n : undefined;\n}\n\nexport function runWithScopedConfig<R>(\n contextLocalStorage: ContextLocalStorage<Record<string, unknown>>,\n scopedConfig: CompiledScopedConfig,\n callback: () => R,\n): R {\n const parentStore = contextLocalStorage.getStore() ?? {};\n scopedConfig.parent = getCurrentScopedConfig(contextLocalStorage);\n return contextLocalStorage.run({\n ...parentStore,\n [scopedConfigSymbol]: scopedConfig,\n } as Record<string, unknown>, callback);\n}\n\nexport function scopedConfigHasSink(\n scopedConfig: CompiledScopedConfig,\n category: readonly string[],\n level: LogLevel,\n): boolean {\n return getScopedSinkDispatchPlan(scopedConfig, category, level).kind !==\n \"none\";\n}\n\nexport function emitWithScopedConfig(\n scopedConfig: CompiledScopedConfig,\n record: LogRecord,\n bypassSinks: Set<Sink> | undefined,\n emitToSink: (sink: Sink, bypassSinks: Set<Sink> | undefined) => void,\n): void {\n const plan = getScopedSinkDispatchPlan(\n scopedConfig,\n record.category,\n record.level,\n );\n if (plan.kind === \"none\") return;\n if (!filterScopedRecord(scopedConfig, record.category, record)) return;\n if (plan.kind === \"one\") {\n if (!bypassSinks?.has(plan.sink)) emitToSink(plan.sink, bypassSinks);\n return;\n }\n for (const sink of plan.sinks) {\n if (bypassSinks?.has(sink)) continue;\n emitToSink(sink, bypassSinks);\n }\n}\n\nexport async function disposeScopedConfig(\n scopedConfig: CompiledScopedConfig,\n retainedDisposables?: ReadonlySet<Disposable | AsyncDisposable>,\n): Promise<void> {\n const parentDisposables = getParentScopedDisposables(\n scopedConfig,\n retainedDisposables,\n );\n scopedConfig.disposed = true;\n const errors: unknown[] = [];\n try {\n disposeSyncDisposables(scopedConfig.syncFilters, parentDisposables);\n } catch (error) {\n errors.push(error);\n }\n try {\n await disposeAsyncDisposables(scopedConfig.asyncFilters, parentDisposables);\n } catch (error) {\n errors.push(error);\n }\n try {\n disposeSyncDisposables(scopedConfig.syncSinks, parentDisposables);\n } catch (error) {\n errors.push(error);\n }\n try {\n await disposeAsyncDisposables(scopedConfig.asyncSinks, parentDisposables);\n } catch (error) {\n errors.push(error);\n }\n throwDisposeErrors(errors);\n}\n\nexport function disposeScopedConfigSync(\n scopedConfig: CompiledScopedConfig,\n retainedDisposables?: ReadonlySet<Disposable | AsyncDisposable>,\n): void {\n const parentDisposables = getParentScopedDisposables(\n scopedConfig,\n retainedDisposables,\n );\n scopedConfig.disposed = true;\n const errors: unknown[] = [];\n try {\n disposeSyncDisposables(scopedConfig.syncFilters, parentDisposables);\n } catch (error) {\n errors.push(error);\n }\n try {\n disposeSyncDisposables(scopedConfig.syncSinks, parentDisposables);\n } catch (error) {\n errors.push(error);\n }\n throwDisposeErrors(errors);\n}\n\nexport function throwCombinedErrors(\n primary: unknown,\n secondary: unknown,\n): never {\n throw new AggregateError(\n flattenErrors(primary, secondary),\n \"Multiple errors occurred while running LogTape scoped configuration.\",\n );\n}\n\nfunction isCompiledScopedConfig(value: unknown): value is CompiledScopedConfig {\n return value != null && typeof value === \"object\" && \"nodes\" in value;\n}\n\nfunction isObjectLike(\n value: unknown,\n): value is object | ((...args: never[]) => unknown) {\n return value != null &&\n (typeof value === \"object\" || typeof value === \"function\");\n}\n\nfunction isFilterLike(value: unknown): value is FilterLike {\n return value == null || typeof value === \"function\" ||\n (typeof value === \"string\" && isLogLevel(value));\n}\n\nfunction getActiveScopedConfig(\n scopedConfig: CompiledScopedConfig,\n): CompiledScopedConfig | undefined {\n let activeConfig: CompiledScopedConfig | undefined = scopedConfig;\n while (activeConfig?.disposed) activeConfig = activeConfig.parent;\n return activeConfig;\n}\n\nfunction getParentScopedDisposables(\n scopedConfig: CompiledScopedConfig,\n extraRetained?: ReadonlySet<Disposable | AsyncDisposable>,\n): ReadonlySet<Disposable | AsyncDisposable> {\n const disposables = new Set<Disposable | AsyncDisposable>(extraRetained);\n let parent = scopedConfig.parent;\n while (parent != null) {\n const activeParent = getActiveScopedConfig(parent);\n if (activeParent == null) break;\n addScopedDisposables(disposables, activeParent);\n parent = activeParent.parent;\n }\n return disposables;\n}\n\nfunction addScopedDisposables(\n disposables: Set<Disposable | AsyncDisposable>,\n scopedConfig: CompiledScopedConfig,\n): void {\n for (const disposable of scopedConfig.syncFilters) {\n disposables.add(disposable);\n }\n for (const disposable of scopedConfig.asyncFilters) {\n disposables.add(disposable);\n }\n for (const disposable of scopedConfig.syncSinks) disposables.add(disposable);\n for (const disposable of scopedConfig.asyncSinks) disposables.add(disposable);\n}\n\nfunction normalizeCategory(category: string | readonly string[]): string[] {\n return typeof category === \"string\" ? [category] : [...category];\n}\n\nfunction categoryKey(category: readonly string[]): string {\n return JSON.stringify(category);\n}\n\nfunction getScopedSinkDispatchPlan(\n scopedConfig: CompiledScopedConfig,\n category: readonly string[],\n level: LogLevel,\n): ScopedSinkDispatchPlan {\n const cacheKey = `${categoryKey(category)}:${level}`;\n let plan = scopedConfig.dispatchCache.get(cacheKey);\n if (plan == null) {\n plan = getScopedSinkDispatchPlanForPrefix(\n scopedConfig,\n category,\n category.length,\n level,\n );\n scopedConfig.dispatchCache.set(cacheKey, plan);\n }\n return plan;\n}\n\nfunction getScopedSinkDispatchPlanForPrefix(\n scopedConfig: CompiledScopedConfig,\n category: readonly string[],\n length: number,\n level: LogLevel,\n): ScopedSinkDispatchPlan {\n const prefix = category.slice(0, length);\n const logger = scopedConfig.nodes.get(categoryKey(prefix)) ??\n defaultScopedLogger;\n if (\n logger.lowestLevel === null ||\n compareLogLevel(level, logger.lowestLevel) < 0\n ) {\n return { kind: \"none\" };\n }\n\n const parentPlan = length > 0 && logger.parentSinks === \"inherit\"\n ? getScopedSinkDispatchPlanForPrefix(\n scopedConfig,\n category,\n length - 1,\n level,\n )\n : { kind: \"none\" } as const;\n\n let firstSink: Sink | undefined;\n let sinks: Sink[] | undefined;\n const appendSink = (sink: Sink): void => {\n if (sinks != null) {\n sinks.push(sink);\n } else if (firstSink == null) {\n firstSink = sink;\n } else {\n sinks = [firstSink, sink];\n }\n };\n\n if (parentPlan.kind === \"one\") appendSink(parentPlan.sink);\n else if (parentPlan.kind === \"many\") {\n for (const sink of parentPlan.sinks) appendSink(sink);\n }\n for (const sink of logger.sinks) appendSink(sink);\n\n if (sinks != null) return { kind: \"many\", sinks };\n if (firstSink != null) return { kind: \"one\", sink: firstSink };\n return { kind: \"none\" };\n}\n\nfunction filterScopedRecord(\n scopedConfig: CompiledScopedConfig,\n category: readonly string[],\n record: LogRecord,\n): boolean {\n for (let length = category.length; length >= 0; length--) {\n const logger = scopedConfig.nodes.get(\n categoryKey(category.slice(0, length)),\n );\n if (logger == null || logger.filters.length < 1) continue;\n return logger.filters.every((filter) => filter(record));\n }\n return true;\n}\n\nfunction disposeSyncDisposables(\n disposables: Set<Disposable>,\n retainedDisposables: ReadonlySet<Disposable | AsyncDisposable>,\n): void {\n const errors: unknown[] = [];\n try {\n for (const disposable of disposables) {\n try {\n if (!retainedDisposables.has(disposable)) {\n disposable[Symbol.dispose]();\n }\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 disposeAsyncDisposables(\n disposables: Set<AsyncDisposable>,\n retainedDisposables: ReadonlySet<Disposable | AsyncDisposable>,\n): Promise<void> {\n const disposableList = filterRetainedDisposables(\n disposables,\n retainedDisposables,\n );\n for (const disposable of disposableList) disposables.delete(disposable);\n try {\n const results = await Promise.allSettled(\n disposableList.map((disposable) =>\n Promise.resolve().then(() => disposable[Symbol.asyncDispose]())\n ),\n );\n throwDisposeErrors(\n results\n .filter((result): result is PromiseRejectedResult =>\n result.status === \"rejected\"\n )\n .map((result) => result.reason),\n );\n } finally {\n disposables.clear();\n }\n}\n\nfunction filterRetainedDisposables<\n TDisposable extends Disposable | AsyncDisposable,\n>(\n disposables: ReadonlySet<TDisposable>,\n retainedDisposables: ReadonlySet<Disposable | AsyncDisposable>,\n): TDisposable[] {\n return Array.from(\n disposables,\n ).filter((disposable) => !retainedDisposables.has(disposable));\n}\n\nfunction throwDisposeErrors(errors: readonly unknown[]): void {\n if (errors.length < 1) return;\n if (errors.length === 1) throw errors[0];\n throw new AggregateError(\n errors,\n \"Multiple errors occurred while disposing LogTape scoped resources.\",\n );\n}\n\nfunction flattenErrors(...errors: readonly unknown[]): unknown[] {\n const flattened: unknown[] = [];\n for (const error of errors) {\n if (error instanceof AggregateError) flattened.push(...error.errors);\n else flattened.push(error);\n }\n return flattened;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"scoped-config.js","names":["scopedConfigSymbol: unique symbol","defaultScopedLogger: CompiledScopedLogger","config: ScopedConfigLike<TSinkId, TFilterId>","allowAsync: boolean","createError: (message: string) => Error","sinks: Sink[]","sinkIds: readonly TSinkId[]","filters: ((record: LogRecord) => boolean)[]","filterIds: readonly TFilterId[]","contextLocalStorage:\n | ContextLocalStorage<Record<string, unknown>>\n | undefined","contextLocalStorage: ContextLocalStorage<Record<string, unknown>>","scopedConfig: CompiledScopedConfig","callback: () => R","category: readonly string[]","level: LogLevel","record: LogRecord","bypassSinks: Set<Sink> | undefined","emitToSink: (sink: Sink, bypassSinks: Set<Sink> | undefined) => void","retainedDisposables?: ReadonlySet<Disposable | AsyncDisposable>","errors: unknown[]","primary: unknown","secondary: unknown","value: unknown","activeConfig: CompiledScopedConfig | undefined","extraRetained?: ReadonlySet<Disposable | AsyncDisposable>","disposables: Set<Disposable | AsyncDisposable>","category: unknown","length: number","firstSink: Sink | undefined","sinks: Sink[] | undefined","sink: Sink","disposables: Set<Disposable>","retainedDisposables: ReadonlySet<Disposable | AsyncDisposable>","disposables: Set<AsyncDisposable>","disposables: ReadonlySet<TDisposable>","errors: readonly unknown[]","flattened: unknown[]"],"sources":["../src/scoped-config.ts"],"sourcesContent":["import type { ContextLocalStorage } from \"./context.ts\";\nimport { type FilterLike, toFilter } from \"./filter.ts\";\nimport { compareLogLevel, isLogLevel, type LogLevel } from \"./level.ts\";\nimport type { LogRecord } from \"./record.ts\";\nimport type { Sink } from \"./sink.ts\";\n\nexport type ScopedConfigSymbol = typeof scopedConfigSymbol;\n\nexport const scopedConfigSymbol: unique symbol = Symbol.for(\n \"logtape.scopedConfig\",\n);\n\nexport interface ScopedConfigLike<\n TSinkId extends string,\n TFilterId extends string,\n> {\n readonly sinks: Record<TSinkId, Sink>;\n readonly filters?: Record<TFilterId, FilterLike>;\n readonly loggers: readonly ScopedLoggerConfigLike<TSinkId, TFilterId>[];\n}\n\nexport interface ScopedLoggerConfigLike<\n TSinkId extends string,\n TFilterId extends string,\n> {\n readonly category: string | readonly string[];\n readonly sinks?: readonly TSinkId[];\n readonly parentSinks?: \"inherit\" | \"override\";\n readonly filters?: readonly TFilterId[];\n readonly lowestLevel?: LogLevel | null;\n}\n\nexport interface CompiledScopedConfig {\n readonly nodes: ReadonlyMap<string, CompiledScopedLogger>;\n readonly dispatchCache: Map<string, ScopedSinkDispatchPlan>;\n parent: CompiledScopedConfig | undefined;\n disposed: boolean;\n readonly syncFilters: Set<Disposable>;\n readonly asyncFilters: Set<AsyncDisposable>;\n readonly syncSinks: Set<Disposable>;\n readonly asyncSinks: Set<AsyncDisposable>;\n}\n\ninterface CompiledScopedLogger {\n readonly filters: readonly ((record: LogRecord) => boolean)[];\n readonly lowestLevel: LogLevel | null;\n readonly parentSinks: \"inherit\" | \"override\";\n readonly sinks: readonly Sink[];\n}\n\ntype ScopedSinkDispatchPlan =\n | { readonly kind: \"none\" }\n | { readonly kind: \"one\"; readonly sink: Sink }\n | { readonly kind: \"many\"; readonly sinks: readonly Sink[] };\n\nconst defaultScopedLogger: CompiledScopedLogger = {\n filters: [],\n lowestLevel: \"trace\",\n parentSinks: \"inherit\",\n sinks: [],\n};\n\nexport function compileScopedConfig<\n TSinkId extends string,\n TFilterId extends string,\n>(\n config: ScopedConfigLike<TSinkId, TFilterId>,\n allowAsync: boolean,\n createError: (message: string) => Error,\n): CompiledScopedConfig {\n if (!isObjectLike(config)) {\n throw createError(\"Configuration must be an object.\");\n }\n if (!isObjectLike(config.sinks)) {\n throw createError(\"Configuration must include a sinks object.\");\n }\n if (!Array.isArray(config.loggers)) {\n throw createError(\"Configuration must include a loggers array.\");\n }\n\n const nodes = new Map<string, CompiledScopedLogger>();\n const configuredCategories = new Set<string>();\n for (const logger of config.loggers) {\n if (!isObjectLike(logger)) {\n throw createError(\"Logger configuration must be an object.\");\n }\n const loggerConfig = logger as ScopedLoggerConfigLike<TSinkId, TFilterId>;\n const category = normalizeCategory(loggerConfig.category, createError);\n if (\n loggerConfig.sinks !== undefined && !Array.isArray(loggerConfig.sinks)\n ) {\n throw createError(\"Logger sinks must be an array.\");\n }\n if (\n loggerConfig.filters !== undefined &&\n !Array.isArray(loggerConfig.filters)\n ) {\n throw createError(\"Logger filters must be an array.\");\n }\n if (\n loggerConfig.parentSinks !== undefined &&\n loggerConfig.parentSinks !== \"inherit\" &&\n loggerConfig.parentSinks !== \"override\"\n ) {\n throw createError(\n 'Logger parentSinks must be \"inherit\" or \"override\".',\n );\n }\n if (\n loggerConfig.lowestLevel !== undefined &&\n loggerConfig.lowestLevel !== null &&\n !isLogLevel(loggerConfig.lowestLevel)\n ) {\n throw createError(\"Logger lowestLevel must be a log level or null.\");\n }\n const key = categoryKey(category);\n if (configuredCategories.has(key)) {\n throw createError(\n `Duplicate logger configuration for category: ${key}. ` +\n \"Each category can only be configured once.\",\n );\n }\n configuredCategories.add(key);\n\n const sinks: Sink[] = [];\n const sinkIds: readonly TSinkId[] = loggerConfig.sinks ?? [];\n for (const sinkId of sinkIds) {\n const sink = config.sinks[sinkId];\n if (!sink) throw createError(`Sink not found: ${sinkId}.`);\n if (typeof sink !== \"function\") {\n throw createError(`Sink must be a function: ${sinkId}.`);\n }\n sinks.push(sink);\n }\n\n const filters: ((record: LogRecord) => boolean)[] = [];\n const filterIds: readonly TFilterId[] = loggerConfig.filters ?? [];\n for (const filterId of filterIds) {\n const filter = config.filters?.[filterId];\n if (filter === undefined) {\n throw createError(`Filter not found: ${filterId}.`);\n }\n if (!isFilterLike(filter)) {\n throw createError(\n `Filter must be a function, log level, or null: ${filterId}.`,\n );\n }\n filters.push(toFilter(filter));\n }\n\n nodes.set(key, {\n filters,\n lowestLevel: loggerConfig.lowestLevel === undefined\n ? \"trace\"\n : loggerConfig.lowestLevel,\n parentSinks: loggerConfig.parentSinks ?? \"inherit\",\n sinks,\n });\n }\n\n const syncFilters = new Set<Disposable>();\n const asyncFilters = new Set<AsyncDisposable>();\n const syncSinks = new Set<Disposable>();\n const asyncSinks = new Set<AsyncDisposable>();\n\n for (const sink of Object.values<Sink>(config.sinks)) {\n if (!isObjectLike(sink)) continue;\n if (Symbol.asyncDispose in sink) {\n if (!allowAsync) {\n throw createError(\n \"Async disposables cannot be used with withConfigSync().\",\n );\n }\n asyncSinks.add(sink as AsyncDisposable);\n } else if (Symbol.dispose in sink) syncSinks.add(sink as Disposable);\n }\n\n for (const filter of Object.values<FilterLike>(config.filters ?? {})) {\n if (!isObjectLike(filter)) continue;\n if (Symbol.asyncDispose in filter) {\n if (!allowAsync) {\n throw createError(\n \"Async disposables cannot be used with withConfigSync().\",\n );\n }\n asyncFilters.add(filter as AsyncDisposable);\n asyncSinks.delete(filter as AsyncDisposable);\n } else if (Symbol.dispose in filter) {\n syncFilters.add(filter as Disposable);\n syncSinks.delete(filter as Disposable);\n }\n }\n\n return {\n asyncFilters,\n asyncSinks,\n dispatchCache: new Map(),\n disposed: false,\n nodes,\n parent: undefined,\n syncFilters,\n syncSinks,\n };\n}\n\nexport function getCurrentScopedConfig(\n contextLocalStorage:\n | ContextLocalStorage<Record<string, unknown>>\n | undefined,\n): CompiledScopedConfig | undefined {\n const store = contextLocalStorage?.getStore();\n const scopedConfig = (store as Record<ScopedConfigSymbol, unknown> | null)\n ?.[scopedConfigSymbol];\n return isCompiledScopedConfig(scopedConfig)\n ? getActiveScopedConfig(scopedConfig)\n : undefined;\n}\n\nexport function runWithScopedConfig<R>(\n contextLocalStorage: ContextLocalStorage<Record<string, unknown>>,\n scopedConfig: CompiledScopedConfig,\n callback: () => R,\n): R {\n const parentStore = contextLocalStorage.getStore() ?? {};\n scopedConfig.parent = getCurrentScopedConfig(contextLocalStorage);\n return contextLocalStorage.run({\n ...parentStore,\n [scopedConfigSymbol]: scopedConfig,\n } as Record<string, unknown>, callback);\n}\n\nexport function scopedConfigHasSink(\n scopedConfig: CompiledScopedConfig,\n category: readonly string[],\n level: LogLevel,\n): boolean {\n return getScopedSinkDispatchPlan(scopedConfig, category, level).kind !==\n \"none\";\n}\n\nexport function emitWithScopedConfig(\n scopedConfig: CompiledScopedConfig,\n record: LogRecord,\n bypassSinks: Set<Sink> | undefined,\n emitToSink: (sink: Sink, bypassSinks: Set<Sink> | undefined) => void,\n): void {\n const plan = getScopedSinkDispatchPlan(\n scopedConfig,\n record.category,\n record.level,\n );\n if (plan.kind === \"none\") return;\n if (!filterScopedRecord(scopedConfig, record.category, record)) return;\n if (plan.kind === \"one\") {\n if (!bypassSinks?.has(plan.sink)) emitToSink(plan.sink, bypassSinks);\n return;\n }\n for (const sink of plan.sinks) {\n if (bypassSinks?.has(sink)) continue;\n emitToSink(sink, bypassSinks);\n }\n}\n\nexport async function disposeScopedConfig(\n scopedConfig: CompiledScopedConfig,\n retainedDisposables?: ReadonlySet<Disposable | AsyncDisposable>,\n): Promise<void> {\n const parentDisposables = getParentScopedDisposables(\n scopedConfig,\n retainedDisposables,\n );\n scopedConfig.disposed = true;\n const errors: unknown[] = [];\n try {\n disposeSyncDisposables(scopedConfig.syncFilters, parentDisposables);\n } catch (error) {\n errors.push(error);\n }\n try {\n await disposeAsyncDisposables(scopedConfig.asyncFilters, parentDisposables);\n } catch (error) {\n errors.push(error);\n }\n try {\n disposeSyncDisposables(scopedConfig.syncSinks, parentDisposables);\n } catch (error) {\n errors.push(error);\n }\n try {\n await disposeAsyncDisposables(scopedConfig.asyncSinks, parentDisposables);\n } catch (error) {\n errors.push(error);\n }\n throwDisposeErrors(errors);\n}\n\nexport function disposeScopedConfigSync(\n scopedConfig: CompiledScopedConfig,\n retainedDisposables?: ReadonlySet<Disposable | AsyncDisposable>,\n): void {\n const parentDisposables = getParentScopedDisposables(\n scopedConfig,\n retainedDisposables,\n );\n scopedConfig.disposed = true;\n const errors: unknown[] = [];\n try {\n disposeSyncDisposables(scopedConfig.syncFilters, parentDisposables);\n } catch (error) {\n errors.push(error);\n }\n try {\n disposeSyncDisposables(scopedConfig.syncSinks, parentDisposables);\n } catch (error) {\n errors.push(error);\n }\n throwDisposeErrors(errors);\n}\n\nexport function throwCombinedErrors(\n primary: unknown,\n secondary: unknown,\n): never {\n throw new AggregateError(\n flattenErrors(primary, secondary),\n \"Multiple errors occurred while running LogTape scoped configuration.\",\n );\n}\n\nfunction isCompiledScopedConfig(value: unknown): value is CompiledScopedConfig {\n return value != null && typeof value === \"object\" && \"nodes\" in value;\n}\n\nfunction isObjectLike(\n value: unknown,\n): value is object | ((...args: never[]) => unknown) {\n return value != null &&\n (typeof value === \"object\" || typeof value === \"function\");\n}\n\nfunction isFilterLike(value: unknown): value is FilterLike {\n return value == null || typeof value === \"function\" ||\n (typeof value === \"string\" && isLogLevel(value));\n}\n\nfunction getActiveScopedConfig(\n scopedConfig: CompiledScopedConfig,\n): CompiledScopedConfig | undefined {\n let activeConfig: CompiledScopedConfig | undefined = scopedConfig;\n while (activeConfig?.disposed) activeConfig = activeConfig.parent;\n return activeConfig;\n}\n\nfunction getParentScopedDisposables(\n scopedConfig: CompiledScopedConfig,\n extraRetained?: ReadonlySet<Disposable | AsyncDisposable>,\n): ReadonlySet<Disposable | AsyncDisposable> {\n const disposables = new Set<Disposable | AsyncDisposable>(extraRetained);\n let parent = scopedConfig.parent;\n while (parent != null) {\n const activeParent = getActiveScopedConfig(parent);\n if (activeParent == null) break;\n addScopedDisposables(disposables, activeParent);\n parent = activeParent.parent;\n }\n return disposables;\n}\n\nfunction addScopedDisposables(\n disposables: Set<Disposable | AsyncDisposable>,\n scopedConfig: CompiledScopedConfig,\n): void {\n for (const disposable of scopedConfig.syncFilters) {\n disposables.add(disposable);\n }\n for (const disposable of scopedConfig.asyncFilters) {\n disposables.add(disposable);\n }\n for (const disposable of scopedConfig.syncSinks) disposables.add(disposable);\n for (const disposable of scopedConfig.asyncSinks) disposables.add(disposable);\n}\n\nfunction normalizeCategory(\n category: unknown,\n createError: (message: string) => Error,\n): string[] {\n if (typeof category === \"string\") return [category];\n if (!Array.isArray(category)) {\n throw createError(\"Logger category must be a string or array of strings.\");\n }\n if (category.some((part) => typeof part !== \"string\")) {\n throw createError(\"Logger category must only contain strings.\");\n }\n return [...category];\n}\n\nfunction categoryKey(category: readonly string[]): string {\n return JSON.stringify(category);\n}\n\nfunction getScopedSinkDispatchPlan(\n scopedConfig: CompiledScopedConfig,\n category: readonly string[],\n level: LogLevel,\n): ScopedSinkDispatchPlan {\n const cacheKey = `${categoryKey(category)}:${level}`;\n let plan = scopedConfig.dispatchCache.get(cacheKey);\n if (plan == null) {\n plan = getScopedSinkDispatchPlanForPrefix(\n scopedConfig,\n category,\n category.length,\n level,\n );\n scopedConfig.dispatchCache.set(cacheKey, plan);\n }\n return plan;\n}\n\nfunction getScopedSinkDispatchPlanForPrefix(\n scopedConfig: CompiledScopedConfig,\n category: readonly string[],\n length: number,\n level: LogLevel,\n): ScopedSinkDispatchPlan {\n const prefix = category.slice(0, length);\n const logger = scopedConfig.nodes.get(categoryKey(prefix)) ??\n defaultScopedLogger;\n if (\n logger.lowestLevel === null ||\n compareLogLevel(level, logger.lowestLevel) < 0\n ) {\n return { kind: \"none\" };\n }\n\n const parentPlan = length > 0 && logger.parentSinks === \"inherit\"\n ? getScopedSinkDispatchPlanForPrefix(\n scopedConfig,\n category,\n length - 1,\n level,\n )\n : { kind: \"none\" } as const;\n\n let firstSink: Sink | undefined;\n let sinks: Sink[] | undefined;\n const appendSink = (sink: Sink): void => {\n if (sinks != null) {\n sinks.push(sink);\n } else if (firstSink == null) {\n firstSink = sink;\n } else {\n sinks = [firstSink, sink];\n }\n };\n\n if (parentPlan.kind === \"one\") appendSink(parentPlan.sink);\n else if (parentPlan.kind === \"many\") {\n for (const sink of parentPlan.sinks) appendSink(sink);\n }\n for (const sink of logger.sinks) appendSink(sink);\n\n if (sinks != null) return { kind: \"many\", sinks };\n if (firstSink != null) return { kind: \"one\", sink: firstSink };\n return { kind: \"none\" };\n}\n\nfunction filterScopedRecord(\n scopedConfig: CompiledScopedConfig,\n category: readonly string[],\n record: LogRecord,\n): boolean {\n for (let length = category.length; length >= 0; length--) {\n const logger = scopedConfig.nodes.get(\n categoryKey(category.slice(0, length)),\n );\n if (logger == null || logger.filters.length < 1) continue;\n return logger.filters.every((filter) => filter(record));\n }\n return true;\n}\n\nfunction disposeSyncDisposables(\n disposables: Set<Disposable>,\n retainedDisposables: ReadonlySet<Disposable | AsyncDisposable>,\n): void {\n const disposableList = filterRetainedDisposables(\n disposables,\n retainedDisposables,\n );\n const errors: unknown[] = [];\n try {\n for (const disposable of disposableList) {\n try {\n disposable[Symbol.dispose]();\n } catch (error) {\n errors.push(error);\n }\n }\n } finally {\n disposables.clear();\n }\n throwDisposeErrors(errors);\n}\n\nasync function disposeAsyncDisposables(\n disposables: Set<AsyncDisposable>,\n retainedDisposables: ReadonlySet<Disposable | AsyncDisposable>,\n): Promise<void> {\n const disposableList = filterRetainedDisposables(\n disposables,\n retainedDisposables,\n );\n for (const disposable of disposableList) disposables.delete(disposable);\n try {\n const results = await Promise.allSettled(\n disposableList.map((disposable) =>\n Promise.resolve().then(() => disposable[Symbol.asyncDispose]())\n ),\n );\n throwDisposeErrors(\n results\n .filter((result): result is PromiseRejectedResult =>\n result.status === \"rejected\"\n )\n .map((result) => result.reason),\n );\n } finally {\n disposables.clear();\n }\n}\n\nfunction filterRetainedDisposables<\n TDisposable extends Disposable | AsyncDisposable,\n>(\n disposables: ReadonlySet<TDisposable>,\n retainedDisposables: ReadonlySet<Disposable | AsyncDisposable>,\n): TDisposable[] {\n return Array.from(\n disposables,\n ).filter((disposable) => !retainedDisposables.has(disposable));\n}\n\nfunction throwDisposeErrors(errors: readonly unknown[]): void {\n if (errors.length < 1) return;\n if (errors.length === 1) throw errors[0];\n throw new AggregateError(\n errors,\n \"Multiple errors occurred while disposing LogTape scoped resources.\",\n );\n}\n\nfunction flattenErrors(...errors: readonly unknown[]): unknown[] {\n const flattened: unknown[] = [];\n for (const error of errors) {\n if (error instanceof AggregateError) flattened.push(...error.errors);\n else flattened.push(error);\n }\n return flattened;\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@logtape/logtape",
3
- "version": "2.3.0-dev.805+2fc375ff",
3
+ "version": "2.3.0-dev.809+77fa6f1a",
4
4
  "description": "Unobtrusive logging library with zero dependencies—library-first design for Deno/Node.js/Bun/browsers/edge",
5
5
  "keywords": [
6
6
  "logging",