streamiterator
Advanced tools
Comparing version 1.0.6 to 1.0.7
@@ -15,5 +15,5 @@ "use strict"; | ||
value: function asyncIterator() { | ||
return (0, _streamiterator2.default)(this)[Symbol.asyncIterator](); | ||
return _streamiterator2.default.createStreamIterator(this)[Symbol.asyncIterator](); | ||
} | ||
}); | ||
} |
@@ -14,82 +14,101 @@ "use strict"; | ||
function streamIterator(stream) { | ||
if (typeof stream[Symbol.asyncIterator] === "function") { | ||
return stream; | ||
} | ||
return _defineProperty({}, Symbol.asyncIterator, function () { | ||
var resolvers = []; | ||
var results = []; | ||
var closed = false; | ||
function createStreamIterator(stream) { | ||
var _result; | ||
function copyResults() { | ||
while (resolvers.length > 0 && results.length > 0) { | ||
resolvers.shift()(results.shift()); | ||
} | ||
while (resolvers.length > 0 && closed) { | ||
var resolvers = []; | ||
var results = []; | ||
var inputClosed = false; | ||
var outputClosed = false; | ||
function copyResults() { | ||
while (!outputClosed && resolvers.length > 0 && results.length > 0) { | ||
resolvers.shift()(results.shift()); | ||
} | ||
if (inputClosed || outputClosed) { | ||
while (resolvers.length > 0) { | ||
resolvers.shift()({ value: undefined, done: true }); | ||
} | ||
if (resolvers.length > 0) { | ||
stream.resume(); | ||
} else { | ||
if (!closed) { | ||
stream.pause(); | ||
} | ||
} | ||
if (resolvers.length > 0) { | ||
stream.resume(); | ||
} else { | ||
if (!inputClosed) { | ||
stream.pause(); | ||
} | ||
} | ||
} | ||
function onData(value) { | ||
results.push({ value: value, done: false }); | ||
copyResults(); | ||
function pushResult(promise) { | ||
if (!inputClosed) { | ||
results.push(promise); | ||
} | ||
} | ||
function onError(error) { | ||
results.push(Promise.reject(error)); | ||
close(); | ||
} | ||
function onData(value) { | ||
pushResult({ value: value, done: false }); | ||
copyResults(); | ||
} | ||
function onEnd() { | ||
close(); | ||
} | ||
function onError(error) { | ||
pushResult(Promise.reject(error)); | ||
close(); | ||
} | ||
function close() { | ||
if (!closed) { | ||
closed = true; | ||
stream.removeListener("data", onData).removeListener("error", onError).removeListener("end", onEnd); | ||
// .destroy?.() | ||
if (stream.destroy) { | ||
stream.destroy(); | ||
} | ||
function onEnd() { | ||
close(); | ||
} | ||
function close() { | ||
if (!inputClosed) { | ||
inputClosed = true; | ||
stream // | ||
.removeListener("data", onData).removeListener("error", onError).removeListener("end", onEnd); | ||
// .destroy?.() | ||
if (stream.destroy) { | ||
stream.destroy(); | ||
} | ||
copyResults(); | ||
} | ||
copyResults(); | ||
} | ||
stream.on("data", onData).on("error", onError).on("end", onEnd).pause(); | ||
stream // | ||
.on("data", onData).on("error", onError).on("end", onEnd).pause(); | ||
return { | ||
next: function next() { | ||
return new Promise(function (resolve) { | ||
resolvers.push(resolve); | ||
copyResults(); | ||
var result = (_result = {}, _defineProperty(_result, Symbol.asyncIterator, function () { | ||
return result; | ||
}), _defineProperty(_result, "next", function next() { | ||
return new Promise(function (resolve) { | ||
resolvers.push(resolve); | ||
copyResults(); | ||
}); | ||
}), _defineProperty(_result, "return", function _return(value) { | ||
return new Promise(function (resolve) { | ||
if (resolvers.length === 0) { | ||
finish(); | ||
} else { | ||
var last = resolvers.pop(); | ||
resolvers.push(function (value) { | ||
last(value); | ||
finish(); | ||
}); | ||
}, | ||
return: function _return(value) { | ||
return new Promise(function (resolve) { | ||
if (resolvers.length === 0) { | ||
finish(); | ||
} else { | ||
var last = resolvers.pop(); | ||
resolvers.push(function (result) { | ||
last(result); | ||
finish(); | ||
}); | ||
} | ||
function finish() { | ||
resolve({ value: value, done: true }); | ||
close(); | ||
} | ||
}); | ||
} | ||
}; | ||
}); | ||
function finish() { | ||
outputClosed = true; | ||
resolve({ value: value, done: true }); | ||
close(); | ||
} | ||
}); | ||
}), _result); | ||
return result; | ||
} | ||
function streamIterator(stream) { | ||
if (typeof stream[Symbol.asyncIterator] === "function") { | ||
return stream; | ||
} else { | ||
return createStreamIterator(stream); | ||
} | ||
} | ||
Object.assign(streamIterator, { createStreamIterator: createStreamIterator }); | ||
module.exports = exports["default"]; |
{ | ||
"name": "streamiterator", | ||
"version": "1.0.6", | ||
"version": "1.0.7", | ||
"description": "converts ReadableStream into AsyncIterator", | ||
@@ -8,3 +8,5 @@ "main": "distr/streamiterator.js", | ||
"build": "babel source --out-dir distr", | ||
"prepare": "npm run build" | ||
"prettier": "prettier --write $(cat .prettier) 'source/**/*.js' '*.js'", | ||
"prepare": "npm run prettier && npm run build", | ||
"test": "jest" | ||
}, | ||
@@ -16,7 +18,10 @@ "repository": "https://github.com/vadzim/streamiterator", | ||
"babel-cli": "^6.26.0", | ||
"babel-jest": "^20.0.3", | ||
"babel-plugin-add-module-exports": "^0.2.1", | ||
"babel-preset-env": "^1.6.0", | ||
"babel-preset-flow": "^6.23.0", | ||
"babel-preset-stage-0": "^6.24.1" | ||
"babel-preset-stage-0": "^6.24.1", | ||
"jest": "^20.0.4", | ||
"prettier": "^1.5.3" | ||
} | ||
} |
# streamiterator | ||
converts ReadableStream into AsyncIterator | ||
Converts ReadableStream into AsyncIterator. | ||
### Using ### | ||
With this module you can ![iterate](https://github.com/tc39/proposal-async-iteration) over a stream with a plain loop: | ||
```js | ||
import streamIterator from "streamiterator" | ||
// or | ||
// const streamIterator = require("streamiterator") | ||
async function DoIt(stream) { | ||
for await (const value of streamIterator(stream)) { | ||
console.log(`Read: ${value}`) | ||
} | ||
} | ||
``` | ||
As of August, 2017 you need smth like either ![babel](http://babeljs.io/) or ![node.js 8.4.0 or higher](https://nodejs.org/) with `--harmony_async_iteration` switch to be able to use `for await` operator. | ||
Of course, you can iterate without `for await`, though it is not so nice as using syntactic suger: | ||
```js | ||
import streamIterator from "streamiterator" | ||
async function DoIt(stream) { | ||
for (let done, value, iterator = streamIterator(stream); {done, value} = await iterator.next(), !done;) { | ||
console.log(`Read: ${value}`) | ||
} | ||
} | ||
``` | ||
If the stream emits an error, it will be thrown while looping. Wrap your loop in `try..catch` to deal with it. | ||
If eventually streams will support async iteration natively then this module will just redirect iteration to those native mechanism. No overhead will be added. | ||
### Polyfill ### | ||
But if you believe that writing `streamIterator(...)` everywhere is a bullshit and in your world streams have to be iterable from the scratch right now, then you can import `streamiterator/polyfill` in the root of your project and iterate just on streams: | ||
```js | ||
import "streamiterator/polyfill" | ||
import fs from "fs" | ||
async function DoIt() { | ||
for await (const data of fs.createReadableStream("./data.txt")) { | ||
console.log(data) | ||
} | ||
} | ||
``` | ||
Note that you don't need to import `streamiterator/polyfill` in every file of your project. Just in the `main.js` or similar. | ||
### Contributing ### | ||
__Please contribute!__ | ||
All contributions are greatly appreciated no matter how small or large the contribution is. | ||
Whether it's a small grammar fix in the README, a huge bug fix, or just an issue report, you will be recognized as a 'Contributor' to this project. | ||
Please, feel free to ![open an issue](https://github.com/vadzim/streamiterator/issues) if you have any question. |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
112993
9
110
62
8