{"id":18552428,"url":"https://github.com/andrejewski/reem-flow","last_synced_at":"2025-05-15T11:13:02.264Z","repository":{"id":18083258,"uuid":"21147133","full_name":"andrejewski/reem-flow","owner":"andrejewski","description":"Middleware flow controls for Reem","archived":false,"fork":false,"pushed_at":"2014-06-24T00:44:44.000Z","size":148,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-19T16:25:28.993Z","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":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andrejewski.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}},"created_at":"2014-06-24T00:39:00.000Z","updated_at":"2019-03-28T16:39:13.000Z","dependencies_parsed_at":"2022-09-26T21:40:57.686Z","dependency_job_id":null,"html_url":"https://github.com/andrejewski/reem-flow","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrejewski%2Freem-flow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrejewski%2Freem-flow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrejewski%2Freem-flow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrejewski%2Freem-flow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andrejewski","download_url":"https://codeload.github.com/andrejewski/reem-flow/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254328389,"owners_count":22052633,"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-06T21:14:11.882Z","updated_at":"2025-05-15T11:12:57.399Z","avatar_url":"https://github.com/andrejewski.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"reem-flow\n===\n\nMiddleware flow controls for Reem.\n\n## Installation\n\n```bash\nnpm install reem-flow # --save for projects\n```\n\n## Usage\n\n```javascript\nvar flow = require('reem-flow'),\n\tFlowClass = flow.Flow,\n// see \"controls\" for use cases\n```\n\n## About\n\n`reem-flow` is a plugin for [Reem](https://github.com/andrejewski/reem) that simplifies the process of adding middleware to Reem. The whole idea is a way to combine middleware which should work only under certain conditions and `reem-flow` provides functions for that task. Each flow control returns a Reem compatible plugin so controls can be nested if the logic sees fit.\n\n## Controls\n\nThis plugin comes with only a few controls, but alone or combined they are still pretty powerful and feature rich.\n\n### cond\n\nCond (conditional/switch) is an adaption of JavaScript's own conditional switch made for Reem plugins. Instead of reserved words switch, case, and default, here we uses cond, when, and otherwise respectively. Breaks are automatically called once a `when` clause is met, falling back to the `otherwise` clause if none are met.\n\n```javascript\nflow.cond('basename')\n\t.when('source')\n\t\t.use(plugin)\n\t\t.use(plugin)\n\t.when('assets')\n\t\t.use([plugins])\n\t.otherwise()\n\t\t.use(plugin);\n```\n\n`Flow.cond (prop Function(item Reem.Item) Any) Plugin`\nThe method takes a function, passes that function the current item, and uses the result to compare with any `when` clauses. If the comparison yields true, the included plugins execute.\n\n`Flow.cond (prop String) Plugin`\nIf a String is passed, `cond` will use the item's value at that property name. If the String has access dots (`nested.prop`), `item[nested][prop]` will be used as you would expect.\n\n`Flow.cond (prop Any) Plugin`\nThis will use the plain value at `item[prop]`.\n\n#### when clause\n\nThe when clauses enqueue (Array::push) so be careful not to pass the same condition to different clauses and expect them to be grouped. The `when` clause accepts different type signatures.\n\n`when (value Function(prop Any) Boolean) Plugin`\nIf given a function, the value of cond's argument given the item is passed to this function. If this function returns true, the middleware is executed on that item and `cond` stops cascading down remaining clauses.\n\n`when (value Any) Plugin`\nAny value to compare to the value returned by the `cond` argument.\n\n#### otherwise clause\n\nOnce the otherwise clause is called, no more when clauses can be added and any call of `use` is attached to otherwise. Otherwise wraps `use` so plugins passed to `otherwise` will work as expected.\n\n### filter\n\nFilter is simple. If the given function applied to a given item returns true, the plugins are executed on the item.\n\n```javascript\nvar filter = flow.filter(function(item) {\n\treturn item.ignore;\n}).use(This).use(That).use(TheOtherThing);\n```\n\n### group\n\nGroup is a function taking no arguments that returns essentially a control plugin without any conditional logic. This would be used to group plugins and serve as a building block to other controls if desired.\n\n```javascript\nvar stack = flow.group()\n\t.use(thisSpecificallyFirst)\n\t.use(thatSpecificallySecond)\n```\n\n### within\n\nThis control handles the case of where plugins should only apply if the item is within the given list. \"Within\" does not mean \"within the immediate list.\" If any of the parent lists match, the item is run through the plugins all the same.\n\n```javascript\nvar inBlog = flow.within(BlogList),\n\tinAssets = flow.within(function(list) {\n\t\treturn list.filename === 'assets';\n\t});\n```\n\n`Flow.within (list Reem.List) Plugin`\nThe item must be within the given list for its plugin to execute. This uses `===` to compare the list to lists containing the item. This will override the standard type signatures this function shares with `filter` and `toggle` if the conditions are met.\n\n### toggle\n\nThis control is like filter but partitions items by whether the given function yields true or false. Both values have their own middleware stacks. The plugin uses, instead of `use`, `yes` and `no` (and `yay` and `nay`) chain-able calls to add plugins to the two separate stacks.\n\n```javascript\nvar isDraft = flow.toggle('draft')\n\t.yes(yayIsADraft)\n\t.no(booNotADraft)\n\t.yay(yesIsADraft)\n\t.nay(noNotADraft)\n```\n\n### Standard Control Interface\n\nThe `filter`, `within`, and `toggle` methods all have the same overloaded type signatures. They all result in a filter function that accepts an Reem.Item and returns a Boolean. \n\n```javascript\n// All of these are equivalent\nFlow.method(function(item) {\n\treturn item.draft === true;\n});\nFlow.method({draft: true});\nFlow.method(\"draft\");\nFlow.method(\"draft\", true);\n```\n\nThe type signatures below are checked for in order.\n\n`Flow.method (Function(item Reem.Item) Boolean) Plugin`\nPlain filter function, no coercion here.\n\n`Flow.method (obj Object) Plugin`\nShorthand for a variation of [Underscore's `matches`](http://underscorejs.org/#matches). Similar to `_.matches(obj)(item)`.\n\n`Flow.method (prop Any) Plugin`\nShorthand for `!!item[prop]`.\n\n`Flow.method (prop Any, value Any) Plugin`\nShorthand for `item[prop] === value`.\n\nIf the property name is a String and has access dots (`nested.prop`), these methods will use `item[nested][prop]` as you would expect.\n\n## Classes\n\n### Flow\nThis is just a simple class that contains all the control functions. None of the control functions rely on being part of a class, it is just for convenience.\n\nThis class is accessible via `require('reem-flow').Flow`.\n\n### Plugin\nTechnically not a class, but an interface. Most controls return plugins which have only the `use` function. `cond` and `toggle` are the exceptions. The plugin itself is a function that can be passed to Reem or another control.\n\n## Contributing\n\nIf you have an issue or find a bug open an issue and I will see what we can do. If you can fix the bug yourself, by all means send a pull request for consideration.\n\nUntil `reem` and `reem-flow` hit v1, I would like to keep backwards compatibility with the v0.0.1, treating it like v1. When the conditions are met for v1, we can cut away the cruft of v0.\n\n```bash\n# running tests\nnpm run test\nnpm run test-spec\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrejewski%2Freem-flow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandrejewski%2Freem-flow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrejewski%2Freem-flow/lists"}