Skip to content

Commit

Permalink
version cleanup (nodejs#2483)
Browse files Browse the repository at this point in the history
* remove require('stream/web')

* remove node <= 16 version checks

* remove DOMException, structuredClone, WeakRef, FinalizationRegistry workarounds
  • Loading branch information
KhafraDev authored and crysmags committed Feb 27, 2024
1 parent 54d263c commit eef4a6e
Show file tree
Hide file tree
Showing 46 changed files with 63 additions and 425 deletions.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,6 @@ Implements [fetch](https://fetch.spec.whatwg.org/#fetch-method).
* https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
* https://fetch.spec.whatwg.org/#fetch-method

Only supported on Node 16.8+.

Basic usage example:

```js
Expand Down
1 change: 0 additions & 1 deletion benchmarks/benchmark-http2.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ const path = require('path')
const { readFileSync } = require('fs')
const { table } = require('table')
const { Writable } = require('stream')
const { WritableStream } = require('stream/web')
const { isMainThread } = require('worker_threads')

const { Pool, Client, fetch, Agent, setGlobalDispatcher } = require('..')
Expand Down
1 change: 0 additions & 1 deletion benchmarks/benchmark-https.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ const path = require('path')
const { readFileSync } = require('fs')
const { table } = require('table')
const { Writable } = require('stream')
const { WritableStream } = require('stream/web')
const { isMainThread } = require('worker_threads')

const { Pool, Client, fetch, Agent, setGlobalDispatcher } = require('..')
Expand Down
1 change: 0 additions & 1 deletion benchmarks/benchmark.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ const os = require('os')
const path = require('path')
const { table } = require('table')
const { Writable } = require('stream')
const { WritableStream } = require('stream/web')
const { isMainThread } = require('worker_threads')

const { Pool, Client, fetch, Agent, setGlobalDispatcher } = require('..')
Expand Down
7 changes: 1 addition & 6 deletions lib/compat/dispatcher-weakref.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
'use strict'

/* istanbul ignore file: only for Node 12 */

const { kConnected, kSize } = require('../core/symbols')

class CompatWeakRef {
Expand Down Expand Up @@ -41,8 +39,5 @@ module.exports = function () {
FinalizationRegistry: CompatFinalizer
}
}
return {
WeakRef: global.WeakRef || CompatWeakRef,
FinalizationRegistry: global.FinalizationRegistry || CompatFinalizer
}
return { WeakRef, FinalizationRegistry }
}
20 changes: 5 additions & 15 deletions lib/core/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -359,22 +359,9 @@ function getSocketInfo (socket) {
}
}

async function * convertIterableToBuffer (iterable) {
for await (const chunk of iterable) {
yield Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)
}
}

/** @type {globalThis['ReadableStream']} */
let ReadableStream
function ReadableStreamFrom (iterable) {
if (!ReadableStream) {
ReadableStream = require('stream/web').ReadableStream
}

if (ReadableStream.from) {
return ReadableStream.from(convertIterableToBuffer(iterable))
}
// We cannot use ReadableStream.from here because it does not return a byte stream.

let iterator
return new ReadableStream(
Expand All @@ -387,10 +374,13 @@ function ReadableStreamFrom (iterable) {
if (done) {
queueMicrotask(() => {
controller.close()
controller.byobRequest?.respond(0)
})
} else {
const buf = Buffer.isBuffer(value) ? value : Buffer.from(value)
controller.enqueue(new Uint8Array(buf))
if (buf.byteLength) {
controller.enqueue(new Uint8Array(buf))
}
}
return controller.desiredSize > 0
},
Expand Down
12 changes: 0 additions & 12 deletions lib/fetch/body.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ const {
const { FormData } = require('./formdata')
const { kState } = require('./symbols')
const { webidl } = require('./webidl')
const { DOMException, structuredClone } = require('./constants')
const { Blob, File: NativeFile } = require('buffer')
const { kBodyUsed } = require('../core/symbols')
const assert = require('assert')
Expand All @@ -22,19 +21,13 @@ const { isUint8Array, isArrayBuffer } = require('util/types')
const { File: UndiciFile } = require('./file')
const { parseMIMEType, serializeAMimeType } = require('./dataURL')

let ReadableStream = globalThis.ReadableStream

/** @type {globalThis['File']} */
const File = NativeFile ?? UndiciFile
const textEncoder = new TextEncoder()
const textDecoder = new TextDecoder()

// https://fetch.spec.whatwg.org/#concept-bodyinit-extract
function extractBody (object, keepalive = false) {
if (!ReadableStream) {
ReadableStream = require('stream/web').ReadableStream
}

// 1. Let stream be null.
let stream = null

Expand Down Expand Up @@ -258,11 +251,6 @@ function extractBody (object, keepalive = false) {

// https://fetch.spec.whatwg.org/#bodyinit-safely-extract
function safelyExtractBody (object, keepalive = false) {
if (!ReadableStream) {
// istanbul ignore next
ReadableStream = require('stream/web').ReadableStream
}

// To safely extract a body and a `Content-Type` value from
// a byte sequence or BodyInit object object, run these steps:

Expand Down
36 changes: 0 additions & 36 deletions lib/fetch/constants.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
'use strict'

const { MessageChannel, receiveMessageOnPort } = require('worker_threads')

const corsSafeListedMethods = ['GET', 'HEAD', 'POST']
const corsSafeListedMethodsSet = new Set(corsSafeListedMethods)

Expand Down Expand Up @@ -92,41 +90,7 @@ const subresource = [
]
const subresourceSet = new Set(subresource)

/** @type {globalThis['DOMException']} */
const DOMException = globalThis.DOMException ?? (() => {
// DOMException was only made a global in Node v17.0.0,
// but fetch supports >= v16.8.
try {
atob('~')
} catch (err) {
return Object.getPrototypeOf(err).constructor
}
})()

let channel

/** @type {globalThis['structuredClone']} */
const structuredClone =
globalThis.structuredClone ??
// https://github.com/nodejs/node/blob/b27ae24dcc4251bad726d9d84baf678d1f707fed/lib/internal/structured_clone.js
// structuredClone was added in v17.0.0, but fetch supports v16.8
function structuredClone (value, options = undefined) {
if (arguments.length === 0) {
throw new TypeError('missing argument')
}

if (!channel) {
channel = new MessageChannel()
}
channel.port1.unref()
channel.port2.unref()
channel.port1.postMessage(value, options?.transfer)
return receiveMessageOnPort(channel.port2).message
}

module.exports = {
DOMException,
structuredClone,
subresource,
forbiddenMethods,
requestBodyHeader,
Expand Down
9 changes: 1 addition & 8 deletions lib/fetch/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,23 +52,20 @@ const {
nullBodyStatus,
safeMethodsSet,
requestBodyHeader,
subresourceSet,
DOMException
subresourceSet
} = require('./constants')
const { kHeadersList } = require('../core/symbols')
const EE = require('events')
const { Readable, pipeline } = require('stream')
const { addAbortListener, isErrored, isReadable, nodeMajor, nodeMinor } = require('../core/util')
const { dataURLProcessor, serializeAMimeType, parseMIMEType } = require('./dataURL')
const { TransformStream } = require('stream/web')
const { getGlobalDispatcher } = require('../global')
const { webidl } = require('./webidl')
const { STATUS_CODES } = require('http')
const GET_OR_HEAD = ['GET', 'HEAD']

/** @type {import('buffer').resolveObjectURL} */
let resolveObjectURL
let ReadableStream = globalThis.ReadableStream

class Fetch extends EE {
constructor (dispatcher) {
Expand Down Expand Up @@ -1934,10 +1931,6 @@ async function httpNetworkFetch (
// 15. Let stream be a new ReadableStream.
// 16. Set up stream with byte reading support with pullAlgorithm set to pullAlgorithm,
// cancelAlgorithm set to cancelAlgorithm.
if (!ReadableStream) {
ReadableStream = require('stream/web').ReadableStream
}

const stream = new ReadableStream(
{
async start (controller) {
Expand Down
6 changes: 0 additions & 6 deletions lib/fetch/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ const { kHeadersList, kConstruct } = require('../core/symbols')
const assert = require('assert')
const { getMaxListeners, setMaxListeners, getEventListeners, defaultMaxListeners } = require('events')

let TransformStream = globalThis.TransformStream

const kAbortController = Symbol('abortController')

const requestFinalizer = new FinalizationRegistry(({ signal, abort }) => {
Expand Down Expand Up @@ -516,10 +514,6 @@ class Request {
}

// 2. Set finalBody to the result of creating a proxy for inputBody.
if (!TransformStream) {
TransformStream = require('stream/web').TransformStream
}

// https://streams.spec.whatwg.org/#readablestream-create-a-proxy
const identityTransform = new TransformStream()
inputBody.stream.pipeThrough(identityTransform)
Expand Down
4 changes: 1 addition & 3 deletions lib/fetch/response.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ const {
} = require('./util')
const {
redirectStatusSet,
nullBodyStatus,
DOMException
nullBodyStatus
} = require('./constants')
const { kState, kHeaders, kGuard, kRealm } = require('./symbols')
const { webidl } = require('./webidl')
Expand All @@ -27,7 +26,6 @@ const { kHeadersList, kConstruct } = require('../core/symbols')
const assert = require('assert')
const { types } = require('util')

const ReadableStream = globalThis.ReadableStream || require('stream/web').ReadableStream
const textEncoder = new TextEncoder('utf-8')

// https://fetch.spec.whatwg.org/#response-class
Expand Down
13 changes: 0 additions & 13 deletions lib/fetch/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -890,14 +890,7 @@ async function fullyReadBody (body, processBody, processBodyError) {
}
}

/** @type {ReadableStream} */
let ReadableStream = globalThis.ReadableStream

function isReadableStreamLike (stream) {
if (!ReadableStream) {
ReadableStream = require('stream/web').ReadableStream
}

return stream instanceof ReadableStream || (
stream[Symbol.toStringTag] === 'ReadableStream' &&
typeof stream.tee === 'function'
Expand Down Expand Up @@ -1186,11 +1179,6 @@ function buildContentRange (rangeStart, rangeEnd, fullLength) {
return contentRange
}

/**
* Fetch supports node >= 16.8.0, but Object.hasOwn was added in v16.9.0.
*/
const hasOwn = Object.hasOwn || ((dict, key) => Object.prototype.hasOwnProperty.call(dict, key))

module.exports = {
isAborted,
isCancelled,
Expand Down Expand Up @@ -1223,7 +1211,6 @@ module.exports = {
makeIterator,
isValidHeaderName,
isValidHeaderValue,
hasOwn,
isErrorLike,
fullyReadBody,
bytesMatch,
Expand Down
6 changes: 3 additions & 3 deletions lib/fetch/webidl.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict'

const { types } = require('util')
const { hasOwn, toUSVString } = require('./util')
const { toUSVString } = require('./util')

/** @type {import('../../types/webidl').Webidl} */
const webidl = {}
Expand Down Expand Up @@ -346,7 +346,7 @@ webidl.dictionaryConverter = function (converters) {
const { key, defaultValue, required, converter } = options

if (required === true) {
if (!hasOwn(dictionary, key)) {
if (!Object.hasOwn(dictionary, key)) {
throw webidl.errors.exception({
header: 'Dictionary',
message: `Missing required key "${key}".`
Expand All @@ -355,7 +355,7 @@ webidl.dictionaryConverter = function (converters) {
}

let value = dictionary[key]
const hasDefault = hasOwn(options, 'defaultValue')
const hasDefault = Object.hasOwn(options, 'defaultValue')

// Only use defaultValue if value is undefined and
// a defaultValue options was provided.
Expand Down
1 change: 0 additions & 1 deletion lib/fileapi/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ const {
} = require('./symbols')
const { ProgressEvent } = require('./progressevent')
const { getEncoding } = require('./encoding')
const { DOMException } = require('../fetch/constants')
const { serializeAMimeType, parseMIMEType } = require('../fetch/dataURL')
const { types } = require('util')
const { StringDecoder } = require('string_decoder')
Expand Down
1 change: 0 additions & 1 deletion lib/websocket/websocket.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict'

const { webidl } = require('../fetch/webidl')
const { DOMException } = require('../fetch/constants')
const { URLSerializer } = require('../fetch/dataURL')
const { getGlobalOrigin } = require('../fetch/global')
const { staticPropertyDescriptors, states, opcodes, emptyBuffer } = require('./constants')
Expand Down
8 changes: 1 addition & 7 deletions test/client-pipeline.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ const {
Writable,
PassThrough
} = require('stream')
const { nodeMajor } = require('../lib/core/util')

test('pipeline get', (t) => {
t.plan(17)
Expand Down Expand Up @@ -535,12 +534,7 @@ test('pipeline abort piped res', (t) => {
return pipeline(body, pt, () => {})
})
.on('error', (err) => {
// Node < 13 doesn't always detect premature close.
if (nodeMajor < 13) {
t.ok(err)
} else {
t.equal(err.code, 'UND_ERR_ABORTED')
}
t.equal(err.code, 'UND_ERR_ABORTED')
})
.end()
})
Expand Down
Loading

0 comments on commit eef4a6e

Please sign in to comment.