documonster 0.20.2 → 0.21.0
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/README.md +1 -1
- package/README_zh.md +1 -1
- package/THIRD_PARTY_NOTICES.md +34 -2
- package/dist/esm/modules/archive/core/byte-queue.js +2 -1
- package/dist/esm/modules/archive/unzip/stream.browser.js +6 -0
- package/dist/esm/modules/csv/parse/async.js +2 -1
- package/dist/esm/modules/excel/bridge/csv-bridge.js +1 -1
- package/dist/esm/modules/excel/core/xlsx-io.browser.js +5 -9
- package/dist/esm/modules/excel/core/xlsx-io.js +1 -3
- package/dist/esm/modules/excel/core/xlsx-stream.js +3 -1
- package/dist/esm/modules/excel/stream/workbook-reader.browser.js +10 -10
- package/dist/esm/modules/excel/stream/workbook-reader.js +30 -6
- package/dist/esm/modules/stream/browser/collector.js +3 -5
- package/dist/esm/modules/stream/browser/compose.js +13 -228
- package/dist/esm/modules/stream/browser/duplex-pair.js +71 -0
- package/dist/esm/modules/stream/browser/factories.js +35 -217
- package/dist/esm/modules/stream/browser/pipeline.js +43 -478
- package/dist/esm/modules/stream/browser/utils.js +21 -247
- package/dist/esm/modules/stream/browser/web.js +25 -0
- package/dist/esm/modules/stream/buffered-stream.js +8 -6
- package/dist/esm/modules/stream/core/factories.js +166 -0
- package/dist/esm/modules/stream/core/pipeline-api.js +32 -0
- package/dist/esm/modules/stream/core/sink-adapter.js +94 -24
- package/dist/esm/modules/stream/core/stream-helpers.js +160 -0
- package/dist/esm/modules/stream/core/utils.js +0 -23
- package/dist/esm/modules/stream/core/web-conversions.js +31 -0
- package/dist/esm/modules/stream/core/web-pipeline.js +90 -0
- package/dist/esm/modules/stream/index.base.js +2 -2
- package/dist/esm/modules/stream/index.browser.js +13 -19
- package/dist/esm/modules/stream/index.js +6 -10
- package/dist/esm/modules/stream/kernel/classes.js +618 -0
- package/dist/esm/modules/stream/kernel/compose-impl.js +225 -0
- package/dist/esm/modules/stream/kernel/destroy.js +255 -0
- package/dist/esm/modules/stream/kernel/duplexify.js +355 -0
- package/dist/esm/modules/stream/kernel/end-of-stream.js +212 -0
- package/dist/esm/modules/stream/kernel/errors.js +215 -0
- package/dist/esm/modules/stream/kernel/from.js +202 -0
- package/dist/esm/modules/stream/kernel/legacy.js +35 -0
- package/dist/esm/modules/stream/kernel/operators.js +285 -0
- package/dist/esm/modules/stream/kernel/pipeline-impl.js +561 -0
- package/dist/esm/modules/stream/kernel/readable-impl.js +963 -0
- package/dist/esm/modules/stream/kernel/state.js +253 -0
- package/dist/esm/modules/stream/kernel/stream-utils.js +212 -0
- package/dist/esm/modules/stream/kernel/web-adapters.js +584 -0
- package/dist/esm/modules/stream/kernel/writable.js +651 -0
- package/dist/esm/modules/stream/node/collector.js +7 -1
- package/dist/esm/modules/stream/node/compose.js +21 -206
- package/dist/esm/modules/stream/node/factories.js +34 -238
- package/dist/esm/modules/stream/node/pipeline.js +40 -94
- package/dist/esm/modules/stream/node/utils.js +15 -239
- package/dist/esm/modules/stream/node/web.js +27 -0
- package/dist/esm/modules/stream/pull-stream.js +15 -9
- package/dist/esm/modules/word/writer/streaming-writer.js +3 -0
- package/dist/iife/THIRD_PARTY_NOTICES.md +34 -2
- package/dist/iife/documonster.archive.iife.min.js +4 -4
- package/dist/iife/documonster.csv.iife.min.js +19 -19
- package/dist/iife/documonster.draw.iife.min.js +1 -1
- package/dist/iife/documonster.excel.iife.min.js +50 -50
- package/dist/iife/documonster.formula.iife.min.js +1 -1
- package/dist/iife/documonster.markdown.iife.min.js +1 -1
- package/dist/iife/documonster.mermaid.iife.min.js +1 -1
- package/dist/iife/documonster.pdf.iife.min.js +1 -1
- package/dist/iife/documonster.stream.iife.min.js +2 -2
- package/dist/iife/documonster.word.iife.min.js +60 -60
- package/dist/iife/documonster.xml.iife.min.js +1 -1
- package/dist/types/modules/excel/core/xlsx-io.browser.d.ts +5 -9
- package/dist/types/modules/excel/core/xlsx-io.d.ts +1 -3
- package/dist/types/modules/excel/core/xlsx-stream.d.ts +3 -2
- package/dist/types/modules/excel/stream/workbook-reader.browser.d.ts +2 -1
- package/dist/types/modules/excel/stream/workbook-reader.d.ts +2 -1
- package/dist/types/modules/stream/browser/collector.d.ts +1 -1
- package/dist/types/modules/stream/browser/compose.d.ts +14 -15
- package/dist/types/modules/stream/browser/duplex-pair.d.ts +10 -0
- package/dist/types/modules/stream/browser/factories.d.ts +22 -79
- package/dist/types/modules/stream/browser/pipeline.d.ts +8 -40
- package/dist/types/modules/stream/browser/utils.d.ts +6 -47
- package/dist/types/modules/stream/browser/web.d.ts +18 -0
- package/dist/types/modules/stream/core/add-abort-signal.d.ts +2 -1
- package/dist/types/modules/stream/core/consumers.d.ts +1 -1
- package/dist/types/modules/stream/core/event-utils.d.ts +2 -1
- package/dist/types/modules/stream/core/factories.d.ts +129 -0
- package/dist/types/modules/stream/core/pipeline-api.d.ts +10 -0
- package/dist/types/modules/stream/core/sink-adapter.d.ts +18 -1
- package/dist/types/modules/stream/core/stream-helpers.d.ts +76 -0
- package/dist/types/modules/stream/core/utils.d.ts +0 -9
- package/dist/types/modules/stream/core/web-conversions.d.ts +68 -0
- package/dist/types/modules/stream/core/web-pipeline.d.ts +27 -0
- package/dist/types/modules/stream/index.base.d.ts +6 -4
- package/dist/types/modules/stream/index.browser.d.ts +13 -14
- package/dist/types/modules/stream/index.d.ts +7 -10
- package/dist/types/modules/stream/kernel/classes.d.ts +220 -0
- package/dist/types/modules/stream/kernel/compose-impl.d.ts +10 -0
- package/dist/types/modules/stream/kernel/destroy.d.ts +21 -0
- package/dist/types/modules/stream/kernel/duplexify.d.ts +31 -0
- package/dist/types/modules/stream/kernel/end-of-stream.d.ts +28 -0
- package/dist/types/modules/stream/kernel/errors.d.ts +42 -0
- package/dist/types/modules/stream/kernel/from.d.ts +17 -0
- package/dist/types/modules/stream/kernel/legacy.d.ts +20 -0
- package/dist/types/modules/stream/kernel/operators.d.ts +44 -0
- package/dist/types/modules/stream/kernel/pipeline-impl.d.ts +32 -0
- package/dist/types/modules/stream/kernel/readable-impl.d.ts +34 -0
- package/dist/types/modules/stream/kernel/state.d.ts +223 -0
- package/dist/types/modules/stream/kernel/stream-utils.d.ts +34 -0
- package/dist/types/modules/stream/kernel/web-adapters.d.ts +65 -0
- package/dist/types/modules/stream/kernel/writable.d.ts +107 -0
- package/dist/types/modules/stream/node/collector.d.ts +7 -2
- package/dist/types/modules/stream/node/compose.d.ts +31 -5
- package/dist/types/modules/stream/node/factories.d.ts +22 -85
- package/dist/types/modules/stream/node/pipeline.d.ts +4 -15
- package/dist/types/modules/stream/node/utils.d.ts +9 -49
- package/dist/types/modules/stream/node/web.d.ts +18 -0
- package/dist/types/modules/stream/pull-stream.d.ts +2 -2
- package/dist/types/modules/stream/types.d.ts +24 -6
- package/package.json +5 -3
- package/dist/esm/modules/stream/browser/_lazy.js +0 -30
- package/dist/esm/modules/stream/browser/chunk-buffer.js +0 -223
- package/dist/esm/modules/stream/browser/duplex.js +0 -979
- package/dist/esm/modules/stream/browser/helpers.js +0 -44
- package/dist/esm/modules/stream/browser/microtask-context.js +0 -60
- package/dist/esm/modules/stream/browser/passthrough.js +0 -16
- package/dist/esm/modules/stream/browser/pipe-manager.js +0 -161
- package/dist/esm/modules/stream/browser/readable.js +0 -2208
- package/dist/esm/modules/stream/browser/transform.js +0 -1241
- package/dist/esm/modules/stream/browser/writable.js +0 -1316
- package/dist/esm/modules/stream/core/end-args.js +0 -24
- package/dist/esm/modules/stream/node/writable.js +0 -125
- package/dist/esm/modules/stream/utils.base.js +0 -126
- package/dist/esm/modules/stream/utils.browser.js +0 -80
- package/dist/esm/modules/stream/utils.js +0 -81
- package/dist/types/modules/stream/browser/_lazy.d.ts +0 -20
- package/dist/types/modules/stream/browser/chunk-buffer.d.ts +0 -61
- package/dist/types/modules/stream/browser/duplex.d.ts +0 -299
- package/dist/types/modules/stream/browser/helpers.d.ts +0 -13
- package/dist/types/modules/stream/browser/microtask-context.d.ts +0 -44
- package/dist/types/modules/stream/browser/passthrough.d.ts +0 -11
- package/dist/types/modules/stream/browser/pipe-manager.d.ts +0 -38
- package/dist/types/modules/stream/browser/readable.d.ts +0 -379
- package/dist/types/modules/stream/browser/transform.d.ts +0 -314
- package/dist/types/modules/stream/browser/writable.d.ts +0 -238
- package/dist/types/modules/stream/core/end-args.d.ts +0 -20
- package/dist/types/modules/stream/node/writable.d.ts +0 -53
- package/dist/types/modules/stream/utils.base.d.ts +0 -63
- package/dist/types/modules/stream/utils.browser.d.ts +0 -23
- package/dist/types/modules/stream/utils.d.ts +0 -24
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stream kernel - compose algorithm
|
|
3
|
+
*
|
|
4
|
+
* `composeImpl` is a port of Node.js `lib/internal/streams/compose.js`: the
|
|
5
|
+
* stages are connected with `pipelineImpl`, and one Duplex writes into the
|
|
6
|
+
* head and reads from the tail. It backs `Readable.prototype.compose` and the
|
|
7
|
+
* module's `compose()`; the stream classes are passed in by both.
|
|
8
|
+
*/
|
|
9
|
+
import { destroyer } from "./destroy.js";
|
|
10
|
+
import { eos } from "./end-of-stream.js";
|
|
11
|
+
import { createAbortError, errInvalidArgValue, errMissingArgs } from "./errors.js";
|
|
12
|
+
import { pipelineImpl } from "./pipeline-impl.js";
|
|
13
|
+
import { isNodeStream, isReadable, isReadableStream, isTransformStream, isWebStream, isWritable, isWritableStream } from "./stream-utils.js";
|
|
14
|
+
const noop = () => { };
|
|
15
|
+
export function composeImpl(kernel, ...streams) {
|
|
16
|
+
const { Duplex } = kernel;
|
|
17
|
+
if (streams.length === 0) {
|
|
18
|
+
throw errMissingArgs("streams");
|
|
19
|
+
}
|
|
20
|
+
if (streams.length === 1) {
|
|
21
|
+
return Duplex.from(streams[0]);
|
|
22
|
+
}
|
|
23
|
+
const orgStreams = streams.slice();
|
|
24
|
+
if (typeof streams[0] === "function") {
|
|
25
|
+
streams[0] = Duplex.from(streams[0]);
|
|
26
|
+
}
|
|
27
|
+
if (typeof streams[streams.length - 1] === "function") {
|
|
28
|
+
const idx = streams.length - 1;
|
|
29
|
+
streams[idx] = Duplex.from(streams[idx]);
|
|
30
|
+
}
|
|
31
|
+
for (let n = 0; n < streams.length; ++n) {
|
|
32
|
+
if (!isNodeStream(streams[n]) && !isWebStream(streams[n])) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (n < streams.length - 1 &&
|
|
36
|
+
!(isReadable(streams[n]) || isReadableStream(streams[n]) || isTransformStream(streams[n]))) {
|
|
37
|
+
throw errInvalidArgValue(`streams[${n}]`, orgStreams[n], "must be readable");
|
|
38
|
+
}
|
|
39
|
+
if (n > 0 &&
|
|
40
|
+
!(isWritable(streams[n]) || isWritableStream(streams[n]) || isTransformStream(streams[n]))) {
|
|
41
|
+
throw errInvalidArgValue(`streams[${n}]`, orgStreams[n], "must be writable");
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
let ondrain = null;
|
|
45
|
+
let onfinish = null;
|
|
46
|
+
// undefined: running; null: the pipeline settled; a function: destroy waiting on it.
|
|
47
|
+
let onclose;
|
|
48
|
+
function onfinished(err) {
|
|
49
|
+
const cb = onclose;
|
|
50
|
+
onclose = null;
|
|
51
|
+
if (cb) {
|
|
52
|
+
cb(err);
|
|
53
|
+
}
|
|
54
|
+
else if (err) {
|
|
55
|
+
d.destroy(err);
|
|
56
|
+
}
|
|
57
|
+
else if (!readable && !writable) {
|
|
58
|
+
d.destroy();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function finishWrite() {
|
|
62
|
+
if (onfinish) {
|
|
63
|
+
const cb = onfinish;
|
|
64
|
+
onfinish = null;
|
|
65
|
+
cb();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const head = streams[0];
|
|
69
|
+
const tail = pipelineImpl(kernel, streams, onfinished);
|
|
70
|
+
const writable = !!(isWritable(head) || isWritableStream(head) || isTransformStream(head));
|
|
71
|
+
const readable = !!(isReadable(tail) || isReadableStream(tail) || isTransformStream(tail));
|
|
72
|
+
// The Web reader / writer compose takes for itself: released when done,
|
|
73
|
+
// cancelled or aborted when the composed stream is destroyed early.
|
|
74
|
+
let headWriter;
|
|
75
|
+
let tailReader;
|
|
76
|
+
function releaseHeadWriter() {
|
|
77
|
+
if (headWriter) {
|
|
78
|
+
headWriter.releaseLock();
|
|
79
|
+
headWriter = undefined;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function releaseTailReader() {
|
|
83
|
+
if (tailReader) {
|
|
84
|
+
tailReader.releaseLock();
|
|
85
|
+
tailReader = undefined;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/** Stop whatever Web side is still held; resolves once that is done. */
|
|
89
|
+
function abandonWebSides(err) {
|
|
90
|
+
const tasks = [];
|
|
91
|
+
if (tailReader) {
|
|
92
|
+
const reader = tailReader;
|
|
93
|
+
tasks.push(reader
|
|
94
|
+
.cancel(err ?? undefined)
|
|
95
|
+
.catch(noop)
|
|
96
|
+
.then(releaseTailReader));
|
|
97
|
+
}
|
|
98
|
+
if (headWriter) {
|
|
99
|
+
const writer = headWriter;
|
|
100
|
+
tasks.push(writer
|
|
101
|
+
.abort(err ?? undefined)
|
|
102
|
+
.catch(noop)
|
|
103
|
+
.then(releaseHeadWriter));
|
|
104
|
+
}
|
|
105
|
+
return Promise.allSettled(tasks);
|
|
106
|
+
}
|
|
107
|
+
const d = new Duplex({
|
|
108
|
+
writableObjectMode: !!head?.writableObjectMode,
|
|
109
|
+
readableObjectMode: !!tail?.readableObjectMode,
|
|
110
|
+
writable,
|
|
111
|
+
readable
|
|
112
|
+
});
|
|
113
|
+
if (writable) {
|
|
114
|
+
if (isNodeStream(head)) {
|
|
115
|
+
d._write = function (chunk, encoding, callback) {
|
|
116
|
+
if (head.write(chunk, encoding)) {
|
|
117
|
+
callback();
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
ondrain = callback;
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
d._final = function (callback) {
|
|
124
|
+
head.end();
|
|
125
|
+
onfinish = callback;
|
|
126
|
+
};
|
|
127
|
+
head.on("drain", () => {
|
|
128
|
+
if (ondrain) {
|
|
129
|
+
const cb = ondrain;
|
|
130
|
+
ondrain = null;
|
|
131
|
+
cb();
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
const writer = (isTransformStream(head) ? head.writable : head).getWriter();
|
|
137
|
+
headWriter = writer;
|
|
138
|
+
d._write = async function (chunk, _encoding, callback) {
|
|
139
|
+
try {
|
|
140
|
+
await writer.ready;
|
|
141
|
+
writer.write(chunk).catch(() => { });
|
|
142
|
+
callback();
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
callback(err);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
d._final = async function (callback) {
|
|
149
|
+
try {
|
|
150
|
+
await writer.ready;
|
|
151
|
+
writer.close().then(releaseHeadWriter, noop);
|
|
152
|
+
onfinish = callback;
|
|
153
|
+
}
|
|
154
|
+
catch (err) {
|
|
155
|
+
callback(err);
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
// The writable side is finished once the tail has produced everything.
|
|
160
|
+
if (isNodeStream(tail)) {
|
|
161
|
+
eos(tail, finishWrite);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (readable) {
|
|
165
|
+
if (isNodeStream(tail)) {
|
|
166
|
+
d._read = function () {
|
|
167
|
+
tail.resume();
|
|
168
|
+
};
|
|
169
|
+
tail.on("data", (chunk) => {
|
|
170
|
+
if (!d.push(chunk)) {
|
|
171
|
+
tail.pause();
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
tail.on("end", () => {
|
|
175
|
+
d.push(null);
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
const reader = (isTransformStream(tail) ? tail.readable : tail).getReader();
|
|
180
|
+
tailReader = reader;
|
|
181
|
+
d._read = async function () {
|
|
182
|
+
while (true) {
|
|
183
|
+
try {
|
|
184
|
+
const { value, done } = await reader.read();
|
|
185
|
+
if (done) {
|
|
186
|
+
releaseTailReader();
|
|
187
|
+
d.push(null);
|
|
188
|
+
finishWrite();
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
if (!d.push(value)) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
d._destroy = function (err, callback) {
|
|
203
|
+
if (!err && onclose !== null) {
|
|
204
|
+
err = createAbortError();
|
|
205
|
+
}
|
|
206
|
+
ondrain = null;
|
|
207
|
+
onfinish = null;
|
|
208
|
+
if (isNodeStream(tail)) {
|
|
209
|
+
destroyer(tail, err);
|
|
210
|
+
}
|
|
211
|
+
// Cancelling the tail's reader (or aborting the head's writer) is also
|
|
212
|
+
// what lets the inner pipeline finish, so wait for it either way.
|
|
213
|
+
const abandoned = abandonWebSides(err);
|
|
214
|
+
const finishDestroy = (e) => {
|
|
215
|
+
abandoned.then(() => callback(e));
|
|
216
|
+
};
|
|
217
|
+
if (onclose === null) {
|
|
218
|
+
finishDestroy(err);
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
onclose = finishDestroy;
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
return d;
|
|
225
|
+
}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stream kernel - destroy / construct lifecycle
|
|
3
|
+
*
|
|
4
|
+
* Port of Node.js `lib/internal/streams/destroy.js`. Every stream class shares
|
|
5
|
+
* these functions, so a Duplex is destroyed once — both of its states are
|
|
6
|
+
* marked in the same call, and `'error'` / `'close'` are emitted once.
|
|
7
|
+
*/
|
|
8
|
+
import { aggregateTwoErrors, createAbortError, errMultipleCallback } from "./errors.js";
|
|
9
|
+
import { nextTick } from "./state.js";
|
|
10
|
+
import { isDestroyed, isFinished, kIsDestroyed } from "./stream-utils.js";
|
|
11
|
+
const kDestroy = Symbol("kDestroy");
|
|
12
|
+
const kConstruct = Symbol("kConstruct");
|
|
13
|
+
function checkError(err, w, r) {
|
|
14
|
+
if (err) {
|
|
15
|
+
if (w && !w.errored) {
|
|
16
|
+
w.errored = err;
|
|
17
|
+
}
|
|
18
|
+
if (r && !r.errored) {
|
|
19
|
+
r.errored = err;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export function destroy(err, cb) {
|
|
24
|
+
const r = this._readableState;
|
|
25
|
+
const w = this._writableState;
|
|
26
|
+
const s = (w || r);
|
|
27
|
+
if (w?.destroyed || r?.destroyed) {
|
|
28
|
+
if (typeof cb === "function") {
|
|
29
|
+
cb();
|
|
30
|
+
}
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
// Mark destroyed before any callback runs so re-entrant destroy() is a no-op.
|
|
34
|
+
checkError(err, w, r);
|
|
35
|
+
if (w) {
|
|
36
|
+
w.destroyed = true;
|
|
37
|
+
}
|
|
38
|
+
if (r) {
|
|
39
|
+
r.destroyed = true;
|
|
40
|
+
}
|
|
41
|
+
if (!s.constructed) {
|
|
42
|
+
this.once(kDestroy, (er) => {
|
|
43
|
+
callDestroy(this, aggregateTwoErrors(er, err), cb);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
callDestroy(this, err, cb);
|
|
48
|
+
}
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
function callDestroy(self, err, cb) {
|
|
52
|
+
let called = false;
|
|
53
|
+
const onDestroy = (err) => {
|
|
54
|
+
if (called) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
called = true;
|
|
58
|
+
const r = self._readableState;
|
|
59
|
+
const w = self._writableState;
|
|
60
|
+
checkError(err, w, r);
|
|
61
|
+
if (w) {
|
|
62
|
+
w.closed = true;
|
|
63
|
+
}
|
|
64
|
+
if (r) {
|
|
65
|
+
r.closed = true;
|
|
66
|
+
}
|
|
67
|
+
if (typeof cb === "function") {
|
|
68
|
+
cb(err);
|
|
69
|
+
}
|
|
70
|
+
if (err) {
|
|
71
|
+
nextTick(() => emitErrorCloseNT(self, err));
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
nextTick(() => emitCloseNT(self));
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
try {
|
|
78
|
+
self._destroy(err || null, onDestroy);
|
|
79
|
+
}
|
|
80
|
+
catch (e) {
|
|
81
|
+
onDestroy(e);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function emitErrorCloseNT(self, err) {
|
|
85
|
+
emitErrorNT(self, err);
|
|
86
|
+
emitCloseNT(self);
|
|
87
|
+
}
|
|
88
|
+
function emitCloseNT(self) {
|
|
89
|
+
const r = self._readableState;
|
|
90
|
+
const w = self._writableState;
|
|
91
|
+
if (w) {
|
|
92
|
+
w.closeEmitted = true;
|
|
93
|
+
}
|
|
94
|
+
if (r) {
|
|
95
|
+
r.closeEmitted = true;
|
|
96
|
+
}
|
|
97
|
+
if (w?.emitClose || r?.emitClose) {
|
|
98
|
+
self.emit("close");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function emitErrorNT(self, err) {
|
|
102
|
+
const r = self._readableState;
|
|
103
|
+
const w = self._writableState;
|
|
104
|
+
if (w?.errorEmitted || r?.errorEmitted) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (w) {
|
|
108
|
+
w.errorEmitted = true;
|
|
109
|
+
}
|
|
110
|
+
if (r) {
|
|
111
|
+
r.errorEmitted = true;
|
|
112
|
+
}
|
|
113
|
+
self.emit("error", err);
|
|
114
|
+
}
|
|
115
|
+
export function undestroy() {
|
|
116
|
+
const r = this._readableState;
|
|
117
|
+
const w = this._writableState;
|
|
118
|
+
if (r) {
|
|
119
|
+
r.constructed = true;
|
|
120
|
+
r.closed = false;
|
|
121
|
+
r.closeEmitted = false;
|
|
122
|
+
r.destroyed = false;
|
|
123
|
+
r.errored = null;
|
|
124
|
+
r.errorEmitted = false;
|
|
125
|
+
r.reading = false;
|
|
126
|
+
r.ended = r.readable === false;
|
|
127
|
+
r.endEmitted = r.readable === false;
|
|
128
|
+
}
|
|
129
|
+
if (w) {
|
|
130
|
+
w.constructed = true;
|
|
131
|
+
w.destroyed = false;
|
|
132
|
+
w.closed = false;
|
|
133
|
+
w.closeEmitted = false;
|
|
134
|
+
w.errored = null;
|
|
135
|
+
w.errorEmitted = false;
|
|
136
|
+
w.finalCalled = false;
|
|
137
|
+
w.prefinished = false;
|
|
138
|
+
w.ended = w.writable === false;
|
|
139
|
+
w.ending = w.writable === false;
|
|
140
|
+
w.finished = w.writable === false;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Report an error the way the stream is configured to: destroy it when
|
|
145
|
+
* `autoDestroy` is on, otherwise record and emit it without tearing down.
|
|
146
|
+
*/
|
|
147
|
+
export function errorOrDestroy(stream, err, sync) {
|
|
148
|
+
const r = stream._readableState;
|
|
149
|
+
const w = stream._writableState;
|
|
150
|
+
if (w?.destroyed || r?.destroyed) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if (r?.autoDestroy || w?.autoDestroy) {
|
|
154
|
+
stream.destroy(err);
|
|
155
|
+
}
|
|
156
|
+
else if (err) {
|
|
157
|
+
if (w && !w.errored) {
|
|
158
|
+
w.errored = err;
|
|
159
|
+
}
|
|
160
|
+
if (r && !r.errored) {
|
|
161
|
+
r.errored = err;
|
|
162
|
+
}
|
|
163
|
+
if (sync) {
|
|
164
|
+
nextTick(() => emitErrorNT(stream, err));
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
emitErrorNT(stream, err);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
export function construct(stream, cb) {
|
|
172
|
+
if (typeof stream._construct !== "function") {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const r = stream._readableState;
|
|
176
|
+
const w = stream._writableState;
|
|
177
|
+
if (r) {
|
|
178
|
+
r.constructed = false;
|
|
179
|
+
}
|
|
180
|
+
if (w) {
|
|
181
|
+
w.constructed = false;
|
|
182
|
+
}
|
|
183
|
+
stream.once(kConstruct, cb);
|
|
184
|
+
if (stream.listenerCount(kConstruct) > 1) {
|
|
185
|
+
// Duplex: the second side registers its callback on the same run.
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
nextTick(() => constructNT(stream));
|
|
189
|
+
}
|
|
190
|
+
function constructNT(stream) {
|
|
191
|
+
let called = false;
|
|
192
|
+
const onConstruct = (err) => {
|
|
193
|
+
if (called) {
|
|
194
|
+
errorOrDestroy(stream, err ?? errMultipleCallback());
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
called = true;
|
|
198
|
+
const r = stream._readableState;
|
|
199
|
+
const w = stream._writableState;
|
|
200
|
+
const s = (w || r);
|
|
201
|
+
if (r) {
|
|
202
|
+
r.constructed = true;
|
|
203
|
+
}
|
|
204
|
+
if (w) {
|
|
205
|
+
w.constructed = true;
|
|
206
|
+
}
|
|
207
|
+
if (s.destroyed) {
|
|
208
|
+
stream.emit(kDestroy, err);
|
|
209
|
+
}
|
|
210
|
+
else if (err) {
|
|
211
|
+
errorOrDestroy(stream, err, true);
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
stream.emit(kConstruct);
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
try {
|
|
218
|
+
stream._construct(err => {
|
|
219
|
+
nextTick(() => onConstruct(err));
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
catch (err) {
|
|
223
|
+
nextTick(() => onConstruct(err));
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Tear down any stream-like object. A stream that has not finished cleanly is
|
|
228
|
+
* destroyed with an AbortError so whoever is waiting on it learns why.
|
|
229
|
+
*/
|
|
230
|
+
export function destroyer(stream, err) {
|
|
231
|
+
if (!stream || isDestroyed(stream)) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
if (!err && !isFinished(stream)) {
|
|
235
|
+
err = createAbortError();
|
|
236
|
+
}
|
|
237
|
+
if (typeof stream.destroy === "function") {
|
|
238
|
+
stream.destroy(err);
|
|
239
|
+
}
|
|
240
|
+
else if (typeof stream.close === "function") {
|
|
241
|
+
stream.close();
|
|
242
|
+
}
|
|
243
|
+
else if (err) {
|
|
244
|
+
nextTick(() => {
|
|
245
|
+
stream.emit("error", err);
|
|
246
|
+
nextTick(() => stream.emit("close"));
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
nextTick(() => stream.emit("close"));
|
|
251
|
+
}
|
|
252
|
+
if (!stream.destroyed) {
|
|
253
|
+
stream[kIsDestroyed] = true;
|
|
254
|
+
}
|
|
255
|
+
}
|