@trevrpc/trevrpc-js 0.2.2 → 1.0.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 +89 -47
- package/bin/protoc-gen-trevrpc-js.js +1 -1
- package/package.json +11 -41
- package/src/bytes.js +10 -0
- package/src/call.js +287 -0
- package/src/channel.js +131 -296
- package/src/client.js +203 -1292
- package/src/framing.js +125 -519
- package/src/generator.js +26 -103
- package/src/index.d.ts +79 -452
- package/src/index.js +4 -3
- package/src/status.js +24 -70
- package/src/wire.js +4 -59
- package/examples/greeter/README.md +0 -35
- package/examples/greeter/client.js +0 -172
- package/examples/greeter/greeter.node.trevrpc.d.ts +0 -53
- package/examples/greeter/greeter.node.trevrpc.js +0 -9
- package/examples/greeter/greeter.proto +0 -18
- package/examples/greeter/greeter.trevrpc.d.ts +0 -55
- package/examples/greeter/greeter.trevrpc.js +0 -103
- package/examples/greeter/index.html +0 -140
- package/examples/greeter/static-server.js +0 -168
- package/src/advanced.d.ts +0 -29
- package/src/advanced.js +0 -1
- package/src/browser-channel.js +0 -49
- package/src/connect.js +0 -6
- package/src/connect.node.js +0 -6
- package/src/index.node.d.ts +0 -10
- package/src/index.node.js +0 -3
- package/src/native-loader.js +0 -118
- package/src/node-advanced.d.ts +0 -27
- package/src/node-advanced.js +0 -1
- package/src/node-generated.d.ts +0 -24
- package/src/node-generated.js +0 -126
- package/src/node-index.d.ts +0 -1
- package/src/node-index.js +0 -7
- package/src/node.d.ts +0 -298
- package/src/node.js +0 -1456
- package/src/runtime.js +0 -66
- package/src/server-response.js +0 -49
- package/src/timer.js +0 -29
- package/src/webtransport.js +0 -639
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
-
<title>TrevRPC JavaScript Greeter Client</title>
|
|
7
|
-
<style>
|
|
8
|
-
:root {
|
|
9
|
-
color-scheme: light dark;
|
|
10
|
-
font-family:
|
|
11
|
-
Inter,
|
|
12
|
-
ui-sans-serif,
|
|
13
|
-
system-ui,
|
|
14
|
-
-apple-system,
|
|
15
|
-
BlinkMacSystemFont,
|
|
16
|
-
"Segoe UI",
|
|
17
|
-
sans-serif;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
body {
|
|
21
|
-
margin: 0;
|
|
22
|
-
min-height: 100vh;
|
|
23
|
-
background:
|
|
24
|
-
radial-gradient(circle at top left, rgb(80 80 180 / 30%), transparent 35rem), Canvas;
|
|
25
|
-
color: CanvasText;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
main {
|
|
29
|
-
box-sizing: border-box;
|
|
30
|
-
width: min(54rem, 100%);
|
|
31
|
-
margin: 0 auto;
|
|
32
|
-
padding: 3rem 1rem;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
form,
|
|
36
|
-
pre {
|
|
37
|
-
border: 1px solid color-mix(in srgb, CanvasText 18%, transparent);
|
|
38
|
-
border-radius: 1rem;
|
|
39
|
-
background: color-mix(in srgb, Canvas 92%, CanvasText 8%);
|
|
40
|
-
box-shadow: 0 1rem 3rem rgb(0 0 0 / 12%);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
form {
|
|
44
|
-
display: grid;
|
|
45
|
-
gap: 1rem;
|
|
46
|
-
padding: 1rem;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
label {
|
|
50
|
-
display: grid;
|
|
51
|
-
gap: 0.35rem;
|
|
52
|
-
font-weight: 700;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
input,
|
|
56
|
-
button {
|
|
57
|
-
border: 1px solid color-mix(in srgb, CanvasText 22%, transparent);
|
|
58
|
-
border-radius: 0.7rem;
|
|
59
|
-
font: inherit;
|
|
60
|
-
padding: 0.75rem;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
button {
|
|
64
|
-
cursor: pointer;
|
|
65
|
-
font-weight: 800;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
.actions {
|
|
69
|
-
display: flex;
|
|
70
|
-
flex-wrap: wrap;
|
|
71
|
-
gap: 0.75rem;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
#submit {
|
|
75
|
-
background: #5b5bd6;
|
|
76
|
-
color: white;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
small {
|
|
80
|
-
opacity: 0.75;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
pre {
|
|
84
|
-
min-height: 14rem;
|
|
85
|
-
overflow: auto;
|
|
86
|
-
padding: 1rem;
|
|
87
|
-
white-space: pre-wrap;
|
|
88
|
-
}
|
|
89
|
-
</style>
|
|
90
|
-
<script type="importmap">
|
|
91
|
-
{
|
|
92
|
-
"imports": {
|
|
93
|
-
"protobufjs": "./vendor/protobufjs.js"
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
</script>
|
|
97
|
-
</head>
|
|
98
|
-
<body>
|
|
99
|
-
<main>
|
|
100
|
-
<h1>TrevRPC JavaScript Greeter Client</h1>
|
|
101
|
-
<p>
|
|
102
|
-
Connect this page to a WebTransport-enabled TrevRPC Go or Rust greeter server and run all
|
|
103
|
-
four RPC shapes from the browser.
|
|
104
|
-
</p>
|
|
105
|
-
|
|
106
|
-
<form id="client-form">
|
|
107
|
-
<label>
|
|
108
|
-
WebTransport URL
|
|
109
|
-
<input name="url" required value="https://127.0.0.1:50051/trevrpc" />
|
|
110
|
-
</label>
|
|
111
|
-
<div class="actions">
|
|
112
|
-
<button type="button" data-url="https://127.0.0.1:50051/trevrpc">Go default URL</button>
|
|
113
|
-
<button type="button" data-url="https://127.0.0.1:5000/trevrpc">Rust default URL</button>
|
|
114
|
-
</div>
|
|
115
|
-
<label>
|
|
116
|
-
Name
|
|
117
|
-
<input name="name" value="TrevRPC" />
|
|
118
|
-
</label>
|
|
119
|
-
<label>
|
|
120
|
-
Bearer token
|
|
121
|
-
<input name="token" value="trevrpc-example-token" />
|
|
122
|
-
</label>
|
|
123
|
-
<label>
|
|
124
|
-
Server certificate SHA-256 hash
|
|
125
|
-
<input name="certificate-hash" placeholder="optional hex or base64 hash" />
|
|
126
|
-
<small>
|
|
127
|
-
The local static server loads this from
|
|
128
|
-
<code>~/.config/trevrpc/trevrpc-example-cert.pem</code> when available. Leave empty when
|
|
129
|
-
the browser already trusts the server certificate.
|
|
130
|
-
</small>
|
|
131
|
-
</label>
|
|
132
|
-
<button id="submit" type="submit">Run RPCs</button>
|
|
133
|
-
</form>
|
|
134
|
-
|
|
135
|
-
<h2>Output</h2>
|
|
136
|
-
<pre id="output" aria-live="polite"></pre>
|
|
137
|
-
</main>
|
|
138
|
-
<script type="module" src="./client.js"></script>
|
|
139
|
-
</body>
|
|
140
|
-
</html>
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
|
-
import { createReadStream } from "node:fs";
|
|
3
|
-
import { readFile, stat } from "node:fs/promises";
|
|
4
|
-
import { createServer } from "node:http";
|
|
5
|
-
import { homedir } from "node:os";
|
|
6
|
-
import { extname, join, normalize, resolve, sep } from "node:path";
|
|
7
|
-
import { fileURLToPath } from "node:url";
|
|
8
|
-
|
|
9
|
-
const root = resolve(fileURLToPath(new URL("../..", import.meta.url)));
|
|
10
|
-
const port = Number.parseInt(process.env.PORT ?? "8080", 10);
|
|
11
|
-
const authToken = "trevrpc-example-token";
|
|
12
|
-
const protobufBundlePath = fileURLToPath(import.meta.resolve("protobufjs/dist/protobuf.min.js"));
|
|
13
|
-
|
|
14
|
-
const contentTypes = new Map([
|
|
15
|
-
[".html", "text/html; charset=utf-8"],
|
|
16
|
-
[".js", "text/javascript; charset=utf-8"],
|
|
17
|
-
[".json", "application/json; charset=utf-8"],
|
|
18
|
-
[".md", "text/markdown; charset=utf-8"],
|
|
19
|
-
[".proto", "text/plain; charset=utf-8"],
|
|
20
|
-
]);
|
|
21
|
-
|
|
22
|
-
const server = createServer(async (request, response) => {
|
|
23
|
-
try {
|
|
24
|
-
const path = requestPath(request.url ?? "/");
|
|
25
|
-
|
|
26
|
-
if (path === "/favicon.ico") {
|
|
27
|
-
response.writeHead(204);
|
|
28
|
-
response.end();
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if (path === "/examples/greeter/certificate-hash.json") {
|
|
33
|
-
await writeCertificateHash(response);
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (path === "/examples/greeter/vendor/protobufjs.js") {
|
|
38
|
-
writeProtobufModule(response);
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if (path === "/examples/greeter/vendor/protobuf.min.js") {
|
|
43
|
-
await writeProtobufBundle(response);
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const file = path.endsWith("/") ? join(path, "index.html") : path;
|
|
48
|
-
await writeStaticFile(response, safePath(file));
|
|
49
|
-
} catch (error) {
|
|
50
|
-
if (error?.code === "ENOENT") {
|
|
51
|
-
notFound(response);
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
response.writeHead(500, { "content-type": "text/plain; charset=utf-8" });
|
|
56
|
-
response.end(error?.message ?? String(error));
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
server.listen(port, "127.0.0.1", () => {
|
|
61
|
-
console.log(`serving trevrpc-js from http://127.0.0.1:${port}/examples/greeter/`);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
function requestPath(url) {
|
|
65
|
-
return decodeURIComponent(new URL(url, "http://127.0.0.1").pathname);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
async function writeStaticFile(response, absolute) {
|
|
69
|
-
const info = await stat(absolute);
|
|
70
|
-
|
|
71
|
-
if (!info.isFile()) {
|
|
72
|
-
notFound(response);
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
response.writeHead(200, {
|
|
77
|
-
"content-type": contentTypes.get(extname(absolute)) ?? "application/octet-stream",
|
|
78
|
-
});
|
|
79
|
-
createReadStream(absolute).pipe(response);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function safePath(path) {
|
|
83
|
-
const absolute = normalize(join(root, path));
|
|
84
|
-
if (absolute !== root && !absolute.startsWith(`${root}${sep}`)) {
|
|
85
|
-
throw new Error("path escapes example root");
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return absolute;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
async function writeCertificateHash(response) {
|
|
92
|
-
const path = certificatePath();
|
|
93
|
-
|
|
94
|
-
try {
|
|
95
|
-
const certificate = await readFile(path);
|
|
96
|
-
const der = certificateDer(certificate);
|
|
97
|
-
const hash = createHash("sha256").update(der).digest();
|
|
98
|
-
|
|
99
|
-
response.writeHead(200, { "content-type": "application/json; charset=utf-8" });
|
|
100
|
-
response.end(
|
|
101
|
-
JSON.stringify({
|
|
102
|
-
exists: true,
|
|
103
|
-
path,
|
|
104
|
-
bearerToken: authToken,
|
|
105
|
-
sha256Base64: hash.toString("base64"),
|
|
106
|
-
sha256Hex: hash.toString("hex"),
|
|
107
|
-
}),
|
|
108
|
-
);
|
|
109
|
-
} catch (error) {
|
|
110
|
-
response.writeHead(200, { "content-type": "application/json; charset=utf-8" });
|
|
111
|
-
response.end(
|
|
112
|
-
JSON.stringify({
|
|
113
|
-
exists: false,
|
|
114
|
-
path,
|
|
115
|
-
bearerToken: authToken,
|
|
116
|
-
error: error?.message ?? String(error),
|
|
117
|
-
}),
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function writeProtobufModule(response) {
|
|
123
|
-
response.writeHead(200, { "content-type": "text/javascript; charset=utf-8" });
|
|
124
|
-
response.end(`await new Promise((resolve, reject) => {
|
|
125
|
-
if (globalThis.protobuf != null) {
|
|
126
|
-
resolve();
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const script = document.createElement("script");
|
|
131
|
-
script.src = new URL("./protobuf.min.js", import.meta.url).href;
|
|
132
|
-
script.onload = resolve;
|
|
133
|
-
script.onerror = () => reject(new Error("failed to load protobuf.js browser bundle"));
|
|
134
|
-
document.head.append(script);
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
export default globalThis.protobuf;
|
|
138
|
-
export const protobuf = globalThis.protobuf;
|
|
139
|
-
`);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
async function writeProtobufBundle(response) {
|
|
143
|
-
await writeStaticFile(response, protobufBundlePath);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
function certificatePath() {
|
|
147
|
-
return (
|
|
148
|
-
process.env.TREVRPC_EXAMPLE_CERT ??
|
|
149
|
-
join(homedir(), ".config", "trevrpc", "trevrpc-example-cert.pem")
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
function certificateDer(certificate) {
|
|
154
|
-
const text = certificate.toString("utf8");
|
|
155
|
-
const match = /-----BEGIN CERTIFICATE-----([A-Za-z0-9+/=\s]+)-----END CERTIFICATE-----/.exec(
|
|
156
|
-
text,
|
|
157
|
-
);
|
|
158
|
-
if (match == null) {
|
|
159
|
-
return certificate;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
return Buffer.from(match[1].replace(/\s/g, ""), "base64");
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
function notFound(response) {
|
|
166
|
-
response.writeHead(404, { "content-type": "text/plain; charset=utf-8" });
|
|
167
|
-
response.end("not found");
|
|
168
|
-
}
|
package/src/advanced.d.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
ResolvedCallOptions,
|
|
3
|
-
RpcRequestMessage,
|
|
4
|
-
RpcResponseMessage,
|
|
5
|
-
RpcStreamFrameMessage,
|
|
6
|
-
Transport,
|
|
7
|
-
WebTransportBidirectionalStreamLike,
|
|
8
|
-
WebTransportCloseInfoLike,
|
|
9
|
-
WebTransportOptions,
|
|
10
|
-
WebTransportSessionLike,
|
|
11
|
-
} from "./index.js";
|
|
12
|
-
|
|
13
|
-
/** Raw single-session TrevRPC transport for browser WebTransport. */
|
|
14
|
-
export class RawWebTransport implements Transport {
|
|
15
|
-
session: WebTransportSessionLike;
|
|
16
|
-
maxFrameSize: number;
|
|
17
|
-
|
|
18
|
-
constructor(session: WebTransportSessionLike, options?: WebTransportOptions);
|
|
19
|
-
static connect(url: string | URL, options?: WebTransportOptions): Promise<RawWebTransport>;
|
|
20
|
-
ready(): Promise<void>;
|
|
21
|
-
close(closeInfo?: WebTransportCloseInfoLike): void;
|
|
22
|
-
call(request: RpcRequestMessage, options?: ResolvedCallOptions): Promise<RpcResponseMessage>;
|
|
23
|
-
streamingCall(
|
|
24
|
-
request: RpcRequestMessage,
|
|
25
|
-
requestBody: AsyncIterable<Uint8Array>,
|
|
26
|
-
options?: ResolvedCallOptions,
|
|
27
|
-
): Promise<AsyncIterableIterator<RpcStreamFrameMessage>>;
|
|
28
|
-
openBidirectionalStream(): Promise<WebTransportBidirectionalStreamLike>;
|
|
29
|
-
}
|
package/src/advanced.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { RawWebTransport } from "./webtransport.js";
|
package/src/browser-channel.js
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { ChannelStateMachine, stripChannelOptions, waitForInitialReady } from "./channel.js";
|
|
2
|
-
import { unavailable } from "./status.js";
|
|
3
|
-
import {
|
|
4
|
-
RawWebTransport,
|
|
5
|
-
createWebTransportSession,
|
|
6
|
-
waitForWebTransportReady,
|
|
7
|
-
} from "./webtransport.js";
|
|
8
|
-
|
|
9
|
-
/** Browser channel with background session reconnection. */
|
|
10
|
-
export class Channel extends ChannelStateMachine {
|
|
11
|
-
constructor(url, options = {}) {
|
|
12
|
-
const retainedUrl = url instanceof URL ? url.href : url;
|
|
13
|
-
const retainedOptions = Object.freeze({ ...options });
|
|
14
|
-
const transportOptions = stripChannelOptions(retainedOptions);
|
|
15
|
-
super(
|
|
16
|
-
(signal) => connectWebTransport(retainedUrl, transportOptions, signal),
|
|
17
|
-
retainedOptions,
|
|
18
|
-
(transport) => transport.session.closed,
|
|
19
|
-
);
|
|
20
|
-
this.url = retainedUrl;
|
|
21
|
-
this.options = retainedOptions;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/** Creates a channel and waits for its first ready generation. */
|
|
25
|
-
static async connect(url, options = {}) {
|
|
26
|
-
const channel = new Channel(url, options);
|
|
27
|
-
await waitForInitialReady(channel, options);
|
|
28
|
-
return channel;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async function connectWebTransport(url, options, signal) {
|
|
33
|
-
const session = createWebTransportSession(url, options);
|
|
34
|
-
const onAbort = () => session.close?.();
|
|
35
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
36
|
-
|
|
37
|
-
try {
|
|
38
|
-
await waitForWebTransportReady(session);
|
|
39
|
-
if (signal.aborted) {
|
|
40
|
-
throw unavailable("channel is closed");
|
|
41
|
-
}
|
|
42
|
-
return new RawWebTransport(session, options);
|
|
43
|
-
} catch (error) {
|
|
44
|
-
session.close?.();
|
|
45
|
-
throw error;
|
|
46
|
-
} finally {
|
|
47
|
-
signal.removeEventListener("abort", onAbort);
|
|
48
|
-
}
|
|
49
|
-
}
|
package/src/connect.js
DELETED
package/src/connect.node.js
DELETED
package/src/index.node.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export * from "./index.js";
|
|
2
|
-
export { Channel } from "./node.js";
|
|
3
|
-
|
|
4
|
-
import type { Channel, NodeChannelOptions, NodeChannelTarget } from "./node.js";
|
|
5
|
-
|
|
6
|
-
/** Opens a native Node channel and waits for its first ready generation. */
|
|
7
|
-
export function connect(
|
|
8
|
-
target: string | URL | NodeChannelTarget,
|
|
9
|
-
options?: NodeChannelOptions,
|
|
10
|
-
): Promise<Channel>;
|
package/src/index.node.js
DELETED
package/src/native-loader.js
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import { existsSync } from "node:fs";
|
|
2
|
-
import { createRequire } from "node:module";
|
|
3
|
-
import { dirname, join } from "node:path";
|
|
4
|
-
import process from "node:process";
|
|
5
|
-
import { fileURLToPath } from "node:url";
|
|
6
|
-
|
|
7
|
-
const require = createRequire(import.meta.url);
|
|
8
|
-
const packageRoot = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
9
|
-
const packageVersion = (() => {
|
|
10
|
-
try {
|
|
11
|
-
return require(join(packageRoot, "package.json")).version ?? "unknown";
|
|
12
|
-
} catch {
|
|
13
|
-
return "unknown";
|
|
14
|
-
}
|
|
15
|
-
})();
|
|
16
|
-
const SupportedOptionalTarget = "linux/x64/glibc";
|
|
17
|
-
const LinuxX64GnuPackage = "@trevrpc/trevrpc-js-native-linux-x64-gnu";
|
|
18
|
-
|
|
19
|
-
/** Loads the target-specific native addon without building during installation. */
|
|
20
|
-
export function loadNativeAddon({ loadOptionalPackage = true, loadBundledAddon = true } = {}) {
|
|
21
|
-
const target = nativeTarget();
|
|
22
|
-
const packageName = nativePackageName(target);
|
|
23
|
-
let packageError;
|
|
24
|
-
let packageState = "unsupported";
|
|
25
|
-
|
|
26
|
-
if (loadOptionalPackage && packageName != null) {
|
|
27
|
-
try {
|
|
28
|
-
return require(packageName);
|
|
29
|
-
} catch (error) {
|
|
30
|
-
packageError = error;
|
|
31
|
-
packageState = isMissingPackage(error, packageName) ? "missing" : "failed to load";
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const bundled = loadBundledAddon ? bundledNativePath() : null;
|
|
36
|
-
let bundledError;
|
|
37
|
-
if (bundled != null) {
|
|
38
|
-
try {
|
|
39
|
-
return require(bundled);
|
|
40
|
-
} catch (error) {
|
|
41
|
-
bundledError = error;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const fallback = developmentFallbackPath();
|
|
46
|
-
let fallbackError;
|
|
47
|
-
if (fallback != null) {
|
|
48
|
-
try {
|
|
49
|
-
return require(fallback);
|
|
50
|
-
} catch (error) {
|
|
51
|
-
fallbackError = error;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const detected = targetName(target);
|
|
56
|
-
const expected = packageName ?? "no optional package (unsupported target)";
|
|
57
|
-
const bundledState =
|
|
58
|
-
bundled == null ? "no Nix-bundled addon was present" : "the Nix-bundled addon failed to load";
|
|
59
|
-
const fallbackState =
|
|
60
|
-
fallback == null
|
|
61
|
-
? "no source-checkout fallback was present"
|
|
62
|
-
: fallbackError == null
|
|
63
|
-
? "the source-checkout fallback was unavailable"
|
|
64
|
-
: "the source-checkout fallback failed to load";
|
|
65
|
-
throw new Error(
|
|
66
|
-
`TrevRPC native addon is unavailable for detected target ${detected}. ` +
|
|
67
|
-
`Supported optional-package targets: ${SupportedOptionalTarget}. Expected optional package: ${expected}@${packageVersion}; ` +
|
|
68
|
-
`package state: ${packageState}; ${bundledState}; ${fallbackState}. ` +
|
|
69
|
-
"Install the matching optional package or build build/native/trevrpc_native.node explicitly in a source checkout; npm installation never starts a source build.",
|
|
70
|
-
{ cause: fallbackError ?? bundledError ?? packageError },
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/** Returns the normalized native npm target. */
|
|
75
|
-
export function nativeTarget() {
|
|
76
|
-
return Object.freeze({
|
|
77
|
-
platform: process.platform,
|
|
78
|
-
arch: process.arch,
|
|
79
|
-
libc: process.platform === "linux" ? linuxLibc() : undefined,
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function nativePackageName(target) {
|
|
84
|
-
if (target.platform === "linux" && target.arch === "x64" && target.libc === "glibc") {
|
|
85
|
-
return LinuxX64GnuPackage;
|
|
86
|
-
}
|
|
87
|
-
return null;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function bundledNativePath() {
|
|
91
|
-
const path = join(packageRoot, "native", "trevrpc_native.node");
|
|
92
|
-
return existsSync(path) ? path : null;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function developmentFallbackPath() {
|
|
96
|
-
if (!existsSync(join(packageRoot, "native", "CMakeLists.txt"))) {
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
const path = join(packageRoot, "build", "native", "trevrpc_native.node");
|
|
100
|
-
return existsSync(path) ? path : null;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function targetName(target) {
|
|
104
|
-
return `${target.platform}/${target.arch}${target.libc == null ? "" : `/${target.libc}`}`;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function linuxLibc() {
|
|
108
|
-
const report = process.report?.getReport?.();
|
|
109
|
-
return report?.header?.glibcVersionRuntime == null ? "musl" : "glibc";
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function isMissingPackage(error, packageName) {
|
|
113
|
-
return (
|
|
114
|
-
error?.code === "MODULE_NOT_FOUND" &&
|
|
115
|
-
typeof error.message === "string" &&
|
|
116
|
-
error.message.includes(packageName)
|
|
117
|
-
);
|
|
118
|
-
}
|
package/src/node-advanced.d.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { RpcResponseMessage, RpcStreamFrameMessage, Transport } from "./index.js";
|
|
2
|
-
import type { NodeChannelTarget, NodeConnectOptions } from "./node.js";
|
|
3
|
-
|
|
4
|
-
export interface RawNodeCloseInfo {
|
|
5
|
-
nativeCode: number;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
/** Raw single-connection Node transport backed by trevrpc-c and MsQuic. */
|
|
9
|
-
export class RawNodeTransport implements Transport {
|
|
10
|
-
maxFrameSize?: number;
|
|
11
|
-
readonly closed: Promise<RawNodeCloseInfo>;
|
|
12
|
-
|
|
13
|
-
static connect(
|
|
14
|
-
target: string | URL | NodeChannelTarget,
|
|
15
|
-
options?: NodeConnectOptions,
|
|
16
|
-
): Promise<RawNodeTransport>;
|
|
17
|
-
call(
|
|
18
|
-
request: Parameters<Transport["call"]>[0],
|
|
19
|
-
options?: Parameters<Transport["call"]>[1],
|
|
20
|
-
): Promise<RpcResponseMessage>;
|
|
21
|
-
streamingCall(
|
|
22
|
-
request: Parameters<Transport["streamingCall"]>[0],
|
|
23
|
-
requestBody: AsyncIterable<Uint8Array>,
|
|
24
|
-
options?: Parameters<Transport["streamingCall"]>[2],
|
|
25
|
-
): Promise<AsyncIterableIterator<RpcStreamFrameMessage>>;
|
|
26
|
-
close(): void;
|
|
27
|
-
}
|
package/src/node-advanced.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { RawNodeTransport } from "./node.js";
|
package/src/node-generated.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { Root, Type } from "protobufjs";
|
|
2
|
-
|
|
3
|
-
import type { RpcMethodKind, RpcServiceDescriptor } from "./index.js";
|
|
4
|
-
import type { NodeServer, NodeServerCall } from "./node.js";
|
|
5
|
-
|
|
6
|
-
export type { StreamingServerResponse, UnaryServerResponse } from "./index.js";
|
|
7
|
-
export type { NodeServer, NodeServerCall } from "./node.js";
|
|
8
|
-
|
|
9
|
-
/** Registers typed generated handlers on a Node server. */
|
|
10
|
-
export function registerTypedService(
|
|
11
|
-
server: NodeServer,
|
|
12
|
-
root: Root,
|
|
13
|
-
service: RpcServiceDescriptor,
|
|
14
|
-
handlers: Record<string, unknown>,
|
|
15
|
-
): NodeServer;
|
|
16
|
-
|
|
17
|
-
/** Dispatches one typed generated Node handler. */
|
|
18
|
-
export function dispatchTypedNodeHandler(
|
|
19
|
-
call: NodeServerCall,
|
|
20
|
-
handler: (...args: unknown[]) => unknown,
|
|
21
|
-
kind: RpcMethodKind,
|
|
22
|
-
requestType: Type,
|
|
23
|
-
responseType: Type,
|
|
24
|
-
): Promise<void>;
|