@livedesk/client 0.1.172 → 0.1.174
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 +180 -58
- package/package.json +5 -5
- package/src/runtime/client-runtime-server.js +30 -16
package/bin/livedesk-client.js
CHANGED
|
@@ -14,6 +14,7 @@ import { createClientRuntimeServer } from '../src/runtime/client-runtime-server.
|
|
|
14
14
|
import { installAgentTerminationHandlers } from '../src/runtime/agent-process-lifecycle.js';
|
|
15
15
|
import { createHubWakeListener } from '../src/runtime/hub-wake-listener.js';
|
|
16
16
|
import { normalizeRuntimeAuthSession } from '../../runtime-core/src/auth-session.js';
|
|
17
|
+
import { startRoleTransitionSupervisor } from '../../runtime-core/src/role-transition-supervisor.js';
|
|
17
18
|
|
|
18
19
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
19
20
|
const require = createRequire(import.meta.url);
|
|
@@ -21,6 +22,7 @@ const packageRoot = resolve(__dirname, '..');
|
|
|
21
22
|
const nodeAgentPath = join(__dirname, 'livedesk-client-node.js');
|
|
22
23
|
const FAST_PREFLIGHT_TIMEOUT_MS = 5000;
|
|
23
24
|
const DEFAULT_MANAGER = '127.0.0.1:5197';
|
|
25
|
+
const DEFAULT_HUB_CLIENT_PORT = 5197;
|
|
24
26
|
const DEFAULT_AUTH_CALLBACK_HOST = '127.0.0.1';
|
|
25
27
|
const DEFAULT_AUTH_CALLBACK_PORT = 5179;
|
|
26
28
|
const ENDPOINT_PROBE_TIMEOUT_MS = 900;
|
|
@@ -112,30 +114,53 @@ function writeLocalRoleCache(role, deviceId, roleVersion = 0, assignedHubId = ''
|
|
|
112
114
|
return true;
|
|
113
115
|
}
|
|
114
116
|
|
|
115
|
-
function
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
117
|
+
export function buildUnifiedRoleRestartEnvironment(role, baseEnv = process.env, runtimePid = process.pid) {
|
|
118
|
+
const normalizedRole = String(role || '').trim().toLowerCase();
|
|
119
|
+
const waitPid = Number(runtimePid);
|
|
120
|
+
if (normalizedRole !== 'hub' && normalizedRole !== 'client') {
|
|
121
|
+
throw new Error(`Unsupported LiveDesk role restart: ${role}`);
|
|
122
|
+
}
|
|
123
|
+
if (!Number.isInteger(waitPid) || waitPid <= 1) {
|
|
124
|
+
throw new Error(`Invalid LiveDesk runtime PID for role restart: ${runtimePid}`);
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
...baseEnv,
|
|
128
|
+
LIVEDESK_ROLE_TRANSITION: '1',
|
|
129
|
+
// The replacement must wait only for this Client runtime. Waiting for
|
|
130
|
+
// npm, npx, PowerShell, or another terminal parent can deadlock the
|
|
131
|
+
// takeover even after Supabase has selected this device as Hub.
|
|
132
|
+
LIVEDESK_RESTART_WAIT_PID: String(waitPid),
|
|
133
|
+
LIVEDESK_ROLE_TAKEOVER: normalizedRole === 'hub' ? '1' : '',
|
|
134
|
+
LIVEDESK_SKIP_BROWSER_OPEN: '1'
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async function spawnUnifiedRoleRestart(role) {
|
|
139
|
+
if (isTruthy(process.env.LIVEDESK_DESKTOP_HOST)) {
|
|
140
|
+
console.log(`[LiveDesk] Desktop supervisor will restart the runtime as ${role}.`);
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
const unifiedEntry = String(process.env.LIVEDESK_UNIFIED_LAUNCHER_ENTRY || '').trim();
|
|
144
|
+
const restartEnvironment = buildUnifiedRoleRestartEnvironment(role);
|
|
145
|
+
if (!unifiedEntry || !existsSync(unifiedEntry)) {
|
|
146
|
+
throw new Error(`LiveDesk unified role launcher is unavailable: ${unifiedEntry || 'missing path'}`);
|
|
147
|
+
}
|
|
148
|
+
const handoff = await startRoleTransitionSupervisor({
|
|
149
|
+
role,
|
|
150
|
+
previousPid: process.pid,
|
|
151
|
+
launcherEntry: unifiedEntry,
|
|
152
|
+
stateDir: UNIFIED_CLIENT_STATE_DIR,
|
|
153
|
+
runtimePort: Number(process.env.LIVEDESK_CLIENT_RUNTIME_PORT || DEFAULT_AUTH_CALLBACK_PORT),
|
|
154
|
+
remotePort: resolveHubClientPort(),
|
|
155
|
+
env: restartEnvironment,
|
|
156
|
+
cwd: process.cwd()
|
|
157
|
+
});
|
|
158
|
+
console.log(
|
|
159
|
+
`[LiveDesk] Role transition supervisor claimed target=${role} `
|
|
160
|
+
+ `pid=${handoff.supervisorPid}. Diagnostics: ${handoff.logPath}`
|
|
161
|
+
);
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
139
164
|
|
|
140
165
|
function printHelp() {
|
|
141
166
|
process.stdout.write(`
|
|
@@ -349,15 +374,64 @@ function parseLauncherArgs(argv) {
|
|
|
349
374
|
};
|
|
350
375
|
}
|
|
351
376
|
|
|
352
|
-
function normalizePort(value) {
|
|
377
|
+
function normalizePort(value) {
|
|
353
378
|
const port = Number(String(value || '').trim());
|
|
354
379
|
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
355
380
|
return 0;
|
|
356
381
|
}
|
|
357
382
|
return port;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
function
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
export function resolveHubClientPort(env = process.env) {
|
|
386
|
+
return normalizePort(env.REMOTE_HUB_PORT || env.LIVEDESK_HUB_REMOTE_PORT) || DEFAULT_HUB_CLIENT_PORT;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
export function preflightHubClientPort(port = resolveHubClientPort()) {
|
|
390
|
+
const normalizedPort = normalizePort(port);
|
|
391
|
+
if (!normalizedPort) {
|
|
392
|
+
return Promise.resolve({ ok: false, port: Number(port) || 0, code: 'invalid-hub-client-port' });
|
|
393
|
+
}
|
|
394
|
+
return new Promise(resolvePreflight => {
|
|
395
|
+
const probe = net.createServer();
|
|
396
|
+
let completed = false;
|
|
397
|
+
const finish = result => {
|
|
398
|
+
if (completed) return;
|
|
399
|
+
completed = true;
|
|
400
|
+
resolvePreflight({ port: normalizedPort, ...result });
|
|
401
|
+
};
|
|
402
|
+
probe.unref?.();
|
|
403
|
+
probe.once('error', error => {
|
|
404
|
+
finish({
|
|
405
|
+
ok: false,
|
|
406
|
+
code: error?.code === 'EADDRINUSE' ? 'hub-client-port-in-use' : 'hub-client-port-unavailable',
|
|
407
|
+
systemCode: String(error?.code || '')
|
|
408
|
+
});
|
|
409
|
+
});
|
|
410
|
+
probe.listen({ host: '0.0.0.0', port: normalizedPort, exclusive: true }, () => {
|
|
411
|
+
probe.close(error => {
|
|
412
|
+
if (error) {
|
|
413
|
+
finish({ ok: false, code: 'hub-client-port-unavailable', systemCode: String(error?.code || '') });
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
finish({ ok: true, code: 'ok' });
|
|
417
|
+
});
|
|
418
|
+
});
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
function hubClientPortPreflightError(preflight) {
|
|
423
|
+
const port = Number(preflight?.port || resolveHubClientPort());
|
|
424
|
+
return {
|
|
425
|
+
ok: false,
|
|
426
|
+
code: String(preflight?.code || 'hub-client-port-unavailable'),
|
|
427
|
+
port,
|
|
428
|
+
error: preflight?.code === 'hub-client-port-in-use'
|
|
429
|
+
? `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.`
|
|
430
|
+
: `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.`
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
function normalizeSlotNumber(value) {
|
|
361
435
|
const number = Number(String(value || '').trim());
|
|
362
436
|
if (!Number.isInteger(number) || number < 1 || number > 999) {
|
|
363
437
|
return '';
|
|
@@ -2628,12 +2702,18 @@ async function startConnectionChoiceServer(supabase, options = {}) {
|
|
|
2628
2702
|
payload = Object.fromEntries(params.entries());
|
|
2629
2703
|
}
|
|
2630
2704
|
const nextRole = String(payload.role || '').trim().toLowerCase();
|
|
2631
|
-
if (nextRole !== 'hub') {
|
|
2705
|
+
if (nextRole !== 'hub') {
|
|
2632
2706
|
res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8', 'Access-Control-Allow-Origin': '*' });
|
|
2633
2707
|
res.end(JSON.stringify({ ok: false, error: 'client-can-only-transition-to-hub' }));
|
|
2634
|
-
return;
|
|
2635
|
-
}
|
|
2636
|
-
const
|
|
2708
|
+
return;
|
|
2709
|
+
}
|
|
2710
|
+
const portPreflight = await preflightHubClientPort();
|
|
2711
|
+
if (!portPreflight.ok) {
|
|
2712
|
+
res.writeHead(409, { 'Content-Type': 'application/json; charset=utf-8', 'Access-Control-Allow-Origin': '*' });
|
|
2713
|
+
res.end(JSON.stringify(hubClientPortPreflightError(portPreflight)));
|
|
2714
|
+
return;
|
|
2715
|
+
}
|
|
2716
|
+
const session = await refreshSessionIfNeeded(supabase);
|
|
2637
2717
|
const expectedRoleVersion = Number(dashboardState.roleVersion || 0);
|
|
2638
2718
|
const { data, error } = await supabase.rpc('set_livedesk_device_role', {
|
|
2639
2719
|
p_device_id: deviceId,
|
|
@@ -2888,15 +2968,18 @@ async function startConnectionChoiceServer(supabase, options = {}) {
|
|
|
2888
2968
|
|
|
2889
2969
|
async function chooseClientConnection(supabase, options = {}) {
|
|
2890
2970
|
if (isTruthy(process.env.LIVEDESK_UNIFIED_RUNTIME)) {
|
|
2891
|
-
const connectionPage = createClientRuntimeServer({
|
|
2892
|
-
host: process.env.LIVEDESK_CLIENT_RUNTIME_HOST || '127.0.0.1',
|
|
2893
|
-
port: options.authPort || DEFAULT_AUTH_CALLBACK_PORT,
|
|
2894
|
-
webDist: process.env.LIVEDESK_WEB_DIST || '',
|
|
2971
|
+
const connectionPage = createClientRuntimeServer({
|
|
2972
|
+
host: process.env.LIVEDESK_CLIENT_RUNTIME_HOST || '127.0.0.1',
|
|
2973
|
+
port: options.authPort || DEFAULT_AUTH_CALLBACK_PORT,
|
|
2974
|
+
webDist: process.env.LIVEDESK_WEB_DIST || '',
|
|
2895
2975
|
appVersion: process.env.LIVEDESK_NPM_LAUNCHER_VERSION || readPackageVersion(),
|
|
2896
|
-
deviceId: options.deviceId,
|
|
2897
|
-
engine: options.engine,
|
|
2976
|
+
deviceId: options.deviceId,
|
|
2977
|
+
engine: options.engine,
|
|
2898
2978
|
savedSession: options.savedSession,
|
|
2979
|
+
initialChoice: options.initialChoice,
|
|
2980
|
+
initialChoiceMessage: options.initialChoiceMessage,
|
|
2899
2981
|
beginGoogleSignIn: async redirectTo => {
|
|
2982
|
+
if (!supabase?.auth) throw new Error('supabase-session-required');
|
|
2900
2983
|
const { data, error } = await supabase.auth.signInWithOAuth({
|
|
2901
2984
|
provider: 'google',
|
|
2902
2985
|
options: {
|
|
@@ -2910,15 +2993,26 @@ async function chooseClientConnection(supabase, options = {}) {
|
|
|
2910
2993
|
return { url: data.url };
|
|
2911
2994
|
},
|
|
2912
2995
|
exchangeGoogleCode: async code => {
|
|
2996
|
+
if (!supabase?.auth) throw new Error('supabase-session-required');
|
|
2913
2997
|
const { data, error } = await supabase.auth.exchangeCodeForSession(code);
|
|
2914
2998
|
if (error) throw error;
|
|
2915
2999
|
if (!data?.session) throw new Error('google-session-missing');
|
|
2916
3000
|
if (!writeSavedSessionToFile(data.session)) throw new Error('refresh-token-required');
|
|
2917
3001
|
return data.session;
|
|
2918
3002
|
},
|
|
2919
|
-
resolvePin: pin =>
|
|
2920
|
-
|
|
2921
|
-
|
|
3003
|
+
resolvePin: pin => {
|
|
3004
|
+
if (!supabase) throw new Error('supabase-session-required');
|
|
3005
|
+
return resolveManagerFromPin(supabase, pin);
|
|
3006
|
+
},
|
|
3007
|
+
changeRole: async (role, snapshot) => {
|
|
3008
|
+
if (!supabase) {
|
|
3009
|
+
return { ok: false, error: 'supabase-session-required' };
|
|
3010
|
+
}
|
|
3011
|
+
const portPreflight = await preflightHubClientPort();
|
|
3012
|
+
if (!portPreflight.ok) {
|
|
3013
|
+
return hubClientPortPreflightError(portPreflight);
|
|
3014
|
+
}
|
|
3015
|
+
const session = await refreshSessionIfNeeded(supabase);
|
|
2922
3016
|
if (!session?.access_token) {
|
|
2923
3017
|
return { ok: false, error: 'supabase-session-required' };
|
|
2924
3018
|
}
|
|
@@ -3255,7 +3349,7 @@ async function prepareLoginConnection(parsed, existingConnectionPage = null) {
|
|
|
3255
3349
|
let connectionPage = null;
|
|
3256
3350
|
let discoverySource = '';
|
|
3257
3351
|
|
|
3258
|
-
if (shouldLogin) {
|
|
3352
|
+
if (shouldLogin) {
|
|
3259
3353
|
const supabase = await createSupabaseClient();
|
|
3260
3354
|
const startupArgs = buildStartupClientArgs(parsed);
|
|
3261
3355
|
let savedSession = null;
|
|
@@ -3362,10 +3456,38 @@ async function prepareLoginConnection(parsed, existingConnectionPage = null) {
|
|
|
3362
3456
|
message: `Connected to LiveDesk Hub at ${manager}.`
|
|
3363
3457
|
});
|
|
3364
3458
|
}
|
|
3365
|
-
console.log(`Found LiveDesk Hub at ${manager}.`);
|
|
3366
|
-
}
|
|
3367
|
-
|
|
3368
|
-
|
|
3459
|
+
console.log(`Found LiveDesk Hub at ${manager}.`);
|
|
3460
|
+
}
|
|
3461
|
+
// Exact-package updates preserve the already paired Hub endpoint and pass
|
|
3462
|
+
// --no-login so the replacement cannot block on browser auth. The unified
|
|
3463
|
+
// launcher must still own its local runtime/status API; the package
|
|
3464
|
+
// supervisor uses that API to prove the new launcher and Agent are stable
|
|
3465
|
+
// before it commits the update.
|
|
3466
|
+
if (!shouldLogin
|
|
3467
|
+
&& !existingConnectionPage
|
|
3468
|
+
&& isTruthy(process.env.LIVEDESK_UNIFIED_RUNTIME)
|
|
3469
|
+
&& manager
|
|
3470
|
+
&& pair) {
|
|
3471
|
+
const preservedSession = readSavedSessionFromFile();
|
|
3472
|
+
const explicitConnection = await chooseClientConnection(null, {
|
|
3473
|
+
authPort: parsed.authPort,
|
|
3474
|
+
deviceId: parsed.deviceId,
|
|
3475
|
+
engine: parsed.engine,
|
|
3476
|
+
savedSession: preservedSession,
|
|
3477
|
+
openBrowser: false,
|
|
3478
|
+
initialChoice: {
|
|
3479
|
+
type: 'explicit',
|
|
3480
|
+
manager,
|
|
3481
|
+
pair,
|
|
3482
|
+
endpointCandidates: [manager],
|
|
3483
|
+
...(preservedSession?.access_token ? { session: preservedSession } : {})
|
|
3484
|
+
},
|
|
3485
|
+
initialChoiceMessage: `Using the existing LiveDesk Hub pairing at ${manager}.`
|
|
3486
|
+
});
|
|
3487
|
+
connectionPage = explicitConnection.connectionPage || null;
|
|
3488
|
+
}
|
|
3489
|
+
|
|
3490
|
+
const slot = normalizeSlotNumber(parsed.slot);
|
|
3369
3491
|
if (manager) {
|
|
3370
3492
|
forwarded = upsertForwardedOption(forwarded, '--manager', manager);
|
|
3371
3493
|
}
|
|
@@ -3892,12 +4014,12 @@ export async function runClientRuntime(argv = process.argv.slice(2)) {
|
|
|
3892
4014
|
while (true) {
|
|
3893
4015
|
const prepared = await prepareLoginConnection(parsed, connectionPage);
|
|
3894
4016
|
connectionPage = prepared.connectionPage || connectionPage;
|
|
3895
|
-
const roleRestartBeforeAgent = connectionPage?.getRoleRestartRequest?.() || roleRestartRequest;
|
|
3896
|
-
if (roleRestartBeforeAgent?.role) {
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
process.exit(0);
|
|
4017
|
+
const roleRestartBeforeAgent = connectionPage?.getRoleRestartRequest?.() || roleRestartRequest;
|
|
4018
|
+
if (roleRestartBeforeAgent?.role) {
|
|
4019
|
+
if (isTruthy(process.env.LIVEDESK_DESKTOP_HOST)) process.exit(43);
|
|
4020
|
+
await spawnUnifiedRoleRestart(roleRestartBeforeAgent.role);
|
|
4021
|
+
connectionPage?.close?.();
|
|
4022
|
+
process.exit(0);
|
|
3901
4023
|
}
|
|
3902
4024
|
const fastRuntime = getFastRuntime();
|
|
3903
4025
|
const useFast = shouldTryFast(prepared, fastRuntime);
|
|
@@ -3986,12 +4108,12 @@ export async function runClientRuntime(argv = process.argv.slice(2)) {
|
|
|
3986
4108
|
});
|
|
3987
4109
|
});
|
|
3988
4110
|
}
|
|
3989
|
-
const requestedRoleRestart = connectionPage?.getRoleRestartRequest?.();
|
|
3990
|
-
if (requestedRoleRestart?.role) {
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
process.exit(0);
|
|
4111
|
+
const requestedRoleRestart = connectionPage?.getRoleRestartRequest?.();
|
|
4112
|
+
if (requestedRoleRestart?.role) {
|
|
4113
|
+
if (isTruthy(process.env.LIVEDESK_DESKTOP_HOST)) process.exit(43);
|
|
4114
|
+
await spawnUnifiedRoleRestart(requestedRoleRestart.role);
|
|
4115
|
+
connectionPage?.close?.();
|
|
4116
|
+
process.exit(0);
|
|
3995
4117
|
}
|
|
3996
4118
|
if (result?.signal) {
|
|
3997
4119
|
connectionPage?.close?.();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@livedesk/client",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.174",
|
|
4
4
|
"description": "LiveDesk local remote client",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
"ws": "^8.18.3"
|
|
40
40
|
},
|
|
41
41
|
"optionalDependencies": {
|
|
42
|
-
"@livedesk/fast-linux-x64": "0.1.
|
|
43
|
-
"@livedesk/fast-osx-arm64": "0.1.
|
|
44
|
-
"@livedesk/fast-osx-x64": "0.1.
|
|
45
|
-
"@livedesk/fast-win-x64": "0.1.
|
|
42
|
+
"@livedesk/fast-linux-x64": "0.1.380",
|
|
43
|
+
"@livedesk/fast-osx-arm64": "0.1.380",
|
|
44
|
+
"@livedesk/fast-osx-x64": "0.1.380",
|
|
45
|
+
"@livedesk/fast-win-x64": "0.1.380"
|
|
46
46
|
},
|
|
47
47
|
"publishConfig": {
|
|
48
48
|
"access": "public"
|
|
@@ -514,9 +514,16 @@ function sendText(res, status, body, type = 'text/plain; charset=utf-8') {
|
|
|
514
514
|
res.end(body);
|
|
515
515
|
}
|
|
516
516
|
|
|
517
|
-
export function createClientRuntimeServer(options = {}) {
|
|
518
|
-
const host = normalizeString(options.host, 80) || DEFAULT_HOST;
|
|
517
|
+
export function createClientRuntimeServer(options = {}) {
|
|
518
|
+
const host = normalizeString(options.host, 80) || DEFAULT_HOST;
|
|
519
519
|
const port = normalizePort(options.port, DEFAULT_PORT);
|
|
520
|
+
const initialChoice = options.initialChoice && typeof options.initialChoice === 'object'
|
|
521
|
+
? options.initialChoice
|
|
522
|
+
: null;
|
|
523
|
+
const initialChoiceMessage = normalizeString(
|
|
524
|
+
options.initialChoiceMessage,
|
|
525
|
+
1000
|
|
526
|
+
) || 'Existing LiveDesk credentials accepted. Starting the Client.';
|
|
520
527
|
const trustedWebOrigins = createTrustedWebOrigins(port);
|
|
521
528
|
const webDist = resolve(String(options.webDist || process.env.LIVEDESK_WEB_DIST || '').trim() || join(process.cwd(), 'apps', 'web', 'dist'));
|
|
522
529
|
const deviceId = normalizeString(options.deviceId || process.env.LIVEDESK_DEVICE_ID, 160);
|
|
@@ -732,6 +739,7 @@ export function createClientRuntimeServer(options = {}) {
|
|
|
732
739
|
osVersion: os.release(),
|
|
733
740
|
pid: process.pid,
|
|
734
741
|
cpuUsagePercent: Math.round(cpuUsagePercent * 10) / 10,
|
|
742
|
+
cpuLogicalCores: Math.max(1, os.cpus().length),
|
|
735
743
|
memoryTotalBytes: totalMemoryBytes,
|
|
736
744
|
memoryUsedBytes: Math.max(0, totalMemoryBytes - freeMemoryBytes),
|
|
737
745
|
uptimeSeconds: Math.max(0, Math.floor(os.uptime())),
|
|
@@ -1030,23 +1038,29 @@ export function createClientRuntimeServer(options = {}) {
|
|
|
1030
1038
|
else res.end();
|
|
1031
1039
|
});
|
|
1032
1040
|
});
|
|
1033
|
-
server.once('error', rejectStart);
|
|
1034
|
-
server.listen(port, host, () => {
|
|
1035
|
-
runtime.emit('runtime.http.started', { host, port });
|
|
1036
|
-
|
|
1037
|
-
if (saved.ok) {
|
|
1041
|
+
server.once('error', rejectStart);
|
|
1042
|
+
server.listen(port, host, () => {
|
|
1043
|
+
runtime.emit('runtime.http.started', { host, port });
|
|
1044
|
+
if (initialChoice) {
|
|
1038
1045
|
setImmediate(() => {
|
|
1039
|
-
|
|
1040
|
-
if (!writeSavedSession(saved.session)) throw new Error('refresh-token-required');
|
|
1041
|
-
state.auth.persisted = true;
|
|
1042
|
-
complete({ type: 'google', session: saved.session }, 'Saved sign-in found. Finding the LiveDesk Hub.');
|
|
1043
|
-
} catch (error) {
|
|
1044
|
-
recordAuthAttempt('rejected', `session-persistence-failed:${normalizeString(error?.message || error, 160)}`);
|
|
1045
|
-
}
|
|
1046
|
+
complete(initialChoice, initialChoiceMessage);
|
|
1046
1047
|
});
|
|
1048
|
+
} else {
|
|
1049
|
+
const saved = normalizeRuntimeAuthSession(options.savedSession, { requireRefreshToken: true });
|
|
1050
|
+
if (saved.ok) {
|
|
1051
|
+
setImmediate(() => {
|
|
1052
|
+
try {
|
|
1053
|
+
if (!writeSavedSession(saved.session)) throw new Error('refresh-token-required');
|
|
1054
|
+
state.auth.persisted = true;
|
|
1055
|
+
complete({ type: 'google', session: saved.session }, 'Saved sign-in found. Finding the LiveDesk Hub.');
|
|
1056
|
+
} catch (error) {
|
|
1057
|
+
recordAuthAttempt('rejected', `session-persistence-failed:${normalizeString(error?.message || error, 160)}`);
|
|
1058
|
+
}
|
|
1059
|
+
});
|
|
1060
|
+
}
|
|
1047
1061
|
}
|
|
1048
|
-
resolveStart();
|
|
1049
|
-
});
|
|
1062
|
+
resolveStart();
|
|
1063
|
+
});
|
|
1050
1064
|
});
|
|
1051
1065
|
|
|
1052
1066
|
return {
|