export async function runBrowserOpfsDirectorySections(context, simulator) { const { expectFileList, expectMissingOpfsFile, expectMissingWasmPath, expectText, runSection, withSmokeSimulator, } = context; await runSection("opfs directory persist and load", async () => { const fixturePath = simulator.fs.opfs.resolvePath("fixtures"); simulator.fs.module.FS.mkdirTree(`${fixturePath}/nested`); simulator.fs.module.FS.mkdirTree(`${fixturePath}/empty/nested`); simulator.fs.module.FS.writeFile(`${fixturePath}/nested/fixture.ngc`, "G21 G90\nG0 X3\n"); simulator.fs.module.FS.writeFile(`${fixturePath}/root.ngc`, "G21 G90\nG0 X4\n"); const persistedFiles = await simulator.fs.opfs.persistDirectory("fixtures"); const fixtureStat = await simulator.fs.opfs.stat("fixtures"); if (fixtureStat.kind !== "directory" || fixtureStat.size !== null) { throw new Error("OPFS stat did not report a persisted directory"); } expectFileList(persistedFiles, ["nested/fixture.ngc", "root.ngc"], "unexpected OPFS directory persist file list"); const fixtureDecoded = new TextDecoder().decode( await simulator.fs.opfs.readFile("fixtures/nested/fixture.ngc"), ); expectText(fixtureDecoded, "G21 G90\nG0 X3\n", "persisted WASM filesystem directory file was not readable from OPFS"); const emptyFixtureStat = await simulator.fs.opfs.stat("fixtures/empty/nested"); if (emptyFixtureStat.kind !== "directory" || emptyFixtureStat.size !== null) { throw new Error("OPFS persistDirectory did not preserve an empty directory"); } await withSmokeSimulator(async (staleDirectorySimulator) => { await staleDirectorySimulator.fs.opfs.writeFile("fixtures/stale.ngc", "G21 G90\nG0 X6\n"); }); simulator.fs.module.FS.unlink(`${fixturePath}/nested/fixture.ngc`); const refreshedPersistedFiles = await simulator.fs.opfs.persistDirectory("fixtures"); expectFileList(refreshedPersistedFiles, ["root.ngc"], "unexpected refreshed OPFS directory persist file list"); await expectMissingOpfsFile( () => simulator.fs.opfs.readFile("fixtures/stale.ngc"), "stale OPFS directory file remained after directory persist", ); await expectMissingOpfsFile( () => simulator.fs.opfs.readFile("fixtures/nested/fixture.ngc"), "removed WASM directory file remained in OPFS after directory persist", ); simulator.fs.module.FS.writeFile(`${fixturePath}/nested/fixture.ngc`, "G21 G90\nG0 X3\n"); const restoredPersistedFiles = await simulator.fs.opfs.persistDirectory("fixtures"); expectFileList(restoredPersistedFiles, ["nested/fixture.ngc", "root.ngc"], "unexpected restored OPFS directory persist file list"); const loadedFiles = await simulator.fs.opfs.readDirectory("fixtures"); expectFileList(loadedFiles, ["nested/fixture.ngc", "root.ngc"], "unexpected OPFS directory load file list"); const loadedRootPath = simulator.fs.opfs.resolvePath("fixtures/root.ngc"); const loadedRootDecoded = new TextDecoder().decode(simulator.fs.module.FS.readFile(loadedRootPath)); expectText(loadedRootDecoded, "G21 G90\nG0 X4\n", "OPFS directory file was not mirrored into the WASM filesystem"); const loadedEmptyPath = simulator.fs.opfs.resolvePath("fixtures/empty/nested"); const loadedEmptyMode = simulator.fs.module.FS.stat(loadedEmptyPath).mode; if (!simulator.fs.module.FS.isDir(loadedEmptyMode)) { throw new Error("OPFS readDirectory did not mirror an empty directory into WASM FS"); } }); await runSection("opfs directory refresh and type conflicts", async () => { const loadedRootPath = simulator.fs.opfs.resolvePath("fixtures/root.ngc"); await withSmokeSimulator(async (updateDirectorySimulator) => { await updateDirectorySimulator.fs.opfs.removeFile("fixtures/root.ngc"); await updateDirectorySimulator.fs.opfs.writeFile("fixtures/nested/fixture.ngc", "G21 G90\nG0 X5\n"); const refreshedFiles = await simulator.fs.opfs.readDirectory("fixtures"); expectFileList(refreshedFiles, ["nested/fixture.ngc"], "unexpected refreshed OPFS directory file list"); expectMissingWasmPath( () => simulator.fs.module.FS.stat(loadedRootPath), "stale OPFS directory mirror file remained in WASM FS", ); const refreshedFixturePath = simulator.fs.opfs.resolvePath("fixtures/nested/fixture.ngc"); const refreshedFixture = new TextDecoder().decode( simulator.fs.module.FS.readFile(refreshedFixturePath), ); expectText(refreshedFixture, "G21 G90\nG0 X5\n", "OPFS directory refresh did not replace the WASM mirror file"); await simulator.fs.opfs.writeFile("fixtures/type-conflict/original.ngc", "G21 G90\n"); await updateDirectorySimulator.fs.opfs.removeDirectory("fixtures/type-conflict"); await updateDirectorySimulator.fs.opfs.writeFile("fixtures/type-conflict", "G21 G90\nG0 X11\n"); const replacedConflictFile = new TextDecoder().decode( await simulator.fs.opfs.readFile("fixtures/type-conflict"), ); expectText(replacedConflictFile, "G21 G90\nG0 X11\n", "OPFS readFile did not load a file that replaced a directory"); const conflictMirrorPath = simulator.fs.opfs.resolvePath("fixtures/type-conflict"); const conflictMirrorMode = simulator.fs.module.FS.stat(conflictMirrorPath).mode; if (!simulator.fs.module.FS.isFile(conflictMirrorMode)) { throw new Error("OPFS readFile did not replace the WASM mirror directory with a file"); } await updateDirectorySimulator.fs.opfs.removeFile("fixtures/type-conflict"); await updateDirectorySimulator.fs.opfs.writeFile( "fixtures/type-conflict/original.ngc", "G21 G90\n", ); await updateDirectorySimulator.fs.opfs.removeDirectory("fixtures/type-conflict"); await updateDirectorySimulator.fs.opfs.writeFile("fixtures/root.ngc", "G21 G90\nG0 X4\n"); await updateDirectorySimulator.fs.opfs.writeFile("fixtures/nested/fixture.ngc", "G21 G90\nG0 X3\n"); const restoredFiles = await simulator.fs.opfs.readDirectory("fixtures"); expectFileList(restoredFiles, ["nested/fixture.ngc", "root.ngc"], "unexpected reloaded OPFS directory file list"); }); }); await runSection("opfs directory restore in new instance", async () => { await withSmokeSimulator(async (restoredDirectorySimulator) => { const restoredDirectoryFiles = await restoredDirectorySimulator.fs.opfs.readDirectory("fixtures"); expectFileList(restoredDirectoryFiles, ["nested/fixture.ngc", "root.ngc"], "unexpected restored OPFS directory file list"); const restoredFixtureRootPath = restoredDirectorySimulator.fs.opfs.resolvePath("fixtures/root.ngc"); const restoredFixtureRoot = new TextDecoder().decode( restoredDirectorySimulator.fs.module.FS.readFile(restoredFixtureRootPath), ); expectText(restoredFixtureRoot, "G21 G90\nG0 X4\n", "OPFS directory was not restored into a new WASM filesystem instance"); const restoredEmptyFixturePath = restoredDirectorySimulator.fs.opfs.resolvePath("fixtures/empty/nested"); const restoredEmptyFixtureMode = restoredDirectorySimulator.fs.module.FS.stat(restoredEmptyFixturePath).mode; if (!restoredDirectorySimulator.fs.module.FS.isDir(restoredEmptyFixtureMode)) { throw new Error("OPFS empty directory was not restored into a new WASM filesystem instance"); } }); }); await runSection("opfs metadata queries avoid wasm mirror pollution", async () => { await withSmokeSimulator(async (existsOnlySimulator) => { await existsOnlySimulator.fs.opfs.writeFile("programs/exists-only.ngc", "G21 G90\nG0 X10\n"); const existsOnlyPath = simulator.fs.opfs.resolvePath("programs/exists-only.ngc"); if (!(await simulator.fs.opfs.exists("programs/exists-only.ngc"))) { throw new Error("OPFS exists did not see a file written by another simulator instance"); } const existsOnlyStat = await simulator.fs.opfs.stat("programs/exists-only.ngc"); if (existsOnlyStat.kind !== "file" || existsOnlyStat.size !== 15) { throw new Error("OPFS stat did not see a file written by another simulator instance"); } expectMissingWasmPath( () => simulator.fs.module.FS.stat(existsOnlyPath), "OPFS metadata queries polluted the WASM filesystem mirror", ); }); }); await runSection("opfs workspace clear and mirror removal", async () => { await simulator.fs.opfs.clear(); await withSmokeSimulator(async (clearedWorkspaceSimulator) => { await expectMissingOpfsFile( () => clearedWorkspaceSimulator.fs.opfs.readDirectory("fixtures"), "cleared OPFS workspace still exposed a persisted directory", ); }); await simulator.fs.opfs.removeFile("programs/browser-smoke.ngc"); if (await simulator.fs.opfs.exists("programs/browser-smoke.ngc")) { throw new Error("OPFS exists reported a removed file"); } const removedProgramPath = simulator.fs.opfs.resolvePath("programs/browser-smoke.ngc"); expectMissingWasmPath( () => simulator.fs.module.FS.stat(removedProgramPath), "OPFS removeFile did not remove the WASM mirror", ); const fixturePath = simulator.fs.opfs.resolvePath("fixtures"); await simulator.fs.opfs.removeDirectory("fixtures"); await simulator.fs.opfs.removeDirectory("fixtures"); expectMissingWasmPath( () => simulator.fs.module.FS.stat(fixturePath), "OPFS removeDirectory did not remove the WASM mirror", ); }); }