a post-component library for building user-interfaces on the web.
at main 41 lines 1.4 kB view raw
1import * as child_process from 'node:child_process' 2import { once } from 'node:events' 3import * as fs from 'node:fs/promises' 4import * as os from 'node:os' 5import * as path from 'node:path' 6import { fileURLToPath } from 'node:url' 7import type { Runtime } from './main.ts' 8 9export interface NodeRuntimeOptions { 10 collect_coverage?: boolean 11} 12 13export async function create_node_runtime(options: NodeRuntimeOptions = {}): Promise<Runtime> { 14 const collect_coverage = options.collect_coverage ?? true 15 const coverage_dir = collect_coverage ? await fs.mkdtemp(path.join(os.tmpdir(), 'coverage-')) : null 16 const child = child_process.fork(fileURLToPath(import.meta.resolve('./runtime.ts')), { 17 env: collect_coverage ? { ...process.env, NODE_V8_COVERAGE: coverage_dir! } : process.env, 18 stdio: 'inherit', 19 }) 20 21 const { port1, port2 } = new MessageChannel() 22 port1.onmessage = e => child.send(e.data) 23 child.on('message', data => port1.postMessage(data)) 24 25 await once(child, 'spawn') 26 27 return { 28 port: port2, 29 async coverage() { 30 if (!collect_coverage || !coverage_dir) return [] 31 const [filename] = await fs.readdir(coverage_dir) 32 const { result } = JSON.parse(await fs.readFile(path.join(coverage_dir, filename), 'utf8')) 33 return result 34 }, 35 async [Symbol.asyncDispose]() { 36 port1.close() 37 child.kill() 38 if (coverage_dir) await fs.rm(coverage_dir, { recursive: true }) 39 }, 40 } 41}