This commit is contained in:
seb
2026-10-30 11:54:16 +00:00
parent fbe3105dc9
commit bc1340419c
4 changed files with 102 additions and 11 deletions

View File

@@ -316,13 +316,9 @@ export async function runSelfTest() {
apiLog.info(`Config: host=${env.host} port=${env.port} dbProvider=${env.dbProvider}`);
// 2. Test database & store initialization
try {
await ensureConnection();
const schemaVer = await getSchemaVersion();
apiLog.info(`Database & store: OK (provider: ${env.dbProvider}, schema v${schemaVer})`);
} catch (err) {
apiLog.warn(`Database connection warning: ${err.message}`);
}
await ensureConnection();
const schemaVer = await getSchemaVersion();
apiLog.info(`Database & store: OK (provider: ${env.dbProvider}, schema v${schemaVer})`);
// 3. Build API app and register all route modules
const app = await buildApiApp();

View File

@@ -15,23 +15,65 @@ const { createRequire } = require('node:module');
function getProjectRoot() {
// If embedded application payload is present in SEA
if (sea.isSea && sea.isSea() && sea.getAssetKeys && sea.getAssetKeys().includes('app-payload.bin')) {
const distDir = path.dirname(process.execPath);
const runtimeDir = process.env.DASHBACK_RUNTIME_DIR || path.join(os.tmpdir(), 'dashback-runtime');
const markerFile = path.join(runtimeDir, '.unpacked');
const nativeMapFile = path.join(runtimeDir, '.native-nodes.json');
if (!fs.existsSync(markerFile)) {
const compressed = Buffer.from(sea.getRawAsset('app-payload.bin'));
const json = zlib.inflateSync(compressed).toString('utf8');
const files = JSON.parse(json);
const nativeNodes = files['.native-nodes.json']
? JSON.parse(Buffer.from(files['.native-nodes.json'], 'base64').toString('utf8'))
: {};
for (const [relPath, b64] of Object.entries(files)) {
if (relPath === '.native-nodes.json') continue;
const targetFile = path.join(runtimeDir, relPath);
fs.mkdirSync(path.dirname(targetFile), { recursive: true });
fs.writeFileSync(targetFile, Buffer.from(b64, 'base64'));
}
for (const [relPath, distFileName] of Object.entries(nativeNodes)) {
const targetLink = path.join(runtimeDir, relPath);
const distTarget = path.join(distDir, distFileName);
fs.mkdirSync(path.dirname(targetLink), { recursive: true });
try {
if (fs.lstatSync(targetLink)) fs.unlinkSync(targetLink);
} catch {}
try {
fs.symlinkSync(distTarget, targetLink, 'file');
} catch {}
}
fs.writeFileSync(nativeMapFile, JSON.stringify(nativeNodes));
fs.writeFileSync(markerFile, '1');
}
const nativeNodes = fs.existsSync(nativeMapFile)
? JSON.parse(fs.readFileSync(nativeMapFile, 'utf8'))
: {};
// Redirect native .node loading to distDir and preload libvips from distDir if present
const origDlopen = process.dlopen;
process.dlopen = function (mod, filename, flags) {
const relFromRuntime = path.relative(runtimeDir, filename);
const mappedName = nativeNodes[relFromRuntime] || path.basename(filename);
const distCandidate = path.join(distDir, mappedName);
const target = fs.existsSync(distCandidate) ? distCandidate : filename;
if (mappedName.startsWith('sharp-')) {
const vipsPath = path.join(distDir, 'libvips-cpp.so.8.18.7');
if (fs.existsSync(vipsPath)) {
try {
origDlopen.call(process, { exports: {} }, vipsPath, os.constants.dlopen.RTLD_NOW | os.constants.dlopen.RTLD_GLOBAL);
} catch {}
}
}
return flags !== undefined ? origDlopen.call(process, mod, target, flags) : origDlopen.call(process, mod, target);
};
// Link host .env if present so config/env.js can find it
const hostEnv = path.resolve(process.cwd(), '.env');
const runtimeEnv = path.join(runtimeDir, '.env');