@lesomnus/grpc-dgram 0.0.1 → 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/CHANGELOG.md +43 -0
- package/README.md +61 -21
- package/dist/{conn-DOmx4nbt.mjs → conn-CmYPHTPR.mjs} +327 -23
- package/dist/conn-Dc57BC-h.d.mts +775 -0
- package/dist/index.d.mts +4 -3
- package/dist/index.mjs +238 -48
- package/dist/{protocol-K4Zy8MuQ.mjs → protocol-CTxSUZQF.mjs} +60 -5
- package/dist/transport/connect.d.mts +1 -1
- package/dist/transport/node-udp.d.mts +5 -4
- package/dist/transport/node-udp.mjs +16 -10
- package/dist/transport/port.d.mts +5 -4
- package/dist/transport/port.mjs +15 -8
- package/dist/transport/webrtc.d.mts +5 -4
- package/dist/transport/webrtc.mjs +13 -7
- package/dist/transport/websocket.d.mts +5 -4
- package/dist/transport/websocket.mjs +14 -8
- package/dist/transport/webtransport.d.mts +53 -0
- package/dist/transport/webtransport.mjs +144 -0
- package/dist/wasm/worker.mjs +20 -5
- package/dist/wasm.d.mts +7 -3
- package/dist/wasm.mjs +21 -9
- package/dist/{wire-BR8KiyRg.mjs → wire-DqHx0oUs.mjs} +211 -39
- package/package.json +6 -3
- package/dist/conn-DTWG9vIx.d.mts +0 -331
- package/dist/server-xIr1mwqq.d.mts +0 -112
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { n as Conn } from "../conn-CmYPHTPR.mjs";
|
|
2
|
+
import { F as Latch, Y as noop, c as decodeEnvelope, it as unpack, u as encodeEnvelope } from "../wire-DqHx0oUs.mjs";
|
|
3
|
+
import { n as MessageTooLargeError, r as StatusError } from "../status-DZwMDWIn.mjs";
|
|
4
|
+
//#region src/transport/webtransport/index.ts
|
|
5
|
+
const DefaultMaxMessageSize = 1200;
|
|
6
|
+
function closeCauseOf(info) {
|
|
7
|
+
const i = info;
|
|
8
|
+
const code = typeof i?.closeCode === "number" ? i.closeCode : 0;
|
|
9
|
+
const reason = typeof i?.reason === "string" && i.reason !== "" ? `: ${i.reason}` : "";
|
|
10
|
+
if (code === 0 && reason === "") return void 0;
|
|
11
|
+
return /* @__PURE__ */ new Error(`webtransport: session closed with code ${code}${reason}`);
|
|
12
|
+
}
|
|
13
|
+
function bytesOf(v) {
|
|
14
|
+
if (v instanceof Uint8Array) return v;
|
|
15
|
+
if (ArrayBuffer.isView(v)) return new Uint8Array(v.buffer, v.byteOffset, v.byteLength);
|
|
16
|
+
if (v instanceof ArrayBuffer) return new Uint8Array(v);
|
|
17
|
+
}
|
|
18
|
+
var WebTransportDatagramTransport = class {
|
|
19
|
+
wt;
|
|
20
|
+
max;
|
|
21
|
+
writer;
|
|
22
|
+
reader;
|
|
23
|
+
opened = new Latch();
|
|
24
|
+
dead = new Latch();
|
|
25
|
+
err;
|
|
26
|
+
attached = false;
|
|
27
|
+
closed = false;
|
|
28
|
+
constructor(wt, opts = {}) {
|
|
29
|
+
this.wt = wt;
|
|
30
|
+
this.max = opts.maxMessageSize;
|
|
31
|
+
const ds = wt.datagrams;
|
|
32
|
+
let sink;
|
|
33
|
+
if (typeof ds.createWritable === "function") try {
|
|
34
|
+
sink = ds.createWritable();
|
|
35
|
+
} catch (e) {
|
|
36
|
+
this.fail(e);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
sink = ds.writable;
|
|
40
|
+
if (sink === void 0) throw new Error("webtransport: session exposes neither datagrams.createWritable() nor datagrams.writable");
|
|
41
|
+
}
|
|
42
|
+
this.writer = sink?.getWriter();
|
|
43
|
+
this.writer?.closed.catch(noop);
|
|
44
|
+
wt.ready.then(() => this.opened.trip(), (e) => this.fail(e));
|
|
45
|
+
wt.closed.then((info) => this.fail(closeCauseOf(info)), (e) => this.fail(e));
|
|
46
|
+
}
|
|
47
|
+
reliable() {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
attachConn(conn) {
|
|
51
|
+
if (this.attached) throw new Error("webtransport: transport already attached to a Conn");
|
|
52
|
+
this.attached = true;
|
|
53
|
+
const reader = this.wt.datagrams.readable.getReader();
|
|
54
|
+
this.reader = reader;
|
|
55
|
+
this.pump(conn, reader);
|
|
56
|
+
this.dead.wait().then(() => {
|
|
57
|
+
conn.close(this.err);
|
|
58
|
+
this.close();
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
async pump(conn, reader) {
|
|
62
|
+
try {
|
|
63
|
+
for (;;) {
|
|
64
|
+
const { done, value } = await reader.read();
|
|
65
|
+
if (done) return;
|
|
66
|
+
if (this.dead.tripped) return;
|
|
67
|
+
const data = bytesOf(value);
|
|
68
|
+
if (data === void 0) continue;
|
|
69
|
+
let frames;
|
|
70
|
+
try {
|
|
71
|
+
frames = decodeEnvelope(data);
|
|
72
|
+
} catch {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
unpack(frames, conn, {});
|
|
76
|
+
}
|
|
77
|
+
} catch {}
|
|
78
|
+
}
|
|
79
|
+
limit() {
|
|
80
|
+
if (this.max !== void 0) return this.max;
|
|
81
|
+
if (!this.opened.tripped) return DefaultMaxMessageSize;
|
|
82
|
+
const m = this.wt.datagrams.maxDatagramSize;
|
|
83
|
+
return typeof m === "number" && m > 0 ? m : DefaultMaxMessageSize;
|
|
84
|
+
}
|
|
85
|
+
check(data) {
|
|
86
|
+
const max = this.limit();
|
|
87
|
+
if (max > 0 && data.length > max) throw new MessageTooLargeError(`webtransport: ${data.length}-byte envelope over the ${max}-byte limit`);
|
|
88
|
+
}
|
|
89
|
+
sendFrames(frames) {
|
|
90
|
+
const data = encodeEnvelope(frames);
|
|
91
|
+
this.check(data);
|
|
92
|
+
return this.send(data);
|
|
93
|
+
}
|
|
94
|
+
handle(f) {
|
|
95
|
+
return this.sendFrames([f]);
|
|
96
|
+
}
|
|
97
|
+
async send(data) {
|
|
98
|
+
if (!this.opened.tripped) {
|
|
99
|
+
await Promise.race([this.opened.wait(), this.dead.wait()]);
|
|
100
|
+
if (this.dead.tripped) throw this.closedErr();
|
|
101
|
+
this.check(data);
|
|
102
|
+
}
|
|
103
|
+
const writer = this.writer;
|
|
104
|
+
if (writer === void 0 || this.dead.tripped) throw this.closedErr();
|
|
105
|
+
try {
|
|
106
|
+
await writer.write(data);
|
|
107
|
+
} catch (e) {
|
|
108
|
+
this.fail(e);
|
|
109
|
+
throw this.closedErr();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
fail(err) {
|
|
113
|
+
if (!this.dead.tripped && this.err === void 0) this.err = err;
|
|
114
|
+
this.dead.trip();
|
|
115
|
+
}
|
|
116
|
+
closedErr() {
|
|
117
|
+
const e = new StatusError(14, `webtransport: session closed${this.err instanceof Error ? `: ${this.err.message}` : ""}`);
|
|
118
|
+
if (this.err !== void 0) e.cause = this.err;
|
|
119
|
+
return e;
|
|
120
|
+
}
|
|
121
|
+
close() {
|
|
122
|
+
if (this.closed) return;
|
|
123
|
+
this.closed = true;
|
|
124
|
+
this.fail(void 0);
|
|
125
|
+
try {
|
|
126
|
+
this.wt.close();
|
|
127
|
+
} catch {}
|
|
128
|
+
this.reader?.cancel().catch(noop);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
function dialWebTransport(url, opts = {}) {
|
|
132
|
+
const ctor = globalThis.WebTransport;
|
|
133
|
+
if (ctor === void 0) throw new Error("webtransport: this runtime has no global WebTransport; construct one and pass it to new WebTransportDatagramTransport()");
|
|
134
|
+
const { allowPooling, congestionControl, protocols, requireUnreliable = true, serverCertificateHashes } = opts;
|
|
135
|
+
return new Conn(new WebTransportDatagramTransport(new ctor(url, {
|
|
136
|
+
allowPooling,
|
|
137
|
+
congestionControl,
|
|
138
|
+
protocols,
|
|
139
|
+
requireUnreliable,
|
|
140
|
+
serverCertificateHashes
|
|
141
|
+
}), opts), opts);
|
|
142
|
+
}
|
|
143
|
+
//#endregion
|
|
144
|
+
export { DefaultMaxMessageSize, WebTransportDatagramTransport, dialWebTransport };
|
package/dist/wasm/worker.mjs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { o as startInstance, t as isPageMessage } from "../protocol-
|
|
1
|
+
import { o as startInstance, t as isPageMessage } from "../protocol-CTxSUZQF.mjs";
|
|
2
2
|
//#region src/wasm/worker.ts
|
|
3
3
|
const GOODBYE = /* @__PURE__ */ new Uint8Array(0);
|
|
4
4
|
function serveIn(scope) {
|
|
5
5
|
const ports = /* @__PURE__ */ new Set();
|
|
6
6
|
let instance;
|
|
7
7
|
let gone = false;
|
|
8
|
+
let answered = false;
|
|
8
9
|
const bury = () => {
|
|
9
10
|
gone = true;
|
|
10
11
|
for (const port of ports) farewell(port);
|
|
@@ -14,13 +15,20 @@ function serveIn(scope) {
|
|
|
14
15
|
const msg = ev.data;
|
|
15
16
|
if (!isPageMessage(msg)) return;
|
|
16
17
|
if (msg.drpc === "start") {
|
|
17
|
-
if (instance !== void 0)
|
|
18
|
+
if (instance !== void 0) {
|
|
19
|
+
if (answered) scope.postMessage({
|
|
20
|
+
drpc: "error",
|
|
21
|
+
message: "this worker already runs an instance — a second server in it is a second entry point, dialled with sock.dial({ entryPoint }), not a second open()"
|
|
22
|
+
});
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
18
25
|
instance = startInstance(msg.app, {
|
|
19
26
|
entryPoint: msg.entryPoint,
|
|
20
27
|
readyTimeoutMs: msg.readyTimeoutMs,
|
|
21
28
|
wasmExec: msg.wasmExec
|
|
22
29
|
});
|
|
23
30
|
instance.then((inst) => {
|
|
31
|
+
answered = true;
|
|
24
32
|
scope.postMessage({ drpc: "ready" });
|
|
25
33
|
inst.exited.then((cause) => {
|
|
26
34
|
bury();
|
|
@@ -30,6 +38,7 @@ function serveIn(scope) {
|
|
|
30
38
|
});
|
|
31
39
|
});
|
|
32
40
|
}, (e) => {
|
|
41
|
+
answered = true;
|
|
33
42
|
bury();
|
|
34
43
|
scope.postMessage({
|
|
35
44
|
drpc: "error",
|
|
@@ -46,14 +55,20 @@ function serveIn(scope) {
|
|
|
46
55
|
}
|
|
47
56
|
ports.add(port);
|
|
48
57
|
instance.then((inst) => {
|
|
58
|
+
let served;
|
|
49
59
|
try {
|
|
50
|
-
inst.serve(port);
|
|
60
|
+
served = inst.serve(port, msg.entryPoint, msg.readyTimeoutMs);
|
|
51
61
|
} catch {
|
|
52
|
-
|
|
53
|
-
|
|
62
|
+
abandon(port);
|
|
63
|
+
return;
|
|
54
64
|
}
|
|
65
|
+
served.catch(() => abandon(port));
|
|
55
66
|
}, () => {});
|
|
56
67
|
});
|
|
68
|
+
function abandon(port) {
|
|
69
|
+
ports.delete(port);
|
|
70
|
+
farewell(port);
|
|
71
|
+
}
|
|
57
72
|
}
|
|
58
73
|
function farewell(port) {
|
|
59
74
|
try {
|
package/dist/wasm.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { i as ConnOptions, r as Conn } from "./conn-Dc57BC-h.mjs";
|
|
2
2
|
import { PortOptions } from "./transport/port.mjs";
|
|
3
3
|
//#region src/wasm/instance.d.ts
|
|
4
4
|
declare const DefaultEntryPoint = "drpcServe";
|
|
@@ -25,12 +25,16 @@ interface OpenOptions extends PortOptions {
|
|
|
25
25
|
readyTimeoutMs?: number;
|
|
26
26
|
go?: GoLike;
|
|
27
27
|
}
|
|
28
|
+
interface DialOptions extends ConnOptions {
|
|
29
|
+
entryPoint?: string;
|
|
30
|
+
readyTimeoutMs?: number;
|
|
31
|
+
}
|
|
28
32
|
interface WasmSock {
|
|
29
33
|
readonly worker?: WasmWorker;
|
|
30
34
|
readonly exited: Promise<unknown>;
|
|
31
|
-
dial(opts?:
|
|
35
|
+
dial(opts?: DialOptions): Conn;
|
|
32
36
|
close(): void;
|
|
33
37
|
}
|
|
34
38
|
declare function open(app: WasmApp, opts?: OpenOptions): Promise<WasmSock>;
|
|
35
39
|
//#endregion
|
|
36
|
-
export { DefaultEntryPoint, DefaultReadyTimeoutMs, DefaultWasmExec, type GoLike, OpenOptions, type WasmApp, WasmSock, WasmWorker, open };
|
|
40
|
+
export { DefaultEntryPoint, DefaultReadyTimeoutMs, DefaultWasmExec, DialOptions, type GoLike, OpenOptions, type WasmApp, WasmSock, WasmWorker, open };
|
package/dist/wasm.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { n as Conn } from "./conn-
|
|
1
|
+
import { n as Conn } from "./conn-CmYPHTPR.mjs";
|
|
2
2
|
import { PortTransport } from "./transport/port.mjs";
|
|
3
|
-
import { a as DefaultWasmExec, i as DefaultReadyTimeoutMs, n as isWorkerMessage, o as startInstance, r as DefaultEntryPoint } from "./protocol-
|
|
3
|
+
import { a as DefaultWasmExec, i as DefaultReadyTimeoutMs, n as isWorkerMessage, o as startInstance, r as DefaultEntryPoint } from "./protocol-CTxSUZQF.mjs";
|
|
4
4
|
//#region src/wasm/index.ts
|
|
5
5
|
async function open(app, opts = {}) {
|
|
6
6
|
if (opts.worker === false) return new HereSock(await startInstance(app, opts), opts);
|
|
@@ -38,9 +38,10 @@ var Sock = class {
|
|
|
38
38
|
const what = this.closed ? "this sock is closed" : "the wasm instance has exited";
|
|
39
39
|
throw new Error(`wasm: ${what}${this.dead.cause instanceof Error ? `: ${this.dead.cause.message}` : ""}`);
|
|
40
40
|
}
|
|
41
|
-
const
|
|
41
|
+
const { entryPoint, readyTimeoutMs, ...connOpts } = opts;
|
|
42
|
+
const tx = this.connect(entryPoint, readyTimeoutMs);
|
|
42
43
|
this.txs.add(tx);
|
|
43
|
-
return new Conn(tx,
|
|
44
|
+
return new Conn(tx, connOpts);
|
|
44
45
|
}
|
|
45
46
|
close() {
|
|
46
47
|
if (this.closed) return;
|
|
@@ -53,7 +54,14 @@ var Sock = class {
|
|
|
53
54
|
let tx;
|
|
54
55
|
try {
|
|
55
56
|
tx = new PortTransport(ch.port1, this.o);
|
|
56
|
-
handover(ch.port2);
|
|
57
|
+
const handed = handover(ch.port2);
|
|
58
|
+
if (handed !== void 0) {
|
|
59
|
+
const t = tx;
|
|
60
|
+
handed.catch((e) => {
|
|
61
|
+
this.txs.delete(t);
|
|
62
|
+
t.close(e);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
57
65
|
return tx;
|
|
58
66
|
} catch (e) {
|
|
59
67
|
tx?.close(e);
|
|
@@ -105,8 +113,12 @@ var WorkerSock = class extends Sock {
|
|
|
105
113
|
this.worker.postMessage(start);
|
|
106
114
|
return this.readiness;
|
|
107
115
|
}
|
|
108
|
-
connect() {
|
|
109
|
-
const serve = {
|
|
116
|
+
connect(entryPoint, readyTimeoutMs) {
|
|
117
|
+
const serve = {
|
|
118
|
+
drpc: "serve",
|
|
119
|
+
...entryPoint === void 0 ? {} : { entryPoint },
|
|
120
|
+
...readyTimeoutMs === void 0 ? {} : { readyTimeoutMs }
|
|
121
|
+
};
|
|
110
122
|
return this.channelTo((port) => this.worker.postMessage(serve, [port]));
|
|
111
123
|
}
|
|
112
124
|
stop() {
|
|
@@ -147,8 +159,8 @@ var HereSock = class extends Sock {
|
|
|
147
159
|
this.inst = inst;
|
|
148
160
|
inst.exited.then((cause) => this.bury(cause));
|
|
149
161
|
}
|
|
150
|
-
connect() {
|
|
151
|
-
return this.channelTo((port) => this.inst.serve(port));
|
|
162
|
+
connect(entryPoint, readyTimeoutMs) {
|
|
163
|
+
return this.channelTo((port) => this.inst.serve(port, entryPoint, readyTimeoutMs));
|
|
152
164
|
}
|
|
153
165
|
stop() {}
|
|
154
166
|
};
|