接上一轮,按接续文件继续执行

结论:Three.js 程序预览和刀具执行显示已收口,公网 HTTP/IP 下 Save/Restore Session 已支持 memory-fallback 降级并通过 node/browser gate。
This commit is contained in:
2026-06-22 06:56:34 +08:00
parent bd11a5f8d6
commit 8321055934
9 changed files with 631 additions and 221 deletions

View File

@@ -88,20 +88,22 @@ export function validateFiveAxisSessionSnapshot(snapshot, sessionId) {
export async function saveFiveAxisSessionSnapshot(sessionId, payload, options = {}) {
const snapshot = createFiveAxisSessionSnapshot(sessionId, payload, options);
const path = sessionSnapshotPath(sessionId, options.filename);
await saveTextFile(path, `${JSON.stringify(snapshot, null, 2)}\n`, options.storage);
return { snapshot, path };
const storage = resolveSessionStorage(options);
await saveTextFile(path, `${JSON.stringify(snapshot, null, 2)}\n`, storage.storage);
return { snapshot, path, storageMode: storage.mode };
}
export async function loadFiveAxisSessionSnapshot(sessionId, options = {}) {
const path = sessionSnapshotPath(sessionId, options.filename);
const text = await loadTextFile(path, options.storage);
const storage = resolveSessionStorage(options);
const text = await loadTextFile(path, storage.storage);
let snapshot;
try {
snapshot = JSON.parse(text);
} catch (error) {
throw new Error(`Invalid five-axis session snapshot JSON: ${error.message}`);
}
return { snapshot: validateFiveAxisSessionSnapshot(snapshot, sessionId), path };
return { snapshot: validateFiveAxisSessionSnapshot(snapshot, sessionId), path, storageMode: storage.mode };
}
export function restoreFiveAxisSessionState(snapshot) {
@@ -138,6 +140,7 @@ export function restoreFiveAxisSessionState(snapshot) {
export function createMemorySessionStorage(seed = {}) {
const files = new Map(Object.entries(seed));
return {
apiName: "web-rtcp-5axis-memory-session-storage",
files,
async getDirectory() {
return createDirectoryHandle(files, []);
@@ -145,6 +148,35 @@ export function createMemorySessionStorage(seed = {}) {
};
}
let browserMemorySessionStorage = null;
function resolveSessionStorage(options = {}) {
if (options.storage) {
return {
storage: options.storage,
mode: options.storageMode || storageModeFor(options.storage),
};
}
const browserStorage = globalThis.navigator?.storage;
if (browserStorage?.getDirectory) {
return {
storage: browserStorage,
mode: "opfs",
};
}
browserMemorySessionStorage ??= createMemorySessionStorage();
return {
storage: browserMemorySessionStorage,
mode: "memory-fallback",
};
}
function storageModeFor(storage) {
return storage?.apiName === "web-rtcp-5axis-memory-session-storage"
? "memory"
: "custom";
}
function validateFiveAxisSessionPayload(payload) {
assertPlainObject(payload, "five-axis session payload");
if (payload.apiName !== "web-rtcp-5axis-session-payload") {