import { Handler } from '../handler'; import { BaseHookSystem } from '../hooksystems'; import { IFilterModel, IHandlerRegistration } from './filtermodel'; /** * A simple in memory model for filters. */ export class InMemoryFilterModel implements IFilterModel { private handlers: { [k: string]: Array> } = {}; private data: { [filterKey: string]: { [handlerKey: string]: { priority: number, handler: Handler; } } } = { _handlers_: {} }; public async queryHandlers(filter: BaseHookSystem): Promise>> { const handlers = this.handlers[filter.baseKey] || []; return handlers .map((w) => new Handler(w.key, (obj: T, ...rest: any[]) => { if (typeof(this.data[filter.baseKey][w.key]) === 'undefined') { // if i was unregistered then do not run myself return Promise.resolve(obj); } try { return w.handle(obj, ...rest); } catch (e) { return Promise.reject(e); } } )); } // tslint:disable-next-line public async registerHandler(obj: { hookSystem: BaseHookSystem; handler: Handler; priority?: number }): Promise { const {hookSystem, handler} = obj; if (typeof(this.data[hookSystem.baseKey]) === 'undefined') { this.data[hookSystem.baseKey] = {}; } this.data[hookSystem.baseKey][handler.key] = { handler, priority: obj.priority || 10, }; const handlers = Object.keys(this.data[hookSystem.baseKey]) .map((handlerKey) => this.data[hookSystem.baseKey][handlerKey]); handlers.sort((a, b) => a.priority - b.priority); this.handlers[hookSystem.baseKey] = handlers.map((h) => h.handler); return { id : handler.key, unregister: async () => { delete this.data[hookSystem.baseKey][handler.key]; const index = this.handlers[hookSystem.baseKey].findIndex((a) => a.key === handler.key); if (index === -1) { console.warn(`Unregistering same handler twice ${handler.key}`); } this.handlers[hookSystem.baseKey].splice(index, 1); return true; }, }; } }