Skip to content

Commit e28dbe1

Browse files
authored
lib: add WebSocket client
fixup add test lint fixup update doc/node.1 PR-URL: #49830 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Robert Nagy <ronagy@icloud.com>
1 parent a4fdb1a commit e28dbe1

File tree

10 files changed

+72
-20
lines changed

10 files changed

+72
-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
@@ -2248,6 +2256,7 @@ Node.js options that are allowed are:
22482256
* `--experimental-vm-modules`
22492257
* `--experimental-wasi-unstable-preview1`
22502258
* `--experimental-wasm-modules`
2259+
* `--experimental-websocket`
22512260
* `--force-context-aware`
22522261
* `--force-fips`
22532262
* `--force-node-api-uncaught-exceptions-policy`
@@ -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
@@ -1018,6 +1018,17 @@ The object that acts as the namespace for all W3C
10181018
[WebAssembly][webassembly-org] related functionality. See the
10191019
[Mozilla Developer Network][webassembly-mdn] for usage and compatibility.
10201020

1021+
## `WebSocket`
1022+
1023+
<!-- YAML
1024+
added: REPLACEME
1025+
-->
1026+
1027+
> Stability: 1 - Experimental.
1028+
1029+
A browser-compatible implementation of [`WebSocket`][]. Enable this API
1030+
with the [`--experimental-websocket`][] CLI flag.
1031+
10211032
## Class: `WritableStream`
10221033

10231034
<!-- YAML
@@ -1052,6 +1063,7 @@ A browser-compatible implementation of [`WritableStreamDefaultWriter`][].
10521063
[ECMAScript module]: esm.md
10531064
[Navigator API]: https://html.spec.whatwg.org/multipage/system-state.html#the-navigator-object
10541065
[Web Crypto API]: webcrypto.md
1066+
[`--experimental-websocket`]: cli.md#--experimental-websocket
10551067
[`--no-experimental-global-customevent`]: cli.md#--no-experimental-global-customevent
10561068
[`--no-experimental-global-webcrypto`]: cli.md#--no-experimental-global-webcrypto
10571069
[`AbortController`]: https://developer.mozilla.org/en-US/docs/Web/API/AbortController
@@ -1085,6 +1097,7 @@ A browser-compatible implementation of [`WritableStreamDefaultWriter`][].
10851097
[`TransformStream`]: webstreams.md#class-transformstream
10861098
[`URLSearchParams`]: url.md#class-urlsearchparams
10871099
[`URL`]: url.md#class-url
1100+
[`WebSocket`]: https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
10881101
[`WritableStreamDefaultController`]: webstreams.md#class-writablestreamdefaultcontroller
10891102
[`WritableStreamDefaultWriter`]: webstreams.md#class-writablestreamdefaultwriter
10901103
[`WritableStream`]: webstreams.md#class-writablestream

doc/node.1

+3
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,9 @@ Use this flag to enable ShadowRealm support.
178178
.It Fl -experimental-test-coverage
179179
Enable code coverage in the test runner.
180180
.
181+
.It Fl -experimental-websocket
182+
Enable experimental support for the WebSocket API.
183+
.
181184
.It Fl -no-experimental-fetch
182185
Disable experimental support for the Fetch API.
183186
.

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

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

0 commit comments

Comments
 (0)