@moq/web-transport 0.0.4 → 0.1.0
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/README.md +97 -0
- package/{index.d.ts → napi.d.ts} +2 -0
- package/package.json +9 -9
- package/src/datagrams.ts +1 -1
- package/src/index.ts +3 -1
- package/src/request.ts +24 -0
- package/src/server.ts +24 -0
- package/src/session.ts +1 -1
- package/web-transport.darwin-arm64.node +0 -0
- package/web-transport.darwin-x64.node +0 -0
- package/web-transport.linux-arm64-gnu.node +0 -0
- package/web-transport.linux-x64-gnu.node +0 -0
- package/web-transport.win32-x64-msvc.node +0 -0
- /package/{index.js → napi.js} +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# @moq/web-transport
|
|
2
|
+
|
|
3
|
+
WebTransport for Node.js, powered by QUIC and HTTP/3.
|
|
4
|
+
|
|
5
|
+
This package provides both a client-side `WebTransport` polyfill and a server implementation.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @moq/web-transport
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Client
|
|
14
|
+
|
|
15
|
+
The `Session` class implements the [W3C WebTransport API](https://www.w3.org/TR/webtransport/).
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import Session from "@moq/web-transport";
|
|
19
|
+
|
|
20
|
+
const session = new Session("https://example.com:4443");
|
|
21
|
+
await session.ready;
|
|
22
|
+
|
|
23
|
+
// Bidirectional streams
|
|
24
|
+
const bidi = await session.createBidirectionalStream();
|
|
25
|
+
const writer = bidi.writable.getWriter();
|
|
26
|
+
await writer.write(new Uint8Array([1, 2, 3]));
|
|
27
|
+
await writer.close();
|
|
28
|
+
|
|
29
|
+
// Unidirectional streams
|
|
30
|
+
const uni = await session.createUnidirectionalStream();
|
|
31
|
+
const uniWriter = uni.getWriter();
|
|
32
|
+
await uniWriter.write(new Uint8Array([4, 5, 6]));
|
|
33
|
+
await uniWriter.close();
|
|
34
|
+
|
|
35
|
+
// Datagrams
|
|
36
|
+
const dgWriter = session.datagrams.writable.getWriter();
|
|
37
|
+
await dgWriter.write(new Uint8Array([7, 8, 9]));
|
|
38
|
+
|
|
39
|
+
// Incoming streams
|
|
40
|
+
for await (const recv of session.incomingUnidirectionalStreams) {
|
|
41
|
+
const reader = recv.getReader();
|
|
42
|
+
// read from reader...
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
session.close();
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Polyfill
|
|
49
|
+
|
|
50
|
+
Use `install()` to register `Session` as the global `WebTransport` if one doesn't already exist:
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
import { install } from "@moq/web-transport";
|
|
54
|
+
install();
|
|
55
|
+
|
|
56
|
+
// Now use the standard WebTransport API
|
|
57
|
+
const session = new WebTransport("https://example.com:4443");
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Certificate Options
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
// Skip certificate verification (testing only!)
|
|
64
|
+
const session = new Session("https://localhost:4443", {
|
|
65
|
+
serverCertificateDisableVerify: true,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Pin to specific certificate hashes
|
|
69
|
+
const session = new Session("https://example.com:4443", {
|
|
70
|
+
serverCertificateHashes: [
|
|
71
|
+
{ algorithm: "sha-256", value: hashBuffer },
|
|
72
|
+
],
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Server
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { Server } from "@moq/web-transport";
|
|
80
|
+
import fs from "node:fs";
|
|
81
|
+
|
|
82
|
+
const certPem = fs.readFileSync("cert.pem");
|
|
83
|
+
const keyPem = fs.readFileSync("key.pem");
|
|
84
|
+
|
|
85
|
+
const server = Server.bind("[::]:4443", certPem, keyPem);
|
|
86
|
+
|
|
87
|
+
while (true) {
|
|
88
|
+
const request = await server.accept();
|
|
89
|
+
if (!request) break;
|
|
90
|
+
|
|
91
|
+
const url = await request.url;
|
|
92
|
+
console.log("incoming request:", url);
|
|
93
|
+
|
|
94
|
+
const session = await request.ok();
|
|
95
|
+
// Use session just like the client-side API
|
|
96
|
+
}
|
|
97
|
+
```
|
package/{index.d.ts → napi.d.ts}
RENAMED
|
@@ -59,6 +59,8 @@ export declare class NapiServer {
|
|
|
59
59
|
static bind(addr: string, certPem: Buffer, keyPem: Buffer): NapiServer;
|
|
60
60
|
/** Accept the next incoming WebTransport session request. */
|
|
61
61
|
accept(): Promise<NapiRequest | null>;
|
|
62
|
+
/** Close the server, stopping it from accepting new connections. */
|
|
63
|
+
close(): void;
|
|
62
64
|
}
|
|
63
65
|
|
|
64
66
|
/** An established WebTransport session. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moq/web-transport",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "WebTransport polyfill for Node.js via QUIC/HTTP3",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "(MIT OR Apache-2.0)",
|
|
@@ -21,12 +21,12 @@
|
|
|
21
21
|
"types": "./src/index.ts",
|
|
22
22
|
"files": [
|
|
23
23
|
"./src",
|
|
24
|
-
"
|
|
25
|
-
"
|
|
24
|
+
"napi.js",
|
|
25
|
+
"napi.d.ts",
|
|
26
26
|
"*.node"
|
|
27
27
|
],
|
|
28
28
|
"scripts": {
|
|
29
|
-
"build": "napi build --platform --release --manifest-path ../../rs/web-transport-node/Cargo.toml --output-dir .",
|
|
29
|
+
"build": "napi build --platform --release --manifest-path ../../rs/web-transport-node/Cargo.toml --output-dir . --js napi.js --dts napi.d.ts",
|
|
30
30
|
"check": "tsc --noEmit",
|
|
31
31
|
"release": "bun scripts/release.ts"
|
|
32
32
|
},
|
|
@@ -36,11 +36,11 @@
|
|
|
36
36
|
"@types/node": "^24.3.0"
|
|
37
37
|
},
|
|
38
38
|
"optionalDependencies": {
|
|
39
|
-
"@moq/web-transport-darwin-x64": "0.0
|
|
40
|
-
"@moq/web-transport-darwin-arm64": "0.0
|
|
41
|
-
"@moq/web-transport-win32-x64-msvc": "0.0
|
|
42
|
-
"@moq/web-transport-linux-x64-gnu": "0.0
|
|
43
|
-
"@moq/web-transport-linux-arm64-gnu": "0.0
|
|
39
|
+
"@moq/web-transport-darwin-x64": "0.1.0",
|
|
40
|
+
"@moq/web-transport-darwin-arm64": "0.1.0",
|
|
41
|
+
"@moq/web-transport-win32-x64-msvc": "0.1.0",
|
|
42
|
+
"@moq/web-transport-linux-x64-gnu": "0.1.0",
|
|
43
|
+
"@moq/web-transport-linux-arm64-gnu": "0.1.0"
|
|
44
44
|
},
|
|
45
45
|
"keywords": [
|
|
46
46
|
"webtransport",
|
package/src/datagrams.ts
CHANGED
package/src/index.ts
CHANGED
package/src/request.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { NapiRequest } from "../napi.js";
|
|
2
|
+
import Session from "./session.ts";
|
|
3
|
+
|
|
4
|
+
export class Request {
|
|
5
|
+
#inner: NapiRequest;
|
|
6
|
+
|
|
7
|
+
/** @internal */
|
|
8
|
+
constructor(inner: NapiRequest) {
|
|
9
|
+
this.#inner = inner;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
get url(): Promise<string> {
|
|
13
|
+
return this.#inner.url;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async ok(): Promise<Session> {
|
|
17
|
+
const session = await this.#inner.ok();
|
|
18
|
+
return new Session(session);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
reject(status: number): Promise<void> {
|
|
22
|
+
return this.#inner.reject(status);
|
|
23
|
+
}
|
|
24
|
+
}
|
package/src/server.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { NapiServer } from "../napi.js";
|
|
2
|
+
import { Request } from "./request.ts";
|
|
3
|
+
|
|
4
|
+
export class Server {
|
|
5
|
+
#inner: NapiServer;
|
|
6
|
+
|
|
7
|
+
private constructor(inner: NapiServer) {
|
|
8
|
+
this.#inner = inner;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
static bind(addr: string, certPem: Buffer, keyPem: Buffer): Server {
|
|
12
|
+
return new Server(NapiServer.bind(addr, certPem, keyPem));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async accept(): Promise<Request | null> {
|
|
16
|
+
const inner = await this.#inner.accept();
|
|
17
|
+
if (!inner) return null;
|
|
18
|
+
return new Request(inner);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
close(): void {
|
|
22
|
+
this.#inner.close();
|
|
23
|
+
}
|
|
24
|
+
}
|
package/src/session.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NapiClient, type NapiRecvStream, type NapiSendStream, type NapiSession } from "../
|
|
1
|
+
import { NapiClient, type NapiRecvStream, type NapiSendStream, type NapiSession } from "../napi.js";
|
|
2
2
|
import { Datagrams } from "./datagrams.ts";
|
|
3
3
|
|
|
4
4
|
function wrapRecvStream(recv: NapiRecvStream): ReadableStream<Uint8Array> {
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
/package/{index.js → napi.js}
RENAMED
|
File without changes
|