import { QuickJSWorker } from "../dist"; describe("Runtime event compatibility", () => { let worker: QuickJSWorker; beforeEach(() => { worker = new QuickJSWorker(); }); afterEach(async () => { if (worker && !worker.isClosed()) await worker.close(); }); it("emits eval begin/end runtime events", async () => { const events: Array> = []; worker.on("runtime", (event) => events.push(event)); await expect(worker.eval("(a, b) => a + b", { args: [2, 3] })).resolves.toBe(5); const begin = events.find((event) => event.kind === "eval.begin") as any; const end = events.find((event) => event.kind === "eval.end") as any; expect(begin).toBeTruthy(); expect(end).toBeTruthy(); expect(begin.args).toEqual([2, 3]); expect(typeof begin.hostFile).toBe("string"); expect(typeof begin.hostLine).toBe("number"); expect(typeof begin.hostColumn).toBe("number"); expect(String(begin.hostCallSite ?? "")).toContain(":"); expect(begin.opId).toBe(end.opId); expect(end.ok).toBe(true); }); it("forwards eval failures to error listeners", async () => { const errors: Array> = []; worker.on("error", (error) => errors.push(error)); await expect(worker.eval(`throw new Error("boom")`)).rejects.toThrow("boom"); expect(errors).toHaveLength(1); expect(errors[0]).toMatchObject({ kind: "error.thrown", surface: "eval", }); expect(String((errors[0] as any).error?.message ?? "")).toContain("boom"); expect(typeof (errors[0] as any).hostCallSite).toBe("string"); expect(typeof (errors[0] as any).hostImmediateCallSite).toBe("string"); }); it("preserves originating and immediate host callsites through wrapper layers", async () => { const events: Array> = []; worker.on("runtime", (event) => events.push(event)); const wrapper = async () => { await worker.eval(`throw new Error("wrapper-boom")`); }; const invokeThroughWrapper = async () => { await wrapper(); }; await expect(invokeThroughWrapper()).rejects.toBeTruthy(); const thrown = events.find((event) => event.kind === "error.thrown") as any; expect(thrown).toBeTruthy(); expect(typeof thrown.hostCallSite).toBe("string"); expect(typeof thrown.hostImmediateCallSite).toBe("string"); expect(String(thrown.hostCallSite)).toContain("runtime.compat.spec.ts"); expect(String(thrown.hostImmediateCallSite)).toContain("runtime.compat.spec.ts"); expect(String(thrown.hostCallSite)).not.toBe(String(thrown.hostImmediateCallSite)); }); });