Description
Is your feature request related to a problem? Please describe.
I have a PR open against graceful-fs
which (among other updates) adds support for fs.promises
. A sticky point is the implementation of gracefulFS.promises.open
. We need this to create an object that extends FileHandle
from lib/internal/fs/promises.js
.
Describe the solution you'd like
Directly expose class FileHandle
from internal/fs/promises.js
as fs.promises.FileHandle
to allow extending. Alter the constructor to detect a numeric filehandle
:
class FileHandle {
constructor(filehandle) {
if (typeof filehandle === 'number') {
filehandle = new binding.FileHandle(filehandle);
}
// validate (filehandle instanceof binding.FileHandle)?
this[kHandle] = filehandle;
}
// ... clipped ...
}
This would allow implementing a user-space fs.promises.open
with a function based on a promisified fs.open
function. In this scheme setting fs.promises.FileHandle
would not alter the functionality of fs.promises.open
.
const promiseOpen = promisify(gracefulFS.open);
class GracefulFileHandle extends fs.promises.FileHandle {
// override methods as needed
}
const myPromises = {
...fs.promises, // simplified copy of default functions for demo
FileHandle: GracefulFileHandle,
async open(...args) {
return new GracefulFileHandle(await promiseOpen(...args));
}
};
Describe alternatives you've considered
Current PR at isaacs/node-graceful-fs#173 does some very ugly stuff in promises.js to implement fs.promises.open
which resolves to an extended class based on fs.promises.FileHandle. First it retrieves the C++ file handle class from process.binding('fs').FileHandle
even though process.binding
is heading for deprecation. Worse it uses fs.promises.open(__filename, 'r')
to create a filehandle which is used to retrieve class FileHandle
from lib/internal/fs/promises.js
, then extends that class. A temporary promises.open
method is created which awaits creation of the real method. This hacky method would be required to support require('graceful-fs').promises
for current versions of node.js, but it would be nice if fs.promises.FileHandle
could be detected to avoid all the hacks/deprecated API's.
I had considered a completely user-space implementation of gracefulFS.promises
based on util.promisify
but this would get really messy to reimplement fs.promises
functions which accept filehandle
, would potentially cause file handles returned by gracefulFS.promises.open
to be incompatible with native fs.promises
methods. fs.promises.readFile
for example accepts a filehandle as the first argument, I'm unsure how it would react to a userspace implementation of the file handle. The user-space implementation would also fail to close FD's upon garbage collection (I don't agree with this auto-close feature but it exists).