first commit
This commit is contained in:
49
docs/api-stack/api/api-ws-bun/src/handshake/subprotocol.md
Normal file
49
docs/api-stack/api/api-ws-bun/src/handshake/subprotocol.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# `subprotocol`
|
||||
|
||||
## Purpose
|
||||
|
||||
Implements RFC 6455 §4.1 subprotocol negotiation as a tiny pure function. The server is supplied the client's requested protocols and the server-supported list; the function returns the first server-supported protocol the client requested, or `null` when the client requested nothing.
|
||||
|
||||
This is exposed as a public utility because callers occasionally need to short-circuit the full handshake — for example, an OpenAPI documentation route advertising the engine's supported subprotocols before any actual upgrade.
|
||||
|
||||
## Features
|
||||
|
||||
- Strict RFC 6455 ordering — server-supported list determines priority, NOT the client's preference list.
|
||||
- Throws `WS_BUN.SUBPROTOCOL_UNSUPPORTED` when the client requested any subprotocol but none match.
|
||||
- Returns `null` for the common "client requested nothing" case.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { resolveSubprotocol } from "@suaveplan/api-ws-bun";
|
||||
|
||||
const chosen = resolveSubprotocol(
|
||||
["graphql-transport-ws"],
|
||||
["suaveplan.v1", "graphql-transport-ws"]
|
||||
);
|
||||
// chosen === "graphql-transport-ws"
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
import { WS_BUN_CODES, resolveSubprotocol } from "@suaveplan/api-ws-bun";
|
||||
|
||||
try {
|
||||
resolveSubprotocol(["unknown"], ["suaveplan.v1"]);
|
||||
} catch (err) {
|
||||
if ((err as { code?: string }).code === WS_BUN_CODES.SUBPROTOCOL_UNSUPPORTED) {
|
||||
// respond 400 with `Sec-WebSocket-Protocol: <server's list>`
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `resolveSubprotocol(requested, supported): string | null` — pure negotiation function.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
Server-priority ordering matters: a client might list `["graphql-ws", "graphql-transport-ws"]` expecting the older protocol, but if the server prefers the newer one and lists it first, the function returns `"graphql-transport-ws"`. That matches the RFC and matches the behaviour Bun's native `Server.upgrade` would apply if the negotiation were delegated to Bun itself.
|
||||
|
||||
The empty-`requested` short-circuit returns `null` rather than throwing because RFC 6455 explicitly permits handshakes with no `Sec-WebSocket-Protocol` header — the connection is valid, it just has no negotiated subprotocol. This is the default state for a Bun client written against the foundation's plain-JSON envelope wire format.
|
||||
Reference in New Issue
Block a user