import 'fake-indexeddb/auto' import { create } from '/mnt/d/CodeWorkspace/MarkLite/node_modules/@metona-team/metona-sqlark/dist/metona-sqlark.esm.js' const DB = 'aria-heal-test' // 1. 正常建库写数据 const db1 = await create({ name: 'heal-test', mode: 'aria', diskEngine: 'indexeddb', version: 0 }) await db1.defineTable('recentFiles', { filePath: { type: 'string', primaryKey: true }, lastOpened: { type: 'number' } }) await db1.table('recentFiles').insert({ filePath: '/a.md', lastOpened: 1 }) await db1.close() // 2. 制造损坏:写一个 footer 声称块偏移在 100000 的残缺 sst 文件(data store 里直接塞坏数据) await new Promise((resolve, reject) => { const req = indexedDB.open(DB, 1) req.onsuccess = () => { const idb = req.result const tx = idb.transaction('data', 'readwrite') const store = tx.objectStore('data') // 残缺 sst:8 字节(正常是 4096 块),meta 记录会声称偏移 4096+ store.put(new ArrayBuffer(8), 'sst_1') tx.oncomplete = () => { idb.close(); resolve() } tx.onerror = () => reject(tx.error) } req.onerror = () => reject(req.error) }) // 3. 删除损坏库(模拟自愈,无活动连接时应该成功) await new Promise((resolve) => { const req = indexedDB.deleteDatabase(DB) req.onsuccess = () => { console.log('deleteDatabase OK'); resolve() } req.onerror = () => { console.log('deleteDatabase error'); resolve() } req.onblocked = () => { console.log('deleteDatabase BLOCKED'); resolve() } }) // 4. 重建库成功 const db2 = await create({ name: 'heal-test', mode: 'aria', diskEngine: 'indexeddb', version: 0 }) await db2.defineTable('recentFiles', { filePath: { type: 'string', primaryKey: true }, lastOpened: { type: 'number' } }) await db2.table('recentFiles').insert({ filePath: '/new.md', lastOpened: 2 }) console.log('rebuilt rows:', JSON.stringify(await db2.table('recentFiles').select().execute())) await db2.close() console.log('HEAL OK')