Skip to content

Commit 8782e1c

Browse files
committed
feat: optimize DNR rule id generate
1 parent e40f591 commit 8782e1c

1 file changed

Lines changed: 35 additions & 59 deletions

File tree

src/pages/background/request-handler/dnr-handler.ts

Lines changed: 35 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import browser from 'webextension-polyfill';
2-
import { RULE_MATCH_TYPE, RULE_TYPE } from '@/share/core/constant';
2+
import { RULE_MATCH_TYPE, RULE_TYPE, TABLE_NAMES } from '@/share/core/constant';
33
import emitter from '@/share/core/emitter';
44
import { prefs } from '@/share/core/prefs';
55
import { detectRunner } from '@/share/core/rule-utils';
66
import type { Rule, RULE_ACTION_OBJ } from '@/share/core/types';
7-
import { getVirtualKey } from '@/share/core/utils';
8-
import { getAll } from '../core/rules';
7+
import { getTableName } from '@/share/core/utils';
8+
import { getAll, waitLoad } from '../core/rules';
99
import type { DeclarativeNetRequest } from 'webextension-polyfill/namespaces/declarativeNetRequest';
1010

1111
type DNRRule = DeclarativeNetRequest.Rule;
@@ -98,9 +98,20 @@ function createDNR(rule: Rule, id: number) {
9898
return res;
9999
}
100100

101+
function getRuleId(id: number, table?: TABLE_NAMES, ruleType?: RULE_TYPE) {
102+
const list = {
103+
[TABLE_NAMES.request]: 0,
104+
[TABLE_NAMES.sendHeader]: 10000,
105+
[TABLE_NAMES.receiveHeader]: 20000,
106+
[TABLE_NAMES.receiveBody]: 30000,
107+
};
108+
109+
const t = table || getTableName(ruleType || RULE_TYPE.REDIRECT);
110+
111+
return Number(id) + list[t];
112+
}
113+
101114
class DNRRequestHandler {
102-
private lastRuleId = 1;
103-
private ruleIdMap: Map<string, number> = new Map();
104115
private _disableAll = false;
105116

106117
constructor() {
@@ -126,45 +137,31 @@ class DNRRequestHandler {
126137
}
127138

128139
private async clearRules() {
129-
const ids = Array.from(this.ruleIdMap.values());
140+
const current = await browser.declarativeNetRequest.getSessionRules();
130141
await browser.declarativeNetRequest.updateSessionRules({
131-
removeRuleIds: ids,
142+
removeRuleIds: current.map((x) => x.id),
132143
});
133-
this.ruleIdMap.clear();
134144
}
135145

136146
private async initRules() {
137-
const v = Object.values(getAll());
147+
await waitLoad();
138148

139-
if (v.some((x) => x === null)) {
140-
// rule not ready
141-
setTimeout(() => this.initRules());
142-
return;
143-
}
149+
const v = Object.values(getAll());
144150

145151
// if service worker restart, get exists rules
146-
if (MANIFEST_VER === 'v3') {
147-
const data: any = (await browser.storage.session.get('dnr_handler')).dnr_handler;
148-
if (data) {
149-
this.lastRuleId = data.lastRuleId || 1;
150-
Object.entries(data.ruleIdMap || {}).forEach(([key, val]) => {
151-
this.ruleIdMap.set(key, Number(val));
152-
});
153-
} else {
154-
// clear all exists rules
155-
await this.clearRules();
156-
}
157-
}
158-
152+
const current = (await browser.declarativeNetRequest.getSessionRules()).map((x) => x.id);
159153
const allRules = v.reduce((a, b) => [...a!, ...b!], []) || [];
160154
const addRules: DNRRule[] = [];
161155
allRules.forEach((rule) => {
162156
if (rule._runner !== 'dnr') {
163157
return;
164158
}
165-
const newRuleId = this.lastRuleId++;
166-
this.ruleIdMap.set(getVirtualKey(rule), newRuleId);
167-
addRules.push(createDNR(rule, newRuleId));
159+
const ruleId = getRuleId(rule.id, undefined, rule.ruleType);
160+
if (current.includes(ruleId)) {
161+
// rule exists
162+
return;
163+
}
164+
addRules.push(createDNR(rule, ruleId));
168165
});
169166
if (IS_DEV) {
170167
console.log('init dnr rules', addRules);
@@ -173,43 +170,33 @@ class DNRRequestHandler {
173170
browser.declarativeNetRequest.updateSessionRules({
174171
addRules,
175172
});
176-
this.updateStorage();
177173
}
178174
}
179175

180176
private initHook() {
181177
emitter.on(emitter.INNER_RULE_REMOVE, ({ table, id }) => {
182-
const old = this.ruleIdMap.get(`${table}-${id}`);
183-
if (typeof old === 'number') {
184-
browser.declarativeNetRequest.updateSessionRules({
185-
removeRuleIds: [old],
186-
});
187-
this.ruleIdMap.delete(`${table}-${id}`);
188-
this.updateStorage();
189-
}
178+
const old = getRuleId(id, table);
179+
browser.declarativeNetRequest.updateSessionRules({
180+
removeRuleIds: [old],
181+
});
190182
});
191183

192-
emitter.on(emitter.INNER_RULE_UPDATE, ({ from, target }) => {
184+
emitter.on(emitter.INNER_RULE_UPDATE, ({ from, target }: { from: Rule; target: Rule }) => {
193185
const command: DeclarativeNetRequest.UpdateSessionRulesOptionsType = {
194186
removeRuleIds: [],
195187
addRules: [],
196188
};
197189
if (from) {
198-
const old = this.ruleIdMap.get(getVirtualKey(from));
199-
if (typeof old === 'number') {
200-
command.removeRuleIds!.push(old);
201-
}
190+
const old = getRuleId(from.id, undefined, from.ruleType);
191+
command.removeRuleIds!.push(old);
202192
}
203193
// detect new rule is DNR or not
204194
if (detectRunner(target) === 'dnr') {
205-
const newRuleId = this.lastRuleId++;
206-
this.ruleIdMap.set(getVirtualKey(target), newRuleId);
207-
command.addRules!.push(createDNR(target, newRuleId));
195+
command.addRules!.push(createDNR(target, getRuleId(target.id, undefined, target.ruleType)));
208196
}
209197
if (IS_DEV) {
210198
console.log('dnr rules update', command);
211199
}
212-
this.updateStorage();
213200
browser.declarativeNetRequest.updateSessionRules(command);
214201
});
215202
}
@@ -229,17 +216,6 @@ class DNRRequestHandler {
229216
this.disableAll = Boolean(prefs.get('disable-all'));
230217
});
231218
}
232-
233-
private updateStorage() {
234-
if (MANIFEST_VER === 'v3') {
235-
browser.storage.session.set({
236-
dnr_handler: {
237-
lastRuleId: this.lastRuleId,
238-
ruleIdMap: Object.fromEntries(this.ruleIdMap),
239-
},
240-
});
241-
}
242-
}
243219
}
244220

245221
export const createDNRHandler = () => new DNRRequestHandler();

0 commit comments

Comments
 (0)