Giter Site home page Giter Site logo

horpyna's Introduction

HORPYNA

Build Status Downloads Downloads NPM version

DESCRIPTION

This module is for better organizing chain processes with multiple branches. It allows to design process flow by creating branches and setting conditions when they should be called.

Main use case is to create flow template and reuse it with setting concrete functions instead of template ones.

Main unit is a Branch. Each branch accepts condition function and action function. Also each branch can accept other branches.

Use case

import { Branch} from "Horpyna";
const branch = new Branch({
    name: "branchName"
})
branch.execute(someInput)
    .then(response => console.log(response))

or

import { Branch} from "Horpyna";
const branch = Branch.create({
    name: "branchName"
})
branch.execute(someInput)
    .then(response => console.log(response))

API

new Branch(options: Object): branch

Creates new branch instance.

Branch.create(options: Object): branch

Creates new branch instance.

options

{   name: String
    condition: Function,
    action: Function,
    branches: Array<Branch>,
    exceptionHandler: Bool
}
  • name - branch name
  • condition - function with condition to test. It can return promise.
  • action - function to call if condition pass. It can return promise.
  • branches - array of sub branches
  • exceptionHandler: boolean if true this branch will be only trigger to handle exceptions

example

import { Branch } from "Horpyna";
const mainBranch = new Branch({ 
    name: "mainBranch",
    condition: value => value > 10, 
    action:  value => value + 1,
    branches: [{
        name: "maxBranch",
        condition: value => value >= 15,
        action: value => 15
    }]
});
mainBranch.execute(10)
    .then(console.log)//null
mainBranch.execute(11)
    .then(console.log)//12
mainBranch.execute(15)
    .then(console.log)//15

branch.setCondition(condition: (value: any) => result: any): branch

Changes branch condition. Returns this branch instance.

example

import { Branch } from "Horpyna";
const mainBranch = new Branch({ 
    name: "mainBranch",
    condition: value => value > 10, 
    action:  value => value + 1,
});
mainBranch.execute(11)
    .then(console.log)//12

mainBranch.setCondition(value => value > 11);

mainBranch.execute(11)
    .then(console.log)//null

branch.setAction(action: (value: any) => result: any): branch

Changes/set branch action. Returns this branch instance.

example

import { Branch } from "Horpyna";
const mainBranch = new Branch({ 
    name: "mainBranch",
    condition: value => value > 10, 
    action:  value => value + 1,
});

mainBranch.execute(11)
    .then(console.log)//12
    
mainBranch.setAction(value => value + 2);

mainBranch.execute(11)
    .then(console.log)//13

branch.addBranch(branchName: String, subBranch: branch): branch

Adds additional branch to existing one. Returns this branch instance.

example

import { Branch } from "Horpyna";
const mainBranch = new Branch({ 
    name: "mainBranch",
    condition: value => value > 10, 
    action:  value => value + 1,
    branches: [{
        name: "maxBranch",
        condition: value => value >= 15,
        action: value => 15
    }]
});

mainBranch.execute(10)
    .then(console.log)//null
    
mainBranch.addBranch(new Branch({
    name: "minBranch",
    condition: value => value < 15,
    action: value => value
}));

mainBranch.execute(10)
    .then(console.log)//11

branch,getBranch(branchName: String): branch

Returns first branch by name. If branch doesn't exist it will return null.

example

import { Branch } from "Horpyna";
const mainBranch = new Branch({ 
    name: "mainBranch",
    condition: () => true,
    action: () => true,
    branches: [{
        name: "maxBranch",
        condition: () => true,
        action: () => true
    }]
});
const maxBranch = mainBranch.getBranch("maxBranch");

branch,findBranch(branchName: String): branch

It will search in all branch tree beginning from current branch. If there is no such a branch it will return null.

example

import { Branch } from "Horpyna";
const mainBranch = new Branch({ 
    name: "mainBranch",
    condition: () => true,
    action: () => true,
    branches: [{
        name: "maxBranch",
        condition: () => true,
        action: () => true,
        branches: [{
            name: "someDeepBranch",
            condition: () => true,
            action: () => true
        }]
    }]
});
const someDeepBranch = mainBranch.findBranch("someDeepBranch");

branch,getAction(): function

Returns branch action function

branch,getCondition(): function

Returns branch condition function

branch,getName(): string

Returns branch name

branch,getBranches(): Array

Returns all child branches

branch.chain(branch): Branch

Add another branch to queue. All branches in queue will be invoked one by one after all child branches are done. Return current branch

example

import { Branch } from "Horpyna";
const mainBranch = new Branch({ 
    name: "branchA",
    condition: () => true,
    action: value => value + "A",
    branches: [{
        name: "branchB",
        condition: () => true,
        action: value => value + "B",
    }]
});
mainBranch.chain({
    name: "branchC",
    condition: () => true,
    action: value => value + "C",
})
mainBranch.chain({
    name: "branchD",
    condition: () => true,
    action: value => value + "D",
})

