Skip to content

Commit 2d8f060

Browse files
committed
lib: add WebSocket client
fixup add test
1 parent 55fde47 commit 2d8f060

File tree

9 files changed

+68
-20
lines changed

9 files changed

+68
-20
lines changed

.eslintrc.js

+1
Original file line numberDiff line numberDiff line change
@@ -361,5 +361,6 @@ module.exports = {
361361
WritableStream: 'readable',
362362
WritableStreamDefaultWriter: 'readable',
363363
WritableStreamDefaultController: 'readable',
364+
WebSocket: 'readable',
364365
},
365366
};

doc/api/cli.md

+10
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,14 @@ added: v12.3.0
738738

739739
Enable experimental WebAssembly module support.
740740

741+
### `--experimental-websocket`
742+
743+
<!-- YAML
744+
added: REPLACEME
745+
-->
746+
747+
Enable experimental [`WebSocket`][] support..
748+
741749
### `--force-context-aware`
742750

743751
<!-- YAML
@@ -2235,6 +2243,7 @@ Node.js options that are allowed are:
22352243
* `--enable-network-family-autoselection`
22362244
* `--enable-source-maps`
22372245
* `--experimental-abortcontroller`
2246+
* `--experimental-websocket`
22382247
* `--experimental-import-meta-resolve`
22392248
* `--experimental-json-modules`
22402249
* `--experimental-loader`
@@ -2715,6 +2724,7 @@ done
27152724
[`NODE_OPTIONS`]: #node_optionsoptions
27162725
[`NO_COLOR`]: https://no-color.org
27172726
[`SlowBuffer`]: buffer.md#class-slowbuffer
2727+
[`WebSocket`]: https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
27182728
[`YoungGenerationSizeFromSemiSpaceSize`]: https://chromium.googlesource.com/v8/v8.git/+/refs/tags/10.3.129/src/heap/heap.cc#328
27192729
[`dns.lookup()`]: dns.md#dnslookuphostname-options-callback
27202730
[`dns.setDefaultResultOrder()`]: dns.md#dnssetdefaultresultorderorder

doc/api/globals.md

+13
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,17 @@ The object that acts as the namespace for all W3C
10031003
[WebAssembly][webassembly-org] related functionality. See the
10041004
[Mozilla Developer Network][webassembly-mdn] for usage and compatibility.
10051005

1006+
## `WebSocket`
1007+
1008+
<!-- YAML
1009+
added: REPLACEME
1010+
-->
1011+
1012+
> Stability: 1 - Experimental.
1013+
1014+
A browser-compatible implementation of [`WebSocket`][]. Enable this API
1015+
with the [`--experimental-websocket`][] CLI flag.
1016+
10061017
## Class: `WritableStream`
10071018

10081019
<!-- YAML
@@ -1037,6 +1048,7 @@ A browser-compatible implementation of [`WritableStreamDefaultWriter`][].
10371048
[ECMAScript module]: esm.md
10381049
[Navigator API]: https://html.spec.whatwg.org/multipage/system-state.html#the-navigator-object
10391050
[Web Crypto API]: webcrypto.md
1051+
[`--experimental-websocket`]: cli.md#--experimental-websocket
10401052
[`--no-experimental-fetch`]: cli.md#--no-experimental-fetch
10411053
[`--no-experimental-global-customevent`]: cli.md#--no-experimental-global-customevent
10421054
[`--no-experimental-global-webcrypto`]: cli.md#--no-experimental-global-webcrypto
@@ -1071,6 +1083,7 @@ A browser-compatible implementation of [`WritableStreamDefaultWriter`][].
10711083
[`TransformStream`]: webstreams.md#class-transformstream
10721084
[`URLSearchParams`]: url.md#class-urlsearchparams
10731085
[`URL`]: url.md#class-url
1086+
[`WebSocket`]: https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
10741087
[`WritableStreamDefaultController`]: webstreams.md#class-writablestreamdefaultcontroller
10751088
[`WritableStreamDefaultWriter`]: webstreams.md#class-writablestreamdefaultwriter
10761089
[`WritableStream`]: webstreams.md#class-writablestream

lib/internal/process/pre_execution.js

