slige/web/runtime.ts

84 lines
2.2 KiB
TypeScript
Raw Normal View History

2024-11-21 11:08:07 +00:00
export class Runtime {
2024-12-13 12:16:03 +00:00
private runtimeProcess?: Deno.ChildProcess;
2024-11-21 11:08:07 +00:00
constructor(private port: number) {}
2024-12-13 12:16:03 +00:00
async checkRuntimeRev() {
const currentRev = new TextDecoder().decode(
await new Deno.Command("git", { args: ["rev-parse", "HEAD"] })
.output()
.then((output) => output.stdout),
).trim();
const runtimeRev = (await Deno.readTextFile("../runtime/build/rev"))
.trim();
if (runtimeRev !== currentRev) {
console.error(
"runtime out-of-date; run 'make' inside runtime/ folder",
);
Deno.exit(1);
}
}
async start() {
await this.checkRuntimeRev();
this.runtimeProcess = new Deno.Command("../runtime/build/sliger", {
args: [],
stdout: "piped",
}).spawn();
}
stop() {
this.runtimeProcess?.kill();
this.runtimeProcess = undefined;
}
2024-11-21 11:08:07 +00:00
async connect(): Promise<RuntimeConnection> {
2024-12-13 12:16:03 +00:00
return await new Promise((resolve) => {
setTimeout(async () => {
resolve(
new RuntimeConnection(
await Deno.connect({
port: this.port,
}),
),
);
}, 1000);
});
2024-11-21 11:08:07 +00:00
}
}
export class RuntimeConnection {
constructor(private connection: Deno.Conn) {}
async write(text: string): Promise<void> {
const req = new TextEncoder().encode(text);
await this.connection.write(req);
}
async send<T>(value: T): Promise<void> {
await this.write(JSON.stringify(value));
}
async read(): Promise<string> {
let result = "";
while (true) {
const buf = new Uint8Array(256);
const readRes = await this.connection.read(buf);
2024-12-12 10:56:22 +00:00
if (readRes != null) {
result += new TextDecoder().decode(buf.slice(0, readRes));
} else {
2024-11-21 11:08:07 +00:00
break;
}
}
return result;
}
async receive<T>(): Promise<T> {
return JSON.parse(await this.read()) as T;
}
close() {
this.connection.close();
}
}