diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 0000000..814ef5e --- /dev/null +++ b/index.d.ts @@ -0,0 +1,234 @@ +import EventEmitter, { EventMap } from 'bare-events' +import Buffer, { BufferEncoding } from 'bare-buffer' + +type StreamEncoding = BufferEncoding | 'buffer' + +interface StreamCallback { + (err: Error | null): void +} + +interface StreamEvents extends EventMap { + close: [] + error: [err: Error] +} + +interface StreamOptions { + eagerOpen?: boolean + signal?: AbortSignal + open?(this: S, cb: StreamCallback): void + predestroy?(this: S): void + destroy?(this: S, err: Error | null, cb: StreamCallback): void +} + +interface Stream + extends EventEmitter { + _open(cb: StreamCallback): void + _predestroy(): void + _destroy(err: Error | null, cb: StreamCallback): void + + readonly readable: boolean + readonly writable: boolean + readonly destroyed: boolean + readonly destroying: boolean + + destroy(err?: Error | null): void +} + +declare class Stream {} + +interface ReadableEvents extends StreamEvents { + data: [data: Buffer | string] + end: [] + readable: [] + piping: [dest: Writable] +} + +interface ReadableOptions + extends StreamOptions { + encoding?: BufferEncoding + highWaterMark?: number + read?(this: S, size: number): void +} + +interface Readable + extends Stream, + AsyncIterable { + _read(size: number): void + + push(data: string, encoding?: BufferEncoding): boolean + push(data: Buffer | null): boolean + + unshift(data: string, encoding?: BufferEncoding): boolean + unshift(data: Buffer | null): boolean + + read(): Buffer | string | null + + resume(): this + pause(): this + + pipe(dest: S, cb?: StreamCallback): S + + setEncoding(encoding: BufferEncoding): void +} + +declare class Readable< + M extends ReadableEvents = ReadableEvents +> extends Stream { + constructor(opts?: ReadableOptions) + + static from( + data: + | (Buffer | string) + | (Buffer | string)[] + | AsyncIterable, + opts?: ReadableOptions + ): Readable + + static isBackpressured(rs: Readable): boolean + + static isPaused(rs: Readable): boolean +} + +interface WritableEvents extends StreamEvents { + drain: [] + finish: [] + pipe: [src: Readable] +} + +interface WritableOptions + extends StreamOptions { + write?( + this: S, + data: Buffer, + encoding: StreamEncoding, + cb: StreamCallback + ): void + writev?( + this: S, + batch: { chunk: Buffer; encoding: StreamEncoding }[], + cb: StreamCallback + ): void + final?(this: S, cb: StreamCallback): void +} + +interface Writable + extends Stream { + _write(data: Buffer, encoding: StreamEncoding, cb: StreamCallback): void + _writev( + batch: { chunk: Buffer; encoding: StreamEncoding }[], + cb: StreamCallback + ): void + _final(cb: StreamCallback): void + + readonly destroyed: boolean + + write(data: string, encoding?: BufferEncoding, cb?: StreamCallback): boolean + write(data: Buffer, cb?: StreamCallback): boolean + + end(cb?: StreamCallback): this + end(data: string, encoding?: BufferEncoding, cb?: StreamCallback): this + end(data: Buffer, cb?: StreamCallback): this + + cork(): void + uncork(): void +} + +declare class Writable< + M extends WritableEvents = WritableEvents +> extends Stream { + constructor(opts?: WritableOptions) + + static isBackpressured(ws: Writable): boolean + + static drained(ws: Writable): Promise +} + +interface DuplexEvents extends ReadableEvents, WritableEvents {} + +interface DuplexOptions + extends ReadableOptions, + WritableOptions {} + +interface Duplex + extends Readable, + Writable {} + +declare class Duplex extends Stream { + constructor(opts?: DuplexOptions) +} + +interface TransformEvents extends DuplexEvents {} + +interface TransformOptions + extends DuplexOptions { + transform?( + this: S, + data: Buffer, + encoding: StreamEncoding, + cb: StreamCallback + ): void + flush?(this: S, cb: StreamCallback): void +} + +interface Transform + extends Duplex { + _transform(data: Buffer, encoding: StreamEncoding, cb: StreamCallback): void + _flush(cb: StreamCallback): void +} + +declare class Transform< + M extends TransformEvents = TransformEvents +> extends Duplex { + constructor(opts?: TransformOptions) +} + +type Pipeline = [ + src: Readable, + ...transforms: Duplex[], + dest: S +] + +declare namespace Stream { + export { + Stream, + Readable, + Writable, + Duplex, + Transform, + Transform as PassThrough + } + + export function pipeline( + streams: Pipeline, + cb?: StreamCallback + ): S + + export function pipeline(...args: Pipeline): S + + export function pipeline( + ...args: [...Pipeline, cb: StreamCallback] + ): S + + export function finished( + stream: Stream, + opts: { cleanup?: boolean }, + cb: StreamCallback + ): () => void + + export function finished(stream: Stream, cb: StreamCallback): () => void + + export function isStream(stream: unknown): stream is Stream + + export function isEnded(stream: Stream): boolean + + export function isFinished(stream: Stream): boolean + + export function isDisturbed(stream: Stream): boolean + + export function getStreamError( + stream: Stream, + opts?: { all?: boolean } + ): Error | null +} + +export = Stream diff --git a/index.js b/index.js index 1585b90..db40c25 100644 --- a/index.js +++ b/index.js @@ -17,7 +17,13 @@ exports.Stream = exports exports.Readable = class Readable extends stream.Readable { constructor(opts = {}) { - super(opts) + super({ + ...opts, + byteLength: null, + byteLengthReadable: null, + map: null, + mapReadable: null + }) if (this._construct) this._open = this._construct @@ -49,7 +55,13 @@ exports.Readable = class Readable extends stream.Readable { exports.Writable = class Writable extends stream.Writable { constructor(opts = {}) { - super({ ...opts, byteLengthWritable }) + super({ + ...opts, + byteLength: null, + byteLengthWritable, + map: null, + mapWritable: null + }) if (this._construct) this._open = this._construct @@ -77,7 +89,7 @@ exports.Writable = class Writable extends stream.Writable { const result = super.write({ chunk, encoding }) - if (cb) stream.Writable.drained(this).then(cb, cb) + if (cb) stream.Writable.drained(this).then(() => cb(null), cb) return result } @@ -103,7 +115,7 @@ exports.Writable = class Writable extends stream.Writable { ? super.end({ chunk, encoding }) : super.end() - if (cb) this.once('end', cb) + if (cb) this.once('end', () => cb(null)) return result } @@ -111,7 +123,15 @@ exports.Writable = class Writable extends stream.Writable { exports.Duplex = class Duplex extends stream.Duplex { constructor(opts = {}) { - super({ ...opts, byteLengthWritable }) + super({ + ...opts, + byteLength: null, + byteLengthReadable: null, + byteLengthWritable, + map: null, + mapReadable: null, + mapWritable: null + }) if (this._construct) this._open = this._construct @@ -159,7 +179,7 @@ exports.Duplex = class Duplex extends stream.Duplex { const result = super.write({ chunk, encoding }) - if (cb) stream.Writable.drained(this).then(cb, cb) + if (cb) stream.Writable.drained(this).then(() => cb(null), cb) return result } @@ -185,7 +205,7 @@ exports.Duplex = class Duplex extends stream.Duplex { ? super.end({ chunk, encoding }) : super.end() - if (cb) this.once('end', cb) + if (cb) this.once('end', () => cb(null)) return result } @@ -193,7 +213,15 @@ exports.Duplex = class Duplex extends stream.Duplex { exports.Transform = class Transform extends stream.Transform { constructor(opts = {}) { - super({ ...opts, byteLengthWritable }) + super({ + ...opts, + byteLength: null, + byteLengthReadable: null, + byteLengthWritable, + map: null, + mapReadable: null, + mapWritable: null + }) if (this._transform !== stream.Transform.prototype._transform) { this._transform = transform.bind(this, this._transform) @@ -233,7 +261,7 @@ exports.Transform = class Transform extends stream.Transform { const result = super.write({ chunk, encoding }) - if (cb) stream.Writable.drained(this).then(cb, cb) + if (cb) stream.Writable.drained(this).then(() => cb(null), cb) return result } @@ -259,7 +287,7 @@ exports.Transform = class Transform extends stream.Transform { ? super.end({ chunk, encoding }) : super.end() - if (cb) this.once('end', cb) + if (cb) this.once('end', () => cb(null)) return result } diff --git a/package.json b/package.json index 7493b73..69eacb0 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,10 @@ "version": "2.6.1", "description": "Streaming data for JavaScript", "exports": { - ".": "./index.js", + ".": { + "types": "./index.d.ts", + "default": "./index.js" + }, "./package": "./package.json", "./promises": "./promises.js", "./web": "./web.js", @@ -11,12 +14,13 @@ }, "files": [ "index.js", + "index.d.ts", "promises.js", "web.js", "global.js" ], "scripts": { - "test": "prettier . --check && bare test/all.js" + "test": "prettier . --check && bare test.js" }, "repository": { "type": "git", @@ -32,8 +36,14 @@ "streamx": "^2.21.0" }, "devDependencies": { + "bare-buffer": "^3.0.0", + "bare-events": "^2.5.4", "brittle": "^3.5.2", "prettier": "^3.3.3", "prettier-config-standard": "^7.0.0" + }, + "peerDependencies": { + "bare-buffer": "*", + "bare-events": "*" } } diff --git a/test.js b/test.js new file mode 100644 index 0000000..73f59bf --- /dev/null +++ b/test.js @@ -0,0 +1,2 @@ +require('./test/basic') +require('./test/web') diff --git a/test/all.js b/test/all.js deleted file mode 100644 index 1075a78..0000000 --- a/test/all.js +++ /dev/null @@ -1,2 +0,0 @@ -require('./basic') -require('./web')