{"id":23537479,"url":"https://github.com/smikodanic/functionflowx","last_synced_at":"2025-07-20T02:36:38.248Z","repository":{"id":57749458,"uuid":"524131653","full_name":"smikodanic/functionflowx","owner":"smikodanic","description":"Control how the javascript functions will be executed.","archived":false,"fork":false,"pushed_at":"2023-08-12T08:26:05.000Z","size":27,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-15T00:21:20.622Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/smikodanic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-08-12T15:09:32.000Z","updated_at":"2022-08-12T15:11:18.000Z","dependencies_parsed_at":"2025-02-17T07:38:41.448Z","dependency_job_id":null,"html_url":"https://github.com/smikodanic/functionflowx","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/smikodanic/functionflowx","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smikodanic%2Ffunctionflowx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smikodanic%2Ffunctionflowx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smikodanic%2Ffunctionflowx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smikodanic%2Ffunctionflowx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/smikodanic","download_url":"https://codeload.github.com/smikodanic/functionflowx/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smikodanic%2Ffunctionflowx/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266058481,"owners_count":23870157,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-26T03:15:43.091Z","updated_at":"2025-07-20T02:36:38.223Z","avatar_url":"https://github.com/smikodanic.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# functionflowx\n\u003e Control how the javascript functions will be executed.\n\n- methods which will execute JS functions in serial or parallel order\n- repeat multiple serial/parallel bundled functions\n- start, stop, pause the function execution\n- no npm dependencies\n\nThe FunctionFlowX® controls whether functions will be executed in serial or in parallel sequence. It gives the possibility for iterative repetition of serial or parallel function sequence. It defines time delays between every function execution step. Finally, it controls the whole process to start, stop or pause.\nThere is some similarity with the async npm library but FunctionFlow is much more powerful because it uses JS Promises and async/await.\n\n\n## Installation\n```bash\n$ npm install --save functionflowx\n```\n\n\n## Example\n```js\n/*** NodeJS script ***/\nconst { EventEmitter } = require('events');\nconst FunctionFlow = require('functionflowx');\n\n\n// functions\nconst f1 = (x, lib) =\u003e {\n  x++;\n  console.log('f1::', x);\n  return x;\n};\n\nconst f2 = (x, lib) =\u003e {\n  x++;\n  console.log('f2::', x);\n  return x;\n};\n\nconst f3 = function (x, lib) {\n  x++;\n  console.log('f3::', x);\n  console.log('this::', this); // {}\n  console.log('lib::', lib); // {evenEmitter,ff}\n  return x;\n};\n\n\n// main\nconst main = async (input, eventEmitter) =\u003e {\n  const ff = new FunctionFlow({ debug: true, msDelay: 800 }, eventEmitter);\n\n  const x = input;\n  const lib = { eventEmitter, ff };\n  ff.xInject(x);\n  ff.libInject(lib);\n\n  await ff.serial([f1, f2, f3, f1]);\n  await ff.delay(3400);\n\n  return ff.x;\n};\n\n\n// execute main\nconst inp = 5;\nconst eventEmitter = new EventEmitter();\nmain(inp, eventEmitter)\n  .then(res =\u003e console.log('RES:: ', res))\n  .catch(err =\u003e console.error('ERR:: ', err));\n```\n\nOther examples are in /tests/ folder.\n\n\n\n## API\n\n#### constructor(opts:{debug:boolean, msDelay:number}, eventEmitter:EventEmitter)\n- debug - show debug message\n- msDelay - delay between functions\n- eventEmitter - NodeJS event emitter object (connects with outer code)\n\n\n#### xInject(x:any) :void\nInject x (transitional variable) in function first parameter - func(x, lib).\n\n#### libInject(lib:object) :void\nInject libraries like Cheerio, Puppeteer, ...etc. in function second parameter - func(x, lib).\n\n#### libAdd(lib:object) :void\nAdd libraries to libraries already injected by libInject().\n\n#### libRemove() :void\nRemove all libraries.\n\n#### libList() :array\nList all libraries.\n\n\n### /*=========== FUNCTION  BUNDLERS ==============*/\n\n#### async serial(funcs:function[]) :any\nExecute funcs functions one by one.\n```\ninput------\u003e|--f0--\u003e|msDelay|--f3--\u003e|msDelay|--f2--\u003e|msDelay|------\u003eoutput\n```\n\n#### async serialEach(funcs:function[], arr:array) :any\nExecute funcs functions one by one and repeat it for every array element.\nThe funcs chain is repeated the arr.length times. The \"arr\" element is stored in the \"lib.serialEachElement\" and can be used inside the function.\n```\ninput------\u003e|--f0--\u003e|msDelay|--f3--\u003e|msDelay|--f2--\u003e|msDelay|------\u003eoutput\n            |                                            arr|\n            |\u003c--------------repeat arr.length --------------|\n```\n\n#### async serialRepeat(funcs:function[], n:number) :any\nExecute funcs functions one by one and repeat it n times.\nThe funcs chain is repeated the n times. The iteration number is stored in the \"lib.serialRepeatIteration\" and can be used in the function.\n```\ninput------\u003e|--f0--\u003e|msDelay|--f3--\u003e|msDelay|--f2--\u003e|msDelay|------\u003eoutput\n            |                                              n|\n            |\u003c-------------------repeat n ------------------|\n```\n\n#### async one(func:function) :any\nExecute just one function.\n\n#### async parallelAll(funcs:function[]) :any\nTake any defined function and execute simultaneously. All defined functions must return fulfilled promises. Input is same for all functions. Returned value is an array of resolved values.\n```\n         --\u003e |--------- f2(x) ----------\u003e---|\n-- input --\u003e |--------- f4(x) -------\u003e------|msDelay|---\u003e [r2, r4, r8]\n         --\u003e |--------- f8(x) -------------\u003e|\n```\n\n#### async parallelRace(funcs:function[]) :any\nRun functions in paralell. Fastest function must return fulfilled promise. Returned value is value from first resolved (fastest) function.\n```\n         --\u003e |--------- f2(x) --------|--\u003e\n-- input --\u003e |--------- f4(x) -------\u003e|msDelay|---\u003e r4\n         --\u003e |--------- f8(x) --------|-----\u003e\n```\n\n\n### /*=========== ITERATION  METHODS ==============*/\n#### async repeat(n:number) :any\nRepeat last executed FunctionFlow bundle method (serial, serialEach, ...) n times.\n\n\n\n### /*=========== COMMANDS ==============*/\n#### stop() :void\nStops the execution of all functions used in bundle methods (serial, one or parallel). Condition: status = 'start'.\n```\nff.stop(); // inside function\neventEmitter.emit('ff-stop'); // out of function\n```\n\n#### start() :void\nStarts/restarts function flow execution if it's previously been stopped or paused. Condition: status = 'pause' | 'stop'.\n```\nff.start(); // inside function\neventEmitter.emit('ff-start'); // out of function\n```\n\n#### pause() :void\nPauses function flow execution used in bundle methods (serial, one or parallel). Condition: status = 'start'.\n```\nff.pause(); // inside function\neventEmitter.emit('ff-pause'); // out of function\n```\n\n\n#### go(goTo:number) :void\nGo to the function used in the serial(funcs) method. Parameter goTo is the index number of funcs array and the condition 0 \u003c= goTo \u003c funcs.length must be fulfilled. When the execution of that function is finished, continue with the next function in funcs array.\nIt's usually used to go to another function which is in the serial() method.\n```\nf2.js\n------------------\nmodule.exports = (x, lib) =\u003e {\n  x++;\n  lib.echo.log('f2:: ', x);\n  if (x \u003c 13 ) { lib.ff.go(1); } // go back to f1\n  return x;\n};\n```\n\n#### next() :void\nStop execution of all funcs functions in serial(funcs) method and continue with the next serial, one or parallel bundle method.\nIt will work only inside a function used in the serial() method. A parameter is not needed for this method.\n```\nf2.js\n------------------\nmodule.exports = (x, lib) =\u003e {\n  x++;\n  lib.echo.log('f2::', x);\n  lib.ff.next();\n  return x;\n};\n```\n\n#### jump(jumpTo:number) :void\nJump to iteration number defined in the repeat(n) method. When that iteration is executed continue with the next iteration in repeat(n) method. The current iteration will finish with all its functions.\nParameter jumpTo is the iteration number and the condition 0 \u003c jumpTo \u003c= n must be fulfilled.\nIt's usually used to skip some iterations under certain conditions. To get a current iteration number use ff.iteration.\n```\nf2.js\n------------------\nmodule.exports = (x, lib) =\u003e {\n  x++;\n  lib.echo.log('f2::', x);\n  if (lib.ff.iteration === 2) { lib.ff.jump(10); } // on 2nd iteration jump to last iteration\n  return x;\n};\n```\n\n#### break() :void\nBreaks all iterations in repeat(n) method. Parameter is not required. The current iteration will finish with all its functions.\nIt sets this.jumpTo = Infinity. It's used inside the function to stop all repeats (iterations).\n```\nffunc.js\n------------------\nmodule.exports = (x, lib) =\u003e {\n  x++;\n  if (x.val \u003e 2) { lib.ff.break(); } // stop iterations defined in main.js by ff.repeat(n);\n  return x;\n};\n```\n\n\n### /*=========== DELAYS ==============*/\n#### delay(ms:number) :void\nDelay in miliseconds.\n```\nawait ff.delay(3400); // delay of 3.4 seconds\n```\n\n#### delay(msMin:number, msMax:number) :void\nRandom delay from msMin to msMax.\n```\nawait ff.delayRnd(3000, 8000); // delay between 3 and 8 seconds\n```\n\n\n\n\n\n### License\nThe software licensed under [AGPL-3](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmikodanic%2Ffunctionflowx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmikodanic%2Ffunctionflowx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmikodanic%2Ffunctionflowx/lists"}