|
23 | 23 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE |
24 | 24 | // USE OR OTHER DEALINGS IN THE SOFTWARE. |
25 | 25 |
|
26 | | -import { validateAbortSignal } from 'node-internal:validators'; |
27 | | -import { isNodeStream } from 'node-internal:streams_util'; |
28 | | -import { eos } from 'node-internal:streams_end_of_stream'; |
29 | 26 | import { |
30 | 27 | AbortError, |
31 | 28 | ERR_INVALID_ARG_TYPE, |
32 | 29 | } from 'node-internal:internal_errors'; |
33 | | -import { addAbortListener } from 'node-internal:events'; |
34 | 30 |
|
| 31 | +import { |
| 32 | + isNodeStream, |
| 33 | + isWebStream, |
| 34 | + kControllerErrorFunction, |
| 35 | +} from 'node-internal:streams_util'; |
| 36 | + |
| 37 | +import { eos } from 'node-internal:streams_end_of_stream'; |
35 | 38 | import type { Readable } from 'node-internal:streams_readable'; |
36 | 39 | import type { Writable } from 'node-internal:streams_writable'; |
37 | 40 | import type { Transform } from 'node-internal:streams_transform'; |
| 41 | +import { addAbortListener } from 'node-internal:events'; |
| 42 | + |
| 43 | +// This method is inlined here for readable-stream |
| 44 | +// It also does not allow for signal to not exist on the stream |
| 45 | +// https://github.com/nodejs/node/pull/36061#discussion_r533718029 |
| 46 | +function validateAbortSignal( |
| 47 | + signal: unknown, |
| 48 | + name: string |
| 49 | +): asserts signal is AbortSignal { |
| 50 | + if (signal == null || typeof signal !== 'object' || !('aborted' in signal)) { |
| 51 | + throw new ERR_INVALID_ARG_TYPE(name, 'AbortSignal', signal); |
| 52 | + } |
| 53 | +} |
38 | 54 |
|
39 | | -type NodeStream = Readable | Writable | Transform; |
| 55 | +type StreamType = |
| 56 | + | Readable |
| 57 | + | Writable |
| 58 | + | Transform |
| 59 | + | ReadableStream |
| 60 | + | WritableStream; |
40 | 61 |
|
41 | | -export function addAbortSignal<T extends { destroy: (err: Error) => void }>( |
| 62 | +export function addAbortSignal<T extends StreamType>( |
42 | 63 | signal: unknown, |
43 | 64 | stream: T |
44 | 65 | ): T { |
45 | 66 | validateAbortSignal(signal, 'signal'); |
46 | | - if (!isNodeStream(stream)) { |
47 | | - throw new ERR_INVALID_ARG_TYPE('stream', 'stream.Stream', stream); |
48 | | - } |
49 | | - const onAbort = (): void => { |
50 | | - stream.destroy( |
51 | | - new AbortError(undefined, { |
52 | | - cause: signal.reason, |
53 | | - }) |
| 67 | + if (!isNodeStream(stream) && !isWebStream(stream)) { |
| 68 | + throw new ERR_INVALID_ARG_TYPE( |
| 69 | + 'stream', |
| 70 | + ['ReadableStream', 'WritableStream', 'Stream'], |
| 71 | + stream |
54 | 72 | ); |
55 | | - }; |
| 73 | + } |
| 74 | + return addAbortSignalNoValidate(signal, stream); |
| 75 | +} |
| 76 | + |
| 77 | +export function addAbortSignalNoValidate<T extends StreamType>( |
| 78 | + signal: AbortSignal | null | undefined, |
| 79 | + stream: T |
| 80 | +): T { |
| 81 | + if (signal == null || typeof signal !== 'object' || !('aborted' in signal)) { |
| 82 | + return stream; |
| 83 | + } |
| 84 | + const onAbort = isNodeStream(stream) |
| 85 | + ? (): void => { |
| 86 | + stream.destroy(new AbortError(undefined, { cause: signal.reason })); |
| 87 | + } |
| 88 | + : (): void => { |
| 89 | + ( |
| 90 | + stream as ReadableStream & { |
| 91 | + [kControllerErrorFunction]: (err: Error) => void; |
| 92 | + } |
| 93 | + )[kControllerErrorFunction]( |
| 94 | + new AbortError(undefined, { cause: signal.reason }) |
| 95 | + ); |
| 96 | + }; |
56 | 97 | if (signal.aborted) { |
57 | 98 | onAbort(); |
58 | 99 | } else { |
59 | 100 | const disposable = addAbortListener(signal, onAbort); |
60 | | - eos(stream as NodeStream, disposable[Symbol.dispose]); |
| 101 | + eos( |
| 102 | + stream as Readable | Writable | Transform, |
| 103 | + disposable[Symbol.dispose] as () => void |
| 104 | + ); |
61 | 105 | } |
62 | 106 | return stream; |
63 | 107 | } |
0 commit comments