From c91da1222b1a57a38aad4bca7af7fe88d8ef2476 Mon Sep 17 00:00:00 2001 From: Leo Kettmeir Date: Mon, 8 Nov 2021 12:54:24 +0100 Subject: [PATCH] feat(ext/web): WritableStreamDefaultController.signal (#12654) --- ext/web/06_streams.js | 22 +++++++++++++++++----- ext/web/lib.deno_web.d.ts | 1 + tools/wpt/expectation.json | 34 ++++------------------------------ 3 files changed, 22 insertions(+), 35 deletions(-) diff --git a/ext/web/06_streams.js b/ext/web/06_streams.js index d3e8e97d41..15f51ca7a4 100644 --- a/ext/web/06_streams.js +++ b/ext/web/06_streams.js @@ -9,7 +9,8 @@ ((window) => { const webidl = window.__bootstrap.webidl; - // TODO(lucacasonato): get AbortSignal from __bootstrap. + const { add, remove, signalAbort, newSignal } = + window.__bootstrap.abortSignal; const { ArrayBuffer, ArrayBufferIsView, @@ -286,6 +287,7 @@ const _readRequests = Symbol("[[readRequests]]"); const _readIntoRequests = Symbol("[[readIntoRequests]]"); const _readyPromise = Symbol("[[readyPromise]]"); + const _signal = Symbol("[[signal]]"); const _started = Symbol("[[started]]"); const _state = Symbol("[[state]]"); const _storedError = Symbol("[[storedError]]"); @@ -1902,8 +1904,7 @@ abortAlgorithm(); return promise.promise; } - // TODO(lucacasonato): use the internal API to listen for abort. - signal.addEventListener("abort", abortAlgorithm); + signal[add](abortAlgorithm); } function pipeLoop() { @@ -2107,8 +2108,7 @@ readableStreamReaderGenericRelease(reader); if (signal !== undefined) { - // TODO(lucacasonato): use the internal API to remove the listener. - signal.removeEventListener("abort", abortAlgorithm); + signal[remove](abortAlgorithm); } if (isError) { promise.reject(error); @@ -2985,6 +2985,7 @@ controller[_stream] = stream; stream[_controller] = controller; resetQueue(controller); + controller[_signal] = newSignal(); controller[_started] = false; controller[_strategySizeAlgorithm] = sizeAlgorithm; controller[_strategyHWM] = highWaterMark; @@ -3342,6 +3343,10 @@ if (state === "closed" || state === "errored") { return resolvePromiseWith(undefined); } + stream[_controller][_signal][signalAbort](); + if (state === "closed" || state === "errored") { + return resolvePromiseWith(undefined); + } if (stream[_pendingAbortRequest] !== undefined) { return stream[_pendingAbortRequest].deferred.promise; } @@ -5421,6 +5426,13 @@ [_stream]; /** @type {(chunk: W, controller: this) => Promise} */ [_writeAlgorithm]; + /** @type {AbortSignal} */ + [_signal]; + + get signal() { + webidl.assertBranded(this, WritableStreamDefaultController); + return this[_signal]; + } constructor() { webidl.illegalConstructor(); diff --git a/ext/web/lib.deno_web.d.ts b/ext/web/lib.deno_web.d.ts index 29e83ae1a2..8440045b82 100644 --- a/ext/web/lib.deno_web.d.ts +++ b/ext/web/lib.deno_web.d.ts @@ -635,6 +635,7 @@ declare var WritableStream: { * sink is given a corresponding WritableStreamDefaultController instance to * manipulate. */ interface WritableStreamDefaultController { + signal: AbortSignal; error(error?: any): void; } diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json index 8e3e61b51c..95032263a4 100644 --- a/tools/wpt/expectation.json +++ b/tools/wpt/expectation.json @@ -6056,18 +6056,8 @@ "window-worker-timeOrigin.window.html": false }, "streams": { - "idlharness.any.html": [ - "WritableStreamDefaultController interface: attribute abortReason", - "WritableStreamDefaultController interface: attribute signal", - "WritableStreamDefaultController interface: self.writableStreamDefaultController must inherit property \"abortReason\" with the proper type", - "WritableStreamDefaultController interface: self.writableStreamDefaultController must inherit property \"signal\" with the proper type" - ], - "idlharness.any.worker.html": [ - "WritableStreamDefaultController interface: attribute abortReason", - "WritableStreamDefaultController interface: attribute signal", - "WritableStreamDefaultController interface: self.writableStreamDefaultController must inherit property \"abortReason\" with the proper type", - "WritableStreamDefaultController interface: self.writableStreamDefaultController must inherit property \"signal\" with the proper type" - ], + "idlharness.any.html": true, + "idlharness.any.worker.html": true, "piping": { "abort.any.html": true, "abort.any.worker.html": true, @@ -6169,24 +6159,8 @@ "terminate.any.worker.html": true }, "writable-streams": { - "aborting.any.html": [ - "WritableStreamDefaultController.signal", - "the abort signal is signalled synchronously - write", - "the abort signal is signalled synchronously - close", - "the abort signal is not signalled on error", - "the abort signal is not signalled on write failure", - "the abort signal is not signalled on close failure", - "recursive abort() call" - ], - "aborting.any.worker.html": [ - "WritableStreamDefaultController.signal", - "the abort signal is signalled synchronously - write", - "the abort signal is signalled synchronously - close", - "the abort signal is not signalled on error", - "the abort signal is not signalled on write failure", - "the abort signal is not signalled on close failure", - "recursive abort() call" - ], + "aborting.any.html": true, + "aborting.any.worker.html": true, "bad-strategies.any.html": true, "bad-strategies.any.worker.html": true, "bad-underlying-sinks.any.html": true,