/** * Composes single-argument functions from right to left. The rightmost * function can take multiple arguments as it provides the signature for * the resulting composite function. * * @param {...Function} funcs The functions to compose. * @returns {Function} A function obtained by composing the argument functions * from right to left. For example, compose(f, g, h) is identical to doing * (...args) => f(g(h(...args))). */ export function arrayUnique(array) { return Array.from((new Set(array)).values()); } export function compose(...funcs) { if (funcs.length === 0) { return arg => arg } if (funcs.length === 1) { return funcs[0] } return funcs.reduce((a, b) => (...args) => a(b(...args))) } export function flatten(array) { return array.reduce((flattened, elm) => flattened.concat(elm), []); } export function virtualize(fields) { return (Superclass) => { class Virtualized extends Superclass {} fields.forEach((field) => { Virtualized.prototype[field] = function() { const prototype = Object.getPrototypeOf(this); const className = prototype.constructor.name; throw new ReferenceError( `"${className}" has undefined pure virtual method "${field}"` ); } }); return Virtualized; } } export function virtualizeStatic(fields) { return (Superclass) => { class Virtualized extends Superclass {} fields.forEach((field) => { Virtualized[field] = function() { const prototype = Virtualized.prototype; const className = prototype.constructor.name; throw new ReferenceError( `"${className}" has undefined pure virtual static method "${field}"` ); } }); return Virtualized; } } export class TickingPromise extends Promise { constructor(resolve, reject) { super(resolve, reject); this.ticker = null; } } export {EventEmitterMixin as EventEmitter} from './event-emitter'; export {PropertyMixin as Property} from './property';