{"id":21522214,"url":"https://github.com/greguz/fluido","last_synced_at":"2025-04-09T22:23:07.424Z","repository":{"id":37502915,"uuid":"173336103","full_name":"greguz/fluido","owner":"greguz","description":"A drop in replacement for stream with Promise support and more!","archived":false,"fork":false,"pushed_at":"2023-12-15T21:29:17.000Z","size":511,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-24T00:16:17.580Z","etag":null,"topics":["node","promise","stream"],"latest_commit_sha":null,"homepage":"","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/greguz.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":"2019-03-01T16:42:27.000Z","updated_at":"2023-12-11T14:31:14.000Z","dependencies_parsed_at":"2023-02-19T06:46:06.207Z","dependency_job_id":null,"html_url":"https://github.com/greguz/fluido","commit_stats":null,"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/greguz%2Ffluido","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/greguz%2Ffluido/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/greguz%2Ffluido/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/greguz%2Ffluido/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/greguz","download_url":"https://codeload.github.com/greguz/fluido/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247999859,"owners_count":21031046,"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":["node","promise","stream"],"created_at":"2024-11-24T01:09:37.347Z","updated_at":"2025-04-09T22:23:07.399Z","avatar_url":"https://github.com/greguz.png","language":"JavaScript","funding_links":["https://www.buymeacoffee.com/greguz"],"categories":[],"sub_categories":[],"readme":"# fluido\n\n[![npm version](https://badge.fury.io/js/fluido.svg)](https://badge.fury.io/js/fluido)\n[![Dependencies Status](https://david-dm.org/greguz/fluido.svg)](https://david-dm.org/greguz/fluido.svg)\n[![ci](https://github.com/greguz/fluido/actions/workflows/ci.yaml/badge.svg?branch=master)](https://github.com/greguz/fluido/actions/workflows/ci.yaml)\n[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)\n\nFluido is a drop-in replacement for the native `stream` module. It adds some functions that aren't included in the standard module and adds `Promise` support to stream methods. It also enables _concurrent_ jobs while writing or transforming.\n\n## Features\n\n- **Promise**: you can use `async/await` inside stream methods, and functions without a callback will return a `Promise`.\n- **Concurrency**: a concurrency option available for `Writable` and `Transform` streams.\n- **ESM**: support native ESM (`import` and `export` keywords).\n- **CommonJS**: support old Node.js runtimes (`require`).\n- **TypeScript**: types declaration are included.\n\n## Install\n\n```\nnpm install --save fluido\n```\n\n## Usage\n\n### Callback and `Promise`\n\nThe [`pipeline`](https://nodejs.org/api/stream.html#streampipelinestreams-callback) and [`finished`](https://nodejs.org/api/stream.html#streamfinishedstream-options-callback) functions now returns a `Promise` if a callback function is not provided as last argument.\n\nThe `pipeline` function supports mapping functions as argument. This makes not possibile to Fluido to understand when the last function passed inside the pipeline is a callback or a mapping function.\n\nA special type of callback needs to be used in that case:\n\n```javascript\nimport { asCallback, isCallback, pipeline } from 'fluido'\n\nconst callback = asCallback(err =\u003e {\n  if (err) {\n    // handle error\n  } else {\n    // all done\n  }\n})\n\nconsole.log(isCallback(callback)) // true\nconsole.log(isCallback(() =\u003e {})) // false\n\npipeline(source, mapSource, callback)\n```\n\n### Stream with `async/await`\n\nStream implementation methods `_construct`, `_write`, `_writev`, `_final`, `_transform`, `_flush`, and `_destroy` (and their option conunterpart) now support the `async` keyword and/or a `Promise` as return value.\n\n```javascript\nimport { Readable, Transform, Writable } from 'fluido'\n\nconst r = new Readable({\n  async construct () {\n    // construct async stuff\n  },\n  async destroy () {\n    // destroy async stuff\n  }\n})\n\nconst t = new Transform({\n  async construct () {\n    // construct async stuff\n  },\n  async transform (chunk) {\n    // transform async stuff\n  },\n  async flush () {\n    // flush async stuff\n  },\n  async destroy () {\n    // destroy async stuff\n  }\n})\n\nconst w = new Writable({\n  async construct () {\n    // construct async stuff\n  },\n  async write (chunk) {\n    // write async stuff\n  },\n  async writev (items) {\n    // write async stuff\n  },\n  async final () {\n    // finalize async stuff\n  },\n  async destroy () {\n    // destroy async stuff\n  }\n})\n```\n\nA _Readable_ stream does not implement a callback for the `_read` method by default. Because of that, It's not possible for Fluido to automatically detect when the `_read` method needs to be `async`.\n\nTo support `async` reads, a new method is available: `_asyncRead` (along side with its `asyncRead` option).\n\n```javascript\nimport { Readable } from 'fluido'\n\nconst r = new Readable({\n  async asyncRead (size) {\n    // read async stuff\n  }\n})\n```\n\n### Concurrency\n\nPassing the `concurrency` option to the Writable (may be Duplex or Transform) constructor will cause _write (or _transform) calls to be concurrent.\n\n```javascript\nconst { Transform, Writable } = require('fluido')\n\nconst w = new Writable({\n  concurrency: 8,\n  async write (chunk) {\n    // At most 8 concurrent writes\n  }\n})\n\nconst t = new Transform({\n  concurrency: 8,\n  async transform (chunck) {\n    // At most 8 concurrent transforms\n  }\n})\n```\n\n### isNodeStream(value)\n\nReturns `true` if `value` is a _Readable_ **or** a _Writable_ stream.\n\n- `value` `\u003c*\u003e`\n- Returns: `\u003cBoolean\u003e`\n\n```javascript\nimport { Readable, Writable, isNodeStream } from 'fluido'\n\nconsole.log(isNodeStream(new Readable())) // true\nconsole.log(isNodeStream(new Writable())) // true\n```\n\n### isReadableStream(value)\n\nReturns `true` if `value` is a _Readable_ stream.\n\n- `value` `\u003c*\u003e`\n- Returns: `\u003cBoolean\u003e`\n\n```javascript\nimport { Readable, Writable, isReadableStream } from 'fluido'\n\nconsole.log(isReadableStream(new Readable())) // true\nconsole.log(isReadableStream(new Writable())) // false\n```\n\n### isWritableStream(value)\n\nReturns `true` if `value` is a _Writable_ stream.\n\n- `value` `\u003c*\u003e`\n- Returns: `\u003cBoolean\u003e`\n\n```javascript\nimport { Readable, Writable, isWritableStream } from 'fluido'\n\nconsole.log(isWritableStream(new Readable())) // false\nconsole.log(isWritableStream(new Writable())) // true\n```\n\n### isDuplexStream(value)\n\nReturns `true` if `value` is both a _Readable_ **and** a _Writable_ stream.\n\n- `value` `\u003c*\u003e`\n- Returns: `\u003cBoolean\u003e`\n\n```javascript\nimport { Duplex, Readable, Writable, isDuplexStream } from 'fluido'\n\nconsole.log(isDuplexStream(new Readable())) // false\nconsole.log(isDuplexStream(new Writable())) // false\nconsole.log(isDuplexStream(new Duplex())) // true\n```\n\n### merge(...streams)\n\nCombines two or more streams into a _Duplex_ stream that writes concurrently to all _Writable_ streams and reads concurrently from all _Readable_ streams.\n\n- `streams` `\u003cStream[]\u003e`\n- Returns: `\u003cDuplex\u003e`\n\n## Donate\n\nThank you!\n\n[![\"Buy Me A Coffee\"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/greguz)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgreguz%2Ffluido","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgreguz%2Ffluido","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgreguz%2Ffluido/lists"}