release: v0.6.0 — 完全移除 IndexedDB,自研 KVStore 事务存储引擎(多key原子写/快照日志恢复/CRC自愈)+ KVStoreEngine + 旧库迁移工具 + 10万级压力验证 + 崩溃注入e2e
This commit is contained in:
+17
-18
@@ -4,14 +4,13 @@
|
||||
*
|
||||
* 覆盖:CASE WHEN 用于 WHERE/聚合 / JOIN 哈希连接 / 多标签页同步
|
||||
*/
|
||||
import 'fake-indexeddb/auto';
|
||||
import { MetonaSqlark } from '../src/core';
|
||||
|
||||
async function createDb(mode: 'memory' | 'hybrid' = 'memory', extra: Record<string, unknown> = {}) {
|
||||
const db = new MetonaSqlark({
|
||||
name: `sql-ext3-${mode}-${Date.now()}-${Math.random()}`,
|
||||
mode,
|
||||
diskEngine: 'indexeddb',
|
||||
diskEngine: 'opfs',
|
||||
...extra,
|
||||
});
|
||||
await db.init();
|
||||
@@ -249,13 +248,13 @@ describe('[v0.3.2] 多标签页同步', () => {
|
||||
|
||||
test('SQL 写语句广播表变更,其他标签页订阅收到 external 事件', async () => {
|
||||
// 先建表(DDL 版本升级会触发其他标签页 onversionchange 关闭连接,故先建表再开第二连接)
|
||||
const setup = new MetonaSqlark({ name: 'mt-a', mode: 'hybrid', diskEngine: 'indexeddb' });
|
||||
const setup = new MetonaSqlark({ name: 'mt-a', mode: 'hybrid', diskEngine: 'opfs' });
|
||||
await setup.init();
|
||||
await setup.defineTable('t', { id: { type: 'string', primaryKey: true }, v: { type: 'number' } });
|
||||
await setup.close();
|
||||
|
||||
const dbA = new MetonaSqlark({ name: 'mt-a', version: 2, mode: 'hybrid', diskEngine: 'indexeddb', multiTabSync: true });
|
||||
const dbB = new MetonaSqlark({ name: 'mt-a', version: 2, mode: 'hybrid', diskEngine: 'indexeddb', multiTabSync: true });
|
||||
const dbA = new MetonaSqlark({ name: 'mt-a', version: 2, mode: 'hybrid', diskEngine: 'opfs', multiTabSync: true });
|
||||
const dbB = new MetonaSqlark({ name: 'mt-a', version: 2, mode: 'hybrid', diskEngine: 'opfs', multiTabSync: true });
|
||||
await dbA.init();
|
||||
await dbB.init();
|
||||
|
||||
@@ -274,13 +273,13 @@ describe('[v0.3.2] 多标签页同步', () => {
|
||||
});
|
||||
|
||||
test('Hybrid 标签页收到广播后内存重载(读到其他标签页的新数据)', async () => {
|
||||
const setup = new MetonaSqlark({ name: 'mt-b', mode: 'hybrid', diskEngine: 'indexeddb' });
|
||||
const setup = new MetonaSqlark({ name: 'mt-b', mode: 'hybrid', diskEngine: 'opfs' });
|
||||
await setup.init();
|
||||
await setup.defineTable('t', { id: { type: 'string', primaryKey: true }, v: { type: 'number' } });
|
||||
await setup.close();
|
||||
|
||||
const dbA = new MetonaSqlark({ name: 'mt-b', version: 2, mode: 'hybrid', diskEngine: 'indexeddb', multiTabSync: true });
|
||||
const dbB = new MetonaSqlark({ name: 'mt-b', version: 2, mode: 'hybrid', diskEngine: 'indexeddb', multiTabSync: true });
|
||||
const dbA = new MetonaSqlark({ name: 'mt-b', version: 2, mode: 'hybrid', diskEngine: 'opfs', multiTabSync: true });
|
||||
const dbB = new MetonaSqlark({ name: 'mt-b', version: 2, mode: 'hybrid', diskEngine: 'opfs', multiTabSync: true });
|
||||
await dbA.init();
|
||||
await dbB.init();
|
||||
|
||||
@@ -305,13 +304,13 @@ describe('[v0.3.2] 多标签页同步', () => {
|
||||
});
|
||||
|
||||
test('未启用 multiTabSync 不广播', async () => {
|
||||
const setup = new MetonaSqlark({ name: 'mt-c', mode: 'hybrid', diskEngine: 'indexeddb' });
|
||||
const setup = new MetonaSqlark({ name: 'mt-c', mode: 'hybrid', diskEngine: 'opfs' });
|
||||
await setup.init();
|
||||
await setup.defineTable('t', { id: { type: 'string', primaryKey: true }, v: { type: 'number' } });
|
||||
await setup.close();
|
||||
|
||||
const dbA = new MetonaSqlark({ name: 'mt-c', version: 2, mode: 'hybrid', diskEngine: 'indexeddb' });
|
||||
const dbB = new MetonaSqlark({ name: 'mt-c', version: 2, mode: 'hybrid', diskEngine: 'indexeddb', multiTabSync: true });
|
||||
const dbA = new MetonaSqlark({ name: 'mt-c', version: 2, mode: 'hybrid', diskEngine: 'opfs' });
|
||||
const dbB = new MetonaSqlark({ name: 'mt-c', version: 2, mode: 'hybrid', diskEngine: 'opfs', multiTabSync: true });
|
||||
await dbA.init();
|
||||
await dbB.init();
|
||||
|
||||
@@ -327,13 +326,13 @@ describe('[v0.3.2] 多标签页同步', () => {
|
||||
});
|
||||
|
||||
test('Table API 写入也广播', async () => {
|
||||
const setup = new MetonaSqlark({ name: 'mt-d', mode: 'hybrid', diskEngine: 'indexeddb' });
|
||||
const setup = new MetonaSqlark({ name: 'mt-d', mode: 'hybrid', diskEngine: 'opfs' });
|
||||
await setup.init();
|
||||
await setup.defineTable('t', { id: { type: 'string', primaryKey: true }, v: { type: 'number' } });
|
||||
await setup.close();
|
||||
|
||||
const dbA = new MetonaSqlark({ name: 'mt-d', version: 2, mode: 'hybrid', diskEngine: 'indexeddb', multiTabSync: true });
|
||||
const dbB = new MetonaSqlark({ name: 'mt-d', version: 2, mode: 'hybrid', diskEngine: 'indexeddb', multiTabSync: true });
|
||||
const dbA = new MetonaSqlark({ name: 'mt-d', version: 2, mode: 'hybrid', diskEngine: 'opfs', multiTabSync: true });
|
||||
const dbB = new MetonaSqlark({ name: 'mt-d', version: 2, mode: 'hybrid', diskEngine: 'opfs', multiTabSync: true });
|
||||
await dbA.init();
|
||||
await dbB.init();
|
||||
|
||||
@@ -354,7 +353,7 @@ describe('[v0.3.2] 多标签页同步', () => {
|
||||
|
||||
describe('[v0.3.2] IndexedDB reopen schema 持久化', () => {
|
||||
test('close 后重新 open 表结构与数据完整', async () => {
|
||||
const setup = new MetonaSqlark({ name: 'reopen-a', mode: 'hybrid', diskEngine: 'indexeddb' });
|
||||
const setup = new MetonaSqlark({ name: 'reopen-a', mode: 'hybrid', diskEngine: 'opfs' });
|
||||
await setup.init();
|
||||
await setup.defineTable('t', {
|
||||
id: { type: 'string', primaryKey: true },
|
||||
@@ -365,7 +364,7 @@ describe('[v0.3.2] IndexedDB reopen schema 持久化', () => {
|
||||
await setup.close();
|
||||
|
||||
// 重新打开(模拟页面刷新)
|
||||
const db = new MetonaSqlark({ name: 'reopen-a', version: 2, mode: 'hybrid', diskEngine: 'indexeddb' });
|
||||
const db = new MetonaSqlark({ name: 'reopen-a', version: 2, mode: 'hybrid', diskEngine: 'opfs' });
|
||||
await db.init();
|
||||
|
||||
const schema = await db.getEngine().getTableSchema('t');
|
||||
@@ -383,7 +382,7 @@ describe('[v0.3.2] IndexedDB reopen schema 持久化', () => {
|
||||
});
|
||||
|
||||
test('reopen 后 UPDATE 全列生效', async () => {
|
||||
const setup = new MetonaSqlark({ name: 'reopen-b', mode: 'hybrid', diskEngine: 'indexeddb' });
|
||||
const setup = new MetonaSqlark({ name: 'reopen-b', mode: 'hybrid', diskEngine: 'opfs' });
|
||||
await setup.init();
|
||||
await setup.defineTable('t', {
|
||||
id: { type: 'string', primaryKey: true },
|
||||
@@ -393,7 +392,7 @@ describe('[v0.3.2] IndexedDB reopen schema 持久化', () => {
|
||||
await setup.query(`INSERT INTO t VALUES ('1', 'Alice', 42)`);
|
||||
await setup.close();
|
||||
|
||||
const db = new MetonaSqlark({ name: 'reopen-b', version: 2, mode: 'hybrid', diskEngine: 'indexeddb' });
|
||||
const db = new MetonaSqlark({ name: 'reopen-b', version: 2, mode: 'hybrid', diskEngine: 'opfs' });
|
||||
await db.init();
|
||||
await db.query(`UPDATE t SET name = 'Renamed', v = 99 WHERE id = '1'`);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user