+28-20
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ function prepareExecution(options) {
7878
setupTraceCategoryState();
7979
setupInspectorHooks();
8080
setupWarningHandler();
81-
setupFetch();
81+
setupUndici();
8282
setupWebCrypto();
8383
setupCustomEvent();
8484
setupCodeCoverage();
@@ -262,9 +262,9 @@ function setupWarningHandler() {
262262
}
263263

264264
// https://fetch.spec.whatwg.org/
265-
function setupFetch() {
266-
if (getEmbedderOptions().noBrowserGlobals ||
267-
getOptionValue('--no-experimental-fetch')) {
265+
// https://websockets.spec.whatwg.org/
266+
function setupUndici() {
267+
if (getEmbedderOptions().noBrowserGlobals) {
268268
return;
269269
}
270270

@@ -278,12 +278,6 @@ function setupFetch() {
278278
return undici;
279279
}
280280

281-
async function fetch(input, init = undefined) {
282-
return lazyUndici().fetch(input, init);
283-
}
284-
285-
defineOperation(globalThis, 'fetch', fetch);
286-
287281
function lazyInterface(name) {
288282
return {
289283
configurable: true,
@@ -297,17 +291,31 @@ function setupFetch() {
297291
};
298292
}
299293

300-
ObjectDefineProperties(globalThis, {
301-
FormData: lazyInterface('FormData'),
302-
Headers: lazyInterface('Headers'),
303-
Request: lazyInterface('Request'),
304-
Response: lazyInterface('Response'),
305-
});
294+
if (!getOptionValue('--no-experimental-fetch')) {
295+
async function fetch(input, init = undefined) {
296+
return lazyUndici().fetch(input, init);
297+
}
306298

307-
// The WebAssembly Web API: https://webassembly.github.io/spec/web-api
308-
internalBinding('wasm_web_api').setImplementation((streamState, source) => {
309-
require('internal/wasm_web_api').wasmStreamingCallback(streamState, source);
310-
});
299+
defineOperation(globalThis, 'fetch', fetch);
300+
301+
ObjectDefineProperties(globalThis, {
302+
FormData: lazyInterface('FormData'),
303+
Headers: lazyInterface('Headers'),
304+
Request: lazyInterface('Request'),
305+
Response: lazyInterface('Response'),
306+
});
307+
308+
// The WebAssembly Web API: https://webassembly.github.io/spec/web-api
309+
internalBinding('wasm_web_api').setImplementation((streamState, source) => {
310+
require('internal/wasm_web_api').wasmStreamingCallback(streamState, source);
311+
});
312+
}
313+
314+
if (getOptionValue('--experimental-websocket')) {
315+
ObjectDefineProperties(globalThis, {
316+
WebSocket: lazyInterface('WebSocket'),
317+
});
318+
}
311319
}
312320

313321
// TODO(aduh95): move this to internal/bootstrap/web/* when the CLI flag is

src/node_options.cc

+5
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,11 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
370370
&EnvironmentOptions::experimental_fetch,
371371
kAllowedInEnvvar,
372372
true);
373+
AddOption("--experimental-websocket",
374+
"experimental WebSocket API",
375+
&EnvironmentOptions::experimental_websocket,
376+
kAllowedInEnvvar,
377+
true);
373378
AddOption("--experimental-global-customevent",
374379
"expose experimental CustomEvent on the global scope",
375380
&EnvironmentOptions::experimental_global_customevent,

src/node_options.h

+1
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ class EnvironmentOptions : public Options {
111111
std::string dns_result_order;
112112
bool enable_source_maps = false;
113113
bool experimental_fetch = true;
114+
bool experimental_websocket = false;
114115
bool experimental_global_customevent = true;
115116
bool experimental_global_web_crypto = true;
116117
bool experimental_https_modules = false;

test/common/globals.js

+1
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ const webIdlExposedWindow = new Set([
123123
'Headers',
124124
'Request',
125125
'Response',
126+
'WebSocket',
126127
]);
127128

128129
const nodeGlobals = new Set([

test/common/index.js

+3
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,9 @@ if (global.ReadableStream) {
370370
global.DecompressionStream,
371371
);
372372
}
373+
if (global.WebSocket) {
374+
knownGlobals.push(WebSocket);
375+
}
373376

374377
function allowGlobals(...allowlist) {
375378
knownGlobals = knownGlobals.concat(allowlist);

test/parallel/test-websocket.js

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Flags: --experimental-websocket
2+
'use strict';
3+
4+
const assert = require('assert');
5+
6+
assert.equal(typeof WebSocket, 'function');

0 commit comments

Comments
 (0)