UNPKG

octonom

Version:

Object Document Mapper for any database

58 lines (47 loc) 1.83 kB
import { Model } from './model'; import { ISchemaInstance, Path } from './schema/schema'; /* Hook handlers are always called with instance set to the *unproxied* * instance where the hook is registered **/ export interface IChangeHookOptions<TModel extends Model> { path: Path; value: any; modelInstance: TModel; schemaInstance: ISchemaInstance; } export interface IChangeHooks<TModel extends Model = Model> { beforeChange?(options: IChangeHookOptions<TModel>); afterChange?(options: IChangeHookOptions<TModel>); } // union of all hook interfaces export type IHooks<TModel extends Model = Model> = IChangeHooks<TModel>; export interface IHookOptionsMap<TModel extends Model> { beforeChange: IChangeHookOptions<TModel>; afterChange: IChangeHookOptions<TModel>; } export type hookHandlers<TOptions> = Array<(options: TOptions) => void>; export type HookHandlersMap<TModel extends Model> = { [k in keyof IHookOptionsMap<TModel>]: hookHandlers<IHookOptionsMap<TModel>[k]>; }; export class Hooks<TModel extends Model> { private handlers: HookHandlersMap<TModel> = { beforeChange: [], afterChange: [], }; constructor(hooks?: Hooks<TModel>) { // copy hooks from passed Hooks instance if (hooks) { Object.keys(this.handlers).forEach(key => { this.handlers[key] = hooks.handlers[key].slice(); }); } } public register<K extends keyof HookHandlersMap<TModel>>(name: K, handler: HookHandlersMap<TModel>[K][0]) { const handlers = this.handlers[name] as Array<HookHandlersMap<TModel>[K][0]>; handlers.push(handler); } public run<K extends keyof IHookOptionsMap<TModel>>(name: K, options: IHookOptionsMap<TModel>[K]) { const handlers = this.handlers[name] as Array<HookHandlersMap<TModel>[K][0]>; handlers.forEach(handler => handler(options)); } }