remote-codex 0.11.23 → 0.11.24
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/apps/relay-server/dist/index.js +151 -7
- package/apps/supervisor-api/dist/index.js +68 -27
- package/apps/supervisor-web/dist/assets/index-DeQ67jTv.js +5 -0
- package/apps/supervisor-web/dist/assets/index-DgSdRu7a.css +1 -0
- package/apps/supervisor-web/dist/assets/{thread-ui-jJyFqIuV.js → thread-ui-Ck4oSYRQ.js} +20 -20
- package/apps/supervisor-web/dist/index.html +3 -3
- package/package.json +1 -1
- package/packages/shared/src/index.ts +19 -0
- package/apps/supervisor-web/dist/assets/index-CtcCwgIc.js +0 -5
- package/apps/supervisor-web/dist/assets/index-PMKHoC-h.css +0 -1
|
@@ -203,7 +203,7 @@ var RelayStore = class _RelayStore {
|
|
|
203
203
|
).get(ownerUserId, target.id, input.deviceId, input.threadId)
|
|
204
204
|
);
|
|
205
205
|
if (existing) {
|
|
206
|
-
return this.
|
|
206
|
+
return this.updateShareRecord(existing.id, {
|
|
207
207
|
label: input.label?.trim() || null,
|
|
208
208
|
workspaceId: input.workspaceId?.trim() || null,
|
|
209
209
|
threadAccess: normalizeThreadAccess(input.threadAccess),
|
|
@@ -226,11 +226,31 @@ var RelayStore = class _RelayStore {
|
|
|
226
226
|
workspaceAccess: normalizeWorkspaceAccess(input.workspaceAccess),
|
|
227
227
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
228
228
|
revokedAt: null,
|
|
229
|
-
expiresAt: normalizeExpiresAt(input.expiresAt)
|
|
229
|
+
expiresAt: normalizeExpiresAt(input.expiresAt),
|
|
230
|
+
lastAccessedAt: null,
|
|
231
|
+
lastAccessedByUsername: null,
|
|
232
|
+
accessEvents: []
|
|
230
233
|
};
|
|
231
234
|
this.insertShare(share);
|
|
232
235
|
return share;
|
|
233
236
|
}
|
|
237
|
+
updateShare(userId, shareId, input) {
|
|
238
|
+
const share = this.rowToShare(
|
|
239
|
+
this.sqlite.prepare("SELECT * FROM relay_shares WHERE id = ? AND owner_user_id = ? AND revoked_at IS NULL").get(shareId, userId)
|
|
240
|
+
);
|
|
241
|
+
if (!share) {
|
|
242
|
+
throw new RelayStoreError(404, "not_found", "Share was not found.");
|
|
243
|
+
}
|
|
244
|
+
return this.publicShare(
|
|
245
|
+
this.updateShareRecord(shareId, {
|
|
246
|
+
label: input.label !== void 0 ? input.label?.trim() || null : share.label,
|
|
247
|
+
workspaceId: input.workspaceId !== void 0 ? input.workspaceId?.trim() || null : share.workspaceId,
|
|
248
|
+
threadAccess: input.threadAccess !== void 0 ? normalizeThreadAccess(input.threadAccess) : share.threadAccess,
|
|
249
|
+
workspaceAccess: input.workspaceAccess !== void 0 ? normalizeWorkspaceAccess(input.workspaceAccess) : share.workspaceAccess,
|
|
250
|
+
expiresAt: input.expiresAt !== void 0 ? normalizeExpiresAt(input.expiresAt) : share.expiresAt
|
|
251
|
+
})
|
|
252
|
+
);
|
|
253
|
+
}
|
|
234
254
|
revokeShare(userId, shareId) {
|
|
235
255
|
const share = this.rowToShare(
|
|
236
256
|
this.sqlite.prepare("SELECT * FROM relay_shares WHERE id = ? AND owner_user_id = ?").get(shareId, userId)
|
|
@@ -404,15 +424,33 @@ var RelayStore = class _RelayStore {
|
|
|
404
424
|
createdAt: device.createdAt
|
|
405
425
|
};
|
|
406
426
|
}
|
|
427
|
+
recordShareAccess(share, user) {
|
|
428
|
+
if (share.revokedAt || share.expiresAt && share.expiresAt <= (/* @__PURE__ */ new Date()).toISOString()) {
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
const accessedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
432
|
+
this.sqlite.prepare(
|
|
433
|
+
`
|
|
434
|
+
INSERT INTO relay_share_access_events (
|
|
435
|
+
id, share_id, user_id, username, accessed_at
|
|
436
|
+
) VALUES (?, ?, ?, ?, ?)
|
|
437
|
+
`
|
|
438
|
+
).run(crypto.randomUUID(), share.id, user.id, user.username, accessedAt);
|
|
439
|
+
}
|
|
407
440
|
publicShare(share) {
|
|
408
441
|
const owner = this.getUser(share.ownerUserId);
|
|
409
442
|
const target = this.getUser(share.targetUserId);
|
|
410
443
|
const device = this.getDevice(share.deviceId);
|
|
444
|
+
const accessEvents = this.getShareAccessEvents(share.id);
|
|
445
|
+
const lastAccess = accessEvents[0] ?? null;
|
|
411
446
|
return {
|
|
412
447
|
...share,
|
|
413
448
|
ownerUsername: share.ownerUsername ?? owner?.username ?? "unknown",
|
|
414
449
|
targetUsername: share.targetUsername ?? target?.username ?? "unknown",
|
|
415
|
-
deviceName: share.deviceName ?? device?.name ?? "Remote Codex device"
|
|
450
|
+
deviceName: share.deviceName ?? device?.name ?? "Remote Codex device",
|
|
451
|
+
lastAccessedAt: lastAccess?.accessedAt ?? null,
|
|
452
|
+
lastAccessedByUsername: lastAccess?.username ?? null,
|
|
453
|
+
accessEvents
|
|
416
454
|
};
|
|
417
455
|
}
|
|
418
456
|
migrate() {
|
|
@@ -466,6 +504,16 @@ var RelayStore = class _RelayStore {
|
|
|
466
504
|
CREATE INDEX IF NOT EXISTS relay_shares_owner_idx ON relay_shares(owner_user_id);
|
|
467
505
|
CREATE INDEX IF NOT EXISTS relay_shares_target_idx ON relay_shares(target_user_id);
|
|
468
506
|
CREATE INDEX IF NOT EXISTS relay_shares_device_thread_idx ON relay_shares(device_id, thread_id);
|
|
507
|
+
|
|
508
|
+
CREATE TABLE IF NOT EXISTS relay_share_access_events (
|
|
509
|
+
id TEXT PRIMARY KEY,
|
|
510
|
+
share_id TEXT NOT NULL REFERENCES relay_shares(id) ON DELETE CASCADE,
|
|
511
|
+
user_id TEXT NOT NULL REFERENCES relay_users(id) ON DELETE CASCADE,
|
|
512
|
+
username TEXT NOT NULL,
|
|
513
|
+
accessed_at TEXT NOT NULL
|
|
514
|
+
);
|
|
515
|
+
|
|
516
|
+
CREATE INDEX IF NOT EXISTS relay_share_access_events_share_idx ON relay_share_access_events(share_id, accessed_at DESC);
|
|
469
517
|
`);
|
|
470
518
|
this.ensureColumn("relay_devices", "token", "TEXT");
|
|
471
519
|
this.ensureColumn("relay_shares", "workspace_id", "TEXT");
|
|
@@ -672,7 +720,23 @@ var RelayStore = class _RelayStore {
|
|
|
672
720
|
share.expiresAt
|
|
673
721
|
);
|
|
674
722
|
}
|
|
675
|
-
|
|
723
|
+
getShareAccessEvents(shareId) {
|
|
724
|
+
return this.sqlite.prepare(
|
|
725
|
+
`
|
|
726
|
+
SELECT * FROM relay_share_access_events
|
|
727
|
+
WHERE share_id = ?
|
|
728
|
+
ORDER BY accessed_at DESC
|
|
729
|
+
LIMIT 8
|
|
730
|
+
`
|
|
731
|
+
).all(shareId).map((row) => ({
|
|
732
|
+
id: row.id,
|
|
733
|
+
shareId: row.share_id,
|
|
734
|
+
userId: row.user_id,
|
|
735
|
+
username: row.username,
|
|
736
|
+
accessedAt: row.accessed_at
|
|
737
|
+
}));
|
|
738
|
+
}
|
|
739
|
+
updateShareRecord(shareId, input) {
|
|
676
740
|
this.sqlite.prepare(
|
|
677
741
|
`
|
|
678
742
|
UPDATE relay_shares
|
|
@@ -768,7 +832,10 @@ var RelayStore = class _RelayStore {
|
|
|
768
832
|
workspaceAccess: normalizeWorkspaceAccess(row.workspace_access),
|
|
769
833
|
createdAt: row.created_at,
|
|
770
834
|
revokedAt: row.revoked_at,
|
|
771
|
-
expiresAt: row.expires_at ?? null
|
|
835
|
+
expiresAt: row.expires_at ?? null,
|
|
836
|
+
lastAccessedAt: null,
|
|
837
|
+
lastAccessedByUsername: null,
|
|
838
|
+
accessEvents: []
|
|
772
839
|
};
|
|
773
840
|
}
|
|
774
841
|
};
|
|
@@ -854,6 +921,13 @@ var createShareSchema = z.object({
|
|
|
854
921
|
message: "targetIdentifier is required.",
|
|
855
922
|
path: ["targetIdentifier"]
|
|
856
923
|
});
|
|
924
|
+
var updateShareSchema = z.object({
|
|
925
|
+
workspaceId: z.string().uuid().nullable().optional(),
|
|
926
|
+
label: z.string().trim().min(1).max(160).nullable().optional(),
|
|
927
|
+
threadAccess: threadAccessSchema.optional(),
|
|
928
|
+
workspaceAccess: workspaceAccessSchema.optional(),
|
|
929
|
+
expiresAt: z.string().datetime().nullable().optional()
|
|
930
|
+
});
|
|
857
931
|
var setEnabledSchema = z.object({
|
|
858
932
|
enabled: z.boolean()
|
|
859
933
|
});
|
|
@@ -888,6 +962,58 @@ var WEBVIEW_CORS_ALLOW_METHODS = [
|
|
|
888
962
|
"DELETE",
|
|
889
963
|
"OPTIONS"
|
|
890
964
|
].join(", ");
|
|
965
|
+
var RELAY_REQUEST_HEADER_BLOCKLIST = /* @__PURE__ */ new Set([
|
|
966
|
+
"authorization",
|
|
967
|
+
"connection",
|
|
968
|
+
"content-length",
|
|
969
|
+
"cookie",
|
|
970
|
+
"expect",
|
|
971
|
+
"forwarded",
|
|
972
|
+
"host",
|
|
973
|
+
"keep-alive",
|
|
974
|
+
"origin",
|
|
975
|
+
"proxy-authenticate",
|
|
976
|
+
"proxy-authorization",
|
|
977
|
+
"proxy-connection",
|
|
978
|
+
"referer",
|
|
979
|
+
"referrer",
|
|
980
|
+
"set-cookie",
|
|
981
|
+
"te",
|
|
982
|
+
"trailer",
|
|
983
|
+
"transfer-encoding",
|
|
984
|
+
"upgrade",
|
|
985
|
+
"via",
|
|
986
|
+
"x-client-ip",
|
|
987
|
+
"x-forwarded-for",
|
|
988
|
+
"x-forwarded-host",
|
|
989
|
+
"x-forwarded-port",
|
|
990
|
+
"x-forwarded-proto",
|
|
991
|
+
"x-forwarded-protocol",
|
|
992
|
+
"x-forwarded-scheme",
|
|
993
|
+
"x-real-ip",
|
|
994
|
+
"x-remote-codex-relay-forwarded"
|
|
995
|
+
]);
|
|
996
|
+
var RELAY_RESPONSE_HEADER_BLOCKLIST = /* @__PURE__ */ new Set([
|
|
997
|
+
"access-control-allow-credentials",
|
|
998
|
+
"access-control-allow-headers",
|
|
999
|
+
"access-control-allow-methods",
|
|
1000
|
+
"access-control-allow-origin",
|
|
1001
|
+
"access-control-expose-headers",
|
|
1002
|
+
"access-control-max-age",
|
|
1003
|
+
"access-control-request-headers",
|
|
1004
|
+
"access-control-request-method",
|
|
1005
|
+
"connection",
|
|
1006
|
+
"content-length",
|
|
1007
|
+
"keep-alive",
|
|
1008
|
+
"location",
|
|
1009
|
+
"proxy-authenticate",
|
|
1010
|
+
"refresh",
|
|
1011
|
+
"set-cookie",
|
|
1012
|
+
"te",
|
|
1013
|
+
"trailer",
|
|
1014
|
+
"transfer-encoding",
|
|
1015
|
+
"upgrade"
|
|
1016
|
+
]);
|
|
891
1017
|
function buildRelayServer(config2, options = {}) {
|
|
892
1018
|
const app2 = Fastify({ logger: false });
|
|
893
1019
|
app2.addContentTypeParser("*", { parseAs: "buffer" }, (_request, body, done) => {
|
|
@@ -1038,6 +1164,15 @@ function buildRelayServer(config2, options = {}) {
|
|
|
1038
1164
|
expiresAt: body.expiresAt ?? null
|
|
1039
1165
|
});
|
|
1040
1166
|
});
|
|
1167
|
+
app2.patch("/relay/shares/:shareId", async (request, reply) => {
|
|
1168
|
+
const user = requireRelayUser(request, reply, store);
|
|
1169
|
+
if (!user) {
|
|
1170
|
+
return;
|
|
1171
|
+
}
|
|
1172
|
+
const { shareId } = z.object({ shareId: z.string().uuid() }).parse(request.params);
|
|
1173
|
+
const body = updateShareSchema.parse(request.body ?? {});
|
|
1174
|
+
return store.updateShare(user.id, shareId, body);
|
|
1175
|
+
});
|
|
1041
1176
|
app2.delete("/relay/shares/:shareId", async (request, reply) => {
|
|
1042
1177
|
const user = requireRelayUser(request, reply, store);
|
|
1043
1178
|
if (!user) {
|
|
@@ -1231,6 +1366,9 @@ function buildRelayServer(config2, options = {}) {
|
|
|
1231
1366
|
socket.close(1013, "No supervisor is connected for this device.");
|
|
1232
1367
|
return;
|
|
1233
1368
|
}
|
|
1369
|
+
if (access.kind === "shared") {
|
|
1370
|
+
store.recordShareAccess(access.share, session.user);
|
|
1371
|
+
}
|
|
1234
1372
|
connectRelayWebsocket(supervisor, socket, threadId, access);
|
|
1235
1373
|
}
|
|
1236
1374
|
});
|
|
@@ -1261,6 +1399,9 @@ function buildRelayServer(config2, options = {}) {
|
|
|
1261
1399
|
socket.close(1008, "Device access is not allowed.");
|
|
1262
1400
|
return;
|
|
1263
1401
|
}
|
|
1402
|
+
if (access.kind === "shared") {
|
|
1403
|
+
store.recordShareAccess(access.share, session.user);
|
|
1404
|
+
}
|
|
1264
1405
|
connectRelayWebsocket(supervisor, socket, threadId, access);
|
|
1265
1406
|
}
|
|
1266
1407
|
});
|
|
@@ -1335,6 +1476,9 @@ async function forwardRelayHttp(input) {
|
|
|
1335
1476
|
});
|
|
1336
1477
|
return;
|
|
1337
1478
|
}
|
|
1479
|
+
if (access.kind === "shared") {
|
|
1480
|
+
input.store.recordShareAccess(access.share, input.user);
|
|
1481
|
+
}
|
|
1338
1482
|
const supervisor = input.state.supervisors.get(input.deviceId);
|
|
1339
1483
|
if (!supervisor || supervisor.socket.readyState !== WEBSOCKET_OPEN) {
|
|
1340
1484
|
input.reply.status(503).send({
|
|
@@ -1678,7 +1822,7 @@ function relayRequestHeaders(headers) {
|
|
|
1678
1822
|
const output = {};
|
|
1679
1823
|
for (const [name, value] of Object.entries(headers)) {
|
|
1680
1824
|
const lower = name.toLowerCase();
|
|
1681
|
-
if (lower
|
|
1825
|
+
if (RELAY_REQUEST_HEADER_BLOCKLIST.has(lower) || lower.startsWith("x-forwarded-")) {
|
|
1682
1826
|
continue;
|
|
1683
1827
|
}
|
|
1684
1828
|
if (Array.isArray(value)) {
|
|
@@ -1691,7 +1835,7 @@ function relayRequestHeaders(headers) {
|
|
|
1691
1835
|
}
|
|
1692
1836
|
function canForwardResponseHeader(name) {
|
|
1693
1837
|
const lower = name.toLowerCase();
|
|
1694
|
-
return lower
|
|
1838
|
+
return !RELAY_RESPONSE_HEADER_BLOCKLIST.has(lower);
|
|
1695
1839
|
}
|
|
1696
1840
|
function bearerToken(value) {
|
|
1697
1841
|
const match = /^Bearer\s+(.+)$/i.exec(value ?? "");
|
|
@@ -27428,6 +27428,7 @@ function constantTimeEqual(left, right) {
|
|
|
27428
27428
|
|
|
27429
27429
|
// src/relay-tunnel-client.ts
|
|
27430
27430
|
var RELAY_HEARTBEAT_INTERVAL_MS = 3e4;
|
|
27431
|
+
var RELAY_CONNECT_TIMEOUT_MS = 15e3;
|
|
27431
27432
|
var RELAY_RECONNECT_INITIAL_DELAY_MS = 1e3;
|
|
27432
27433
|
var RELAY_RECONNECT_MAX_DELAY_MS = 3e4;
|
|
27433
27434
|
var RelayTunnelClient = class {
|
|
@@ -27443,6 +27444,7 @@ var RelayTunnelClient = class {
|
|
|
27443
27444
|
handleClientMessage;
|
|
27444
27445
|
socket = null;
|
|
27445
27446
|
heartbeatHandle = null;
|
|
27447
|
+
connectTimeoutHandle = null;
|
|
27446
27448
|
reconnectHandle = null;
|
|
27447
27449
|
reconnectDelayMs = RELAY_RECONNECT_INITIAL_DELAY_MS;
|
|
27448
27450
|
stopped = false;
|
|
@@ -27464,42 +27466,50 @@ var RelayTunnelClient = class {
|
|
|
27464
27466
|
const url = new URL("/supervisor/tunnel", this.config.serverUrl ?? void 0);
|
|
27465
27467
|
url.searchParams.set("token", this.config.agentToken ?? "");
|
|
27466
27468
|
url.searchParams.set("deviceToken", this.config.agentToken ?? "");
|
|
27467
|
-
|
|
27468
|
-
this.socket
|
|
27469
|
+
const socket = new WebSocket(url);
|
|
27470
|
+
this.socket = socket;
|
|
27471
|
+
this.connectTimeoutHandle = setTimeout(() => {
|
|
27472
|
+
if (this.socket === socket && socket.readyState !== WebSocket.OPEN) {
|
|
27473
|
+
this.closeAndReconnect(socket);
|
|
27474
|
+
}
|
|
27475
|
+
}, RELAY_CONNECT_TIMEOUT_MS);
|
|
27476
|
+
socket.addEventListener("open", () => {
|
|
27477
|
+
this.clearConnectTimeout();
|
|
27469
27478
|
this.reconnectDelayMs = RELAY_RECONNECT_INITIAL_DELAY_MS;
|
|
27470
27479
|
this.sendHeartbeat();
|
|
27480
|
+
this.clearHeartbeat();
|
|
27471
27481
|
this.heartbeatHandle = setInterval(() => {
|
|
27472
27482
|
this.sendHeartbeat();
|
|
27473
27483
|
}, RELAY_HEARTBEAT_INTERVAL_MS);
|
|
27474
27484
|
});
|
|
27475
|
-
|
|
27476
|
-
this.
|
|
27477
|
-
|
|
27478
|
-
|
|
27479
|
-
this.
|
|
27485
|
+
socket.addEventListener("close", () => {
|
|
27486
|
+
this.closeAndReconnect(socket);
|
|
27487
|
+
});
|
|
27488
|
+
socket.addEventListener("error", () => {
|
|
27489
|
+
this.closeAndReconnect(socket);
|
|
27480
27490
|
});
|
|
27481
|
-
|
|
27491
|
+
socket.addEventListener("message", (event) => {
|
|
27482
27492
|
void this.handleMessage(String(event.data));
|
|
27483
27493
|
});
|
|
27484
27494
|
}
|
|
27485
27495
|
stop() {
|
|
27486
27496
|
this.stopped = true;
|
|
27487
27497
|
this.clearHeartbeat();
|
|
27498
|
+
this.clearConnectTimeout();
|
|
27488
27499
|
this.clearReconnect();
|
|
27489
27500
|
this.cleanupRelayClients();
|
|
27490
27501
|
this.socket?.close();
|
|
27491
27502
|
this.socket = null;
|
|
27492
27503
|
}
|
|
27493
27504
|
sendHeartbeat() {
|
|
27494
|
-
|
|
27505
|
+
const socket = this.socket;
|
|
27506
|
+
if (socket?.readyState !== WebSocket.OPEN) {
|
|
27495
27507
|
return;
|
|
27496
27508
|
}
|
|
27497
|
-
this.socket
|
|
27498
|
-
|
|
27499
|
-
|
|
27500
|
-
|
|
27501
|
-
})
|
|
27502
|
-
);
|
|
27509
|
+
this.sendEnvelope(socket, {
|
|
27510
|
+
type: "relay.heartbeat",
|
|
27511
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
27512
|
+
});
|
|
27503
27513
|
}
|
|
27504
27514
|
async handleMessage(rawMessage) {
|
|
27505
27515
|
let parsed;
|
|
@@ -27530,27 +27540,52 @@ var RelayTunnelClient = class {
|
|
|
27530
27540
|
return;
|
|
27531
27541
|
}
|
|
27532
27542
|
const response = await this.handleRequest(parsed.payload);
|
|
27533
|
-
this.socket
|
|
27534
|
-
|
|
27543
|
+
const socket = this.socket;
|
|
27544
|
+
if (socket?.readyState !== WebSocket.OPEN) {
|
|
27545
|
+
return;
|
|
27546
|
+
}
|
|
27547
|
+
this.sendEnvelope(
|
|
27548
|
+
socket,
|
|
27549
|
+
{
|
|
27535
27550
|
type: "relay.response",
|
|
27536
27551
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
27537
27552
|
requestId: parsed.requestId,
|
|
27538
27553
|
payload: response
|
|
27539
|
-
}
|
|
27554
|
+
}
|
|
27540
27555
|
);
|
|
27541
27556
|
}
|
|
27542
27557
|
sendClientMessage(clientId, message) {
|
|
27543
|
-
|
|
27558
|
+
const socket = this.socket;
|
|
27559
|
+
if (socket?.readyState !== WebSocket.OPEN) {
|
|
27544
27560
|
return;
|
|
27545
27561
|
}
|
|
27546
|
-
this.socket
|
|
27547
|
-
|
|
27548
|
-
|
|
27549
|
-
|
|
27550
|
-
|
|
27551
|
-
|
|
27552
|
-
|
|
27553
|
-
|
|
27562
|
+
this.sendEnvelope(socket, {
|
|
27563
|
+
type: "relay.server.message",
|
|
27564
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
27565
|
+
clientId,
|
|
27566
|
+
payload: message
|
|
27567
|
+
});
|
|
27568
|
+
}
|
|
27569
|
+
sendEnvelope(socket, message) {
|
|
27570
|
+
try {
|
|
27571
|
+
socket.send(JSON.stringify(message));
|
|
27572
|
+
} catch {
|
|
27573
|
+
this.closeAndReconnect(socket);
|
|
27574
|
+
}
|
|
27575
|
+
}
|
|
27576
|
+
closeAndReconnect(socket) {
|
|
27577
|
+
if (this.socket !== socket) {
|
|
27578
|
+
return;
|
|
27579
|
+
}
|
|
27580
|
+
this.clearHeartbeat();
|
|
27581
|
+
this.clearConnectTimeout();
|
|
27582
|
+
this.cleanupRelayClients();
|
|
27583
|
+
this.socket = null;
|
|
27584
|
+
try {
|
|
27585
|
+
socket.close();
|
|
27586
|
+
} catch {
|
|
27587
|
+
}
|
|
27588
|
+
this.scheduleReconnect();
|
|
27554
27589
|
}
|
|
27555
27590
|
clearHeartbeat() {
|
|
27556
27591
|
if (this.heartbeatHandle) {
|
|
@@ -27558,6 +27593,12 @@ var RelayTunnelClient = class {
|
|
|
27558
27593
|
this.heartbeatHandle = null;
|
|
27559
27594
|
}
|
|
27560
27595
|
}
|
|
27596
|
+
clearConnectTimeout() {
|
|
27597
|
+
if (this.connectTimeoutHandle) {
|
|
27598
|
+
clearTimeout(this.connectTimeoutHandle);
|
|
27599
|
+
this.connectTimeoutHandle = null;
|
|
27600
|
+
}
|
|
27601
|
+
}
|
|
27561
27602
|
scheduleReconnect() {
|
|
27562
27603
|
if (this.stopped || this.reconnectHandle) {
|
|
27563
27604
|
return;
|