ventiws 1.0.0-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Farben
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,138 @@
1
+ <p align="center">
2
+ <img src="misc/ventiws_banner.png" alt="ventiws banner" />
3
+ </p>
4
+
5
+ # ventiws
6
+
7
+ A WebSocket implementation for Node.js with the API of
8
+ [`ws`](https://github.com/websockets/ws), delivered as a native addon whose framing
9
+ engine is written in Zig. It targets `ws` 8.21.3 and reproduces that release's
10
+ observable behaviour rather than its source. ventiws is not affiliated with the
11
+ `ws` project and vendors none of its code; the upstream API reference is vendored
12
+ as the pinned contract, credited in
13
+ [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
14
+
15
+ **ventiws is at `1.0.0-alpha`.** Nothing is published to npm yet, so an
16
+ install builds the addon for one platform, and the surface may change between
17
+ alpha releases. What "alpha" means here is bounded: the `ws` compatibility
18
+ contract is tracked row by row in
19
+ [COMPATIBILITY.md](COMPATIBILITY.md), and the four places ventiws knowingly
20
+ differs from `ws` are listed in [CHANGELOG.md](CHANGELOG.md) under "Known
21
+ divergences from `ws`".
22
+
23
+ ## Install
24
+
25
+ Working in the tree:
26
+
27
+ ```sh
28
+ git clone git@github.com:farbenbuilds/ventiws.git
29
+ cd ventiws
30
+ nix develop
31
+ pnpm install
32
+ pnpm build
33
+ ```
34
+
35
+ Published usage, once a release lands:
36
+
37
+ ```sh
38
+ pnpm add ventiws
39
+ ```
40
+
41
+ `nix develop` pins Node.js, pnpm, and Zig 0.16.0. The first `pnpm build` compiles
42
+ the vendored C dependencies, which takes minutes and about a gigabyte; later
43
+ builds are incremental.
44
+
45
+ ## Usage
46
+
47
+ ```ts
48
+ import { WebSocket, WebSocketServer } from "ventiws";
49
+
50
+ const server = new WebSocketServer({ port: 8080 });
51
+
52
+ server.on("listening", () => {
53
+ console.log("listening on", server.address()?.port);
54
+ });
55
+
56
+ server.on("connection", (socket) => {
57
+ socket.on("message", (data, isBinary) => {
58
+ socket.send(isBinary ? data : `echo: ${data.toString()}`);
59
+ });
60
+ socket.on("close", (code, reason) => {
61
+ console.log("closed", code, reason.toString());
62
+ });
63
+ });
64
+
65
+ const client = new WebSocket("ws://127.0.0.1:8080/");
66
+ client.on("open", () => client.send("hello"));
67
+ client.on("message", (data) => console.log("client saw", data.toString()));
68
+ client.on("error", (error) => console.error(error));
69
+ ```
70
+
71
+ Both halves run against a real `ws` peer in this repository's suites, and the
72
+ constructors are plain functions returning state records: no `class`, no `this`,
73
+ no prototype.
74
+
75
+ ## Status
76
+
77
+ Option defaults match `ws`: `maxPayload` 100 MiB, `maxFragments` 16384, and
78
+ `closeTimeout` 30000 ms. The itemised matrix, with the owner module and the
79
+ evidence test behind every row, is [COMPATIBILITY.md](COMPATIBILITY.md).
80
+
81
+ | Area | State |
82
+ | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
83
+ | `WebSocketServer`: options, events, `handleUpgrade`, `shouldHandle`, `verifyClient` | Works, compared property for property against `ws` |
84
+ | Server-side `WebSocket`: properties, `on*` and DOM handlers, ready states | Works, with exactly-once `close` |
85
+ | `WebSocket` client: `net` and `tls`, redirects, `ws+unix:`, `unexpected-response` | Works against a real `ws` server |
86
+ | `send`, fragmentation, `binaryType`, `ping`/`pong`, close codes | Works both directions; `maxPayload` and `maxFragments` are enforced per connection |
87
+ | `permessage-deflate` | Works; context takeover is declined in both directions ([why](COMPATIBILITY.md#shared-with-the-engine)) |
88
+ | `createWebSocketStream`, `clientTracking`, `server.options` | Works, including the `WebSocket` class option |
89
+ | Engine route message cap, 64 KiB | A property of the build. [Two limits](#two-limits-worth-knowing) |
90
+ | Engine route inbound ring, 64 messages | Excess is dropped and counted. Same section |
91
+ | RFC 6455 Autobahn suite | Regression gate; 424 of 517 cases in the full run, 268 in the framing selection ([matrix](COMPATIBILITY.md#rfc-6455-conformance)) |
92
+ | Client `wss:` to `ws:` downgrade, redirect hop limit, `origin`, `handshakeTimeout` | Implemented with no behavioural test ([outstanding](COMPATIBILITY.md#what-is-still-outstanding)) |
93
+
94
+ ## Two limits worth knowing
95
+
96
+ **The 64 KiB message cap.** `message_capacity` in
97
+ `src/engine/server/capacities.zig` is a `comptime` constant, so it is baked into
98
+ the addon: `maxPayload` sizes each connection's own ceiling and does not lift this
99
+ one. 64 KiB is the largest payload the conformance suite puts on the wire, and a
100
+ frame above it is closed with 1009. Raising it costs about 22 MB per live server,
101
+ because the message slab, the write queue, and both staging rings scale with it.
102
+
103
+ **The 64-slot inbound ring.** The engine has no hook for stopping a read when its
104
+ consumer falls behind, so the ring in `src/engine/server/instance.zig` is the
105
+ only place a burst can be absorbed. It holds 64 messages, and a peer delivering
106
+ more before the Node main thread drains has the excess dropped and counted by
107
+ `serverDroppedMessages`. `ws` applies backpressure instead, so it has no cliff.
108
+
109
+ Both bind the engine route, which is µWebZockets' own listener. The codec route
110
+ the public `ws` surface uses is bound by neither: its buffers grow into each
111
+ connection's own `maxPayload` and `maxFragments`. `engineLimits()` is exported
112
+ from the package entry, so the compiled numbers are readable at runtime.
113
+
114
+ ## Commands
115
+
116
+ ```sh
117
+ pnpm build
118
+ pnpm test
119
+ pnpm test:compat
120
+ pnpm test:autobahn
121
+ pnpm bench
122
+ pnpm typecheck
123
+ pnpm lint
124
+ pnpm format:check
125
+ ```
126
+
127
+ ## Docs and licence
128
+
129
+ - [COMPATIBILITY.md](COMPATIBILITY.md): every `ws` surface item, its owner module, its status, and its evidence test.
130
+ - [CODEBASE.md](CODEBASE.md): repository layout, the two routes, the boundary, and the compiled capacities.
131
+ - [CODING_CONVENTION.md](CODING_CONVENTION.md): TypeScript and Zig style, the anti-OOP rules, and the module budget.
132
+ - [docs/migrating.md](docs/migrating.md): moving an existing `ws` application over.
133
+ - [CONTRIBUTE.md](CONTRIBUTE.md): environment setup, the script contract, and how to release.
134
+
135
+ MIT. See [LICENSE](LICENSE). `ws` is copyright Einar Otto Stangvik, Arnout
136
+ Kazemier, and contributors, MIT-licensed. µWebZockets is the first-party
137
+ MIT-licensed protocol engine written for this project. Provenance for everything
138
+ vendored or CI-only is in [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).