I am writing a spoof of the `fs` module; the actual storage mechanism is not the the filesystem but rather a database. Overall, however, the api will function exactly like `fs`.
So far my code is comparable to the following:
```
let underlyingDb = require('module-for-accessing-db');
let mockFs = {
promises: {
readFile: async (fp, opts) => {
let pk = convertFpToPk(fp);
let res = await underlyingDb.query('SELECT * FROM "MockFs" WHERE "pk"=$1', [ pk ]);
// Mock potential fs error:
if (!res.rows.length) throw new Error(`ENOENT: no such file or directory...`);
// TODO: check `opts` to see which encoding is desired
return res.rows[0].fileContent;
},
writeFile: async (fp, data, opts) => {
// Same idea as readFile, but with an INSERT ON CONFLICT statement
// instead of SELECT...
}
},
readFileSync: () => { /* ... */ }
};
```
As you can see it is straightforward for me to mock async file reading and writing.
I am now wondering, however, if it is possible to mock the `*Sync` methods in `fs`. Importantly, `module-for-accessing-db` *only* provides async access methods!
My initial instinct was to try the following (warning: gross!):
```
{
readFileSync: (fp, data) => {
let result = null;
let err = null;
(async () => {
try {
result = await mockFs.promises.readFile(fp, data);
} catch(err0) {
err = err0;
}
})();
while (result === null && err === null) {} // Ew!!
if (err) throw err;
return result;
}
}
```
Of course, this doesn't work. The `while` loop chokes out the entire event loop making it impossible for `result` or `err` to ever become set, even if the async database queries complete.
What are my options here? Do I need to switch the module I'm using to access the db? Do I need to write C code? Or is there a really clever technique to directly solve this problem, using only nodejs?