├── src
├── index.js
├── lib
│ ├── util.js
│ ├── stream.js
│ └── operators.js
└── index.d.ts
├── rollup
├── test.js
└── build.js
├── examples
├── scripts
│ ├── fixtures.js
│ └── rollup.node.js
├── readme.md
├── node.js
├── node
│ └── fromFile.js
├── browser
│ ├── fromFetch.js
│ └── browser-adapter.js
├── index.html
└── csv-parser.js
├── test
├── index.js
├── utils.js
├── includes.js
├── util
│ └── source.js
├── concat.js
├── every.js
├── reduce.js
├── some.js
├── take.js
├── skip.js
├── map.js
├── filter.js
├── find.js
├── flatMap.js
├── slice.js
└── stream.js
├── .circleci
└── config.yml
├── LICENSE
├── .gitignore
├── package.json
├── dist
├── declarations
│ └── index.d.ts
└── bundle
│ ├── index.mjs
│ ├── module.js
│ ├── index.js
│ └── for-await.js
└── README.md
/src/index.js:
--------------------------------------------------------------------------------
1 | export * from './lib/operators';
2 | export {stream, toAsync as from} from './lib/stream';
3 |
--------------------------------------------------------------------------------
/rollup/test.js:
--------------------------------------------------------------------------------
1 | import node from 'rollup-plugin-node-resolve';
2 | import cjs from 'rollup-plugin-commonjs';
3 |
4 | export default {
5 | input: './test/index.js',
6 | plugins: [node(), cjs()]
7 | };
8 |
--------------------------------------------------------------------------------
/examples/scripts/fixtures.js:
--------------------------------------------------------------------------------
1 | console.log('id,foo,bar,bim');
2 |
3 | const int = () => Math.floor(Math.random() * 10);
4 |
5 | for (let i = 0; i<10000;i++){
6 | console.log(`${i},${int()},${int()},${int()}`);
7 | }
8 |
--------------------------------------------------------------------------------
/examples/scripts/rollup.node.js:
--------------------------------------------------------------------------------
1 | import node from 'rollup-plugin-node-resolve';
2 |
3 | export default {
4 | input: './examples/node.js',
5 | output: [{
6 | format: 'cjs'
7 | }],
8 | plugins:[node()]
9 | };
10 |
--------------------------------------------------------------------------------
/examples/readme.md:
--------------------------------------------------------------------------------
1 | # examples
2 |
3 | ### run for nodejs (version > 9)
4 |
5 | ``npm run example:node``
6 |
7 | ### run for browser (chrome without transpilation)
8 |
9 | ``npm run example:browser``
10 |
11 | [open in the browser](http://localhost:8080/examples/index.html
--------------------------------------------------------------------------------
/examples/node.js:
--------------------------------------------------------------------------------
1 | import {parser} from './csv-parser.js';
2 | import fromFile from './node/fromFile.js';
3 |
4 | //program
5 | (async function () {
6 | const stream = await parser(fromFile('./examples/fixture.csv'));
7 | for await (const line of stream) {
8 | console.log(line);
9 | }
10 | })();
11 |
--------------------------------------------------------------------------------
/examples/node/fromFile.js:
--------------------------------------------------------------------------------
1 | import {createReadStream} from 'fs';
2 |
3 | // note: create a new stream on every asyncIterator invocation
4 | export default (file, opts = {encoding: 'utf8'}) => {
5 | return ({
6 | [Symbol.asyncIterator]() {
7 | return createReadStream(file, opts)[Symbol.asyncIterator]();
8 | }
9 | });
10 | }
11 |
--------------------------------------------------------------------------------
/src/lib/util.js:
--------------------------------------------------------------------------------
1 | // with two arguments
2 | export const curry = (fn) => (a, b) => b === void 0 ? b => fn(a, b) : fn(a, b);
3 | export const toCurriedIterable = gen => curry((a, b) => ({
4 | [Symbol.asyncIterator]() {
5 | return gen(a, b);
6 | }
7 | }));
8 | export const toIterable = gen => (...args) => ({
9 | [Symbol.asyncIterator]() {
10 | return gen(...args);
11 | }
12 | });
13 |
--------------------------------------------------------------------------------
/examples/browser/fromFetch.js:
--------------------------------------------------------------------------------
1 | import iterable from './browser-adapter.js';
2 |
3 | export default (path, otps = {}) => {
4 | return {
5 | [Symbol.asyncIterator]: async function* () {
6 | const res = await fetch(path);
7 | for await (const chunk of iterable(res.body)) {
8 | // decode
9 | yield String.fromCodePoint(...chunk);
10 | }
11 | }
12 | };
13 | }
14 |
--------------------------------------------------------------------------------
/rollup/build.js:
--------------------------------------------------------------------------------
1 | export default {
2 | input: './src/index.js',
3 | output: [{
4 | file: './dist/bundle/index.js',
5 | format: 'cjs'
6 | }, {
7 | file: './dist/bundle/index.mjs',
8 | format: 'es'
9 | }, {
10 | file: './dist/bundle/module.js',
11 | format: 'es'
12 | }, {
13 | file: './dist/bundle/for-await.js',
14 | format: 'iife',
15 | name: 'ForAwait'
16 | }]
17 | };
18 |
--------------------------------------------------------------------------------
/test/index.js:
--------------------------------------------------------------------------------
1 | import util from './utils';
2 | import stream from './stream';
3 | import map from './map';
4 | import filter from './filter';
5 | import take from './take';
6 | import skip from './skip';
7 | import flatMap from './flatMap';
8 | import concat from './concat';
9 | import slice from './slice';
10 | import reduce from './reduce';
11 | import find from './find';
12 | import include from './includes';
13 | import every from './every';
14 | import some from './some';
15 |
--------------------------------------------------------------------------------
/examples/browser/browser-adapter.js:
--------------------------------------------------------------------------------
1 | export default async function* (readable) {
2 | let exhausted = false;
3 | const reader = readable.getReader();
4 | try {
5 | while (true) {
6 | const {value, done} = await reader.read();
7 | exhausted = done;
8 | if (done) {
9 | break;
10 | }
11 | yield value;
12 | }
13 | }
14 | finally {
15 | reader.cancel();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/test/utils.js:
--------------------------------------------------------------------------------
1 | import {test} from 'zora';
2 | import {curry} from '../src/lib/util';
3 |
4 | export default test('utils test suite', t => {
5 | t.test('should curry function with two arguments', t => {
6 | const sum = curry((a, b) => a + b);
7 | const plusTwo = sum(2);
8 |
9 | t.equal(sum(3, 2), 5, 'should return result when called with two arguments');
10 | t.equal(typeof plusTwo, 'function', 'should return a function when called with one argument');
11 | t.equal(plusTwo(4), 6, 'should curry function if called with one argument');
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/examples/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Title
6 |
7 |
8 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | # Javascript Node CircleCI 2.0 configuration file
2 | #
3 | # Check https://circleci.com/docs/2.0/language-javascript/ for more details
4 | #
5 | version: 2
6 | jobs:
7 | build:
8 | docker:
9 | # specify the version you desire here
10 | - image: circleci/node:9
11 |
12 | steps:
13 | - checkout
14 |
15 | # Download and cache dependencies
16 | - restore_cache:
17 | keys:
18 | - v1-dependencies-{{ checksum "package.json" }}
19 | # fallback to using the latest cache if no exact match is found
20 | - v1-dependencies-
21 |
22 | - run: npm install
23 |
24 | - save_cache:
25 | paths:
26 | - node_modules
27 | key: v1-dependencies-{{ checksum "package.json" }}
28 |
29 | # run tests!
30 | - run: npm run test:ci
31 |
32 |
--------------------------------------------------------------------------------
/examples/csv-parser.js:
--------------------------------------------------------------------------------
1 | import {stream} from '../dist/bundle/module.js';
2 |
3 | // take chunks stream (whether they come from file or network) and yield lines.
4 | export const lines = chunkStream => ({
5 | [Symbol.asyncIterator]: async function* () {
6 | let remaining = ''; // chunk may ends in the middle of a line
7 | for await (const chunk of chunkStream) {
8 | const chunkLines = (remaining + chunk).split('\n');
9 | remaining = chunkLines.pop();
10 | yield* chunkLines;
11 | }
12 | yield remaining;
13 | }
14 | });
15 |
16 | export async function parser(source) {
17 | const iterable = stream(lines(source))
18 | .map(i => i.split(','));
19 |
20 | const headers = await iterable
21 | .slice(0, 1)
22 | .reduce(acc => acc);
23 |
24 | return stream(iterable)
25 | .slice(1)
26 | .map(line => {
27 | const item = {};
28 | for (let i = 0; i < headers.length; i++) {
29 | item[headers[i]] = line[i];
30 | }
31 | return item;
32 | });
33 | }
34 |
35 |
36 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 RENARD Laurent
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (http://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # Typescript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | .idea
61 |
62 |
--------------------------------------------------------------------------------
/test/includes.js:
--------------------------------------------------------------------------------
1 | import {test} from 'zora';
2 | import {counterGenerator} from './util/source.js';
3 | import {includes} from '../src/lib/operators';
4 |
5 | export default test('includes test suite', t => {
6 | t.test('includes', async t => {
7 | const has3 = await includes(3, counterGenerator(5));
8 | t.equal(has3, true, 'should have 3');
9 |
10 | const has666 = await includes(666, counterGenerator(5));
11 | t.equal(has666, false, 'should not have 666');
12 |
13 | const has1 = await includes(0, 1, counterGenerator(5));
14 | t.equal(has1, false, 'should not have 0 when starting at 1');
15 |
16 | const has5 = await includes(5, 3, counterGenerator(10));
17 | t.equal(has5, true, 'should have 5 when starting at 3');
18 | });
19 |
20 | t.test('includes curried', async t => {
21 | const has3 = await includes(3)(counterGenerator(5));
22 | t.equal(has3, true, 'should have 3');
23 |
24 | const has666 = await includes(666)(counterGenerator(5));
25 | t.equal(has666, false, 'should not have 666');
26 |
27 | const has1 = await includes(0, 1)(counterGenerator(5));
28 | t.equal(has1, false, 'should not have 0 when starting at 1');
29 |
30 | const has5 = await includes(5, 3)(counterGenerator(10));
31 | t.equal(has5, true, 'should have 5 when starting at 3');
32 | });
33 |
34 | });
35 |
--------------------------------------------------------------------------------
/test/util/source.js:
--------------------------------------------------------------------------------
1 | export const wait = (time = 10) => new Promise(resolve => setTimeout(() => resolve(), time));
2 |
3 | export const counterGenerator = async function* (limit = 3) {
4 | let i = 0;
5 | while (true) {
6 | if (i >= limit) {
7 | break;
8 | }
9 | await wait();
10 | yield i;
11 | i++;
12 | }
13 | };
14 |
15 | export const counterIterable = (limit = 3) => ({
16 | [Symbol.asyncIterator]() {
17 | return counterGenerator(limit);
18 | }
19 | });
20 |
21 |
22 | export const breakableCounter = (limit = 3) => {
23 | let i = 0;
24 | let done = false;
25 |
26 | const instance = {
27 | [Symbol.asyncIterator]() {
28 | return this;
29 | },
30 | async next() {
31 | if (i >= limit || this.done === true) {
32 | return {done: true};
33 | }
34 | const item = {value: i, done: false};
35 | i++;
36 | return item;
37 | },
38 |
39 | async return() {
40 | done = true;
41 | return {done: true};
42 | }
43 | };
44 |
45 | Object.defineProperties(instance, {
46 | index: {
47 | get() {
48 | return i;
49 | }
50 | },
51 | done: {
52 | get() {
53 | return done;
54 | }
55 | }
56 | });
57 |
58 | return instance;
59 |
60 | };
61 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@lorenzofox3/for-await",
3 | "version": "0.2.1",
4 | "description": "operators and stream utilities for async iterators",
5 | "engines": {
6 | "node": ">=9.3.0"
7 | },
8 | "directories": {
9 | "test": "test"
10 | },
11 | "repository": {
12 | "type": "git",
13 | "url": "https://github.com/lorenzofox3/for-await.git"
14 | },
15 | "main": "./dist/bundle/index",
16 | "module": "./dist/bundle/module.js",
17 | "types": "./dist/bundle/index.d.ts",
18 | "scripts": {
19 | "build:clean": "rm -rf ./dist && mkdir -p ./dist/bundle ./dist/declarations",
20 | "build:bundle": "rollup -c ./rollup/build.js && cp ./src/index.d.ts ./dist/declarations/",
21 | "build": "npm run build:clean && npm run build:bundle",
22 | "test": "rollup -c ./rollup/test.js --output.format cjs | node",
23 | "test:ci": "rollup -c ./rollup/test.js --output.format cjs | node | tap-diff",
24 | "example:node": "rollup -c ./examples/scripts/rollup.node.js | node"
25 | },
26 | "files": [
27 | "dist/bundle",
28 | "dist/declarations"
29 | ],
30 | "keywords": [
31 | "stream",
32 | "for-await",
33 | "reactive-programming",
34 | "iterator",
35 | "async-iterator",
36 | "asyncIterator",
37 | "generator",
38 | "async"
39 | ],
40 | "author": "Laurent Renard",
41 | "license": "MIT",
42 | "devDependencies": {
43 | "rollup": "^1.27.14",
44 | "rollup-plugin-commonjs": "^10.1.0",
45 | "rollup-plugin-node-resolve": "^5.2.0",
46 | "tap-diff": "^0.1.1",
47 | "zora": "^3.1.8"
48 | },
49 | "dependencies": {}
50 | }
51 |
--------------------------------------------------------------------------------
/test/concat.js:
--------------------------------------------------------------------------------
1 | import {test} from 'zora';
2 | import {concat} from '../src/lib/operators';
3 | import {breakableCounter, counterGenerator} from './util/source.js';
4 |
5 | export default test('concat operator test suite', t => {
6 |
7 | t.test('basic', async t => {
8 | let i = 0;
9 | const to3 = counterGenerator();
10 | const stream = concat(666, [1, 2], {foo: 'bar'}, to3, 'foo');
11 |
12 | const result = [];
13 | for await (const item of stream) {
14 | i++;
15 | result.push(item);
16 | }
17 |
18 | t.equal(i, 7, 'should have seen 7 iterations');
19 | t.deepEqual(result, [666, [1, 2], {foo: 'bar'}, 0, 1, 2, 'foo'], 'should have seen the flattened items');
20 | });
21 |
22 | t.test('forward control flow events', async t => {
23 | const to3 = breakableCounter();
24 | const to3Bis = breakableCounter();
25 | let i = 0;
26 | const stream = concat(to3, to3Bis);
27 | const result = [];
28 | for await (const item of stream) {
29 | result.push(item);
30 | i++;
31 | if (i >= 4) {
32 | break;
33 | }
34 | }
35 |
36 | t.equal(i, 4, 'should have seen 4 iterations only');
37 | t.deepEqual(result, [0, 1, 2, 0], 'should have collected the flattened items');
38 | t.equal(to3.done, false, 'should have been exhausted regularly');
39 | t.equal(to3Bis.done, true, 'should have called the return hook');
40 | t.equal(to3.index, 3, 'should have been pulled 3 times');
41 | t.equal(to3Bis.index, 1, 'should have been pulled 1 time only');
42 | });
43 | });
44 |
--------------------------------------------------------------------------------
/test/every.js:
--------------------------------------------------------------------------------
1 | import {test} from 'zora';
2 | import {counterGenerator} from './util/source.js';
3 | import {every} from '../src/lib/operators';
4 |
5 | export default test('every test suite', t => {
6 | t.test('basic', async t => {
7 | let i = 0;
8 | const lowerThan5 = await every((item, index) => {
9 | t.equal(i, index, 'should have forwarded the index');
10 | i++;
11 | return item <= 5;
12 | }, counterGenerator(5));
13 |
14 | t.equal(i, 5, 'should have done 5 iterations');
15 | t.equal(lowerThan5, true, 'all items are lower than 5');
16 |
17 | i = 0;
18 |
19 | const odd = await every((item, index) => {
20 | t.equal(i, index, 'should have forwarded the index');
21 | i++;
22 | return item % 2 === 0;
23 | }, counterGenerator(5));
24 |
25 | t.equal(i, 2, 'should have done 2 iterations (until the first non odd number');
26 | t.equal(odd, false, 'not every item is odd');
27 | });
28 |
29 | t.test('curried', async t => {
30 | let i = 0;
31 | const lowerThan5 = await every((item, index) => {
32 | t.equal(i, index, 'should have forwarded the index');
33 | i++;
34 | return item <= 5;
35 | })(counterGenerator(5));
36 |
37 | t.equal(i, 5, 'should have done 5 iterations');
38 | t.equal(lowerThan5, true, 'all items are lower than 5');
39 |
40 | i = 0;
41 |
42 | const odd = await every((item, index) => {
43 | t.equal(i, index, 'should have forwarded the index');
44 | i++;
45 | return item % 2 === 0;
46 | })(counterGenerator(5));
47 |
48 | t.equal(i, 2, 'should have done 2 iterations (until the first non odd number');
49 | t.equal(odd, false, 'not every item is odd');
50 | });
51 |
52 | });
53 |
--------------------------------------------------------------------------------
/test/reduce.js:
--------------------------------------------------------------------------------
1 | import {reduce} from '../src/lib/operators';
2 | import {test} from 'zora';
3 | import {counterGenerator} from './util/source.js';
4 |
5 | export default test('test suite for reduce', t => {
6 |
7 | t.test('basic', async t => {
8 | let index = 0;
9 | const value = await reduce((acc, curr, i) => {
10 | t.equal(i, index, 'should have forwarded the index to the callback');
11 | index++;
12 | return acc + curr;
13 | }, 0, counterGenerator(5));
14 |
15 | t.equal(value, 10, 'should equal to the sum of 0+1+2+3+4');
16 | });
17 |
18 | t.test('with no initial value', async t => {
19 | let index = 1;
20 | const value = await reduce((acc, curr, i) => {
21 | t.equal(i, index, 'should have forwarded the index to the callback');
22 | index++;
23 | return acc + curr;
24 | }, counterGenerator(5));
25 |
26 | t.equal(value, 10, 'should equal to the sum of 0+1+2+3+4');
27 | });
28 |
29 | t.test('curried', async t => {
30 | let index = 0;
31 | const reducer = reduce((acc, curr, i) => {
32 | t.equal(i, index, 'should have forwarded the index to the callback');
33 | index++;
34 | return acc + curr;
35 | }, 0);
36 |
37 | const value = await reducer(counterGenerator(5));
38 | t.equal(value, 10, 'should equal to the sum of 0+1+2+3+4');
39 | });
40 |
41 | t.test('curried with no initial value', async t => {
42 | let index = 1;
43 | const reducer = reduce((acc, curr, i) => {
44 | t.equal(i, index, 'should have forwarded the index to the callback');
45 | index++;
46 | return acc + curr;
47 | });
48 |
49 | const value = await reducer(counterGenerator(5));
50 | t.equal(value, 10, 'should equal to the sum of 0+1+2+3+4');
51 | });
52 |
53 | });
54 |
--------------------------------------------------------------------------------
/test/some.js:
--------------------------------------------------------------------------------
1 | import {test} from 'zora';
2 | import {counterGenerator} from './util/source.js';
3 | import {some} from '../src/lib/operators';
4 |
5 | export default test('some test suite', t => {
6 | t.test('basic', async t => {
7 | let i = 0;
8 | const lowerThan5 = await some((item, index) => {
9 | t.equal(i, index, 'should have forwarded the index');
10 | i++;
11 | return item <= 5;
12 | }, counterGenerator(5));
13 |
14 | t.equal(i, 1, 'should have done 1 iteration as the first item is lower than 5');
15 | t.equal(lowerThan5, true, 'at least one item is lower than 5');
16 |
17 | i = 0;
18 |
19 | const greaterThanEvil = await some((item, index) => {
20 | t.equal(i, index, 'should have forwarded the index');
21 | i++;
22 | return item >= 666;
23 | }, counterGenerator(5));
24 |
25 | t.equal(i, 5, 'should have done the 5 iterations');
26 | t.equal(greaterThanEvil, false, 'There is no item greater than 666');
27 | });
28 |
29 | t.test('curried', async t => {
30 | let i = 0;
31 | const lowerThan5 = await some((item, index) => {
32 | t.equal(i, index, 'should have forwarded the index');
33 | i++;
34 | return item <= 5;
35 | })(counterGenerator(5));
36 |
37 | t.equal(i, 1, 'should have done 1 iteration as the first item is lower than 5');
38 | t.equal(lowerThan5, true, 'at least one item is lower than 5');
39 |
40 | i = 0;
41 |
42 | const greaterThanEvil = await some((item, index) => {
43 | t.equal(i, index, 'should have forwarded the index');
44 | i++;
45 | return item >= 666;
46 | })(counterGenerator(5));
47 |
48 | t.equal(i, 5, 'should have done the 5 iterations');
49 | t.equal(greaterThanEvil, false, 'There is no item greater than 666');
50 | });
51 |
52 | });
53 |
--------------------------------------------------------------------------------
/src/lib/stream.js:
--------------------------------------------------------------------------------
1 | import * as operators from './operators';
2 | import {toIterable} from './util';
3 |
4 | /*
5 | The iterable won't always be consumed with a for await statement (which implicitly convert an iterable into a asyncIterable) so we need to explicitly make it async iterable
6 | for await (const t of [1,2,3,4,5]){
7 | //no problem
8 | }
9 |
10 | but
11 |
12 | const iterator = [1,2,3][Symbol.asyncIterator]();
13 | //problem
14 | */
15 | export const toAsync = toIterable(async function* (iterable) {
16 | yield* iterable;
17 | });
18 |
19 | export const proto = {
20 | [Symbol.asyncIterator]() {
21 | return this._source[Symbol.asyncIterator]();
22 | },
23 | map(fn) {
24 | return stream(operators.map(fn, this));
25 | },
26 | filter(fn) {
27 | return stream(operators.filter(fn, this));
28 | },
29 | flatMap(fn) {
30 | return stream(operators.flatMap(fn, this));
31 | },
32 | slice(start = 0, end = void 0) {
33 | return stream(operators.slice(start, end, this));
34 | },
35 | concat(...values) {
36 | return stream(operators.concat(this, ...values));
37 | },
38 | reduce(fn, initialValue) {
39 | return operators.reduce(fn, initialValue, this);
40 | },
41 | find(fn) {
42 | return operators.find(fn, this);
43 | },
44 | findIndex(fn) {
45 | return operators.findIndex(fn, this);
46 | },
47 | includes(item, from = 0) {
48 | return operators.includes(item, from, this);
49 | },
50 | every(fn) {
51 | return operators.every(fn, this);
52 | },
53 | some(fn) {
54 | return operators.some(fn, this);
55 | }
56 | };
57 |
58 | export const stream = iterable => {
59 | const source = !iterable[Symbol.asyncIterator] ? toAsync(iterable) : iterable; // we make a difference as any wrap of iterable has performance impact (for the moment)
60 | return Object.create(proto, {_source: {value: source}});
61 | };
62 |
--------------------------------------------------------------------------------
/test/take.js:
--------------------------------------------------------------------------------
1 | import {test} from 'zora';
2 | import {take} from '../src/lib/operators';
3 | import {breakableCounter, counterGenerator, counterIterable} from './util/source';
4 |
5 | export default test('take operator', t => {
6 |
7 | t.test('basic', async t => {
8 | let i = 0;
9 | const to3 = counterGenerator();
10 | const stream = take(2, to3);
11 |
12 | for await (const item of stream) {
13 | t.equal(item, i, `should see item ${i}`);
14 | i++;
15 | }
16 |
17 | for await (const item of stream) {
18 | i++;
19 | }
20 |
21 | t.equal(i, 2, 'should have seen 2 iterations only');
22 |
23 | });
24 |
25 | t.test('forward the consumable nature of the underlying asyncIterator', async t => {
26 | let i = 0;
27 | const to3 = counterIterable();
28 | const stream = take(2, to3);
29 |
30 | for await (const item of stream) {
31 | t.equal(item, i, `should see the item ${i}`);
32 | i++;
33 | }
34 |
35 | t.equal(i, 2, 'should have seen 2 iterations');
36 | i = 0;
37 |
38 | for await (const item of stream) {
39 | t.equal(item, i, `should see the item ${i} again`);
40 | i++;
41 | }
42 |
43 | t.equal(i, 2, 'should have seen 2 iterations again');
44 |
45 | });
46 |
47 | t.test('forward control flow event', async t => {
48 | let i = 0;
49 | const to3 = breakableCounter();
50 | const stream = take(2, to3);
51 | for await (const item of stream) {
52 | i++;
53 | break;
54 | }
55 |
56 | t.equal(i, 1, 'should have done a single iteration');
57 |
58 | t.equal(to3.done, true, 'should have called the return of underlying iterator');
59 | t.equal(to3.index, 1, 'should have pulled one single time');
60 | });
61 |
62 | t.test('curried take', async t => {
63 | const getTwo = take(2);
64 | let i = 0;
65 | for await (const item of getTwo(counterGenerator())) {
66 | t.equal(item, i, `should have seen the item ${i}`);
67 | i++;
68 | }
69 |
70 | i = 0;
71 | for await (const item of getTwo(counterGenerator())) {
72 | t.equal(item, i, `should have seen the item ${i}`);
73 | i++;
74 | }
75 | });
76 | });
77 |
--------------------------------------------------------------------------------
/test/skip.js:
--------------------------------------------------------------------------------
1 | import {test} from 'zora';
2 | import {skip} from '../src/lib/operators';
3 | import {breakableCounter, counterGenerator, counterIterable} from './util/source.js';
4 |
5 | export default test('skip operator', t => {
6 |
7 | t.test('basic', async t => {
8 | let i = 1;
9 | const to3 = counterGenerator();
10 | const stream = skip(1, to3);
11 |
12 |
13 | for await (const item of stream) {
14 | t.equal(item, i, `should see item ${i}`);
15 | i++;
16 | }
17 |
18 | for await (const item of stream) {
19 | i++;
20 | }
21 |
22 | t.equal(i - 1, 2, 'should have seen 2 iterations only');
23 |
24 | });
25 |
26 | t.test('forward the consumable nature of the underlying asyncIterator', async t => {
27 | let i = 1;
28 | const to3 = counterIterable();
29 | const stream = skip(1, to3);
30 |
31 | for await (const item of stream) {
32 | t.equal(item, i, `should see the item ${i}`);
33 | i++;
34 | }
35 |
36 | t.equal(i - 1, 2, 'should have seen 2 iterations');
37 | i = 1;
38 |
39 | for await (const item of stream) {
40 | t.equal(item, i, `should see the item ${i} again`);
41 | i++;
42 | }
43 |
44 | t.equal(i - 1, 2, 'should have seen 2 iterations again');
45 |
46 | });
47 |
48 | t.test('forward control flow event', async t => {
49 | let i = 0;
50 | const to3 = breakableCounter();
51 | const stream = skip(1, to3);
52 | for await (const item of stream) {
53 | i++;
54 | break;
55 | }
56 |
57 | t.equal(i, 1, 'should have done a single iteration');
58 |
59 | t.equal(to3.done, true, 'should have called the return of underlying iterator');
60 | t.equal(to3.index, 2, 'should have pulled two items (one for the skipped');
61 | });
62 |
63 | t.test('curried skip', async t => {
64 | const skipOne = skip(1);
65 | let i = 1;
66 | for await (const item of skipOne(counterGenerator())) {
67 | t.equal(item, i, `should have seen the item ${i}`);
68 | i++;
69 | }
70 |
71 | i = 1;
72 | for await (const item of skipOne(counterGenerator())) {
73 | t.equal(item, i, `should have seen the item ${i}`);
74 | i++;
75 | }
76 | });
77 | });
78 |
--------------------------------------------------------------------------------
/test/map.js:
--------------------------------------------------------------------------------
1 | import {test} from 'zora';
2 | import {map} from '../src/lib/operators';
3 | import {counterIterable, breakableCounter, counterGenerator} from './util/source.js';
4 |
5 | export default test('map operator test suite', t => {
6 |
7 | t.test('basic', async t => {
8 | let i = 0;
9 | const to3 = counterGenerator();
10 | const mappedStream = map((x, index) => {
11 | t.equal(index, x, 'should have passed the index');
12 | return x * x;
13 | }, to3);
14 |
15 | for await (const item of mappedStream) {
16 | t.equal(item, i * i, `should see the square value of ${i} (${i * i})`);
17 | i++;
18 | }
19 |
20 | for await (const item of mappedStream) {
21 | i++;
22 | }
23 |
24 | t.equal(i, 3, 'should have seen 3 iterations only');
25 |
26 | });
27 |
28 | t.test('forward the consumable nature of the underlying asyncIterable', async t => {
29 | let i = 0;
30 | const to3 = counterIterable();
31 | const mappedStream = map((x, index) => {
32 | t.equal(index, x, 'should have passed the index');
33 | return x * x;
34 | }, to3);
35 |
36 | for await (const item of mappedStream) {
37 | t.equal(item, i * i, `should see the square value of ${i} (${i * i})`);
38 | i++;
39 | }
40 |
41 | for await (const item of mappedStream) {
42 | t.equal(item, (i - 3) * (i - 3), `should see the square value of ${i - 3} (${(i - 3) * (i - 3)})`);
43 | i++;
44 | }
45 |
46 | t.equal(i, 6, 'should have seen 6 iterations');
47 | });
48 |
49 | t.test('forward control flow event', async t => {
50 | let i = 0;
51 | const to3 = breakableCounter();
52 | const mappedStream = map(x => x * x, to3);
53 | for await (const item of mappedStream) {
54 | i++;
55 | break;
56 | }
57 |
58 | t.equal(i, 1, 'should have done a single iteration');
59 |
60 | t.equal(to3.done, true, 'should have called the return of underlying iterator');
61 | t.equal(to3.index, 1, 'should have pulled one single time');
62 |
63 | });
64 |
65 | t.test('curried map', async t => {
66 | const square = map(x => x * x);
67 | let i = 0;
68 | for await (const item of square(counterGenerator())) {
69 | t.equal(item, i * i, `should see the square value of ${i} (${i * i})`);
70 | i++;
71 | }
72 |
73 | i = 0;
74 | for await (const item of square(counterGenerator())) {
75 | t.equal(item, i * i, `should see the square value of ${i} (${i * i}) from an other iterable`);
76 | i++;
77 | }
78 | });
79 | });
80 |
--------------------------------------------------------------------------------
/test/filter.js:
--------------------------------------------------------------------------------
1 | import {test} from 'zora';
2 | import {filter} from '../src/lib/operators';
3 | import {breakableCounter, counterGenerator, counterIterable} from './util/source.js';
4 |
5 | export default test('filter operator test suite', t => {
6 |
7 | t.test('basic filter', async t => {
8 | let i = 0;
9 | const to3 = counterGenerator();
10 | const filterStream = filter((x, index) => {
11 | t.equal(index, x, 'should have passed the index');
12 | return x % 2 === 0;
13 | }, to3);
14 |
15 | let result = [];
16 |
17 | for await (const item of filterStream) {
18 | result.push(item);
19 | i++;
20 | }
21 |
22 | t.deepEqual(result, [0, 2], 'should have kept odd numbers');
23 |
24 | for await (const item of filterStream) {
25 | i++;
26 | }
27 |
28 | t.equal(i, 2, 'should have seen 3 iterations only');
29 | });
30 |
31 | t.test('filter: forward the consumable nature of the underlying asyncIterator', async t => {
32 | let i = 0;
33 | const to3 = counterIterable();
34 | const filterStream = filter((x, index) => {
35 | t.equal(index, x, 'should have passed the index');
36 | return x % 2 === 0;
37 | }, to3);
38 |
39 | let result = [];
40 |
41 | for await (const item of filterStream) {
42 | result.push(item);
43 | i++;
44 | }
45 |
46 | t.deepEqual(result, [0, 2], 'should have kept odd numbers');
47 |
48 | result = [];
49 |
50 | for await (const item of filterStream) {
51 | result.push(item);
52 | i++;
53 | }
54 |
55 | t.deepEqual(result, [0, 2], 'should have kept odd numbers again');
56 | t.equal(i, 4, 'should have seen 6 iterations');
57 |
58 | });
59 |
60 | t.test('should forward control flow event', async t => {
61 | let i = 0;
62 | const to3 = breakableCounter();
63 | const filteredStream = filter(x => x % 2 === 0, to3);
64 | for await (const item of filteredStream) {
65 | i++;
66 | break;
67 | }
68 |
69 | t.equal(i, 1, 'should have done a single iteration');
70 |
71 | t.equal(to3.done, true, 'should have called the return of underlying iterator');
72 | t.equal(to3.index, 1, 'should have pulled one single time');
73 |
74 | });
75 |
76 | t.test('curried filter', async t => {
77 | const odd = filter(x => x % 2 === 0);
78 | let i = 0;
79 | let result = [];
80 | for await (const item of odd(counterGenerator())) {
81 | result.push(item);
82 | i++;
83 | }
84 |
85 | t.deepEqual(result, [0, 2], 'should have kept odd numbers only');
86 |
87 | result = [];
88 |
89 | i = 0;
90 | for await (const item of odd(counterGenerator())) {
91 | result.push(item);
92 | i++;
93 | }
94 |
95 | t.deepEqual(result, [0, 2], 'should have kept odd numbers only');
96 | });
97 | });
98 |
--------------------------------------------------------------------------------
/test/find.js:
--------------------------------------------------------------------------------
1 | import {test} from 'zora';
2 | import {find, findIndex} from '../src/lib/operators';
3 | import {counterGenerator} from './util/source.js';
4 |
5 | export default test('find test suite', t => {
6 |
7 | t.test('find', async t => {
8 | let i = 0;
9 | const value = await find((item, index) => {
10 | t.equal(index, i, 'should have forwarded the index');
11 | i++;
12 | return item >= 3;
13 | }, counterGenerator(5));
14 |
15 | t.equal(value, 3, 'should have found 3');
16 | t.equal(i, 4, 'should have broken after four iterations');
17 | });
18 |
19 | t.test('find: no result', async t => {
20 | let i = 0;
21 | const value = await find((item, index) => {
22 | t.equal(index, i, 'should have forwarded the index');
23 | i++;
24 | return item >= 666;
25 | }, counterGenerator(5));
26 |
27 | t.equal(value, void 0, 'result value should be undefined');
28 | t.equal(i, 5, 'should have iterated over the whole stream');
29 | });
30 |
31 | t.test('find curried', async t => {
32 | let i = 0;
33 |
34 | const greaterOrEqualTo3 = find((item, index) => {
35 | t.equal(index, i, 'should have forwarded the index');
36 | i++;
37 | return item >= 3;
38 | });
39 |
40 | const value = await greaterOrEqualTo3(counterGenerator(5));
41 |
42 | t.equal(value, 3, 'should have found 3');
43 | t.equal(i, 4, 'should have broken after four iterations');
44 | });
45 |
46 | t.test('find curried with no result', async t => {
47 | let i = 0;
48 |
49 | const greaterOrEqualToEvil = find((item, index) => {
50 | t.equal(index, i, 'should have forwarded the index');
51 | i++;
52 | return item >= 666;
53 | });
54 |
55 | const value = await greaterOrEqualToEvil(counterGenerator(5));
56 |
57 | t.equal(value, void 0, 'retuned value should be undefined');
58 | t.equal(i, 5, 'should have iterated the whole stream');
59 | });
60 |
61 | t.test('find Index', async t => {
62 | let i = 0;
63 | const value = await findIndex((item, index) => {
64 | t.equal(index, i, 'should have forwarded the index');
65 | i++;
66 | return item >= 3;
67 | }, counterGenerator(5));
68 |
69 | t.equal(value, 3, 'should have return the index of value 3');
70 | t.equal(i, 4, 'should have broken after four iterations');
71 | });
72 |
73 | t.test('find Index: no result', async t => {
74 | let i = 0;
75 | const value = await findIndex((item, index) => {
76 | t.equal(index, i, 'should have forwarded the index');
77 | i++;
78 | return item >= 666;
79 | }, counterGenerator(5));
80 |
81 | t.equal(value, -1, 'result index should be -1');
82 | t.equal(i, 5, 'should have iterated over the whole stream');
83 | });
84 |
85 | t.test('find Index curried', async t => {
86 | let i = 0;
87 |
88 | const greaterOrEqualTo3 = findIndex((item, index) => {
89 | t.equal(index, i, 'should have forwarded the index');
90 | i++;
91 | return item >= 3;
92 | });
93 |
94 | const value = await greaterOrEqualTo3(counterGenerator(5));
95 |
96 | t.equal(value, 3, 'should have return the index of value 3');
97 | t.equal(i, 4, 'should have broken after four iterations');
98 | });
99 |
100 | t.test('find Index curried with no result', async t => {
101 | let i = 0;
102 |
103 | const greaterOrEqualToEvil = findIndex((item, index) => {
104 | t.equal(index, i, 'should have forwarded the index');
105 | i++;
106 | return item >= 666;
107 | });
108 |
109 | const value = await greaterOrEqualToEvil(counterGenerator(5));
110 |
111 | t.equal(value, -1, 'result index should be -1');
112 | t.equal(i, 5, 'should have iterated over the whole stream');
113 | });
114 | });
115 |
--------------------------------------------------------------------------------
/test/flatMap.js:
--------------------------------------------------------------------------------
1 | import {test} from 'zora';
2 | import {flatMap} from '../src/lib/operators';
3 | import {counterGenerator} from './util/source';
4 |
5 | export default test('flat map operator', t => {
6 | t.test('basic: should simply map if items are not asyncIterable', async t => {
7 | let index = 0;
8 | const gen = async function* () {
9 | yield 0;
10 | index++;
11 | yield 'foo';
12 | index++;
13 | yield ['bar'];
14 | index++;
15 | yield false;
16 | };
17 |
18 | const result = [];
19 | let iter = 0;
20 | const iterator = flatMap(x => x, gen());
21 |
22 | for await (const item of iterator) {
23 | iter++;
24 | result.push(item);
25 | }
26 |
27 | for await (const item of iterator) {
28 | iter++;
29 | }
30 |
31 | t.equal(iter, 4, 'should have seen 4 iterations only');
32 | t.deepEqual(result, [0, 'foo', ['bar'], false]);
33 | });
34 |
35 | t.test('basic: should flatten asyncIterator items', async t => {
36 | let index = 0;
37 | const gen = async function* () {
38 | yield 666;
39 | index++;
40 | yield counterGenerator();
41 | index++;
42 | yield ['bar'];
43 | index++;
44 | yield false;
45 | };
46 |
47 | const result = [];
48 | let iter = 0;
49 | for await (const item of flatMap(x => x, gen())) {
50 | iter++;
51 | result.push(item);
52 | }
53 | t.equal(index, 3, 'should have seen 3 index increments');
54 | t.equal(iter, 6, 'should have seen 6 iterations');
55 | t.deepEqual(result, [666, 0, 1, 2, ['bar'], false]);
56 | });
57 |
58 | t.test('should forward the consumable nature of the asyncIterable', async t => {
59 | let index = 0;
60 | const gen = async function* () {
61 | yield 666;
62 | index++;
63 | yield counterGenerator();
64 | index++;
65 | yield ['bar'];
66 | index++;
67 | yield false;
68 | };
69 |
70 | let result = [];
71 | let iter = 0;
72 | const iterator = flatMap(x => x, {
73 | [Symbol.asyncIterator]: gen
74 | });
75 |
76 | for await (const item of iterator) {
77 | iter++;
78 | result.push(item);
79 | }
80 |
81 | t.equal(iter, 6, 'should have seen 6 iterations');
82 | t.deepEqual(result, [666, 0, 1, 2, ['bar'], false]);
83 |
84 | iter = 0;
85 | result = [];
86 |
87 | for await (const item of iterator) {
88 | iter++;
89 | result.push(item);
90 | }
91 |
92 |
93 | t.equal(iter, 6, 'should have seen 6 iterations again');
94 | t.deepEqual(result, [666, 0, 1, 2, ['bar'], false]);
95 | });
96 |
97 | t.test('forward control flow event', async t => {
98 |
99 | let i = 0;
100 | let done = false;
101 |
102 | const iterator = {
103 | [Symbol.asyncIterator]() {
104 | return this;
105 | },
106 | async next() {
107 | if (done === true || i > 2) {
108 | return {done: true};
109 | }
110 |
111 | const value = {value: counterGenerator(), done: false};
112 | i++;
113 | return value;
114 | },
115 |
116 | async return() {
117 | done = true;
118 | return {done: true};
119 | }
120 | };
121 |
122 | let iter = 0;
123 | const result = [];
124 | for await (const item of flatMap(x => x, iterator)) {
125 | iter++;
126 | result.push(item);
127 | break;
128 | }
129 |
130 | t.equal(iter, 1, 'should have pulled one item of the main stream');
131 | t.deepEqual(result, [0], 'should have iterated only on the first item of the sub stream');
132 | t.equal(done, true, 'should have called the return hook of the source stream');
133 |
134 | });
135 | });
136 |
137 |
--------------------------------------------------------------------------------
/src/index.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | interface MapCallback {
4 | (item: T, index: number, iterable: AsyncIterable): U | Promise;
5 | }
6 |
7 | declare function map(callback: MapCallback): (iterable: AsyncIterable) => AsyncIterable;
8 | declare function map(callback: MapCallback, iterable: AsyncIterable): AsyncIterable;
9 |
10 | interface PredicateCallback {
11 | (item: T, index: number, iterable: AsyncIterable): boolean;
12 | }
13 |
14 | declare function filter(callback: PredicateCallback): (iterable: AsyncIterable) => AsyncIterable;
15 | declare function filter(callback: PredicateCallback, iterable: AsyncIterable): AsyncIterable;
16 |
17 | declare function take(number: number): (iterable: AsyncIterable) => AsyncIterable;
18 | declare function take(number: number, iterable: AsyncIterable): AsyncIterable;
19 |
20 | declare function skip(number: number): (iterable: AsyncIterable) => AsyncIterable;
21 | declare function skip(number: number, iterable: AsyncIterable): AsyncIterable;
22 |
23 | type ItemOrAsyncIterable = T | AsyncIterable;
24 |
25 | declare function flatMap(fn: MapCallback): (iterable: AsyncIterable>) => AsyncIterable;
26 | declare function flatMap(fn: MapCallback, iterable: AsyncIterable>): AsyncIterable;
27 |
28 | declare function slice(iterable: AsyncIterable): AsyncIterable;
29 | declare function slice(start: number, iterable: AsyncIterable): AsyncIterable;
30 | declare function slice(start: number, end: number, iterable: AsyncIterable): AsyncIterable;
31 | declare function slice(start?: number, end?: number): (iterable: AsyncIterable) => AsyncIterable;
32 |
33 | declare function concat(...args: ItemOrAsyncIterable[]): AsyncIterable;
34 |
35 | interface ReduceCallback {
36 | (accumulator: U, currentItem: T, index: number, iterable: AsyncIterable): Promise;
37 | }
38 |
39 | declare function reduce(fn: ReduceCallback, initialValue?: U): (iterable: AsyncIterable) => Promise;
40 | declare function reduce(fn: ReduceCallback, iterable: AsyncIterable): Promise;
41 | declare function reduce(fn: ReduceCallback, initialValue: U, iterable: AsyncIterable): Promise;
42 |
43 | interface TupleCallback {
44 | (item: T, index: number, iterable: AsyncIterable): boolean;
45 | }
46 |
47 | declare function find(fn: TupleCallback): (iterable: AsyncIterable) => Promise;
48 | declare function find(fn: TupleCallback, iterable: AsyncIterable): Promise;
49 |
50 | declare function findIndex(fn: TupleCallback): (iterable: AsyncIterable) => Promise;
51 | declare function findIndex(fn: TupleCallback, iterable: AsyncIterable): Promise;
52 |
53 | declare function includes(item: T, from ?: number): (iterable: AsyncIterable) => Promise;
54 | declare function includes(item: T, iterable: AsyncIterable): Promise;
55 | declare function includes(item: T, from: number, iterable: AsyncIterable): Promise;
56 |
57 | declare function every(fn: PredicateCallback, iterable: AsyncIterable): Promise;
58 | declare function every(fn: PredicateCallback): (iterable: AsyncIterable) => Promise;
59 |
60 | declare function some(fn: PredicateCallback, iterable: AsyncIterable): Promise;
61 | declare function some(fn: PredicateCallback): (iterable: AsyncIterable) => Promise;
62 |
63 | declare function from(iterable: Iterable): AsyncIterable;
64 |
65 | export interface Stream extends AsyncIterable {
66 | map(fn: MapCallback): Stream;
67 |
68 | filter(fn: PredicateCallback): Stream;
69 |
70 | flatMap(fn: MapCallback): Stream;
71 |
72 | slice(start?: number, end?: number): Stream;
73 |
74 | concat(...values: ItemOrAsyncIterable[]): Stream;
75 |
76 | reduce(fn: ReduceCallback, initialValue?: U): Promise;
77 |
78 | find(fn: TupleCallback): Promise;
79 |
80 | findIndex(fn: TupleCallback): Promise;
81 |
82 | includes(item: T, from?: number): Promise;
83 |
84 | every(fn: PredicateCallback): Promise;
85 |
86 | some(fn: PredicateCallback): Promise;
87 | }
88 |
89 | declare function stream(iterable: Iterable | AsyncIterable): Stream;
90 |
--------------------------------------------------------------------------------
/dist/declarations/index.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | interface MapCallback {
4 | (item: T, index: number, iterable: AsyncIterable): U | Promise;
5 | }
6 |
7 | declare function map(callback: MapCallback): (iterable: AsyncIterable) => AsyncIterable;
8 | declare function map(callback: MapCallback, iterable: AsyncIterable): AsyncIterable;
9 |
10 | interface PredicateCallback {
11 | (item: T, index: number, iterable: AsyncIterable): boolean;
12 | }
13 |
14 | declare function filter(callback: PredicateCallback): (iterable: AsyncIterable) => AsyncIterable;
15 | declare function filter(callback: PredicateCallback, iterable: AsyncIterable): AsyncIterable;
16 |
17 | declare function take(number: number): (iterable: AsyncIterable) => AsyncIterable;
18 | declare function take(number: number, iterable: AsyncIterable): AsyncIterable;
19 |
20 | declare function skip(number: number): (iterable: AsyncIterable) => AsyncIterable;
21 | declare function skip(number: number, iterable: AsyncIterable): AsyncIterable;
22 |
23 | type ItemOrAsyncIterable = T | AsyncIterable;
24 |
25 | declare function flatMap(fn: MapCallback): (iterable: AsyncIterable>) => AsyncIterable;
26 | declare function flatMap(fn: MapCallback, iterable: AsyncIterable>): AsyncIterable;
27 |
28 | declare function slice(iterable: AsyncIterable): AsyncIterable;
29 | declare function slice(start: number, iterable: AsyncIterable): AsyncIterable;
30 | declare function slice(start: number, end: number, iterable: AsyncIterable): AsyncIterable;
31 | declare function slice(start?: number, end?: number): (iterable: AsyncIterable) => AsyncIterable;
32 |
33 | declare function concat(...args: ItemOrAsyncIterable[]): AsyncIterable;
34 |
35 | interface ReduceCallback {
36 | (accumulator: U, currentItem: T, index: number, iterable: AsyncIterable): Promise;
37 | }
38 |
39 | declare function reduce(fn: ReduceCallback, initialValue?: U): (iterable: AsyncIterable) => Promise;
40 | declare function reduce(fn: ReduceCallback, iterable: AsyncIterable): Promise;
41 | declare function reduce(fn: ReduceCallback, initialValue: U, iterable: AsyncIterable): Promise;
42 |
43 | interface TupleCallback {
44 | (item: T, index: number, iterable: AsyncIterable): boolean;
45 | }
46 |
47 | declare function find(fn: TupleCallback): (iterable: AsyncIterable) => Promise;
48 | declare function find(fn: TupleCallback, iterable: AsyncIterable): Promise;
49 |
50 | declare function findIndex(fn: TupleCallback): (iterable: AsyncIterable) => Promise;
51 | declare function findIndex(fn: TupleCallback, iterable: AsyncIterable): Promise;
52 |
53 | declare function includes(item: T, from ?: number): (iterable: AsyncIterable) => Promise;
54 | declare function includes(item: T, iterable: AsyncIterable): Promise;
55 | declare function includes(item: T, from: number, iterable: AsyncIterable): Promise;
56 |
57 | declare function every(fn: PredicateCallback, iterable: AsyncIterable): Promise;
58 | declare function every(fn: PredicateCallback