From 81108027bbfb3fc079894c74a5b99fa75259f117 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 3 Nov 2023 10:28:16 +0900 Subject: [PATCH 01/11] tweak --- ext/web/03_abort_signal.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/ext/web/03_abort_signal.js b/ext/web/03_abort_signal.js index 9b5eb51ad42a46..b0d84f16687b66 100644 --- a/ext/web/03_abort_signal.js +++ b/ext/web/03_abort_signal.js @@ -73,9 +73,7 @@ class AbortSignal extends EventTarget { if (this.aborted) { return; } - if (this[abortAlgos] === null) { - this[abortAlgos] = new SafeSet(); - } + this[abortAlgos] ??= new SafeSet(); SetPrototypeAdd(this[abortAlgos], algorithm); } @@ -91,7 +89,7 @@ class AbortSignal extends EventTarget { const event = new Event("abort"); setIsTrusted(event, true); - this.dispatchEvent(event); + super.dispatchEvent(event); if (algos !== null) { for (const algorithm of new SafeSetIterator(algos)) { algorithm(); @@ -104,7 +102,7 @@ class AbortSignal extends EventTarget { } constructor(key = null) { - if (key != illegalConstructorKey) { + if (key !== illegalConstructorKey) { throw new TypeError("Illegal constructor."); } super(); From a53d5dd28e30c7b02ec3d2c6a213935dd03d61f7 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 3 Nov 2023 16:47:23 +0900 Subject: [PATCH 02/11] feat: add `AbortSignal.any` --- ext/web/03_abort_signal.js | 106 ++++++++++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) diff --git a/ext/web/03_abort_signal.js b/ext/web/03_abort_signal.js index b0d84f16687b66..49ba3aa75da151 100644 --- a/ext/web/03_abort_signal.js +++ b/ext/web/03_abort_signal.js @@ -4,6 +4,7 @@ /// import * as webidl from "ext:deno_webidl/00_webidl.js"; +import { assert } from "ext:deno_web/00_infra.js"; import { defineEventHandler, Event, @@ -13,27 +14,115 @@ import { } from "ext:deno_web/02_event.js"; const primordials = globalThis.__bootstrap.primordials; const { + ArrayPrototypePush, SafeArrayIterator, SafeSet, SafeSetIterator, + SafeWeakRef, + SafeWeakSet, SetPrototypeAdd, SetPrototypeDelete, Symbol, TypeError, + WeakRefPrototypeDeref, + WeakSetPrototypeAdd, + WeakSetPrototypeHas, } = primordials; import { refTimer, setTimeout, unrefTimer } from "ext:deno_web/02_timers.js"; +// Since WeakSet is not a iterable, WeakRefSet class is provided to store and +// iterate objects. +// To create an AsyncIterable using GeneratorFunction in the internal code, +// there are many primordial considerations, so we simply implement the +// toArray method. +class WeakRefSet { + #weakSet = new SafeWeakSet(); + #refSet = new SafeSet(); + + add(value) { + if (WeakSetPrototypeHas(this.#weakSet, value)) { + return; + } + const ref = new SafeWeakRef(value); + WeakSetPrototypeAdd(this.#weakSet, value); + SetPrototypeAdd(this.#refSet, ref); + } + + has(value) { + return WeakSetPrototypeHas(this.#weakSet, value); + } + + toArray() { + const arr = []; + for (const ref of new SafeSetIterator(this.#refSet)) { + const value = WeakRefPrototypeDeref(ref); + if (value !== undefined) { + ArrayPrototypePush(value); + } + } + return arr; + } +} + const add = Symbol("[[add]]"); const signalAbort = Symbol("[[signalAbort]]"); const remove = Symbol("[[remove]]"); const abortReason = Symbol("[[abortReason]]"); const abortAlgos = Symbol("[[abortAlgos]]"); +const dependent = Symbol("[[dependent]]"); +const sourceSignals = Symbol("[[sourceSignals]]"); +const dependentSignals = Symbol("[[dependentSignals]]"); const signal = Symbol("[[signal]]"); const timerId = Symbol("[[timerId]]"); const illegalConstructorKey = Symbol("illegalConstructorKey"); class AbortSignal extends EventTarget { + static any(signals) { + const prefix = "Failed to call 'AbortSignal.any'"; + webidl.requiredArguments(arguments.length, 1, prefix); + signals = webidl.converters["sequence"]( + signals, + prefix, + "Argument 1", + ); + + const resultSignal = new AbortSignal(illegalConstructorKey); + for (let i = 0; i < signals.length; ++i) { + const signal = signals[i]; + if (signal[abortReason] !== undefined) { + resultSignal[abortReason] = signal[abortReason]; + return resultSignal; + } + } + + resultSignal[dependent] = true; + resultSignal[sourceSignals] = new WeakRefSet(); + for (let i = 0; i < signals.length; ++i) { + const signal = signals[i]; + if (!signal[dependent]) { + signal[dependentSignals] ??= new WeakRefSet(); + resultSignal[sourceSignals].add(signal); + signal[dependentSignals].add(resultSignal); + } else { + const sourceSignalArray = signal[sourceSignals].toArray(); + for (let j = 0; j < sourceSignalArray.length; ++j) { + const sourceSignal = sourceSignalArray[j]; + assert(sourceSignal[abortReason] === undefined); + assert(!sourceSignal[dependent]); + + if (resultSignal[sourceSignals].has(sourceSignal)) { + continue; + } + resultSignal[sourceSignals].add(sourceSignal); + sourceSignal[dependentSignals].add(resultSignal); + } + } + } + + return resultSignal; + } + static abort(reason = undefined) { if (reason !== undefined) { reason = webidl.converters.any(reason); @@ -95,6 +184,15 @@ class AbortSignal extends EventTarget { algorithm(); } } + + const signals = this[dependentSignals]; + if (signals !== null) { + const signalArray = signals.toArray(); + for (let i = 0; i < signalArray; ++i) { + const signal = signalArray[i]; + signal[signalAbort](reason); + } + } } [remove](algorithm) { @@ -108,6 +206,9 @@ class AbortSignal extends EventTarget { super(); this[abortReason] = undefined; this[abortAlgos] = null; + this[dependent] = false; + this[sourceSignals] = null; + this[dependentSignals] = null; this[timerId] = null; this[webidl.brand] = webidl.brand; } @@ -174,10 +275,13 @@ class AbortController { webidl.configureInterface(AbortController); const AbortControllerPrototype = AbortController.prototype; -webidl.converters["AbortSignal"] = webidl.createInterfaceConverter( +webidl.converters.AbortSignal = webidl.createInterfaceConverter( "AbortSignal", AbortSignal.prototype, ); +webidl.converters["sequence"] = webidl.createSequenceConverter( + webidl.converters.AbortSignal, +); function newSignal() { return new AbortSignal(illegalConstructorKey); From 31e9e484248ff7156f0e671454235005dd2d1df0 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 4 Nov 2023 14:25:30 +0900 Subject: [PATCH 03/11] fix --- ext/web/03_abort_signal.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ext/web/03_abort_signal.js b/ext/web/03_abort_signal.js index 49ba3aa75da151..661a5e3f9b8b59 100644 --- a/ext/web/03_abort_signal.js +++ b/ext/web/03_abort_signal.js @@ -43,9 +43,8 @@ class WeakRefSet { if (WeakSetPrototypeHas(this.#weakSet, value)) { return; } - const ref = new SafeWeakRef(value); WeakSetPrototypeAdd(this.#weakSet, value); - SetPrototypeAdd(this.#refSet, ref); + SetPrototypeAdd(this.#refSet, new SafeWeakRef(value)); } has(value) { @@ -57,7 +56,7 @@ class WeakRefSet { for (const ref of new SafeSetIterator(this.#refSet)) { const value = WeakRefPrototypeDeref(ref); if (value !== undefined) { - ArrayPrototypePush(value); + ArrayPrototypePush(arr, value); } } return arr; @@ -188,7 +187,7 @@ class AbortSignal extends EventTarget { const signals = this[dependentSignals]; if (signals !== null) { const signalArray = signals.toArray(); - for (let i = 0; i < signalArray; ++i) { + for (let i = 0; i < signalArray.length; ++i) { const signal = signalArray[i]; signal[signalAbort](reason); } From 3ad837dcc74756f455f94747360088ae11221222 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 4 Nov 2023 14:45:09 +0900 Subject: [PATCH 04/11] tweak --- ext/web/03_abort_signal.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ext/web/03_abort_signal.js b/ext/web/03_abort_signal.js index 661a5e3f9b8b59..e3d10428484ee4 100644 --- a/ext/web/03_abort_signal.js +++ b/ext/web/03_abort_signal.js @@ -37,14 +37,14 @@ import { refTimer, setTimeout, unrefTimer } from "ext:deno_web/02_timers.js"; // toArray method. class WeakRefSet { #weakSet = new SafeWeakSet(); - #refSet = new SafeSet(); + #refs = []; add(value) { if (WeakSetPrototypeHas(this.#weakSet, value)) { return; } WeakSetPrototypeAdd(this.#weakSet, value); - SetPrototypeAdd(this.#refSet, new SafeWeakRef(value)); + ArrayPrototypePush(this.#refs, new SafeWeakRef(value)); } has(value) { @@ -52,14 +52,14 @@ class WeakRefSet { } toArray() { - const arr = []; - for (const ref of new SafeSetIterator(this.#refSet)) { - const value = WeakRefPrototypeDeref(ref); + const ret = []; + for (let i = 0; i < this.#refs.length; ++i) { + const value = WeakRefPrototypeDeref(this.#refs[i]); if (value !== undefined) { - ArrayPrototypePush(arr, value); + ArrayPrototypePush(ret, value); } } - return arr; + return ret; } } From 0c4ba0b29498185f8220fe9018db476ee3678e34 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 4 Nov 2023 15:32:31 +0900 Subject: [PATCH 05/11] add type --- ext/web/lib.deno_web.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/web/lib.deno_web.d.ts b/ext/web/lib.deno_web.d.ts index 5a3f658a3673cf..aa832cc013a660 100644 --- a/ext/web/lib.deno_web.d.ts +++ b/ext/web/lib.deno_web.d.ts @@ -442,6 +442,7 @@ declare var AbortSignal: { readonly prototype: AbortSignal; new (): never; abort(reason?: any): AbortSignal; + any(signals: AbortSignal[]): AbortSignal; timeout(milliseconds: number): AbortSignal; }; From 0e2110783e87e38c5f1049c1f352ed9b67601e9e Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 4 Nov 2023 15:52:33 +0900 Subject: [PATCH 06/11] update wpt expectation.json --- tools/wpt/expectation.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json index 4b01f0c0065561..fc5870f6202225 100644 --- a/tools/wpt/expectation.json +++ b/tools/wpt/expectation.json @@ -2302,7 +2302,9 @@ "AbortSignal.any.html": true, "AbortSignal.any.worker.html": true, "event.any.html": true, - "event.any.worker.html": true + "event.any.worker.html": true, + "abort-signal-any.any.html": true, + "abort-signal-any.any.worker.html": true }, "events": { "AddEventListenerOptions-once.any.html": true, @@ -2364,7 +2366,6 @@ "EventTarget interface: operation addEventListener(DOMString, EventListener?, optional (AddEventListenerOptions or boolean))", "EventTarget interface: operation removeEventListener(DOMString, EventListener?, optional (EventListenerOptions or boolean))", "AbortController interface: operation abort(optional any)", - "AbortSignal interface: operation any(sequence)", "AbortSignal interface: attribute onabort", "NodeList interface: existence and properties of interface object", "NodeList interface object length", From 83e5c106b075325de93a7ec2d9305470dda553b5 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 4 Nov 2023 16:24:35 +0900 Subject: [PATCH 07/11] fix --- ext/web/03_abort_signal.js | 42 ++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/ext/web/03_abort_signal.js b/ext/web/03_abort_signal.js index e3d10428484ee4..95e87011f3f812 100644 --- a/ext/web/03_abort_signal.js +++ b/ext/web/03_abort_signal.js @@ -14,6 +14,7 @@ import { } from "ext:deno_web/02_event.js"; const primordials = globalThis.__bootstrap.primordials; const { + ArrayPrototypeEvery, ArrayPrototypePush, SafeArrayIterator, SafeSet, @@ -236,15 +237,48 @@ class AbortSignal extends EventTarget { // ops which would block the event loop. addEventListener(...args) { super.addEventListener(...new SafeArrayIterator(args)); - if (this[timerId] !== null && listenerCount(this, "abort") > 0) { - refTimer(this[timerId]); + if (listenerCount(this, "abort") > 0) { + if (this[timerId] !== null) { + refTimer(this[timerId]); + } else if (this[sourceSignals] !== null) { + const sourceSignalArray = this[sourceSignals].toArray(); + for (let i = 0; i < sourceSignalArray.length; ++i) { + const sourceSignal = sourceSignalArray[i]; + if (sourceSignal[timerId] !== null) { + refTimer(sourceSignal[timerId]); + } + } + } } } removeEventListener(...args) { super.removeEventListener(...new SafeArrayIterator(args)); - if (this[timerId] !== null && listenerCount(this, "abort") === 0) { - unrefTimer(this[timerId]); + if (listenerCount(this, "abort") === 0) { + if (this[timerId] !== null) { + unrefTimer(this[timerId]); + } else if (this[sourceSignals] !== null) { + const sourceSignalArray = this[sourceSignals].toArray(); + for (let i = 0; i < sourceSignalArray.length; ++i) { + const sourceSignal = sourceSignalArray[i]; + if ( + sourceSignal[timerId] !== null && + sourceSignal[dependentSignals] !== null + ) { + // Check that all dependent signals of the timer signal do not have listeners + if ( + ArrayPrototypeEvery( + sourceSignal[dependentSignals].toArray(), + (dependentSignal) => + dependentSignal === this || + listenerCount(dependentSignal, "abort") === 0, + ) + ) { + unrefTimer(sourceSignal[timerId]); + } + } + } + } } } } From b512831852c8d4d8fb4da941c2001d524c597b88 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 4 Nov 2023 16:44:16 +0900 Subject: [PATCH 08/11] fix --- ext/web/03_abort_signal.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ext/web/03_abort_signal.js b/ext/web/03_abort_signal.js index 95e87011f3f812..0035f9169a7fad 100644 --- a/ext/web/03_abort_signal.js +++ b/ext/web/03_abort_signal.js @@ -261,10 +261,7 @@ class AbortSignal extends EventTarget { const sourceSignalArray = this[sourceSignals].toArray(); for (let i = 0; i < sourceSignalArray.length; ++i) { const sourceSignal = sourceSignalArray[i]; - if ( - sourceSignal[timerId] !== null && - sourceSignal[dependentSignals] !== null - ) { + if (sourceSignal[timerId] !== null) { // Check that all dependent signals of the timer signal do not have listeners if ( ArrayPrototypeEvery( From 0b4fa4c663bb32029127f6aeac11a3c31386b5a0 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 4 Nov 2023 16:47:52 +0900 Subject: [PATCH 09/11] tweak --- ext/web/03_abort_signal.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/ext/web/03_abort_signal.js b/ext/web/03_abort_signal.js index 0035f9169a7fad..f8a9b4db586855 100644 --- a/ext/web/03_abort_signal.js +++ b/ext/web/03_abort_signal.js @@ -185,12 +185,11 @@ class AbortSignal extends EventTarget { } } - const signals = this[dependentSignals]; - if (signals !== null) { - const signalArray = signals.toArray(); - for (let i = 0; i < signalArray.length; ++i) { - const signal = signalArray[i]; - signal[signalAbort](reason); + if (this[dependentSignals] !== null) { + const dependentSignalArray = this[dependentSignals].toArray(); + for (let i = 0; i < dependentSignalArray.length; ++i) { + const dependentSignal = dependentSignalArray[i]; + dependentSignal[signalAbort](reason); } } } From 2071eb8a875e8f9bfb0fe068913bc3ee9ab3d722 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 11 Nov 2023 01:35:15 +0900 Subject: [PATCH 10/11] Update to `createDependentAbortSignal` from `follow` --- ext/fetch/23_request.js | 47 ++++++++++---------- ext/web/03_abort_signal.js | 89 ++++++++++++++++++-------------------- 2 files changed, 65 insertions(+), 71 deletions(-) diff --git a/ext/fetch/23_request.js b/ext/fetch/23_request.js index a59bfb29d75211..cedace6a10a093 100644 --- a/ext/fetch/23_request.js +++ b/ext/fetch/23_request.js @@ -10,6 +10,7 @@ /// import * as webidl from "ext:deno_webidl/00_webidl.js"; +import { assert } from "ext:deno_web/00_infra.js"; import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; import { byteUpperCase, @@ -356,21 +357,19 @@ class Request { request.clientRid = init.client?.rid ?? null; } - // 27. - this[_request] = request; - // 28. - this[_signal] = abortSignal.newSignal(); + this[_request] = request; // 29. - if (signal !== null) { - abortSignal.follow(this[_signal], signal); - } + const signals = signal !== null ? [signal] : []; + + // 30. + this[_signal] = abortSignal.createDependentAbortSignal(signals, prefix); // 30. this[_headers] = headersFromHeaderList(request.headerList, "request"); - // 32. + // 33. if (init.headers || ObjectKeys(init).length > 0) { const headerList = headerListFromHeaders(this[_headers]); const headers = init.headers ?? ArrayPrototypeSlice( @@ -384,13 +383,13 @@ class Request { fillHeaders(this[_headers], headers); } - // 33. + // 34. let inputBody = null; if (ObjectPrototypeIsPrototypeOf(RequestPrototype, input)) { inputBody = input[_body]; } - // 34. + // 35. if ( (request.method === "GET" || request.method === "HEAD") && ((init.body !== undefined && init.body !== null) || @@ -399,10 +398,10 @@ class Request { throw new TypeError("Request with GET/HEAD method cannot have body."); } - // 35. + // 36. let initBody = null; - // 36. + // 37. if (init.body !== undefined && init.body !== null) { const res = extractBody(init.body); initBody = res.body; @@ -411,13 +410,13 @@ class Request { } } - // 37. + // 38. const inputOrInitBody = initBody ?? inputBody; - // 39. + // 40. let finalBody = inputOrInitBody; - // 40. + // 41. if (initBody === null && inputBody !== null) { if (input[_body] && input[_body].unusable()) { throw new TypeError("Input request's body is unusable."); @@ -425,7 +424,7 @@ class Request { finalBody = inputBody.createProxy(); } - // 41. + // 42. request.body = finalBody; } @@ -464,20 +463,22 @@ class Request { } clone() { + const prefix = "Failed to call 'Request.clone'"; webidl.assertBranded(this, RequestPrototype); if (this[_body] && this[_body].unusable()) { throw new TypeError("Body is unusable."); } - const newReq = cloneInnerRequest(this[_request]); - const newSignal = abortSignal.newSignal(); + const clonedReq = cloneInnerRequest(this[_request]); - if (this[_signal]) { - abortSignal.follow(newSignal, this[_signal]); - } + assert(this[_signal] !== null); + const clonedSignal = abortSignal.createDependentAbortSignal( + [this[_signal]], + prefix, + ); return fromInnerRequest( - newReq, - newSignal, + clonedReq, + clonedSignal, guardFromHeaders(this[_headers]), ); } diff --git a/ext/web/03_abort_signal.js b/ext/web/03_abort_signal.js index f8a9b4db586855..a237b273c32a7e 100644 --- a/ext/web/03_abort_signal.js +++ b/ext/web/03_abort_signal.js @@ -81,46 +81,7 @@ class AbortSignal extends EventTarget { static any(signals) { const prefix = "Failed to call 'AbortSignal.any'"; webidl.requiredArguments(arguments.length, 1, prefix); - signals = webidl.converters["sequence"]( - signals, - prefix, - "Argument 1", - ); - - const resultSignal = new AbortSignal(illegalConstructorKey); - for (let i = 0; i < signals.length; ++i) { - const signal = signals[i]; - if (signal[abortReason] !== undefined) { - resultSignal[abortReason] = signal[abortReason]; - return resultSignal; - } - } - - resultSignal[dependent] = true; - resultSignal[sourceSignals] = new WeakRefSet(); - for (let i = 0; i < signals.length; ++i) { - const signal = signals[i]; - if (!signal[dependent]) { - signal[dependentSignals] ??= new WeakRefSet(); - resultSignal[sourceSignals].add(signal); - signal[dependentSignals].add(resultSignal); - } else { - const sourceSignalArray = signal[sourceSignals].toArray(); - for (let j = 0; j < sourceSignalArray.length; ++j) { - const sourceSignal = sourceSignalArray[j]; - assert(sourceSignal[abortReason] === undefined); - assert(!sourceSignal[dependent]); - - if (resultSignal[sourceSignals].has(sourceSignal)) { - continue; - } - resultSignal[sourceSignals].add(sourceSignal); - sourceSignal[dependentSignals].add(resultSignal); - } - } - } - - return resultSignal; + return createDependentAbortSignal(signals, prefix); } static abort(reason = undefined) { @@ -316,15 +277,47 @@ function newSignal() { return new AbortSignal(illegalConstructorKey); } -function follow(followingSignal, parentSignal) { - if (followingSignal.aborted) { - return; +function createDependentAbortSignal(signals, prefix) { + signals = webidl.converters["sequence"]( + signals, + prefix, + "Argument 1", + ); + + const resultSignal = new AbortSignal(illegalConstructorKey); + for (let i = 0; i < signals.length; ++i) { + const signal = signals[i]; + if (signal[abortReason] !== undefined) { + resultSignal[abortReason] = signal[abortReason]; + return resultSignal; + } } - if (parentSignal.aborted) { - followingSignal[signalAbort](parentSignal.reason); - } else { - parentSignal[add](() => followingSignal[signalAbort](parentSignal.reason)); + + resultSignal[dependent] = true; + resultSignal[sourceSignals] = new WeakRefSet(); + for (let i = 0; i < signals.length; ++i) { + const signal = signals[i]; + if (!signal[dependent]) { + signal[dependentSignals] ??= new WeakRefSet(); + resultSignal[sourceSignals].add(signal); + signal[dependentSignals].add(resultSignal); + } else { + const sourceSignalArray = signal[sourceSignals].toArray(); + for (let j = 0; j < sourceSignalArray.length; ++j) { + const sourceSignal = sourceSignalArray[j]; + assert(sourceSignal[abortReason] === undefined); + assert(!sourceSignal[dependent]); + + if (resultSignal[sourceSignals].has(sourceSignal)) { + continue; + } + resultSignal[sourceSignals].add(sourceSignal); + sourceSignal[dependentSignals].add(resultSignal); + } + } } + + return resultSignal; } export { @@ -332,7 +325,7 @@ export { AbortSignal, AbortSignalPrototype, add, - follow, + createDependentAbortSignal, newSignal, remove, signalAbort, From efb9445e951a4cd769477a71a959483c5907d52d Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 11 Nov 2023 01:37:30 +0900 Subject: [PATCH 11/11] tweak --- ext/fetch/23_request.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/fetch/23_request.js b/ext/fetch/23_request.js index cedace6a10a093..bbaf886a61e841 100644 --- a/ext/fetch/23_request.js +++ b/ext/fetch/23_request.js @@ -366,7 +366,7 @@ class Request { // 30. this[_signal] = abortSignal.createDependentAbortSignal(signals, prefix); - // 30. + // 31. this[_headers] = headersFromHeaderList(request.headerList, "request"); // 33.