Files
ignis/shims/fs/sync.js

100 lines
2.6 KiB
JavaScript
Raw Normal View History

2026-03-07 15:42:19 +01:00
export function createFsSync(metadataCache, contentCache, transport) {
return {
existsSync(path) {
return metadataCache.has(path);
},
statSync(path) {
const stat = metadataCache.toStat(path);
if (!stat) {
2026-03-10 20:49:10 +01:00
const err = new Error(
`ENOENT: no such file or directory, stat '${path}'`,
);
err.code = "ENOENT";
2026-03-07 15:42:19 +01:00
throw err;
}
return stat;
},
accessSync(path, mode) {
if (!metadataCache.has(path)) {
2026-03-10 20:49:10 +01:00
const err = new Error(
`ENOENT: no such file or directory, access '${path}'`,
);
err.code = "ENOENT";
2026-03-07 15:42:19 +01:00
throw err;
}
},
readFileSync(path, encoding) {
2026-03-10 20:49:10 +01:00
if (typeof encoding === "object") encoding = encoding?.encoding;
const meta = metadataCache.get(path);
if (meta && meta.type === "directory") {
const e = new Error("EISDIR: illegal operation on a directory, read");
e.code = "EISDIR";
throw e;
}
2026-03-07 15:42:19 +01:00
const cached = contentCache.get(path);
if (cached !== null) {
2026-03-10 20:49:10 +01:00
if (encoding === "utf8" || encoding === "utf-8") {
return typeof cached === "string"
? cached
: new TextDecoder().decode(cached);
2026-03-07 15:42:19 +01:00
}
return cached;
}
2026-03-10 20:49:10 +01:00
console.warn("[shim:fs] readFileSync cache miss, using sync XHR:", path);
2026-03-07 15:42:19 +01:00
const data = transport.readFileSync(path, encoding);
contentCache.set(path, data);
return data;
},
writeFileSync(path, data, encoding) {
2026-03-10 20:49:10 +01:00
if (typeof encoding === "object") encoding = encoding?.encoding;
2026-03-07 15:42:19 +01:00
contentCache.set(path, data);
2026-03-10 20:49:10 +01:00
const size =
typeof data === "string" ? data.length : data.byteLength || 0;
2026-03-07 15:42:19 +01:00
metadataCache.set(path, {
2026-03-10 20:49:10 +01:00
type: "file",
2026-03-07 15:42:19 +01:00
size,
mtime: Date.now(),
ctime: metadataCache.get(path)?.ctime || Date.now(),
});
// Fire-and-forget async send to server
transport.writeFile(path, data, encoding).catch((e) => {
2026-03-10 20:49:10 +01:00
console.error(
"[shim:fs] writeFileSync background save failed:",
path,
e,
);
2026-03-07 15:42:19 +01:00
});
},
unlinkSync(path) {
contentCache.delete(path);
metadataCache.delete(path);
// Fire-and-forget. suppress ENOENT (file already gone)
2026-03-07 15:42:19 +01:00
transport.unlink(path).catch((e) => {
2026-03-10 20:49:10 +01:00
if (e.code !== "ENOENT") {
console.error(
"[shim:fs] unlinkSync background delete failed:",
path,
e,
);
}
2026-03-07 15:42:19 +01:00
});
},
readdirSync(path) {
const entries = metadataCache.readdir(path);
2026-03-10 20:49:10 +01:00
return entries.map((e) => e.name);
2026-03-07 15:42:19 +01:00
},
};
}