electron/companion-autostart.mjs
Rama main · réplica de lectura del repositorio original.
// The first launch after an update is the slow one on Windows: the new files are scanned and the old companion may
// still hold its ports, so the one start at launch can time out. A paired phone then has no way in until the app is
// restarted by hand, so the launch start tries again a few times, as long as the companion is still wanted.
export const COMPANION_AUTOSTART_RETRY_DELAYS_MS = Object.freeze([5_000, 15_000, 30_000]);
/**
* Starts the companion, retrying a failed start after each delay while `wanted()` holds. Resolves with the last state;
* a thrown error (a policy refusal) is never retried.
*/
export async function startCompanionWithRetries({
start,
wanted,
log = () => {},
delaysMs = COMPANION_AUTOSTART_RETRY_DELAYS_MS,
sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
}) {
let state = await start();
for (const [index, delay] of delaysMs.entries()) {
if (!state?.error) return state;
log(`companion start failed: ${state.error}; trying again in ${Math.round(delay / 1000)}s (${index + 1} of ${delaysMs.length})`);
await sleep(delay);
if (!wanted()) {
log("companion start retry skipped: the companion is no longer wanted");
return state;
}
state = await start();
}
if (state?.error) log(`companion start failed: ${state.error}; giving up until the app restarts`);
return state;
}
/**
* The start at launch: waits for `restored` (a saved organisation policy may turn remote access off), then starts with
* retries. Never rejects: a refusal, or a policy that could not be restored, is logged as a skipped auto-start.
*/
export function autoStartCompanion({ restored, log = () => {}, ...retry }) {
return Promise.resolve(restored)
.then(() => startCompanionWithRetries({ log, ...retry }))
.catch((error) => {
log(`companion auto-start skipped: ${error?.message ?? error}`);
return null;
});
}