UNPKG

@code-o-mat/globals

Version:

Abstract Package to support CodeOMat series of apps.

227 lines (189 loc) 6.13 kB
import curry from 'curry'; import { NONE } from 'o-mat-globals/globals/values'; import { CODE_O_MAT, METHOD_O_MAT } from 'o-mat-globals/globals/types'; import { REDUCE, STACK } from 'o-mat-globals/globals/methods'; import { assertIsFunction, assertIsObject } from 'o-mat-globals/globals/assertions'; const COMBINE = Symbol('COMBINE'); const SET_COMBINE_MODE = Symbol('SET_COMBINE_MODE'); class MethodOMat { static APP_FAMILY = O_MAT; static TYPE = METHOD_O_MAT; APP_FAMILY = O_MAT; TYPE = METHOD_O_MAT; constructor(name='lambda', method=NONE) { this._props = { name, bindToObject: NONE, doAppend: true, combineMode: STACK, returns: false, method: NONE, invalidMethod: `Invalid Method at MethodOMat ${name}`, } this.method(method); } build() { return this.method(); } /** * binds the method to an object. * @param {Object} bindToObject * @return {MethodOMat} self for continuation */ bind(bindToObject = NONE) { assertIsObject(bindToObject, this._props.invalidBindObject); this._props.bindToObject = bindToObject; return this; } curry(doAppend, method, newMethod) { return this.method( curry(this.method()) ); } /** * Puts MethodOMat into the reduce mode for building the function. * If a method is passed in, it will combine that method into the * existing function using append mode. * @param {function} newMethod * @return {MethodOMat} self for continuation */ append(newMethod = NONE) { this._props.doAppend = true; return newMethod === NONE ? this : this._combine(newMethod); } /** * Puts MethodOMat into the prepend mode for building the function. * If a method is passed in, it will combine that method into the * existing function using prepend mode. * @param {function} newMethod * @return {MethodOMat} self for continuation */ prepend(newMethod = NONE) { this._props.doAppend = false; return newMethod === NONE ? this : this._combine(newMethod); } /** * Puts MethodOMat into the reduce mode for building the function. * If a method is passed in, it will combine that method into the * existing function using reduce mode. * @param {function} newMethod * @return {MethodOMat} self for continuation */ reduce(newMethod = NONE) { return this[SET_COMBINE_MODE](REDUCE, newMethod); } /** * puts MethodOMat into the stack mode for building the function. * This will simply run all the functions in sequence without * dealing with any return values. * @param {[type]} newMethod [description] * @return {[type]} [description] */ stack(newMethod = NONE) { return this[SET_COMBINE_MODE](STACK, newMethod); } /** * puts MethodOMat into the stackWithReturns mode. * This will run all the functions in sequence and will * collect their return values in an array in order in which * the component functions were run. * @param {[type]} newMethod [description] * @return {[type]} [description] */ stackWithReturns(newMethod = NONE) { return this[SET_COMBINE_MODE](STACK_WITH_RETURNS, newMethod); } /** * getter or setter for the current method. Will overwrite * any previous method. * @param {function | NONE} method * @returns {function | MethodOMat} either the function to be * build or the current methodOMat */ method(method = NONE) { if (method === NONE) { return this._props.method.bind(this._props.bindToObject) } assertIsFunction(method, this._props.invalidMethod); this._props.method = method; return this; } /** * combines a function to the existing function. * @private * @param {function} newMethod the new method * to be combined to the existing one. * @return {MethodOMat} self for continuation. */ [COMBINE](newMethod) { assertIsFunction(newMethod, this._props.invalidMethod); const { doAppend, doReduce, method } = this._props; return doReduce === true ? this._reduce(doAppend, method, newMethod) : this._curry(doAppend, method, newMethod); } [SET_COMBINE_MODE](mode, newMethod) { this._props.combineMode = mode; return newMethod === NONE ? this : this[COMBINE](newMethod); } /** * combines a function to the existing function * using the reduce method. * @private * @param {Boolean} doAppend * @param {function} method * @param {function} newMethod * @return {MethodOMat} self for continuation. */ [REDUCE](doAppend, method, newMethod) { return this.method( doAppend === true ? function(...p) { return newMethod(method(...p))} : function(...p) { return method(newMethod(...p))} ); } [REDUCE_WITH_RETURNS](doAppend, method, newMethod) { return this.method( doAppend === true ? function(...p) { const rts = []; rts = rts.concat(method(...p)); return rts.concat(newMethod(rts.slice(-1), rts)); } : function(...p) { const rts = []; rts = rts.concat(newMethod(...p)); return rts.concat(method(rts.slice(-1), rts)); } ); } [STACK](doAppend, method, newMethod) { return this.method( doAppend === true ? function(...p) { method(...p); return newMethod(...p); } : function(...p) { newMethod(...p); return method(...p); } ); } [STACK_WITH_RETURNS](doAppend, method, newMethod) { return this.method( doAppend === true ? function(...p) { const rts = []; rts = rts.concat(method(...p)); return rts.concat(newMethod(...p)); } : function(...p) { const rts = []; rts = rts.concat(newMethod(...p)); return rts.concat(method(...p)); } ); } } export default MethodOMat;