commit
This commit is contained in:
parent
a15c733e45
commit
2a5130cbda
2838 changed files with 288613 additions and 0 deletions
21
node_modules/peek-readable/LICENSE
generated
vendored
Normal file
21
node_modules/peek-readable/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License
|
||||
|
||||
Copyright (c) 2010-2017 Borewit
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
95
node_modules/peek-readable/README.md
generated
vendored
Normal file
95
node_modules/peek-readable/README.md
generated
vendored
Normal file
|
@ -0,0 +1,95 @@
|
|||

|
||||
[](https://npmjs.org/package/peek-readable)
|
||||
[](https://npmcharts.com/compare/peek-readable?start=600&interval=30)
|
||||
[](https://coveralls.io/github/Borewit/peek-readable?branch=master)
|
||||
[](https://www.codacy.com/gh/Borewit/peek-readable/dashboard?utm_source=github.com&utm_medium=referral&utm_content=Borewit/peek-readable&utm_campaign=Badge_Grade)
|
||||
[](https://lgtm.com/projects/g/Borewit/peek-readable/alerts/)
|
||||
[](https://lgtm.com/projects/g/Borewit/peek-readable/context:javascript)
|
||||
[](https://snyk.io/test/github/Borewit/peek-readable?targetFile=package.json)
|
||||
|
||||
# peek-readable
|
||||
|
||||
A promise based asynchronous stream reader, which makes reading from a stream easy.
|
||||
|
||||
Allows to read and peek from a [Readable Stream](https://nodejs.org/api/stream.html#stream_readable_streams)
|
||||
|
||||
Note that [peek-readable](https://github.com/Borewit/peek-readable) was formally released as [then-read-stream](https://github.com/Borewit/peek-readable).
|
||||
|
||||
## Usage
|
||||
|
||||
### Installation
|
||||
|
||||
```shell script
|
||||
npm install --save peek-readable
|
||||
```
|
||||
|
||||
The `peek-readable` contains one class: `StreamReader`, which reads from a [stream.Readable](https://nodejs.org/api/stream.html#stream_class_stream_readable).
|
||||
|
||||
### Compatibility
|
||||
|
||||
Module: version 5 migrated from [CommonJS](https://en.wikipedia.org/wiki/CommonJS) to [pure ECMAScript Module (ESM)](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c).
|
||||
JavaScript is compliant with [ECMAScript 2019 (ES10)](https://en.wikipedia.org/wiki/ECMAScript#10th_Edition_%E2%80%93_ECMAScript_2019).
|
||||
Requires Node.js ≥ 14.16 engine.
|
||||
|
||||
## Examples
|
||||
|
||||
In the following example we read the first 16 bytes from a stream and store them in our buffer.
|
||||
Source code of examples can be found [here](test/examples.ts).
|
||||
|
||||
```js
|
||||
import fs from 'node:fs';
|
||||
import { StreamReader } from 'peek-readable';
|
||||
|
||||
(async () => {
|
||||
const readable = fs.createReadStream('JPEG_example_JPG_RIP_001.jpg');
|
||||
const streamReader = new StreamReader(readable);
|
||||
const uint8Array = new Uint8Array(16);
|
||||
const bytesRead = await streamReader.read(uint8Array, 0, 16);;
|
||||
// buffer contains 16 bytes, if the end-of-stream has not been reached
|
||||
})();
|
||||
```
|
||||
|
||||
End-of-stream detection:
|
||||
```js
|
||||
(async () => {
|
||||
|
||||
const fileReadStream = fs.createReadStream('JPEG_example_JPG_RIP_001.jpg');
|
||||
const streamReader = new StreamReader(fileReadStream);
|
||||
const buffer = Buffer.alloc(16); // or use: new Uint8Array(16);
|
||||
|
||||
try {
|
||||
await streamReader.read(buffer, 0, 16);
|
||||
// buffer contains 16 bytes, if the end-of-stream has not been reached
|
||||
} catch(error) {
|
||||
if (error instanceof EndOfStreamError) {
|
||||
console.log('End-of-stream reached');
|
||||
}
|
||||
}
|
||||
})();
|
||||
```
|
||||
|
||||
With peek you can read ahead:
|
||||
```js
|
||||
import fs from 'node:fs';
|
||||
import { StreamReader } from 'peek-readable';
|
||||
|
||||
const fileReadStream = fs.createReadStream('JPEG_example_JPG_RIP_001.jpg');
|
||||
const streamReader = new StreamReader(fileReadStream);
|
||||
const buffer = Buffer.alloc(20);
|
||||
|
||||
(async () => {
|
||||
let bytesRead = await streamReader.peek(buffer, 0, 3);
|
||||
if (bytesRead === 3 && buffer[0] === 0xFF && buffer[1] === 0xD8 && buffer[2] === 0xFF) {
|
||||
console.log('This is a JPEG file');
|
||||
} else {
|
||||
throw Error('Expected a JPEG file');
|
||||
}
|
||||
|
||||
bytesRead = await streamReader.read(buffer, 0, 20); // Read JPEG header
|
||||
if (bytesRead === 20) {
|
||||
console.log('Got the JPEG header');
|
||||
} else {
|
||||
throw Error('Failed to read JPEG header');
|
||||
}
|
||||
})();
|
||||
```
|
6
node_modules/peek-readable/lib/Deferred.d.ts
generated
vendored
Normal file
6
node_modules/peek-readable/lib/Deferred.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
export declare class Deferred<T> {
|
||||
promise: Promise<T>;
|
||||
resolve: (value: T) => void;
|
||||
reject: (reason: any) => void;
|
||||
constructor();
|
||||
}
|
10
node_modules/peek-readable/lib/Deferred.js
generated
vendored
Normal file
10
node_modules/peek-readable/lib/Deferred.js
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
export class Deferred {
|
||||
constructor() {
|
||||
this.resolve = () => null;
|
||||
this.reject = () => null;
|
||||
this.promise = new Promise((resolve, reject) => {
|
||||
this.reject = reject;
|
||||
this.resolve = resolve;
|
||||
});
|
||||
}
|
||||
}
|
7
node_modules/peek-readable/lib/EndOfFileStream.d.ts
generated
vendored
Normal file
7
node_modules/peek-readable/lib/EndOfFileStream.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
export declare const defaultMessages = "End-Of-Stream";
|
||||
/**
|
||||
* Thrown on read operation of the end of file or stream has been reached
|
||||
*/
|
||||
export declare class EndOfStreamError extends Error {
|
||||
constructor();
|
||||
}
|
9
node_modules/peek-readable/lib/EndOfFileStream.js
generated
vendored
Normal file
9
node_modules/peek-readable/lib/EndOfFileStream.js
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
export const defaultMessages = 'End-Of-Stream';
|
||||
/**
|
||||
* Thrown on read operation of the end of file or stream has been reached
|
||||
*/
|
||||
export class EndOfStreamError extends Error {
|
||||
constructor() {
|
||||
super(defaultMessages);
|
||||
}
|
||||
}
|
47
node_modules/peek-readable/lib/StreamReader.d.ts
generated
vendored
Normal file
47
node_modules/peek-readable/lib/StreamReader.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
/// <reference types="node" resolution-mode="require"/>
|
||||
import { Readable } from 'node:stream';
|
||||
export { EndOfStreamError } from './EndOfFileStream.js';
|
||||
export declare class StreamReader {
|
||||
private s;
|
||||
/**
|
||||
* Deferred used for postponed read request (as not data is yet available to read)
|
||||
*/
|
||||
private deferred;
|
||||
private endOfStream;
|
||||
/**
|
||||
* Store peeked data
|
||||
* @type {Array}
|
||||
*/
|
||||
private peekQueue;
|
||||
constructor(s: Readable);
|
||||
/**
|
||||
* Read ahead (peek) from stream. Subsequent read or peeks will return the same data
|
||||
* @param uint8Array - Uint8Array (or Buffer) to store data read from stream in
|
||||
* @param offset - Offset target
|
||||
* @param length - Number of bytes to read
|
||||
* @returns Number of bytes peeked
|
||||
*/
|
||||
peek(uint8Array: Uint8Array, offset: number, length: number): Promise<number>;
|
||||
/**
|
||||
* Read chunk from stream
|
||||
* @param buffer - Target Uint8Array (or Buffer) to store data read from stream in
|
||||
* @param offset - Offset target
|
||||
* @param length - Number of bytes to read
|
||||
* @returns Number of bytes read
|
||||
*/
|
||||
read(buffer: Uint8Array, offset: number, length: number): Promise<number>;
|
||||
/**
|
||||
* Read chunk from stream
|
||||
* @param buffer Target Uint8Array (or Buffer) to store data read from stream in
|
||||
* @param offset Offset target
|
||||
* @param length Number of bytes to read
|
||||
* @returns Number of bytes read
|
||||
*/
|
||||
private readFromStream;
|
||||
/**
|
||||
* Process deferred read request
|
||||
* @param request Deferred read request
|
||||
*/
|
||||
private readDeferred;
|
||||
private reject;
|
||||
}
|
129
node_modules/peek-readable/lib/StreamReader.js
generated
vendored
Normal file
129
node_modules/peek-readable/lib/StreamReader.js
generated
vendored
Normal file
|
@ -0,0 +1,129 @@
|
|||
import { EndOfStreamError } from './EndOfFileStream.js';
|
||||
import { Deferred } from './Deferred.js';
|
||||
export { EndOfStreamError } from './EndOfFileStream.js';
|
||||
const maxStreamReadSize = 1 * 1024 * 1024; // Maximum request length on read-stream operation
|
||||
export class StreamReader {
|
||||
constructor(s) {
|
||||
this.s = s;
|
||||
/**
|
||||
* Deferred used for postponed read request (as not data is yet available to read)
|
||||
*/
|
||||
this.deferred = null;
|
||||
this.endOfStream = false;
|
||||
/**
|
||||
* Store peeked data
|
||||
* @type {Array}
|
||||
*/
|
||||
this.peekQueue = [];
|
||||
if (!s.read || !s.once) {
|
||||
throw new Error('Expected an instance of stream.Readable');
|
||||
}
|
||||
this.s.once('end', () => this.reject(new EndOfStreamError()));
|
||||
this.s.once('error', err => this.reject(err));
|
||||
this.s.once('close', () => this.reject(new Error('Stream closed')));
|
||||
}
|
||||
/**
|
||||
* Read ahead (peek) from stream. Subsequent read or peeks will return the same data
|
||||
* @param uint8Array - Uint8Array (or Buffer) to store data read from stream in
|
||||
* @param offset - Offset target
|
||||
* @param length - Number of bytes to read
|
||||
* @returns Number of bytes peeked
|
||||
*/
|
||||
async peek(uint8Array, offset, length) {
|
||||
const bytesRead = await this.read(uint8Array, offset, length);
|
||||
this.peekQueue.push(uint8Array.subarray(offset, offset + bytesRead)); // Put read data back to peek buffer
|
||||
return bytesRead;
|
||||
}
|
||||
/**
|
||||
* Read chunk from stream
|
||||
* @param buffer - Target Uint8Array (or Buffer) to store data read from stream in
|
||||
* @param offset - Offset target
|
||||
* @param length - Number of bytes to read
|
||||
* @returns Number of bytes read
|
||||
*/
|
||||
async read(buffer, offset, length) {
|
||||
if (length === 0) {
|
||||
return 0;
|
||||
}
|
||||
if (this.peekQueue.length === 0 && this.endOfStream) {
|
||||
throw new EndOfStreamError();
|
||||
}
|
||||
let remaining = length;
|
||||
let bytesRead = 0;
|
||||
// consume peeked data first
|
||||
while (this.peekQueue.length > 0 && remaining > 0) {
|
||||
const peekData = this.peekQueue.pop(); // Front of queue
|
||||
if (!peekData)
|
||||
throw new Error('peekData should be defined');
|
||||
const lenCopy = Math.min(peekData.length, remaining);
|
||||
buffer.set(peekData.subarray(0, lenCopy), offset + bytesRead);
|
||||
bytesRead += lenCopy;
|
||||
remaining -= lenCopy;
|
||||
if (lenCopy < peekData.length) {
|
||||
// remainder back to queue
|
||||
this.peekQueue.push(peekData.subarray(lenCopy));
|
||||
}
|
||||
}
|
||||
// continue reading from stream if required
|
||||
while (remaining > 0 && !this.endOfStream) {
|
||||
const reqLen = Math.min(remaining, maxStreamReadSize);
|
||||
const chunkLen = await this.readFromStream(buffer, offset + bytesRead, reqLen);
|
||||
bytesRead += chunkLen;
|
||||
if (chunkLen < reqLen)
|
||||
break;
|
||||
remaining -= chunkLen;
|
||||
}
|
||||
return bytesRead;
|
||||
}
|
||||
/**
|
||||
* Read chunk from stream
|
||||
* @param buffer Target Uint8Array (or Buffer) to store data read from stream in
|
||||
* @param offset Offset target
|
||||
* @param length Number of bytes to read
|
||||
* @returns Number of bytes read
|
||||
*/
|
||||
async readFromStream(buffer, offset, length) {
|
||||
const readBuffer = this.s.read(length);
|
||||
if (readBuffer) {
|
||||
buffer.set(readBuffer, offset);
|
||||
return readBuffer.length;
|
||||
}
|
||||
else {
|
||||
const request = {
|
||||
buffer,
|
||||
offset,
|
||||
length,
|
||||
deferred: new Deferred()
|
||||
};
|
||||
this.deferred = request.deferred;
|
||||
this.s.once('readable', () => {
|
||||
this.readDeferred(request);
|
||||
});
|
||||
return request.deferred.promise;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Process deferred read request
|
||||
* @param request Deferred read request
|
||||
*/
|
||||
readDeferred(request) {
|
||||
const readBuffer = this.s.read(request.length);
|
||||
if (readBuffer) {
|
||||
request.buffer.set(readBuffer, request.offset);
|
||||
request.deferred.resolve(readBuffer.length);
|
||||
this.deferred = null;
|
||||
}
|
||||
else {
|
||||
this.s.once('readable', () => {
|
||||
this.readDeferred(request);
|
||||
});
|
||||
}
|
||||
}
|
||||
reject(err) {
|
||||
this.endOfStream = true;
|
||||
if (this.deferred) {
|
||||
this.deferred.reject(err);
|
||||
this.deferred = null;
|
||||
}
|
||||
}
|
||||
}
|
2
node_modules/peek-readable/lib/index.d.ts
generated
vendored
Normal file
2
node_modules/peek-readable/lib/index.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
export { EndOfStreamError } from './EndOfFileStream.js';
|
||||
export { StreamReader } from './StreamReader.js';
|
2
node_modules/peek-readable/lib/index.js
generated
vendored
Normal file
2
node_modules/peek-readable/lib/index.js
generated
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
export { EndOfStreamError } from './EndOfFileStream.js';
|
||||
export { StreamReader } from './StreamReader.js';
|
73
node_modules/peek-readable/package.json
generated
vendored
Normal file
73
node_modules/peek-readable/package.json
generated
vendored
Normal file
|
@ -0,0 +1,73 @@
|
|||
{
|
||||
"name": "peek-readable",
|
||||
"version": "5.0.0",
|
||||
"description": "Read and peek from a readable stream",
|
||||
"author": {
|
||||
"name": "Borewit",
|
||||
"url": "https://github.com/Borewit"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Borewit"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "del-cli lib/**/*.js lib/**/*.js.map lib/**/*.d.ts test/**/*.js test/**/*.js.map coverage .nyc_output",
|
||||
"build": "npm run clean && npm run compile",
|
||||
"compile-src": "tsc -p lib",
|
||||
"compile-test": "tsc -p test",
|
||||
"compile": "npm run compile-src && yarn run compile-test",
|
||||
"eslint": "eslint lib test --ext .ts --ignore-pattern *.d.ts",
|
||||
"lint-md": "remark -u preset-lint-recommended .",
|
||||
"lint": "npm run lint-md && npm run eslint",
|
||||
"test": "mocha",
|
||||
"test-coverage": "c8 npm run test",
|
||||
"start": "npm run compile && npm run lint && npm run cover-test"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.16"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/Borewit/peek-readable"
|
||||
},
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"exports": "./lib/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"bugs": {
|
||||
"url": "https://github.com/Borewit/peek-readable/issues"
|
||||
},
|
||||
"files": [
|
||||
"lib/**/*.js",
|
||||
"lib/**/*.d.ts"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/chai": "^4.3.1",
|
||||
"@types/mocha": "^9.1.1",
|
||||
"@types/node": "^18.6.3",
|
||||
"@typescript-eslint/eslint-plugin": "^4.33.0",
|
||||
"@typescript-eslint/parser": "^4.33.0",
|
||||
"c8": "^7.12.0",
|
||||
"chai": "^4.3.6",
|
||||
"coveralls": "^3.1.1",
|
||||
"del-cli": "^5.0.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-import-resolver-typescript": "^3.4.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-jsdoc": "^39.3.4",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-unicorn": "^40.1.0",
|
||||
"mocha": "^10.0.0",
|
||||
"remark-cli": "^11.0.0",
|
||||
"remark-preset-lint-recommended": "^6.1.2",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^4.7.4"
|
||||
},
|
||||
"keywords": [
|
||||
"readable",
|
||||
"buffer",
|
||||
"stream",
|
||||
"read"
|
||||
]
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue