From 3a57d17b832731f1e6781a00a9e030b243276473 Mon Sep 17 00:00:00 2001 From: Jesse Wright Date: Sat, 26 Mar 2022 13:28:47 +1100 Subject: [PATCH 1/6] feat: create fast transform iterator --- asynciterator.ts | 138 +++++++++++ composite-iterator copy.ts | 250 ++++++++++++++++++++ fasttransformiterator.ts | 139 +++++++++++ package-lock.json | 432 ++++++++++++++++++++++++++++++++++ package.json | 2 + test/FastTransformIterator.js | 157 ++++++++++++ 6 files changed, 1118 insertions(+) create mode 100644 composite-iterator copy.ts create mode 100644 fasttransformiterator.ts create mode 100644 test/FastTransformIterator.js diff --git a/asynciterator.ts b/asynciterator.ts index 3ec2ab6..efd6730 100644 --- a/asynciterator.ts +++ b/asynciterator.ts @@ -1923,3 +1923,141 @@ type SourceExpression = type InternalSource = AsyncIterator & { _destination: AsyncIterator }; + + interface Transform { filter: boolean, function: Function }[]; + +function build(transforms: Transform[]) { + return transforms.reduceRight((f, transform) => transform.filter ? + (item: any) => transform.function(item) ? f(item) : null : + (item: any) => f(transform.function(item)), (e: any) => e); +} + +export class FastTransformIterator extends AsyncIterator { + private transforms: { filter: boolean, function: Function }[] = []; + constructor(private source: AsyncIterator) { + super(); + source.on('readable', () => { + this.emit('readable'); + }); + source.on('end', () => { + this.close(); + }); + } + + read(): T | null { + const func = build(this.transforms); + + // const { source } = this + + this.read = () => { + let item; + while ((item = this.source.read()) !== null) { + if ((item = func(item)) !== null) + return item; + } + return null; + }; + + return this.read(); + } + + filter(filter: (item: T) => boolean): FastTransformIterator { + this.transforms.push({ filter: true, function: filter }); + + if (process.env.NODE_ENV === 'development') { + const that = Object.assign({}, this); + for (const key in this) { + if (typeof this[key] === 'function') { + // @ts-ignore + this[key] = () => { throw new Error('You are trying to use methods on an iterator - which has been destroyed by another transform operation'); }; + } + else { + delete this[key]; + } + } + return that as unknown as FastTransformIterator; + } + + return this as unknown as FastTransformIterator; + } + + map(map: (item: T) => D): AsyncIterator { + this.transforms.push({ filter: false, function: map }); + + console.log(process.env.NODE_ENV); + + if (process.env.NODE_ENV === 'development') { + const that = Object.assign({}, this); + for (const key in this) { + if (typeof this[key] === 'function') { + // @ts-ignore + this[key] = () => { throw new Error('You are trying to use methods on an iterator - which has been destroyed by another transform operation'); }; + } + else { + delete this[key]; + } + } + return that as unknown as AsyncIterator; + } + + return this as unknown as AsyncIterator; + } + + syncTransform(transform: (item: T) => Generator): FastTransformIterator { + const { source } = this; + + // Build the map-filter transformation pipeline between the current source and the use + // of this generator. + const func = build(this.transforms); + this.transforms = []; + + let transformation: Generator | null; + + // Override the current source with a new source that applies the generator mapping + // @ts-ignore + this.source = { + read(): D | null { + let item: any; + + while (true) { + // If we are not currently using a generator then get one + if (!transformation) { + // Get the first non-null upstream item + while ((item = source.read()) !== null) { + if ((item = func(item)) !== null) + break; + } + + // If we cannot get a non-null item from the + // source then return null + if (item === null) + return item; + + // Otherwise create a new generator + transformation = transform(item); + } + + if (!(item = transformation.next()).done) + return item.value; + transformation = null; + } + }, + } as unknown as AsyncIterator; + + if (process.env.NODE_ENV === 'development') { + const that = Object.assign({}, this); + for (const key in this) { + if (typeof this[key] === 'function') { + // @ts-ignore + this[key] = () => { throw new Error('You are trying to use methods on an iterator - which has been destroyed by another transform operation'); }; + } + else { + delete this[key]; + } + } + return that as unknown as FastTransformIterator; + } + + return this as unknown as FastTransformIterator; + } +} diff --git a/composite-iterator copy.ts b/composite-iterator copy.ts new file mode 100644 index 0000000..7e68f3f --- /dev/null +++ b/composite-iterator copy.ts @@ -0,0 +1,250 @@ +// import { AsyncIterator, TransformOptions } from './asynciterator'; + +// interface Transform { filter: boolean, function: Function }[]; + +// function build(transforms: Transform[]) { +// return transforms.reduceRight((f, transform) => { +// return transform.filter ? +// (item: any) => transform.function(item) ? f(item) : null : +// (item: any) => transform.function(f(item)) +// }, (e: any) => e) +// } + +// class CompositeMapFilterTransform extends AsyncIterator { +// private transforms: { filter: boolean, function: Function }[] = []; +// constructor(private source: AsyncIterator) { +// super(); +// source.on('readable', () => { +// this.emit('readable'); +// }); +// source.on('end', () => { +// this.close(); +// }); +// } +// read(): T | null { +// const func = build(this.transforms); + +// const { source } = this + +// this.read = () => { +// let item; +// while ((item = source.read()) !== null) { +// if ((item = func(item)) !== null) +// return item; +// } +// return item; +// } + +// return this.read(); +// } +// filter(filter: (item: T) => boolean): AsyncIterator { +// this.transforms.push({ filter: true, function: filter }); + +// if (process.env.NODE_ENV === 'development') { + +// const that = Object.assign({}, this); +// for (const key in this) { +// if (typeof this[key] === 'function') { +// // @ts-ignore +// this[key] = () => { throw new Error('You are trying to use methods on an iterator - which has been destroyed by another transform operation') }; +// } else { +// delete this[key]; +// } +// } +// return that as unknown as AsyncIterator; + +// } + +// return this as unknown as AsyncIterator; +// } +// map(map: (item: T) => D): AsyncIterator { +// this.transforms.push({ filter: false, function: map }); + +// if (process.env.NODE_ENV === 'development') { + +// const that = Object.assign({}, this); +// for (const key in this) { +// if (typeof this[key] === 'function') { +// // @ts-ignore +// this[key] = () => { throw new Error('You are trying to use methods on an iterator - which has been destroyed by another transform operation') }; +// } else { +// delete this[key]; +// } +// } +// return that as unknown as AsyncIterator; + +// } + +// return this as unknown as AsyncIterator; +// } +// syncTransform(transform: (item: T) => Generator): AsyncIterator { +// const { source } = this; + +// // Build the map-filter transformation pipeline between the current source and the use +// // of this generator. +// const func = build(this.transforms); +// this.transforms = []; + +// let transformation: Generator | null; + +// // Override the current source with a new source that applies the generator mapping +// // @ts-ignore +// this.source = { +// read(): D | null { +// let item: any; + +// while (true) { +// // If we are not currently using a generator then get one +// if (!transformation) { +// // Get the first non-null upstream item +// while ((item = source.read()) !== null) { +// if ((item = func(item)) !== null) +// break; +// } + +// // If we cannot get a non-null item from the +// // source then return null +// if (item === null) +// return item; + +// // Otherwise create a new generator +// transformation = transform(item); +// } + +// if (!(item = transformation.next()).done) +// return item.value; +// else +// transformation = null; +// } +// } +// } as unknown as AsyncIterator; + +// if (process.env.NODE_ENV === 'development') { + +// const that = Object.assign({}, this); +// for (const key in this) { +// if (typeof this[key] === 'function') { +// // @ts-ignore +// this[key] = () => { throw new Error('You are trying to use methods on an iterator - which has been destroyed by another transform operation') }; +// } else { +// delete this[key]; +// } +// } +// return that as unknown as AsyncIterator; + +// } + +// return this as unknown as AsyncIterator; +// } +// } + +// class CompositeMapFilter extends AsyncIterator { +// private transforms: { filter: boolean, function: Function }[] = []; +// constructor(private source: AsyncIterator) { +// super(); +// source.on('readable', () => { +// this.emit('readable'); +// }); +// source.on('end', () => { +// this.close(); +// }); +// } +// read(): T | null { +// const func = this.transforms.reduceRight((f, transform) => { +// return transform.filter ? +// (item: any) => transform.function(item) ? f(item) : null : +// (item: any) => transform.function(f(item)) +// }, (e: any) => e) + +// const { source } = this + +// this.read = () => { +// let item; +// while ((item = source.read()) !== null) { +// if ((item = func(item)) !== null) +// return item; +// } +// return item; +// } + +// return this.read(); +// } +// filter(filter: (item: T) => boolean): AsyncIterator { +// this.transforms.push({ filter: true, function: filter }); + +// if (process.env.NODE_ENV === 'development') { + +// const that = Object.assign({}, this); +// for (const key in this) { +// if (typeof this[key] === 'function') { +// // @ts-ignore +// this[key] = () => { throw new Error('You are trying to use methods on an iterator - which has been destroyed by another transform operation') }; +// } else { +// delete this[key]; +// } +// } +// return that as unknown as AsyncIterator; + +// } + +// return this as unknown as AsyncIterator; +// } +// map(map: (item: T) => D): AsyncIterator { +// this.transforms.push({ filter: false, function: map }); + +// if (process.env.NODE_ENV === 'development') { + +// const that = Object.assign({}, this); +// for (const key in this) { +// if (typeof this[key] === 'function') { +// // @ts-ignore +// this[key] = () => { throw new Error('You are trying to use methods on an iterator - which has been destroyed by another transform operation') }; +// } else { +// delete this[key]; +// } +// } +// return that as unknown as AsyncIterator; + +// } + +// return this as unknown as AsyncIterator; +// } +// syncTransform(transform: (item: T) => Generator): AsyncIterator { +// return new SyncTransformer(this, transform); +// } +// } + +// class SyncTransformer extends AsyncIterator { +// constructor(source: AsyncIterator, transform: (item: T) => Generator) { +// super(); +// let transformation: Generator | null; +// source.on('readable', () => { +// this.emit('readable'); +// }); +// source.on('end', () => { +// this.close(); +// }); +// this.read = () => { +// let item: any; + +// while (true) { +// if (!transformation) { +// if ((item = source.read()) === null) +// return item; +// transformation = transform(item); +// } + +// if (!(item = transformation.next()).done) +// return item.value; +// else +// transformation = null; +// } +// } +// } +// map(map: (item: D) => K): AsyncIterator { +// return new CompositeMapFilter(this).map(map); +// } +// filter(filter: (item: T) => boolean): AsyncIterator { +// return new CompositeMapFilter(this).filter(filter); +// } +// } diff --git a/fasttransformiterator.ts b/fasttransformiterator.ts new file mode 100644 index 0000000..f2ff9fc --- /dev/null +++ b/fasttransformiterator.ts @@ -0,0 +1,139 @@ +// import { AsyncIterator } from './asynciterator'; + +// interface Transform { filter: boolean, function: Function }[]; + +// function build(transforms: Transform[]) { +// return transforms.reduceRight((f, transform) => { +// return transform.filter ? +// (item: any) => transform.function(item) ? f(item) : null : +// (item: any) => transform.function(f(item)) +// }, (e: any) => e) +// } + +// export class FastTransformIterator extends AsyncIterator { +// private transforms: { filter: boolean, function: Function }[] = []; +// constructor(private source: AsyncIterator) { +// super(); +// source.on('readable', () => { +// this.emit('readable'); +// }); +// source.on('end', () => { +// this.close(); +// }); +// } +// read(): T | null { +// const func = build(this.transforms); + +// const { source } = this + +// this.read = () => { +// let item; +// while ((item = source.read()) !== null) { +// if ((item = func(item)) !== null) +// return item; +// } +// return item; +// } + +// return this.read(); +// } +// filter(filter: (item: T) => boolean): AsyncIterator { +// this.transforms.push({ filter: true, function: filter }); + +// if (process.env.NODE_ENV === 'development') { + +// const that = Object.assign({}, this); +// for (const key in this) { +// if (typeof this[key] === 'function') { +// // @ts-ignore +// this[key] = () => { throw new Error('You are trying to use methods on an iterator - which has been destroyed by another transform operation') }; +// } else { +// delete this[key]; +// } +// } +// return that as unknown as AsyncIterator; + +// } + +// return this as unknown as AsyncIterator; +// } +// map(map: (item: T) => D): AsyncIterator { +// this.transforms.push({ filter: false, function: map }); + +// if (process.env.NODE_ENV === 'development') { + +// const that = Object.assign({}, this); +// for (const key in this) { +// if (typeof this[key] === 'function') { +// // @ts-ignore +// this[key] = () => { throw new Error('You are trying to use methods on an iterator - which has been destroyed by another transform operation') }; +// } else { +// delete this[key]; +// } +// } +// return that as unknown as AsyncIterator; + +// } + +// return this as unknown as AsyncIterator; +// } +// syncTransform(transform: (item: T) => Generator): AsyncIterator { +// const { source } = this; + +// // Build the map-filter transformation pipeline between the current source and the use +// // of this generator. +// const func = build(this.transforms); +// this.transforms = []; + +// let transformation: Generator | null; + +// // Override the current source with a new source that applies the generator mapping +// // @ts-ignore +// this.source = { +// read(): D | null { +// let item: any; + +// while (true) { +// // If we are not currently using a generator then get one +// if (!transformation) { +// // Get the first non-null upstream item +// while ((item = source.read()) !== null) { +// if ((item = func(item)) !== null) +// break; +// } + +// // If we cannot get a non-null item from the +// // source then return null +// if (item === null) +// return item; + +// // Otherwise create a new generator +// transformation = transform(item); +// } + +// if (!(item = transformation.next()).done) +// return item.value; +// else +// transformation = null; +// } +// } +// } as unknown as AsyncIterator; + +// if (process.env.NODE_ENV === 'development') { + +// const that = Object.assign({}, this); +// for (const key in this) { +// if (typeof this[key] === 'function') { +// // @ts-ignore +// this[key] = () => { throw new Error('You are trying to use methods on an iterator - which has been destroyed by another transform operation') }; +// } else { +// delete this[key]; +// } +// } +// return that as unknown as AsyncIterator; + +// } + +// return this as unknown as AsyncIterator; +// } +// } diff --git a/package-lock.json b/package-lock.json index 831df0f..2680f99 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,8 @@ "@babel/core": "^7.10.2", "@babel/plugin-transform-modules-commonjs": "^7.10.1", "@babel/register": "^7.10.1", + "@types/jest": "^27.4.1", + "@types/mocha": "^9.1.0", "@types/node": "^14.0.13", "@typescript-eslint/eslint-plugin": "^3.2.0", "@typescript-eslint/parser": "^3.2.0", @@ -506,12 +508,28 @@ "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", "dev": true }, + "node_modules/@types/jest": { + "version": "27.4.1", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", + "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", + "dev": true, + "dependencies": { + "jest-matcher-utils": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, "node_modules/@types/json-schema": { "version": "7.0.8", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz", "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==", "dev": true }, + "node_modules/@types/mocha": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.0.tgz", + "integrity": "sha512-QCWHkbMv4Y5U9oW10Uxbr45qMMSzl4OzijsozynUAgx3kEHUdXB00udx2dWDQ7f2TU2a2uuiFaRZjCe3unPpeg==", + "dev": true + }, "node_modules/@types/node": { "version": "14.17.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.5.tgz", @@ -1728,6 +1746,15 @@ "node": ">=0.3.1" } }, + "node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -3158,6 +3185,185 @@ "underscore": "^1.7.0" } }, + "node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-diff/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-diff/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-matcher-utils/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-matcher-utils/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -4584,6 +4790,41 @@ "node": ">= 0.8.0" } }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -4618,6 +4859,12 @@ "safe-buffer": "^5.1.0" } }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", @@ -6477,12 +6724,28 @@ "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", "dev": true }, + "@types/jest": { + "version": "27.4.1", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", + "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", + "dev": true, + "requires": { + "jest-matcher-utils": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, "@types/json-schema": { "version": "7.0.8", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz", "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==", "dev": true }, + "@types/mocha": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.0.tgz", + "integrity": "sha512-QCWHkbMv4Y5U9oW10Uxbr45qMMSzl4OzijsozynUAgx3kEHUdXB00udx2dWDQ7f2TU2a2uuiFaRZjCe3unPpeg==", + "dev": true + }, "@types/node": { "version": "14.17.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.5.tgz", @@ -7409,6 +7672,12 @@ "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, + "diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "dev": true + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -8517,6 +8786,138 @@ "underscore": "^1.7.0" } }, + "jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "dev": true + }, + "jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -9610,6 +10011,31 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, + "pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + } + } + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -9638,6 +10064,12 @@ "safe-buffer": "^5.1.0" } }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", diff --git a/package.json b/package.json index 06ab110..e5fba79 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,8 @@ "@babel/core": "^7.10.2", "@babel/plugin-transform-modules-commonjs": "^7.10.1", "@babel/register": "^7.10.1", + "@types/jest": "^27.4.1", + "@types/mocha": "^9.1.0", "@types/node": "^14.0.13", "@typescript-eslint/eslint-plugin": "^3.2.0", "@typescript-eslint/parser": "^3.2.0", diff --git a/test/FastTransformIterator.js b/test/FastTransformIterator.js new file mode 100644 index 0000000..7732157 --- /dev/null +++ b/test/FastTransformIterator.js @@ -0,0 +1,157 @@ +import { + FastTransformIterator, + range, +} from '../dist/asynciterator.js'; + +describe('FastTransformIterator (development mode)', () => { + let iterator; + beforeEach(() => { + process.env.NODE_ENV === 'development'; + iterator = new FastTransformIterator(range(0, 2)); + }); + it('Should handle no transforms', async () => { + iterator.read().should.equal(0); + iterator.read().should.equal(1); + iterator.read().should.equal(2); + }); + it('Should handle no transforms arrayified', async () => { + (await iterator.toArray()).should.deep.equal([0, 1, 2]); + }); + it('Should apply maps that doubles correctly', async () => { + (await iterator.map(x => x * 2).toArray()).should.deep.equal([0, 2, 4]); + }); + it('Should apply maps that doubles correctly', async () => { + (await iterator.map(x => `x${x}`).toArray()).should.deep.equal(['x0', 'x1', 'x2']); + }); + it('Should apply filter correctly', async () => { + (await iterator.filter(x => x % 2 === 0).toArray()).should.deep.equal([0, 2]); + }); + it('Should apply filter then map correctly', async () => { + (await iterator.filter(x => x % 2 === 0).map(x => `x${x}`).toArray()).should.deep.equal(['x0', 'x2']); + }); + it('Should apply map then filter correctly (1)', async () => { + (await iterator.map(x => x).filter(x => x % 2 === 0).toArray()).should.deep.equal([0, 2]); + }); + it('Should apply map then filter to false correctly', async () => { + (await iterator.map(x => `x${x}`).filter(x => true).toArray()).should.deep.equal(['x0', 'x1', 'x2']); + }); + it('Should apply map then filter to true correctly', async () => { + (await iterator.map(x => `x${x}`).filter(x => false).toArray()).should.deep.equal([]); + }); + it('Should apply filter to false then map correctly', async () => { + (await iterator.filter(x => true).map(x => `x${x}`).toArray()).should.deep.equal(['x0', 'x1', 'x2']); + }); + it('Should apply filter to true then map correctly', async () => { + (await iterator.filter(x => false).map(x => `x${x}`).filter(x => false).toArray()).should.deep.equal([]); + }); + it('Should apply filter one then double', async () => { + (await iterator.filter(x => x !== 1).map(x => x * 2).toArray()).should.deep.equal([0, 4]); + }); + it('Should apply double then filter one', async () => { + (await iterator.map(x => x * 2).filter(x => x !== 1).toArray()).should.deep.equal([0, 2, 4]); + }); + it('Should apply map then filter correctly', async () => { + (await iterator.map(x => `x${x}`).filter(x => (x[1] === '0')).toArray()).should.deep.equal(['x0']); + }); + it('Should handle transforms', async () => { + iterator = iterator.syncTransform(function* (data) { + yield `x${data}`; + yield `y${data}`; + }); + (await iterator.toArray()).should.deep.equal(['x0', 'y0', 'x1', 'y1', 'x2', 'y2']); + }); + it('Should handle transforms and maps', async () => { + iterator = iterator.syncTransform(function* (data) { + yield `x${data}`; + yield `y${data}`; + }).map(x => `z${x}`); + (await iterator.toArray()).should.deep.equal(['zx0', 'zy0', 'zx1', 'zy1', 'zx2', 'zy2']); + }); + it('Should handle maps and transforms', async () => { + iterator = iterator.map(x => `z${x}`).syncTransform(function* (data) { + yield `x${data}`; + yield `y${data}`; + }); + (await iterator.toArray()).should.deep.equal(['xz0', 'yz0', 'xz1', 'yz1', 'xz2', 'yz2']); + }); + + it('Should throw errors when misusing the iterator', () => { + iterator.map(x => x); + expect(() => { iterator.map(x => x); }).to.throw(Error); + }); +}); + + +describe('FastTransformIterator (production mode)', () => { + let iterator; + beforeEach(() => { + process.env.NODE_ENV === 'production'; + iterator = new FastTransformIterator(range(0, 2)); + }); + it('Should handle no transforms', async () => { + iterator.read().should.equal(0); + iterator.read().should.equal(1); + iterator.read().should.equal(2); + }); + it('Should handle no transforms arrayified', async () => { + (await iterator.toArray()).should.deep.equal([0, 1, 2]); + }); + it('Should apply maps that doubles correctly', async () => { + (await iterator.map(x => x * 2).toArray()).should.deep.equal([0, 2, 4]); + }); + it('Should apply maps that doubles correctly', async () => { + (await iterator.map(x => `x${x}`).toArray()).should.deep.equal(['x0', 'x1', 'x2']); + }); + it('Should apply filter correctly', async () => { + (await iterator.filter(x => x % 2 === 0).toArray()).should.deep.equal([0, 2]); + }); + it('Should apply filter then map correctly', async () => { + (await iterator.filter(x => x % 2 === 0).map(x => `x${x}`).toArray()).should.deep.equal(['x0', 'x2']); + }); + it('Should apply map then filter correctly (1)', async () => { + (await iterator.map(x => x).filter(x => x % 2 === 0).toArray()).should.deep.equal([0, 2]); + }); + it('Should apply map then filter to false correctly', async () => { + (await iterator.map(x => `x${x}`).filter(x => true).toArray()).should.deep.equal(['x0', 'x1', 'x2']); + }); + it('Should apply map then filter to true correctly', async () => { + (await iterator.map(x => `x${x}`).filter(x => false).toArray()).should.deep.equal([]); + }); + it('Should apply filter to false then map correctly', async () => { + (await iterator.filter(x => true).map(x => `x${x}`).toArray()).should.deep.equal(['x0', 'x1', 'x2']); + }); + it('Should apply filter to true then map correctly', async () => { + (await iterator.filter(x => false).map(x => `x${x}`).filter(x => false).toArray()).should.deep.equal([]); + }); + it('Should apply filter one then double', async () => { + (await iterator.filter(x => x !== 1).map(x => x * 2).toArray()).should.deep.equal([0, 4]); + }); + it('Should apply double then filter one', async () => { + (await iterator.map(x => x * 2).filter(x => x !== 1).toArray()).should.deep.equal([0, 2, 4]); + }); + it('Should apply map then filter correctly', async () => { + (await iterator.map(x => `x${x}`).filter(x => (x[1] === '0')).toArray()).should.deep.equal(['x0']); + }); + it('Should handle transforms', async () => { + iterator = iterator.syncTransform(function* (data) { + yield `x${data}`; + yield `y${data}`; + }); + (await iterator.toArray()).should.deep.equal(['x0', 'y0', 'x1', 'y1', 'x2', 'y2']); + }); + it('Should handle transforms and maps', async () => { + iterator = iterator.syncTransform(function* (data) { + yield `x${data}`; + yield `y${data}`; + }).map(x => `z${x}`); + (await iterator.toArray()).should.deep.equal(['zx0', 'zy0', 'zx1', 'zy1', 'zx2', 'zy2']); + }); + it('Should handle maps and transforms', async () => { + iterator = iterator.map(x => `z${x}`).syncTransform(function* (data) { + yield `x${data}`; + yield `y${data}`; + }); + (await iterator.toArray()).should.deep.equal(['xz0', 'yz0', 'xz1', 'yz1', 'xz2', 'yz2']); + }); +}); + From 2a1954f161acc1155330c8eee82a479a6a6ac9d5 Mon Sep 17 00:00:00 2001 From: Jesse Wright Date: Sat, 26 Mar 2022 13:41:12 +1100 Subject: [PATCH 2/6] chore: remove production mode stuff --- asynciterator.ts | 60 +------- composite-iterator copy.ts | 250 ---------------------------------- fasttransformiterator.ts | 139 ------------------- test/FastTransformIterator.js | 83 +---------- 4 files changed, 8 insertions(+), 524 deletions(-) delete mode 100644 composite-iterator copy.ts delete mode 100644 fasttransformiterator.ts diff --git a/asynciterator.ts b/asynciterator.ts index efd6730..89f47f8 100644 --- a/asynciterator.ts +++ b/asynciterator.ts @@ -1924,7 +1924,7 @@ type SourceExpression = type InternalSource = AsyncIterator & { _destination: AsyncIterator }; - interface Transform { filter: boolean, function: Function }[]; +interface Transform { filter: boolean, function: Function } function build(transforms: Transform[]) { return transforms.reduceRight((f, transform) => transform.filter ? @@ -1933,7 +1933,7 @@ function build(transforms: Transform[]) { } export class FastTransformIterator extends AsyncIterator { - private transforms: { filter: boolean, function: Function }[] = []; + private transforms: Transform[] = []; constructor(private source: AsyncIterator) { super(); source.on('readable', () => { @@ -1947,11 +1947,10 @@ export class FastTransformIterator extends AsyncIterator { read(): T | null { const func = build(this.transforms); - // const { source } = this - this.read = () => { + const { source } = this; let item; - while ((item = this.source.read()) !== null) { + while ((item = source.read()) !== null) { if ((item = func(item)) !== null) return item; } @@ -1963,44 +1962,12 @@ export class FastTransformIterator extends AsyncIterator { filter(filter: (item: T) => boolean): FastTransformIterator { this.transforms.push({ filter: true, function: filter }); - - if (process.env.NODE_ENV === 'development') { - const that = Object.assign({}, this); - for (const key in this) { - if (typeof this[key] === 'function') { - // @ts-ignore - this[key] = () => { throw new Error('You are trying to use methods on an iterator - which has been destroyed by another transform operation'); }; - } - else { - delete this[key]; - } - } - return that as unknown as FastTransformIterator; - } - return this as unknown as FastTransformIterator; } - map(map: (item: T) => D): AsyncIterator { + map(map: (item: T) => D): FastTransformIterator { this.transforms.push({ filter: false, function: map }); - - console.log(process.env.NODE_ENV); - - if (process.env.NODE_ENV === 'development') { - const that = Object.assign({}, this); - for (const key in this) { - if (typeof this[key] === 'function') { - // @ts-ignore - this[key] = () => { throw new Error('You are trying to use methods on an iterator - which has been destroyed by another transform operation'); }; - } - else { - delete this[key]; - } - } - return that as unknown as AsyncIterator; - } - - return this as unknown as AsyncIterator; + return this as unknown as FastTransformIterator; } syncTransform(transform: (item: T) => Generator): FastTransformIterator { @@ -2019,6 +1986,7 @@ export class FastTransformIterator extends AsyncIterator { read(): D | null { let item: any; + // eslint-disable-next-line no-constant-condition while (true) { // If we are not currently using a generator then get one if (!transformation) { @@ -2044,20 +2012,6 @@ export class FastTransformIterator extends AsyncIterator { }, } as unknown as AsyncIterator; - if (process.env.NODE_ENV === 'development') { - const that = Object.assign({}, this); - for (const key in this) { - if (typeof this[key] === 'function') { - // @ts-ignore - this[key] = () => { throw new Error('You are trying to use methods on an iterator - which has been destroyed by another transform operation'); }; - } - else { - delete this[key]; - } - } - return that as unknown as FastTransformIterator; - } - return this as unknown as FastTransformIterator; } } diff --git a/composite-iterator copy.ts b/composite-iterator copy.ts deleted file mode 100644 index 7e68f3f..0000000 --- a/composite-iterator copy.ts +++ /dev/null @@ -1,250 +0,0 @@ -// import { AsyncIterator, TransformOptions } from './asynciterator'; - -// interface Transform { filter: boolean, function: Function }[]; - -// function build(transforms: Transform[]) { -// return transforms.reduceRight((f, transform) => { -// return transform.filter ? -// (item: any) => transform.function(item) ? f(item) : null : -// (item: any) => transform.function(f(item)) -// }, (e: any) => e) -// } - -// class CompositeMapFilterTransform extends AsyncIterator { -// private transforms: { filter: boolean, function: Function }[] = []; -// constructor(private source: AsyncIterator) { -// super(); -// source.on('readable', () => { -// this.emit('readable'); -// }); -// source.on('end', () => { -// this.close(); -// }); -// } -// read(): T | null { -// const func = build(this.transforms); - -// const { source } = this - -// this.read = () => { -// let item; -// while ((item = source.read()) !== null) { -// if ((item = func(item)) !== null) -// return item; -// } -// return item; -// } - -// return this.read(); -// } -// filter(filter: (item: T) => boolean): AsyncIterator { -// this.transforms.push({ filter: true, function: filter }); - -// if (process.env.NODE_ENV === 'development') { - -// const that = Object.assign({}, this); -// for (const key in this) { -// if (typeof this[key] === 'function') { -// // @ts-ignore -// this[key] = () => { throw new Error('You are trying to use methods on an iterator - which has been destroyed by another transform operation') }; -// } else { -// delete this[key]; -// } -// } -// return that as unknown as AsyncIterator; - -// } - -// return this as unknown as AsyncIterator; -// } -// map(map: (item: T) => D): AsyncIterator { -// this.transforms.push({ filter: false, function: map }); - -// if (process.env.NODE_ENV === 'development') { - -// const that = Object.assign({}, this); -// for (const key in this) { -// if (typeof this[key] === 'function') { -// // @ts-ignore -// this[key] = () => { throw new Error('You are trying to use methods on an iterator - which has been destroyed by another transform operation') }; -// } else { -// delete this[key]; -// } -// } -// return that as unknown as AsyncIterator; - -// } - -// return this as unknown as AsyncIterator; -// } -// syncTransform(transform: (item: T) => Generator): AsyncIterator { -// const { source } = this; - -// // Build the map-filter transformation pipeline between the current source and the use -// // of this generator. -// const func = build(this.transforms); -// this.transforms = []; - -// let transformation: Generator | null; - -// // Override the current source with a new source that applies the generator mapping -// // @ts-ignore -// this.source = { -// read(): D | null { -// let item: any; - -// while (true) { -// // If we are not currently using a generator then get one -// if (!transformation) { -// // Get the first non-null upstream item -// while ((item = source.read()) !== null) { -// if ((item = func(item)) !== null) -// break; -// } - -// // If we cannot get a non-null item from the -// // source then return null -// if (item === null) -// return item; - -// // Otherwise create a new generator -// transformation = transform(item); -// } - -// if (!(item = transformation.next()).done) -// return item.value; -// else -// transformation = null; -// } -// } -// } as unknown as AsyncIterator; - -// if (process.env.NODE_ENV === 'development') { - -// const that = Object.assign({}, this); -// for (const key in this) { -// if (typeof this[key] === 'function') { -// // @ts-ignore -// this[key] = () => { throw new Error('You are trying to use methods on an iterator - which has been destroyed by another transform operation') }; -// } else { -// delete this[key]; -// } -// } -// return that as unknown as AsyncIterator; - -// } - -// return this as unknown as AsyncIterator; -// } -// } - -// class CompositeMapFilter extends AsyncIterator { -// private transforms: { filter: boolean, function: Function }[] = []; -// constructor(private source: AsyncIterator) { -// super(); -// source.on('readable', () => { -// this.emit('readable'); -// }); -// source.on('end', () => { -// this.close(); -// }); -// } -// read(): T | null { -// const func = this.transforms.reduceRight((f, transform) => { -// return transform.filter ? -// (item: any) => transform.function(item) ? f(item) : null : -// (item: any) => transform.function(f(item)) -// }, (e: any) => e) - -// const { source } = this - -// this.read = () => { -// let item; -// while ((item = source.read()) !== null) { -// if ((item = func(item)) !== null) -// return item; -// } -// return item; -// } - -// return this.read(); -// } -// filter(filter: (item: T) => boolean): AsyncIterator { -// this.transforms.push({ filter: true, function: filter }); - -// if (process.env.NODE_ENV === 'development') { - -// const that = Object.assign({}, this); -// for (const key in this) { -// if (typeof this[key] === 'function') { -// // @ts-ignore -// this[key] = () => { throw new Error('You are trying to use methods on an iterator - which has been destroyed by another transform operation') }; -// } else { -// delete this[key]; -// } -// } -// return that as unknown as AsyncIterator; - -// } - -// return this as unknown as AsyncIterator; -// } -// map(map: (item: T) => D): AsyncIterator { -// this.transforms.push({ filter: false, function: map }); - -// if (process.env.NODE_ENV === 'development') { - -// const that = Object.assign({}, this); -// for (const key in this) { -// if (typeof this[key] === 'function') { -// // @ts-ignore -// this[key] = () => { throw new Error('You are trying to use methods on an iterator - which has been destroyed by another transform operation') }; -// } else { -// delete this[key]; -// } -// } -// return that as unknown as AsyncIterator; - -// } - -// return this as unknown as AsyncIterator; -// } -// syncTransform(transform: (item: T) => Generator): AsyncIterator { -// return new SyncTransformer(this, transform); -// } -// } - -// class SyncTransformer extends AsyncIterator { -// constructor(source: AsyncIterator, transform: (item: T) => Generator) { -// super(); -// let transformation: Generator | null; -// source.on('readable', () => { -// this.emit('readable'); -// }); -// source.on('end', () => { -// this.close(); -// }); -// this.read = () => { -// let item: any; - -// while (true) { -// if (!transformation) { -// if ((item = source.read()) === null) -// return item; -// transformation = transform(item); -// } - -// if (!(item = transformation.next()).done) -// return item.value; -// else -// transformation = null; -// } -// } -// } -// map(map: (item: D) => K): AsyncIterator { -// return new CompositeMapFilter(this).map(map); -// } -// filter(filter: (item: T) => boolean): AsyncIterator { -// return new CompositeMapFilter(this).filter(filter); -// } -// } diff --git a/fasttransformiterator.ts b/fasttransformiterator.ts deleted file mode 100644 index f2ff9fc..0000000 --- a/fasttransformiterator.ts +++ /dev/null @@ -1,139 +0,0 @@ -// import { AsyncIterator } from './asynciterator'; - -// interface Transform { filter: boolean, function: Function }[]; - -// function build(transforms: Transform[]) { -// return transforms.reduceRight((f, transform) => { -// return transform.filter ? -// (item: any) => transform.function(item) ? f(item) : null : -// (item: any) => transform.function(f(item)) -// }, (e: any) => e) -// } - -// export class FastTransformIterator extends AsyncIterator { -// private transforms: { filter: boolean, function: Function }[] = []; -// constructor(private source: AsyncIterator) { -// super(); -// source.on('readable', () => { -// this.emit('readable'); -// }); -// source.on('end', () => { -// this.close(); -// }); -// } -// read(): T | null { -// const func = build(this.transforms); - -// const { source } = this - -// this.read = () => { -// let item; -// while ((item = source.read()) !== null) { -// if ((item = func(item)) !== null) -// return item; -// } -// return item; -// } - -// return this.read(); -// } -// filter(filter: (item: T) => boolean): AsyncIterator { -// this.transforms.push({ filter: true, function: filter }); - -// if (process.env.NODE_ENV === 'development') { - -// const that = Object.assign({}, this); -// for (const key in this) { -// if (typeof this[key] === 'function') { -// // @ts-ignore -// this[key] = () => { throw new Error('You are trying to use methods on an iterator - which has been destroyed by another transform operation') }; -// } else { -// delete this[key]; -// } -// } -// return that as unknown as AsyncIterator; - -// } - -// return this as unknown as AsyncIterator; -// } -// map(map: (item: T) => D): AsyncIterator { -// this.transforms.push({ filter: false, function: map }); - -// if (process.env.NODE_ENV === 'development') { - -// const that = Object.assign({}, this); -// for (const key in this) { -// if (typeof this[key] === 'function') { -// // @ts-ignore -// this[key] = () => { throw new Error('You are trying to use methods on an iterator - which has been destroyed by another transform operation') }; -// } else { -// delete this[key]; -// } -// } -// return that as unknown as AsyncIterator; - -// } - -// return this as unknown as AsyncIterator; -// } -// syncTransform(transform: (item: T) => Generator): AsyncIterator { -// const { source } = this; - -// // Build the map-filter transformation pipeline between the current source and the use -// // of this generator. -// const func = build(this.transforms); -// this.transforms = []; - -// let transformation: Generator | null; - -// // Override the current source with a new source that applies the generator mapping -// // @ts-ignore -// this.source = { -// read(): D | null { -// let item: any; - -// while (true) { -// // If we are not currently using a generator then get one -// if (!transformation) { -// // Get the first non-null upstream item -// while ((item = source.read()) !== null) { -// if ((item = func(item)) !== null) -// break; -// } - -// // If we cannot get a non-null item from the -// // source then return null -// if (item === null) -// return item; - -// // Otherwise create a new generator -// transformation = transform(item); -// } - -// if (!(item = transformation.next()).done) -// return item.value; -// else -// transformation = null; -// } -// } -// } as unknown as AsyncIterator; - -// if (process.env.NODE_ENV === 'development') { - -// const that = Object.assign({}, this); -// for (const key in this) { -// if (typeof this[key] === 'function') { -// // @ts-ignore -// this[key] = () => { throw new Error('You are trying to use methods on an iterator - which has been destroyed by another transform operation') }; -// } else { -// delete this[key]; -// } -// } -// return that as unknown as AsyncIterator; - -// } - -// return this as unknown as AsyncIterator; -// } -// } diff --git a/test/FastTransformIterator.js b/test/FastTransformIterator.js index 7732157..33a9d8d 100644 --- a/test/FastTransformIterator.js +++ b/test/FastTransformIterator.js @@ -3,10 +3,9 @@ import { range, } from '../dist/asynciterator.js'; -describe('FastTransformIterator (development mode)', () => { +describe('FastTransformIterator', () => { let iterator; beforeEach(() => { - process.env.NODE_ENV === 'development'; iterator = new FastTransformIterator(range(0, 2)); }); it('Should handle no transforms', async () => { @@ -74,84 +73,4 @@ describe('FastTransformIterator (development mode)', () => { }); (await iterator.toArray()).should.deep.equal(['xz0', 'yz0', 'xz1', 'yz1', 'xz2', 'yz2']); }); - - it('Should throw errors when misusing the iterator', () => { - iterator.map(x => x); - expect(() => { iterator.map(x => x); }).to.throw(Error); - }); }); - - -describe('FastTransformIterator (production mode)', () => { - let iterator; - beforeEach(() => { - process.env.NODE_ENV === 'production'; - iterator = new FastTransformIterator(range(0, 2)); - }); - it('Should handle no transforms', async () => { - iterator.read().should.equal(0); - iterator.read().should.equal(1); - iterator.read().should.equal(2); - }); - it('Should handle no transforms arrayified', async () => { - (await iterator.toArray()).should.deep.equal([0, 1, 2]); - }); - it('Should apply maps that doubles correctly', async () => { - (await iterator.map(x => x * 2).toArray()).should.deep.equal([0, 2, 4]); - }); - it('Should apply maps that doubles correctly', async () => { - (await iterator.map(x => `x${x}`).toArray()).should.deep.equal(['x0', 'x1', 'x2']); - }); - it('Should apply filter correctly', async () => { - (await iterator.filter(x => x % 2 === 0).toArray()).should.deep.equal([0, 2]); - }); - it('Should apply filter then map correctly', async () => { - (await iterator.filter(x => x % 2 === 0).map(x => `x${x}`).toArray()).should.deep.equal(['x0', 'x2']); - }); - it('Should apply map then filter correctly (1)', async () => { - (await iterator.map(x => x).filter(x => x % 2 === 0).toArray()).should.deep.equal([0, 2]); - }); - it('Should apply map then filter to false correctly', async () => { - (await iterator.map(x => `x${x}`).filter(x => true).toArray()).should.deep.equal(['x0', 'x1', 'x2']); - }); - it('Should apply map then filter to true correctly', async () => { - (await iterator.map(x => `x${x}`).filter(x => false).toArray()).should.deep.equal([]); - }); - it('Should apply filter to false then map correctly', async () => { - (await iterator.filter(x => true).map(x => `x${x}`).toArray()).should.deep.equal(['x0', 'x1', 'x2']); - }); - it('Should apply filter to true then map correctly', async () => { - (await iterator.filter(x => false).map(x => `x${x}`).filter(x => false).toArray()).should.deep.equal([]); - }); - it('Should apply filter one then double', async () => { - (await iterator.filter(x => x !== 1).map(x => x * 2).toArray()).should.deep.equal([0, 4]); - }); - it('Should apply double then filter one', async () => { - (await iterator.map(x => x * 2).filter(x => x !== 1).toArray()).should.deep.equal([0, 2, 4]); - }); - it('Should apply map then filter correctly', async () => { - (await iterator.map(x => `x${x}`).filter(x => (x[1] === '0')).toArray()).should.deep.equal(['x0']); - }); - it('Should handle transforms', async () => { - iterator = iterator.syncTransform(function* (data) { - yield `x${data}`; - yield `y${data}`; - }); - (await iterator.toArray()).should.deep.equal(['x0', 'y0', 'x1', 'y1', 'x2', 'y2']); - }); - it('Should handle transforms and maps', async () => { - iterator = iterator.syncTransform(function* (data) { - yield `x${data}`; - yield `y${data}`; - }).map(x => `z${x}`); - (await iterator.toArray()).should.deep.equal(['zx0', 'zy0', 'zx1', 'zy1', 'zx2', 'zy2']); - }); - it('Should handle maps and transforms', async () => { - iterator = iterator.map(x => `z${x}`).syncTransform(function* (data) { - yield `x${data}`; - yield `y${data}`; - }); - (await iterator.toArray()).should.deep.equal(['xz0', 'yz0', 'xz1', 'yz1', 'xz2', 'yz2']); - }); -}); - From 6791d8195f126e0593774ed34629c7a44632e0bc Mon Sep 17 00:00:00 2001 From: Jesse Wright Date: Sat, 26 Mar 2022 13:44:07 +1100 Subject: [PATCH 3/6] chore: revert package-lock --- package-lock.json | 432 ---------------------------------------------- package.json | 2 - 2 files changed, 434 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2680f99..831df0f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,8 +13,6 @@ "@babel/core": "^7.10.2", "@babel/plugin-transform-modules-commonjs": "^7.10.1", "@babel/register": "^7.10.1", - "@types/jest": "^27.4.1", - "@types/mocha": "^9.1.0", "@types/node": "^14.0.13", "@typescript-eslint/eslint-plugin": "^3.2.0", "@typescript-eslint/parser": "^3.2.0", @@ -508,28 +506,12 @@ "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", "dev": true }, - "node_modules/@types/jest": { - "version": "27.4.1", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", - "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", - "dev": true, - "dependencies": { - "jest-matcher-utils": "^27.0.0", - "pretty-format": "^27.0.0" - } - }, "node_modules/@types/json-schema": { "version": "7.0.8", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz", "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==", "dev": true }, - "node_modules/@types/mocha": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.0.tgz", - "integrity": "sha512-QCWHkbMv4Y5U9oW10Uxbr45qMMSzl4OzijsozynUAgx3kEHUdXB00udx2dWDQ7f2TU2a2uuiFaRZjCe3unPpeg==", - "dev": true - }, "node_modules/@types/node": { "version": "14.17.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.5.tgz", @@ -1746,15 +1728,6 @@ "node": ">=0.3.1" } }, - "node_modules/diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", - "dev": true, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -3185,185 +3158,6 @@ "underscore": "^1.7.0" } }, - "node_modules/jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-diff/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-diff/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-diff/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-diff/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-matcher-utils/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-matcher-utils/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-matcher-utils/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-matcher-utils/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-matcher-utils/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-matcher-utils/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -4790,41 +4584,6 @@ "node": ">= 0.8.0" } }, - "node_modules/pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -4859,12 +4618,6 @@ "safe-buffer": "^5.1.0" } }, - "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, "node_modules/readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", @@ -6724,28 +6477,12 @@ "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", "dev": true }, - "@types/jest": { - "version": "27.4.1", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", - "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", - "dev": true, - "requires": { - "jest-matcher-utils": "^27.0.0", - "pretty-format": "^27.0.0" - } - }, "@types/json-schema": { "version": "7.0.8", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz", "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==", "dev": true }, - "@types/mocha": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.0.tgz", - "integrity": "sha512-QCWHkbMv4Y5U9oW10Uxbr45qMMSzl4OzijsozynUAgx3kEHUdXB00udx2dWDQ7f2TU2a2uuiFaRZjCe3unPpeg==", - "dev": true - }, "@types/node": { "version": "14.17.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.5.tgz", @@ -7672,12 +7409,6 @@ "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, - "diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", - "dev": true - }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -8786,138 +8517,6 @@ "underscore": "^1.7.0" } }, - "jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true - }, - "jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -10011,31 +9610,6 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, - "pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } - }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -10064,12 +9638,6 @@ "safe-buffer": "^5.1.0" } }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", diff --git a/package.json b/package.json index e5fba79..06ab110 100644 --- a/package.json +++ b/package.json @@ -42,8 +42,6 @@ "@babel/core": "^7.10.2", "@babel/plugin-transform-modules-commonjs": "^7.10.1", "@babel/register": "^7.10.1", - "@types/jest": "^27.4.1", - "@types/mocha": "^9.1.0", "@types/node": "^14.0.13", "@typescript-eslint/eslint-plugin": "^3.2.0", "@typescript-eslint/parser": "^3.2.0", From 6e20b4502eb19e9af5f1f2b66dd7752a744b3acc Mon Sep 17 00:00:00 2001 From: Jesse Wright Date: Sat, 26 Mar 2022 13:50:40 +1100 Subject: [PATCH 4/6] chore: add documentation --- asynciterator.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/asynciterator.ts b/asynciterator.ts index 89f47f8..a134d24 100644 --- a/asynciterator.ts +++ b/asynciterator.ts @@ -1932,6 +1932,13 @@ function build(transforms: Transform[]) { (item: any) => f(transform.function(item)), (e: any) => e); } +/** + An iterator that is used to quickly transform items, it is optimized for performance + and uses *mutations* - this means that it is unsafe to do anything with the original iterator + after map, transform and syncTransform have been applied to it. + @param source The source to transform + @extends module:asynciterator.FastTransformIterator +*/ export class FastTransformIterator extends AsyncIterator { private transforms: Transform[] = []; constructor(private source: AsyncIterator) { @@ -1960,16 +1967,30 @@ export class FastTransformIterator extends AsyncIterator { return this.read(); } + /** + Filter items according to a given function + @param {item: T) => boolean} filter The function to filter items with + */ + filter(filter: (item: T) => item is K): FastTransformIterator; + filter(filter: (item: T) => boolean): FastTransformIterator; filter(filter: (item: T) => boolean): FastTransformIterator { this.transforms.push({ filter: true, function: filter }); return this as unknown as FastTransformIterator; } + /** + Maps items according to a given function + @param {((item: T) => D} map The function to map items with + */ map(map: (item: T) => D): FastTransformIterator { this.transforms.push({ filter: false, function: map }); return this as unknown as FastTransformIterator; } + /** + Transforms items according to a synchronous generator (hence no need for buffering) + @param {(item: T) => Generator} transform The function to transform items with + */ syncTransform(transform: (item: T) => Generator): FastTransformIterator { const { source } = this; From 96a9a52d16459b6cfeff4e354392b5ffc96b83d2 Mon Sep 17 00:00:00 2001 From: Jesse Wright Date: Sat, 26 Mar 2022 13:56:05 +1100 Subject: [PATCH 5/6] chore: fix docs generation issue --- asynciterator.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/asynciterator.ts b/asynciterator.ts index a134d24..a1947f2 100644 --- a/asynciterator.ts +++ b/asynciterator.ts @@ -1969,7 +1969,7 @@ export class FastTransformIterator extends AsyncIterator { /** Filter items according to a given function - @param {item: T) => boolean} filter The function to filter items with + @param {Function} filter The function to filter items with */ filter(filter: (item: T) => item is K): FastTransformIterator; filter(filter: (item: T) => boolean): FastTransformIterator; @@ -1980,7 +1980,7 @@ export class FastTransformIterator extends AsyncIterator { /** Maps items according to a given function - @param {((item: T) => D} map The function to map items with + @param {Function} map The function to map items with */ map(map: (item: T) => D): FastTransformIterator { this.transforms.push({ filter: false, function: map }); @@ -1989,7 +1989,7 @@ export class FastTransformIterator extends AsyncIterator { /** Transforms items according to a synchronous generator (hence no need for buffering) - @param {(item: T) => Generator} transform The function to transform items with + @param {Function} transform The function to transform items with */ syncTransform(transform: (item: T) => Generator): FastTransformIterator { const { source } = this; From 34032202d489df89fe0453f1f47210557fccd3e9 Mon Sep 17 00:00:00 2001 From: Jesse Wright Date: Sat, 26 Mar 2022 14:14:50 +1100 Subject: [PATCH 6/6] chore: fix extends --- asynciterator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asynciterator.ts b/asynciterator.ts index a1947f2..2c486d1 100644 --- a/asynciterator.ts +++ b/asynciterator.ts @@ -1937,7 +1937,7 @@ function build(transforms: Transform[]) { and uses *mutations* - this means that it is unsafe to do anything with the original iterator after map, transform and syncTransform have been applied to it. @param source The source to transform - @extends module:asynciterator.FastTransformIterator + @extends module:asynciterator.AsyncIterator */ export class FastTransformIterator extends AsyncIterator { private transforms: Transform[] = [];