(name: string)
| 231 | * Deduplicates concurrent calls for the same binary. |
| 232 | */ |
| 233 | export async function ensureRuntimeBinary(name: string): Promise<string> { |
| 234 | const def = REGISTRY[name] |
| 235 | if (!def) throw new Error(`Unknown binary: ${name}`) |
| 236 | |
| 237 | const existing = resolve(name) |
| 238 | if (existing) return existing |
| 239 | |
| 240 | const platformKey = getPlatformKey() |
| 241 | const url = def.urls[platformKey] |
| 242 | if (!url) throw new Error(`${def.displayName} is not available for ${platformKey}`) |
| 243 | |
| 244 | // Deduplicate concurrent downloads |
| 245 | const existingDownload = activeDownloads.get(name) |
| 246 | if (existingDownload) return existingDownload |
| 247 | |
| 248 | const downloadPromise = (async () => { |
| 249 | const binaryPath = getBinaryPath(def) |
| 250 | if (!binaryPath) throw new Error(`No filename mapping for ${process.platform}`) |
| 251 | |
| 252 | try { |
| 253 | await downloadBinary(url, binaryPath, name) |
| 254 | |
| 255 | const verifyResult = await execCommand(binaryPath, def.verifyArgs, { timeout: 10000 }) |
| 256 | if (!verifyResult.success) { |
| 257 | try { |
| 258 | fs.unlinkSync(binaryPath) |
| 259 | } catch (err) { |
| 260 | logger.debug('[Binaries] Error removing failed binary:', err) |
| 261 | } |
| 262 | throw new Error(`Verification failed: ${verifyResult.stderr}`) |
| 263 | } |
| 264 | |
| 265 | writeVersion(name, def.version) |
| 266 | logger.info(`[Binaries] ${def.displayName} ${def.version} ready at ${binaryPath}`) |
| 267 | enhancePath() |
| 268 | return binaryPath |
| 269 | } finally { |
| 270 | activeDownloads.delete(name) |
| 271 | } |
| 272 | })() |
| 273 | |
| 274 | activeDownloads.set(name, downloadPromise) |
| 275 | return downloadPromise |
| 276 | } |
| 277 | |
| 278 | /** |
| 279 | * Get status of all managed binaries. |
no test coverage detected