Last active
January 6, 2024 04:17
-
-
Save unbug/dd596d79b5eace7d245f0a4db6cd2be5 to your computer and use it in GitHub Desktop.
Revisions
-
unbug revised this gist
Apr 13, 2017 . No changes.There are no files selected for viewing
-
unbug revised this gist
Feb 3, 2017 . 1 changed file with 4 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -30,7 +30,7 @@ export function compose(...funcs) { } /** * Manage and apply middlewares for an object. * Middleware functions are functions that have access to the target function and it's arguments, * and the target object and the next middleware function in the target function cycle. * The next middleware function is commonly denoted by a variable named next. @@ -133,11 +133,11 @@ export function compose(...funcs) { * p.speak('hi'); * * ## middlewareMethods * Or we can use `middlewareMethods` to define function names for middleware target within a class. * * class CuePointMiddleware { * constructor() { * //Define function names for middleware target. * this.middlewareMethods = ['walk', 'speak']; * } * log(text) { @@ -217,7 +217,7 @@ export class MiddlewareManager { use(methodName, ...middlewares) { if (typeof methodName === 'object') { Array.prototype.slice.call(arguments).forEach(arg => { // A middleware object can specify target functions within middlewareMethods (Array). // e.g. obj.middlewareMethods = ['method1', 'method2']; // only method1 and method2 will be the target function. typeof arg === 'object' && (arg.middlewareMethods || Object.keys(arg)).forEach(key => { -
unbug revised this gist
Jan 6, 2017 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -221,7 +221,7 @@ export class MiddlewareManager { // e.g. obj.middlewareMethods = ['method1', 'method2']; // only method1 and method2 will be the target function. typeof arg === 'object' && (arg.middlewareMethods || Object.keys(arg)).forEach(key => { typeof arg[key] === 'function' && this._applyToMethod(key, arg[key].bind(arg)); }); }); } else { -
unbug revised this gist
Dec 27, 2016 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -30,7 +30,7 @@ export function compose(...funcs) { } /** * Manage and apply middleweares for an object. * Middleware functions are functions that have access to the target function and it's arguments, * and the target object and the next middleware function in the target function cycle. * The next middleware function is commonly denoted by a variable named next. @@ -207,7 +207,7 @@ export class MiddlewareManager { } /** * Apply (register) middleware functions to the target function or apply (register) middleware objects. * If the first argument is a middleware object, the rest arguments must be middleware objects. * * @param {string|object} methodName String for target function name, object for a middleware object. -
unbug revised this gist
Dec 27, 2016 . No changes.There are no files selected for viewing
-
unbug revised this gist
Dec 27, 2016 . 1 changed file with 13 additions and 13 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,7 +1,7 @@ 'use strict'; /* eslint-disable consistent-this */ let middlewareManagerHash = []; /** * Composes single-argument functions from right to left. The rightmost @@ -30,7 +30,7 @@ export function compose(...funcs) { } /** * Manage and apply middleweare to an object. * Middleware functions are functions that have access to the target function and it's arguments, * and the target object and the next middleware function in the target function cycle. * The next middleware function is commonly denoted by a variable named next. @@ -102,8 +102,8 @@ export function compose(...funcs) { * * // apply middleware to target object * const p = new Person(); * const middlewareManager = new MiddlewareManager(p); * middlewareManager.use('walk', walk); * p.walk(3); * * Whenever a Person instance call it's walk method, we'll see logs from the looger middleware. @@ -127,8 +127,8 @@ export function compose(...funcs) { * * // apply middleware to target object * const p = new Person(); * const middlewareManager = new MiddlewareManager(p); * middlewareManager.use(PersonMiddleware); * p.walk(3); * p.speak('hi'); * @@ -161,28 +161,28 @@ export function compose(...funcs) { * * // apply middleware to target object * const p = new Person(); * const middlewareManager = new MiddlewareManager(p); * middlewareManager.use(new PersonMiddleware()) * p.walk(3); * p.speak('hi'); * */ export class MiddlewareManager { /** * @param {object} target The target object. * @param {...object} middlewareObjects Middleware objects. * @return {object} this */ constructor(target, ...middlewareObjects) { let instance = middlewareManagerHash.find(function (key) { return key._target === target; }); // a target can only has one MiddlewareManager instance if (instance === undefined) { this._target = target; this._methods = {}; this._methodMiddlewares = {}; middlewareManagerHash.push(this); instance = this; } instance.use(...middlewareObjects); @@ -230,4 +230,4 @@ export class ApplyMiddleware { return this; } } -
unbug revised this gist
Dec 23, 2016 . 1 changed file with 8 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -113,13 +113,13 @@ export function compose(...funcs) { * Middleware object is an object that contains function's name as same as the target object's function name. * * const PersonMiddleware { * walk: target => next => step => { * console.log(`walk start, steps: step.`); * const result = next(step); * console.log(`walk end.`); * return result; * }, * speak: target => next => word => { * word = 'this is a middleware trying to say: ' + word; * return next(word); * } @@ -144,15 +144,15 @@ export function compose(...funcs) { * console.log('Middleware log: ' + text); * } * walk(target) { * return next => step => { * this.log(`walk start, steps: step.`); * const result = next(step); * this.log(`walk end.`); * return result; * } * } * speak(target) { * return next => word => { * this.log('this is a middleware tring to say: ' + word); * return next(word); * } @@ -208,8 +208,10 @@ export class ApplyMiddleware { /** * Apply middleware to the target object. * If the first argument is a middleware object, the rest arguments must be middleware objects. * * @param {string|object} methodName String for target function name, object for a middleware object. * @param {...function|...object} middlewares The middleware chain to be applied. * @return {object} this */ use(methodName, ...middlewares) { -
unbug revised this gist
Dec 22, 2016 . 1 changed file with 3 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,5 @@ 'use strict'; /* eslint-disable consistent-this */ let applyMiddlewareHash = []; @@ -173,7 +174,6 @@ export class ApplyMiddleware { * @return {object} this */ constructor(target, ...middlewareObjects) { let instance = applyMiddlewareHash.find(function (key) { return key._target === target; }); @@ -183,7 +183,7 @@ export class ApplyMiddleware { this._methods = {}; this._methodMiddlewares = {}; applyMiddlewareHash.push(this); instance = this; } instance.use(...middlewareObjects); @@ -228,4 +228,4 @@ export class ApplyMiddleware { return this; } } -
unbug revised this gist
Dec 21, 2016 . 1 changed file with 82 additions and 11 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -72,27 +72,98 @@ export function compose(...funcs) { * * @example * * ## Basic * * We define a Person class. * // the target object * class Person { * // the target function * walk(step) { * this.step = step; * } * * speak(word) { * this.word = word; * } * } * * Then we define a middleware function to print log. * * // middleware for walk function * const logger = target => next => (...args) => { * console.log(`walk start, steps: ${args[0]}.`); * const result = next(...args); * console.log(`walk end.`); * return result; * } * * Now we apply the log function as a middleware to a Person instance. * * // apply middleware to target object * const p = new Person(); * const applyMiddleware = new ApplyMiddleware(p); * applyMiddleware.use('walk', walk); * p.walk(3); * * Whenever a Person instance call it's walk method, we'll see logs from the looger middleware. * * ## Middleware object * We can also apply a middleware object to a target object. * Middleware object is an object that contains function's name as same as the target object's function name. * * const PersonMiddleware { * walk: target => next => (step) => { * console.log(`walk start, steps: step.`); * const result = next(step); * console.log(`walk end.`); * return result; * }, * speak: target => next => (word) => { * word = 'this is a middleware trying to say: ' + word; * return next(word); * } * } * * // apply middleware to target object * const p = new Person(); * const applyMiddleware = new ApplyMiddleware(p); * applyMiddleware.use(PersonMiddleware); * p.walk(3); * p.speak('hi'); * * ## middlewareMethods * Or we can use `middlewareMethods` to define function names for middleweare target within a class. * * class CuePointMiddleware { * constructor() { * //Define function names for middleweare target. * this.middlewareMethods = ['walk', 'speak']; * } * log(text) { * console.log('Middleware log: ' + text); * } * walk(target) { * return next => (step) => { * this.log(`walk start, steps: step.`); * const result = next(step); * this.log(`walk end.`); * return result; * } * } * speak(target) { * return next => (word) => { * this.log('this is a middleware tring to say: ' + word); * return next(word); * } * } * } * * // apply middleware to target object * const p = new Person(); * const applyMiddleware = new ApplyMiddleware(p); * applyMiddleware.use(new PersonMiddleware()) * p.walk(3); * p.speak('hi'); * */ export class ApplyMiddleware { @@ -157,4 +228,4 @@ export class ApplyMiddleware { return this; } } -
unbug revised this gist
Dec 21, 2016 . 1 changed file with 3 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -82,9 +82,9 @@ export function compose(...funcs) { * * // middleware for walk function * const logger = target => next => (...args) => { * console.log(`walk start, steps: ${args[0]}.`); * const result = next(...args); * console.log(`walk end.`); * return result; * } * @@ -157,4 +157,4 @@ export class ApplyMiddleware { return this; } } -
unbug revised this gist
Dec 21, 2016 . 1 changed file with 16 additions and 9 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,7 @@ 'use strict'; let applyMiddlewareHash = []; /** * Composes single-argument functions from right to left. The rightmost * function can take multiple arguments as it provides the signature for @@ -26,8 +28,6 @@ export function compose(...funcs) { return (...args) => rest.reduceRight((composed, f) => f(composed), last(...args)); } /** * Apply middleweare to an object. * Middleware functions are functions that have access to the target function and it's arguments, @@ -102,13 +102,20 @@ export class ApplyMiddleware { * @return {object} this */ constructor(target, ...middlewareObjects) { const that = this; let instance = applyMiddlewareHash.find(function (key) { return key._target === target; }); // a target can only has one ApplyMiddleware instance if (instance === undefined) { this._target = target; this._methods = {}; this._methodMiddlewares = {}; applyMiddlewareHash.push(this); instance = that; } instance.use(...middlewareObjects); return instance; } @@ -150,4 +157,4 @@ export class ApplyMiddleware { return this; } } -
unbug revised this gist
Dec 19, 2016 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -141,7 +141,7 @@ export class ApplyMiddleware { // e.g. obj.middlewareMethods = ['method1', 'method2']; // only method1 and method2 will be the target function. typeof arg === 'object' && (arg.middlewareMethods || Object.keys(arg)).forEach(key => { this._applyToMethod(key, arg[key].bind(arg)); }); }); } else { -
unbug revised this gist
Dec 19, 2016 . 1 changed file with 14 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -26,6 +26,8 @@ export function compose(...funcs) { return (...args) => rest.reduceRight((composed, f) => f(composed), last(...args)); } let targetsCache = []; /** * Apply middleweare to an object. * Middleware functions are functions that have access to the target function and it's arguments, @@ -100,10 +102,14 @@ export class ApplyMiddleware { * @return {object} this */ constructor(target, ...middlewareObjects) { let instance = targetsCache.find(function (key) { return key === target; }) || this; instance._target = instance._target || target; instance._methods = instance._methods || {}; instance._methodMiddlewares = instance._methodMiddlewares || {}; instance.use(...middlewareObjects); return instance; } _applyToMethod(methodName, ...middlewares) { @@ -131,7 +137,10 @@ export class ApplyMiddleware { use(methodName, ...middlewares) { if (typeof methodName === 'object') { Array.prototype.slice.call(arguments).forEach(arg => { // A middleweare object can specify targer functions within middlewareMethods (Array). // e.g. obj.middlewareMethods = ['method1', 'method2']; // only method1 and method2 will be the target function. typeof arg === 'object' && (arg.middlewareMethods || Object.keys(arg)).forEach(key => { this._applyToMethod(key, arg[key]); }); }); -
unbug revised this gist
Dec 5, 2016 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -10,7 +10,7 @@ * from right to left. For example, compose(f, g, h) is identical to doing * (...args) => f(g(h(...args))). */ export function compose(...funcs) { if (funcs.length === 0) { return arg => arg; } @@ -117,7 +117,7 @@ export class ApplyMiddleware { middlewares.forEach(middleware => typeof middleware === 'function' && this._methodMiddlewares[methodName].push(middleware(this._target)) ); this._target[methodName] = compose(...this._methodMiddlewares[methodName])(method.bind(this._target)); } } } -
unbug revised this gist
Dec 5, 2016 . No changes.There are no files selected for viewing
-
unbug revised this gist
Dec 5, 2016 . No changes.There are no files selected for viewing
-
unbug created this gist
Dec 5, 2016 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,144 @@ 'use strict'; /** * 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 Compose(...funcs) { if (funcs.length === 0) { return arg => arg; } funcs = funcs.filter(func => typeof func === 'function'); if (funcs.length === 1) { return funcs[0]; } const last = funcs[funcs.length - 1]; const rest = funcs.slice(0, -1); return (...args) => rest.reduceRight((composed, f) => f(composed), last(...args)); } /** * Apply middleweare to an object. * Middleware functions are functions that have access to the target function and it's arguments, * and the target object and the next middleware function in the target function cycle. * The next middleware function is commonly denoted by a variable named next. * * Middleware functions can perform the following tasks: * - Execute any code. * - Make changes to the function's arguments. * - End the target function. * - Call the next middleware in the stack. * * If the current middleware function does not end the target function cycle, * it must call next() to pass control to the next middleware function. Otherwise, * the target function will be left hanging. * * e.g. * ``` * const walk = target => next => (...args) => { * this.log(`walk function start.`); * const result = next(...args); * this.log(`walk function end.`); * return result; * } * ``` * * Middleware object is an object that contains function's name as same as the target object's function name. * * e.g. * ``` * const Logger = { * walk: target => next => (...args) => { * console.log(`walk function start.`); * const result = next(...args); * console.log(`walk function end.`); * return result; * } * } * ``` * * Function's name start or end with "_" will not be able to apply middleware. * * @example * * // the target object * class Person { * // the target function * walk(step) { * this.step = step; * } * } * * // middleware for walk function * const logger = target => next => (...args) => { * this.log(`walk start, steps: ${args[0]}.`); * const result = next(...args); * this.log(`walk end.`); * return result; * } * * // apply middleware to target object * const p = new Person(); * const applyMiddleware = new ApplyMiddleware(p); * applyMiddleware.use('walk', walk); * p.walk(); * */ export class ApplyMiddleware { /** * @param {object} target The target object. * @param {...object} middlewareObjects Middleware objects. * @return {object} this */ constructor(target, ...middlewareObjects) { this._target = target; this._methods = {}; this._methodMiddlewares = {}; this.use(...middlewareObjects); } _applyToMethod(methodName, ...middlewares) { if (typeof methodName === 'string' && !/^_+|_+$/g.test(methodName)) { let method = this._methods[methodName] || this._target[methodName]; if (typeof method === 'function') { this._methods[methodName] = method; if (this._methodMiddlewares[methodName] === undefined) { this._methodMiddlewares[methodName] = []; } middlewares.forEach(middleware => typeof middleware === 'function' && this._methodMiddlewares[methodName].push(middleware(this._target)) ); this._target[methodName] = Compose(...this._methodMiddlewares[methodName])(method.bind(this._target)); } } } /** * Apply middleware to the target object. * @param {string|object} methodName String for target function name, object * @param {...function} middlewares The middleware chain to be applied. * @return {object} this */ use(methodName, ...middlewares) { if (typeof methodName === 'object') { Array.prototype.slice.call(arguments).forEach(arg => { typeof arg === 'object' && Object.keys(arg).forEach(key => { this._applyToMethod(key, arg[key]); }); }); } else { this._applyToMethod(methodName, ...middlewares); } return this; } }