From 6d17ad692e45493b4f9257ae2b1d719d5b32be1a Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Mon, 7 Oct 2019 14:14:52 +0200 Subject: [PATCH 1/3] Move isAbortSignal to separate file --- src/lib/abort-signal.ts | 16 ++++++++++++++++ src/lib/readable-stream.ts | 16 +--------------- src/lib/readable-stream/pipe.ts | 11 ++++------- 3 files changed, 21 insertions(+), 22 deletions(-) create mode 100644 src/lib/abort-signal.ts diff --git a/src/lib/abort-signal.ts b/src/lib/abort-signal.ts new file mode 100644 index 0000000..f502e22 --- /dev/null +++ b/src/lib/abort-signal.ts @@ -0,0 +1,16 @@ +/// + +export function isAbortSignal(value: any): value is AbortSignal { + if (typeof value !== 'object' || value === null) { + return false; + } + + // Use the brand check to distinguish a real AbortSignal from a fake one. + const aborted = Object.getOwnPropertyDescriptor(AbortSignal.prototype, 'aborted')!.get!; + try { + aborted.call(value); + return true; + } catch (e) { + return false; + } +} diff --git a/src/lib/readable-stream.ts b/src/lib/readable-stream.ts index 9db7472..5533acd 100644 --- a/src/lib/readable-stream.ts +++ b/src/lib/readable-stream.ts @@ -59,6 +59,7 @@ import { UnderlyingSource } from './readable-stream/underlying-source'; import { noop } from '../utils'; +import { isAbortSignal } from './abort-signal'; export type ReadableByteStream = ReadableStream; @@ -439,21 +440,6 @@ export { // Helper functions for the ReadableStream. -export function isAbortSignal(value: any): value is AbortSignal { - if (typeof value !== 'object' || value === null) { - return false; - } - - // Use the brand check to distinguish a real AbortSignal from a fake one. - const aborted = Object.getOwnPropertyDescriptor(AbortSignal.prototype, 'aborted')!.get!; - try { - aborted.call(value); - return true; - } catch (e) { - return false; - } -} - function streamBrandCheckException(name: string): TypeError { return new TypeError(`ReadableStream.prototype.${name} can only be used on a ReadableStream`); } diff --git a/src/lib/readable-stream/pipe.ts b/src/lib/readable-stream/pipe.ts index be01299..516b4fc 100644 --- a/src/lib/readable-stream/pipe.ts +++ b/src/lib/readable-stream/pipe.ts @@ -1,10 +1,6 @@ -import { - isAbortSignal, - IsReadableStream, - IsReadableStreamLocked, - ReadableStream, - ReadableStreamCancel -} from '../readable-stream'; +/// + +import { IsReadableStream, IsReadableStreamLocked, ReadableStream, ReadableStreamCancel } from '../readable-stream'; import { AcquireReadableStreamDefaultReader, ReadableStreamDefaultReaderRead } from './default-reader'; import { ReadableStreamReaderGenericRelease } from './generic-reader'; import { @@ -29,6 +25,7 @@ import { uponRejection } from '../helpers'; import { noop } from '../../utils'; +import { isAbortSignal } from '../abort-signal'; export function ReadableStreamPipeTo(source: ReadableStream, dest: WritableStream, From 71c9d725cb0fc6f8e3d4080dfa33f17e0ddb9150 Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Mon, 7 Oct 2019 14:56:08 +0200 Subject: [PATCH 2/3] Accept polyfilled abort signals --- etc/web-streams-polyfill.api.md | 10 ++++++++++ src/lib/abort-signal.ts | 28 ++++++++++++++++++++-------- src/lib/readable-stream.ts | 4 +--- src/lib/readable-stream/pipe.ts | 4 +--- src/ponyfill.ts | 5 ++++- test/types/readable-stream.ts | 2 ++ 6 files changed, 38 insertions(+), 15 deletions(-) diff --git a/etc/web-streams-polyfill.api.md b/etc/web-streams-polyfill.api.md index c98d498..87142bc 100644 --- a/etc/web-streams-polyfill.api.md +++ b/etc/web-streams-polyfill.api.md @@ -4,6 +4,16 @@ ```ts +// @public +export interface AbortSignal { + // (undocumented) + readonly aborted: boolean; + // (undocumented) + addEventListener(type: 'abort', listener: () => void): void; + // (undocumented) + removeEventListener(type: 'abort', listener: () => void): void; +} + // @public (undocumented) export class ByteLengthQueuingStrategy implements QueuingStrategy { constructor({ highWaterMark }: { diff --git a/src/lib/abort-signal.ts b/src/lib/abort-signal.ts index f502e22..18cf4b8 100644 --- a/src/lib/abort-signal.ts +++ b/src/lib/abort-signal.ts @@ -1,16 +1,28 @@ -/// +/** + * A signal object that allows you to communicate with a request and abort it if required + * via its associated `AbortController` object. + * + * @remarks + * This interface is compatible with the `AbortSignal` interface defined in TypeScript's DOM types. + * It is redefined here, so it can be polyfilled without a DOM, for example with + * {@link https://www.npmjs.com/package/abortcontroller-polyfill | abortcontroller-polyfill} in a Node environment. + */ +export interface AbortSignal { + readonly aborted: boolean; -export function isAbortSignal(value: any): value is AbortSignal { + addEventListener(type: 'abort', listener: () => void): void; + + removeEventListener(type: 'abort', listener: () => void): void; +} + +export function isAbortSignal(value: unknown): value is AbortSignal { if (typeof value !== 'object' || value === null) { return false; } - - // Use the brand check to distinguish a real AbortSignal from a fake one. - const aborted = Object.getOwnPropertyDescriptor(AbortSignal.prototype, 'aborted')!.get!; try { - aborted.call(value); - return true; - } catch (e) { + return typeof (value as AbortSignal).aborted === 'boolean'; + } catch { + // AbortSignal.prototype.aborted throws if its brand check fails return false; } } diff --git a/src/lib/readable-stream.ts b/src/lib/readable-stream.ts index 5533acd..4071c26 100644 --- a/src/lib/readable-stream.ts +++ b/src/lib/readable-stream.ts @@ -1,5 +1,3 @@ -/// - import assert from '../stub/assert'; import { createArrayFromList, @@ -59,7 +57,7 @@ import { UnderlyingSource } from './readable-stream/underlying-source'; import { noop } from '../utils'; -import { isAbortSignal } from './abort-signal'; +import { AbortSignal, isAbortSignal } from './abort-signal'; export type ReadableByteStream = ReadableStream; diff --git a/src/lib/readable-stream/pipe.ts b/src/lib/readable-stream/pipe.ts index 516b4fc..dd589bb 100644 --- a/src/lib/readable-stream/pipe.ts +++ b/src/lib/readable-stream/pipe.ts @@ -1,5 +1,3 @@ -/// - import { IsReadableStream, IsReadableStreamLocked, ReadableStream, ReadableStreamCancel } from '../readable-stream'; import { AcquireReadableStreamDefaultReader, ReadableStreamDefaultReaderRead } from './default-reader'; import { ReadableStreamReaderGenericRelease } from './generic-reader'; @@ -25,7 +23,7 @@ import { uponRejection } from '../helpers'; import { noop } from '../../utils'; -import { isAbortSignal } from '../abort-signal'; +import { AbortSignal, isAbortSignal } from '../abort-signal'; export function ReadableStreamPipeTo(source: ReadableStream, dest: WritableStream, diff --git a/src/ponyfill.ts b/src/ponyfill.ts index 75f0172..96c8691 100644 --- a/src/ponyfill.ts +++ b/src/ponyfill.ts @@ -21,6 +21,7 @@ import { QueuingStrategy } from './lib/queuing-strategy'; import ByteLengthQueuingStrategy from './lib/byte-length-queuing-strategy'; import CountQueuingStrategy from './lib/count-queuing-strategy'; import { Transformer, TransformStream, TransformStreamDefaultControllerType } from './lib/transform-stream'; +import { AbortSignal } from './lib/abort-signal'; export { ReadableStream, @@ -46,5 +47,7 @@ export { TransformStream, Transformer, - TransformStreamDefaultControllerType as TransformStreamDefaultController + TransformStreamDefaultControllerType as TransformStreamDefaultController, + + AbortSignal }; diff --git a/test/types/readable-stream.ts b/test/types/readable-stream.ts index 4672ee8..65f583e 100644 --- a/test/types/readable-stream.ts +++ b/test/types/readable-stream.ts @@ -108,6 +108,8 @@ const asyncIteratorReturnResult: Promise> = asyncIterator.re } })(); +const abortSignal: polyfill.AbortSignal = new AbortController().signal; + // Compatibility with stream types from DOM const domUnderlyingSource: UnderlyingSource = underlyingSource; const domUnderlyingByteSource: UnderlyingByteSource = underlyingByteSource; From 7d11d9849ec2c735c16329e630fdf7341f07724a Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Mon, 7 Oct 2019 15:14:04 +0200 Subject: [PATCH 3/3] Update changelog [skip ci] --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4de048c..02e5163 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ ## Unreleased * 👓 Align with [spec version `ae5e0cb`](https://github.com/whatwg/streams/tree/ae5e0cb41e9f72cdd97f3a6d47bc674c1f4049d1/) ([#33](https://github.com/MattiasBuelens/web-streams-polyfill/pull/33)) +* 💅 Accept polyfilled `AbortSignal`s. ([#36](https://github.com/MattiasBuelens/web-streams-polyfill/pull/36)) ## v2.0.4 (2019-08-01)