Repository navigation
feat(proxy): support unix socket targets out of the box - #197
Merged
Merged
Conversation
Support `ws+unix://<socketPath>:<pathname>` proxy targets across Node, Deno, and Bun with no custom `WebSocket` constructor: Bun dials natively, Deno routes via `Deno.createHttpClient`'s unix `client`, and Node dials with a lazily-imported (prebundled, edge-safe) `ws` client. Also adds `webSocketOptions` to merge per-peer options into the upstream constructor as an escape hatch for other transports. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (14)
🔥 Files not summarized due to errors (14)
📝 Walkthrough
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…lients Delegate `ws+unix:` dialing to the runtime `crossws/websocket` client instead of embedding runtime logic in the proxy, so a Unix-socket upstream works out of the box on Node, Bun, and Deno. - add `src/websocket/deno.ts` and `src/websocket/bun.ts` wrappers; Deno routes `ws+unix:` through a unix `Deno.createHttpClient` client, Bun dials natively - make `src/websocket/node.ts` route `ws+unix:` through `ws` (Proxy over the native global) while keeping undici for `ws:`/`wss:` - proxy `_planDial` lazily imports the matching wrapper per runtime; the chunks stay out of the runtime-agnostic entry's eager graph - point the `crossws/websocket` bun/deno export conditions at the new wrappers - add cross-runtime tests for the wrappers and the OOTB Deno proxy path Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…time dispatch
Replace the proxy's runtime detection (`globalThis.{Bun,Deno}` checks + dynamic
`import()` of per-runtime clients) with a single static
`import runtimeWebSocket from "crossws/websocket"`. The export conditions resolve
the right client per runtime, and because the import is statically analyzable a
bundle built for a given runtime tree-shakes the others (e.g. `ws`/`node:*`
never enter a Deno or browser bundle).
- proxy: delete `_planDial`/`_DialPlan`/`_constructUpstream`/`optionsAsSecondArg`
and the async plan machinery; `_dialUpstream` is now one synchronous function
with a uniform `new ctor(url, protocols[, options])` call
- deno client: accept a third options object and relay it into Deno's
second-argument form (custom `client`, headers, …)
- mark `crossws/websocket` external so it stays a bare specifier in `dist`
- add `prepare: obuild --stub` so `dist` re-exports `src` for in-repo dev/tests
(no `development` condition / tsconfig / vitest / fixture flags needed)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pi0
marked this pull request as ready for review
July 2, 2026 11:21
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
pi0
approved these changes
Jul 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Proxy to a Unix-socket upstream by returning a
ws+unix://<socketPath>:<pathname>target — works out of the box on Node, Bun, and Deno, no customWebSocketconstructor required:The path before the
:is the socket file; the path after it is the request path forwarded upstream.How it dials
The proxy dials through a single static import of the runtime WebSocket client:
The
crossws/websocketexport conditions resolve the right client per runtime, and each client owns its own scheme handling — so the proxy has no runtime detection (globalThischecks) and no dynamicimport(). Because the import is statically analyzable, a bundle built for a given runtime tree-shakes the others (ws/node:*never enter a Deno or browser bundle):WebSocketdialsws+unix:natively.WebSocketrejects the scheme, so the Node client routesws+unix:throughws(bundled with crossws, no extra dependency), keeping the native global forws:/wss:.WebSocketrejects the scheme, so the Deno client routes the transport throughDeno.createHttpClient's unixclient(unstable — needs--unstable-net).crossws/websocketwrappersNew per-runtime entries make
ws+unix:(and, on Deno, custom dialing options) work through thecrossws/websocketclient itself, not just the proxy:src/websocket/deno.ts— subclasses the global; rewritesws+unix:to a plainws://target dialed through a unixDeno.createHttpClient, and relays a third options object into Deno's second-argument form.src/websocket/node.ts— aProxyover the native global that routesws+unix:(and everything on Node < 22) throughws, preserving the global's static members.src/websocket/bun.ts— re-exports the global (Bun dialsws+unix:natively).The
./websocketbun/denoexport conditions now point at these wrappers (werenative).crossws/websocketis kept external in the build (a bare specifier indist) so the consumer's runtime/bundler resolves the condition;prepare: obuild --stubmakesdistre-exportsrcso in-repo dev and tests resolve to source without a build.webSocketOptionsAdds a
webSocketOptionsoption (static or per-peer resolver) that passes extra dialing options to the upstream client — the escape hatch for transport options the URL can't express (e.g.ws/undicicreateConnection/dispatcher/agent, or a customDeno.createHttpClientclient). Merged withheaders, withheaderswinning on conflict.Tests
ws+unix:proxy path covered in-process (test/proxy.test.ts), routed through the Node client.test/proxy-runtimes.test.ts).crossws/websocketDeno + Bun wrappers covered by spawned fixtures (test/websocket-runtimes.test.ts).ws/node:*out of the Deno/browser wrappers and the eager edge graph.🤖 Generated with Claude Code