diff --git a/package.json b/package.json index 9f7da7e..16676ef 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@hibas123/logging", - "version": "2.3.4", + "version": "2.3.5", "description": "", "main": "out/index.js", "types": "out/index.d.ts", diff --git a/src/base.ts b/src/base.ts index 609e288..abc8e62 100644 --- a/src/base.ts +++ b/src/base.ts @@ -1,4 +1,4 @@ -import { Observable } from "@hibas123/utils"; +import { Observable, ObservableInterface } from "@hibas123/utils"; import { ConsoleAdapter } from "./consolewriter"; import inspect from "./inspect"; import { @@ -13,7 +13,6 @@ import { FormattedText, FormattedLine, } from "./types"; -import Logging from "."; const browser = typeof window !== "undefined"; @@ -43,6 +42,24 @@ export interface LoggingBaseOptions { } const adapterCache = new WeakMap(); + +class AdapterSet { + change = new Observable<{ type: "add" | "remove"; adapter: Adapter }>(); + adapters: Set = new Set(); + + addAdapter(adapter: Adapter) { + if (!this.adapters.has(adapter)) { + this.adapters.add(adapter); + this.change.send({ + type: "add", + adapter: adapter, + }); + } + } +} + +const consoleAdapter = new ConsoleAdapter(); + export class LoggingBase { private _formatMap: FormatConfig = new DefaultFormatConfig(); @@ -50,7 +67,7 @@ export class LoggingBase { this._formatMap = value; } - private adapter = new Set(); + private adapterSet: AdapterSet; private adapter_init: Promise[] = []; private timerMap = new Map(); @@ -72,7 +89,10 @@ export class LoggingBase { return this._name; } - constructor(options?: Partial | string) { + constructor( + options?: Partial | string, + adapterSet?: AdapterSet + ) { let opt: Partial; if (!options) opt = {}; else if (typeof options === "string") { @@ -94,8 +114,21 @@ export class LoggingBase { this[key] = (this[key]).bind(this); } + if (adapterSet) { + this.adapterSet = adapterSet; + this.adapterSet.adapters.forEach((a) => this.initAdapter(a)); + } else { + this.adapterSet = new AdapterSet(); + } + + this.adapterSet.change.subscribe((change) => { + if (change.type === "add") { + this.initAdapter(change.adapter); + } + }); + if (config.console) { - this.addAdapter(new ConsoleAdapter()); + this.addAdapter(consoleAdapter); } //Binding function to this @@ -109,40 +142,50 @@ export class LoggingBase { } /** - * Creates a new logging instance, with all the adapters from this one. After that the new Instance operates independent + * Can be used to override function from super class + * @param child New child logging instance + */ + protected postGetChild(child: LoggingBase) {} + + /** + * Creates a new logging instance, with the adapters liked together. * @param name Name/Prefix of the new child. The actual name will resolve as "/" */ getChild(name: string) { - let lg = new LoggingBase({ - console: false, - name: this.name ? this.name + "/" + name : name, - }); - this.adapter.forEach((a) => lg.addAdapter(a)); + let lg = new LoggingBase( + { + console: false, + name: this.name ? this.name + "/" + name : name, + }, + this.adapterSet + ); return lg; } + private initAdapter(adapter: Adapter) { + let cached = adapterCache.get(adapter) || 0; + adapterCache.set(adapter, cached + 1); + + let prms = Promise.resolve( + adapter.init(this.messageObservable.getPublicApi()) + ); + this.adapter_init.push(prms); + } + addAdapter(adapter: Adapter) { - if (!this.adapter.has(adapter)) { - this.adapter.add(adapter); - - let cached = adapterCache.get(adapter) || 0; - adapterCache.set(adapter, cached + 1); - - let prms = Promise.resolve( - adapter.init(this.messageObservable.getPublicApi()) - ); - this.adapter_init.push(prms); - } + this.adapterSet.addAdapter(adapter); } flush(sync: true): void; flush(sync: false): Promise; flush(sync: boolean): void | Promise { if (sync) { - this.adapter.forEach((elm) => elm.flush(true)); + this.adapterSet.adapters.forEach((elm) => elm.flush(true)); } else { let adapters: (void | Promise)[] = []; - this.adapter.forEach((elm) => adapters.push(elm.flush(false))); + this.adapterSet.adapters.forEach((elm) => + adapters.push(elm.flush(false)) + ); return Promise.all(adapters).then(() => {}); } } @@ -153,7 +196,7 @@ export class LoggingBase { if (this.$closed) return; this.$closed = true; - this.adapter.forEach((adapter) => { + this.adapterSet.adapters.forEach((adapter) => { let cached = adapterCache.get(adapter); if (cached) { @@ -167,8 +210,7 @@ export class LoggingBase { adapter.close ? adapter.close() : undefined; }); - this.adapter = undefined; - + this.adapterSet = undefined; this.messageObservable.close(); } diff --git a/src/test.ts b/src/test.ts index 429ceda..24343a4 100644 --- a/src/test.ts +++ b/src/test.ts @@ -49,5 +49,31 @@ Logging.warning("This should not be there 4"); Logging.error("This should be there 1"); Logging.errorMessage("This should be there 2"); +const c1 = Logging.getChild("child-level-1"); + +c1.log("Hello from Child 1"); + +const c2 = c1.getChild("child-level-2"); + +c2.log("Hello from Child 2"); + +c2.addAdapter({ + init: (obs) => + obs.subscribe((msg) => + console.log( + "Adapter adden on child level 2: ", + "---", + msg.name, + msg.text.raw + ) + ), + flush: () => undefined, + close: () => undefined, +}); + +c2.log("MSG from C2"); +c1.log("MSG from C1"); +Logging.log("MSG from root"); + const timer = Logging.time("timer1", "Test Timer"); setTimeout(() => timer.end(), 1000);