first commit

This commit is contained in:
Longtail committed 2026-10-31 14:43:15 +08:00
commit ad7a9260b4
12 files changed
+931

No files matched your search

+43
View File
@@ -0,0 +1,43 @@
const DB_NAME = 'dww11-account-switch-v3';
let opening;
export function openDB() {
if (!opening) opening = new Promise((resolve, reject) => {
const req = indexedDB.open(DB_NAME, 1);
req.onupgradeneeded = () => {
req.result.createObjectStore('accounts', { keyPath: 'username' });
req.result.createObjectStore('meta');
};
req.onsuccess = () => {
const db = req.result;
db.onversionchange = () => { db.close(); opening = null; };
db.onclose = () => { opening = null; };
resolve(db);
};
req.onerror = () => { opening = null; reject(new Error('无法打开 IndexedDB:' + req.error?.message)); };
req.onblocked = () => { opening = null; reject(new Error('数据库升级被阻塞,请关闭扩展管理页后重试。')); };
});
return opening;
}
// 所有状态变更跨 accounts/meta 使用同一事务。回调必须同步,避免 await 使事务自动提交。
export async function transact(reducer, write = true) {
const db = await openDB();
return new Promise((resolve, reject) => {
const tx = db.transaction(['accounts', 'meta'], write ? 'readwrite' : 'readonly', write ? { durability: 'strict' } : undefined);
const accountsStore = tx.objectStore('accounts'), metaStore = tx.objectStore('meta');
const a = accountsStore.getAll(), m = metaStore.get('state');
let output, failure, ready = 0;
const loaded = () => {
if (++ready !== 2) return;
try {
const state = m.result || { schedule: null, flow: null };
output = reducer(a.result, state, accountsStore);
if (write) metaStore.put(state, 'state');
} catch (e) { failure = e; tx.abort(); }
};
a.onsuccess = loaded; m.onsuccess = loaded;
tx.oncomplete = () => resolve(output);
tx.onabort = () => reject(failure || new Error('数据库事务未提交:' + (tx.error?.message || '已中止')));
tx.onerror = () => {}; // 由 onabort 统一处理,不在提交之前返回成功。
});
}