feat(extension): add Firefox WebExtension support
Testing / remote-protocol-compat (0.9.5) (push) Successful in 48s
Testing / remote-protocol-compat (0.9.3) (push) Successful in 47s
Build & Publish Package / publish (push) Successful in 46s
Package Extension / package-extension (push) Successful in 59s
Testing / test (push) Failing after 50s
Testing / remote-protocol-compat (0.9.5) (push) Successful in 48s
Testing / remote-protocol-compat (0.9.3) (push) Successful in 47s
Build & Publish Package / publish (push) Successful in 46s
Package Extension / package-extension (push) Successful in 59s
Testing / test (push) Failing after 50s
- Add a neutral WebExtension API adapter that uses Firefox browser.* or Chromium chrome.* without mutating globals. - Switch extension runtime code to the adapter and add Firefox-specific typings for tabs, windows, tab groups, storage, scripting, and native messaging ports. - Fix Firefox temporary add-on instructions to load the packaged manifest with background.scripts instead of the Chromium service worker manifest. - Detect Firefox in clients.list via runtime.getBrowserInfo and keep Chromium user-agent fallback support. - Make navigate.open wait briefly for Firefox to replace initial about:blank with the requested URL. - Add JS coverage for API selection, clients.list browser detection, and Firefox navigate.open URL polling. - Bump package and extension version to 0.15.2.
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import { webExtApi as api } from '../browser-api';
|
||||
/**
|
||||
* Background-job retention helpers + the JobManager that owns the live job map.
|
||||
*
|
||||
* `pruneFinishedJobs` / `MAX_FINISHED_JOBS` are kept free of chrome.* /
|
||||
* `pruneFinishedJobs` / `MAX_FINISHED_JOBS` are kept free of api.* /
|
||||
* service-worker side effects so the retention logic (memory-leak guard) can be
|
||||
* unit-tested in isolation.
|
||||
*/
|
||||
@@ -16,7 +17,7 @@ export const MAX_FINISHED_JOBS = 20;
|
||||
|
||||
// Watchdog: if a runner never resolves/rejects (e.g. executeScript against a
|
||||
// dead tab), finalize the job as an error so its persist interval stops instead
|
||||
// of writing to chrome.storage.local every second forever.
|
||||
// of writing to api.storage.local every second forever.
|
||||
export const JOB_TIMEOUT_MS = 5 * 60 * 1000;
|
||||
|
||||
/**
|
||||
@@ -65,11 +66,11 @@ export class JobManager {
|
||||
const running = all.filter(job => job.status === "running");
|
||||
const finished = all.filter(job => job.status !== "running").slice(-MAX_FINISHED_JOBS);
|
||||
const recentJobs = [...running, ...finished].map(({ __timer, __watchdog, ...rest }) => rest);
|
||||
await chrome.storage.local.set({ recentJobs });
|
||||
await api.storage.local.set({ recentJobs });
|
||||
}
|
||||
|
||||
// Evict the oldest finished jobs once their count exceeds the retention cap.
|
||||
// Recent finished jobs remain queryable via chrome.storage.local (persistJobs)
|
||||
// Recent finished jobs remain queryable via api.storage.local (persistJobs)
|
||||
// even after eviction from the in-memory Map.
|
||||
private pruneJobs() {
|
||||
pruneFinishedJobs(this.jobs, MAX_FINISHED_JOBS);
|
||||
@@ -143,7 +144,7 @@ export class JobManager {
|
||||
async status({ jobId }: { jobId?: string }) {
|
||||
const job = this.jobs.get(jobId);
|
||||
if (job) return { ...job };
|
||||
const { recentJobs } = await chrome.storage.local.get<{ recentJobs?: Job[] }>("recentJobs");
|
||||
const { recentJobs } = await api.storage.local.get<{ recentJobs?: Job[] }>("recentJobs");
|
||||
const stored = (recentJobs || []).find(entry => entry.id === jobId);
|
||||
if (!stored) throw new Error(`Job '${jobId}' not found`);
|
||||
return stored;
|
||||
|
||||
Reference in New Issue
Block a user