UNPKG

4.59 kBJavaScriptView Raw
1const { Writable } = require('stream');
2let erotic = require('erotic'); if (erotic && erotic.__esModule) erotic = erotic.default;
3let cleanStack = require('@artdeco/clean-stack'); if (cleanStack && cleanStack.__esModule) cleanStack = cleanStack.default;
4
5function joinBufferData(array) {
6 return array.join('')
7}
8
9/**
10 * A writable stream which collects incoming data into memory, and provides a promise to way for the stream to finish. The promise is resolved with joined chunks.
11 */
12class Catchment extends Writable {
13 /**
14 * Create a new catchment to pipe a readable stream into and collect all emitted data.
15 * @constructor
16 * @param {Options} [options] Options to pass to the `Writable` super constructor, and others shown below.
17 * @param {Readable} [options.rs] A readable stream to automatically pipe into the catchment. If an error occurs during reading of this stream, the catchment promise will be rejected with it.
18 * @param {boolean} [options.binary=false] Whether to return a raw buffer instead of a string. The string is created by joining all incoming chunks together with `.join('')` method. Default `false`.
19 * @example
20 *
21 * import { createReadStream } from 'fs'
22 * import Catchment from 'catchment'
23 *
24 * const rs = createReadStream('file.txt')
25 * const { promise } = new Catchment({ rs })
26 * const res = await promise
27 */
28 constructor({ er = erotic(true), ...options } = {}) {
29 super(options)
30 const { binary, rs } = options
31 this._caughtData = []
32 this._promise = new Promise((r, j) => {
33 this.on('finish', () => {
34 let d
35 if (binary) {
36 d = Buffer.concat(this._caughtData)
37 } else {
38 d = joinBufferData(this._caughtData)
39 }
40 r(d)
41 this._caughtData = []
42 })
43 this.once('error', (e) => {
44 if (e.stack.indexOf('\n') == -1) {
45 const err = er(e)
46 j(err)
47 } else {
48 const stack = cleanStack(e.stack)
49 e.stack = stack
50 j(e)
51 }
52 })
53 if (rs) {
54 rs.once('error', e => this.emit('error', e))
55 rs.pipe(this)
56 }
57 })
58 }
59 _write(chunk, encoding, callback) {
60 this._caughtData.push(chunk)
61 callback()
62 }
63 /**
64 * A promise which will resolve will all data when the stream finishes.
65 * @type {Promise.<string|Buffer>}
66 */
67 get promise() {
68 return this._promise
69 }
70}
71
72module.exports=Catchment
73
74/**
75 * Collect data into a catchment, and return results when the stream finishes.
76 * @param {Readable} readable A readable stream to collect all data from. If an error occurs during reading of this stream, the promise will be rejected with it.
77 * @param {CollectOptions} options Options when collecting data into a catchment. They can extend `Writable` options which will be passed to the `Catchment` constructor.
78 * @param {boolean} [options.binary=false] Whether to return a raw buffer instead of a string. The string is created by joining all incoming chunks together with `.join('')` method. Default `false`.
79 * @example
80 *
81 * import { collect } from 'catchment'
82 * import { createReadStream } from 'fs'
83 *
84 * const readFile = async (path) => {
85 * const rs = createReadStream(path)
86 * const res = await collect()
87 * return res
88 * }
89 */
90 const collect = async (readable, options = { binary: false }) => {
91 const { promise } = new Catchment({
92 rs: readable,
93 ...options,
94 er: erotic(true),
95 })
96 const res = await promise
97 return res
98}
99
100/* documentary types/index.xml */
101/**
102 * @typedef {import('stream').Readable} Readable
103 *
104 * @typedef {Object} Options Options to pass to the `Writable` super constructor, and others shown below.
105 * @prop {Readable} [rs] A readable stream to automatically pipe into the catchment. If an error occurs during reading of this stream, the catchment promise will be rejected with it.
106 * @prop {boolean} [binary=false] Whether to return a raw buffer instead of a string. The string is created by joining all incoming chunks together with `.join('')` method. Default `false`.
107 */
108
109/* documentary types/collect.xml */
110/**
111 * @typedef {import('stream').Readable} Readable
112 *
113 * @typedef {Object} CollectOptions Options when collecting data into a catchment. They can extend `Writable` options which will be passed to the `Catchment` constructor.
114 * @prop {boolean} [binary=false] Whether to return a raw buffer instead of a string. The string is created by joining all incoming chunks together with `.join('')` method. Default `false`.
115 */
116
117
118module.exports.collect = collect
119//# sourceMappingURL=index.js.map
\No newline at end of file