@spawn-dock/dev-tunnel 1.0.4 → 1.0.6
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/proxy.js +27 -4
- package/dist/proxy.js.map +1 -1
- package/dist/tunnel.d.ts +1 -0
- package/dist/tunnel.js +23 -6
- package/dist/tunnel.js.map +1 -1
- package/package.json +1 -1
package/dist/proxy.js
CHANGED
|
@@ -2,6 +2,23 @@ const HOP_BY_HOP = new Set([
|
|
|
2
2
|
"connection", "host", "keep-alive", "proxy-authenticate",
|
|
3
3
|
"proxy-authorization", "te", "trailer", "transfer-encoding", "upgrade", "content-length",
|
|
4
4
|
]);
|
|
5
|
+
const REQUEST_HEADERS_TO_DROP = new Set([
|
|
6
|
+
...HOP_BY_HOP,
|
|
7
|
+
"accept-encoding",
|
|
8
|
+
]);
|
|
9
|
+
const RESPONSE_HEADERS_TO_DROP = new Set([
|
|
10
|
+
...HOP_BY_HOP,
|
|
11
|
+
"content-encoding",
|
|
12
|
+
]);
|
|
13
|
+
function filterResponseHeaders(headers) {
|
|
14
|
+
const result = [];
|
|
15
|
+
for (const [name, value] of headers.entries()) {
|
|
16
|
+
if (!RESPONSE_HEADERS_TO_DROP.has(name.toLowerCase())) {
|
|
17
|
+
result.push([name, value]);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
5
22
|
function decodeBody(body) {
|
|
6
23
|
if (body.encoding === "utf8")
|
|
7
24
|
return body.value;
|
|
@@ -12,7 +29,7 @@ export async function proxyRequest(request, localOrigin) {
|
|
|
12
29
|
const url = new URL(request.path, localOrigin);
|
|
13
30
|
const headers = new Headers();
|
|
14
31
|
for (const [name, value] of request.headers) {
|
|
15
|
-
if (!
|
|
32
|
+
if (!REQUEST_HEADERS_TO_DROP.has(name.toLowerCase())) {
|
|
16
33
|
headers.set(name, value);
|
|
17
34
|
}
|
|
18
35
|
}
|
|
@@ -24,7 +41,7 @@ export async function proxyRequest(request, localOrigin) {
|
|
|
24
41
|
try {
|
|
25
42
|
const res = await fetch(url, init);
|
|
26
43
|
const bodyBytes = new Uint8Array(await res.arrayBuffer());
|
|
27
|
-
const responseHeaders =
|
|
44
|
+
const responseHeaders = filterResponseHeaders(res.headers);
|
|
28
45
|
const response = {
|
|
29
46
|
requestId: request.requestId,
|
|
30
47
|
status: res.status,
|
|
@@ -41,9 +58,15 @@ export async function proxyRequest(request, localOrigin) {
|
|
|
41
58
|
catch (err) {
|
|
42
59
|
return {
|
|
43
60
|
requestId: request.requestId,
|
|
44
|
-
status:
|
|
61
|
+
status: 503,
|
|
45
62
|
headers: [["content-type", "application/json"]],
|
|
46
|
-
body: {
|
|
63
|
+
body: {
|
|
64
|
+
encoding: "utf8",
|
|
65
|
+
value: JSON.stringify({
|
|
66
|
+
error: "server_offline",
|
|
67
|
+
message: "Local development server is offline. Start it again with `npm run dev`.",
|
|
68
|
+
}),
|
|
69
|
+
},
|
|
47
70
|
};
|
|
48
71
|
}
|
|
49
72
|
}
|
package/dist/proxy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;IACzB,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,oBAAoB;IACxD,qBAAqB,EAAE,IAAI,EAAE,SAAS,EAAE,mBAAmB,EAAE,SAAS,EAAE,gBAAgB;CACzF,CAAC,CAAC;AAEH,SAAS,UAAU,CAAC,IAAyC;IAC3D,IAAI,IAAI,CAAC,QAAQ,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC,KAAK,CAAC;IAChD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC9C,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC;AAC3E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAA8B,EAC9B,WAAmB;IAEnB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAC9B,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QAC5C,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"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"}
|
package/dist/tunnel.d.ts
CHANGED
package/dist/tunnel.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import WebSocket from "ws";
|
|
2
2
|
import { parseInbound, serialize } from "./protocol.js";
|
|
3
3
|
import { proxyRequest } from "./proxy.js";
|
|
4
|
+
const HEARTBEAT_INTERVAL_MS = 15_000;
|
|
5
|
+
const INITIAL_RECONNECT_DELAY_MS = 1_000;
|
|
6
|
+
const MAX_RECONNECT_DELAY_MS = 30_000;
|
|
7
|
+
const MAX_RECONNECT_ATTEMPTS = 5;
|
|
4
8
|
export function createTunnel(config) {
|
|
5
9
|
const localOrigin = `http://127.0.0.1:${config.port}`;
|
|
6
10
|
const wsUrl = buildWsUrl(config);
|
|
7
|
-
connect(wsUrl, config, localOrigin);
|
|
11
|
+
connect(wsUrl, config, localOrigin, 0);
|
|
8
12
|
}
|
|
9
13
|
function resolveForwardedPath(previewPath, path) {
|
|
10
14
|
if (!previewPath || previewPath.length === 0) {
|
|
@@ -34,7 +38,10 @@ export function buildWsUrl(config) {
|
|
|
34
38
|
url.searchParams.set("token", config.deviceSecret);
|
|
35
39
|
return url.toString();
|
|
36
40
|
}
|
|
37
|
-
function
|
|
41
|
+
export function getReconnectDelayMs(attempt) {
|
|
42
|
+
return Math.min(INITIAL_RECONNECT_DELAY_MS * (2 ** Math.max(attempt - 1, 0)), MAX_RECONNECT_DELAY_MS);
|
|
43
|
+
}
|
|
44
|
+
function connect(wsUrl, config, localOrigin, reconnectAttempt) {
|
|
38
45
|
const ws = new WebSocket(wsUrl);
|
|
39
46
|
let heartbeatInterval = null;
|
|
40
47
|
ws.on("open", () => {
|
|
@@ -53,7 +60,7 @@ function connect(wsUrl, config, localOrigin) {
|
|
|
53
60
|
timestamp: Date.now(),
|
|
54
61
|
}));
|
|
55
62
|
}
|
|
56
|
-
},
|
|
63
|
+
}, HEARTBEAT_INTERVAL_MS);
|
|
57
64
|
});
|
|
58
65
|
ws.on("message", async (data) => {
|
|
59
66
|
const msg = parseInbound(data.toString());
|
|
@@ -80,11 +87,21 @@ function connect(wsUrl, config, localOrigin) {
|
|
|
80
87
|
}
|
|
81
88
|
}
|
|
82
89
|
});
|
|
83
|
-
ws.on("close", () => {
|
|
90
|
+
ws.on("close", (code) => {
|
|
84
91
|
if (heartbeatInterval)
|
|
85
92
|
clearInterval(heartbeatInterval);
|
|
86
|
-
|
|
87
|
-
|
|
93
|
+
if (code === 4001) {
|
|
94
|
+
console.log("Disconnected because another tunnel replaced this session.");
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const nextAttempt = reconnectAttempt + 1;
|
|
98
|
+
if (nextAttempt > MAX_RECONNECT_ATTEMPTS) {
|
|
99
|
+
console.error("Tunnel reconnect failed after 5 attempts.");
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const delayMs = getReconnectDelayMs(nextAttempt);
|
|
103
|
+
console.log(`Disconnected. Reconnecting in ${Math.round(delayMs / 1000)}s (attempt ${nextAttempt}/5)...`);
|
|
104
|
+
setTimeout(() => connect(wsUrl, config, localOrigin, nextAttempt), delayMs);
|
|
88
105
|
});
|
|
89
106
|
ws.on("error", (err) => {
|
|
90
107
|
console.error(`WebSocket error: ${err.message}`);
|
package/dist/tunnel.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tunnel.js","sourceRoot":"","sources":["../src/tunnel.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,IAAI,CAAC;AAE3B,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,UAAU,YAAY,CAAC,MAAoB;IAC/C,MAAM,WAAW,GAAG,oBAAoB,MAAM,CAAC,IAAI,EAAE,CAAC;IACtD,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IAEjC,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"tunnel.js","sourceRoot":"","sources":["../src/tunnel.ts"],"names":[],"mappings":"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"}
|