{"id":21186596,"url":"https://github.com/fetchte/teflow","last_synced_at":"2025-07-12T03:37:10.815Z","repository":{"id":57159179,"uuid":"42692061","full_name":"fetchTe/teFlow","owner":"fetchTe","description":"A function wrapper to help you organize your code in cleaner functional manner.","archived":false,"fork":false,"pushed_at":"2017-03-20T06:56:46.000Z","size":305,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-17T01:35:24.807Z","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":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fetchTe.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-09-18T01:26:33.000Z","updated_at":"2017-03-20T06:37:50.000Z","dependencies_parsed_at":"2022-09-08T10:40:11.147Z","dependency_job_id":null,"html_url":"https://github.com/fetchTe/teFlow","commit_stats":null,"previous_names":["fetchte/teflow","artisin/teflow"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fetchTe%2FteFlow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fetchTe%2FteFlow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fetchTe%2FteFlow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fetchTe%2FteFlow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fetchTe","download_url":"https://codeload.github.com/fetchTe/teFlow/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243639555,"owners_count":20323511,"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-11-20T18:24:36.864Z","updated_at":"2025-03-14T20:18:14.251Z","avatar_url":"https://github.com/fetchTe.png","language":"JavaScript","readme":"# teFlow _A pipeline for control and flow_\n\n[![No Maintenance Intended](http://unmaintained.tech/badge.svg)](http://unmaintained.tech/)[![license](http://img.shields.io/badge/license-mit-3498db.svg)](https://github.com/artisin/ifd/blob/master/LICENSE) [![npm](https://img.shields.io/npm/v/te-flow.svg)](https://github.com/artisin/ifd/blob/master/LICENSE) [![Dependencies Status](https://david-dm.org/artisin/te-flow.svg)](https://david-dm.org/artisin/ifd) [![wercker status](https://app.wercker.com/status/e67347a76765e3822455de87c1fa1ec6/s/master \"wercker status\")](https://app.wercker.com/project/byKey/e67347a76765e3822455de87c1fa1ec6)\n\n\n## Important!!!!\nI wrote this package early in my career because I needed a better way to control Functions and data flow. At the time of creation, I thought this was what functional programming entailed or was? Nevertheless, while I do not recommend you use this package it is an interesting concept, and it works, it fucking works hella magic considering I created this at a time when I had little idea what I was doing. (I still don’t know what I’m doing, but I do have a little better idea.) It’s the backbone of [`ctr`](https://github.com/ctr-lang/ctr), and it did the job for the time, but like I said previously I don’t recommend you use this package.\n\n\n## Intro\n\nA function wrapper which creates a pipeline to help you organize your code in a cleaner functional manner. In a nutshell teFlow creates an argument pipeline/stream through `apply` so you can be functional with your thoughts and code.\n\n```js\n//The native way\nlet res1 = one();\nlet res2 = two.apply(null, res1);\nlet res3 = three.apply(null, res2);\n\n//The teFlow way\nlet res = teFlow(\n  one,\n  two,\n  three\n);\n```\n\n\n## Usage\n### Install\n\n```\nnpm install te-flow --save-dev\n```\n\n```\nyarn add te-flow\n```\n\n### Use\n```\nvar teFlow = require('te-flow');\n```\n###### _Alternative_ \nDownload the `te-flow.js` or `te-flow-browsers.js` file depending on your use in the `/lib` folder and drop it into your project. The difference between the two files is the `-browser` injects all the dependencies into one file while the default uses `require` to include the dependencies. \n###### _Compressed Files_\nI recommend you use webpack to manage your Js assets but I understand this is sometimes not an option so in the lib folder I have also included compressed and non-webpacked files.\n\n### Commands\nFirst, make sure you have [yarn](https://yarnpkg.com) [installed](https://yarnpkg.com/en/docs/install).\n\n__SetUp__\n```\nyarn run link\nyarn install\n```\n\n__Test__\n```\nyarn test\n```\n\n__Development__\n```\nyarn run dev\n```\n\n__Build__\n```\nyarn run bulid\n```\n\n\n\n## Api\n\n### Init Options\n+ `args` || `initArgs`\n    * Value: `Object`, `Method`, `Object Methods` \n    * Sets the initial arguments which will be passed to the first function that is invoked.\n+ `this`\n    * Value: `Object`\n    * Default: `null`\n    * Sets the value of `this` that will be applied to your functions otherwise your functions will be applied with null ex:`fn.apply(null, [args])`\n+ `objReturn` \n    * Value: `Boolean` \n    * Default: `true`\n    * Allows you to return an `object` whose values are mapped and passed onto the next function as arguments instead of having to return an array or the `arguments` object making your code much more readable.\n+ `objKeep`\n    * Value: `Boolean` \n    * Default: `false`\n    * This is a particularly dangerous option, but useful in some use cases. What is does is process the first `object` returned and maps out those key/values pairs as separate individual `object` arguments. This can be quite useful with `reduce` and the like with certain data structures. But do note order in objects are not guaranteed in JavaScript  \n+ `flow`\n    * Value:`Boolean` \n    * Default:`false`\n    * An interesting option, basically every return from each invoked function is pushed into the argument pipeline. \n+ `flatten`\n    * Value: `Boolean`\n    * Default: `false`\n    * Flattens any sub-arrays in the stream.\n\n### Return Options\nNote: These options need to be passed as the initial object argument in the return.\n\n+ `_return`\n    * Value: `Boolean`\n    * It will immediately return the values at hand and not call the next functions in line.\n+ `_kill`\n    * Value: `Boolean`\n    * It will immediately return `undefined` and not call the next functions in line.\n+ `_objReturn`\n    * Value: `Boolean`\n    * Temporarily alter the default setting for said function.\n_ `_objKeep`\n    * Value: `Boolean`\n    * Temporarily alter the default setting for said function.\n\n### Control Options\nNote: Still it bit unsure how I want to handle these options yet. \n\n+ `start`\n    * Value: `Object Methods`\n    * Arguments before applied to function.\n+ `end`\n    * Value: `Object Methods`\n    * Arguments after applied to function.\n+ `res`\n    * Value: `Object Methods`\n    * The value that is returned from all functions.\n+ `memoize`\n    * Value: `Boolean`\n    * Default: `true`\n    * Uses lodash memoize to reduce overhead.\n\n## Examples\nNote: These examples are using `ECMAScript 2015` syntax.\n\n#### Basic Concept\nThe basic concept is that each function will be invoked and then the return will be passed onto the next function as the argument.\n```js\nconst one = function () {\n  return 1;\n};\n\n//oneVal the value returned from fn one\n//oneVal === 1\nconst two = function (oneVal) {\n  return oneVal + 1;\n};\n\n//oneVal the value returned from fn two\n//twoVal === 2\nconst three = function (twoVal) {\n  return twoVal + 1;\n};\n\nlet res = teFlow(\n  one,\n  two,\n  three\n);\n//res === 3\n```\n\n#### Setting The Options\nOptions are set via a `call` object argument or as a `object` being the first argument. If your using `object` method the option keys must be prefixed with `_`. \n```js\n//call\nlet res = teFlow.call({\n  this: self,\n  flow: true,\n  args: {\n    argOne: 1,\n    cool: 'dog'\n  }},\n  fnOne,\n  fnTwo,\n  fnThree\n);\n\n//obj\nlet res = teFlow({\n  _this: self,\n  _flow: true,\n  _args: {\n    argOne: 1,\n    cool: 'sorta'\n  }},\n  fnOne,\n  fnTwo,\n  fnThree\n);\n```\n\n_Ps. for the rest of these examples I will be using the `call` methodology._\n\n#### Passing Initial Arguments - `args`\nThe `args` option allows you to set the initial arguments which in turn are applied to the first function.\n```js\n//All methods will produce the same arguments\nconst fnOne = function (one, two, three) {\n  //one === 1\n  //two === true\n  //three === 'three'\n};\n\n//Object\nteFlow.call({\n  args: {\n    one: 1,\n    two: true,\n    three: 'three'\n  }},\n  fnOne\n);\n\n//Method\nteFlow.call({\n  args: function () {\n    return {\n      one: 1,\n      two: true,\n      three: 'three'\n    };\n  }},\n  fnOne\n);\n\n//Object with methods\nteFlow.call({\n  args: {\n    one: function () {\n      return 1;\n    },\n    two: function () {\n      return true;\n    },\n    three: function () {\n      return 'three';\n    }\n  }},\n  fnOne\n);\n\n```\n\n\n#### Object Return - `objReturn`\nBy default the `objReturn` option is set to __true__ to help you better organize and visualize what your are passing onto the next function. That being said, if you were to return a non object it will reset the argument stream to that value. \n```js\nconst one = function () {\n  return 1;\n};\n\n//oneVal === 1\nconst two = function (oneVal) {\n  let twoVal = oneVal++;\n  return {\n    oneVal,\n    twoVal\n  };\n};\n\n//oneVal === 1\n//twoVal === 2\nconst three = function (oneVal, twoVal) {\n  let threeVal = twoVal++;\n  return {\n    oneVal,\n    twoVal,\n    threeVal\n  };\n};\n\n//oneVal === 1\n//twoVal === 2\n//threeVal === 3\nconst addOne = function (oneVal, twoVal, threeVal) {\n  oneVal++;\n  twoVal++;\n  threeVal++;\n  return {\n    oneVal,\n    twoVal,\n    threeVal\n  };\n};\n\nlet res = teFlow(\n  one,\n  two,\n  three,\n  addOne\n);\n//res === [2, 3, 4]\n```\n\n#### Specified Return Object Method\nFor convenience, readability, and a bit of extra control if you have a `Object Method` with the key of `return` as your last value it will be the final function that is invoked and whatever is return will be the results.\n```js\n//oneVal === 1\nconst one = function (oneVal) {\n  return {\n    oneVal\n  };\n};\n\n//oneVal === 1\nconst two = function (oneVal) {\n  let twoVal = 2;\n  return {\n    oneVal,\n    twoVal\n  };\n};\n\n//oneVal === 1\n//twoVal === 2\nconst three = function (oneVal, twoVal) {\n  let threeVal = 3;\n  return {\n    oneVal,\n    twoVal,\n    threeVal\n  };\n};\n\n\nlet res = teFlow.call({\n  args: {\n    oneVal: 1\n  }},\n  one,\n  two,\n  three, {\n    //oneVal === 1\n    //twoVal === 2\n    //threeVal === 3\n    return: function (oneVal, twoVal, threeVal) {\n      // res will equale whatever is returned here\n      return 'Beer Me!'\n    }\n  }\n);\n//res === 'Beer Me!'\n```\n\n#### Object Keep - `objKeep`\nBy default the `objKeep` option is set to __false__,  nevertheless, as I said previously this is a particularly dangerous option, but useful in some use cases. What is does is process the first `object` returned and maps out those key/values pairs as separate individual `object` arguments. This can be quite useful with `reduce` and the like when dealing with certain data structures. \n\n__Note:__ The order in objects are not guaranteed in JavaScript.\n```js\n//Merge helper\nconst _ = require('lodash');\n\nconst one = function () {\n  return {\n    keyOne: 1\n  };\n};\n\n//oneVal === {keyOne: 1}\nconst two = function (oneVal) {\n  return _.merge(oneVal, {keyTwo: 2});\n};\n\n//oneVal === {keyOne: 1}\n//twoVal === {keyTwo: 2}\nconst three = function (oneVal, twoVal) {\n  return _.merge(oneVal, twoVal, {keyThree: 3});\n};\n\nlet res = teFlow.call({objKeep: true},\n  one,\n  two,\n  three\n);\n//res === [{keyOne: 1}, {keyTwo: 2}, {keyThree: 3}]\n```\n\nWhile `objKeep` is great and all there will be times when you will not want it to be returned as such. Good news, you can override the set default on a individual function basis through your return and passing `_objKeep` as the first argument. This action is only temporary and after the return it will revert back to the set default.\n```js\n//using the same code as above just overriding the _objKeep\nconst three = function (oneVal, twoVal) {\n  //oneVal === {keyOne: 1}\n  //twoVal === {keyTwo: 2}\n  return {\n    _objKeep: false,\n    //make note of the key value pair\n    one: _.merge(oneVal, twoVal, {keyThree: 3})\n  };\n};\n//You might have expected a result like below but since\n//the obj is assinged to the `one` obj we are only passing\n//along one argument here\n//res === [{keyOne: 1, keyTwo: 2, keyThree: 3}]\n\n//Alternativly if you want to pass only the values just dont\n//assing the objs to a key\nconst three = function (oneVal, twoVal) {\n  //oneVal === {keyOne: 1}\n  //twoVal === {keyTwo: 2}\n  return {\n    _objKeep: false,\n    _.merge(oneVal, twoVal, {keyThree: 3})\n  };\n};\n\n//res === [1, 2, 3,]\n```\n\n\n#### Specified Return Object Method Example Two\nLong story short, I accidentally made another example for the specified return but rather than omitting it I will leave it here because it demonstrates a somewhat different use case. There might be times when you would like to specify your return to a certain global variable or something of the sort. Don't you fret my friend you can do so via passing an `object` as the last argument that has the key of `return` and then the corresponding value will be what is returned. The `return` can be a specified `object` or `method`.\n```js\n//To Be returned\nlet globalArray = [];\nlet staticStr = 'Static';\nlet string = null;\n\n//oneVal === 'Did you'\nconst two = function (oneVal) {\n  globalArray.push(oneVal + ' say,');\n  string = oneVal + ' say, ';\n  return 'you';\n};\n\n//oneVal === 'you'\nconst three = function (twoVal) {\n  globalArray.push(twoVal + ' needed to');\n  string += twoVal + ' needed to';\n  return {\n    key1: 'specify',\n    key2: 'your',\n    key3: 'return?',\n    space: ' '\n  };\n};\n\n//k1 === 'specify'\n//k2 === 'your'\n//k3 === 'return?'\n//sp === ' '\nconst four = function (k1, k2, k3, sp) {\n  globalArray.push(k1 + sp + k2 + sp + k3);\n  string += sp + k1 + sp + k2 + sp + k3;\n  return true;\n};\n\nlet res = teFlow(\n  one,\n  two,\n  three,\n  four, {\n    return: function (cool) {\n      //cool === true\n      return {\n        static: staticStr,\n        globalArray: globalArray,\n        string: string,\n        cool: cool\n      };\n    }\n  }\n);\n// res = {\n//  static: 'Static',\n//  globalArray: [\"Did you say,\", \"you needed to\", \"specify your return?\"],\n//  string: \"Did you say, you needed to specify your return?\",\n//  cool: true\n// }\n\n```\n\n\n#### This - `this`\nBy default each function is invoked via `fn.apply(null, [args])` so of course you have the ability to set `this`. In addition, you can reassign `this` in you return object via the `_this` key and the corresponding value will be reassigned to `this`. \n\n```js\n//A Little Module Pattern\nconst beThis = (function () {\n  let count = 0;\n  let cool = function (obj) {\n    this.name = obj.name;\n    this.getName = function () {\n      return this.name;\n    };\n    this.changeName = function (newName) {\n      this.name = newName;\n    };\n    this.returnThis = function () {\n      return this;\n    };\n    this.incNum = function () {\n      count++;\n    };\n    this.rtnNum = function() {\n      return count;\n    };\n  };\n  return cool;\n})();\n\nconst addMe = function () {\n  return this.getName();\n};\n\n//name === '\u003c/artisin\u003e'\n//bump shared count\nconst changeMe = function (name) {\n  this.incNum();\n  //change name\n  this.changeName('Te');\n  return {\n    oldName: name,\n    newName: this.getName()\n  };\n};\n\n//oldName === '\u003c/artisin\u003e'\n//newName === 'Te'\nconst addYou = function (oldName, newName) {\n  //Add you\n  var you = new beThis({\n    name: 'You'\n  });\n  //bind me to current this ref for latter use\n  var me = function() {\n    return this;\n  };\n  me = me.call(this);\n  return {\n    //reassign this\n    _this: you,\n    me: me\n  };\n};\n\nlet res = teFlow.call({\n  //set the `this` ref for `addMe`\n  this: new beThis({\n    name: '\u003c/artisin\u003e'\n  })},\n  addMe,\n  changeMe,\n  addYou, {\n    return: function (me) {\n      //me ref to me this\n      return {\n        count: this.rtnNum(),\n        myName: me.getName(),\n        //reassigned this from prv fn\n        yourName: this.getName()\n      };\n    }\n  }\n);\n\n// res = {\n//   count: 1,\n//   myName: 'Te',\n//   yourName: 'You'\n// }\n```\n\n#### Flow - `flow`\nWith this option set to true every return will be added to a single return array. Additionally, you can pass `flatten: true` which will flatten any sub-arrays that are returned. \n```js\nconst one = function () {\n  return 1;\n};\nconst two = function () {\n  return 2;\n};\nconst three = function () {\n  //no return\n};\nconst four = function () {\n  return 4;\n};\n\nlet res = teFlow.call({flow: true},\n  one,\n  two,\n  three,\n  four\n);\n// res === [1, 2, 4];\n```\n\n#### Return - `_return`\nReturns values at said point and does not call the next functions in line. __Note:__ If you have a return method in teFlow it will return the values to that return method.\n```js\n//oneVal === 1\nconst one = function (oneVal) {\n  return {\n    oneVal: oneVal\n  };\n};\n\n//oneVal === 1\nconst two = function (oneVal) {\n  let twoVal = 2;\n  //return said vaules at this point\n  return {\n    _return: true,\n    oneVal: oneVal,\n    twoVal: twoVal\n  };\n};\n\nconst three = function (oneVal, twoVal) {\n  let threeVal = 3;\n  return {\n    oneVal: oneVal,\n    twoVal: twoVal,\n    threeVal: threeVal\n  };\n};\n\nconst res = teFlow.call({\n  args: {\n    oneVal: 1\n  }},\n  one,\n  two,\n  three\n);\n// res === [1, 2];\n```\n\n#### Kill - `_kill`\nStops everything and returns `undefined`\n```js\n//oneVal === 1\nconst one = function (oneVal) {\n  return {\n    oneVal: oneVal\n  };\n};\n\n//oneVal === 1\nconst two = function (oneVal) {\n  let twoVal = 2;\n  //return said vaules at this point\n  return {\n    _kill: true,\n    oneVal: oneVal,\n    twoVal: twoVal\n  };\n};\n\nconst three = function (oneVal, twoVal) {\n  let threeVal = 3;\n  return {\n    oneVal: oneVal,\n    twoVal: twoVal,\n    threeVal: threeVal\n  };\n};\n\nconst res = teFlow.call({\n  args: {\n    oneVal: 1\n  }},\n  one,\n  two,\n  three\n);\n// res === undefined;\n```\n\n\n\n#### Control Methods\n_Docs Coming Soon, need to do some cogitating_\nNote: I did write some early test for these methods if you would like a better picture.\n\nThese methods will be invoked every start, end, or as the result of the current function. The functions will be applied in order as listed. For example if your end arguments look something like this `[1, 2, 3]` and you had two function it would do the following: `fn1(arg[0])`, `fn2(arg[0])`, `fn1(arg[1])`, `fn2(arg[1])`, ...\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffetchte%2Fteflow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffetchte%2Fteflow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffetchte%2Fteflow/lists"}