{"id":16440332,"url":"https://github.com/constgen/streamed","last_synced_at":"2026-06-25T06:31:20.778Z","repository":{"id":57372137,"uuid":"123112222","full_name":"constgen/streamed","owner":"constgen","description":"Array-like stream","archived":false,"fork":false,"pushed_at":"2019-03-04T19:29:17.000Z","size":35,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-28T21:49:29.915Z","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/constgen.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":"2018-02-27T10:21:32.000Z","updated_at":"2019-03-04T19:29:19.000Z","dependencies_parsed_at":"2022-09-07T19:12:41.129Z","dependency_job_id":null,"html_url":"https://github.com/constgen/streamed","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/constgen/streamed","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/constgen%2Fstreamed","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/constgen%2Fstreamed/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/constgen%2Fstreamed/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/constgen%2Fstreamed/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/constgen","download_url":"https://codeload.github.com/constgen/streamed/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/constgen%2Fstreamed/sbom","scorecard":{"id":303190,"data":{"date":"2025-08-11","repo":{"name":"github.com/constgen/streamed","commit":"825e12e010bb25f85aecf6b8519e97764ff696c4"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":0,"reason":"Found 0/16 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}}]},"last_synced_at":"2025-08-17T21:17:25.020Z","repository_id":57372137,"created_at":"2025-08-17T21:17:25.020Z","updated_at":"2025-08-17T21:17:25.020Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34763481,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-25T02:00:05.521Z","response_time":101,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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-10-11T09:11:51.517Z","updated_at":"2026-06-25T06:31:20.758Z","avatar_url":"https://github.com/constgen.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Streamed\n\n[![Build Status](https://travis-ci.org/constgen/streamed.svg?branch=master)](https://travis-ci.org/constgen/streamed)\n\n**Streamed** is an array-like stream. It has methods that are similar to Array ones. In many cases it can be used as a replacement of arrays but with additional reactive features. \"Reactive\" means you can define a chain ones and stream will process already collected data and future coming data in the same way.\n\n## Importing\n\n`streamed` can be installed from NPM\n\n```bash\n❯ npm install --save streamed\n```\n\nThen you can import it using ES syntax\n\n```js\nimport Streamed from 'streamed' \n```\n\nor using CommonJS \n\n```js\nvar Streamed = require('streamed')\n```\n\nAlso it can be imported with the regular `\u003cscript\u003e` tag. This will expose the `Streamed` variable to the global scope\n\n```html\n\u003cscript src=\"../node_modules/streamed/dist/streamed.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n   console.log(Streamed)\n\u003c/script\u003e\n```\n\n## Basic usage\n\nStreams are reactive and can handle values pushed before and after callbacks attached.\n\n```js\nvar stream = new Streamed(Infinity)\nstream.push(1, 2, 3)\nstream.forEach(console.log)\nstream.push(4, 5, 6)\n```\n\noutputs:\n\n```txt\n1\n2\n3\n4\n5\n6\n```\n\n### Stream size\n\nThe first and the only argument of the `Streamed` class is its size (like in Array). It defines how much data will be buffered:\n\n- `new Streamed(Infinity)`: Infinite size. All data will be stored in the stream instance\n- `new Streamed({Number})`: Only last items of a given number will be saved. Old items will be destroyed.\n- `new Streamed()`: No items will be buffered. Any data will be passed down to the stream but will not be stored in the instance.\n\nExamples:\n\n**Infinite:**\n\n```js\nvar stream = new Streamed(Infinity)\nstream.push(1, 2, 3, 4, 5, 6)\nstream.forEach(console.log) // logs: 1, 2, 3, 4, 5, 6\n```\n\n**Limited:**\n\n```js\nvar stream = new Streamed(4)\nstream.push(1, 2, 3, 4, 5, 6)\nstream.forEach(console.log) // logs: 3, 4, 5, 6\n```\n\n**Empty:**\n\n```js\nvar stream = new Streamed()\nstream.push(1, 2, 3, 4, 5, 6)\nstream.forEach(console.log) // no logs. But will log if something is pushed later\n```\n\nEvery option above is suitable for different cases. Typically you would like the last pushed value to be buffered. So you can create 1-size stream. Handlers attached any time in the future will handle only the last most relevant value. This makes a stream to act like an observable. See the example of tracking of a geo-position:\n\n```js\nvar geoPositions = new Streamed(1)\ngeoPositions.push({long: 10.5788457, lat: 36.76867834})\ngeoPositions.push({long: 11.323122, lat: 34.4564656})\ngeoPositions.push({long: 12.7879993, lat: 35.778993})\n\ngeoPositions.forEach(console.log) //logs: {long: 12.7879993, lat: 35.778993} - only the latest position, because earlier are obsolete\n```\n\n## Chain methods\n\n### .push(value:Any)\n\nPasses the next value to a stream. If no argument is provided nothing is pushed. Returns a current stream. May have infinite amount of arguments which values will be respectively pushed to the stream.\n\n```js\nvar stream = new Streamed()\n\nstream.push('a')\nstream.push('b')\nstream.push('c')\n// or\nstream.push('a', 'b', 'c')\n```\n\n### .forEach(callback:Function)\n\nSimilarly to array, `callback` function is called on every item pushed. Only one argument is passed with an item value because streamed items has no indexes. Returns a new stream with the same values. So it can be chained after.\n\n```js\nvar stream = new Streamed()\nvar iterationStream = stream\n   .forEach(function(value){\n      console.info(value)\n   })\n   .forEach(function(value){\n      console.log(value)\n   })\n```\n\nInherits the size of the stream which it is attached to.\n\n### .map(callback:Function)\n\nSimilarly to array, `callback` function is called on every item pushed. Only one argument is passed with an item value because streamed items has no indexes. Returns a new stream with values returned from a `callback`. So it can be chained after.\n\n```js\nvar stream = new Streamed()\nvar types = stream\n   .map(getType)\n   .map(toUpperCase)\n\nfunction getType(value){\n   return typeof value\n}\nfunction toUpperCase (value){\n   return value.toUpperCase()\n}\n\ntypes.forEach(function(value){\n   console.log(value)\n})\n\n// we need to push items to `stream` so they can flow to `types`\nstream.push(1, 'str', undefined, {})\n```\n\n_Output:_\n\n```txt\nNUMBER\nSTRING\nUNDEFINED\nOBJECT\n```\n\nInherits the size of the stream which it is attached to.\n\n### .filter(callback:Function)\n\nSimilarly to array, `callback` function is called on every item pushed. Only one argument is passed with an item value because streamed items has no indexes. Returns a new stream with values filtered with a `callback`. So it can be chained after.\n\n```js\nvar stream = new Streamed()\nvar positiveNumbers = stream\n   .filter(isNumber)\n   .filter(isPositive)\n\nfunction isNumber(value){\n   return typeof value === 'number'\n}\nfunction isPositive (value){\n   return value \u003e 0\n}\n\npositiveNumbers.forEach(function(value){\n   console.log(value)\n})\n\n// we need to push items to `stream` so they can flow to `positiveNumbers`\nstream.push(-1, 0, 'str', undefined, {}, 10, Infinity)\n```\n\n_Output:_\n\n```js\n10\nInfinity\n```\n\nInherits the size of the stream which it is attached to.\n\n### .buffer(size:Number)\n\nCreates a new stream from the existing one but with the given size. All values will be pushed without changes but buffered with the necessary limit. Returns a new stream.\n\n```js\nvar stream = new Streamed() // 0 size\nvar numbers = stream\n   .filter(isNumber)\n   .buffer(3) // set necessary size\n\nstream.push(1, '2', 3, 4, 5, '6')\n\nstream.forEach(console.log) // logs:\nnumbers.forEach(console.log) // logs: 3, 4, 5\n```\n\nThis method is convenient if you want to change the size of an existing stream producing a new one or if you want to keep some amount of last values in a memory if the original stream size is 0.\n\n### .reduce(callback:Function, initialValue)\n\nSimilarly to array, `callback` function is called on every item pushed. Only one argument is passed with an item value because streamed items has no indexes. Returns a new stream with values returned from a `callback`. So it can be chained after.\n\n```js\nvar numbers = new Streamed()\nvar sums = numbers\n   .reduce(add)\n   .forEach(function(value){\n      console.log(value)\n   })\n\nfunction add(valueA, valueB) {\n   return valueA + valueB\n}\n\n// we need to push items to `numbers` so they can flow to `sums`\nnumbers.push(1, 2, 3, 4, 5, 6, 7, 8)\n```\n\n_Output:_\n\n```txt\n1\n3\n6\n10\n15\n21\n28\n36\n```\n\nThe size of the result stream is **always reduced to 0**\n\nThere also an initial value can be passed as a second argument. It will be used as a first argument in the first call of the callback.\n\n```js\nvar numbers = new Streamed(4)\nvar sums = numbers\n   .reduce(add)\n   .forEach(function(value){\n      console.log(value)\n   })\n\nnumbers.push(1, 2, 3, 4, 5, 6, 7, 8)\n\n```\n\n_Output:_\n\n```txt\n1\n3\n6\n10\n14\n18\n22\n26\n```\n\nReducing has an optimization for every of 3 types of streams: unlimited, limited and infinite. If the stream has a size, only the necessary amount of data will be computed, e.g.:\n\n```js\nvar sums = numbers\n   .reduce(add, 10) // pass 10 as an initial value\n   .forEach(function(value){\n      console.log(value)\n   })\n\nnumbers.push(1, 2, 3, 4, 5, 6, 7, 8)\n\n```\n\n_Output:_\n\n```txt\n11\n13\n16\n20\n25\n31\n38\n46\n```\n\nKeep in mind that if the size of the stream is 1 and there is no initial value the callback will be not applied at all to any of values.\n\n### .merge(stream:Streamed)\n\nJoins values passed to both streams to a single new stream. Returns a new stream.\n\n```js\nvar streamA = new Streamed()\nvar streamB = new Streamed()\nvar streamTogether = streamA.merge(streamB)\n\nstreamTogether.forEach(console.log)\n\nstreamA.push(1)\nstreamB.push(2)\nstreamA.push(3)\n```\n\n_Output:_\n\n```txt\n1\n2\n3\n```\n\nThis is not a sequenced stream. So there is no difference between `streamA.merge(streamB)` and `streamB.merge(streamA)`. The data is pushed as it arrives.\n\nSince this method returns a new stream it may be merged with another one. For example you can merge several streams streamTogether\n\n```js\nstreamA.merge(streamB).merge(streamC).merge(streamD)\n```\n\nThe size of the new stream is equal to the sum of the sizes of 2 origin streams. It will completely buffer the values buffered in the both origin streams. E.g.:\n\n```js\nvar streamA = new Streamed(2)\nvar streamB = new Streamed(3)\nvar streamTogether = streamA.merge(streamA)\n\nconsole.log(streamTogether.size) // 5\n```\n\n### .pipe(stream:Streamed)\n\nForwards values from existing stream to another instance of a stream creating a connection between 2 streams. Returns the instance that is passed to the argument.\n\n```js\nvar streamA = new Streamed()\nvar streamB = new Streamed()\n\nstreamA.pipe(streamB)\nstreamB.forEach(console.log)\nstreamA.push('a', 'b', 'c')\n```\n\n_Output:_\n\n```text\na\nb\nc\n```\n\n### .unpipe(stream:Streamed)\n\nDestroys the connection between \"piped\" streams. Returns the instance that is passed to the argument.\n\n```js\nvar streamA = new Streamed()\nvar streamB = new Streamed()\n\nstreamA.pipe(streamB)\nstreamB.forEach(console.log)\nstreamA.push('a')\nstreamA.unpipe(streamB)\nstreamA.push('b', 'c')\n```\n\n_Output:_\n\n```text\na\n```\n\n### .unsubscribe()\n\nRemoves all piped and chained streams. Call this if you want to stop to handle values in a stream and would like to destroy it. Returns the same stream.\n\n```js\nvar stream = new Streamed()\nfunction getType(value){\n   return typeof value\n}\n\nstream.map(getType) // attach mapped stream\nstream.unsubscribe() // destroy mapped stream and any other handlers\nstream = undefined // delete reference\n```\n\n## Lazy evaluation\n\nBy default the stream computation is lazy and the data will start to flow thru chain if there is a side effect in form of one of two:\n\n- `.forEach()` at the end\n- `.pipe()` at the end\n\nFor example, console logs in this code will not be shown until `forEach()` is not attached\n\n```js\nvar values = new Streamed(Infinity)\nvar processedValues = values.filter(function(value){\n   console.log('filter', value)\n   return value \u003e 3\n}).map(function(value){\n   console.log('map', value)\n   return value + 10\n})\n\nvalues.push(1, 2, 3, 4, 5)\n```\n\nThis will not output anything as callbacks will not be even called. But as soon as we attach `forEach()` or pipe it to another stream, e.g.:\n\n```js\nprocessedValues.forEach(function(value){\n   console.log('forEach', value)\n})\n```\n\nit will output\n\n```txt\nfilter 1\nfilter 2\nfilter 3\nfilter 4\nmap 4\nforEach 14\nfilter 5\nmap 5\nforEach 15\n```\n\nLooking at logs you may notice that data flows from top to down instead of left to right how it happens in regular Arrays.\n\nWe also have used `new Streamed(Infinity)` to not lose the data later. If you will not set the size and will not process the data in a moment when it is pushed it will be lost. Some time it is expected but some time it is not. You can manage it passing the necessary size limit in the first argument of the `Streamed` class.\n\n### Cold and hot streams\n\nIf you are familiar with terminology of _hot_ and _cold_ streams it may be more clear to you if we say that\n\n- all `Streamed` instances with undefined size are _cold_ streams by default\n- all `Streamed` instances with the size greater than 0 are _hot_ streams by default\n- `pipe()` and `forEach()` methods return _hot_ streams\n- `map()`, `filter()`, `reduce()`, `merge()`, `buffer()`, `unpipe()` return _cold_ streams\n\n## Inheritance\n\nInheritance usually is used to provide a custom stream source. This may be UI input events, global events, server-sent events, etc. This example shows how to create a custom stream class of mouse moves in a browser:\n\n```js\nclass MouseMoves extends Streamed {\n   constructor (size) {\n      super(size)\n      window.addEventListener('mousemove', this, false)\n   }\n   handleEvent (event) {\n      this.push(event)\n   }\n}\n\nvar mouseMoves = new MouseMoves(1)\nmouseMoves.forEach(console.log)\n```\n\n\u003c!-- \nСостояние flowing или paused, Flow Control --\u003e\n\n\u003c!-- ### Readable and Writable streams --\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconstgen%2Fstreamed","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fconstgen%2Fstreamed","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconstgen%2Fstreamed/lists"}