Skip to content

Commit

Permalink
lib: define FormData and fetch etc. in the built-in snapshot
Browse files Browse the repository at this point in the history
Now that --experimental-fetch is true by default, define the
dependent interfaces in the built-in snapshot and only delete
them at run time when --no-experimental-fetch is set.

PR-URL: #51598
Reviewed-By: Ethan Arrowood <ethan@arrowood.dev>
Reviewed-By: Matthew Aitken <maitken033380023@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
  • Loading branch information
joyeecheung authored and targos committed Feb 15, 2024
1 parent 8f63f6f commit 7f698f0
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 53 deletions.
42 changes: 42 additions & 0 deletions lib/internal/bootstrap/web/exposed-window-or-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

const {
globalThis,
ObjectDefineProperty,
} = primordials;

const {
Expand Down Expand Up @@ -55,3 +56,44 @@ defineReplaceableLazyAttribute(globalThis, 'perf_hooks', ['performance']);
// https://w3c.github.io/FileAPI/#creating-revoking
const { installObjectURLMethods } = require('internal/url');
installObjectURLMethods();

{
// https://fetch.spec.whatwg.org/#fetch-method
function set(value) {
ObjectDefineProperty(globalThis, 'fetch', {
__proto__: null,
writable: true,
value,
});
}
ObjectDefineProperty(globalThis, 'fetch', {
__proto__: null,
configurable: true,
enumerable: true,
set,
get() {
function fetch(input, init = undefined) {
// Loading undici alone lead to promises which breaks lots of tests so we
// have to load it really lazily for now.
const { fetch: impl } = require('internal/deps/undici/undici');
return impl(input, init);
}
set(fetch);
return fetch;
},
});
}

// https://xhr.spec.whatwg.org/#interface-formdata
// https://fetch.spec.whatwg.org/#headers-class
// https://fetch.spec.whatwg.org/#request-class
// https://fetch.spec.whatwg.org/#response-class
exposeLazyInterfaces(globalThis, 'internal/deps/undici/undici', [
'FormData', 'Headers', 'Request', 'Response',
]);

// The WebAssembly Web API which relies on Response.
// https:// webassembly.github.io/spec/web-api/#streaming-modules
internalBinding('wasm_web_api').setImplementation((streamState, source) => {
require('internal/wasm_web_api').wasmStreamingCallback(streamState, source);
});
60 changes: 8 additions & 52 deletions lib/internal/process/pre_execution.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ const {
DatePrototypeGetMonth,
DatePrototypeGetSeconds,
NumberParseInt,
ObjectDefineProperties,
ObjectDefineProperty,
ObjectFreeze,
ObjectGetOwnPropertyDescriptor,
Expand All @@ -30,7 +29,6 @@ const {
} = require('internal/options');
const { reconnectZeroFillToggle } = require('internal/buffer');
const {
defineOperation,
exposeInterface,
exposeLazyInterfaces,
defineReplaceableLazyAttribute,
Expand Down Expand Up @@ -302,58 +300,16 @@ function setupWarningHandler() {
// https://fetch.spec.whatwg.org/
// https://websockets.spec.whatwg.org/
function setupUndici() {
if (getEmbedderOptions().noBrowserGlobals) {
return;
}

let undici;
function lazyUndici() {
if (undici) {
return undici;
}

undici = require('internal/deps/undici/undici');
return undici;
}

function lazyInterface(name) {
return {
configurable: true,
enumerable: false,
get() {
return lazyUndici()[name];
},
set(value) {
exposeInterface(globalThis, name, value);
},
};
if (getOptionValue('--no-experimental-fetch')) {
delete globalThis.fetch;
delete globalThis.FormData;
delete globalThis.Headers;
delete globalThis.Request;
delete globalThis.Response;
}

if (!getOptionValue('--no-experimental-fetch')) {
// Fetch is meant to return a Promise, but not be async.
function fetch(input, init = undefined) {
return lazyUndici().fetch(input, init);
}

defineOperation(globalThis, 'fetch', fetch);

ObjectDefineProperties(globalThis, {
FormData: lazyInterface('FormData'),
Headers: lazyInterface('Headers'),
Request: lazyInterface('Request'),
Response: lazyInterface('Response'),
});

// The WebAssembly Web API: https://webassembly.github.io/spec/web-api
internalBinding('wasm_web_api').setImplementation((streamState, source) => {
require('internal/wasm_web_api').wasmStreamingCallback(streamState, source);
});
}

if (getOptionValue('--experimental-websocket')) {
ObjectDefineProperties(globalThis, {
WebSocket: lazyInterface('WebSocket'),
});
if (!getEmbedderOptions().noBrowserGlobals && getOptionValue('--experimental-websocket')) {
exposeLazyInterfaces(globalThis, 'internal/deps/undici/undici', ['WebSocket']);
}
}

Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-bootstrap-modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,10 @@ expected.beforePreExec = new Set([
'NativeModule internal/modules/package_json_reader',
'Internal Binding module_wrap',
'NativeModule internal/modules/cjs/loader',
'Internal Binding wasm_web_api',
]);

expected.atRunTime = new Set([
'Internal Binding wasm_web_api',
'Internal Binding worker',
'NativeModule internal/modules/run_main',
'NativeModule internal/net',
Expand Down

0 comments on commit 7f698f0

Please sign in to comment.