diff --git a/packages/core/src/context.ts b/packages/core/src/context.ts index b4b90f4..29e0d0c 100644 --- a/packages/core/src/context.ts +++ b/packages/core/src/context.ts @@ -25,8 +25,8 @@ export namespace Context { export interface Accessor { type: 'accessor' - get: () => any - set?: (value: any) => boolean + get: (this: Context) => any + set?: (this: Context, value: any) => boolean } export interface Alias { @@ -88,8 +88,8 @@ export class Context { self.registry = new Registry(self, config) self.lifecycle = new Lifecycle(self) self.mixin('scope', ['config', 'runtime', 'effect', 'collect', 'accept', 'decline']) - self.mixin('registry', ['using', 'inject', 'plugin', 'dispose']) - self.mixin('lifecycle', ['on', 'once', 'off', 'after', 'parallel', 'emit', 'serial', 'bail', 'start', 'stop']) + self.mixin('registry', ['using', 'inject', 'plugin']) + self.mixin('lifecycle', ['on', 'once', 'parallel', 'emit', 'serial', 'bail', 'start', 'stop']) const attach = (internal: Context[typeof symbols.internal]) => { if (!internal) return diff --git a/packages/core/src/events.ts b/packages/core/src/events.ts index f927158..11ecc50 100644 --- a/packages/core/src/events.ts +++ b/packages/core/src/events.ts @@ -39,7 +39,7 @@ export interface EventOptions { global?: boolean } -interface Hook extends EventOptions { +export interface Hook extends EventOptions { ctx: Context callback: (...args: any[]) => any } @@ -123,8 +123,7 @@ export default class Lifecycle { } } - getHooks(name: keyof any, thisArg?: object) { - const hooks = this._hooks[name] || [] + filterHooks(hooks: Hook[], thisArg?: object) { return hooks.slice().filter((hook) => { const filter = thisArg?.[Context.filter] return hook.global || !filter || filter.call(thisArg, hook.ctx) @@ -137,7 +136,7 @@ export default class Lifecycle { if (name !== 'internal/event') { this.emit('internal/event', type, name, args, thisArg) } - for (const hook of this.getHooks(name, thisArg)) { + for (const hook of this.filterHooks(this._hooks[name] || [], thisArg)) { yield hook.callback.apply(thisArg, args) } } diff --git a/packages/core/src/reflect.ts b/packages/core/src/reflect.ts index a4bcd7f..4c88c5c 100644 --- a/packages/core/src/reflect.ts +++ b/packages/core/src/reflect.ts @@ -12,7 +12,8 @@ declare module './context' { provide(name: string, value?: any, builtin?: boolean): void accessor(name: string, options: Omit): void alias(name: string, aliases: string[]): void - mixin(name: string, mixins: string[] | Dict): void + mixin(name: K, mixins: (keyof this & keyof this[K])[] | Dict): void + mixin(source: T, mixins: (keyof this & keyof T)[] | Dict): void } } @@ -160,19 +161,20 @@ export default class ReflectService { } } - mixin(name: string, mixins: string[] | Dict) { + mixin(source: any, mixins: string[] | Dict) { const entries = Array.isArray(mixins) ? mixins.map(key => [key, key]) : Object.entries(mixins) + const getTarget = typeof source === 'string' ? (ctx: Context) => ctx[source] : () => source for (const [key, value] of entries) { this.accessor(value, { get() { - const service = this[name] + const service = getTarget(this) if (isNullable(service)) return service const value = Reflect.get(service, key) - if (typeof value !== 'function') return value + if (typeof value !== 'function' || typeof source !== 'string') return value return value.bind(service) }, set(value) { - return Reflect.set(this[name], key, value) + return Reflect.set(getTarget(this), key, value) }, }) }