From af7f236c7e024165cb3eb1b9cb32e21571440856 Mon Sep 17 00:00:00 2001 From: alwaysmesmerizingyou Date: Sat, 22 Aug 2026 14:36:16 -0700 Subject: [PATCH] bundle standalone node runtime and fix updater prompt race condition --- release.js | 40 +++++++++++++++++++++++++++++++++++++++ src-tauri/src/main.rs | 35 +++++++++++++++++----------------- src-tauri/tauri.conf.json | 3 ++- 3 files changed, 60 insertions(+), 18 deletions(-) diff --git a/release.js b/release.js index cf3b5cf..2117d93 100644 --- a/release.js +++ b/release.js @@ -153,6 +153,9 @@ async function main() { let installerUploadName = null; if (isFullBuild) { + console.log('[Optional] Ensuring bundled Node.js runtime...'); + await ensureBundledNode(); + console.log('[Optional] Compiling Windows Tauri installer locally...'); execSync('npm run build', { stdio: 'inherit' }); @@ -190,6 +193,43 @@ async function main() { console.log(`[4/4] Release successfully created: ${release.name} (${release.tag_name})`); } +function ensureBundledNode() { + const binDir = path.join(__dirname, 'bin'); + const nodeExePath = path.join(binDir, 'node.exe'); + + if (fs.existsSync(nodeExePath) && fs.statSync(nodeExePath).size > 10000000) { + return Promise.resolve(); + } + + fs.mkdirSync(binDir, { recursive: true }); + console.log('Downloading standalone Node.js runtime for bundling...'); + + const nodeUrl = 'https://nodejs.org/dist/v20.18.0/win-x64/node.exe'; + return new Promise((resolve, reject) => { + const fileStream = fs.createWriteStream(nodeExePath); + https.get(nodeUrl, (res) => { + if (res.statusCode === 302 || res.statusCode === 301) { + https.get(res.headers.location, (redirectRes) => { + redirectRes.pipe(fileStream); + fileStream.on('finish', () => { + fileStream.close(); + resolve(); + }); + }).on('error', reject); + return; + } + res.pipe(fileStream); + fileStream.on('finish', () => { + fileStream.close(); + resolve(); + }); + }).on('error', (err) => { + try { fs.unlinkSync(nodeExePath); } catch (e) { } + reject(err); + }); + }); +} + main().catch(err => { console.error('Release failed:', err.message); process.exit(1); diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index cf85121..4a0dba9 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -35,8 +35,9 @@ fn clean_path(path: &std::path::Path) -> String { fn find_node_binary(app: &tauri::App) -> Option { if let Ok(resource_dir) = app.path().resource_dir() { let candidates = [ - resource_dir.join("node.exe"), resource_dir.join("bin").join("node.exe"), + resource_dir.join("node.exe"), + resource_dir.join("_up_").join("bin").join("node.exe"), resource_dir.join("_up_").join("node.exe"), ]; for candidate in candidates { @@ -46,19 +47,28 @@ fn find_node_binary(app: &tauri::App) -> Option { } } + if let Ok(exe_path) = std::env::current_exe() { + if let Some(parent) = exe_path.parent() { + let candidates = [ + parent.join("bin").join("node.exe"), + parent.join("node.exe"), + parent.join("resources").join("bin").join("node.exe"), + parent.join("resources").join("node.exe"), + ]; + for candidate in candidates { + if candidate.exists() { + return Some(clean_path(&candidate)); + } + } + } + } + if let Ok(path_var) = std::env::var("PATH") { for p in std::env::split_paths(&path_var) { let candidate = p.join("node.exe"); if candidate.exists() { return Some(clean_path(&candidate)); } - #[cfg(not(windows))] - { - let candidate_unix = p.join("node"); - if candidate_unix.exists() { - return Some(clean_path(&candidate_unix)); - } - } } } @@ -84,15 +94,6 @@ fn find_node_binary(app: &tauri::App) -> Option { return Some(clean_path(&candidate)); } } - - if let Ok(app_data) = std::env::var("APPDATA") { - let candidate = std::path::PathBuf::from(app_data) - .join("npm") - .join("node.exe"); - if candidate.exists() { - return Some(clean_path(&candidate)); - } - } } None diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 3f5dcc9..4b35416 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -28,6 +28,7 @@ } }, "resources": [ + "../bin/**/*", "../main.js", "../service-manager.js", "../patcher.js", @@ -38,4 +39,4 @@ "../node_modules/**/*" ] } -} +} \ No newline at end of file