livedesk 0.1.257 → 0.1.259
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/bin/livedesk.js
CHANGED
|
@@ -220,28 +220,45 @@ function waitMilliseconds(milliseconds) {
|
|
|
220
220
|
return new Promise(resolve => setTimeout(resolve, milliseconds));
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
-
function probePortBind(port, host = '0.0.0.0') {
|
|
224
|
-
return new Promise(resolve => {
|
|
225
|
-
const server = net.createServer();
|
|
226
|
-
let settled = false;
|
|
227
|
-
const finish = value => {
|
|
228
|
-
if (settled) return;
|
|
223
|
+
function probePortBind(port, host = '0.0.0.0') {
|
|
224
|
+
return new Promise(resolve => {
|
|
225
|
+
const server = net.createServer();
|
|
226
|
+
let settled = false;
|
|
227
|
+
const finish = value => {
|
|
228
|
+
if (settled) return;
|
|
229
229
|
settled = true;
|
|
230
230
|
resolve(value);
|
|
231
231
|
};
|
|
232
|
-
server.once('error', error => finish({
|
|
233
|
-
ok: false,
|
|
234
|
-
error: error?.code || error?.message || 'bind-failed'
|
|
235
|
-
}));
|
|
236
|
-
server.listen(port, host, () => {
|
|
237
|
-
server.close(() => finish({ ok: true, error: '' }));
|
|
238
|
-
});
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
async function canBindPort(port, host = '0.0.0.0') {
|
|
243
|
-
return (await probePortBind(port, host)).ok;
|
|
244
|
-
}
|
|
232
|
+
server.once('error', error => finish({
|
|
233
|
+
ok: false,
|
|
234
|
+
error: error?.code || error?.message || 'bind-failed'
|
|
235
|
+
}));
|
|
236
|
+
server.listen(port, host, () => {
|
|
237
|
+
server.close(() => finish({ ok: true, error: '' }));
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
async function canBindPort(port, host = '0.0.0.0') {
|
|
243
|
+
return (await probePortBind(port, host)).ok;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
async function waitForPortBindable(port, host = '0.0.0.0', timeoutMs = PORT_CLEANUP_TIMEOUT_MS) {
|
|
247
|
+
const deadline = Date.now() + timeoutMs;
|
|
248
|
+
let lastProbe = { ok: false, error: 'bind-not-tested' };
|
|
249
|
+
do {
|
|
250
|
+
lastProbe = await probePortBind(port, host);
|
|
251
|
+
if (lastProbe.ok) {
|
|
252
|
+
return lastProbe;
|
|
253
|
+
}
|
|
254
|
+
const remainingMs = deadline - Date.now();
|
|
255
|
+
if (remainingMs <= 0) {
|
|
256
|
+
break;
|
|
257
|
+
}
|
|
258
|
+
await waitMilliseconds(Math.min(PORT_CLEANUP_POLL_MS, remainingMs));
|
|
259
|
+
} while (true);
|
|
260
|
+
return lastProbe;
|
|
261
|
+
}
|
|
245
262
|
|
|
246
263
|
function isKnownLiveDeskProcess(processName, commandLine) {
|
|
247
264
|
const normalizedName = String(processName || '').trim();
|
|
@@ -270,7 +287,7 @@ function assertPortCleanupReady(finalRecords, portStates) {
|
|
|
270
287
|
const owners = finalRecords
|
|
271
288
|
.filter(record => Number(record?.Port) === Number(port?.Port))
|
|
272
289
|
.map(formatPortOwner);
|
|
273
|
-
return `TCP ${port.Port}[available=${port.PortAvailable === true},bindable=${port.PortBindable === true},bind-error=${port.BindError || 'none'},owners=${owners.length ? owners.join('; ') : 'owner not visible'}`;
|
|
290
|
+
return `TCP ${port.Port}[available=${port.PortAvailable === true},bindable=${port.PortBindable === true},bind-error=${port.BindError || 'none'},owners=${owners.length ? owners.join('; ') : 'owner not visible'}`;
|
|
274
291
|
}).join('], ');
|
|
275
292
|
throw new Error(`LiveDesk Hub startup cleanup could not release the configured port(s): ${summary}]. Unrelated processes are preserved; stop the owning process manually or choose an explicit --port/--remote-port value.`);
|
|
276
293
|
}
|
|
@@ -388,7 +405,7 @@ async function stopProcessesOnPorts(ports) {
|
|
|
388
405
|
' [pscustomobject]@{ Port = [int]$port; Pid = $owner; ProcessName = $processName; CommandLine = $commandLine; KnownLiveDesk = $knownLiveDesk; Action = "preserved"; KillAttempted = $false }',
|
|
389
406
|
' }',
|
|
390
407
|
'}',
|
|
391
|
-
'$records = @($ports | ForEach-Object { Get-PortRecords $_ } | Sort-Object Port,Pid -Unique);',
|
|
408
|
+
'$records = @($ports | ForEach-Object { Get-PortRecords $_ } | Sort-Object Port,Pid -Unique);',
|
|
392
409
|
'$killableOwners = @($records | Where-Object { $_.KnownLiveDesk } | Group-Object Pid | ForEach-Object { @($_.Group)[0] });',
|
|
393
410
|
'foreach ($owner in $killableOwners) {',
|
|
394
411
|
' Stop-Process -Id $owner.Pid -Force -ErrorAction SilentlyContinue;',
|
|
@@ -406,8 +423,8 @@ async function stopProcessesOnPorts(ports) {
|
|
|
406
423
|
' $portStates = @($ports | ForEach-Object {',
|
|
407
424
|
' $port = [int]$_;',
|
|
408
425
|
' $busy = $busyPorts -contains $port;',
|
|
409
|
-
' $bindable = [bool](-not $busy);',
|
|
410
|
-
' [pscustomobject]@{ Port = $port; PortAvailable = [bool](-not $busy); PortBindable = $bindable; Ready = [bool](-not $busy) }',
|
|
426
|
+
' $bindable = [bool](-not $busy);',
|
|
427
|
+
' [pscustomobject]@{ Port = $port; PortAvailable = [bool](-not $busy); PortBindable = $bindable; Ready = [bool](-not $busy) }',
|
|
411
428
|
' });',
|
|
412
429
|
' if ((@($portStates | Where-Object { -not $_.Ready }).Count -eq 0) -or (Get-Date).ToUniversalTime() -ge $deadline) { break }',
|
|
413
430
|
` Start-Sleep -Milliseconds ${PORT_CLEANUP_POLL_MS};`,
|
|
@@ -431,22 +448,22 @@ async function stopProcessesOnPorts(ports) {
|
|
|
431
448
|
}
|
|
432
449
|
const records = Array.isArray(payload?.Records) ? payload.Records : [];
|
|
433
450
|
const finalRecords = Array.isArray(payload?.FinalRecords) ? payload.FinalRecords : [];
|
|
434
|
-
const rawPortStates = Array.isArray(payload?.Ports) ? payload.Ports : [];
|
|
435
|
-
const rawStatesByPort = new Map(rawPortStates.map(state => [Number(state?.Port), state]));
|
|
436
|
-
const portStates = [];
|
|
437
|
-
for (const port of uniquePorts) {
|
|
438
|
-
const rawState = rawStatesByPort.get(Number(port)) || {};
|
|
439
|
-
const probe = rawState.PortAvailable === true
|
|
440
|
-
? await
|
|
441
|
-
: { ok: false, error: 'port-in-use' };
|
|
442
|
-
portStates.push({
|
|
443
|
-
...rawState,
|
|
444
|
-
Port: Number(port),
|
|
445
|
-
PortBindable: probe.ok,
|
|
446
|
-
BindError: probe.error || '',
|
|
447
|
-
Ready: rawState.PortAvailable === true && probe.ok
|
|
448
|
-
});
|
|
449
|
-
}
|
|
451
|
+
const rawPortStates = Array.isArray(payload?.Ports) ? payload.Ports : [];
|
|
452
|
+
const rawStatesByPort = new Map(rawPortStates.map(state => [Number(state?.Port), state]));
|
|
453
|
+
const portStates = [];
|
|
454
|
+
for (const port of uniquePorts) {
|
|
455
|
+
const rawState = rawStatesByPort.get(Number(port)) || {};
|
|
456
|
+
const probe = rawState.PortAvailable === true
|
|
457
|
+
? await waitForPortBindable(port)
|
|
458
|
+
: { ok: false, error: 'port-in-use' };
|
|
459
|
+
portStates.push({
|
|
460
|
+
...rawState,
|
|
461
|
+
Port: Number(port),
|
|
462
|
+
PortBindable: probe.ok,
|
|
463
|
+
BindError: probe.error || '',
|
|
464
|
+
Ready: rawState.PortAvailable === true && probe.ok
|
|
465
|
+
});
|
|
466
|
+
}
|
|
450
467
|
const stopped = records.filter(record => record?.Action === 'stopped');
|
|
451
468
|
if (stopped.length > 0) {
|
|
452
469
|
const stoppedOwners = new Map();
|