@ricsam/r5d-worker 0.0.69 → 0.0.71
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/dist/cjs/main.cjs +6 -2
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/port-forward-client.cjs +88 -30
- package/dist/mjs/main.mjs +6 -2
- package/dist/mjs/package.json +1 -1
- package/dist/mjs/port-forward-client.mjs +88 -30
- package/dist/types/main.d.ts +1 -0
- package/package.json +1 -1
package/dist/cjs/main.cjs
CHANGED
|
@@ -2296,7 +2296,10 @@ function resolveHostShell(command, platform = process.platform) {
|
|
|
2296
2296
|
return /(?:^|[\\/])cmd\.exe$/i.test(file2) ? { file: file2, args: ["/d", "/s", "/c", command] } : { file: file2, args: ["-Command", command] };
|
|
2297
2297
|
}
|
|
2298
2298
|
const file = process.env.SHELL || "/bin/bash";
|
|
2299
|
-
|
|
2299
|
+
if (command === void 0) {
|
|
2300
|
+
return { file, args: ["-l"] };
|
|
2301
|
+
}
|
|
2302
|
+
return { file, args: ["-lc", 'eval "$R5D_SHELL_COMMAND"'], env: { R5D_SHELL_COMMAND: command } };
|
|
2300
2303
|
}
|
|
2301
2304
|
async function openPty(input) {
|
|
2302
2305
|
if (activePtys.has(input.message.ptyId)) {
|
|
@@ -2331,7 +2334,8 @@ async function openPty(input) {
|
|
|
2331
2334
|
...githubProcessEnv(),
|
|
2332
2335
|
...input.message.env ?? {},
|
|
2333
2336
|
...planProcessEnv,
|
|
2334
|
-
...targetProcessEnv
|
|
2337
|
+
...targetProcessEnv,
|
|
2338
|
+
...shell.env ?? {}
|
|
2335
2339
|
}
|
|
2336
2340
|
},
|
|
2337
2341
|
onOpened: () => {
|
package/dist/cjs/package.json
CHANGED
|
@@ -36,6 +36,7 @@ var import_ws = __toESM(require("ws"), 1);
|
|
|
36
36
|
const RELAY_FRAME_BYTES = 64 * 1024;
|
|
37
37
|
const RELAY_PAUSE_BYTES = 1024 * 1024;
|
|
38
38
|
const RELAY_RESUME_BYTES = 256 * 1024;
|
|
39
|
+
const LOOPBACK_HOSTS = ["127.0.0.1", "::1"];
|
|
39
40
|
function relayUrl(baseUrl, label, forwardId, relayConnectionId) {
|
|
40
41
|
const url = new URL("/worker/port-forward/ws", baseUrl);
|
|
41
42
|
url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
|
|
@@ -44,42 +45,59 @@ function relayUrl(baseUrl, label, forwardId, relayConnectionId) {
|
|
|
44
45
|
url.searchParams.set("connection", relayConnectionId);
|
|
45
46
|
return url.toString();
|
|
46
47
|
}
|
|
48
|
+
function loopbackAddress(host, port) {
|
|
49
|
+
return host.includes(":") ? `[${host}]:${port}` : `${host}:${port}`;
|
|
50
|
+
}
|
|
47
51
|
function rawDataBuffer(data) {
|
|
48
52
|
if (Buffer.isBuffer(data)) return data;
|
|
49
53
|
if (Array.isArray(data)) return Buffer.concat(data);
|
|
50
54
|
return Buffer.from(data);
|
|
51
55
|
}
|
|
52
56
|
function openWorkerPortForwardRelay(options) {
|
|
53
|
-
const socket = import_node_net.default.createConnection({ host: "127.0.0.1", port: options.workerPort, allowHalfOpen: true });
|
|
54
|
-
socket.pause();
|
|
55
|
-
socket.setNoDelay(true);
|
|
56
57
|
const relay = new import_ws.default(relayUrl(options.baseUrl, options.label, options.forwardId, options.relayConnectionId), {
|
|
57
58
|
headers: { Authorization: `Bearer ${options.token}` },
|
|
58
59
|
perMessageDeflate: false
|
|
59
60
|
});
|
|
61
|
+
let socket;
|
|
60
62
|
let relayReady = false;
|
|
61
63
|
let targetReady = false;
|
|
64
|
+
let targetEndRequested = false;
|
|
65
|
+
let targetFailure;
|
|
62
66
|
const pendingChunks = [];
|
|
63
67
|
let pendingBytes = 0;
|
|
68
|
+
const pendingWrites = [];
|
|
69
|
+
let pendingWriteBytes = 0;
|
|
64
70
|
let closing = false;
|
|
65
71
|
let resumeTimer;
|
|
66
72
|
const maybeResume = () => {
|
|
67
|
-
if (relayReady && targetReady && !resumeTimer) socket
|
|
73
|
+
if (relayReady && targetReady && !resumeTimer) socket?.resume();
|
|
68
74
|
};
|
|
69
75
|
const cleanup = () => {
|
|
70
76
|
if (closing) return;
|
|
71
77
|
closing = true;
|
|
72
78
|
if (resumeTimer) clearInterval(resumeTimer);
|
|
73
|
-
socket
|
|
79
|
+
socket?.destroy();
|
|
74
80
|
if (relay.readyState === import_ws.default.OPEN || relay.readyState === import_ws.default.CONNECTING) relay.close();
|
|
75
81
|
};
|
|
76
82
|
const sendError = (message) => {
|
|
77
|
-
if (
|
|
83
|
+
if (closing) return;
|
|
84
|
+
const payload = JSON.stringify({ type: "error", error: message });
|
|
85
|
+
if (relay.readyState === import_ws.default.CONNECTING) {
|
|
86
|
+
closing = true;
|
|
87
|
+
if (resumeTimer) clearInterval(resumeTimer);
|
|
88
|
+
socket?.destroy();
|
|
89
|
+
relay.once("open", () => {
|
|
90
|
+
relay.send(payload);
|
|
91
|
+
relay.close();
|
|
92
|
+
});
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (relay.readyState === import_ws.default.OPEN) relay.send(payload);
|
|
78
96
|
cleanup();
|
|
79
97
|
};
|
|
80
98
|
const waitForRelayDrain = () => {
|
|
81
99
|
if (resumeTimer || relay.bufferedAmount <= RELAY_PAUSE_BYTES) return;
|
|
82
|
-
socket
|
|
100
|
+
socket?.pause();
|
|
83
101
|
resumeTimer = setInterval(() => {
|
|
84
102
|
if (relay.readyState !== import_ws.default.OPEN) return cleanup();
|
|
85
103
|
if (relay.bufferedAmount > RELAY_RESUME_BYTES) return;
|
|
@@ -94,25 +112,53 @@ function openWorkerPortForwardRelay(options) {
|
|
|
94
112
|
}
|
|
95
113
|
waitForRelayDrain();
|
|
96
114
|
};
|
|
97
|
-
|
|
115
|
+
const adoptTarget = (target, host) => {
|
|
116
|
+
if (closing) return target.destroy();
|
|
117
|
+
socket = target;
|
|
118
|
+
target.on("data", (chunk) => {
|
|
119
|
+
if (!relayReady || relay.readyState !== import_ws.default.OPEN) {
|
|
120
|
+
pendingBytes += chunk.byteLength;
|
|
121
|
+
if (pendingBytes > RELAY_PAUSE_BYTES) return cleanup();
|
|
122
|
+
pendingChunks.push(Buffer.from(chunk));
|
|
123
|
+
target.pause();
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
sendChunk(chunk);
|
|
127
|
+
});
|
|
128
|
+
target.on("end", () => {
|
|
129
|
+
if (relay.readyState === import_ws.default.OPEN) relay.send(JSON.stringify({ type: "end" }));
|
|
130
|
+
});
|
|
131
|
+
target.on("error", (error) => sendError(`Connection to ${loopbackAddress(host, options.workerPort)} failed: ${error.message}`));
|
|
132
|
+
target.on("close", cleanup);
|
|
133
|
+
target.pause();
|
|
98
134
|
targetReady = true;
|
|
135
|
+
for (const chunk of pendingWrites.splice(0)) target.write(chunk);
|
|
136
|
+
pendingWriteBytes = 0;
|
|
137
|
+
if (targetFailure) return void target.destroy(targetFailure);
|
|
138
|
+
if (targetEndRequested) target.end();
|
|
99
139
|
maybeResume();
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
140
|
+
};
|
|
141
|
+
const dialFailures = [];
|
|
142
|
+
const dialTarget = (host, fallbackHosts2) => {
|
|
143
|
+
if (closing) return;
|
|
144
|
+
const candidate = import_node_net.default.createConnection({ host, port: options.workerPort, allowHalfOpen: true });
|
|
145
|
+
candidate.pause();
|
|
146
|
+
candidate.setNoDelay(true);
|
|
147
|
+
const onDialError = (error) => {
|
|
148
|
+
candidate.destroy();
|
|
149
|
+
dialFailures.push(`${loopbackAddress(host, options.workerPort)} (${error.code ?? error.message})`);
|
|
150
|
+
const [nextHost, ...rest] = fallbackHosts2;
|
|
151
|
+
if (nextHost) return dialTarget(nextHost, rest);
|
|
152
|
+
sendError(
|
|
153
|
+
`Could not connect to ${dialFailures.join(" or ")} on the worker. Nothing is listening on either loopback address for port ${options.workerPort} \u2014 make sure the server is running and bound to a loopback or wildcard host.`
|
|
154
|
+
);
|
|
155
|
+
};
|
|
156
|
+
candidate.once("error", onDialError);
|
|
157
|
+
candidate.once("connect", () => {
|
|
158
|
+
candidate.off("error", onDialError);
|
|
159
|
+
adoptTarget(candidate, host);
|
|
160
|
+
});
|
|
161
|
+
};
|
|
116
162
|
relay.on("message", (data, isBinary) => {
|
|
117
163
|
if (!isBinary) {
|
|
118
164
|
let control;
|
|
@@ -123,24 +169,36 @@ function openWorkerPortForwardRelay(options) {
|
|
|
123
169
|
}
|
|
124
170
|
if (control.type === "ready") {
|
|
125
171
|
relayReady = true;
|
|
126
|
-
for (const
|
|
172
|
+
for (const chunk2 of pendingChunks.splice(0)) sendChunk(chunk2);
|
|
127
173
|
pendingBytes = 0;
|
|
128
174
|
maybeResume();
|
|
129
175
|
} else if (control.type === "end") {
|
|
130
|
-
socket.end();
|
|
176
|
+
if (socket) socket.end();
|
|
177
|
+
else targetEndRequested = true;
|
|
131
178
|
} else if (control.type === "error") {
|
|
132
|
-
|
|
179
|
+
const failure = new Error(control.error || "Port-forward relay failed.");
|
|
180
|
+
if (socket) socket.destroy(failure);
|
|
181
|
+
else targetFailure = failure;
|
|
133
182
|
}
|
|
134
183
|
return;
|
|
135
184
|
}
|
|
136
|
-
|
|
185
|
+
const chunk = rawDataBuffer(data);
|
|
186
|
+
if (!socket) {
|
|
187
|
+
pendingWriteBytes += chunk.byteLength;
|
|
188
|
+
if (pendingWriteBytes > RELAY_PAUSE_BYTES) return cleanup();
|
|
189
|
+
pendingWrites.push(Buffer.from(chunk));
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const target = socket;
|
|
193
|
+
if (!target.write(chunk)) {
|
|
137
194
|
relay.pause();
|
|
138
|
-
|
|
195
|
+
target.once("drain", () => relay.resume());
|
|
139
196
|
}
|
|
140
197
|
});
|
|
141
198
|
relay.on("error", cleanup);
|
|
142
199
|
relay.once("close", cleanup);
|
|
143
|
-
|
|
200
|
+
const [primaryHost, ...fallbackHosts] = LOOPBACK_HOSTS;
|
|
201
|
+
dialTarget(primaryHost, fallbackHosts);
|
|
144
202
|
}
|
|
145
203
|
// Annotate the CommonJS export names for ESM import in node:
|
|
146
204
|
0 && (module.exports = {
|
package/dist/mjs/main.mjs
CHANGED
|
@@ -2267,7 +2267,10 @@ function resolveHostShell(command, platform = process.platform) {
|
|
|
2267
2267
|
return /(?:^|[\\/])cmd\.exe$/i.test(file2) ? { file: file2, args: ["/d", "/s", "/c", command] } : { file: file2, args: ["-Command", command] };
|
|
2268
2268
|
}
|
|
2269
2269
|
const file = process.env.SHELL || "/bin/bash";
|
|
2270
|
-
|
|
2270
|
+
if (command === void 0) {
|
|
2271
|
+
return { file, args: ["-l"] };
|
|
2272
|
+
}
|
|
2273
|
+
return { file, args: ["-lc", 'eval "$R5D_SHELL_COMMAND"'], env: { R5D_SHELL_COMMAND: command } };
|
|
2271
2274
|
}
|
|
2272
2275
|
async function openPty(input) {
|
|
2273
2276
|
if (activePtys.has(input.message.ptyId)) {
|
|
@@ -2302,7 +2305,8 @@ async function openPty(input) {
|
|
|
2302
2305
|
...githubProcessEnv(),
|
|
2303
2306
|
...input.message.env ?? {},
|
|
2304
2307
|
...planProcessEnv,
|
|
2305
|
-
...targetProcessEnv
|
|
2308
|
+
...targetProcessEnv,
|
|
2309
|
+
...shell.env ?? {}
|
|
2306
2310
|
}
|
|
2307
2311
|
},
|
|
2308
2312
|
onOpened: () => {
|
package/dist/mjs/package.json
CHANGED
|
@@ -3,6 +3,7 @@ import WebSocket, {} from "ws";
|
|
|
3
3
|
const RELAY_FRAME_BYTES = 64 * 1024;
|
|
4
4
|
const RELAY_PAUSE_BYTES = 1024 * 1024;
|
|
5
5
|
const RELAY_RESUME_BYTES = 256 * 1024;
|
|
6
|
+
const LOOPBACK_HOSTS = ["127.0.0.1", "::1"];
|
|
6
7
|
function relayUrl(baseUrl, label, forwardId, relayConnectionId) {
|
|
7
8
|
const url = new URL("/worker/port-forward/ws", baseUrl);
|
|
8
9
|
url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
|
|
@@ -11,42 +12,59 @@ function relayUrl(baseUrl, label, forwardId, relayConnectionId) {
|
|
|
11
12
|
url.searchParams.set("connection", relayConnectionId);
|
|
12
13
|
return url.toString();
|
|
13
14
|
}
|
|
15
|
+
function loopbackAddress(host, port) {
|
|
16
|
+
return host.includes(":") ? `[${host}]:${port}` : `${host}:${port}`;
|
|
17
|
+
}
|
|
14
18
|
function rawDataBuffer(data) {
|
|
15
19
|
if (Buffer.isBuffer(data)) return data;
|
|
16
20
|
if (Array.isArray(data)) return Buffer.concat(data);
|
|
17
21
|
return Buffer.from(data);
|
|
18
22
|
}
|
|
19
23
|
function openWorkerPortForwardRelay(options) {
|
|
20
|
-
const socket = net.createConnection({ host: "127.0.0.1", port: options.workerPort, allowHalfOpen: true });
|
|
21
|
-
socket.pause();
|
|
22
|
-
socket.setNoDelay(true);
|
|
23
24
|
const relay = new WebSocket(relayUrl(options.baseUrl, options.label, options.forwardId, options.relayConnectionId), {
|
|
24
25
|
headers: { Authorization: `Bearer ${options.token}` },
|
|
25
26
|
perMessageDeflate: false
|
|
26
27
|
});
|
|
28
|
+
let socket;
|
|
27
29
|
let relayReady = false;
|
|
28
30
|
let targetReady = false;
|
|
31
|
+
let targetEndRequested = false;
|
|
32
|
+
let targetFailure;
|
|
29
33
|
const pendingChunks = [];
|
|
30
34
|
let pendingBytes = 0;
|
|
35
|
+
const pendingWrites = [];
|
|
36
|
+
let pendingWriteBytes = 0;
|
|
31
37
|
let closing = false;
|
|
32
38
|
let resumeTimer;
|
|
33
39
|
const maybeResume = () => {
|
|
34
|
-
if (relayReady && targetReady && !resumeTimer) socket
|
|
40
|
+
if (relayReady && targetReady && !resumeTimer) socket?.resume();
|
|
35
41
|
};
|
|
36
42
|
const cleanup = () => {
|
|
37
43
|
if (closing) return;
|
|
38
44
|
closing = true;
|
|
39
45
|
if (resumeTimer) clearInterval(resumeTimer);
|
|
40
|
-
socket
|
|
46
|
+
socket?.destroy();
|
|
41
47
|
if (relay.readyState === WebSocket.OPEN || relay.readyState === WebSocket.CONNECTING) relay.close();
|
|
42
48
|
};
|
|
43
49
|
const sendError = (message) => {
|
|
44
|
-
if (
|
|
50
|
+
if (closing) return;
|
|
51
|
+
const payload = JSON.stringify({ type: "error", error: message });
|
|
52
|
+
if (relay.readyState === WebSocket.CONNECTING) {
|
|
53
|
+
closing = true;
|
|
54
|
+
if (resumeTimer) clearInterval(resumeTimer);
|
|
55
|
+
socket?.destroy();
|
|
56
|
+
relay.once("open", () => {
|
|
57
|
+
relay.send(payload);
|
|
58
|
+
relay.close();
|
|
59
|
+
});
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (relay.readyState === WebSocket.OPEN) relay.send(payload);
|
|
45
63
|
cleanup();
|
|
46
64
|
};
|
|
47
65
|
const waitForRelayDrain = () => {
|
|
48
66
|
if (resumeTimer || relay.bufferedAmount <= RELAY_PAUSE_BYTES) return;
|
|
49
|
-
socket
|
|
67
|
+
socket?.pause();
|
|
50
68
|
resumeTimer = setInterval(() => {
|
|
51
69
|
if (relay.readyState !== WebSocket.OPEN) return cleanup();
|
|
52
70
|
if (relay.bufferedAmount > RELAY_RESUME_BYTES) return;
|
|
@@ -61,25 +79,53 @@ function openWorkerPortForwardRelay(options) {
|
|
|
61
79
|
}
|
|
62
80
|
waitForRelayDrain();
|
|
63
81
|
};
|
|
64
|
-
|
|
82
|
+
const adoptTarget = (target, host) => {
|
|
83
|
+
if (closing) return target.destroy();
|
|
84
|
+
socket = target;
|
|
85
|
+
target.on("data", (chunk) => {
|
|
86
|
+
if (!relayReady || relay.readyState !== WebSocket.OPEN) {
|
|
87
|
+
pendingBytes += chunk.byteLength;
|
|
88
|
+
if (pendingBytes > RELAY_PAUSE_BYTES) return cleanup();
|
|
89
|
+
pendingChunks.push(Buffer.from(chunk));
|
|
90
|
+
target.pause();
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
sendChunk(chunk);
|
|
94
|
+
});
|
|
95
|
+
target.on("end", () => {
|
|
96
|
+
if (relay.readyState === WebSocket.OPEN) relay.send(JSON.stringify({ type: "end" }));
|
|
97
|
+
});
|
|
98
|
+
target.on("error", (error) => sendError(`Connection to ${loopbackAddress(host, options.workerPort)} failed: ${error.message}`));
|
|
99
|
+
target.on("close", cleanup);
|
|
100
|
+
target.pause();
|
|
65
101
|
targetReady = true;
|
|
102
|
+
for (const chunk of pendingWrites.splice(0)) target.write(chunk);
|
|
103
|
+
pendingWriteBytes = 0;
|
|
104
|
+
if (targetFailure) return void target.destroy(targetFailure);
|
|
105
|
+
if (targetEndRequested) target.end();
|
|
66
106
|
maybeResume();
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
107
|
+
};
|
|
108
|
+
const dialFailures = [];
|
|
109
|
+
const dialTarget = (host, fallbackHosts2) => {
|
|
110
|
+
if (closing) return;
|
|
111
|
+
const candidate = net.createConnection({ host, port: options.workerPort, allowHalfOpen: true });
|
|
112
|
+
candidate.pause();
|
|
113
|
+
candidate.setNoDelay(true);
|
|
114
|
+
const onDialError = (error) => {
|
|
115
|
+
candidate.destroy();
|
|
116
|
+
dialFailures.push(`${loopbackAddress(host, options.workerPort)} (${error.code ?? error.message})`);
|
|
117
|
+
const [nextHost, ...rest] = fallbackHosts2;
|
|
118
|
+
if (nextHost) return dialTarget(nextHost, rest);
|
|
119
|
+
sendError(
|
|
120
|
+
`Could not connect to ${dialFailures.join(" or ")} on the worker. Nothing is listening on either loopback address for port ${options.workerPort} \u2014 make sure the server is running and bound to a loopback or wildcard host.`
|
|
121
|
+
);
|
|
122
|
+
};
|
|
123
|
+
candidate.once("error", onDialError);
|
|
124
|
+
candidate.once("connect", () => {
|
|
125
|
+
candidate.off("error", onDialError);
|
|
126
|
+
adoptTarget(candidate, host);
|
|
127
|
+
});
|
|
128
|
+
};
|
|
83
129
|
relay.on("message", (data, isBinary) => {
|
|
84
130
|
if (!isBinary) {
|
|
85
131
|
let control;
|
|
@@ -90,24 +136,36 @@ function openWorkerPortForwardRelay(options) {
|
|
|
90
136
|
}
|
|
91
137
|
if (control.type === "ready") {
|
|
92
138
|
relayReady = true;
|
|
93
|
-
for (const
|
|
139
|
+
for (const chunk2 of pendingChunks.splice(0)) sendChunk(chunk2);
|
|
94
140
|
pendingBytes = 0;
|
|
95
141
|
maybeResume();
|
|
96
142
|
} else if (control.type === "end") {
|
|
97
|
-
socket.end();
|
|
143
|
+
if (socket) socket.end();
|
|
144
|
+
else targetEndRequested = true;
|
|
98
145
|
} else if (control.type === "error") {
|
|
99
|
-
|
|
146
|
+
const failure = new Error(control.error || "Port-forward relay failed.");
|
|
147
|
+
if (socket) socket.destroy(failure);
|
|
148
|
+
else targetFailure = failure;
|
|
100
149
|
}
|
|
101
150
|
return;
|
|
102
151
|
}
|
|
103
|
-
|
|
152
|
+
const chunk = rawDataBuffer(data);
|
|
153
|
+
if (!socket) {
|
|
154
|
+
pendingWriteBytes += chunk.byteLength;
|
|
155
|
+
if (pendingWriteBytes > RELAY_PAUSE_BYTES) return cleanup();
|
|
156
|
+
pendingWrites.push(Buffer.from(chunk));
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const target = socket;
|
|
160
|
+
if (!target.write(chunk)) {
|
|
104
161
|
relay.pause();
|
|
105
|
-
|
|
162
|
+
target.once("drain", () => relay.resume());
|
|
106
163
|
}
|
|
107
164
|
});
|
|
108
165
|
relay.on("error", cleanup);
|
|
109
166
|
relay.once("close", cleanup);
|
|
110
|
-
|
|
167
|
+
const [primaryHost, ...fallbackHosts] = LOOPBACK_HOSTS;
|
|
168
|
+
dialTarget(primaryHost, fallbackHosts);
|
|
111
169
|
}
|
|
112
170
|
export {
|
|
113
171
|
openWorkerPortForwardRelay
|
package/dist/types/main.d.ts
CHANGED