- Bump bareOsCtxApiVersion to 1.48.0; sync CHANGELOG, compatibility matrix, syscalls.example.json, ctx d.ts, generated ctx-client helper - POSIX: getconf _SC_NPROCESSORS_ONLN; shell set -o pipefail + BARE_OS_PIPESTATUS; posix_utilities schema v2 + JSON Schema; generated dashboard refresh - Host/subprocess: bare-subprocess then Node child_process spawn; optional backend on ctx.bareOsTrySpawnHostSubprocess; bin-worker WASM wall budget - VFS: BARE_OS_VFS_SYSTEM_IMAGE_WRITE for system image writes + warm-cache eviction path; guest /.bare/account EACCES test; environ TOKEN redaction test - Docs: corestore snapshot non-goal in package-bare-os-booter; PEAR-RUN links → docs/PEAR-RUN.md; POSIX pretest matrix in scripts/README + dev guide; environment appendix (PIPESTATUS, WASM_MS, system image write) - Seeder: keep kernel/ mirror in sync after bundle + coreutils builds Verified: npm test -w bare-os-booter, npm run pretest
94 lines
2.6 KiB
JavaScript
94 lines
2.6 KiB
JavaScript
'use strict'
|
|
/**
|
|
* Optional bare-worker thread for heavy `/bin` utilities when
|
|
* `BARE_OS_BIN_WORKER_OFFLOAD=1` (Bare runtime only; Node falls back to in-process).
|
|
*/
|
|
const Worker = require('bare-worker')
|
|
|
|
if (Worker.isMainThread) {
|
|
/**
|
|
* @param {{ source: string, argv: string[] }} workerData
|
|
* @param {{ maxWasmMs?: number }} [opts]
|
|
* @returns {Promise<Record<string, unknown> | null>}
|
|
*/
|
|
exports.runBinOffloaded = function runBinOffloaded(workerData, opts) {
|
|
const raw =
|
|
opts &&
|
|
typeof opts.maxWasmMs === 'number' &&
|
|
Number.isFinite(opts.maxWasmMs) &&
|
|
opts.maxWasmMs > 0
|
|
? Math.floor(opts.maxWasmMs)
|
|
: 0
|
|
const maxWasmMs = raw > 0 ? Math.min(raw, 3_600_000) : 0
|
|
return new Promise((resolve) => {
|
|
let w
|
|
let done = false
|
|
/** @type {ReturnType<typeof setTimeout> | null} */
|
|
let timer = null
|
|
const finish = (msg) => {
|
|
if (done) return
|
|
done = true
|
|
if (timer) clearTimeout(timer)
|
|
resolve(msg)
|
|
}
|
|
try {
|
|
w = new Worker(__filename, { workerData })
|
|
} catch {
|
|
finish(null)
|
|
return
|
|
}
|
|
if (maxWasmMs > 0) {
|
|
timer = setTimeout(() => {
|
|
try {
|
|
w.terminate()
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
finish({ ok: false, reason: 'wasm_time_budget' })
|
|
}, maxWasmMs)
|
|
}
|
|
w.on('message', (msg) => finish(msg))
|
|
w.on('error', () => finish(null))
|
|
})
|
|
}
|
|
} else {
|
|
const { source, argv } = Worker.workerData || {}
|
|
;(async () => {
|
|
try {
|
|
const AsyncFunction = Object.getPrototypeOf(async function () {})
|
|
.constructor
|
|
/** @type {string[]} */
|
|
const logs = []
|
|
/** @type {string[]} */
|
|
const errs = []
|
|
const ctx = {
|
|
exitCode: 0,
|
|
console: {
|
|
log: (...a) => logs.push(a.map(String).join(' ')),
|
|
error: (...a) => errs.push(a.map(String).join(' '))
|
|
}
|
|
}
|
|
const raw = typeof source === 'string' ? source : ''
|
|
const body = raw.startsWith('#!') ? raw.replace(/^#[^\n]*\n/, '') : raw
|
|
const fn = new AsyncFunction(
|
|
'ctx',
|
|
'argv',
|
|
`${body}\nif (typeof run === 'function') await run(ctx, argv)\n`
|
|
)
|
|
await fn(ctx, Array.isArray(argv) ? argv : [])
|
|
Worker.parentPort.postMessage({
|
|
ok: true,
|
|
exitCode:
|
|
ctx.exitCode != null ? Number(ctx.exitCode) || 0 : 0,
|
|
logs,
|
|
errs
|
|
})
|
|
} catch (e) {
|
|
Worker.parentPort.postMessage({
|
|
ok: false,
|
|
error: e && e.message ? e.message : String(e)
|
|
})
|
|
}
|
|
})()
|
|
}
|