add-abort-signal.js 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. 'use strict'
  2. const { SymbolDispose } = require('../../ours/primordials')
  3. const { AbortError, codes } = require('../../ours/errors')
  4. const { isNodeStream, isWebStream, kControllerErrorFunction } = require('./utils')
  5. const eos = require('./end-of-stream')
  6. const { ERR_INVALID_ARG_TYPE } = codes
  7. let addAbortListener
  8. // This method is inlined here for readable-stream
  9. // It also does not allow for signal to not exist on the stream
  10. // https://github.com/nodejs/node/pull/36061#discussion_r533718029
  11. const validateAbortSignal = (signal, name) => {
  12. if (typeof signal !== 'object' || !('aborted' in signal)) {
  13. throw new ERR_INVALID_ARG_TYPE(name, 'AbortSignal', signal)
  14. }
  15. }
  16. module.exports.addAbortSignal = function addAbortSignal(signal, stream) {
  17. validateAbortSignal(signal, 'signal')
  18. if (!isNodeStream(stream) && !isWebStream(stream)) {
  19. throw new ERR_INVALID_ARG_TYPE('stream', ['ReadableStream', 'WritableStream', 'Stream'], stream)
  20. }
  21. return module.exports.addAbortSignalNoValidate(signal, stream)
  22. }
  23. module.exports.addAbortSignalNoValidate = function (signal, stream) {
  24. if (typeof signal !== 'object' || !('aborted' in signal)) {
  25. return stream
  26. }
  27. const onAbort = isNodeStream(stream)
  28. ? () => {
  29. stream.destroy(
  30. new AbortError(undefined, {
  31. cause: signal.reason
  32. })
  33. )
  34. }
  35. : () => {
  36. stream[kControllerErrorFunction](
  37. new AbortError(undefined, {
  38. cause: signal.reason
  39. })
  40. )
  41. }
  42. if (signal.aborted) {
  43. onAbort()
  44. } else {
  45. addAbortListener = addAbortListener || require('../../ours/util').addAbortListener
  46. const disposable = addAbortListener(signal, onAbort)
  47. eos(stream, disposable[SymbolDispose])
  48. }
  49. return stream
  50. }