@pkmn/sim 0.4.20 → 0.4.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/config/formats.js +415 -688
- package/build/config/formats.js.map +1 -1
- package/build/data/aliases.js +7 -5
- package/build/data/aliases.js.map +1 -1
- package/build/data/conditions.js +4 -1
- package/build/data/conditions.js.map +1 -1
- package/build/data/formats-data.js +18 -18
- package/build/data/formats-data.js.map +1 -1
- package/build/data/learnsets.js +10 -8
- package/build/data/learnsets.js.map +1 -1
- package/build/data/mods/gen1/moves.js +1 -1
- package/build/data/mods/gen1/moves.js.map +1 -1
- package/build/data/mods/gen1/scripts.js +18 -22
- package/build/data/mods/gen1/scripts.js.map +1 -1
- package/build/data/mods/gen2/scripts.js +16 -23
- package/build/data/mods/gen2/scripts.js.map +1 -1
- package/build/data/mods/gen3/moves.js +2 -1
- package/build/data/mods/gen3/moves.js.map +1 -1
- package/build/data/mods/gen4/conditions.js +6 -0
- package/build/data/mods/gen4/conditions.js.map +1 -1
- package/build/data/mods/gen4/moves.js +2 -1
- package/build/data/mods/gen4/moves.js.map +1 -1
- package/build/data/mods/gen4/scripts.js +2 -1
- package/build/data/mods/gen4/scripts.js.map +1 -1
- package/build/data/mods/gen6/conditions.js +4 -1
- package/build/data/mods/gen6/conditions.js.map +1 -1
- package/build/data/mods/gen7/formats-data.js +2 -2
- package/build/data/mods/gen7/formats-data.js.map +1 -1
- package/build/data/mods/gen7/moves.js +8 -0
- package/build/data/mods/gen7/moves.js.map +1 -1
- package/build/data/moves.js +25 -13
- package/build/data/moves.js.map +1 -1
- package/build/data/rulesets.js +221 -1
- package/build/data/rulesets.js.map +1 -1
- package/build/data/tags.js +2 -2
- package/build/data/tags.js.map +1 -1
- package/build/lib/streams.d.ts +1 -199
- package/build/lib/streams.js +11 -772
- package/build/lib/streams.js.map +1 -1
- package/build/sim/battle-actions.d.ts +1 -1
- package/build/sim/battle-actions.js +18 -42
- package/build/sim/battle-actions.js.map +1 -1
- package/build/sim/battle.d.ts +1 -0
- package/build/sim/battle.js +5 -0
- package/build/sim/battle.js.map +1 -1
- package/build/sim/dex-moves.d.ts +31 -11
- package/build/sim/dex-moves.js +4 -3
- package/build/sim/dex-moves.js.map +1 -1
- package/build/sim/dex-species.js +11 -1
- package/build/sim/dex-species.js.map +1 -1
- package/build/sim/exported-global-types.d.ts +1 -0
- package/build/sim/global-types.d.ts +1 -0
- package/build/sim/side.js +2 -2
- package/build/sim/side.js.map +1 -1
- package/build/sim/team-validator.js +2 -2
- package/build/sim/team-validator.js.map +1 -1
- package/build/sim/tools/runner.d.ts +1 -6
- package/build/sim/tools/runner.js +6 -6
- package/build/sim/tools/runner.js.map +1 -1
- package/config/formats.ts +393 -643
- package/data/aliases.ts +7 -5
- package/data/conditions.ts +4 -1
- package/data/formats-data.ts +18 -18
- package/data/learnsets.ts +10 -8
- package/data/mods/gen1/moves.ts +1 -1
- package/data/mods/gen1/scripts.ts +23 -19
- package/data/mods/gen2/scripts.ts +20 -19
- package/data/mods/gen3/moves.ts +2 -1
- package/data/mods/gen4/conditions.ts +6 -0
- package/data/mods/gen4/moves.ts +2 -1
- package/data/mods/gen4/scripts.ts +1 -1
- package/data/mods/gen6/conditions.ts +4 -1
- package/data/mods/gen7/formats-data.ts +2 -2
- package/data/mods/gen7/moves.ts +8 -0
- package/data/moves.ts +22 -13
- package/data/rulesets.ts +199 -1
- package/data/tags.ts +2 -2
- package/lib/streams.ts +1 -874
- package/package.json +3 -2
- package/sim/battle-actions.ts +19 -40
- package/sim/battle.ts +6 -0
- package/sim/dex-moves.ts +35 -13
- package/sim/dex-species.ts +10 -1
- package/sim/exported-global-types.ts +1 -0
- package/sim/global-types.ts +1 -0
- package/sim/side.ts +2 -2
- package/sim/team-validator.ts +2 -2
- package/sim/tools/runner.ts +2 -0
package/lib/streams.ts
CHANGED
|
@@ -1,874 +1 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* Streams
|
|
4
|
-
* Pokemon Showdown - http://pokemonshowdown.com/
|
|
5
|
-
*
|
|
6
|
-
* The Node.js standard library's Streams are really hard to use. This
|
|
7
|
-
* offers a better stream API.
|
|
8
|
-
*
|
|
9
|
-
* Documented in STREAMS.md.
|
|
10
|
-
*
|
|
11
|
-
* @license MIT
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
const BUF_SIZE = 65536 * 4;
|
|
15
|
-
|
|
16
|
-
type BufferEncoding =
|
|
17
|
-
'ascii' | 'utf8' | 'utf-8' | 'utf16le' | 'ucs2' | 'ucs-2' | 'base64' | 'latin1' | 'binary' | 'hex';
|
|
18
|
-
|
|
19
|
-
export class ReadStream {
|
|
20
|
-
buf: Buffer;
|
|
21
|
-
bufStart: number;
|
|
22
|
-
bufEnd: number;
|
|
23
|
-
bufCapacity: number;
|
|
24
|
-
readSize: number;
|
|
25
|
-
atEOF: boolean;
|
|
26
|
-
errorBuf: Error[] | null;
|
|
27
|
-
encoding: BufferEncoding;
|
|
28
|
-
isReadable: boolean;
|
|
29
|
-
isWritable: boolean;
|
|
30
|
-
nodeReadableStream: NodeJS.ReadableStream | null;
|
|
31
|
-
nextPushResolver: (() => void) | null;
|
|
32
|
-
nextPush: Promise<void>;
|
|
33
|
-
awaitingPush: boolean;
|
|
34
|
-
|
|
35
|
-
constructor(optionsOrStreamLike: {[k: string]: any} | NodeJS.ReadableStream | string | Buffer = {}) {
|
|
36
|
-
this.buf = Buffer.allocUnsafe(BUF_SIZE);
|
|
37
|
-
this.bufStart = 0;
|
|
38
|
-
this.bufEnd = 0;
|
|
39
|
-
this.bufCapacity = BUF_SIZE;
|
|
40
|
-
this.readSize = 0;
|
|
41
|
-
this.atEOF = false;
|
|
42
|
-
this.errorBuf = null;
|
|
43
|
-
this.encoding = 'utf8';
|
|
44
|
-
this.isReadable = true;
|
|
45
|
-
this.isWritable = false;
|
|
46
|
-
this.nodeReadableStream = null;
|
|
47
|
-
this.nextPushResolver = null;
|
|
48
|
-
this.nextPush = new Promise(resolve => {
|
|
49
|
-
this.nextPushResolver = resolve;
|
|
50
|
-
});
|
|
51
|
-
this.awaitingPush = false;
|
|
52
|
-
|
|
53
|
-
let options;
|
|
54
|
-
if (typeof optionsOrStreamLike === 'string') {
|
|
55
|
-
options = {buffer: optionsOrStreamLike};
|
|
56
|
-
} else if (optionsOrStreamLike instanceof Buffer) {
|
|
57
|
-
options = {buffer: optionsOrStreamLike};
|
|
58
|
-
} else if (typeof (optionsOrStreamLike as any)._readableState === 'object') {
|
|
59
|
-
options = {nodeStream: optionsOrStreamLike as NodeJS.ReadableStream};
|
|
60
|
-
} else {
|
|
61
|
-
options = optionsOrStreamLike;
|
|
62
|
-
}
|
|
63
|
-
if (options.nodeStream) {
|
|
64
|
-
const nodeStream: NodeJS.ReadableStream = options.nodeStream;
|
|
65
|
-
this.nodeReadableStream = nodeStream;
|
|
66
|
-
nodeStream.on('data', data => {
|
|
67
|
-
this.push(data);
|
|
68
|
-
});
|
|
69
|
-
nodeStream.on('end', () => {
|
|
70
|
-
this.pushEnd();
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
options.read = function (this: ReadStream, unusedBytes: number) {
|
|
74
|
-
this.nodeReadableStream!.resume();
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
options.pause = function (this: ReadStream, unusedBytes: number) {
|
|
78
|
-
this.nodeReadableStream!.pause();
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (options.read) this._read = options.read;
|
|
83
|
-
if (options.pause) this._pause = options.pause;
|
|
84
|
-
if (options.destroy) this._destroy = options.destroy;
|
|
85
|
-
if (options.encoding) this.encoding = options.encoding;
|
|
86
|
-
if (options.buffer !== undefined) {
|
|
87
|
-
this.push(options.buffer);
|
|
88
|
-
this.pushEnd();
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
get bufSize() {
|
|
93
|
-
return this.bufEnd - this.bufStart;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
moveBuf() {
|
|
97
|
-
if (this.bufStart !== this.bufEnd) {
|
|
98
|
-
this.buf.copy(this.buf, 0, this.bufStart, this.bufEnd);
|
|
99
|
-
}
|
|
100
|
-
this.bufEnd -= this.bufStart;
|
|
101
|
-
this.bufStart = 0;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
expandBuf(newCapacity = this.bufCapacity * 2) {
|
|
105
|
-
const newBuf = Buffer.allocUnsafe(newCapacity);
|
|
106
|
-
this.buf.copy(newBuf, 0, this.bufStart, this.bufEnd);
|
|
107
|
-
this.bufEnd -= this.bufStart;
|
|
108
|
-
this.bufStart = 0;
|
|
109
|
-
this.bufCapacity = newCapacity;
|
|
110
|
-
this.buf = newBuf;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
ensureCapacity(additionalCapacity: number) {
|
|
114
|
-
if (this.bufEnd + additionalCapacity <= this.bufCapacity) return;
|
|
115
|
-
const capacity = this.bufEnd - this.bufStart + additionalCapacity;
|
|
116
|
-
if (capacity <= this.bufCapacity) {
|
|
117
|
-
return this.moveBuf();
|
|
118
|
-
}
|
|
119
|
-
let newCapacity = this.bufCapacity * 2;
|
|
120
|
-
while (newCapacity < capacity) newCapacity *= 2;
|
|
121
|
-
this.expandBuf(newCapacity);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
push(buf: Buffer | string, encoding: BufferEncoding = this.encoding) {
|
|
125
|
-
let size;
|
|
126
|
-
if (this.atEOF) return;
|
|
127
|
-
if (typeof buf === 'string') {
|
|
128
|
-
size = Buffer.byteLength(buf, encoding);
|
|
129
|
-
this.ensureCapacity(size);
|
|
130
|
-
this.buf.write(buf, this.bufEnd);
|
|
131
|
-
} else {
|
|
132
|
-
size = buf.length;
|
|
133
|
-
this.ensureCapacity(size);
|
|
134
|
-
buf.copy(this.buf, this.bufEnd);
|
|
135
|
-
}
|
|
136
|
-
this.bufEnd += size;
|
|
137
|
-
if (this.bufSize > this.readSize && size * 2 < this.bufSize) this._pause();
|
|
138
|
-
this.resolvePush();
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
pushEnd() {
|
|
142
|
-
this.atEOF = true;
|
|
143
|
-
this.resolvePush();
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
pushError(err: Error, recoverable?: boolean) {
|
|
147
|
-
if (!this.errorBuf) this.errorBuf = [];
|
|
148
|
-
this.errorBuf.push(err);
|
|
149
|
-
if (!recoverable) this.atEOF = true;
|
|
150
|
-
this.resolvePush();
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
readError() {
|
|
154
|
-
if (this.errorBuf) {
|
|
155
|
-
const err = this.errorBuf.shift()!;
|
|
156
|
-
if (!this.errorBuf.length) this.errorBuf = null;
|
|
157
|
-
throw err;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
peekError() {
|
|
162
|
-
if (this.errorBuf) {
|
|
163
|
-
throw this.errorBuf[0];
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
resolvePush() {
|
|
168
|
-
if (!this.nextPushResolver) throw new Error(`Push after end of read stream`);
|
|
169
|
-
this.nextPushResolver();
|
|
170
|
-
if (this.atEOF) {
|
|
171
|
-
this.nextPushResolver = null;
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
this.nextPush = new Promise(resolve => {
|
|
175
|
-
this.nextPushResolver = resolve;
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
_read(size = 0): void | Promise<void> {
|
|
180
|
-
throw new Error(`ReadStream needs to be subclassed and the _read function needs to be implemented.`);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
_destroy(): void | Promise<void> {}
|
|
184
|
-
_pause() {}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Reads until the internal buffer is non-empty. Does nothing if the
|
|
188
|
-
* internal buffer is already non-empty.
|
|
189
|
-
*
|
|
190
|
-
* If `byteCount` is a number, instead read until the internal buffer
|
|
191
|
-
* contains at least `byteCount` bytes.
|
|
192
|
-
*
|
|
193
|
-
* If `byteCount` is `true`, reads even if the internal buffer is
|
|
194
|
-
* non-empty.
|
|
195
|
-
*/
|
|
196
|
-
loadIntoBuffer(byteCount: number | null | true = null, readError?: boolean) {
|
|
197
|
-
this[readError ? 'readError' : 'peekError']();
|
|
198
|
-
if (byteCount === 0) return;
|
|
199
|
-
this.readSize = Math.max(
|
|
200
|
-
byteCount === true ? this.bufSize + 1 : byteCount === null ? 1 : byteCount,
|
|
201
|
-
this.readSize
|
|
202
|
-
);
|
|
203
|
-
if (!this.errorBuf && !this.atEOF && this.bufSize < this.readSize) {
|
|
204
|
-
let bytes: number | null = this.readSize - this.bufSize;
|
|
205
|
-
if (bytes === Infinity || byteCount === null || byteCount === true) bytes = null;
|
|
206
|
-
return this.doLoad(bytes, readError);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
async doLoad(chunkSize?: number | null, readError?: boolean) {
|
|
211
|
-
while (!this.errorBuf && !this.atEOF && this.bufSize < this.readSize) {
|
|
212
|
-
if (chunkSize) void this._read(chunkSize);
|
|
213
|
-
else void this._read();
|
|
214
|
-
await this.nextPush;
|
|
215
|
-
this[readError ? 'readError' : 'peekError']();
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
peek(byteCount?: number | null, encoding?: BufferEncoding): string | null | Promise<string | null>;
|
|
220
|
-
peek(encoding: BufferEncoding): string | null | Promise<string | null>;
|
|
221
|
-
peek(byteCount: number | string | null = null, encoding: BufferEncoding = this.encoding) {
|
|
222
|
-
if (typeof byteCount === 'string') {
|
|
223
|
-
encoding = byteCount as BufferEncoding;
|
|
224
|
-
byteCount = null;
|
|
225
|
-
}
|
|
226
|
-
const maybeLoad = this.loadIntoBuffer(byteCount);
|
|
227
|
-
if (maybeLoad) return maybeLoad.then(() => this.peek(byteCount as number, encoding));
|
|
228
|
-
|
|
229
|
-
if (!this.bufSize && byteCount !== 0) return null;
|
|
230
|
-
if (byteCount === null) return this.buf.toString(encoding, this.bufStart, this.bufEnd);
|
|
231
|
-
if (byteCount > this.bufSize) byteCount = this.bufSize;
|
|
232
|
-
return this.buf.toString(encoding, this.bufStart, this.bufStart + byteCount);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
peekBuffer(byteCount: number | null = null): Buffer | null | Promise<Buffer | null> {
|
|
236
|
-
const maybeLoad = this.loadIntoBuffer(byteCount);
|
|
237
|
-
if (maybeLoad) return maybeLoad.then(() => this.peekBuffer(byteCount));
|
|
238
|
-
|
|
239
|
-
if (!this.bufSize && byteCount !== 0) return null;
|
|
240
|
-
if (byteCount === null) return this.buf.slice(this.bufStart, this.bufEnd);
|
|
241
|
-
if (byteCount > this.bufSize) byteCount = this.bufSize;
|
|
242
|
-
return this.buf.slice(this.bufStart, this.bufStart + byteCount);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
async read(byteCount?: number | null, encoding?: BufferEncoding): Promise<string | null>;
|
|
246
|
-
async read(encoding: BufferEncoding): Promise<string | null>;
|
|
247
|
-
async read(byteCount: number | string | null = null, encoding: BufferEncoding = this.encoding) {
|
|
248
|
-
if (typeof byteCount === 'string') {
|
|
249
|
-
encoding = byteCount as BufferEncoding;
|
|
250
|
-
byteCount = null;
|
|
251
|
-
}
|
|
252
|
-
await this.loadIntoBuffer(byteCount, true);
|
|
253
|
-
|
|
254
|
-
// This MUST NOT be awaited: we MUST synchronously clear byteCount after peeking
|
|
255
|
-
// if the buffer is written to after peek but before clearing the buffer, the write
|
|
256
|
-
// will be lost forever
|
|
257
|
-
const out = this.peek(byteCount, encoding);
|
|
258
|
-
if (out && typeof out !== 'string') {
|
|
259
|
-
throw new Error("Race condition; you must not read before a previous read has completed");
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
if (byteCount === null || byteCount >= this.bufSize) {
|
|
263
|
-
this.bufStart = 0;
|
|
264
|
-
this.bufEnd = 0;
|
|
265
|
-
this.readSize = 0;
|
|
266
|
-
} else {
|
|
267
|
-
this.bufStart += byteCount;
|
|
268
|
-
this.readSize -= byteCount;
|
|
269
|
-
}
|
|
270
|
-
return out;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
byChunk(byteCount?: number | null) {
|
|
274
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
275
|
-
const byteStream = this;
|
|
276
|
-
return new ObjectReadStream<string>({
|
|
277
|
-
async read(this: ObjectReadStream<string>) {
|
|
278
|
-
const next = await byteStream.read(byteCount);
|
|
279
|
-
if (typeof next === 'string') this.push(next);
|
|
280
|
-
else this.pushEnd();
|
|
281
|
-
},
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
byLine() {
|
|
286
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
287
|
-
const byteStream = this;
|
|
288
|
-
return new ObjectReadStream<string>({
|
|
289
|
-
async read(this: ObjectReadStream<string>) {
|
|
290
|
-
const next = await byteStream.readLine();
|
|
291
|
-
if (typeof next === 'string') this.push(next);
|
|
292
|
-
else this.pushEnd();
|
|
293
|
-
},
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
delimitedBy(delimiter: string) {
|
|
298
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
299
|
-
const byteStream = this;
|
|
300
|
-
return new ObjectReadStream<string>({
|
|
301
|
-
async read(this: ObjectReadStream<string>) {
|
|
302
|
-
const next = await byteStream.readDelimitedBy(delimiter);
|
|
303
|
-
if (typeof next === 'string') this.push(next);
|
|
304
|
-
else this.pushEnd();
|
|
305
|
-
},
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
async readBuffer(byteCount: number | null = null) {
|
|
310
|
-
await this.loadIntoBuffer(byteCount, true);
|
|
311
|
-
|
|
312
|
-
// This MUST NOT be awaited: we must synchronously clear the buffer after peeking
|
|
313
|
-
// (see `read`)
|
|
314
|
-
const out = this.peekBuffer(byteCount);
|
|
315
|
-
if (out && (out as Promise<unknown>).then) {
|
|
316
|
-
throw new Error("Race condition; you must not read before a previous read has completed");
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
if (byteCount === null || byteCount >= this.bufSize) {
|
|
320
|
-
this.bufStart = 0;
|
|
321
|
-
this.bufEnd = 0;
|
|
322
|
-
} else {
|
|
323
|
-
this.bufStart += byteCount;
|
|
324
|
-
}
|
|
325
|
-
return out;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
async indexOf(symbol: string, encoding: BufferEncoding = this.encoding) {
|
|
329
|
-
let idx = this.buf.indexOf(symbol, this.bufStart, encoding);
|
|
330
|
-
while (!this.atEOF && (idx >= this.bufEnd || idx < 0)) {
|
|
331
|
-
await this.loadIntoBuffer(true);
|
|
332
|
-
idx = this.buf.indexOf(symbol, this.bufStart, encoding);
|
|
333
|
-
}
|
|
334
|
-
if (idx >= this.bufEnd) return -1;
|
|
335
|
-
return idx - this.bufStart;
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
async readAll(encoding: BufferEncoding = this.encoding) {
|
|
339
|
-
return (await this.read(Infinity, encoding)) || '';
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
peekAll(encoding: BufferEncoding = this.encoding) {
|
|
343
|
-
return this.peek(Infinity, encoding);
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
async readDelimitedBy(symbol: string, encoding: BufferEncoding = this.encoding) {
|
|
347
|
-
if (this.atEOF && !this.bufSize) return null;
|
|
348
|
-
const idx = await this.indexOf(symbol, encoding);
|
|
349
|
-
if (idx < 0) {
|
|
350
|
-
return this.readAll(encoding);
|
|
351
|
-
} else {
|
|
352
|
-
const out = await this.read(idx, encoding);
|
|
353
|
-
this.bufStart += Buffer.byteLength(symbol, 'utf8');
|
|
354
|
-
return out;
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
async readLine(encoding: BufferEncoding = this.encoding) {
|
|
359
|
-
if (!encoding) throw new Error(`readLine must have an encoding`);
|
|
360
|
-
let line = await this.readDelimitedBy('\n', encoding);
|
|
361
|
-
if (line?.endsWith('\r')) line = line.slice(0, -1);
|
|
362
|
-
return line;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
destroy() {
|
|
366
|
-
this.atEOF = true;
|
|
367
|
-
this.bufStart = 0;
|
|
368
|
-
this.bufEnd = 0;
|
|
369
|
-
if (this.nextPushResolver) this.resolvePush();
|
|
370
|
-
return this._destroy();
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
async next(byteCount: number | null = null) {
|
|
374
|
-
const value = await this.read(byteCount);
|
|
375
|
-
return {value, done: value === null};
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
async pipeTo(outStream: WriteStream, options: {noEnd?: boolean} = {}) {
|
|
379
|
-
let value, done;
|
|
380
|
-
while (({value, done} = await this.next(), !done)) {
|
|
381
|
-
await outStream.write(value!);
|
|
382
|
-
}
|
|
383
|
-
if (!options.noEnd) return outStream.writeEnd();
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
interface WriteStreamOptions {
|
|
388
|
-
nodeStream?: NodeJS.WritableStream;
|
|
389
|
-
write?: (this: WriteStream, data: string | Buffer) => (Promise<undefined> | undefined);
|
|
390
|
-
writeEnd?: (this: WriteStream) => Promise<any>;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
export class WriteStream {
|
|
394
|
-
isReadable: boolean;
|
|
395
|
-
isWritable: true;
|
|
396
|
-
encoding: BufferEncoding;
|
|
397
|
-
nodeWritableStream: NodeJS.WritableStream | null;
|
|
398
|
-
drainListeners: (() => void)[];
|
|
399
|
-
|
|
400
|
-
constructor(optionsOrStream: WriteStreamOptions | NodeJS.WritableStream = {}) {
|
|
401
|
-
this.isReadable = false;
|
|
402
|
-
this.isWritable = true;
|
|
403
|
-
this.encoding = 'utf8';
|
|
404
|
-
this.nodeWritableStream = null;
|
|
405
|
-
this.drainListeners = [];
|
|
406
|
-
|
|
407
|
-
let options: WriteStreamOptions = optionsOrStream as any;
|
|
408
|
-
if ((options as any)._writableState) {
|
|
409
|
-
options = {nodeStream: optionsOrStream as NodeJS.WritableStream};
|
|
410
|
-
}
|
|
411
|
-
if (options.nodeStream) {
|
|
412
|
-
const nodeStream: NodeJS.WritableStream = options.nodeStream;
|
|
413
|
-
this.nodeWritableStream = nodeStream;
|
|
414
|
-
options.write = function (data: string | Buffer) {
|
|
415
|
-
const result = this.nodeWritableStream!.write(data);
|
|
416
|
-
if (result !== false) return undefined;
|
|
417
|
-
if (!this.drainListeners.length) {
|
|
418
|
-
this.nodeWritableStream!.once('drain', () => {
|
|
419
|
-
for (const listener of this.drainListeners) listener();
|
|
420
|
-
this.drainListeners = [];
|
|
421
|
-
});
|
|
422
|
-
}
|
|
423
|
-
return new Promise(resolve => {
|
|
424
|
-
// `as () => void` is necessary because TypeScript thinks that it should be a function
|
|
425
|
-
// that takes an undefined value as its only parameter: `(value: PromiseLike<undefined> | undefined) => void`
|
|
426
|
-
this.drainListeners.push(resolve as () => void);
|
|
427
|
-
});
|
|
428
|
-
};
|
|
429
|
-
// Prior to Node v10.12.0, attempting to close STDOUT or STDERR will throw
|
|
430
|
-
if (nodeStream !== process.stdout && nodeStream !== process.stderr) {
|
|
431
|
-
options.writeEnd = function () {
|
|
432
|
-
return new Promise<void>(resolve => {
|
|
433
|
-
this.nodeWritableStream!.end(() => resolve());
|
|
434
|
-
});
|
|
435
|
-
};
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
if (options.write) this._write = options.write;
|
|
440
|
-
if (options.writeEnd) this._writeEnd = options.writeEnd;
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
write(chunk: Buffer | string): void | Promise<void> {
|
|
444
|
-
return this._write(chunk);
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
writeLine(chunk: string): void | Promise<void> {
|
|
448
|
-
if (chunk === null) {
|
|
449
|
-
return this.writeEnd();
|
|
450
|
-
}
|
|
451
|
-
return this.write(chunk + '\n');
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
_write(chunk: Buffer | string): void | Promise<void> {
|
|
455
|
-
throw new Error(`WriteStream needs to be subclassed and the _write function needs to be implemented.`);
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
_writeEnd(): void | Promise<void> {}
|
|
459
|
-
|
|
460
|
-
async writeEnd(chunk?: string): Promise<void> {
|
|
461
|
-
if (chunk) {
|
|
462
|
-
await this.write(chunk);
|
|
463
|
-
}
|
|
464
|
-
return this._writeEnd();
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
export class ReadWriteStream extends ReadStream implements WriteStream {
|
|
469
|
-
isReadable: true;
|
|
470
|
-
isWritable: true;
|
|
471
|
-
nodeWritableStream: NodeJS.WritableStream | null;
|
|
472
|
-
drainListeners: (() => void)[];
|
|
473
|
-
|
|
474
|
-
constructor(options: AnyObject = {}) {
|
|
475
|
-
super(options);
|
|
476
|
-
this.isReadable = true;
|
|
477
|
-
this.isWritable = true;
|
|
478
|
-
this.nodeWritableStream = null;
|
|
479
|
-
this.drainListeners = [];
|
|
480
|
-
|
|
481
|
-
if (options.nodeStream) {
|
|
482
|
-
const nodeStream: NodeJS.WritableStream = options.nodeStream;
|
|
483
|
-
this.nodeWritableStream = nodeStream;
|
|
484
|
-
options.write = function (data: string | Buffer) {
|
|
485
|
-
const result = this.nodeWritableStream!.write(data);
|
|
486
|
-
if (result !== false) return undefined;
|
|
487
|
-
if (!this.drainListeners.length) {
|
|
488
|
-
this.nodeWritableStream!.once('drain', () => {
|
|
489
|
-
for (const listener of this.drainListeners) listener();
|
|
490
|
-
this.drainListeners = [];
|
|
491
|
-
});
|
|
492
|
-
}
|
|
493
|
-
return new Promise(resolve => {
|
|
494
|
-
this.drainListeners.push(resolve);
|
|
495
|
-
});
|
|
496
|
-
};
|
|
497
|
-
// Prior to Node v10.12.0, attempting to close STDOUT or STDERR will throw
|
|
498
|
-
if (nodeStream !== process.stdout && nodeStream !== process.stderr) {
|
|
499
|
-
options.writeEnd = function () {
|
|
500
|
-
return new Promise<void>(resolve => {
|
|
501
|
-
this.nodeWritableStream!.end(() => resolve());
|
|
502
|
-
});
|
|
503
|
-
};
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
if (options.write) this._write = options.write;
|
|
507
|
-
if (options.writeEnd) this._writeEnd = options.writeEnd;
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
write(chunk: Buffer | string): Promise<void> | void {
|
|
511
|
-
return this._write(chunk);
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
writeLine(chunk: string): Promise<void> | void {
|
|
515
|
-
return this.write(chunk + '\n');
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
_write(chunk: Buffer | string): Promise<void> | void {
|
|
519
|
-
throw new Error(`WriteStream needs to be subclassed and the _write function needs to be implemented.`);
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
/**
|
|
523
|
-
* In a ReadWriteStream, `_read` does not need to be implemented,
|
|
524
|
-
* because it's valid for the read stream buffer to be filled only by
|
|
525
|
-
* `_write`.
|
|
526
|
-
*/
|
|
527
|
-
_read(size?: number) {}
|
|
528
|
-
|
|
529
|
-
_writeEnd(): void | Promise<void> {}
|
|
530
|
-
|
|
531
|
-
async writeEnd() {
|
|
532
|
-
return this._writeEnd();
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
type ObjectReadStreamOptions<T> = {
|
|
537
|
-
buffer?: T[],
|
|
538
|
-
read?: (this: ObjectReadStream<T>) => void | Promise<void>,
|
|
539
|
-
pause?: (this: ObjectReadStream<T>) => void | Promise<void>,
|
|
540
|
-
destroy?: (this: ObjectReadStream<T>) => void | Promise<void>,
|
|
541
|
-
nodeStream?: undefined,
|
|
542
|
-
} | {
|
|
543
|
-
buffer?: undefined,
|
|
544
|
-
read?: undefined,
|
|
545
|
-
pause?: undefined,
|
|
546
|
-
destroy?: undefined,
|
|
547
|
-
nodeStream: NodeJS.ReadableStream,
|
|
548
|
-
};
|
|
549
|
-
|
|
550
|
-
export class ObjectReadStream<T> {
|
|
551
|
-
buf: T[];
|
|
552
|
-
readSize: number;
|
|
553
|
-
atEOF: boolean;
|
|
554
|
-
errorBuf: Error[] | null;
|
|
555
|
-
isReadable: boolean;
|
|
556
|
-
isWritable: boolean;
|
|
557
|
-
nodeReadableStream: NodeJS.ReadableStream | null;
|
|
558
|
-
nextPushResolver: (() => void) | null;
|
|
559
|
-
nextPush: Promise<void>;
|
|
560
|
-
awaitingPush: boolean;
|
|
561
|
-
|
|
562
|
-
constructor(optionsOrStreamLike: ObjectReadStreamOptions<T> | NodeJS.ReadableStream | T[] = {}) {
|
|
563
|
-
this.buf = [];
|
|
564
|
-
this.readSize = 0;
|
|
565
|
-
this.atEOF = false;
|
|
566
|
-
this.errorBuf = null;
|
|
567
|
-
this.isReadable = true;
|
|
568
|
-
this.isWritable = false;
|
|
569
|
-
this.nodeReadableStream = null;
|
|
570
|
-
this.nextPushResolver = null;
|
|
571
|
-
this.nextPush = new Promise(resolve => {
|
|
572
|
-
this.nextPushResolver = resolve;
|
|
573
|
-
});
|
|
574
|
-
this.awaitingPush = false;
|
|
575
|
-
|
|
576
|
-
let options: ObjectReadStreamOptions<T>;
|
|
577
|
-
if (Array.isArray(optionsOrStreamLike)) {
|
|
578
|
-
options = {buffer: optionsOrStreamLike};
|
|
579
|
-
} else if (typeof (optionsOrStreamLike as any)._readableState === 'object') {
|
|
580
|
-
options = {nodeStream: optionsOrStreamLike as NodeJS.ReadableStream};
|
|
581
|
-
} else {
|
|
582
|
-
options = optionsOrStreamLike as ObjectReadStreamOptions<T>;
|
|
583
|
-
}
|
|
584
|
-
if ((options as any).nodeStream) {
|
|
585
|
-
const nodeStream: NodeJS.ReadableStream = (options as any).nodeStream;
|
|
586
|
-
this.nodeReadableStream = nodeStream;
|
|
587
|
-
nodeStream.on('data', data => {
|
|
588
|
-
this.push(data);
|
|
589
|
-
});
|
|
590
|
-
nodeStream.on('end', () => {
|
|
591
|
-
this.pushEnd();
|
|
592
|
-
});
|
|
593
|
-
|
|
594
|
-
options = {
|
|
595
|
-
read() {
|
|
596
|
-
this.nodeReadableStream!.resume();
|
|
597
|
-
},
|
|
598
|
-
pause() {
|
|
599
|
-
this.nodeReadableStream!.pause();
|
|
600
|
-
},
|
|
601
|
-
};
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
if (options.read) this._read = options.read;
|
|
605
|
-
if (options.pause) this._pause = options.pause;
|
|
606
|
-
if (options.destroy) this._destroy = options.destroy;
|
|
607
|
-
if (options.buffer !== undefined) {
|
|
608
|
-
this.buf = options.buffer.slice();
|
|
609
|
-
this.pushEnd();
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
push(elem: T) {
|
|
614
|
-
if (this.atEOF) return;
|
|
615
|
-
this.buf.push(elem);
|
|
616
|
-
if (this.buf.length > this.readSize && this.buf.length >= 16) this._pause();
|
|
617
|
-
this.resolvePush();
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
pushEnd() {
|
|
621
|
-
this.atEOF = true;
|
|
622
|
-
this.resolvePush();
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
pushError(err: Error, recoverable?: boolean) {
|
|
626
|
-
if (!this.errorBuf) this.errorBuf = [];
|
|
627
|
-
this.errorBuf.push(err);
|
|
628
|
-
if (!recoverable) this.atEOF = true;
|
|
629
|
-
this.resolvePush();
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
readError() {
|
|
633
|
-
if (this.errorBuf) {
|
|
634
|
-
const err = this.errorBuf.shift()!;
|
|
635
|
-
if (!this.errorBuf.length) this.errorBuf = null;
|
|
636
|
-
throw err;
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
peekError() {
|
|
641
|
-
if (this.errorBuf) {
|
|
642
|
-
throw this.errorBuf[0];
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
resolvePush() {
|
|
647
|
-
if (!this.nextPushResolver) throw new Error(`Push after end of read stream`);
|
|
648
|
-
this.nextPushResolver();
|
|
649
|
-
if (this.atEOF) {
|
|
650
|
-
this.nextPushResolver = null;
|
|
651
|
-
return;
|
|
652
|
-
}
|
|
653
|
-
this.nextPush = new Promise(resolve => {
|
|
654
|
-
this.nextPushResolver = resolve;
|
|
655
|
-
});
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
_read(size = 0): void | Promise<void> {
|
|
659
|
-
throw new Error(`ReadStream needs to be subclassed and the _read function needs to be implemented.`);
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
_destroy() {}
|
|
663
|
-
_pause() {}
|
|
664
|
-
|
|
665
|
-
async loadIntoBuffer(count: number | true = 1, readError?: boolean) {
|
|
666
|
-
this[readError ? 'readError' : 'peekError']();
|
|
667
|
-
if (count === true) count = this.buf.length + 1;
|
|
668
|
-
if (this.buf.length >= count) return;
|
|
669
|
-
this.readSize = Math.max(count, this.readSize);
|
|
670
|
-
while (!this.errorBuf && !this.atEOF && this.buf.length < this.readSize) {
|
|
671
|
-
const readResult = this._read();
|
|
672
|
-
if (readResult) {
|
|
673
|
-
await readResult;
|
|
674
|
-
} else {
|
|
675
|
-
await this.nextPush;
|
|
676
|
-
}
|
|
677
|
-
this[readError ? 'readError' : 'peekError']();
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
async peek() {
|
|
682
|
-
if (this.buf.length) return this.buf[0];
|
|
683
|
-
await this.loadIntoBuffer();
|
|
684
|
-
return this.buf[0];
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
async read() {
|
|
688
|
-
if (this.buf.length) return this.buf.shift();
|
|
689
|
-
await this.loadIntoBuffer(1, true);
|
|
690
|
-
if (!this.buf.length) return null;
|
|
691
|
-
return this.buf.shift()!;
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
async peekArray(count: number | null = null) {
|
|
695
|
-
await this.loadIntoBuffer(count === null ? 1 : count);
|
|
696
|
-
return this.buf.slice(0, count === null ? Infinity : count);
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
async readArray(count: number | null = null) {
|
|
700
|
-
await this.loadIntoBuffer(count === null ? 1 : count, true);
|
|
701
|
-
const out = this.buf.slice(0, count === null ? Infinity : count);
|
|
702
|
-
this.buf = this.buf.slice(out.length);
|
|
703
|
-
return out;
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
async readAll() {
|
|
707
|
-
await this.loadIntoBuffer(Infinity, true);
|
|
708
|
-
const out = this.buf;
|
|
709
|
-
this.buf = [];
|
|
710
|
-
return out;
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
async peekAll() {
|
|
714
|
-
await this.loadIntoBuffer(Infinity);
|
|
715
|
-
return this.buf.slice();
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
destroy() {
|
|
719
|
-
this.atEOF = true;
|
|
720
|
-
this.buf = [];
|
|
721
|
-
this.resolvePush();
|
|
722
|
-
return this._destroy();
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
// eslint-disable-next-line no-restricted-globals
|
|
726
|
-
[Symbol.asyncIterator]() { return this; }
|
|
727
|
-
async next() {
|
|
728
|
-
if (this.buf.length) return {value: this.buf.shift() as T, done: false as const};
|
|
729
|
-
await this.loadIntoBuffer(1, true);
|
|
730
|
-
if (!this.buf.length) return {value: undefined, done: true as const};
|
|
731
|
-
return {value: this.buf.shift() as T, done: false as const};
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
async pipeTo(outStream: ObjectWriteStream<T>, options: {noEnd?: boolean} = {}) {
|
|
735
|
-
let value, done;
|
|
736
|
-
while (({value, done} = await this.next(), !done)) {
|
|
737
|
-
await outStream.write(value!);
|
|
738
|
-
}
|
|
739
|
-
if (!options.noEnd) return outStream.writeEnd();
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
interface ObjectWriteStreamOptions<T> {
|
|
744
|
-
_writableState?: any;
|
|
745
|
-
nodeStream?: NodeJS.WritableStream;
|
|
746
|
-
write?: (this: ObjectWriteStream<T>, data: T) => Promise<any> | undefined;
|
|
747
|
-
writeEnd?: (this: ObjectWriteStream<T>) => Promise<any>;
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
export class ObjectWriteStream<T> {
|
|
751
|
-
isReadable: boolean;
|
|
752
|
-
isWritable: true;
|
|
753
|
-
nodeWritableStream: NodeJS.WritableStream | null;
|
|
754
|
-
|
|
755
|
-
constructor(optionsOrStream: ObjectWriteStreamOptions<T> | NodeJS.WritableStream = {}) {
|
|
756
|
-
this.isReadable = false;
|
|
757
|
-
this.isWritable = true;
|
|
758
|
-
this.nodeWritableStream = null;
|
|
759
|
-
|
|
760
|
-
let options: ObjectWriteStreamOptions<T> = optionsOrStream as any;
|
|
761
|
-
if (options._writableState) {
|
|
762
|
-
options = {nodeStream: optionsOrStream as NodeJS.WritableStream};
|
|
763
|
-
}
|
|
764
|
-
if (options.nodeStream) {
|
|
765
|
-
const nodeStream: NodeJS.WritableStream = options.nodeStream;
|
|
766
|
-
this.nodeWritableStream = nodeStream;
|
|
767
|
-
|
|
768
|
-
options.write = function (data: T) {
|
|
769
|
-
const result = this.nodeWritableStream!.write(data as unknown as string);
|
|
770
|
-
if (result === false) {
|
|
771
|
-
return new Promise<void>(resolve => {
|
|
772
|
-
this.nodeWritableStream!.once('drain', () => {
|
|
773
|
-
resolve();
|
|
774
|
-
});
|
|
775
|
-
});
|
|
776
|
-
}
|
|
777
|
-
};
|
|
778
|
-
|
|
779
|
-
// Prior to Node v10.12.0, attempting to close STDOUT or STDERR will throw
|
|
780
|
-
if (nodeStream !== process.stdout && nodeStream !== process.stderr) {
|
|
781
|
-
options.writeEnd = function () {
|
|
782
|
-
return new Promise<void>(resolve => {
|
|
783
|
-
this.nodeWritableStream!.end(() => resolve());
|
|
784
|
-
});
|
|
785
|
-
};
|
|
786
|
-
}
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
if (options.write) this._write = options.write;
|
|
790
|
-
if (options.writeEnd) this._writeEnd = options.writeEnd;
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
write(elem: T | null): void | Promise<void> {
|
|
794
|
-
if (elem === null) {
|
|
795
|
-
return this.writeEnd();
|
|
796
|
-
}
|
|
797
|
-
return this._write(elem);
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
_write(elem: T): void | Promise<void> {
|
|
801
|
-
throw new Error(`WriteStream needs to be subclassed and the _write function needs to be implemented.`);
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
_writeEnd(): void | Promise<void> {}
|
|
805
|
-
|
|
806
|
-
async writeEnd(elem?: T): Promise<void> {
|
|
807
|
-
if (elem !== undefined) {
|
|
808
|
-
await this.write(elem);
|
|
809
|
-
}
|
|
810
|
-
return this._writeEnd();
|
|
811
|
-
}
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
interface ObjectReadWriteStreamOptions<T> {
|
|
815
|
-
read?: (this: ObjectReadStream<T>) => void | Promise<void>;
|
|
816
|
-
pause?: (this: ObjectReadStream<T>) => void | Promise<void>;
|
|
817
|
-
destroy?: (this: ObjectReadStream<T>) => void | Promise<void>;
|
|
818
|
-
write?: (this: ObjectWriteStream<T>, elem: T) => Promise<any> | undefined | void;
|
|
819
|
-
writeEnd?: () => Promise<any> | undefined | void;
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
export class ObjectReadWriteStream<T> extends ObjectReadStream<T> implements ObjectWriteStream<T> {
|
|
823
|
-
isReadable: true;
|
|
824
|
-
isWritable: true;
|
|
825
|
-
nodeWritableStream: NodeJS.WritableStream | null;
|
|
826
|
-
|
|
827
|
-
constructor(options: ObjectReadWriteStreamOptions<T> = {}) {
|
|
828
|
-
super(options);
|
|
829
|
-
this.isReadable = true;
|
|
830
|
-
this.isWritable = true;
|
|
831
|
-
this.nodeWritableStream = null;
|
|
832
|
-
if (options.write) this._write = options.write;
|
|
833
|
-
if (options.writeEnd) this._writeEnd = options.writeEnd;
|
|
834
|
-
}
|
|
835
|
-
|
|
836
|
-
write(elem: T): void | Promise<void> {
|
|
837
|
-
return this._write(elem);
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
_write(elem: T): void | Promise<void> {
|
|
841
|
-
throw new Error(`WriteStream needs to be subclassed and the _write function needs to be implemented.`);
|
|
842
|
-
}
|
|
843
|
-
/** In a ReadWriteStream, _read does not need to be implemented. */
|
|
844
|
-
_read() {}
|
|
845
|
-
|
|
846
|
-
_writeEnd(): void | Promise<void> {}
|
|
847
|
-
|
|
848
|
-
async writeEnd() {
|
|
849
|
-
return this._writeEnd();
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
export function readAll(nodeStream: NodeJS.ReadableStream, encoding?: any) {
|
|
854
|
-
return new ReadStream(nodeStream).readAll(encoding);
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
export function stdin() {
|
|
858
|
-
return new ReadStream(process.stdin);
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
export function stdout() {
|
|
862
|
-
return new WriteStream(process.stdout);
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
export function stdpipe(stream: WriteStream | ReadStream | ReadWriteStream) {
|
|
866
|
-
const promises = [];
|
|
867
|
-
if ((stream as ReadStream | WriteStream & {pipeTo: undefined}).pipeTo) {
|
|
868
|
-
promises.push((stream as ReadStream).pipeTo(stdout()));
|
|
869
|
-
}
|
|
870
|
-
if ((stream as WriteStream | ReadStream & {write: undefined}).write) {
|
|
871
|
-
promises.push(stdin().pipeTo(stream as WriteStream));
|
|
872
|
-
}
|
|
873
|
-
return Promise.all(promises);
|
|
874
|
-
}
|
|
1
|
+
export * from "@pkmn/streams";
|