mirror of
https://github.com/yaklang/yaklang-chrome-extension.git
synced 2026-09-26 21:21:53 +08:00
use indexedDB manager proxySwitch
This commit is contained in:
+116
@@ -0,0 +1,116 @@
|
||||
class Database {
|
||||
constructor() {
|
||||
this.DB_NAME = 'yaklang_extension';
|
||||
this.DB_VERSION = 1;
|
||||
this.stores = {
|
||||
PROXY_LOGS: 'proxy_logs',
|
||||
PROXY_CONFIGS: 'proxy_configs',
|
||||
CURRENT_PROXY: 'current_proxy',
|
||||
PROXY_AUTH: 'proxy_auth'
|
||||
};
|
||||
}
|
||||
|
||||
async initDB() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = indexedDB.open(this.DB_NAME, this.DB_VERSION);
|
||||
|
||||
request.onerror = () => reject(request.error);
|
||||
request.onsuccess = () => resolve(request.result);
|
||||
|
||||
request.onupgradeneeded = (event) => {
|
||||
const db = event.target.result;
|
||||
|
||||
// 代理日志存储
|
||||
if (!db.objectStoreNames.contains(this.stores.PROXY_LOGS)) {
|
||||
const logsStore = db.createObjectStore(this.stores.PROXY_LOGS, { keyPath: 'id' });
|
||||
logsStore.createIndex('timestamp', 'timestamp');
|
||||
logsStore.createIndex('resourceType', 'resourceType');
|
||||
logsStore.createIndex('status', 'status');
|
||||
}
|
||||
|
||||
// 代理配置列表存储
|
||||
if (!db.objectStoreNames.contains(this.stores.PROXY_CONFIGS)) {
|
||||
const configsStore = db.createObjectStore(this.stores.PROXY_CONFIGS, { keyPath: 'id' });
|
||||
configsStore.createIndex('name', 'name');
|
||||
configsStore.createIndex('enabled', 'enabled');
|
||||
}
|
||||
|
||||
// 当前代理配置存储
|
||||
if (!db.objectStoreNames.contains(this.stores.CURRENT_PROXY)) {
|
||||
db.createObjectStore(this.stores.CURRENT_PROXY);
|
||||
}
|
||||
|
||||
// 代理认证信息存储
|
||||
if (!db.objectStoreNames.contains(this.stores.PROXY_AUTH)) {
|
||||
const authStore = db.createObjectStore(this.stores.PROXY_AUTH, { keyPath: 'id' });
|
||||
authStore.createIndex('host', 'host');
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async getStore(storeName, mode = 'readonly') {
|
||||
const db = await this.initDB();
|
||||
const tx = db.transaction(storeName, mode);
|
||||
return tx.objectStore(storeName);
|
||||
}
|
||||
|
||||
// 通用的 CRUD 操作
|
||||
async get(storeName, key) {
|
||||
const store = await this.getStore(storeName);
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = store.get(key);
|
||||
request.onsuccess = () => resolve(request.result);
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
}
|
||||
|
||||
async getAll(storeName) {
|
||||
const store = await this.getStore(storeName);
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = store.getAll();
|
||||
request.onsuccess = () => resolve(request.result);
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
}
|
||||
|
||||
async put(storeName, value, key = undefined) {
|
||||
try {
|
||||
const store = await this.getStore(storeName, 'readwrite');
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = key ? store.put(value, key) : store.put(value);
|
||||
request.onsuccess = () => {
|
||||
console.log(`Successfully put data in ${storeName}:`, value);
|
||||
resolve(request.result);
|
||||
};
|
||||
request.onerror = () => {
|
||||
console.error(`Error putting data in ${storeName}:`, request.error);
|
||||
reject(request.error);
|
||||
};
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(`Error in put operation for ${storeName}:`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async delete(storeName, key) {
|
||||
const store = await this.getStore(storeName, 'readwrite');
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = store.delete(key);
|
||||
request.onsuccess = () => resolve();
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
}
|
||||
|
||||
async clear(storeName) {
|
||||
const store = await this.getStore(storeName, 'readwrite');
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = store.clear();
|
||||
request.onsuccess = () => resolve();
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const db = new Database();
|
||||
@@ -0,0 +1,137 @@
|
||||
import { db } from './db.js';
|
||||
|
||||
class ProxyStore {
|
||||
constructor() {
|
||||
this.MAX_LOGS = 1000;
|
||||
}
|
||||
|
||||
// 代理配置相关操作
|
||||
async getProxyConfigs() {
|
||||
return await db.getAll(db.stores.PROXY_CONFIGS);
|
||||
}
|
||||
|
||||
async saveProxyConfigs(configs) {
|
||||
try {
|
||||
console.log('Saving proxy configs:', configs);
|
||||
|
||||
// 确保配置数组有效
|
||||
if (!Array.isArray(configs)) {
|
||||
throw new Error('配置必须是数组');
|
||||
}
|
||||
|
||||
// 开始事务
|
||||
const store = await db.getStore(db.stores.PROXY_CONFIGS, 'readwrite');
|
||||
|
||||
// 清除现有配置
|
||||
await store.clear();
|
||||
|
||||
// 保存新配置
|
||||
for (const config of configs) {
|
||||
await store.put(config);
|
||||
}
|
||||
|
||||
console.log('Proxy configs saved successfully');
|
||||
this.notifyConfigUpdate();
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Error saving proxy configs:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async getCurrentProxy() {
|
||||
return await db.get(db.stores.CURRENT_PROXY, 'current');
|
||||
}
|
||||
|
||||
async setCurrentProxy(proxy) {
|
||||
await db.put(db.stores.CURRENT_PROXY, proxy, 'current');
|
||||
}
|
||||
|
||||
async clearCurrentProxy() {
|
||||
await db.delete(db.stores.CURRENT_PROXY, 'current');
|
||||
}
|
||||
|
||||
// 代理日志相关操作
|
||||
async getLogs() {
|
||||
const logs = await db.getAll(db.stores.PROXY_LOGS);
|
||||
return logs.sort((a, b) => b.timestamp - a.timestamp);
|
||||
}
|
||||
|
||||
async addLog(log) {
|
||||
await db.put(db.stores.PROXY_LOGS, log);
|
||||
await this.cleanOldLogs();
|
||||
}
|
||||
|
||||
async clearLogs() {
|
||||
await db.clear(db.stores.PROXY_LOGS);
|
||||
}
|
||||
|
||||
async cleanOldLogs() {
|
||||
const store = await db.getStore(db.stores.PROXY_LOGS, 'readwrite');
|
||||
const countRequest = store.count();
|
||||
|
||||
countRequest.onsuccess = () => {
|
||||
if (countRequest.result > this.MAX_LOGS) {
|
||||
const excess = countRequest.result - this.MAX_LOGS;
|
||||
const cursorRequest = store.index('timestamp').openCursor();
|
||||
let deleted = 0;
|
||||
|
||||
cursorRequest.onsuccess = (event) => {
|
||||
const cursor = event.target.result;
|
||||
if (cursor && deleted < excess) {
|
||||
cursor.delete();
|
||||
deleted++;
|
||||
cursor.continue();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 代理认证相关操作
|
||||
async getAuthHandlers() {
|
||||
return await db.getAll(db.stores.PROXY_AUTH);
|
||||
}
|
||||
|
||||
async saveAuthHandler(handler) {
|
||||
await db.put(db.stores.PROXY_AUTH, handler);
|
||||
}
|
||||
|
||||
async deleteAuthHandler(id) {
|
||||
await db.delete(db.stores.PROXY_AUTH, id);
|
||||
}
|
||||
|
||||
async clearAuthHandlers() {
|
||||
await db.clear(db.stores.PROXY_AUTH);
|
||||
}
|
||||
|
||||
async getErrors() {
|
||||
return await db.get(db.stores.PROXY_AUTH, 'errors') || [];
|
||||
}
|
||||
|
||||
async saveErrors(errors) {
|
||||
await db.put(db.stores.PROXY_AUTH, errors, 'errors');
|
||||
}
|
||||
|
||||
async getAuth() {
|
||||
return await db.get(db.stores.PROXY_AUTH, 'auth');
|
||||
}
|
||||
|
||||
async saveAuth(auth) {
|
||||
await db.put(db.stores.PROXY_AUTH, auth, 'auth');
|
||||
}
|
||||
|
||||
async clearAuth() {
|
||||
await db.delete(db.stores.PROXY_AUTH, 'auth');
|
||||
}
|
||||
|
||||
notifyConfigUpdate() {
|
||||
chrome.runtime.sendMessage({
|
||||
action: 'PROXY_CONFIGS_UPDATED'
|
||||
}).catch(() => {
|
||||
// 忽略接收者不存在的错误
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const proxyStore = new ProxyStore();
|
||||
Reference in New Issue
Block a user