Files
AstrBot/desktop/lib/common.js
T
エイカク a7e580407c feat: supports electron app (#4952)
* feat: add desktop wrapper with frontend-only packaging

* docs: add desktop build docs and track dashboard lockfile

* fix: track desktop lockfile for npm ci

* fix: allow custom install directory for windows installer

* chore: migrate desktop workflow to pnpm

* fix(desktop): build AppImage only on Linux

* fix(desktop): harden packaged startup and backend bundling

* fix(desktop): adapt packaged restart and plugin dependency flow

* fix(desktop): prevent backend respawn race on quit

* fix(desktop): prefer pyproject version for desktop packaging

* fix(desktop): improve startup loading UX and reduce flicker

* ci: add desktop multi-platform release workflow

* ci: fix desktop release build and mac runner labels

* ci: disable electron-builder auto publish in desktop build

* ci: avoid electron-builder publish path in build matrix

* ci: normalize desktop release artifact names

* ci: exclude blockmap files from desktop release assets

* ci: prefix desktop release assets with AstrBot and purge blockmaps

* feat: add electron bridge types and expose backend control methods in preload script

* Update startup screen assets and styles

- Changed the icon from PNG to SVG format for better scalability.
- Updated the border color from #d0d0d0 to #eeeeee for a softer appearance.
- Adjusted the width of the startup screen from 460px to 360px for improved responsiveness.

* Update .gitignore to include package.json

* chore: remove desktop gitkeep ignore exceptions

* docs: update desktop troubleshooting for current runtime behavior

* refactor(desktop): modularize runtime and harden startup flow

---------

Co-authored-by: Soulter <905617992@qq.com>
Co-authored-by: Soulter <37870767+Soulter@users.noreply.github.com>
2026-02-08 21:49:54 +08:00

60 lines
1.2 KiB
JavaScript

'use strict';
const fs = require('fs');
function normalizeUrl(value) {
try {
const url = new URL(value);
if (!url.pathname.endsWith('/')) {
url.pathname += '/';
}
return url.toString();
} catch {
return 'http://127.0.0.1:6185/';
}
}
function ensureDir(value) {
if (!value) {
return;
}
if (fs.existsSync(value)) {
return;
}
fs.mkdirSync(value, { recursive: true });
}
function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
function waitForProcessExit(child, timeoutMs = 5000) {
if (!child) {
return Promise.resolve('missing');
}
if (child.exitCode !== null || child.signalCode !== null) {
return Promise.resolve('exited');
}
return new Promise((resolve) => {
let settled = false;
const finish = (reason) => {
if (settled) {
return;
}
settled = true;
clearTimeout(timeout);
resolve(reason);
};
const timeout = setTimeout(() => finish('timeout'), timeoutMs);
child.once('exit', () => finish('exit'));
child.once('error', () => finish('error'));
});
}
module.exports = {
delay,
ensureDir,
normalizeUrl,
waitForProcessExit,
};