{"id":13393955,"url":"https://github.com/cognitect-labs/transducers-js","last_synced_at":"2025-09-29T02:32:35.990Z","repository":{"id":21064594,"uuid":"24363972","full_name":"cognitect-labs/transducers-js","owner":"cognitect-labs","description":"Transducers for JavaScript","archived":true,"fork":false,"pushed_at":"2023-06-03T21:41:12.000Z","size":275,"stargazers_count":1603,"open_issues_count":19,"forks_count":44,"subscribers_count":53,"default_branch":"master","last_synced_at":"2025-01-08T09:15:36.494Z","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":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cognitect-labs.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}},"created_at":"2014-09-23T08:54:59.000Z","updated_at":"2025-01-02T11:48:56.000Z","dependencies_parsed_at":"2024-01-06T11:14:14.623Z","dependency_job_id":null,"html_url":"https://github.com/cognitect-labs/transducers-js","commit_stats":null,"previous_names":[],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cognitect-labs%2Ftransducers-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cognitect-labs%2Ftransducers-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cognitect-labs%2Ftransducers-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cognitect-labs%2Ftransducers-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cognitect-labs","download_url":"https://codeload.github.com/cognitect-labs/transducers-js/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234583683,"owners_count":18856280,"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-07-30T17:01:03.637Z","updated_at":"2025-09-29T02:32:35.538Z","avatar_url":"https://github.com/cognitect-labs.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","Libraries"],"sub_categories":["[Javascript](https://developer.mozilla.org/en-US/docs/Web/JavaScript)"],"readme":"# This library is no longer maintained, feel free to fork and update as per the license\n\n# transducers-js\n\nA high performance\n[Transducers](http://blog.cognitect.com/blog/2014/8/6/transducers-are-coming)\nimplementation for JavaScript.\n\nTransducers are composable algorithmic transformations. They are\nindependent from the context of their input and output sources and\nspecify only the essence of the transformation in terms of an\nindividual element. Because transducers are decoupled from input or\noutput sources, they can be used in many different processes -\ncollections, streams, channels, observables, etc. Transducers compose\ndirectly, without awareness of input or creation of intermediate\naggregates.\n\nFor further details about Transducers see the following resources:\n* [\"Transducers are coming\" announce blog post](http://blog.cognitect.com/blog/2014/8/6/transducers-are-coming)\n* [Rich Hickey's Transducers StrangeLoop presentation](https://www.youtube.com/watch?v=6mTbuzafcII)\n* [API Docs](http://cognitect-labs.github.io/transducers-js/classes/transducers.html)\n\ntransducers-js is brought to you by [Cognitect Labs](http://cognitect-labs.github.io/).\n\n## Releases and Dependency Information\n\n* Latest release: 0.4.180\n\n### JavaScript\n\nYou can include either the [release](http://cdn.cognitect.com/transducers/transducers-0.4.180-min.js) (2K gzipped) or [development](http://cdn.cognitect.com/transducers/transducers-0.4.180.js) build of transducers-js on your webpage. We also provide [Require.js](http://requirejs.org) compatible [release](http://cdn.cognitect.com/transducers/transducers-0.4.180-amd-min.js) and [dev](http://cdn.cognitect.com/transducers/transducers-0.4.180-amd.js) builds.\n\n### Node.js\n\ntransducers-js is released to [npm](https://www.npmjs.org). Add transducers-js to your `package.json` dependencies:\n\n```javascript\n{...\n  \"dependencies\": {\n    \"transducers-js\": \"0.4.180\"\n  }\n ...}\n```\n\n### Bower\n\nYou can also include transducers-js in your `bower.json` dependencies:\n\n```javascript\n{...\n  \"dependencies\": {\n    \"transducers-js\": \"0.4.180\"\n  }\n ...}\n```\n\n## Usage\n\n### Requiring\n\nTo import the library under Node.js you can just use `require`:\n\n```js\nvar t = require(\"transducers-js\");\n```\n\nThe browser release of the library simply exports a top level\n`transducers` object:\n\n```js\nvar t = transducers;\n```\n\n### Basic Usage\n\nWith \u003c=ES5:\n\n```js\nvar map    = t.map,\n    filter = t.filter,\n    comp   = t.comp,\n    into   = t.into;\n\nvar inc = function(n) { return n + 1; };\nvar isEven = function(n) { return n % 2 == 0; };\nvar xf = comp(map(inc), filter(isEven));\n\nconsole.log(into([], xf, [0,1,2,3,4])); // [2,4]\n```\n\nWith ES6:\n\n```js\nlet {map, filter, comp, into} = t;\n\nlet inc = (n) =\u003e n + 1;\nlet isEven = (n) =\u003e n % 2 == 0;\nlet xf = comp(map(inc), filter(isEven));\n\nconsole.log(into([], xf, [0,1,2,3,4])); // [2,4]\n```\n\n## Documentation\n\nDocumentation can be found [here](http://cognitect-labs.github.io/transducers-js/classes/transducers.html)\n\n## Integration\n\ntransducers-js can also easily be used in combination with *existing*\nreduce implementations, whether native or the shims provided by\n[Underscore](http://underscorejs.org) and\n[Lodash](http://lodash.com). Doing so with native and Underscore can\ndeliver significant performance benefits. Transducers may be easily\nconverted from their object representation into the necessary\ntwo-arity function via `toFn`.\n\n```js\nvar arr   = [0,1,2,3,4,5,6,7,8,9,10],\n    apush = function(arr, x) { arr.push(x); return arr; },\n    xf    = comp(map(inc), filter(isEven)),\n    toFn  = t.toFn;\n\narr.reduce(toFn(xf, apush), []); // native\n_(arr).reduce(toFn(xf, apush), []); // underscore or lodash\n```\n\n### Immutable-js\n\ntransducers-js can work with custom collection types and still\ndeliver the same performance benefits, for example with Immutable-js:\n\n```js\nvar Immutable  = require(\"immutable\"),\n    t          = require(\"transducers-js\"),\n    comp       = t.comp,\n    map        = t.map,\n    filter     = t.filter,\n    transduce  = t.transduce;\n\nvar inc = function(n) { return n + 1; };\nvar isEven = function(n) { return n % 2 == 0; };\nvar sum = function(a,b) { return a+b; };\n\nvar largeVector = Immutable.List();\n\nfor(var i = 0; i \u003c 1000000; i++) {\n    largeVector = largeVector.push(i);\n}\n\n// built in Immutable-js functionality\nlargeVector.map(inc).filter(isEven).reduce(sum);\n\n// faster with transducers\nvar xf = comp(map(inc),filter(isEven));\ntransduce(xf, sum, 0, largeVector);\n```\n\n### ES6 Collections\n\nES6 collections return iterators and therefore can be\nreduced/transduced. For example with\n[transit-js](https://github.com/cognitect/transit-js) collections\nwhich satisfy many of the proposed Map/Set methods:\n\n```js\nvar transit = require(\"transit-js\"),\n    t       = require(\"transducers-js\"),\n    m       = transit.map([\"foo\", \"bar\", \"baz\", \"woz\"]),\n    vUC     = function(kv) { return [kv[0], kv[1].toUpperCase()]; },\n    xf      = t.map(vUC);\n    madd    = function(m, kv) { m.set(kv[0], kv[1]); return m; };\n\ntransduce(xf, madd, transit.map(), m.entries()); // Map [\"foo\", \"BAR\", \"baz\", \"WOZ\"]\n```\n\n## The Transducer Protocol\n\nIt is a goal that all JavaScript transducer implementations\ninteroperate regardless of the surface level API. Towards this end the\nfollowing outlines the protocol all transducers must follow.\n\n### Transducer composition\n\nTransducers are simply a function of one arity. The only argument\nis another transducer *transformer* (labeled `xf` in the code base).\nNote the distinction between the *transducer* which is a function of\none argument and the *transformer* an object whose methods we'll\ndescribe in the following section.\n\nFor example the following simplified definition of `map`:\n\n```js\nvar map = function(f) {\n    return function(xf) {\n        return Map(f, xf);\n    };\n};\n```\n\nSince transducers are simply functions of one argument they can be\ncomposed easily via function composition to create transformer\npipelines. Note that transducers return transformers when invoked.\n\n### Transformer protocol\n\nTransformers are objects. They must implement 3 methods, `@@transducer/init`,\n`@@transducer/result` and `@@transducer/step`. If a transformer is intended to \nbe composed with other transformers they should either close over the next \ntransformer or store it in a field.\n\nFor example the `Map` transformer could look something like the\nfollowing:\n\n```js\nvar Map = function(f, xf) {\n    return {\n       \"@@transducer/init\": function() { \n           return xf[\"@@transducer/init\"](); \n       },\n       \"@@transducer/result\": function(result) { \n           return xf[\"@@transducer/result\"](result); \n       },\n       \"@@transducer/step\": function(result, input) {\n           return xf[\"@@transducer/step\"](result, f(input)); \n       }\n    };\n};\n```\n\nNote how we take care to call the next transformer in the pipeline. We\ncould have of course created `Map` as a proper JavaScript type with\nprototype methods - this is in fact how it is done in transducers-js.\n\n### Reduced\n\nDetecting the reduced state is critical to short circuiting a\nreduction/transduction. A reduced value is denoted by any JavaScript\nobject that has the property `@@transducer/reduced` set to `true`.\nThe reduced value should be stored in the `@@transducer/value` property of this \nobject.\n\n### Iteration\n\nAnything which implements `@@iterator` which returns an ES6 compliant\niterator is reducible/transducible. An ES6 iterator may also just be given directly to `reduce` or `transduce`.\n\n## Building\n\nFetch the dependencies:\n\n```\nbin/deps\n```\n\nTo build for Node.js\n\n```\nbin/build_release_node\n```\n\nTo build for the browser\n\n```\nbin/build_release_browser\n```\n\n## Running the tests\n\nMake sure you've first fetched the dependencies, then:\n\n```\nbin/test\n```\n\n## Contributing \n\nThis library is open source, developed internally by [Cognitect](http://cognitect.com). Issues can be filed using [GitHub Issues](https://github.com/cognitect-labs/transducers-js/issues).\n\nThis project is provided without support or guarantee of continued development.\nBecause transducers-js may be incorporated into products or client projects, we prefer to do development internally and do not accept pull requests or patches. \n\n## Copyright and License\n\nCopyright © 2014-2015 Cognitect\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcognitect-labs%2Ftransducers-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcognitect-labs%2Ftransducers-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcognitect-labs%2Ftransducers-js/lists"}