import assert from "node:assert/strict"; import { opfsCapability, runOpfsProbe } from "../workspace/opfs-runtime.mjs"; import { MemoryStorage, WorkspaceJournal } from "../workspace/journal.mjs"; import { createOfflinePackage, createWorkspacePackage, verifyOfflinePackage } from "../workspace/migration.mjs"; import { ReplayTimeline, fnv1a64 } from "../worker/replay.mjs"; const contextId = "linuxcnc-2.10.0-pre0-wasm-m1-py-c1"; const unavailable = opfsCapability({ navigator: { storage: {} } }); assert.deepEqual(unavailable, { status: "blocked", code: "opfs_unavailable", reason: "storage_get_directory_missing" }); assert.deepEqual(await runOpfsProbe({ storage: {} }), { schema: "opfs-runtime.v1", status: "blocked", code: "opfs_unavailable", reason: "storage_get_directory_missing", project_id: "s6-05-opfs" }); const storage = new MemoryStorage(); const journal = new WorkspaceJournal(storage, { projectId: "s6-05-logical" }); journal.prepare("op-1", [{ path: "config/main.ini", data: "[EMC]\n" }]); journal.commit("op-1"); const recovered = journal.recover(); assert.equal(recovered.status, "recovered"); assert.deepEqual(recovered.files, { "config/main.ini": "[EMC]\n" }); const timeline = new ReplayTimeline(); timeline.appendEvent(1, 0, "SESSION_READY", {}); timeline.checkpoint(1, 0, { tick: 0 }); const workspace = createWorkspacePackage({ contextId, timeline, journal: journal.records(), committedSeq: 1 }); const offline = createOfflinePackage({ workspacePackage: workspace, resources: [{ path: "index.html", data: "offline" }] }); assert.deepEqual(verifyOfflinePackage(offline, { contextId, workspacePackage: workspace, available: [{ path: "index.html", data: "offline" }] }), { status: "ready", missing: [], corrupted: [], offline: true }); assert.throws(() => verifyOfflinePackage(offline, { contextId, workspacePackage: workspace, available: [], online: false }), /offline_resource_invalid/); console.log(JSON.stringify({ schema: "opfs-runtime-s6-05-logical-sample.v1", status: "verified", context_id: contextId, opfs_boundary: unavailable, journal_status: recovered.status, journal_state_hash: recovered.state_hash, offline_status: "ready", offline_bundle_hash: offline.bundle_hash, deterministic_hash: fnv1a64({ recovered: recovered.state_hash, offline: offline.bundle_hash }), }));