* adding promise-based filedescriptor * fixing promisify dep * promisifying shell * deprecating 'exists' method on fs * adding docs * fixing docs * removing redundant code.
This commit is contained in:
parent
de45918cbc
commit
353290a08f
|
@ -3,6 +3,7 @@ bower_components
|
|||
.env
|
||||
*~
|
||||
dist/filer-issue225.js
|
||||
.vscode
|
||||
|
||||
# Parcel build dirs
|
||||
.cache
|
||||
|
|
16
README.md
16
README.md
|
@ -80,6 +80,7 @@ instance. By default, a new [IndexedDB](https://developer.mozilla.org/en/docs/I
|
|||
database is created for each file system. The file system can also use other
|
||||
backend storage providers, for example [WebSQL](http://en.wikipedia.org/wiki/Web_SQL_Database)
|
||||
or even RAM (i.e., for temporary storage). See the section on [Storage Providers](#providers).
|
||||
<a name="overviewExample"></a>
|
||||
|
||||
```javascript
|
||||
var fs = new Filer.FileSystem();
|
||||
|
@ -110,6 +111,21 @@ Like node.js, callbacks for methods that accept them are optional but suggested
|
|||
you omit the callback, errors will be thrown as exceptions). The first callback parameter is
|
||||
reserved for passing errors. It will be `null` if no errors occurred and should always be checked.
|
||||
|
||||
#### Support for Promises
|
||||
The Promise based API mimics the way Node [implements](https://nodejs.org/api/fs.html#fs_fs_promises_api) them. Both `Shell` and `FileSystem` now have a `promises` object attached alongside the regular callback style methods. Method names are identical to their callback counterparts with the difference that instead of receiving a final argument as a callback, they return a Promise that is resolved or rejected based on the success of method execution.
|
||||
> Please note that `exists` method will always throw, since it was [deprecated](https://nodejs.org/api/fs.html#fs_fs_exists_path_callback) by Node.
|
||||
|
||||
See example below:
|
||||
|
||||
```javascript
|
||||
const fs = new Filer.FileSystem().promises;
|
||||
fs.open('/myfile', 'w+')
|
||||
.then(fd => fs.close(fd))
|
||||
.then(() => fs.stat('/myfile'))
|
||||
.then(stats => { console.log(`stats: ${JSON.stringify(stats)}`); })
|
||||
.catch(err => { console.error(err); })
|
||||
```
|
||||
> The callback style usage could be found [here](#overviewExample).
|
||||
#### Filer.FileSystem(options, callback) constructor
|
||||
|
||||
File system constructor, invoked to open an existing file system or create a new one.
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -35,6 +35,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"base64-arraybuffer": "^0.1.5",
|
||||
"es6-promisify": "^6.0.0",
|
||||
"minimatch": "^3.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -1901,6 +1901,7 @@ function exists(fs, context, path, callback) {
|
|||
function cb(err) {
|
||||
callback(err ? false : true);
|
||||
}
|
||||
console.warn('This method is deprecated. For more details see https://nodejs.org/api/fs.html#fs_fs_exists_path_callback');// eslint-disable-line no-console
|
||||
stat(fs, context, path, cb);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
var _ = require('../../lib/nodash.js');
|
||||
var { promisify } = require('es6-promisify');
|
||||
|
||||
var isNullPath = require('../path.js').isNull;
|
||||
var nop = require('../shared.js').nop;
|
||||
|
@ -262,94 +263,97 @@ function FileSystem(options, callback) {
|
|||
impl.ensureRootDirectory(context, complete);
|
||||
}
|
||||
});
|
||||
FileSystem.prototype.promises = {};
|
||||
/**
|
||||
* Public API for FileSystem
|
||||
*/
|
||||
[
|
||||
'open',
|
||||
'chmod',
|
||||
'fchmod',
|
||||
'chown',
|
||||
'fchown',
|
||||
'close',
|
||||
'mknod',
|
||||
'mkdir',
|
||||
'rmdir',
|
||||
'stat',
|
||||
'fstat',
|
||||
'link',
|
||||
'unlink',
|
||||
'read',
|
||||
'readFile',
|
||||
'write',
|
||||
'writeFile',
|
||||
'appendFile',
|
||||
'exists',
|
||||
'lseek',
|
||||
'readdir',
|
||||
'rename',
|
||||
'readlink',
|
||||
'symlink',
|
||||
'lstat',
|
||||
'truncate',
|
||||
'ftruncate',
|
||||
'utimes',
|
||||
'futimes',
|
||||
'setxattr',
|
||||
'getxattr',
|
||||
'fsetxattr',
|
||||
'fgetxattr',
|
||||
'removexattr',
|
||||
'fremovexattr'
|
||||
].forEach(function(methodName) {
|
||||
FileSystem.prototype[methodName] = function() {
|
||||
var fs = this;
|
||||
var args = Array.prototype.slice.call(arguments, 0);
|
||||
var lastArgIndex = args.length - 1;
|
||||
|
||||
// We may or may not get a callback, and since node.js supports
|
||||
// fire-and-forget style fs operations, we have to dance a bit here.
|
||||
var missingCallback = typeof args[lastArgIndex] !== 'function';
|
||||
var callback = maybeCallback(args[lastArgIndex]);
|
||||
|
||||
var error = fs.queueOrRun(function() {
|
||||
var context = fs.provider.openReadWriteContext();
|
||||
|
||||
// Fail early if the filesystem is in an error state (e.g.,
|
||||
// provider failed to open.
|
||||
if(FS_ERROR === fs.readyState) {
|
||||
var err = new Errors.EFILESYSTEMERROR('filesystem unavailable, operation canceled');
|
||||
return callback.call(fs, err);
|
||||
}
|
||||
|
||||
// Wrap the callback so we can explicitly close the context
|
||||
function complete() {
|
||||
context.close();
|
||||
callback.apply(fs, arguments);
|
||||
}
|
||||
|
||||
// Either add or replace the callback with our wrapper complete()
|
||||
if(missingCallback) {
|
||||
args.push(complete);
|
||||
} else {
|
||||
args[lastArgIndex] = complete;
|
||||
}
|
||||
|
||||
// Forward this call to the impl's version, using the following
|
||||
// call signature, with complete() as the callback/last-arg now:
|
||||
// fn(fs, context, arg0, arg1, ... , complete);
|
||||
var fnArgs = [fs, context].concat(args);
|
||||
impl[methodName].apply(null, fnArgs);
|
||||
});
|
||||
if(error) {
|
||||
callback(error);
|
||||
}
|
||||
};
|
||||
|
||||
FileSystem.prototype.promises[methodName] = promisify(FileSystem.prototype[methodName].bind(fs));
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// Expose storage providers on FileSystem constructor
|
||||
FileSystem.providers = providers;
|
||||
|
||||
/**
|
||||
* Public API for FileSystem
|
||||
*/
|
||||
[
|
||||
'open',
|
||||
'chmod',
|
||||
'fchmod',
|
||||
'chown',
|
||||
'fchown',
|
||||
'close',
|
||||
'mknod',
|
||||
'mkdir',
|
||||
'rmdir',
|
||||
'stat',
|
||||
'fstat',
|
||||
'link',
|
||||
'unlink',
|
||||
'read',
|
||||
'readFile',
|
||||
'write',
|
||||
'writeFile',
|
||||
'appendFile',
|
||||
'exists',
|
||||
'lseek',
|
||||
'readdir',
|
||||
'rename',
|
||||
'readlink',
|
||||
'symlink',
|
||||
'lstat',
|
||||
'truncate',
|
||||
'ftruncate',
|
||||
'utimes',
|
||||
'futimes',
|
||||
'setxattr',
|
||||
'getxattr',
|
||||
'fsetxattr',
|
||||
'fgetxattr',
|
||||
'removexattr',
|
||||
'fremovexattr'
|
||||
].forEach(function(methodName) {
|
||||
FileSystem.prototype[methodName] = function() {
|
||||
var fs = this;
|
||||
var args = Array.prototype.slice.call(arguments, 0);
|
||||
var lastArgIndex = args.length - 1;
|
||||
|
||||
// We may or may not get a callback, and since node.js supports
|
||||
// fire-and-forget style fs operations, we have to dance a bit here.
|
||||
var missingCallback = typeof args[lastArgIndex] !== 'function';
|
||||
var callback = maybeCallback(args[lastArgIndex]);
|
||||
|
||||
var error = fs.queueOrRun(function() {
|
||||
var context = fs.provider.openReadWriteContext();
|
||||
|
||||
// Fail early if the filesystem is in an error state (e.g.,
|
||||
// provider failed to open.
|
||||
if(FS_ERROR === fs.readyState) {
|
||||
var err = new Errors.EFILESYSTEMERROR('filesystem unavailable, operation canceled');
|
||||
return callback.call(fs, err);
|
||||
}
|
||||
|
||||
// Wrap the callback so we can explicitly close the context
|
||||
function complete() {
|
||||
context.close();
|
||||
callback.apply(fs, arguments);
|
||||
}
|
||||
|
||||
// Either add or replace the callback with our wrapper complete()
|
||||
if(missingCallback) {
|
||||
args.push(complete);
|
||||
} else {
|
||||
args[lastArgIndex] = complete;
|
||||
}
|
||||
|
||||
// Forward this call to the impl's version, using the following
|
||||
// call signature, with complete() as the callback/last-arg now:
|
||||
// fn(fs, context, arg0, arg1, ... , complete);
|
||||
var fnArgs = [fs, context].concat(args);
|
||||
impl[methodName].apply(null, fnArgs);
|
||||
});
|
||||
if(error) {
|
||||
callback(error);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
module.exports = FileSystem;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
var {promisify} = require('es6-promisify');
|
||||
var Path = require('../path.js');
|
||||
var Errors = require('../errors.js');
|
||||
var Environment = require('./environment.js');
|
||||
|
@ -56,6 +57,24 @@ function Shell(fs, options) {
|
|||
this.pwd = function() {
|
||||
return cwd;
|
||||
};
|
||||
|
||||
this.promises = {};
|
||||
/**
|
||||
* Public API for Shell converted to Promise based
|
||||
*/
|
||||
[
|
||||
'cd',
|
||||
'exec',
|
||||
'touch',
|
||||
'cat',
|
||||
'ls',
|
||||
'rm',
|
||||
'tempDir',
|
||||
'mkdirp',
|
||||
'find'
|
||||
].forEach((methodName)=>{
|
||||
this.promises[methodName] = promisify(this[methodName].bind(this));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue