@livedesk/client 0.1.248 → 0.1.250
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-client.js
CHANGED
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
} from '../src/runtime/agent-process-lifecycle.js';
|
|
21
21
|
import { writeWindowsOwnedProcessManifest } from '../src/runtime/windows-owned-process-manifest.js';
|
|
22
22
|
import { createHubWakeListener } from '../src/runtime/hub-wake-listener.js';
|
|
23
|
+
import { resolveSpawnablePackagedPath } from '../src/runtime/packaged-executable-path.js';
|
|
23
24
|
import {
|
|
24
25
|
inspectLinuxVideoAcceleration,
|
|
25
26
|
installLinuxVideoAcceleration
|
|
@@ -620,13 +621,41 @@ export function preflightHubClientPort(port = resolveHubClientPort()) {
|
|
|
620
621
|
});
|
|
621
622
|
}
|
|
622
623
|
|
|
624
|
+
export async function recoverHubClientPortConflict(preflight, recoverPortOwner) {
|
|
625
|
+
if (preflight?.ok
|
|
626
|
+
|| preflight?.code !== 'hub-client-port-in-use'
|
|
627
|
+
|| typeof recoverPortOwner !== 'function') {
|
|
628
|
+
return preflight;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
try {
|
|
632
|
+
await recoverPortOwner(Number(preflight.port || resolveHubClientPort()));
|
|
633
|
+
} catch (error) {
|
|
634
|
+
return {
|
|
635
|
+
...preflight,
|
|
636
|
+
recoveryAttempted: true,
|
|
637
|
+
recoveryError: error instanceof Error ? error.message : String(error)
|
|
638
|
+
};
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
const verified = await preflightHubClientPort(preflight.port);
|
|
642
|
+
return {
|
|
643
|
+
...verified,
|
|
644
|
+
recoveryAttempted: true,
|
|
645
|
+
recovered: verified.ok === true
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
|
|
623
649
|
function hubClientPortPreflightError(preflight) {
|
|
624
650
|
const port = Number(preflight?.port || resolveHubClientPort());
|
|
651
|
+
const recoveryError = String(preflight?.recoveryError || '').trim();
|
|
625
652
|
return {
|
|
626
653
|
ok: false,
|
|
627
654
|
code: String(preflight?.code || 'hub-client-port-unavailable'),
|
|
628
655
|
port,
|
|
629
|
-
error:
|
|
656
|
+
error: recoveryError
|
|
657
|
+
? `${recoveryError} The current Hub was not changed.`
|
|
658
|
+
: preflight?.code === 'hub-client-port-in-use'
|
|
630
659
|
? `LiveDesk cannot switch this computer to Hub because TCP ${port} is already in use. Change or stop the owning service, then try Switch to Hub again. The current Hub was not changed.`
|
|
631
660
|
: `LiveDesk cannot switch this computer to Hub because TCP ${port} is unavailable. Check the local port configuration, then try again. The current Hub was not changed.`
|
|
632
661
|
};
|
|
@@ -3082,9 +3111,13 @@ async function startConnectionChoiceServer(supabase, options = {}) {
|
|
|
3082
3111
|
return;
|
|
3083
3112
|
}
|
|
3084
3113
|
const portPreflight = await preflightHubClientPort();
|
|
3085
|
-
|
|
3114
|
+
const readyPortPreflight = await recoverHubClientPortConflict(
|
|
3115
|
+
portPreflight,
|
|
3116
|
+
options.recoverHubClientPort
|
|
3117
|
+
);
|
|
3118
|
+
if (!readyPortPreflight.ok) {
|
|
3086
3119
|
res.writeHead(409, { 'Content-Type': 'application/json; charset=utf-8', 'Access-Control-Allow-Origin': '*' });
|
|
3087
|
-
res.end(JSON.stringify(hubClientPortPreflightError(
|
|
3120
|
+
res.end(JSON.stringify(hubClientPortPreflightError(readyPortPreflight)));
|
|
3088
3121
|
return;
|
|
3089
3122
|
}
|
|
3090
3123
|
const session = await refreshSessionIfNeeded(supabase);
|
|
@@ -3403,8 +3436,12 @@ async function chooseClientConnection(supabase, options = {}) {
|
|
|
3403
3436
|
return { ok: false, error: 'supabase-session-required' };
|
|
3404
3437
|
}
|
|
3405
3438
|
const portPreflight = await preflightHubClientPort();
|
|
3406
|
-
|
|
3407
|
-
|
|
3439
|
+
const readyPortPreflight = await recoverHubClientPortConflict(
|
|
3440
|
+
portPreflight,
|
|
3441
|
+
options.recoverHubClientPort
|
|
3442
|
+
);
|
|
3443
|
+
if (!readyPortPreflight.ok) {
|
|
3444
|
+
return hubClientPortPreflightError(readyPortPreflight);
|
|
3408
3445
|
}
|
|
3409
3446
|
const session = await refreshSessionIfNeeded(activeSupabase);
|
|
3410
3447
|
if (!session?.access_token) {
|
|
@@ -4433,8 +4470,8 @@ function getFastRuntime() {
|
|
|
4433
4470
|
return {
|
|
4434
4471
|
rid,
|
|
4435
4472
|
packageName,
|
|
4436
|
-
executable: join(fastRoot, executableName),
|
|
4437
|
-
dll: join(fastRoot, 'livedesk-client-fast.dll')
|
|
4473
|
+
executable: resolveSpawnablePackagedPath(join(fastRoot, executableName)),
|
|
4474
|
+
dll: resolveSpawnablePackagedPath(join(fastRoot, 'livedesk-client-fast.dll'))
|
|
4438
4475
|
};
|
|
4439
4476
|
} catch {
|
|
4440
4477
|
return {
|
|
@@ -4573,7 +4610,9 @@ function clearFastPreflightCache() {
|
|
|
4573
4610
|
function resolveBundledFfmpegPaths() {
|
|
4574
4611
|
const paths = [];
|
|
4575
4612
|
const addPath = (candidate) => {
|
|
4576
|
-
|
|
4613
|
+
// Electron can resolve ffmpeg-static through app.asar, but RemoteFast
|
|
4614
|
+
// is a native process and must receive the physical unpacked path.
|
|
4615
|
+
const ffmpegPath = resolveSpawnablePackagedPath(String(candidate || '').trim());
|
|
4577
4616
|
if (ffmpegPath && existsSync(ffmpegPath) && !paths.includes(ffmpegPath)) {
|
|
4578
4617
|
paths.push(ffmpegPath);
|
|
4579
4618
|
}
|
|
@@ -5084,6 +5123,7 @@ export async function runClientRuntime(argv = process.argv.slice(2), runtimeOpti
|
|
|
5084
5123
|
savedPin: null,
|
|
5085
5124
|
allowRelayFallback: transportAllowsRelay(parsed.transport),
|
|
5086
5125
|
relayEndpoint: parsed.relay,
|
|
5126
|
+
recoverHubClientPort: runtimeOptions.recoverHubClientPort,
|
|
5087
5127
|
openBrowser: parsed.openBrowserOnStart,
|
|
5088
5128
|
onStarted: page => {
|
|
5089
5129
|
connectionPage = page;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@livedesk/client",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.250",
|
|
4
4
|
"description": "LiveDesk local remote client",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -42,10 +42,10 @@
|
|
|
42
42
|
"ws": "^8.18.3"
|
|
43
43
|
},
|
|
44
44
|
"optionalDependencies": {
|
|
45
|
-
"@livedesk/fast-linux-x64": "0.1.
|
|
46
|
-
"@livedesk/fast-osx-arm64": "0.1.
|
|
47
|
-
"@livedesk/fast-osx-x64": "0.1.
|
|
48
|
-
"@livedesk/fast-win-x64": "0.1.
|
|
45
|
+
"@livedesk/fast-linux-x64": "0.1.446",
|
|
46
|
+
"@livedesk/fast-osx-arm64": "0.1.446",
|
|
47
|
+
"@livedesk/fast-osx-x64": "0.1.446",
|
|
48
|
+
"@livedesk/fast-win-x64": "0.1.446"
|
|
49
49
|
},
|
|
50
50
|
"publishConfig": {
|
|
51
51
|
"access": "public"
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
|
|
3
|
+
const ASAR_PATH_SEGMENT = /([\\/])app\.asar([\\/])/i;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Electron's Node loader can read JavaScript through the virtual app.asar
|
|
7
|
+
* path, but the operating system cannot spawn an executable from that virtual
|
|
8
|
+
* archive. electron-builder places executable payloads in the matching
|
|
9
|
+
* app.asar.unpacked tree, so only spawn targets cross that boundary.
|
|
10
|
+
*/
|
|
11
|
+
export function resolveSpawnablePackagedPath(value, pathExists = existsSync) {
|
|
12
|
+
const candidate = String(value || '');
|
|
13
|
+
if (!candidate || !ASAR_PATH_SEGMENT.test(candidate)) {
|
|
14
|
+
return candidate;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const unpacked = candidate.replace(ASAR_PATH_SEGMENT, '$1app.asar.unpacked$2');
|
|
18
|
+
try {
|
|
19
|
+
return pathExists(unpacked) ? unpacked : candidate;
|
|
20
|
+
} catch {
|
|
21
|
+
return candidate;
|
|
22
|
+
}
|
|
23
|
+
}
|