From 9d118954155031c7c90875124edbf956582a22a3 Mon Sep 17 00:00:00 2001 From: Shigma Date: Fri, 16 Feb 2024 01:38:55 +0800 Subject: [PATCH] feat(logger): logger as functional service --- packages/cordis/src/index.ts | 6 ++-- packages/cordis/src/worker/logger.ts | 2 -- packages/core/src/context.ts | 2 +- packages/core/src/scope.ts | 2 +- packages/core/tests/associate.spec.ts | 6 ++++ packages/hmr/src/error.ts | 12 +++---- packages/hmr/src/index.ts | 20 ++++++------ packages/logger/src/index.ts | 47 ++++++++++++++++++--------- 8 files changed, 59 insertions(+), 38 deletions(-) diff --git a/packages/cordis/src/index.ts b/packages/cordis/src/index.ts index 8027710..7611a8a 100644 --- a/packages/cordis/src/index.ts +++ b/packages/cordis/src/index.ts @@ -1,5 +1,5 @@ import * as core from '@cordisjs/core' -import * as logger from '@cordisjs/logger' +import { Logger, LoggerService } from '@cordisjs/logger' import { TimerService } from '@cordisjs/timer' export * from '@cordisjs/core' @@ -26,7 +26,7 @@ export class Context extends core.Context { this.provide('logger', undefined, true) this.provide('timer', undefined, true) - this.plugin(logger) + this.plugin(LoggerService) this.plugin(TimerService) } } @@ -34,7 +34,7 @@ export class Context extends core.Context { export abstract class Service extends core.Service { static Context = Context - public logger: logger.Logger + public logger: Logger constructor(ctx: C | undefined, name: string, options?: boolean | core.Service.Options) { super(ctx, name, options) diff --git a/packages/cordis/src/worker/logger.ts b/packages/cordis/src/worker/logger.ts index 55bf0bd..37c1d26 100644 --- a/packages/cordis/src/worker/logger.ts +++ b/packages/cordis/src/worker/logger.ts @@ -8,8 +8,6 @@ declare module '@cordisjs/loader' { } interface LogLevelConfig { - // a little different from @koishijs/utils - // we don't enforce user to provide a base here base?: number [K: string]: LogLevel | undefined } diff --git a/packages/core/src/context.ts b/packages/core/src/context.ts index ebaa9ee..ca5f24e 100644 --- a/packages/core/src/context.ts +++ b/packages/core/src/context.ts @@ -250,7 +250,7 @@ export class Context { while (runtime && !runtime.name) { runtime = runtime.parent.runtime } - return runtime?.name + return runtime?.name! } get events() { diff --git a/packages/core/src/scope.ts b/packages/core/src/scope.ts index 779912a..7d3d48d 100644 --- a/packages/core/src/scope.ts +++ b/packages/core/src/scope.ts @@ -332,7 +332,7 @@ export class MainScope extends EffectScope { super(registry[Context.current] as C, config) registry.set(plugin, this) if (!plugin) { - this.name = 'root' + this.name = 'app' this.isActive = true } else { this.setup() diff --git a/packages/core/tests/associate.spec.ts b/packages/core/tests/associate.spec.ts index b842f62..7f094f2 100644 --- a/packages/core/tests/associate.spec.ts +++ b/packages/core/tests/associate.spec.ts @@ -39,6 +39,7 @@ describe('Association', () => { } root.provide('foo.bar') + root.provide('foo.baz') root.plugin(Foo) expect(root.foo).to.be.instanceof(Foo) root.foo.qux = 2 @@ -47,6 +48,11 @@ describe('Association', () => { expect(root.foo.bar).to.equal(3) expect(root[`foo.qux`]).to.be.undefined expect(root[`foo.bar`]).to.equal(3) + + root.foo.baz = function () { + return this + } + expect(root.foo.baz()).to.be.instanceof(Foo) }) test('associated type', async () => { diff --git a/packages/hmr/src/error.ts b/packages/hmr/src/error.ts index 5be7532..d916309 100644 --- a/packages/hmr/src/error.ts +++ b/packages/hmr/src/error.ts @@ -1,4 +1,4 @@ -import { Logger } from 'cordis' +import { Context } from 'cordis' import { BuildFailure } from 'esbuild' import { codeFrameColumns } from '@babel/code-frame' import { readFileSync } from 'fs' @@ -7,15 +7,15 @@ function isBuildFailure(e: any): e is BuildFailure { return Array.isArray(e?.errors) && e.errors.every((error: any) => error.text) } -export function handleError(e: any, logger: Logger) { +export function handleError(ctx: Context, e: any) { if (!isBuildFailure(e)) { - logger.warn(e) + ctx.logger.warn(e) return } for (const error of e.errors) { if (!error.location) { - logger.warn(error.text) + ctx.logger.warn(error.text) continue } try { @@ -27,9 +27,9 @@ export function handleError(e: any, logger: Logger) { highlightCode: true, message: error.text, }) - logger.warn(`File: ${file}:${line}:${column}\n` + formatted) + ctx.logger.warn(`File: ${file}:${line}:${column}\n` + formatted) } catch (e) { - logger.warn(e) + ctx.logger.warn(e) } } } diff --git a/packages/hmr/src/index.ts b/packages/hmr/src/index.ts index 3702672..2647d8d 100644 --- a/packages/hmr/src/index.ts +++ b/packages/hmr/src/index.ts @@ -37,6 +37,7 @@ interface Reload { } class Watcher extends Service { + static name = 'hmr' static inject = ['loader'] private base: string @@ -73,7 +74,6 @@ class Watcher extends Service { constructor(ctx: Context, private config: Watcher.Config) { super(ctx, 'hmr') this.base = resolve(ctx.baseDir, config.base || '') - this.logger = ctx.logger('hmr') this.initialURL = pathToFileURL(ctx.loader.filename).href } @@ -104,7 +104,7 @@ class Watcher extends Service { return } - this.logger.debug('change detected:', path) + this.ctx.logger.debug('change detected:', path) if (isEntry) { if (this.ctx.loader.internal!.loadCache.has(filename)) { @@ -220,7 +220,7 @@ class Watcher extends Service { pending.set(job, [plugin, runtime]) this.declined.add(url) } catch (err) { - this.logger.warn(err) + this.ctx.logger.warn(err) } } @@ -287,7 +287,7 @@ class Watcher extends Service { attempts[filename] = this.ctx.loader.unwrapExports(await import(filename)) } } catch (e) { - handleError(e, this.logger) + handleError(this.ctx, e) return rollback() } @@ -301,8 +301,8 @@ class Watcher extends Service { try { this.ctx.registry.delete(plugin) } catch (err) { - this.logger.warn('failed to dispose plugin at %c', path) - this.logger.warn(err) + this.ctx.logger.warn('failed to dispose plugin at %c', path) + this.ctx.logger.warn(err) } // replace loader cache for `keyFor` method @@ -313,10 +313,10 @@ class Watcher extends Service { const fork = oldFork.parent.plugin(attempts[filename], oldFork.config) fork.id = oldFork.id } - this.logger.info('reload plugin at %c', path) + this.ctx.logger.info('reload plugin at %c', path) } catch (err) { - this.logger.warn('failed to reload plugin at %c', path) - this.logger.warn(err) + this.ctx.logger.warn('failed to reload plugin at %c', path) + this.ctx.logger.warn(err) throw err } } @@ -331,7 +331,7 @@ class Watcher extends Service { fork.id = oldFork.id } } catch (err) { - this.logger.warn(err) + this.ctx.logger.warn(err) } } return diff --git a/packages/logger/src/index.ts b/packages/logger/src/index.ts index 47cf1f7..00be1f5 100644 --- a/packages/logger/src/index.ts +++ b/packages/logger/src/index.ts @@ -1,4 +1,4 @@ -import { Context } from '@cordisjs/core' +import { Context, Service } from '@cordisjs/core' import Logger from 'reggol' export { Logger } @@ -9,24 +9,41 @@ declare module '@cordisjs/core' { } } -interface LoggerService { +export interface LoggerService extends Pick { (name: string): Logger } -export function apply(ctx: Context) { - ctx.logger = function (name: string) { - return new Logger(name, { [Context.current]: this }) - } +export class LoggerService extends Service { + static name = 'logger' + + constructor(ctx: Context) { + super(ctx, 'logger', { immediate: true }) + + ctx.on('internal/info', function (format, ...args) { + this.logger('app').info(format, ...args) + }) + + ctx.on('internal/error', function (format, ...args) { + this.logger('app').error(format, ...args) + }) - ctx.on('internal/info', function (format, ...args) { - this.logger('app').info(format, ...args) - }) + ctx.on('internal/warning', function (format, ...args) { + this.logger('app').warn(format, ...args) + }) + } - ctx.on('internal/error', function (format, ...args) { - this.logger('app').error(format, ...args) - }) + [Context.invoke](name: string) { + return new Logger(name, { [Context.current]: this }) + } - ctx.on('internal/warning', function (format, ...args) { - this.logger('app').warn(format, ...args) - }) + static { + for (const type of ['success', 'error', 'info', 'warn', 'debug', 'extend'] as const) { + LoggerService.prototype[type] = function (this: any, ...args: any[]) { + const caller = this[Context.current] + return this(caller.name)[type](...args) + } + } + } } + +export default LoggerService