mirror of
https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology.git
synced 2026-05-15 22:30:38 +08:00
fix(migration): 7 critical fixes for Authority migration safety and data integrity
- Fix #2: _executeStatements fallback now batches transactions (150/batch) and reorders upsert-before-delete to prevent data loss on payload overflow - Fix #3: Read/write migratedToAuthority marker in chat_metadata to prevent re-overwriting from legacy sources after Authority migration - Fix #1: Add OPFS → Authority migration channel (exportOpfsSnapshotForChat, maybeImportLegacyOpfsSnapshotToLocalStore) inserted before IndexedDB in migration chain - Fix #4: Mark runtimeVectorIndexState dirty with triviumRebuildRequired and trigger submitAuthorityVectorRebuildJob after all three migration paths - Fix #5: Dual-save safety snapshots to Authority blob; rollback can now recover from blob when local IndexedDB snapshot is unavailable - Fix #6: Add isEmptyCheck detail and console.warn for near-empty stores to help diagnose residual vs real data in store-not-empty skips - Fix #7: Add overflow warning logs and sessionStorage persistence for Authority offline queue max-items/max-bytes exceeded events
This commit is contained in:
@@ -742,6 +742,12 @@ export class AuthorityGraphStore {
|
||||
edges: emptyStatus.edges,
|
||||
tombstones: emptyStatus.tombstones,
|
||||
},
|
||||
isEmptyCheck: {
|
||||
empty: false,
|
||||
nodes: emptyStatus.nodes,
|
||||
edges: emptyStatus.edges,
|
||||
tombstones: emptyStatus.tombstones,
|
||||
},
|
||||
migrationCompletedAt: 0,
|
||||
migrationSource,
|
||||
legacyRetentionUntil,
|
||||
@@ -1032,12 +1038,42 @@ export class AuthorityGraphStore {
|
||||
async _executeStatements(statements = []) {
|
||||
const normalizedStatements = toArray(statements).filter((statement) => statement?.sql);
|
||||
if (!normalizedStatements.length) return null;
|
||||
|
||||
const BATCH_SIZE = 150;
|
||||
if (typeof this.sqlClient?.transaction === "function") {
|
||||
return await this.sqlClient.transaction(normalizedStatements);
|
||||
if (normalizedStatements.length <= BATCH_SIZE) {
|
||||
return await this.sqlClient.transaction(normalizedStatements);
|
||||
}
|
||||
let lastResult = null;
|
||||
for (let i = 0; i < normalizedStatements.length; i += BATCH_SIZE) {
|
||||
const batch = normalizedStatements.slice(i, i + BATCH_SIZE);
|
||||
lastResult = await this.sqlClient.transaction(batch);
|
||||
}
|
||||
return lastResult;
|
||||
}
|
||||
|
||||
const upsertStatements = [];
|
||||
const deleteStatements = [];
|
||||
for (const stmt of normalizedStatements) {
|
||||
if (stmt.sql.trim().toUpperCase().startsWith("DELETE")) {
|
||||
deleteStatements.push(stmt);
|
||||
} else {
|
||||
upsertStatements.push(stmt);
|
||||
}
|
||||
}
|
||||
let result = null;
|
||||
for (const statement of normalizedStatements) {
|
||||
result = await this._execute(statement.sql, statement.params || {});
|
||||
for (const stmt of upsertStatements) {
|
||||
result = await this._execute(stmt.sql, stmt.params || {});
|
||||
}
|
||||
for (const stmt of deleteStatements) {
|
||||
result = await this._execute(stmt.sql, stmt.params || {});
|
||||
}
|
||||
if (deleteStatements.length > 0 && upsertStatements.length > 0) {
|
||||
console.warn("[ST-BME] _executeStatements fallback 路径执行:先 upsert 后 delete,无事务保护", {
|
||||
chatId: this.chatId,
|
||||
upsertCount: upsertStatements.length,
|
||||
deleteCount: deleteStatements.length,
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user