* fix(hopper): normalize string-backed addresses and update verification * feat(native): add inspection primitives, dispatch traces and approved UI observation * test: prioritize real artifact E2E and captured golden regressions * fix(process): queue observed output before reactive rendering actions * test: prune redundant cases and strengthen boundary assertions * fix(cli): route native value tracing through shared workflows * test: replace synthetic success with real workflows and captured data * fix(catalog): separate portable metadata from native host availability
54 lines
1.6 KiB
TypeScript
54 lines
1.6 KiB
TypeScript
import { mkdtemp, rm } from "node:fs/promises";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { execFileOutput } from "../process/ExecFileOutput.js";
|
|
import type { NativeUiHelper } from "./NativeUiObservation.js";
|
|
|
|
/** Lazily compile one owned helper per observation/scenario and remove its compiler cache. */
|
|
export const createNativeUiHelperRuntime = () => {
|
|
let root: string | undefined;
|
|
let executable: string | undefined;
|
|
const invoke: NativeUiHelper = async (parameters, signal) => {
|
|
if (executable === undefined) {
|
|
root = await mkdtemp(join(tmpdir(), "rea-native-ui-"));
|
|
const output = join(root, "observer");
|
|
await execFileOutput(
|
|
"/usr/bin/xcrun",
|
|
[
|
|
"swiftc",
|
|
"-module-cache-path",
|
|
join(root, "modules"),
|
|
fileURLToPath(
|
|
new URL("../../bridge/native/ReaNativeUI.swift", import.meta.url),
|
|
),
|
|
"-o",
|
|
output,
|
|
],
|
|
{
|
|
timeout: 60_000,
|
|
maxBuffer: 1024 * 1024,
|
|
...(signal === undefined ? {} : { signal }),
|
|
},
|
|
);
|
|
executable = output;
|
|
}
|
|
const output = await execFileOutput(
|
|
executable,
|
|
[JSON.stringify(parameters)],
|
|
{
|
|
timeout: 30_000,
|
|
maxBuffer: 16 * 1024 * 1024,
|
|
...(signal === undefined ? {} : { signal }),
|
|
},
|
|
);
|
|
return JSON.parse(output.stdout) as unknown;
|
|
};
|
|
return {
|
|
invoke,
|
|
close: async () => {
|
|
if (root !== undefined) await rm(root, { recursive: true, force: true });
|
|
},
|
|
};
|
|
};
|