Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions src/app/service/service_worker/dnr.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* scheduler 用于 Service Worker 或 Event Page, Chrome 94+, Firefox 142+
*/
const scheduler_ =
typeof scheduler !== "undefined" &&
typeof scheduler?.postTask === "function" &&
typeof scheduler?.yield === "function"
? scheduler
: null;

// 用于扩充初始化时新增 SessionRules. FireFox 需要等一等才加,否则会失效。
export const addSessionRules = async (rules: chrome.declarativeNetRequest.Rule[]) => {
await scheduler_?.yield?.();
try {
await chrome.declarativeNetRequest.updateSessionRules({
removeRuleIds: [...rules.map((rule) => rule.id)],
addRules: rules,
});
return true;
} catch (e) {
console.error("chrome.declarativeNetRequest.updateSessionRules:", e);
return e;
}
};

export const sessionRuleDynamicAdd = async (rule: chrome.declarativeNetRequest.Rule): Promise<any> => {
try {
await chrome.declarativeNetRequest.updateSessionRules({
removeRuleIds: [rule.id],
addRules: [rule],
});
return true;
} catch (e) {
console.error("chrome.declarativeNetRequest.updateSessionRules:", e);
return e;
}
};

export const sessionRuleDynamicRemove = async (ruleId: number): Promise<any> => {
try {
await chrome.declarativeNetRequest.updateSessionRules({
removeRuleIds: [ruleId],
});
return true;
} catch (e) {
console.error("chrome.declarativeNetRequest.updateSessionRules:", e);
return e;
}
};
43 changes: 10 additions & 33 deletions src/app/service/service_worker/gm_api/gm_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
import type { DownloadCallback } from "../download";
import { detachDownloadCallback, startDownload } from "../download";
import { isRequestInitiatorOriginMatched, gmXhrRequestLinker, type IWebRequestDetails } from "./mv3_utils";
import { addSessionRules, sessionRuleDynamicAdd, sessionRuleDynamicRemove } from "../dnr";

Check failure on line 61 in src/app/service/service_worker/gm_api/gm_api.ts

View workflow job for this annotation

GitHub Actions / Run tests

'addSessionRules' is defined but never used. Allowed unused vars must match /^_/u

let generatedUniqueMarkerIDs = "";
let generatedUniqueMarkerIDWhen = "";
Expand Down Expand Up @@ -90,20 +91,11 @@
headerModifierMap.delete(markerID);
}
if (ruleID) {
chrome.declarativeNetRequest.updateSessionRules(
{
removeRuleIds: [ruleID],
},
() => {
const lastError = chrome.runtime.lastError;
if (lastError) {
// removeRuleIds 失败: 浏览器里仍保留该规则,本地不释放 ruleID 避免复用
console.error("chrome.declarativeNetRequest.updateSessionRules:", lastError);
return;
}
removeSessionRuleIdEntry(ruleID);
}
);
sessionRuleDynamicRemove(ruleID).then((removeResult) => {
// removeRuleIds 失败: 浏览器里仍保留该规则,本地不释放 ruleID 避免复用
if (removeResult !== true) return;
removeSessionRuleIdEntry(ruleID);
});
}
};

Expand Down Expand Up @@ -748,16 +740,12 @@
},
} as chrome.declarativeNetRequest.Rule;
headerModifierMap.set(markerID, { rule, redirectNotManual });
try {
await chrome.declarativeNetRequest.updateSessionRules({
removeRuleIds: [ruleId],
addRules: [rule],
});
} catch (e) {
const addResult = await sessionRuleDynamicAdd(rule);
if (addResult !== true) {
// addRules 失败: 回滚本地 headerModifierMap 关联并释放 ruleId,避免永久占位导致限额锁死
headerModifierMap.delete(markerID);
removeSessionRuleIdEntry(ruleId);
throw e;
throw addResult;
}
}
return true;
Expand Down Expand Up @@ -1664,18 +1652,7 @@
},
};
headerModifierMap.set(markerID, { rule: newRule, redirectNotManual });
chrome.declarativeNetRequest.updateSessionRules(
{
removeRuleIds: [rule.id],
addRules: [newRule],
},
() => {
const lastError = chrome.runtime.lastError;
if (lastError) {
console.error("chrome.declarativeNetRequest.updateSessionRules:", lastError);
}
}
);
sessionRuleDynamicAdd(newRule);
return;
}
}
Expand Down
14 changes: 2 additions & 12 deletions src/app/service/service_worker/gm_api/mv3_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { stackAsyncTask } from "@App/pkg/utils/async_queue";
import { isFirefox } from "@App/pkg/utils/utils";
import { type FetchXHR } from "@App/pkg/utils/xhr/fetch_xhr";
import { scXhrRequests } from "./gm_xhr";
import { sessionRuleDynamicAdd } from "../dnr";

const bFirefox = isFirefox();
type TbgMarkerMapEntry = {
Expand Down Expand Up @@ -175,18 +176,7 @@ export class ChromiumHeaderMarkerLinker implements GmXhrRequestLinker {
tabIds: [chrome.tabs.TAB_ID_NONE], // 只限于后台 service_worker / offscreen
},
} as chrome.declarativeNetRequest.Rule;
chrome.declarativeNetRequest.updateSessionRules(
{
removeRuleIds: [ruleId],
addRules: [rule],
},
() => {
const lastError = chrome.runtime.lastError;
if (lastError) {
console.error("chrome.declarativeNetRequest.updateSessionRules:", lastError);
}
}
);
sessionRuleDynamicAdd(rule);
}

prepareRequest(_details: GMSend.XHRDetails, headers: { [key: string]: string }, markerID: string) {
Expand Down
16 changes: 2 additions & 14 deletions src/app/service/service_worker/script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import { LocalStorageDAO } from "@App/app/repo/localStorage";
import { CompiledResourceDAO } from "@App/app/repo/resource";
import { initRegularUpdateCheck } from "./regular_updatecheck";
import { TempStorageDAO, TempStorageItemType } from "@App/app/repo/tempStorage";
import { addSessionRules } from "./dnr";

export type TCheckScriptUpdateOption = Partial<
{ checkType: "user"; noUpdateCheck?: number } | ({ checkType: "system" } & Record<string, any>)
Expand Down Expand Up @@ -298,20 +299,7 @@ export class ScriptService {
}
}
);
chrome.declarativeNetRequest.updateSessionRules(
{
removeRuleIds: [...rules.map((rule) => rule.id)],
addRules: rules,
},
() => {
if (chrome.runtime.lastError) {
console.error(
"chrome.runtime.lastError in chrome.declarativeNetRequest.updateSessionRules:",
chrome.runtime.lastError
);
}
}
);
addSessionRules(rules);
}

public async openInstallPageByUrl(
Expand Down
14 changes: 14 additions & 0 deletions src/types/main.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@ declare module "@App/app/types.d.ts";
type Override<T, U> = Omit<T, keyof U> & U;
type ValueOf<T> = T[keyof T];
type ReactStateSetter<T> = (value: T | ((prev: T) => T)) => void;
type ResolveFn<T = void> = (val: T) => void;

interface SchedulerPostTaskOptions {
delay?: number;
priority?: "user-blocking" | "user-visible" | "background";
signal?: AbortSignal;
}

interface Scheduler {
postTask<T>(callback: () => T | Promise<T>, options?: SchedulerPostTaskOptions): Promise<T>;
yield(): Promise<void>;
}

declare let scheduler: Scheduler | undefined;

declare const sandbox: Window;

Expand Down
Loading