tokmon 0.28.1 → 0.28.2
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/{bootstrap-ink-L7QSJBMS.js → bootstrap-ink-IMT3S5HU.js} +5 -4
- package/dist/{chunk-FMP3P2WV.js → chunk-44ZSQEOS.js} +1 -1
- package/dist/{chunk-S33XIUAW.js → chunk-6ZEW2M6P.js} +158 -30
- package/dist/{chunk-XDA5RJST.js → chunk-J3JW3RFP.js} +9 -6
- package/dist/{chunk-CVKCVHS7.js → chunk-LCAHTRGP.js} +14 -281
- package/dist/{chunk-4HU4EI5T.js → chunk-LKYOWBD4.js} +15 -15
- package/dist/{chunk-3RTWFGGD.js → chunk-M7XMV36F.js} +1 -1
- package/dist/chunk-WUK3MQUB.js +249 -0
- package/dist/{cli-command-75LP4IDS.js → cli-command-DCENRCO3.js} +5 -5
- package/dist/cli.js +5 -5
- package/dist/{daemon-CL4FJW26.js → daemon-6Y4O7NXS.js} +35 -13
- package/dist/{daemon-handle-QQLJE46Y.js → daemon-handle-GVCYVDPO.js} +3 -3
- package/dist/server-GXXOWUVZ.js +11 -0
- package/package.json +1 -1
- package/dist/chunk-SMPY52EV.js +0 -125
- package/dist/server-EUO7CWYH.js +0 -11
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
createDaemonRpcClient
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-M7XMV36F.js";
|
|
5
5
|
import {
|
|
6
6
|
accountsByProvider,
|
|
7
7
|
buildAccounts,
|
|
8
8
|
fetchPeak,
|
|
9
9
|
modelColor
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-44ZSQEOS.js";
|
|
11
11
|
import {
|
|
12
12
|
PROVIDERS,
|
|
13
13
|
PROVIDER_ORDER,
|
|
@@ -24,7 +24,8 @@ import {
|
|
|
24
24
|
time,
|
|
25
25
|
tokens,
|
|
26
26
|
withTimeout
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-LCAHTRGP.js";
|
|
28
|
+
import "./chunk-WUK3MQUB.js";
|
|
28
29
|
import {
|
|
29
30
|
COLOR_PALETTE,
|
|
30
31
|
DEFAULTS,
|
|
@@ -3560,7 +3561,7 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, mode = "deg
|
|
|
3560
3561
|
if (webStartingRef.current) return;
|
|
3561
3562
|
webStartingRef.current = true;
|
|
3562
3563
|
try {
|
|
3563
|
-
const { startWebServer } = await import("./server-
|
|
3564
|
+
const { startWebServer } = await import("./server-GXXOWUVZ.js");
|
|
3564
3565
|
const ctrl = await startWebServer({ config: cfg, log: false });
|
|
3565
3566
|
webRef.current = ctrl;
|
|
3566
3567
|
openUrl(ctrl.url);
|
|
@@ -1,28 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
appVersion,
|
|
4
|
-
findWebRoot,
|
|
5
|
-
send,
|
|
6
|
-
sendJson,
|
|
7
|
-
serveStatic
|
|
8
|
-
} from "./chunk-SMPY52EV.js";
|
|
9
2
|
import {
|
|
10
3
|
buildAccounts,
|
|
11
4
|
colorHex,
|
|
12
5
|
fetchPeak,
|
|
13
6
|
namedHex
|
|
14
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-44ZSQEOS.js";
|
|
15
8
|
import {
|
|
16
9
|
PROVIDERS,
|
|
10
|
+
detectProviders,
|
|
11
|
+
resolveTimezone,
|
|
12
|
+
withTimeout
|
|
13
|
+
} from "./chunk-LCAHTRGP.js";
|
|
14
|
+
import {
|
|
17
15
|
TOKMON_CAPABILITIES,
|
|
18
16
|
TOKMON_PROTOCOL_VERSION,
|
|
19
17
|
TOKMON_WS_METHODS,
|
|
20
18
|
TOKMON_WS_PATH,
|
|
21
|
-
TokmonRpcGroup
|
|
22
|
-
|
|
23
|
-
resolveTimezone,
|
|
24
|
-
withTimeout
|
|
25
|
-
} from "./chunk-CVKCVHS7.js";
|
|
19
|
+
TokmonRpcGroup
|
|
20
|
+
} from "./chunk-WUK3MQUB.js";
|
|
26
21
|
import {
|
|
27
22
|
cacheDir,
|
|
28
23
|
expandHome,
|
|
@@ -118,11 +113,127 @@ function tzFor(config) {
|
|
|
118
113
|
return resolveTimezone(config.timezone);
|
|
119
114
|
}
|
|
120
115
|
|
|
116
|
+
// src/web/static.ts
|
|
117
|
+
import { createReadStream, existsSync, readFileSync } from "fs";
|
|
118
|
+
import { stat } from "fs/promises";
|
|
119
|
+
import { fileURLToPath } from "url";
|
|
120
|
+
import { extname, join, normalize, sep } from "path";
|
|
121
|
+
var MIME = {
|
|
122
|
+
".html": "text/html; charset=utf-8",
|
|
123
|
+
".js": "text/javascript; charset=utf-8",
|
|
124
|
+
".mjs": "text/javascript; charset=utf-8",
|
|
125
|
+
".css": "text/css; charset=utf-8",
|
|
126
|
+
".json": "application/json; charset=utf-8",
|
|
127
|
+
".svg": "image/svg+xml",
|
|
128
|
+
".png": "image/png",
|
|
129
|
+
".jpg": "image/jpeg",
|
|
130
|
+
".jpeg": "image/jpeg",
|
|
131
|
+
".gif": "image/gif",
|
|
132
|
+
".ico": "image/x-icon",
|
|
133
|
+
".woff": "font/woff",
|
|
134
|
+
".woff2": "font/woff2",
|
|
135
|
+
".ttf": "font/ttf",
|
|
136
|
+
".otf": "font/otf",
|
|
137
|
+
".map": "application/json; charset=utf-8",
|
|
138
|
+
".webmanifest": "application/manifest+json"
|
|
139
|
+
};
|
|
140
|
+
function findWebRoot() {
|
|
141
|
+
const candidates = ["./web/", "../web/", "../dist/web/", "../../dist/web/"];
|
|
142
|
+
for (const rel of candidates) {
|
|
143
|
+
try {
|
|
144
|
+
const dir = fileURLToPath(new URL(rel, import.meta.url));
|
|
145
|
+
if (existsSync(join(dir, "index.html"))) return dir.replace(/[\\/]+$/, "");
|
|
146
|
+
} catch {
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
function resolveStaticPath(webRoot, urlPath) {
|
|
152
|
+
let clean;
|
|
153
|
+
try {
|
|
154
|
+
clean = decodeURIComponent(urlPath.split("?")[0]);
|
|
155
|
+
} catch {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
const rel = normalize(clean).replace(/^(\.\.[/\\])+/, "").replace(/^[/\\]+/, "");
|
|
159
|
+
const full = join(webRoot, rel);
|
|
160
|
+
if (full !== webRoot && !full.startsWith(webRoot + sep)) return null;
|
|
161
|
+
return full;
|
|
162
|
+
}
|
|
163
|
+
function send(res, status, type, body) {
|
|
164
|
+
res.writeHead(status, {
|
|
165
|
+
"Content-Type": type,
|
|
166
|
+
"Cache-Control": "no-store",
|
|
167
|
+
"Referrer-Policy": "no-referrer",
|
|
168
|
+
"X-Content-Type-Options": "nosniff"
|
|
169
|
+
});
|
|
170
|
+
res.end(body);
|
|
171
|
+
}
|
|
172
|
+
function sendJson(res, status, data) {
|
|
173
|
+
send(res, status, "application/json; charset=utf-8", JSON.stringify(data));
|
|
174
|
+
}
|
|
175
|
+
function serveStatic(webRoot, urlPath, res) {
|
|
176
|
+
const path = urlPath.split("?")[0];
|
|
177
|
+
const filePath = resolveStaticPath(webRoot, path === "/" ? "/index.html" : path);
|
|
178
|
+
if (!filePath) {
|
|
179
|
+
send(res, 403, "text/plain", "forbidden");
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
void stat(filePath).then((st) => {
|
|
183
|
+
if (st.isFile()) {
|
|
184
|
+
const type = MIME[extname(filePath).toLowerCase()] || "application/octet-stream";
|
|
185
|
+
const immutable = filePath.includes(`${sep}assets${sep}`);
|
|
186
|
+
res.writeHead(200, {
|
|
187
|
+
"Content-Type": type,
|
|
188
|
+
"Cache-Control": immutable ? "public, max-age=31536000, immutable" : "no-cache",
|
|
189
|
+
"Referrer-Policy": "no-referrer",
|
|
190
|
+
"X-Content-Type-Options": "nosniff"
|
|
191
|
+
});
|
|
192
|
+
createReadStream(filePath).pipe(res);
|
|
193
|
+
} else {
|
|
194
|
+
throw new Error("not a file");
|
|
195
|
+
}
|
|
196
|
+
}).catch(() => {
|
|
197
|
+
if (extname(path)) {
|
|
198
|
+
send(res, 404, "text/plain", "not found");
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
const indexPath = join(webRoot, "index.html");
|
|
202
|
+
if (!existsSync(indexPath)) {
|
|
203
|
+
send(res, 404, "text/plain", "not found");
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
res.writeHead(200, {
|
|
207
|
+
"Content-Type": MIME[".html"],
|
|
208
|
+
"Cache-Control": "no-cache",
|
|
209
|
+
"Referrer-Policy": "no-referrer",
|
|
210
|
+
"X-Content-Type-Options": "nosniff"
|
|
211
|
+
});
|
|
212
|
+
createReadStream(indexPath).on("error", () => {
|
|
213
|
+
try {
|
|
214
|
+
res.destroy();
|
|
215
|
+
} catch {
|
|
216
|
+
}
|
|
217
|
+
}).pipe(res);
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
function appVersion() {
|
|
221
|
+
for (const rel of ["../package.json", "../../package.json"]) {
|
|
222
|
+
try {
|
|
223
|
+
const p = fileURLToPath(new URL(rel, import.meta.url));
|
|
224
|
+
const pkg = JSON.parse(readFileSync(p, "utf-8"));
|
|
225
|
+
if (typeof pkg.version === "string") return pkg.version;
|
|
226
|
+
} catch {
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return "";
|
|
230
|
+
}
|
|
231
|
+
|
|
121
232
|
// src/web/vite-dev.ts
|
|
122
|
-
import { existsSync } from "fs";
|
|
123
|
-
import { fileURLToPath, pathToFileURL } from "url";
|
|
233
|
+
import { existsSync as existsSync2 } from "fs";
|
|
234
|
+
import { fileURLToPath as fileURLToPath2, pathToFileURL } from "url";
|
|
124
235
|
import { createRequire } from "module";
|
|
125
|
-
import { join } from "path";
|
|
236
|
+
import { join as join2 } from "path";
|
|
126
237
|
function isDevMode() {
|
|
127
238
|
const forced = process.env.TOKMON_WEB_MODE;
|
|
128
239
|
if (forced === "dev") return true;
|
|
@@ -132,8 +243,8 @@ function isDevMode() {
|
|
|
132
243
|
function findWebSource() {
|
|
133
244
|
for (const rel of ["../../web/", "../web/", "./web/"]) {
|
|
134
245
|
try {
|
|
135
|
-
const dir =
|
|
136
|
-
if (
|
|
246
|
+
const dir = fileURLToPath2(new URL(rel, import.meta.url));
|
|
247
|
+
if (existsSync2(join2(dir, "vite.config.ts")) && existsSync2(join2(dir, "index.html"))) {
|
|
137
248
|
return dir.replace(/[\\/]+$/, "");
|
|
138
249
|
}
|
|
139
250
|
} catch {
|
|
@@ -148,12 +259,12 @@ async function createViteDevServer(httpServer, log) {
|
|
|
148
259
|
return null;
|
|
149
260
|
}
|
|
150
261
|
try {
|
|
151
|
-
const req = createRequire(pathToFileURL(
|
|
262
|
+
const req = createRequire(pathToFileURL(join2(root, "package.json")).href);
|
|
152
263
|
const vitePath = req.resolve("vite");
|
|
153
264
|
const vite = await import(pathToFileURL(vitePath).href);
|
|
154
265
|
const dev = await vite.createServer({
|
|
155
266
|
root,
|
|
156
|
-
configFile:
|
|
267
|
+
configFile: join2(root, "vite.config.ts"),
|
|
157
268
|
server: { middlewareMode: true, hmr: { server: httpServer } },
|
|
158
269
|
appType: "spa",
|
|
159
270
|
clearScreen: false,
|
|
@@ -177,7 +288,7 @@ code{color:#e6b450}</style></head><body>
|
|
|
177
288
|
</body></html>`;
|
|
178
289
|
|
|
179
290
|
// src/web/data-engine.ts
|
|
180
|
-
import { readFileSync, writeFileSync, mkdirSync, renameSync } from "fs";
|
|
291
|
+
import { readFileSync as readFileSync2, writeFileSync, mkdirSync, renameSync } from "fs";
|
|
181
292
|
|
|
182
293
|
// src/web/refresh-queue.ts
|
|
183
294
|
function deferred() {
|
|
@@ -335,7 +446,7 @@ function createDataEngine(opts) {
|
|
|
335
446
|
});
|
|
336
447
|
const hydrateFromCache = () => {
|
|
337
448
|
try {
|
|
338
|
-
const cached = JSON.parse(
|
|
449
|
+
const cached = JSON.parse(readFileSync2(snapshotCacheFile(), "utf-8"));
|
|
339
450
|
if (!cached || !Array.isArray(cached.accounts)) return;
|
|
340
451
|
for (const a of cached.accounts) {
|
|
341
452
|
if (a.dashboard || a.table) {
|
|
@@ -703,11 +814,11 @@ import { Effect, Exit, Layer, Queue, Scope, Stream } from "effect";
|
|
|
703
814
|
import { RpcSerialization, RpcServer } from "effect/unstable/rpc";
|
|
704
815
|
|
|
705
816
|
// src/web/fs.ts
|
|
706
|
-
import { readdir, stat, realpath } from "fs/promises";
|
|
817
|
+
import { readdir, stat as stat2, realpath } from "fs/promises";
|
|
707
818
|
import { homedir } from "os";
|
|
708
|
-
import { join as
|
|
819
|
+
import { join as join3, resolve as resolvePath, isAbsolute, sep as sep2 } from "path";
|
|
709
820
|
function isContained(root, target) {
|
|
710
|
-
return target === root || target.startsWith(root +
|
|
821
|
+
return target === root || target.startsWith(root + sep2);
|
|
711
822
|
}
|
|
712
823
|
function parentFor(root, abs) {
|
|
713
824
|
const parentResolved = resolvePath(abs, "..");
|
|
@@ -727,7 +838,7 @@ async function listHomeDirectory(rawPath) {
|
|
|
727
838
|
const abs = isContained(root, real) ? real : root;
|
|
728
839
|
let st;
|
|
729
840
|
try {
|
|
730
|
-
st = await
|
|
841
|
+
st = await stat2(abs);
|
|
731
842
|
} catch {
|
|
732
843
|
return { path: abs, parent: parentFor(root, abs), entries: [] };
|
|
733
844
|
}
|
|
@@ -742,7 +853,7 @@ async function listHomeDirectory(rawPath) {
|
|
|
742
853
|
for (const d of dirents) {
|
|
743
854
|
if (d.name.startsWith(".")) continue;
|
|
744
855
|
let dir = d.isDirectory();
|
|
745
|
-
const full =
|
|
856
|
+
const full = join3(abs, d.name);
|
|
746
857
|
if (d.isSymbolicLink()) {
|
|
747
858
|
let real2;
|
|
748
859
|
try {
|
|
@@ -752,7 +863,7 @@ async function listHomeDirectory(rawPath) {
|
|
|
752
863
|
}
|
|
753
864
|
if (!isContained(root, real2)) continue;
|
|
754
865
|
try {
|
|
755
|
-
dir = (await
|
|
866
|
+
dir = (await stat2(full)).isDirectory();
|
|
756
867
|
} catch {
|
|
757
868
|
continue;
|
|
758
869
|
}
|
|
@@ -957,7 +1068,7 @@ function guardSameOrigin(req, res) {
|
|
|
957
1068
|
}
|
|
958
1069
|
return true;
|
|
959
1070
|
}
|
|
960
|
-
function createRouter(engine, state, vite, webRoot, wsToken, version) {
|
|
1071
|
+
function createRouter(engine, state, vite, webRoot, wsToken, version, protocolVersion, capabilities, ownerKind) {
|
|
961
1072
|
return (req, res) => {
|
|
962
1073
|
const url = req.url || "/";
|
|
963
1074
|
const path = url.split("?")[0];
|
|
@@ -973,6 +1084,9 @@ function createRouter(engine, state, vite, webRoot, wsToken, version) {
|
|
|
973
1084
|
ok: true,
|
|
974
1085
|
ready: engine.snapshot() !== null,
|
|
975
1086
|
version,
|
|
1087
|
+
protocolVersion,
|
|
1088
|
+
capabilities,
|
|
1089
|
+
ownerKind,
|
|
976
1090
|
// Discovery requires this proof; public health checks retain their useful 200 response.
|
|
977
1091
|
owner: tokenMatches(header2(req, "x-tokmon-token"), wsToken)
|
|
978
1092
|
});
|
|
@@ -1004,6 +1118,9 @@ async function startWebServer(opts) {
|
|
|
1004
1118
|
const state = { config: opts.config };
|
|
1005
1119
|
const tz = tzFor(state.config);
|
|
1006
1120
|
const version = appVersion();
|
|
1121
|
+
const protocolVersion = opts.protocolVersion ?? TOKMON_PROTOCOL_VERSION;
|
|
1122
|
+
const capabilities = opts.capabilities ?? TOKMON_CAPABILITIES;
|
|
1123
|
+
const ownerKind = opts.ownerKind ?? "cli";
|
|
1007
1124
|
const summaryIntervalMs = summaryIntervalFor(state.config);
|
|
1008
1125
|
const billingIntervalMs = billingIntervalFor(state.config);
|
|
1009
1126
|
const wsToken = opts.wsToken ?? randomBytes(32).toString("base64url");
|
|
@@ -1020,7 +1137,17 @@ async function startWebServer(opts) {
|
|
|
1020
1137
|
const webRoot = vite ? null : findWebRoot();
|
|
1021
1138
|
if (!vite && !webRoot) log(" \u26A0 no dashboard available \u2014 see the page for build/dev instructions");
|
|
1022
1139
|
engine = createDataEngine({ version, config: state.config, tz, summaryIntervalMs, billingIntervalMs, resolved });
|
|
1023
|
-
server.addListener("request", createRouter(
|
|
1140
|
+
server.addListener("request", createRouter(
|
|
1141
|
+
engine,
|
|
1142
|
+
state,
|
|
1143
|
+
vite,
|
|
1144
|
+
webRoot,
|
|
1145
|
+
wsToken,
|
|
1146
|
+
version,
|
|
1147
|
+
protocolVersion,
|
|
1148
|
+
capabilities,
|
|
1149
|
+
ownerKind
|
|
1150
|
+
));
|
|
1024
1151
|
closeWsRpc = await mountWsRpc(server, { engine, state });
|
|
1025
1152
|
const bindHost = state.config.allowNetworkAccess ? NETWORK_HOST : LOOPBACK_HOST;
|
|
1026
1153
|
const port = await listenWithFallback(server, opts.port ?? DEFAULT_PORT, bindHost);
|
|
@@ -1116,5 +1243,6 @@ function listenWithFallback(server, startPort, host) {
|
|
|
1116
1243
|
}
|
|
1117
1244
|
|
|
1118
1245
|
export {
|
|
1246
|
+
appVersion,
|
|
1119
1247
|
startWebServer
|
|
1120
1248
|
};
|
|
@@ -23,7 +23,7 @@ function isLoopbackUrl(value) {
|
|
|
23
23
|
}
|
|
24
24
|
function validLock(value) {
|
|
25
25
|
const lock = value;
|
|
26
|
-
return !!lock && typeof lock.pid === "number" && Number.isInteger(lock.pid) && lock.pid > 0 && typeof lock.port === "number" && Number.isInteger(lock.port) && lock.port >= 0 && lock.port <= 65535 && typeof lock.url === "string" && (lock.state === "starting" || isLoopbackUrl(lock.url)) && typeof lock.wsToken === "string" && lock.wsToken.length >= 32 && typeof lock.version === "string" && typeof lock.startedAt === "number" && typeof lock.ownerId === "string" && lock.ownerId.length >= 32 && (lock.state === "starting" || lock.state === "ready");
|
|
26
|
+
return !!lock && typeof lock.pid === "number" && Number.isInteger(lock.pid) && lock.pid > 0 && typeof lock.port === "number" && Number.isInteger(lock.port) && lock.port >= 0 && lock.port <= 65535 && typeof lock.url === "string" && (lock.state === "starting" || isLoopbackUrl(lock.url)) && typeof lock.wsToken === "string" && lock.wsToken.length >= 32 && typeof lock.version === "string" && typeof lock.protocolVersion === "number" && Number.isSafeInteger(lock.protocolVersion) && lock.protocolVersion >= 1 && Array.isArray(lock.capabilities) && lock.capabilities.every((capability) => typeof capability === "string") && (lock.ownerKind === "cli" || lock.ownerKind === "desktop") && typeof lock.startedAt === "number" && typeof lock.ownerId === "string" && lock.ownerId.length >= 32 && (lock.state === "starting" || lock.state === "ready");
|
|
27
27
|
}
|
|
28
28
|
function readLock(opts = {}) {
|
|
29
29
|
try {
|
|
@@ -161,7 +161,10 @@ function isAlive(pid) {
|
|
|
161
161
|
return err.code === "EPERM";
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
|
-
|
|
164
|
+
function sameCapabilities(actual, expected) {
|
|
165
|
+
return Array.isArray(actual) && actual.length === expected.length && actual.every((capability, index) => capability === expected[index]);
|
|
166
|
+
}
|
|
167
|
+
async function probeHealth(url, token, expected = {}, timeoutMs = 500) {
|
|
165
168
|
if (!isLoopbackUrl(url) || !token) return false;
|
|
166
169
|
try {
|
|
167
170
|
const res = await fetch(`${url.replace(/\/+$/, "")}/healthz`, {
|
|
@@ -170,14 +173,14 @@ async function probeHealth(url, token, version, timeoutMs = 500) {
|
|
|
170
173
|
});
|
|
171
174
|
if (!res.ok) return false;
|
|
172
175
|
const body = await res.json();
|
|
173
|
-
return body.ok === true && body.owner === true && (version === void 0 || body.version === version);
|
|
176
|
+
return body.ok === true && body.owner === true && (expected.version === void 0 || body.version === expected.version) && (expected.protocolVersion === void 0 || body.protocolVersion === expected.protocolVersion) && (expected.capabilities === void 0 || sameCapabilities(body.capabilities, expected.capabilities)) && (expected.ownerKind === void 0 || body.ownerKind === expected.ownerKind);
|
|
174
177
|
} catch {
|
|
175
178
|
return false;
|
|
176
179
|
}
|
|
177
180
|
}
|
|
178
|
-
async function verifyLock(lock,
|
|
179
|
-
if (!lock || lock.state !== "ready" || lock.
|
|
180
|
-
return await probeHealth(lock.url, lock.wsToken,
|
|
181
|
+
async function verifyLock(lock, protocolVersion, timeoutMs) {
|
|
182
|
+
if (!lock || lock.state !== "ready" || lock.protocolVersion !== protocolVersion || !isAlive(lock.pid)) return null;
|
|
183
|
+
return await probeHealth(lock.url, lock.wsToken, lock, timeoutMs) ? lock : null;
|
|
181
184
|
}
|
|
182
185
|
|
|
183
186
|
export {
|