Skip to content

Commit

Permalink
Refactor to TypeScript (#6)
Browse files Browse the repository at this point in the history
* minimal basic working refactor into TS

* minimal basic working refactor into TS

* looseAsyncIterWrapper func into TypeScript

* bump minor version
  • Loading branch information
shtaif authored Aug 3, 2021
1 parent 30d411f commit 01ac1bd
Show file tree
Hide file tree
Showing 53 changed files with 1,483 additions and 370 deletions.
13 changes: 8 additions & 5 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,26 @@ jobs:

- uses: actions/setup-node@v2
with:
node-version: '10.15.0'
node-version: '10.21.0'

- name: Get Node.js Version
id: node_version
run: |
echo "::set-output name=version::$(node -v)"
- run: npm install -g yarn
- name: Install yarn
run: npm install -g yarn

- name: Cache Node modules
- name: Cache node_modules
id: cache-node-modules
uses: actions/cache@v2
with:
path: ./node_modules
key: node-modules-${{ runner.os }}-${{ steps.node_version.outputs.version }}-${{ hashFiles('./yarn.lock') }}

- if: steps.cache-node-modules.outputs.cache-hit != 'true'
- name: Install dependencies
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: yarn install

- run: yarn test
- name: Run code checks
run: yarn code-check
3 changes: 2 additions & 1 deletion .mocharc.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
spec: ./!(node_modules)/**/*.{spec,test}.js
spec: ./!(node_modules)/**/*.{spec,test}.{ts,js}
file:
- ./src/spec/testsGlobalSetup.js
watch-files:
- ./src/**/*.ts
- ./src/**/*.js
27 changes: 21 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,27 +1,42 @@
{
"name": "multerator",
"version": "0.0.2",
"version": "0.1.0",
"license": "MIT",
"main": "index.js",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"repository": "https://github.com/shtaif/multerator",
"engineStrict": true,
"engines": {
"node": ">=10.15.0"
},
"scripts": {
"test": "mocha"
"test": "ts-mocha",
"code-check": "yarn run test && tsc --noEmit"
},
"files": [
"src/**/*",
"!src/spec/**/*"
"./dist"
],
"devDependencies": {
"@tsconfig/node10": "^1.0.8",
"@types/chai": "^4.2.21",
"@types/chai-subset": "^1.3.3",
"@types/mocha": "^8.2.3",
"@types/node": "^16.3.3",
"@typescript-eslint/eslint-plugin": "^4.28.3",
"@typescript-eslint/parser": "^4.28.3",
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
"chai-subset": "^1.6.0",
"dedent": "^0.7.0",
"eslint": "^7.25.0",
"eslint-config-prettier": "^8.3.0",
"eslint-config-standard": "^16.0.3",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-standard": "^5.0.0",
"mocha": "^8.1.3",
"prettier": "^2.3.2"
"prettier": "^2.3.2",
"ts-mocha": "^8.0.0",
"typescript": "^4.3.5"
}
}
22 changes: 15 additions & 7 deletions src/index.js → src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
const pipe = require('./utils/pipe');
const mapAsyncIter = require('./iter-utils/mapAsyncIter');
const normalizeInputToAsyncIter = require('./utils/normalizeInputToAsyncIter');
const splitMultipartStreamToParts = require('./utils/splitMultipartStreamToParts');
const parseMultipartPart = require('./utils/parseMultipartPart');
import pipe from './utils/pipe';
import mapAsyncIter from './iter-utils/mapAsyncIter';
import normalizeInputToAsyncIter from './utils/normalizeInputToAsyncIter';
import splitMultipartStreamToParts from './utils/splitMultipartStreamToParts';
import parseMultipartPart, {
FilePartInfo,
TextPartInfo,
} from './utils/parseMultipartPart';

module.exports = multerator;
export { multerator as default, FilePartInfo, TextPartInfo };

// TODO: For focused testing - several occurances of the search sequence in a row
// TODO: For focused testing - stream starts with an occurance of search sequence
Expand All @@ -23,7 +26,12 @@ async function* multerator({
boundary,
maxFileSize = defaultMaxFileSize,
maxFieldSize = defaultMaxFieldSize,
} = {}) {
}: {
input: AsyncIterable<Buffer>;
boundary: string;
maxFileSize?: number;
maxFieldSize?: number;
}) {
yield* pipe(
input,
normalizeInputToAsyncIter,
Expand Down
19 changes: 0 additions & 19 deletions src/iter-utils/allowOneActiveSubIterAtATime.js

This file was deleted.

23 changes: 23 additions & 0 deletions src/iter-utils/allowOneActiveSubIterAtATime.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export default allowOneActiveSubIterAtATime;

async function* allowOneActiveSubIterAtATime<T>(
source: AsyncIterable<AsyncIterable<T>>
): AsyncGenerator<AsyncGenerator<T>, void, undefined> {
let promise: Promise<void>;
let resolve = noop;

for await (const partIter of source) {
promise = new Promise(_resolve => (resolve = _resolve));

const delayedPartIter = (async function* () {
yield* partIter;
resolve();
})();

yield delayedPartIter;

await promise;
}
}

const noop: Function = () => {};
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
const MulteratorError = require('../utils/MulteratorError');
import MulteratorError from '../utils/MulteratorError';

module.exports = asyncIterOfBuffersSizeLimiter;
export default asyncIterOfBuffersSizeLimiter;

function asyncIterOfBuffersSizeLimiter(sizeLimit) {
if (!Number.isFinite(sizeLimit)) {
function asyncIterOfBuffersSizeLimiter(
sizeLimit: number | undefined | null
): (src: AsyncIterable<Buffer>) => AsyncIterable<Buffer> {
if (!isFiniteNumberPredicated(sizeLimit)) {
return source => source;
}

Expand All @@ -23,3 +25,7 @@ function asyncIterOfBuffersSizeLimiter(sizeLimit) {
}
};
}

function isFiniteNumberPredicated(num: unknown): num is number {
return Number.isFinite(num);
}
9 changes: 0 additions & 9 deletions src/iter-utils/asyncIterToArray.js

This file was deleted.

43 changes: 0 additions & 43 deletions src/iter-utils/asyncIterWindowBetweenOccuranceOf.js

This file was deleted.

47 changes: 47 additions & 0 deletions src/iter-utils/asyncIterWindowBetweenOccuranceOf.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
export default asyncIterWindowBetweenOccuranceOf;

function asyncIterWindowBetweenOccuranceOf<VAL_T, SPLIT_MARK_T>(
valueToSplitBy: SPLIT_MARK_T
): (
src: AsyncIterable<VAL_T | SPLIT_MARK_T>
) => AsyncGenerator<AsyncGenerator<VAL_T, void>, void> {
return async function* (src) {
const srcIterator = src[Symbol.asyncIterator]();
let done: boolean | undefined = false;
let hasError = false;
let error;
let value: VAL_T | SPLIT_MARK_T;

try {
for (;;) {
yield (async function* () {
for (;;) {
try {
({ value, done } = await srcIterator.next());
} catch (err) {
hasError = true;
error = err;
throw err;
}

if (value === valueToSplitBy || done) {
return;
}

yield value as VAL_T; // TODO: What do I do about this `as`?...
}
})();

if (done) {
break;
}

if (hasError) {
throw error;
}
}
} finally {
srcIterator.return?.();
}
};
}
26 changes: 17 additions & 9 deletions src/iter-utils/bufferUntil.js → src/iter-utils/bufferUntil.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
module.exports = bufferUntil;
export default bufferUntil;

async function bufferUntil(
source,
predicate = () => false,
async function bufferUntil<T>(
source: AsyncIterable<T>,
predicate: (val: T) => boolean = defaultPredicate,
{ includeLast = false } = {}
) {
const buffered = [];
): Promise<{
buffered: T[];
rest: AsyncIterable<T>;
done: boolean;
}> {
const buffered: T[] = [];
const sourceIter = source[Symbol.asyncIterator]();

let value;
let done;
let value: T;
let done: boolean | undefined;

for (;;) {
({ done, value } = await sourceIter.next());
Expand All @@ -35,6 +39,10 @@ async function bufferUntil(
return {
buffered,
rest,
done,
done: !!done,
};
}

function defaultPredicate() {
return false;
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
const bufferUntil = require('./bufferUntil');

module.exports = bufferUntilAccumulatedLength;

async function bufferUntilAccumulatedLength(source, targetLength) {
import bufferUntil from './bufferUntil';
import prependAsyncIter from './prependAsyncIter';

export default bufferUntilAccumulatedLength;

async function bufferUntilAccumulatedLength(
source: AsyncIterable<Buffer>,
targetLength: number
): Promise<{
result: Buffer;
rest: AsyncIterable<Buffer>;
}> {
let totalCollectedLength = 0;

const resultOfBufferUntil = await bufferUntil(
Expand All @@ -15,7 +22,10 @@ async function bufferUntilAccumulatedLength(source, targetLength) {
let rest = resultOfBufferUntil.rest;

if (!bufferedChunks.length) {
return { result: Buffer.alloc(0), rest };
return {
result: Buffer.alloc(0),
rest,
};
}

const diffFromTargetLength = totalCollectedLength - targetLength;
Expand All @@ -28,19 +38,17 @@ async function bufferUntilAccumulatedLength(source, targetLength) {

bufferedChunks[bufferedChunks.length - 1] = preSplitChunk;

rest = prependValueToAsyncIter(rest, postSplitChunk);
rest = prependAsyncIter(postSplitChunk, rest);
}

const result = concatBuffers(bufferedChunks);

return { result, rest };
return {
result,
rest,
};
}

function concatBuffers(buffersArr) {
function concatBuffers(buffersArr: Buffer[]): Buffer {
return buffersArr.length === 1 ? buffersArr[0] : Buffer.concat(buffersArr);
}

async function* prependValueToAsyncIter(source, value) {
yield value;
yield* source;
}
Loading

0 comments on commit 01ac1bd

Please sign in to comment.