@livedesk/client 0.1.247 → 0.1.249
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
|
@@ -19,7 +19,8 @@ import {
|
|
|
19
19
|
signalAgentTree
|
|
20
20
|
} from '../src/runtime/agent-process-lifecycle.js';
|
|
21
21
|
import { writeWindowsOwnedProcessManifest } from '../src/runtime/windows-owned-process-manifest.js';
|
|
22
|
-
import { createHubWakeListener } from '../src/runtime/hub-wake-listener.js';
|
|
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
|
|
@@ -587,7 +588,7 @@ export function resolveHubClientPort(env = process.env) {
|
|
|
587
588
|
return normalizePort(env.REMOTE_HUB_PORT || env.LIVEDESK_HUB_REMOTE_PORT) || DEFAULT_HUB_CLIENT_PORT;
|
|
588
589
|
}
|
|
589
590
|
|
|
590
|
-
export function preflightHubClientPort(port = resolveHubClientPort()) {
|
|
591
|
+
export function preflightHubClientPort(port = resolveHubClientPort()) {
|
|
591
592
|
const normalizedPort = normalizePort(port);
|
|
592
593
|
if (!normalizedPort) {
|
|
593
594
|
return Promise.resolve({ ok: false, port: Number(port) || 0, code: 'invalid-hub-client-port' });
|
|
@@ -617,18 +618,46 @@ export function preflightHubClientPort(port = resolveHubClientPort()) {
|
|
|
617
618
|
finish({ ok: true, code: 'ok' });
|
|
618
619
|
});
|
|
619
620
|
});
|
|
620
|
-
});
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
function
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
621
|
+
});
|
|
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
|
+
|
|
649
|
+
function hubClientPortPreflightError(preflight) {
|
|
650
|
+
const port = Number(preflight?.port || resolveHubClientPort());
|
|
651
|
+
const recoveryError = String(preflight?.recoveryError || '').trim();
|
|
652
|
+
return {
|
|
653
|
+
ok: false,
|
|
654
|
+
code: String(preflight?.code || 'hub-client-port-unavailable'),
|
|
655
|
+
port,
|
|
656
|
+
error: recoveryError
|
|
657
|
+
? `${recoveryError} The current Hub was not changed.`
|
|
658
|
+
: preflight?.code === 'hub-client-port-in-use'
|
|
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.`
|
|
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
|
};
|
|
633
662
|
}
|
|
634
663
|
|
|
@@ -3081,12 +3110,16 @@ async function startConnectionChoiceServer(supabase, options = {}) {
|
|
|
3081
3110
|
res.end(JSON.stringify({ ok: false, error: 'client-can-only-transition-to-hub' }));
|
|
3082
3111
|
return;
|
|
3083
3112
|
}
|
|
3084
|
-
const portPreflight = await preflightHubClientPort();
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3113
|
+
const portPreflight = await preflightHubClientPort();
|
|
3114
|
+
const readyPortPreflight = await recoverHubClientPortConflict(
|
|
3115
|
+
portPreflight,
|
|
3116
|
+
options.recoverHubClientPort
|
|
3117
|
+
);
|
|
3118
|
+
if (!readyPortPreflight.ok) {
|
|
3119
|
+
res.writeHead(409, { 'Content-Type': 'application/json; charset=utf-8', 'Access-Control-Allow-Origin': '*' });
|
|
3120
|
+
res.end(JSON.stringify(hubClientPortPreflightError(readyPortPreflight)));
|
|
3121
|
+
return;
|
|
3122
|
+
}
|
|
3090
3123
|
const session = await refreshSessionIfNeeded(supabase);
|
|
3091
3124
|
const expectedRoleVersion = Number(dashboardState.roleVersion || 0);
|
|
3092
3125
|
const { data, error } = await supabase.rpc('set_livedesk_device_role', {
|
|
@@ -3402,10 +3435,14 @@ async function chooseClientConnection(supabase, options = {}) {
|
|
|
3402
3435
|
if (!activeSupabase) {
|
|
3403
3436
|
return { ok: false, error: 'supabase-session-required' };
|
|
3404
3437
|
}
|
|
3405
|
-
const portPreflight = await preflightHubClientPort();
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3438
|
+
const portPreflight = await preflightHubClientPort();
|
|
3439
|
+
const readyPortPreflight = await recoverHubClientPortConflict(
|
|
3440
|
+
portPreflight,
|
|
3441
|
+
options.recoverHubClientPort
|
|
3442
|
+
);
|
|
3443
|
+
if (!readyPortPreflight.ok) {
|
|
3444
|
+
return hubClientPortPreflightError(readyPortPreflight);
|
|
3445
|
+
}
|
|
3409
3446
|
const session = await refreshSessionIfNeeded(activeSupabase);
|
|
3410
3447
|
if (!session?.access_token) {
|
|
3411
3448
|
return { ok: false, error: 'supabase-session-required' };
|
|
@@ -4428,14 +4465,14 @@ function getFastRuntime() {
|
|
|
4428
4465
|
const arch = os.arch();
|
|
4429
4466
|
const resolvePackagedRuntime = (packageName, rid, executableName) => {
|
|
4430
4467
|
try {
|
|
4431
|
-
const packagePath = require.resolve(`${packageName}/package.json`);
|
|
4432
|
-
const fastRoot = join(dirname(packagePath), 'fast');
|
|
4433
|
-
return {
|
|
4434
|
-
rid,
|
|
4435
|
-
packageName,
|
|
4436
|
-
executable: join(fastRoot, executableName),
|
|
4437
|
-
dll: join(fastRoot, 'livedesk-client-fast.dll')
|
|
4438
|
-
};
|
|
4468
|
+
const packagePath = require.resolve(`${packageName}/package.json`);
|
|
4469
|
+
const fastRoot = join(dirname(packagePath), 'fast');
|
|
4470
|
+
return {
|
|
4471
|
+
rid,
|
|
4472
|
+
packageName,
|
|
4473
|
+
executable: resolveSpawnablePackagedPath(join(fastRoot, executableName)),
|
|
4474
|
+
dll: resolveSpawnablePackagedPath(join(fastRoot, 'livedesk-client-fast.dll'))
|
|
4475
|
+
};
|
|
4439
4476
|
} catch {
|
|
4440
4477
|
return {
|
|
4441
4478
|
rid,
|
|
@@ -4570,13 +4607,15 @@ function clearFastPreflightCache() {
|
|
|
4570
4607
|
}
|
|
4571
4608
|
}
|
|
4572
4609
|
|
|
4573
|
-
function resolveBundledFfmpegPaths() {
|
|
4574
|
-
const paths = [];
|
|
4575
|
-
const addPath = (candidate) => {
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4610
|
+
function resolveBundledFfmpegPaths() {
|
|
4611
|
+
const paths = [];
|
|
4612
|
+
const addPath = (candidate) => {
|
|
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());
|
|
4616
|
+
if (ffmpegPath && existsSync(ffmpegPath) && !paths.includes(ffmpegPath)) {
|
|
4617
|
+
paths.push(ffmpegPath);
|
|
4618
|
+
}
|
|
4580
4619
|
};
|
|
4581
4620
|
|
|
4582
4621
|
const addFfmpegInstaller = () => {
|
|
@@ -5082,9 +5121,10 @@ export async function runClientRuntime(argv = process.argv.slice(2), runtimeOpti
|
|
|
5082
5121
|
savedSession: null,
|
|
5083
5122
|
loadSavedSession: false,
|
|
5084
5123
|
savedPin: null,
|
|
5085
|
-
allowRelayFallback: transportAllowsRelay(parsed.transport),
|
|
5086
|
-
relayEndpoint: parsed.relay,
|
|
5087
|
-
|
|
5124
|
+
allowRelayFallback: transportAllowsRelay(parsed.transport),
|
|
5125
|
+
relayEndpoint: parsed.relay,
|
|
5126
|
+
recoverHubClientPort: runtimeOptions.recoverHubClientPort,
|
|
5127
|
+
openBrowser: parsed.openBrowserOnStart,
|
|
5088
5128
|
onStarted: page => {
|
|
5089
5129
|
connectionPage = page;
|
|
5090
5130
|
resolveStarted(page);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@livedesk/client",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.249",
|
|
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.445",
|
|
46
|
+
"@livedesk/fast-osx-arm64": "0.1.445",
|
|
47
|
+
"@livedesk/fast-osx-x64": "0.1.445",
|
|
48
|
+
"@livedesk/fast-win-x64": "0.1.445"
|
|
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
|
+
}
|