build: consolidate typed frontend module graph
This commit is contained in:
@@ -15,43 +15,12 @@ await rm(outputDir, { recursive: true, force: true });
|
||||
|
||||
await build({
|
||||
entryPoints: {
|
||||
"api-client": path.join(sourceDir, "api", "client.ts"),
|
||||
"ui-core": path.join(sourceDir, "ui-core.ts"),
|
||||
"plugin-loader": path.join(sourceDir, "plugin-loader.ts"),
|
||||
"plugin-runtime": path.join(sourceDir, "plugin-runtime.ts"),
|
||||
screenshot: path.join(sourceDir, "screenshot.ts"),
|
||||
"webgl-renderer": path.join(sourceDir, "webgl-renderer.ts"),
|
||||
},
|
||||
outdir: outputDir,
|
||||
bundle: false,
|
||||
target: "es2022",
|
||||
sourcemap: false,
|
||||
legalComments: "inline",
|
||||
charset: "utf8",
|
||||
logLevel: "info",
|
||||
});
|
||||
|
||||
await build({
|
||||
entryPoints: { app: path.join(sourceDir, "bootstrap.ts") },
|
||||
outdir: outputDir,
|
||||
bundle: true,
|
||||
format: "iife",
|
||||
platform: "browser",
|
||||
target: "es2022",
|
||||
sourcemap: false,
|
||||
legalComments: "inline",
|
||||
charset: "utf8",
|
||||
logLevel: "info",
|
||||
});
|
||||
|
||||
await build({
|
||||
entryPoints: {
|
||||
app: path.join(sourceDir, "bootstrap.ts"),
|
||||
ft2: path.join(sourceDir, "plugins", "ft2.ts"),
|
||||
ft4: path.join(sourceDir, "plugins", "ft4.ts"),
|
||||
wspr: path.join(sourceDir, "plugins", "wspr.ts"),
|
||||
cw: path.join(sourceDir, "plugins", "cw.ts"),
|
||||
ft8: path.join(sourceDir, "plugins", "ft8.ts"),
|
||||
"leaflet-ais-tracksymbol": path.join(sourceDir, "leaflet-ais-tracksymbol.ts"),
|
||||
vdes: path.join(sourceDir, "plugins", "vdes.ts"),
|
||||
wefax: path.join(sourceDir, "plugins", "wefax.ts"),
|
||||
"background-decode": path.join(sourceDir, "plugins", "background-decode.ts"),
|
||||
@@ -64,6 +33,7 @@ await build({
|
||||
bookmarks: path.join(sourceDir, "plugins", "bookmarks.ts"),
|
||||
scheduler: path.join(sourceDir, "plugins", "scheduler.ts"),
|
||||
"map-core": path.join(sourceDir, "map-core.ts"),
|
||||
screenshot: path.join(sourceDir, "screenshot.ts"),
|
||||
},
|
||||
outdir: outputDir,
|
||||
bundle: true,
|
||||
|
||||
@@ -6,7 +6,45 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# Frontend source
|
||||
|
||||
This directory is the source of the browser assets embedded by
|
||||
`trx-frontend-http`. Run `npm run build` from the parent `frontend` directory
|
||||
after changing a source file. Cargo consumes the committed output under
|
||||
`../assets/web/generated` and does not invoke Node.js.
|
||||
This directory contains the strict TypeScript source for the browser assets
|
||||
embedded by `trx-frontend-http`. `bootstrap.ts` is the production entry point;
|
||||
esbuild follows its imports and emits `/app.js`. Feature plugins are ESM entry
|
||||
points loaded on demand by `plugin-loader.ts`, and the decode-history worker is
|
||||
built with its own Web Worker TypeScript configuration.
|
||||
|
||||
Run all frontend commands from the parent `frontend` directory:
|
||||
|
||||
```sh
|
||||
npm ci
|
||||
npm run typecheck
|
||||
npm run lint
|
||||
npm test
|
||||
npm run test:browser
|
||||
npm run build
|
||||
npm run verify-generated
|
||||
```
|
||||
|
||||
`npm run verify-generated` regenerates Rust wire contracts and browser bundles,
|
||||
then rejects drift from the committed files. The browser smoke test needs a
|
||||
local Chromium-family executable; set `CHROMIUM_PATH` when it is not installed
|
||||
at a conventional system path.
|
||||
|
||||
Cargo consumes committed output under `../assets/web/generated`. It never
|
||||
invokes Node.js, installs packages, or accesses the network. After changing a
|
||||
source file, commit the deterministic generated asset changes together with the
|
||||
source change.
|
||||
|
||||
## Boundaries
|
||||
|
||||
- `api/generated.ts` is generated from Rust and must not be edited manually.
|
||||
- `api/client.ts` owns runtime validation at version-sensitive HTTP and SSE
|
||||
boundaries.
|
||||
- `core/` contains dependency-light shared helpers.
|
||||
- `features/` contains application behavior grouped by responsibility.
|
||||
- `plugins/` contains lazy decoder and high-coupling feature entries.
|
||||
- Files under `assets/web/vendor/` are vendored JavaScript and are not part of
|
||||
the TypeScript migration.
|
||||
|
||||
First-party features communicate through imports, the typed plugin runtime, or
|
||||
the documented `window.trx` host interface. New standalone `window` callbacks
|
||||
are not permitted.
|
||||
|
||||
@@ -46,6 +46,7 @@ import type { NumericBins } from "./features/spectrum/math.js";
|
||||
import type { AuthRole } from "./api/auth.js";
|
||||
import type { RdsData, RigCapabilities, RigListItem, RigSnapshot } from "./api/generated.js";
|
||||
import type { TrxPluginRuntime } from "./plugins/runtime-contract.js";
|
||||
import { loadEagerPlugins, loadPluginsForTab } from "./plugin-loader.js";
|
||||
|
||||
interface SpectrumFrame {
|
||||
bins: NumericBins;
|
||||
@@ -4530,7 +4531,7 @@ function navigateToTab(name: TabName, options: { updateHistory?: boolean; replac
|
||||
updateTabHistory(name, replaceHistory);
|
||||
}
|
||||
scheduleSpectrumLayout();
|
||||
if (typeof window.loadPluginsForTab === "function") window.loadPluginsForTab(name);
|
||||
void loadPluginsForTab(name).catch((error: unknown) => { console.error(error); });
|
||||
if (name === "map") {
|
||||
_initMapWhenReady();
|
||||
}
|
||||
@@ -4787,7 +4788,7 @@ window.trx = Object.freeze({ state: trxState, core: trxCore, modules: trxModules
|
||||
|
||||
// Load plugin scripts now that window.trx is populated. Dynamic scripts are
|
||||
// async so they must not be created before the namespace they depend on exists.
|
||||
if (typeof window.loadEagerPlugins === "function") window.loadEagerPlugins();
|
||||
void loadEagerPlugins().catch((error: unknown) => { console.error(error); });
|
||||
|
||||
// Start the app
|
||||
initializeApp();
|
||||
@@ -7829,17 +7830,14 @@ window.addEventListener("keydown", (event) => {
|
||||
if (event.ctrlKey || event.metaKey || event.altKey) return;
|
||||
if (shouldIgnoreGlobalShortcut(event.target)) return;
|
||||
|
||||
// S — spectrum screenshot (lazy-loads screenshot.js on first use)
|
||||
// S — spectrum screenshot (lazy-loads its typed module on first use)
|
||||
if (key === "s") {
|
||||
event.preventDefault();
|
||||
if (window.trx.modules.screenshot) {
|
||||
void window.trx.modules.screenshot.captureSpectrumScreenshot();
|
||||
} else {
|
||||
const s = document.createElement("script");
|
||||
s.src = "/screenshot.js";
|
||||
s.onload = () => { void window.trx.modules.screenshot?.captureSpectrumScreenshot(); };
|
||||
document.body.appendChild(s);
|
||||
}
|
||||
} else void import("./screenshot.js")
|
||||
.then(() => window.trx.modules.screenshot?.captureSpectrumScreenshot())
|
||||
.catch((error: unknown) => { console.error("Screenshot module failed to load", error); });
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,4 +2,8 @@
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import "./app.ts";
|
||||
import "./webgl-renderer.js";
|
||||
import "./ui-core.js";
|
||||
import "./plugin-runtime.js";
|
||||
import "./leaflet-ais-tracksymbol.js";
|
||||
import "./app.js";
|
||||
|
||||
@@ -36,21 +36,10 @@ async function loadPlugins(group: string): Promise<void> {
|
||||
for (const path of pluginGroups[group as PluginGroup]) await loadPlugin(path);
|
||||
}
|
||||
|
||||
function requestPlugins(group: string): void {
|
||||
void loadPlugins(group).catch((error: unknown) => { console.error(error); });
|
||||
export async function loadEagerPlugins(): Promise<void> {
|
||||
await Promise.all(["digital-modes", "map-data", "bookmarks", "settings"].map(loadPlugins));
|
||||
}
|
||||
|
||||
const loaderWindow = window as typeof window & {
|
||||
loadEagerPlugins?: () => Promise<void>;
|
||||
loadPluginsForTab?: (tab: string) => Promise<void>;
|
||||
};
|
||||
loaderWindow.loadEagerPlugins = async () => {
|
||||
await Promise.all(["digital-modes", "map-data", "bookmarks", "settings"].map(loadPlugins));
|
||||
};
|
||||
loaderWindow.loadPluginsForTab = loadPlugins;
|
||||
|
||||
document.addEventListener("click", (event) => {
|
||||
if (!(event.target instanceof Element)) return;
|
||||
const tab = event.target.closest<HTMLElement>("[data-tab]")?.dataset.tab;
|
||||
if (tab) requestPlugins(tab);
|
||||
});
|
||||
export async function loadPluginsForTab(tab: string): Promise<void> {
|
||||
await loadPlugins(tab);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ interface TrxScreenshotBridge {
|
||||
showHint(message: string, durationMs: number): void;
|
||||
modules: { screenshot?: ScreenshotModule };
|
||||
}
|
||||
export {};
|
||||
const screenshotWindow = window as typeof window & { trx: TrxScreenshotBridge };
|
||||
|
||||
(function () {
|
||||
|
||||
@@ -6,6 +6,7 @@ import assert from "node:assert/strict";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import test from "node:test";
|
||||
import vm from "node:vm";
|
||||
import { bundleEntry } from "./bundle-entry.mjs";
|
||||
|
||||
test("AIS entry forwards positioned vessels with normalized metadata", async () => {
|
||||
const forwarded = [];
|
||||
@@ -23,7 +24,7 @@ test("AIS entry forwards positioned vessels with normalized metadata", async ()
|
||||
Map,
|
||||
console,
|
||||
});
|
||||
const runtime = await readFile(new URL("../../assets/web/generated/plugin-runtime.js", import.meta.url), "utf8");
|
||||
const runtime = await bundleEntry(new URL("../src/plugin-runtime.ts", import.meta.url));
|
||||
const source = await readFile(new URL("../../assets/web/generated/ais.js", import.meta.url), "utf8");
|
||||
new vm.Script(runtime).runInContext(context);
|
||||
new vm.Script(source).runInContext(context);
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import assert from "node:assert/strict";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import test from "node:test";
|
||||
import vm from "node:vm";
|
||||
import { bundleEntry } from "./bundle-entry.mjs";
|
||||
@@ -26,7 +25,7 @@ test("APRS entry normalizes positioned packets without remote symbol assets", as
|
||||
Reflect,
|
||||
console,
|
||||
});
|
||||
const runtime = await readFile(new URL("../../assets/web/generated/plugin-runtime.js", import.meta.url), "utf8");
|
||||
const runtime = await bundleEntry(new URL("../src/plugin-runtime.ts", import.meta.url));
|
||||
const source = await bundleEntry(new URL("../src/plugins/aprs.ts", import.meta.url));
|
||||
assert.equal(source.includes("raw.githubusercontent.com"), false);
|
||||
new vm.Script(runtime).runInContext(context);
|
||||
|
||||
@@ -6,6 +6,7 @@ import assert from "node:assert/strict";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import test from "node:test";
|
||||
import vm from "node:vm";
|
||||
import { bundleEntry } from "./bundle-entry.mjs";
|
||||
|
||||
class ElementFixture {
|
||||
constructor() { this.children = []; this.textContent = ""; this.style = {}; this.classList = { toggle() {} }; }
|
||||
@@ -37,7 +38,7 @@ test("CW entry appends server-decoded text and registers lifecycle callbacks", a
|
||||
Math,
|
||||
console,
|
||||
});
|
||||
const runtime = await readFile(new URL("../../assets/web/generated/plugin-runtime.js", import.meta.url), "utf8");
|
||||
const runtime = await bundleEntry(new URL("../src/plugin-runtime.ts", import.meta.url));
|
||||
const source = await readFile(new URL("../../assets/web/generated/cw.js", import.meta.url), "utf8");
|
||||
new vm.Script(runtime).runInContext(context);
|
||||
new vm.Script(source).runInContext(context);
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import assert from "node:assert/strict";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import test from "node:test";
|
||||
import vm from "node:vm";
|
||||
import { bundleEntry } from "./bundle-entry.mjs";
|
||||
@@ -30,7 +29,7 @@ test("FT2 entry normalizes audio offsets and registers typed callbacks", async (
|
||||
Array,
|
||||
console,
|
||||
});
|
||||
const runtime = await readFile(new URL("../../assets/web/generated/plugin-runtime.js", import.meta.url), "utf8");
|
||||
const runtime = await bundleEntry(new URL("../src/plugin-runtime.ts", import.meta.url));
|
||||
const source = await bundleEntry(new URL("../src/plugins/ft2.ts", import.meta.url));
|
||||
new vm.Script(runtime).runInContext(context);
|
||||
new vm.Script(source).runInContext(context);
|
||||
@@ -62,7 +61,7 @@ test("FT8 entry installs shared parsing without relying on script globals", asyn
|
||||
Set,
|
||||
console,
|
||||
});
|
||||
const runtime = await readFile(new URL("../../assets/web/generated/plugin-runtime.js", import.meta.url), "utf8");
|
||||
const runtime = await bundleEntry(new URL("../src/plugin-runtime.ts", import.meta.url));
|
||||
const source = await bundleEntry(new URL("../src/plugins/ft8.ts", import.meta.url));
|
||||
new vm.Script(runtime).runInContext(context);
|
||||
new vm.Script(source).runInContext(context);
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import assert from "node:assert/strict";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import test from "node:test";
|
||||
import vm from "node:vm";
|
||||
import { bundleEntry } from "./bundle-entry.mjs";
|
||||
@@ -22,7 +21,7 @@ test("HF APRS entry uses shared typed normalization and local symbols", async ()
|
||||
Reflect,
|
||||
console,
|
||||
});
|
||||
const runtime = await readFile(new URL("../../assets/web/generated/plugin-runtime.js", import.meta.url), "utf8");
|
||||
const runtime = await bundleEntry(new URL("../src/plugin-runtime.ts", import.meta.url));
|
||||
const source = await bundleEntry(new URL("../src/plugins/hf-aprs.ts", import.meta.url));
|
||||
assert.equal(source.includes("raw.githubusercontent.com"), false);
|
||||
new vm.Script(runtime).runInContext(context);
|
||||
|
||||
+2
-5
@@ -3,9 +3,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import assert from "node:assert/strict";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import test from "node:test";
|
||||
import vm from "node:vm";
|
||||
import { bundleEntry } from "./bundle-entry.mjs";
|
||||
|
||||
test("local AIS track-symbol adapter renders immediately on first add", async () => {
|
||||
const listeners = new Map();
|
||||
@@ -34,10 +34,7 @@ test("local AIS track-symbol adapter renders immediately on first add", async ()
|
||||
Util: { extend: Object.assign },
|
||||
divIcon: (options) => options,
|
||||
};
|
||||
const source = await readFile(
|
||||
new URL("../../assets/web/generated/leaflet-ais-tracksymbol.js", import.meta.url),
|
||||
"utf8",
|
||||
);
|
||||
const source = await bundleEntry(new URL("../src/leaflet-ais-tracksymbol.ts", import.meta.url));
|
||||
new vm.Script(source).runInNewContext({ L, console });
|
||||
Object.assign(L.TrxAisTrackSymbol.prototype, {
|
||||
onAdd: markerPrototype.onAdd,
|
||||
|
||||
+2
-2
@@ -3,14 +3,14 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import assert from "node:assert/strict";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import test from "node:test";
|
||||
import vm from "node:vm";
|
||||
import { bundleEntry } from "./bundle-entry.mjs";
|
||||
|
||||
test("plugin runtime queues lazy decoder traffic and flushes in order on registration", async () => {
|
||||
const window = {};
|
||||
const context = vm.createContext({ window, Map, Error });
|
||||
const source = await readFile(new URL("../../assets/web/generated/plugin-runtime.js", import.meta.url), "utf8");
|
||||
const source = await bundleEntry(new URL("../src/plugin-runtime.ts", import.meta.url));
|
||||
new vm.Script(source).runInContext(context);
|
||||
|
||||
assert.equal(window.trxPluginRuntime.dispatch("late", { sequence: 1 }), false);
|
||||
|
||||
@@ -6,6 +6,7 @@ import assert from "node:assert/strict";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import test from "node:test";
|
||||
import vm from "node:vm";
|
||||
import { bundleEntry } from "./bundle-entry.mjs";
|
||||
|
||||
test("satellite entry registers lifecycle callbacks and forwards georeferenced images", async () => {
|
||||
const overlays = [];
|
||||
@@ -26,7 +27,7 @@ test("satellite entry registers lifecycle callbacks and forwards georeferenced i
|
||||
Error,
|
||||
console,
|
||||
});
|
||||
const runtime = await readFile(new URL("../../assets/web/generated/plugin-runtime.js", import.meta.url), "utf8");
|
||||
const runtime = await bundleEntry(new URL("../src/plugin-runtime.ts", import.meta.url));
|
||||
const source = await readFile(new URL("../../assets/web/generated/sat.js", import.meta.url), "utf8");
|
||||
new vm.Script(runtime).runInContext(context);
|
||||
new vm.Script(source).runInContext(context);
|
||||
|
||||
@@ -10,10 +10,11 @@ const indexPath = new URL("../../assets/web/index.html", import.meta.url);
|
||||
const pluginLoaderPath = new URL("../src/plugin-loader.ts", import.meta.url);
|
||||
const mapCorePath = new URL("../src/map-core.ts", import.meta.url);
|
||||
|
||||
test("index loads the shared UI before the application", async () => {
|
||||
test("index loads one first-party application bootstrap", async () => {
|
||||
const html = await readFile(indexPath, "utf8");
|
||||
assert.ok(html.indexOf("/ui-core.js") < html.indexOf("/app.js"));
|
||||
assert.ok(html.indexOf("/plugin-loader.js") < html.indexOf("/app.js"));
|
||||
assert.equal((html.match(/<script[^>]+src="\/(?!vendor\/)[^"]+\.js"/g) ?? []).length, 1);
|
||||
assert.match(html, /src="\/app\.js"/);
|
||||
assert.doesNotMatch(html, /src="\/(?:ui-core|plugin-runtime|plugin-loader|webgl-renderer|leaflet-ais-tracksymbol)\.js"/);
|
||||
assert.equal(html.includes("var pluginScripts"), false);
|
||||
});
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import assert from "node:assert/strict";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import vm from "node:vm";
|
||||
import { bundleEntry } from "./bundle-entry.mjs";
|
||||
|
||||
class ClassList {
|
||||
constructor() { this.values = new Set(); }
|
||||
@@ -104,7 +104,7 @@ const context = vm.createContext({
|
||||
console,
|
||||
});
|
||||
|
||||
const source = await readFile(new URL("../../assets/web/generated/ui-core.js", import.meta.url), "utf8");
|
||||
const source = await bundleEntry(new URL("../src/ui-core.ts", import.meta.url));
|
||||
new vm.Script(source, { filename: "ui-core.js" }).runInContext(context);
|
||||
const ui = window.trxUi;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import assert from "node:assert/strict";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import test from "node:test";
|
||||
import vm from "node:vm";
|
||||
import { bundleEntry } from "./bundle-entry.mjs";
|
||||
|
||||
test("VDES entry normalizes and forwards positioned server messages", async () => {
|
||||
const forwarded = [];
|
||||
@@ -22,7 +23,7 @@ test("VDES entry normalizes and forwards positioned server messages", async () =
|
||||
Array,
|
||||
console,
|
||||
});
|
||||
const runtime = await readFile(new URL("../../assets/web/generated/plugin-runtime.js", import.meta.url), "utf8");
|
||||
const runtime = await bundleEntry(new URL("../src/plugin-runtime.ts", import.meta.url));
|
||||
const source = await readFile(new URL("../../assets/web/generated/vdes.js", import.meta.url), "utf8");
|
||||
new vm.Script(runtime).runInContext(context);
|
||||
new vm.Script(source).runInContext(context);
|
||||
|
||||
+2
-5
@@ -3,9 +3,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import assert from "node:assert/strict";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import test from "node:test";
|
||||
import vm from "node:vm";
|
||||
import { bundleEntry } from "./bundle-entry.mjs";
|
||||
|
||||
test("WebGL color helpers normalize CSS and HSL colors", async () => {
|
||||
const window = {};
|
||||
@@ -22,10 +22,7 @@ test("WebGL color helpers normalize CSS and HSL colors", async () => {
|
||||
String,
|
||||
parseInt,
|
||||
});
|
||||
const source = await readFile(
|
||||
new URL("../../assets/web/generated/webgl-renderer.js", import.meta.url),
|
||||
"utf8",
|
||||
);
|
||||
const source = await bundleEntry(new URL("../src/webgl-renderer.ts", import.meta.url));
|
||||
new vm.Script(source).runInContext(context);
|
||||
|
||||
assert.deepEqual(Array.from(window.trxParseCssColor("#ff800080")), [1, 128 / 255, 0, 128 / 255]);
|
||||
|
||||
@@ -6,6 +6,7 @@ import assert from "node:assert/strict";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import test from "node:test";
|
||||
import vm from "node:vm";
|
||||
import { bundleEntry } from "./bundle-entry.mjs";
|
||||
|
||||
test("WEFAX entry exposes typed lifecycle handlers and renders decoder state", async () => {
|
||||
const status = { textContent: "", style: { color: "" } };
|
||||
@@ -19,7 +20,7 @@ test("WEFAX entry exposes typed lifecycle handlers and renders decoder state", a
|
||||
Uint8Array,
|
||||
console,
|
||||
});
|
||||
const runtime = await readFile(new URL("../../assets/web/generated/plugin-runtime.js", import.meta.url), "utf8");
|
||||
const runtime = await bundleEntry(new URL("../src/plugin-runtime.ts", import.meta.url));
|
||||
const source = await readFile(new URL("../../assets/web/generated/wefax.js", import.meta.url), "utf8");
|
||||
new vm.Script(runtime).runInContext(context);
|
||||
new vm.Script(source).runInContext(context);
|
||||
|
||||
@@ -6,6 +6,7 @@ import assert from "node:assert/strict";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import test from "node:test";
|
||||
import vm from "node:vm";
|
||||
import { bundleEntry } from "./bundle-entry.mjs";
|
||||
|
||||
test("WSPR entry forwards decoded locators at their absolute frequency", async () => {
|
||||
const forwarded = [];
|
||||
@@ -25,7 +26,7 @@ test("WSPR entry forwards decoded locators at their absolute frequency", async (
|
||||
Element: class Element {},
|
||||
console,
|
||||
});
|
||||
const runtime = await readFile(new URL("../../assets/web/generated/plugin-runtime.js", import.meta.url), "utf8");
|
||||
const runtime = await bundleEntry(new URL("../src/plugin-runtime.ts", import.meta.url));
|
||||
const source = await readFile(new URL("../../assets/web/generated/wspr.js", import.meta.url), "utf8");
|
||||
new vm.Script(runtime).runInContext(context);
|
||||
new vm.Script(source).runInContext(context);
|
||||
|
||||
Reference in New Issue
Block a user