refactor: convert map feature to strict TypeScript
This commit is contained in:
+3034
-3043
File diff suppressed because it is too large
Load Diff
+1
-15
@@ -10,25 +10,11 @@ const pluginGroups = {
|
||||
};
|
||||
const loaded = /* @__PURE__ */ new Set();
|
||||
const loading = /* @__PURE__ */ new Map();
|
||||
const modulePlugins = /* @__PURE__ */ new Set(["/ft8.js", "/ft4.js", "/ft2.js", "/wspr.js", "/cw.js", "/vdes.js", "/wefax.js", "/background-decode.js", "/ais.js", "/aprs.js", "/hf-aprs.js", "/sat.js", "/sat-scheduler.js", "/vchan.js", "/bookmarks.js", "/scheduler.js"]);
|
||||
function loadLegacyScript(path) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const script = document.createElement("script");
|
||||
script.src = path;
|
||||
script.addEventListener("load", () => {
|
||||
resolve();
|
||||
}, { once: true });
|
||||
script.addEventListener("error", () => {
|
||||
reject(new Error(`Failed to load plugin script: ${path}`));
|
||||
}, { once: true });
|
||||
document.body.appendChild(script);
|
||||
});
|
||||
}
|
||||
async function loadPlugin(path) {
|
||||
if (loaded.has(path)) return;
|
||||
const pending = loading.get(path);
|
||||
if (pending) return pending;
|
||||
const request = (modulePlugins.has(path) ? import(path).then(() => void 0) : loadLegacyScript(path)).then(() => {
|
||||
const request = import(path).then(() => {
|
||||
loaded.add(path);
|
||||
loading.delete(path);
|
||||
}).catch((error) => {
|
||||
|
||||
@@ -18,7 +18,6 @@ await build({
|
||||
"api-client": path.join(sourceDir, "api", "client.ts"),
|
||||
app: path.join(sourceDir, "app.js"),
|
||||
"ui-core": path.join(sourceDir, "ui-core.ts"),
|
||||
"map-core": path.join(sourceDir, "map-core.js"),
|
||||
"plugin-loader": path.join(sourceDir, "plugin-loader.ts"),
|
||||
"plugin-runtime": path.join(sourceDir, "plugin-runtime.ts"),
|
||||
screenshot: path.join(sourceDir, "screenshot.ts"),
|
||||
@@ -52,6 +51,7 @@ await build({
|
||||
vchan: path.join(sourceDir, "plugins", "vchan.ts"),
|
||||
bookmarks: path.join(sourceDir, "plugins", "bookmarks.ts"),
|
||||
scheduler: path.join(sourceDir, "plugins", "scheduler.ts"),
|
||||
"map-core": path.join(sourceDir, "map-core.ts"),
|
||||
},
|
||||
outdir: outputDir,
|
||||
bundle: true,
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"version": "0.1.0",
|
||||
"devDependencies": {
|
||||
"@eslint/js": "9.39.2",
|
||||
"@types/leaflet": "1.9.22",
|
||||
"esbuild": "0.25.12",
|
||||
"eslint": "9.39.2",
|
||||
"globals": "16.5.0",
|
||||
@@ -691,6 +692,13 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/geojson": {
|
||||
"version": "7946.0.16",
|
||||
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz",
|
||||
"integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/json-schema": {
|
||||
"version": "7.0.15",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
|
||||
@@ -698,6 +706,16 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/leaflet": {
|
||||
"version": "1.9.22",
|
||||
"resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.22.tgz",
|
||||
"integrity": "sha512-h3lhECYEKDasG7LFHu+GiHqAvsgLuQvlJvVZzJDGONo3sEL+wUOqSFLnwkZlK0qVxnxbuGFW8iBlJNYs5wgndA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/geojson": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||
"version": "8.51.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.51.0.tgz",
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "9.39.2",
|
||||
"@types/leaflet": "1.9.22",
|
||||
"esbuild": "0.25.12",
|
||||
"eslint": "9.39.2",
|
||||
"globals": "16.5.0",
|
||||
|
||||
+537
-379
File diff suppressed because it is too large
Load Diff
@@ -16,23 +16,11 @@ const pluginGroups: Readonly<Record<PluginGroup, readonly string[]>> = {
|
||||
|
||||
const loaded = new Set<string>();
|
||||
const loading = new Map<string, Promise<void>>();
|
||||
const modulePlugins = new Set(["/ft8.js", "/ft4.js", "/ft2.js", "/wspr.js", "/cw.js", "/vdes.js", "/wefax.js", "/background-decode.js", "/ais.js", "/aprs.js", "/hf-aprs.js", "/sat.js", "/sat-scheduler.js", "/vchan.js", "/bookmarks.js", "/scheduler.js"]);
|
||||
|
||||
function loadLegacyScript(path: string): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const script = document.createElement("script");
|
||||
script.src = path;
|
||||
script.addEventListener("load", () => { resolve(); }, { once: true });
|
||||
script.addEventListener("error", () => { reject(new Error(`Failed to load plugin script: ${path}`)); }, { once: true });
|
||||
document.body.appendChild(script);
|
||||
});
|
||||
}
|
||||
|
||||
async function loadPlugin(path: string): Promise<void> {
|
||||
if (loaded.has(path)) return;
|
||||
const pending = loading.get(path);
|
||||
if (pending) return pending;
|
||||
const request = (modulePlugins.has(path) ? import(path).then(() => undefined) : loadLegacyScript(path)).then(() => {
|
||||
const request = import(path).then(() => {
|
||||
loaded.add(path);
|
||||
loading.delete(path);
|
||||
}).catch((error: unknown) => {
|
||||
|
||||
@@ -7,6 +7,8 @@ import test from "node:test";
|
||||
import { readFile } from "node:fs/promises";
|
||||
|
||||
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 () => {
|
||||
const html = await readFile(indexPath, "utf8");
|
||||
@@ -26,3 +28,14 @@ test("startup has no remote script or stylesheet dependencies", async () => {
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
test("lazy frontend features use modules and local map symbols", async () => {
|
||||
const [loader, map] = await Promise.all([
|
||||
readFile(pluginLoaderPath, "utf8"),
|
||||
readFile(mapCorePath, "utf8"),
|
||||
]);
|
||||
assert.equal(loader.includes("createElement(\"script\")"), false);
|
||||
assert.match(loader, /import\(path\)/);
|
||||
assert.match(map, /aprs-symbol-local/);
|
||||
assert.equal(map.includes("raw.githubusercontent.com"), false);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user