Skip to content

Add WebSocketInit dictionary as option for second param in constructor - #76

Open
christhompson wants to merge 3 commits into
whatwg:mainfrom
christhompson:constructor-options
Open

christhompson wants to merge 3 commits into
whatwg:mainfrom
christhompson:constructor-options

Conversation

@christhompson

@christhompson christhompson commented Aug 4, 2026 •

Copy link
Copy Markdown

Adds the option for using a WebSocketInit dictionary as the second param in the WebSocket constructor. This updates the non-normative description of how the constructor works, and adds steps to the constructor processing algorithm to handle the case where the second param is a WebSocketInit dictionary (extracting the "protocols" field if present).

Fixes #42

(See WHATWG Working Mode: Changes for more details.)


Preview | Diff

@ricea ricea left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks minimal and good. I'm holding off on approval only because it's been so long since I've used Bikeshed I don't trust my eyes.

Comment thread index.bs Outdated
Comment thread index.bs
1. If |urlRecord|'s [=scheme=] is not "<code>[=ws=]</code>" or "<code>[=wss=]</code>", then throw a
"{{SyntaxError}}" {{DOMException}}.
1. If |urlRecord|'s [=fragment=] is non-null, then throw a "{{SyntaxError}}" {{DOMException}}.
1. Let |protocols| be an empty sequence.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
1. Let |protocols| be an empty sequence.
1. Let |protocols| be « ».
Comment thread index.bs
1. Let |protocols| be an empty sequence.
1. If |protocolsOrOptions| is a {{WebSocketInit}} dictionary, set |protocols| to
|protocolsOrOptions|["{{WebSocketInit/protocols}}"].
1. Otherwise, set |protocols| to |protocolsOrOptions|.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe using a lambda would be clearer here.

  1. Let protocols be the return value of running these steps:
    1. If protocolsOrOptions is a dictionary, then return protocolsOrOptions["protocols"].
    2. If protocolsOrOptions is a string, then return « protocolsOrOptions ».
    3. Return protocolsOrOptions.
@ricea

ricea commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

This change might not be web-compatible. I am currently investigating.

It turns out that new WebSocket(url, undefined, {}) is a pattern used in some web applications. I don't yet know how common it is. The popular ws Node.js WebSocket library takes a third-argument with an options bag. I have seen code like

new WebSocket(url, undefined, isNodeJS() ? { headers } : {});

in the wild.

Before this change, the above constructor call behaves like new WebSocket(url, "undefined"). If the server response headers include Sec-WebSocket-Protocol: undefined it will work.

After this change, the above constructor call behaves like new WebSocket(url, {}), which is functionally equivalent to new WebSocket(url). If the server response headers include Sec-WebSocket-Protocol: undefined it will fail the handshake due to the subprotocol mismatch.

Without actually trying it, I don't know whether servers will stop returning Sec-WebSocket-Protocol: undefined if clients stop requesting it, or continue to send it and fail.

@annevk

annevk commented Aug 27, 2026

Copy link
Copy Markdown
Member

Seems worth measuring. We could special case undefined, but that seems rather undesirable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

3 participants