mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-16 08:27:07 +00:00
Fix crxjs dev service worker crashes after Vite upgrade.
Downgrade to Vite 6 with crxjs 2.6, add dev-only CSP for HMR, and stop the background script from importing Svelte plugin UI into the service worker.
This commit is contained in:
+3
-3
@@ -42,7 +42,7 @@
|
|||||||
"@babel/plugin-transform-runtime": "^7.26.9",
|
"@babel/plugin-transform-runtime": "^7.26.9",
|
||||||
"@babel/runtime": "^7.26.9",
|
"@babel/runtime": "^7.26.9",
|
||||||
"@bedframe/cli": "^0.1.2",
|
"@bedframe/cli": "^0.1.2",
|
||||||
"@crxjs/vite-plugin": "^2.4.0",
|
"@crxjs/vite-plugin": "^2.6.1",
|
||||||
"@types/d3-scale": "^4.0.9",
|
"@types/d3-scale": "^4.0.9",
|
||||||
"@types/d3-shape": "^3.1.8",
|
"@types/d3-shape": "^3.1.8",
|
||||||
"@types/jest": "^30.0.0",
|
"@types/jest": "^30.0.0",
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
"@codemirror/search": "^6.5.10",
|
"@codemirror/search": "^6.5.10",
|
||||||
"@codemirror/state": "^6.5.2",
|
"@codemirror/state": "^6.5.2",
|
||||||
"@codemirror/view": "^6.36.4",
|
"@codemirror/view": "^6.36.4",
|
||||||
"@sveltejs/vite-plugin-svelte": "^7.0.0",
|
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
||||||
"@tailwindcss/forms": "^0.5.10",
|
"@tailwindcss/forms": "^0.5.10",
|
||||||
"@tsconfig/svelte": "^5.0.4",
|
"@tsconfig/svelte": "^5.0.4",
|
||||||
"@types/chrome": "^0.1.4",
|
"@types/chrome": "^0.1.4",
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
"svelte": "^5.46.4",
|
"svelte": "^5.46.4",
|
||||||
"typescript": "^5.8.2",
|
"typescript": "^5.8.2",
|
||||||
"uuid": "^11.1.0",
|
"uuid": "^11.1.0",
|
||||||
"vite": "^8.0.5",
|
"vite": "^6.2.1",
|
||||||
"webextension-polyfill": "^0.12.0"
|
"webextension-polyfill": "^0.12.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/**
|
||||||
|
* Serializable plugin setting defaults for cloud sync backfill.
|
||||||
|
*
|
||||||
|
* Kept separate from `@/plugins` so the service worker never imports Svelte UI or
|
||||||
|
* Vite HMR clients. Values must match each plugin's non-component settings.
|
||||||
|
*/
|
||||||
|
function defaultSearchHotkey(): string {
|
||||||
|
if (typeof navigator !== "undefined") {
|
||||||
|
return navigator.platform.toUpperCase().includes("MAC") ? "cmd+k" : "ctrl+k";
|
||||||
|
}
|
||||||
|
return "ctrl+k";
|
||||||
|
}
|
||||||
|
|
||||||
|
/** `plugin.<id>.settings` defaults (component/button keys omitted). */
|
||||||
|
export const SYNCABLE_PLUGIN_SETTING_DEFAULTS: Record<
|
||||||
|
string,
|
||||||
|
Record<string, unknown>
|
||||||
|
> = {
|
||||||
|
themes: {},
|
||||||
|
"animated-background": { speed: 1 },
|
||||||
|
"assessments-average": { lettergrade: false },
|
||||||
|
notificationCollector: {},
|
||||||
|
timetable: {},
|
||||||
|
timetableEdit: {},
|
||||||
|
"profile-picture": { useCloudPfp: false },
|
||||||
|
"assessments-overview": {},
|
||||||
|
"background-music": { volume: 0.5, pauseOnHidden: true },
|
||||||
|
messageFolders: {
|
||||||
|
showTagsInAllMessages: true,
|
||||||
|
hideFolderedMessagesInAll: true,
|
||||||
|
},
|
||||||
|
"enhanced-navigation": { autoScrollOnClick: false },
|
||||||
|
"global-search": {
|
||||||
|
searchHotkey: defaultSearchHotkey(),
|
||||||
|
showRecentFirst: true,
|
||||||
|
transparencyEffects: true,
|
||||||
|
runIndexingOnLoad: true,
|
||||||
|
passiveIndexing: true,
|
||||||
|
},
|
||||||
|
"grade-analytics": { cacheTtlHours: 24 },
|
||||||
|
};
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import browser from "webextension-polyfill";
|
import browser from "webextension-polyfill";
|
||||||
import { getAllPluginSettings } from "@/plugins";
|
import { SYNCABLE_PLUGIN_SETTING_DEFAULTS } from "@/plugins/syncablePluginDefaults";
|
||||||
import { getDefaultSettingsState } from "@/seqta/utils/defaultSettings";
|
import { getDefaultSettingsState } from "@/seqta/utils/defaultSettings";
|
||||||
import {
|
import {
|
||||||
isKeyIncludedInCloudUploadPayload,
|
isKeyIncludedInCloudUploadPayload,
|
||||||
@@ -38,18 +38,6 @@ const OPTIONAL_UNSET_MEANS_DEFAULT_KEYS = [
|
|||||||
"profile_picture_revision",
|
"profile_picture_revision",
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
function buildDefaultPluginSettings(
|
|
||||||
plugin: ReturnType<typeof getAllPluginSettings>[number],
|
|
||||||
): Record<string, unknown> {
|
|
||||||
const out: Record<string, unknown> = {};
|
|
||||||
for (const [key, setting] of Object.entries(plugin.settings)) {
|
|
||||||
const meta = setting as { type?: string; default?: unknown };
|
|
||||||
if (meta.type === "component" || meta.type === "button") continue;
|
|
||||||
out[key] = meta.default;
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flat default map in upload shape (plugin-format only; no legacy keys).
|
* Flat default map in upload shape (plugin-format only; no legacy keys).
|
||||||
*/
|
*/
|
||||||
@@ -65,9 +53,10 @@ export function getSyncableStorageDefaults(): Record<string, unknown> {
|
|||||||
delete flat[key];
|
delete flat[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const plugin of getAllPluginSettings()) {
|
for (const [pluginId, settings] of Object.entries(
|
||||||
flat[`plugin.${plugin.pluginId}.settings`] =
|
SYNCABLE_PLUGIN_SETTING_DEFAULTS,
|
||||||
buildDefaultPluginSettings(plugin);
|
)) {
|
||||||
|
flat[`plugin.${pluginId}.settings`] = settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
return flat;
|
return flat;
|
||||||
|
|||||||
+38
-4
@@ -4,7 +4,7 @@ import { join, resolve } from "path";
|
|||||||
import touchGlobalCSSPlugin from "./lib/touchGlobalCSS";
|
import touchGlobalCSSPlugin from "./lib/touchGlobalCSS";
|
||||||
import InlineWorkerPlugin from "./lib/inlineWorker";
|
import InlineWorkerPlugin from "./lib/inlineWorker";
|
||||||
import { base64Loader } from "./lib/base64loader";
|
import { base64Loader } from "./lib/base64loader";
|
||||||
import type { BuildTarget } from "./lib/types";
|
import type { BuildTarget, Manifest } from "./lib/types";
|
||||||
import ClosePlugin from "./lib/closePlugin";
|
import ClosePlugin from "./lib/closePlugin";
|
||||||
import { firefoxStripFunctionProbe } from "./lib/firefoxStripFunctionProbe";
|
import { firefoxStripFunctionProbe } from "./lib/firefoxStripFunctionProbe";
|
||||||
|
|
||||||
@@ -22,6 +22,37 @@ import { crx } from "@crxjs/vite-plugin";
|
|||||||
|
|
||||||
const targets: BuildTarget[] = [chrome, brave, edge, firefox, opera, safari];
|
const targets: BuildTarget[] = [chrome, brave, edge, firefox, opera, safari];
|
||||||
|
|
||||||
|
const DEV_SERVER_PORT = 5173;
|
||||||
|
|
||||||
|
/** Vite HMR needs localhost script + ws origins; only applied during `vite dev`. */
|
||||||
|
function withDevManifestCsp(manifest: Manifest, command: string): Manifest {
|
||||||
|
if (command !== "serve") return manifest;
|
||||||
|
|
||||||
|
const extensionPages = manifest.content_security_policy?.extension_pages;
|
||||||
|
if (!extensionPages) return manifest;
|
||||||
|
|
||||||
|
const localhost = `http://localhost:${DEV_SERVER_PORT}`;
|
||||||
|
const localhostWs = `ws://localhost:${DEV_SERVER_PORT}`;
|
||||||
|
const loopback = `http://127.0.0.1:${DEV_SERVER_PORT}`;
|
||||||
|
const loopbackWs = `ws://127.0.0.1:${DEV_SERVER_PORT}`;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...manifest,
|
||||||
|
content_security_policy: {
|
||||||
|
...manifest.content_security_policy,
|
||||||
|
extension_pages: extensionPages
|
||||||
|
.replace(
|
||||||
|
"script-src 'self'",
|
||||||
|
`script-src 'self' ${localhost} ${loopback}`,
|
||||||
|
)
|
||||||
|
.replace(
|
||||||
|
/connect-src ([^;]+)/,
|
||||||
|
`connect-src $1 ${localhost} ${localhostWs} ${loopback} ${loopbackWs}`,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const mode = process.env.MODE || "chrome"; // Check the environment variable to determine which build type to use.
|
const mode = process.env.MODE || "chrome"; // Check the environment variable to determine which build type to use.
|
||||||
//const sourcemap = (process.env.SOURCEMAP === "true") || false; // Check whether we want sourcemaps.
|
//const sourcemap = (process.env.SOURCEMAP === "true") || false; // Check whether we want sourcemaps.
|
||||||
/** Million's compiler can emit `new Function()`, which Firefox extension pages block (strict CSP, no unsafe-eval). */
|
/** Million's compiler can emit `new Function()`, which Firefox extension pages block (strict CSP, no unsafe-eval). */
|
||||||
@@ -46,9 +77,11 @@ export default defineConfig(({ command }) => ({
|
|||||||
}),
|
}),
|
||||||
...(useMillion ? [million.vite({ auto: true })] : []),
|
...(useMillion ? [million.vite({ auto: true })] : []),
|
||||||
crx({
|
crx({
|
||||||
manifest:
|
manifest: withDevManifestCsp(
|
||||||
targets.find((t) => t.browser === mode.toLowerCase())?.manifest ??
|
targets.find((t) => t.browser === mode.toLowerCase())?.manifest ??
|
||||||
chrome.manifest,
|
chrome.manifest,
|
||||||
|
command,
|
||||||
|
),
|
||||||
browser: mode.toLowerCase() === "firefox" ? "firefox" : "chrome",
|
browser: mode.toLowerCase() === "firefox" ? "firefox" : "chrome",
|
||||||
}),
|
}),
|
||||||
touchGlobalCSSPlugin(),
|
touchGlobalCSSPlugin(),
|
||||||
@@ -61,11 +94,12 @@ export default defineConfig(({ command }) => ({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
port: 5173,
|
port: DEV_SERVER_PORT,
|
||||||
|
strictPort: true,
|
||||||
hmr: {
|
hmr: {
|
||||||
host: "localhost",
|
host: "localhost",
|
||||||
protocol: "ws",
|
protocol: "ws",
|
||||||
port: 5173,
|
port: DEV_SERVER_PORT,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
css: {
|
css: {
|
||||||
|
|||||||
Reference in New Issue
Block a user