Files
ST-Bionic-Memory-Ecology/tests/opfs-write-serialization.mjs
2026-04-17 20:17:45 +08:00

268 lines
6.8 KiB
JavaScript

import assert from "node:assert/strict";
import { buildPersistDelta } from "../sync/bme-db.js";
import {
BME_GRAPH_LOCAL_STORAGE_MODE_OPFS_PRIMARY,
OpfsGraphStore,
} from "../sync/bme-opfs-store.js";
import { createMemoryOpfsRoot } from "./helpers/memory-opfs.mjs";
function createRuntimeGraphLikeSnapshot({
chatId,
lastProcessedFloor,
extractionCount,
nodes = [],
edges = [],
batchJournal = [],
} = {}) {
return {
version: 9,
lastProcessedSeq: lastProcessedFloor,
nodes,
edges,
historyState: {
chatId,
lastProcessedAssistantFloor: lastProcessedFloor,
extractionCount,
processedMessageHashVersion: 2,
processedMessageHashes: {},
processedMessageHashesNeedRefresh: false,
historyDirtyFrom: null,
lastMutationReason: "",
lastMutationSource: "",
lastRecoveryResult: null,
lastBatchStatus: null,
lastExtractedRegion: "",
activeRegion: "",
activeRegionSource: "",
activeStorySegmentId: "",
activeStoryTimeLabel: "",
activeStoryTimeSource: "",
lastExtractedStorySegmentId: "",
activeCharacterPovOwner: "",
activeUserPovOwner: "",
activeRecallOwnerKey: "",
recentRecallOwnerKeys: [],
},
vectorIndexState: {
mode: "backend",
collectionId: `st-bme::${chatId}`,
source: "",
modelScope: "",
hashToNodeId: {},
nodeToHash: {},
dirty: false,
replayRequiredNodeIds: [],
dirtyReason: "",
pendingRepairFromFloor: null,
lastSyncAt: 0,
lastStats: {
total: 0,
indexed: 0,
stale: 0,
pending: 0,
},
lastWarning: "",
lastIntegrityIssue: null,
},
batchJournal,
maintenanceJournal: [],
knowledgeState: {},
regionState: {},
timelineState: {},
summaryState: {},
lastRecallResult: null,
};
}
async function testCommitDeltaAndPatchMetaSerialize() {
const rootDirectory = createMemoryOpfsRoot({
writeDelayMs: 5,
});
const store = new OpfsGraphStore("chat-opfs-serialize-meta", {
rootDirectoryFactory: async () => rootDirectory,
storeMode: BME_GRAPH_LOCAL_STORAGE_MODE_OPFS_PRIMARY,
});
await store.open();
await store.importSnapshot(
{
meta: {
revision: 1,
lastBackupFilename: "",
},
state: {
lastProcessedFloor: 0,
extractionCount: 0,
},
nodes: [],
edges: [],
tombstones: [],
},
{
mode: "replace",
preserveRevision: true,
},
);
await Promise.all([
store.commitDelta(
{
upsertNodes: [
{
id: "node-1",
type: "event",
fields: {
title: "serialized",
},
archived: false,
updatedAt: 100,
},
],
},
{
reason: "serialized-node",
},
),
store.patchMeta({
lastBackupFilename: "backup-a.json",
lastProcessedFloor: 7,
extractionCount: 3,
}),
]);
const snapshot = await store.exportSnapshot();
assert.equal(snapshot.nodes.length, 1);
assert.equal(snapshot.nodes[0]?.id, "node-1");
assert.equal(snapshot.meta.lastBackupFilename, "backup-a.json");
assert.equal(snapshot.state.lastProcessedFloor, 7);
assert.equal(snapshot.state.extractionCount, 3);
}
async function testImportSnapshotAndClearAllSerialize() {
const rootDirectory = createMemoryOpfsRoot({
writeDelayMs: 5,
});
const store = new OpfsGraphStore("chat-opfs-serialize-clear", {
rootDirectoryFactory: async () => rootDirectory,
storeMode: BME_GRAPH_LOCAL_STORAGE_MODE_OPFS_PRIMARY,
});
await store.open();
await store.importSnapshot(
{
meta: { revision: 2 },
state: { lastProcessedFloor: 5, extractionCount: 2 },
nodes: [
{
id: "seed-node",
type: "event",
fields: { title: "seed" },
archived: false,
updatedAt: 1,
},
],
edges: [],
tombstones: [],
},
{ mode: "replace", preserveRevision: true },
);
await Promise.all([
store.clearAll(),
store.importSnapshot(
{
meta: { revision: 4 },
state: { lastProcessedFloor: 9, extractionCount: 4 },
nodes: [
{
id: "after-clear-node",
type: "fact",
fields: { title: "after-clear" },
archived: false,
updatedAt: 2,
},
],
edges: [],
tombstones: [],
},
{ mode: "replace", preserveRevision: true },
),
]);
const snapshot = await store.exportSnapshot();
assert.equal(snapshot.nodes.length, 1);
assert.equal(snapshot.nodes[0]?.id, "after-clear-node");
assert.equal(snapshot.state.lastProcessedFloor, 9);
assert.equal(snapshot.state.extractionCount, 4);
}
async function testGraphLikeDeltaPreservesHistoryFrontier() {
const rootDirectory = createMemoryOpfsRoot();
const store = new OpfsGraphStore("chat-opfs-graph-like-delta", {
rootDirectoryFactory: async () => rootDirectory,
storeMode: BME_GRAPH_LOCAL_STORAGE_MODE_OPFS_PRIMARY,
});
await store.open();
const beforeGraph = createRuntimeGraphLikeSnapshot({
chatId: "chat-opfs-graph-like-delta",
lastProcessedFloor: -1,
extractionCount: 0,
});
const afterGraph = createRuntimeGraphLikeSnapshot({
chatId: "chat-opfs-graph-like-delta",
lastProcessedFloor: 12,
extractionCount: 3,
nodes: [
{
id: "node-graph-like",
type: "event",
fields: { title: "graph-like" },
archived: false,
updatedAt: 12,
},
],
batchJournal: [
{
id: "journal-1",
processedRange: [12, 12],
},
],
});
const delta = buildPersistDelta(beforeGraph, afterGraph, {
useNativeDelta: false,
});
assert.equal(delta.runtimeMetaPatch.lastProcessedFloor, 12);
assert.equal(delta.runtimeMetaPatch.extractionCount, 3);
assert.equal(
delta.runtimeMetaPatch.runtimeHistoryState?.lastProcessedAssistantFloor,
12,
);
await store.commitDelta(delta, {
reason: "graph-like-delta",
requestedRevision: 1,
markSyncDirty: true,
});
const reopenedStore = new OpfsGraphStore("chat-opfs-graph-like-delta", {
rootDirectoryFactory: async () => rootDirectory,
storeMode: BME_GRAPH_LOCAL_STORAGE_MODE_OPFS_PRIMARY,
});
await reopenedStore.open();
const snapshot = await reopenedStore.exportSnapshot();
assert.equal(snapshot.state.lastProcessedFloor, 12);
assert.equal(snapshot.state.extractionCount, 3);
assert.equal(
snapshot.meta.runtimeHistoryState?.lastProcessedAssistantFloor,
12,
);
}
await testCommitDeltaAndPatchMetaSerialize();
await testImportSnapshotAndClearAllSerialize();
await testGraphLikeDeltaPreservesHistoryFrontier();
console.log("opfs-write-serialization tests passed");