diff --git a/.changeset/clean-baboons-kneel.md b/.changeset/clean-baboons-kneel.md new file mode 100644 index 000000000..dee9daef3 --- /dev/null +++ b/.changeset/clean-baboons-kneel.md @@ -0,0 +1,5 @@ +--- +"@solid-primitives/filesystem": patch +--- + +fix: removing a file deletes its signal correctly diff --git a/packages/filesystem/src/reactive.ts b/packages/filesystem/src/reactive.ts index 83c2c0e9d..66ce16482 100644 --- a/packages/filesystem/src/reactive.ts +++ b/packages/filesystem/src/reactive.ts @@ -112,6 +112,10 @@ export const createSyncFileSystem = ( getTypeMap.delete(item); } }); + if (readFileMap.has(path)) { + readFileMap.get(path)?.[1](undefined); + readFileMap.delete(path); + } readdirMap.get(getParentDir(path))?.[1]( (items = []) => items.filter(item => item === getItemName(path)) as [] | DirEntries, ); diff --git a/packages/filesystem/test/index.test.ts b/packages/filesystem/test/index.test.ts index ca4ede5fe..c52f15ffd 100644 --- a/packages/filesystem/test/index.test.ts +++ b/packages/filesystem/test/index.test.ts @@ -12,7 +12,7 @@ import { makeTauriFileSystem, rsync, } from "../src/index.js"; -import { createEffect, createRoot } from "solid-js"; +import { catchError, createEffect, createRoot } from "solid-js"; describe("makeNoFileSystem", () => { const fs = makeNoFileSystem(); @@ -52,6 +52,15 @@ describe("makeVirtualFileSystem", () => { }); test("fs.readFile returns file content", () => expect(fs.readFile("src/test.ts")).toBe("// test")); + test("fs.readFile throws on attempting to read a directory as file", () => { + expect(() => fs.readFile("src")).toThrow('"src" is not a file'); + }); + test("fs.readFile throws on attempting to read a non-existent file", () => { + expect(() => fs.readFile("src/nonexistent.ts")).toThrow('"src/nonexistent.ts" is not a file'); + }); + test("fs.readFile throws on attempting to read from a non-existing directory", () => { + expect(() => fs.readFile("nonexistent/test.ts")).toThrow('"nonexistent" is not a directory') + }); test("fs.writeFile creates and overwrites file", () => { expect(fs.readdir("src")).toHaveLength(1); fs.writeFile("src/test2.ts", "// data"); @@ -115,6 +124,20 @@ describe("createFileSystem (sync) calls the underlying fs", () => { }); }); +describe("createFileSystem (sync) relays file system errors", () => { + test("a deleted file stored in a signal throws an error", () => new Promise((done, fail) => { + setTimeout(() => fail(new Error('did not throw')), 100); + const fs = createFileSystem(makeVirtualFileSystem({ 'test.json': '{}' })); + catchError(() => { + createEffect(() => fs.readFile("test.json")); + setTimeout(() => fs.rm("test.json"), 30); + }, (error) => { + expect(error).toEqual(new Error('"test.json" is not a file')); + done(); + }); + })); +}); + describe("createFileSystem (async) calls the underlying fs", () => { const afs = makeNoAsyncFileSystem(); instrumentFs(afs);