Natural Preference for Minification
    Wondering what’s next for npm?Check out our public roadmap! »

    fluid-func

    0.6.1 • Public • Published

    fluid-func

    A way to write your code with functional programming in mind

    NPM Download Stats

    Getting started

    • Installation
        npm install --save fluid-func
    • Javascript (ES6)
        import FluidFunc from 'fluid-func';
    • Javascsript
       var FluidFunc = require('fluid-func');

    Note: This package is basically a fork of fluid-chains with lighter packaging, less dependencies, a more secure aproach to chaining functions and focused on functional programming.

    Two ways to create a Func

        new FluidFunc('_1stFunc', function(parameter){
            // do some work here
        });
        FluidFunc.create('_1stFunc')
            .onStart(function(paramater){
                //do some work here
            });

    Two ways to start a Func

        FluidFunc.start('_1stFunc', {paramName:'paramVAlue'})
            .then(function(result){
                // do some work after
            })
            .catch(function(err){
                // do some error handling
            });
        FluidFunc.create('_1stFunc')
            .onStart(function(paramater){
                //do some work here
            }).execute({paramName:'paramVAlue'})
            .then(function(result){
                // do some work after
            })
            .catch(function(err){
                // do some error handling
            });

    Creating a Func sequence

     
        new FluidFunc('_1stFunc', function(param){
            // do the first func
        });
     
        new FluidFunc('_2ndFunc',function(param){
            //do the 2nd func
        });
     
        FluidFunc.start(['_1stFunc','_2ndFunc'], {paramName:'paramValue'})
            .then(function(result){
                // do something after
            })
            .catch(function(err){
                // do some error handling
            });
     
        FluidFunc.create('_1stFunc')
            .onStart(function(param){
                // do the first func
            })
            .connect('_2ndFunc')
            .onStart(function(param){
                // do the 2nd func
            })
            .execute({paramName:'paramValue'})
            .then(function(result){
                // do something after
            })
            .catch(function(err){
                // do some error handling
            });

    Accessing a parameter

    Parameters are immutable and can be accessed by calling the field as function.

        new FluidFunc('_1stFunc', function(param){
            // do the first func
            const paramValue = param.paramName();
        });
     
        FluidFunc.start('_1stFunc'], {paramName:'paramValue'})
            .then(function(result){
                // do something after
            })
            .catch(function(err){
                // do some error handling
            });
     

    Maintaining a context

    The first parameter is accessible across the Func sequence.

        new FluidFunc('_1stFunc', function(param){
            // do the first func
            const paramValue = param.paramName();
        });
     
        new FluidFunc('_2ndFunc',function(param){
            //do the 2nd func
             const paramValue = param.paramName();
        });
     
        FluidFunc.start(['_1stFunc','_2ndFunc'], {paramName:'paramValue'})
            .then(function(result){
                // do something after
            })
            .catch(function(err){
                // do some error handling
            });

    In Func sequence you can set the next parameter by returning a value or an object in the action method.

        new FluidFunc('_1stFunc', function(param){
            // do the first func
            const paramValue = param.paramName();
            return {
                from1st:'_1st says hi',
                person: {
                    name: 'John Doe',
                    age: 22
                }
            };
        });
     
        new FluidFunc('_2ndFunc',function(param){
            //do the 2nd func
             const paramValue = param.paramName();
             const _1stSaysHi = param.from1st(); // got from the previous func
             const name = param.person('name');
        });
     
        FluidFunc.start(['_1stFunc','_2ndFunc'], {paramName:'paramValue'})
            .then(function(result){
                // do something after
            })
            .catch(function(err){
                // do some error handling
            });

    Returning a literal value will be accessible by paramater.value on the next Func.

        new FluidFunc('_1stFunc', function(param){
            // do the first func
            const paramValue = param.paramName();
            return '_1st says hi';
        });
     
        new FluidFunc('_2ndFunc',function(param){
            //do the 2nd func
             const paramValue = param.paramName();
             const _1stSaysHi = param.value(); // got from the previous func
        });
     
        FluidFunc.start(['_1stFunc','_2ndFunc'], {paramName:'paramValue'})
            .then(function(result){
                // do something after
            })
            .catch(function(err){
                // do some error handling
            });

    Returning a promise in Func

        new FluidFunc('_1stFunc', function(param){
            // do the first func
            const paramValue = param.paramName();
            return new Promise(function(resolve,reject){
                resolve('_1st says hi');
            });
        });
     
        new FluidFunc('_2ndFunc',function(param){
            //do the 2nd func
             const paramValue = param.paramName();
             const _1stSaysHi = param.value(); // got from the previous func
        });
     
        FluidFunc.start(['_1stFunc','_2ndFunc'], {paramName:'paramValue'})
            .then(function(result){
                // do something after
            })
            .catch(function(err){
                // do some error handling
            });

    Restricting parameters with func.strict

    If you want to be strict with parameters and get only what you need you can enable strict mode per func.

     
        new FluidFunc('_2ndFunc', function(parameters){
            const paramValue = parameters.paramName();
            const iNeedThisAlso = parameters.moreParam();
            // parameters.fillerParam will be undefined
        })
        .strict()
        .spec('paramName')
        .spec('moreParam');
     
        FluidFunc.start('_1stFunc',
         {paramName:'paramValue',
         fillerParam:'not needed value',
         moreParam:'I need this also'})
            .then(function(result){
                // do something after
            })
            .catch(function(err){
                // do some error handling
            });

    func.onBefore

    If you want to have something to do before runing the Func use the func.onBefore.

     
        new FluidFunc('_1stFunc', function(parameter) {
     
        })
        .onBefore(function(paramater){
            /* do some security check here or something you do before running the func */
     
            return true; // Func will continue to start
        });

    Using promises.

     
        new FluidFunc('_1stFunc', function(parameter) {
            // do some func thingy here
        })
        .onBefore(function(paramater){
            /* do some security check here or something you do before running the func */
     
            return new Promise(funciton(resolve, reject){
                resolve(true);// Func will continue to start
            });
        });

    Note: FluidFunc will just skip and continue to the next Func when you return false value.

    func.onFail

    A way to handle error or breakage in Func process. In this you have options to retry the Func or break the sequence.

     
        new FluidFunc('_1stFunc', function(parameter) {
            // do some func thingy here
        })
        .onFail(function(error, retry, reject){
            retry();// will re process the Func
        });

    onFail: Function(error: Error, retry: Function, reject: Function)

    Param Description
    error Error instance that contains stack trace and error message
    retry Function that triggers the reprocess of Func
    reject Breaks the Func sequence

    Specifications and validations with func.spec

    spec.require

    • To require value from parameters add require:true in spec
     
        new FluidFunc('_1stFunc', function(parameter){
            const mandatoryField = parameter.mandatoryField(); //this field will always have value
        })
        .spec('mandatoryField', {
            require:true
        });
     
        FluidFunc.start('_1stFunc', {
            mandatoryField: 'hello'
        });
     
    • Adding custom message
     
        new FluidFunc('_1stFunc', function(parameter){
            const mandatoryField = parameter.mandatoryField(); //this field will always have value
        })
        .spec('mandatoryField', {
            require:true,
            requireMessage:'mandatory field is needed.'
        });
     
        FluidFunc.start('_1stFunc', {
            mandatoryField: 'hello'
        });
     
    • Transforming the parameter value

    transform: Function(current: String): Promise

    Param Description
    currentValue Has the current value of the parameter

    Note: Transform function should always return Promise

     
        new FluidFunc('_1stFunc', function(parameter){
            const userData = parameter.user(); // this is now a user object
        })
        .spec('user', {
            require:true,
            requireMessage:'UserId field is needed.'
        }, transform: function(currentValue){
            return new Promise((resolve,reject)=>{
                FindUserById(currentValue)
                    .then(function(user){
                        resolve(user);
                    })
                    .catch(function(err){
                        reject(err);
                    });
            });
        });
     
        FluidFunc.start('_1stFunc', {
            user: '#432userID'
        });
     
    • Translating the parameters

    Tranlates the parameter value into a new sets of parameters

    transform: Function(current: String): Promise

    Param Description
    value Has the current value of the parameter
    context Func current context

    Note: Tranlate function should always return Promise

     
        new FluidFunc('_1stFunc', function(parameter){
            const username = parameter.username();
            const fullname = parameter.fullname();
        })
        .spec('user', {
            require:true,
            requireMessage:'User field is needed.'
        }, translate: function(currentValue, context){
            return new Promise((resolve, reject)=>{
                context.set('username', currentValue.username);
                context.set('fullname', currentValue.fullname);
                resolve();
            });
        });
     
        FluidFunc.start('_1stFunc', {
            user: {
                username: 'rickzx98',
                fullname: 'Jerico de Guzman'
            }
        });
     
    • Customer validator

    validate: Function(current: String): Promise

    Param Description
    currentValue Has the current value of the parameter
        new FluidFunc('_1stFunc', function(parameter){
            const userData = parameter.user(); // this is now a user object
        })
        .spec('user', 
         validate: function(currentValue){
            return new Promise((resolve,reject)=>{
                if(currentValue === validEmail){
                    resolve();
                } else{
                    reject();
                }
            });
        });
     
        FluidFunc.start('_1stFunc', {
            email: 'john.doe@email.com'
        });

    Reducer

    To make the Func act as reducer use func.reduce(${fieldToReduce})

     
            new FluidFunc('_1stFunc', (parameter, current, index) => {
                return current + (parameter.value ? parameter.value() : 0);
            }).reduce('sampleArray');
     
            FluidFunc.start('_1stFunc', { sampleArray: [1, 2, 3, 4, 5] })
                .then(result => {
                    //expect(result.value()).to.be.equal(15);
                });

    Cache

    func.cache(cachedFor:number)

    Param Description Default
    cachedFor Sets the number (in milliseconds) for how long it will cache the Func 1500
      
       var counter = 0;
     
       new FluidFunc('_1stFunc', (parameter) => {
            counter++;
                return '_1st';
            })
            .strict()
            .cache();
     
       new FluidFunc('_2ndFunc', (parameter) => {
            counter++;
                return '_2nd';
            })
            .strict()
            .cache();
     
    FluidFunc.start(['_1stFunc','_2ndFunc','_1stFunc','_2ndFunc'], {
        hi:'hello'})
        .then(()=>{
            //counter will be equal to two
        });
     

    Note: The cache is based on the parameter set to the Func action so enabling .strict() mode will make cache more effective.

    Monitoring

    To monitor a single Func action you must do the following:

        FluidFunc.config({
            logMonitor: function(monitor) {
                  //console.log(monitor);
            }
        });
    • Monitor contains the detail of every Func process including it parameters and resolved context.

    Plugins

    Field Type Description Required
    name String Name of the plugin true
    action Function Action that will run true
    before/after array list of Func names the action will invoke to before/after atleast one of either
    • Plugin.action: Function(context: Context) - Will handle the plugin execution. All return types will be merged to the Context parameter.
    • Plugin.before - Will run the plugin before executing the Func
    • Plugin.after - Will run the plugin after the Func completes
        FluidFunc.config({
            plugins: [
                {
                name:'AwesomePlugin', 
                action: function(context) {
                    return "hello";
                },
                before:['Func1'],
                after:['Func2']
                }
            ]
        });
     
        FluidFunc.create('Func1').onStart(function(parameter){
            parameter.AwesomePlugin() // hello
        });
     
        FluidFunc.create('Func2').onStart(function(){})
        .execute(result => { 
            // plugin was triggered after Func2
            result.AwesomePlugin() // hello
        });
     

    Authors

    See also the list of contributors who participated in this project.

    License

    This project is licensed under the MIT License - see the LICENSE.md file for details

    Install

    npm i fluid-func

    DownloadsWeekly Downloads

    5

    Version

    0.6.1

    License

    MIT

    Unpacked Size

    114 kB

    Total Files

    47

    Last publish

    Collaborators

    • avatar