mirror of
https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology.git
synced 2026-05-15 22:30:38 +08:00
fix: harden opfs capability recovery
This commit is contained in:
@@ -2186,6 +2186,47 @@ result = {
|
||||
assert.equal(plan.reasons.includes("resolved-store-mismatch"), true);
|
||||
}
|
||||
|
||||
{
|
||||
const harness = await createGraphPersistenceHarness({
|
||||
chatId: "chat-panel-open-capability-retry",
|
||||
globalChatId: "chat-panel-open-capability-retry",
|
||||
chatMetadata: {
|
||||
integrity: "chat-panel-open-capability-retry-integrity",
|
||||
},
|
||||
});
|
||||
harness.runtimeContext.extension_settings[MODULE_NAME] = {
|
||||
graphLocalStorageMode: "auto",
|
||||
};
|
||||
harness.api.setLocalStoreCapabilitySnapshot({
|
||||
checked: true,
|
||||
checkedAt: Date.now(),
|
||||
opfsAvailable: false,
|
||||
reason: "UnknownError: transient-opfs-init-failure",
|
||||
});
|
||||
harness.api.setGraphPersistenceState({
|
||||
loadState: "loaded",
|
||||
chatId: "chat-panel-open-capability-retry",
|
||||
reason: "healthy",
|
||||
dbReady: true,
|
||||
writesBlocked: false,
|
||||
pendingPersist: false,
|
||||
indexedDbLastError: "",
|
||||
resolvedLocalStore: "indexeddb:indexeddb",
|
||||
storagePrimary: "indexeddb",
|
||||
storageMode: "indexeddb",
|
||||
});
|
||||
|
||||
const plan = harness.api.buildPanelOpenLocalStoreRefreshPlan();
|
||||
|
||||
assert.equal(plan.shouldRefresh, true);
|
||||
assert.equal(plan.forceCapabilityRefresh, true);
|
||||
assert.equal(
|
||||
plan.reasons.includes("capability-retryable-failure"),
|
||||
true,
|
||||
"可恢复的 OPFS 探测失败应在面板打开时触发重新探测",
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
const harness = await createGraphPersistenceHarness({
|
||||
chatId: "chat-luker-panel-open",
|
||||
|
||||
@@ -23,6 +23,12 @@ function createNotFoundError(message) {
|
||||
return error;
|
||||
}
|
||||
|
||||
function createTypeMismatchError(message) {
|
||||
const error = new Error(String(message || "Type mismatch"));
|
||||
error.name = "TypeMismatchError";
|
||||
return error;
|
||||
}
|
||||
|
||||
class MemoryOpfsFileHandle {
|
||||
constructor(parent, name) {
|
||||
this.parent = parent;
|
||||
@@ -71,6 +77,11 @@ class MemoryOpfsDirectoryHandle {
|
||||
|
||||
async getDirectoryHandle(name, options = {}) {
|
||||
const normalizedName = String(name || "");
|
||||
if (this.files.has(normalizedName)) {
|
||||
throw createTypeMismatchError(
|
||||
`A file already exists for directory: ${normalizedName}`,
|
||||
);
|
||||
}
|
||||
let directory = this.directories.get(normalizedName) || null;
|
||||
if (!directory) {
|
||||
if (!options.create) {
|
||||
@@ -84,6 +95,11 @@ class MemoryOpfsDirectoryHandle {
|
||||
|
||||
async getFileHandle(name, options = {}) {
|
||||
const normalizedName = String(name || "");
|
||||
if (this.directories.has(normalizedName)) {
|
||||
throw createTypeMismatchError(
|
||||
`A directory already exists for file: ${normalizedName}`,
|
||||
);
|
||||
}
|
||||
if (!this.files.has(normalizedName)) {
|
||||
if (!options.create) {
|
||||
throw createNotFoundError(`File not found: ${normalizedName}`);
|
||||
@@ -177,6 +193,16 @@ async function testDetectOpfsSupport() {
|
||||
assert.equal(supported.available, true);
|
||||
assert.equal(supported.reason, "ok");
|
||||
|
||||
const conflictedRootDirectory = createMemoryOpfsRoot();
|
||||
conflictedRootDirectory.files.set("st-bme", "legacy-conflict");
|
||||
const repairedConflict = await detectOpfsSupport({
|
||||
rootDirectoryFactory: async () => conflictedRootDirectory,
|
||||
});
|
||||
assert.equal(repairedConflict.available, true);
|
||||
assert.equal(repairedConflict.reason, "ok");
|
||||
assert.equal(conflictedRootDirectory.files.has("st-bme"), false);
|
||||
assert.ok(conflictedRootDirectory.directories.has("st-bme"));
|
||||
|
||||
const missingHandle = await detectOpfsSupport({
|
||||
rootDirectoryFactory: async () => ({}),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user