import { Arr, Fun, Obj, Type } from '@ephox/katamari'; import type { AlloyEventHandler, EventRunHandler } from '../api/events/AlloyEvents'; import type { EventFormat, SimulatedEvent } from '../events/SimulatedEvent'; const defaultEventHandler = { can: Fun.always, abort: Fun.never, run: Fun.noop }; const nu = (parts: Partial>): AlloyEventHandler => { if (!Obj.hasNonNullableKey(parts, 'can') && !Obj.hasNonNullableKey(parts, 'abort') && !Obj.hasNonNullableKey(parts, 'run')) { throw new Error( 'EventHandler defined by: ' + JSON.stringify(parts, null, 2) + ' does not have can, abort, or run!' ); } return { ...defaultEventHandler, ...parts }; }; const all = (handlers: Array>, f: (handler: AlloyEventHandler) => any) => (...args: any[]) => Arr.foldl(handlers, (acc, handler) => acc && f(handler).apply(undefined, args), true); const any = (handlers: Array>, f: (handler: AlloyEventHandler) => any) => (...args: any[]) => Arr.foldl(handlers, (acc, handler) => acc || f(handler).apply(undefined, args), false); const read = (handler: (() => SimulatedEvent) | AlloyEventHandler): AlloyEventHandler => Type.isFunction(handler) ? { can: Fun.always, abort: Fun.never, run: handler } : handler; const fuse = (handlers: Array>): AlloyEventHandler => { const can = all(handlers, (handler) => handler.can); const abort = any(handlers, (handler) => handler.abort); const run = (...args: Parameters>) => { Arr.each(handlers, (handler) => { // ASSUMPTION: Return value is unimportant. handler.run.apply(undefined, args); }); }; return { can, abort, run }; }; export { read, fuse, nu };