mainBranch.execute("")
.then(console.log)//"ABCD"

branch,setName(name: string): branch

Set new branch name

branch,clone(): branch

Shallow copy current branch and return new branch

branch.execute(input): promise

Returns promise resolvable to calculated output.

example

import { Branch } from "Horpyna";
const mainBranch = new Branch({ 
    name: "mainBranch",
    condition: value => value > 10, 
    action:  value => value + 1,
});

mainBranch.execute(11)
    .then(console.log)//12

LICENSE

MIT

horpyna's People

Contributors

uhlryk avatar

Stargazers

 avatar

Watchers

 avatar

Forkers

mjunaidi

horpyna's Issues

if branch get object it should be converted as Horpyna input

this

Horpyna({
  condition: conditionFunction,
  action: actionFunction,
  branches: {
    branchName: {
        condition: conditionFunction,
        action: actionFunction,
    }
  }
})

should work same as

Horpyna({
  condition: conditionFunction,
  action: actionFunction,
  branches: {
    branchName: Horpyna({
        condition: conditionFunction,
        action: actionFunction,
    })
  }
})

design and change api

Proposition
1.

     const mainBranch = Horpyna
         .when(conditionAFunction)
         .do(callAFunction)
         .addBranch(Horpyna
             .when(conditionBFunction)
             .do(callBFunction))
         .addBranch(Hopyna
             .when(conditionBFunction)
             .do(callBFunction))
             .addBranch(Horpyna
                 .when(conditionCFunction)
                 .do(callCFunction));
    
    //one way to call it
    mainBranch(initValue);
    //second way
    mainBranch
        .setValue(initValue); 

rename getBranch to findBranch

Find branch will search in all branch tree.
Get branch should get subbranch of branch

FindBranch don't need deepBranch arg, it should be removed

add next or setNext or chain method

It will accept branch which will be executed after current branch and subbranches are done

this should replace then()

We will have one branch chain and we will be able to cancel at any step

implement removeBranch

branch.removeBranch(branchName:string):Branch

will remove branch, and it will create new instances of all ascendant branches

Document promise flow with branches

return Branch({
  name: "branch 1",
  branches: [{name: "branch 2"}]
})(someValue)
.then(Branch({ //this will be called when all above branch chain finish
  name: "branch 3",
  branches: [{name: "branch 4"}]
}))
.then(result => console.log(result))

implement replaceBranch

branch.replaceBranch(branchName, subBranch => newSubBranch, deepSearch=true)

will replace branch with new one, and it will create new instances of all ascendant branches

If deepSearch = true it will search for branchName in all branch hierarchy

If branch doesn't exist it will throw error

add deepImmutability property to methods

Calling most methods will create new instances of all ascendant branches (deepImmutability is true), and if deepImmutability = false it will only replace branches

implement rename branch

Allow to change branch name

Works only with branch subbranches

Branch.renameBranch(currentName:string, newName: string)

implement getBranch

branch.getBranch(branchName: string, deepSearch: true)

It will return branch with branchName. If deep is true it will search in all sub branches

if branch condition is not met it should return initial value

const branch = new Branch({ name: "someName", condition:()=>false});
branch(someValue)
.then(response => {
expect(response).to.be.equal(someValue);
})

it will need some fundamental changes. Because we rely on null responses for not met conditions in subbranches

concept changes

From developer perspective:

  • we have only nodes and joints
  • for each node developer need to setup callback function - function will be triggered when node gets inputs. Callback function need to return output or async output
  • for joint developer need to set input node, output node, and evaluation callback function
  • there can be many joints between nodes
  • when node return value each joint connected with this node, call evaluation function. This function gets input and should return true if output node connected with this joint should be called. False if not.
  • joint can also accept optional function for mapping output to input. It gets output from input node and should return correct input for output node. If is not present then input output became input of output node.
  • probably we don't want work with new Joint(). It would be easier to just call Horpyna.createJoint()

constructor will take condition and action and branches

Horpyna(, , <object where key is branch name, and value is sub branch>)
api will be

  • changeWhen
  • changeDo
  • setBranch(, ) //can add new branch and replace existing
  • getBranch
  • removeBranch()
  • setValue(value)

Each operation create new instance. But there is no deep clone (e.g. adding new branch will not clone other branches. It will change instance of main branch but both will work on same references to subranchnes)

Need to remember that if we will change something in subbranch. this subbranch will be new instance and by default it will not be change in main branch. Main branch will have still ref to old subbranch version. To change subbranch for main branch

mainBranch.setBranch("someName",  mainBranch.getBranch("someName").changeWhen(<new condition>))

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.