Filesystem is one of the core components of Bespin, providing high-level API for files / directory manipulations. It is a wrapper of FileSources a low-level files / directory access providers.
Filesystem API is exposed to the plugins through editorapp
module's
files
property and through the same named property on env
object
/ argument that is passed to the extension endpoints.
Filesystem can allow FileSource
"mounting" to any given point on the
filesystem, or on a custom URI scheme, much like it is in unix. This will
allow plugins to expose access to a different resources in a standard manner
just by implementing a few core filesource access functions. Good plugin
examples may be:
- Github plugin exposing user gists under certain mounting point
- Jetpack based plugin exposing a local file system.
Plugins interested in providing custom filsources would have to provide
"filsource" extension point pointing to an instance of FileSource
. Instance
can be created form FileSource class, by providing a set of methods mentioned
in the next section to FileSource.create
. FileSource
class all of most the
optional methods on top of mandatory ones. Obviously plugin providers are in
power to override them to achieve more efficiency by introducing optimizations
specific to their scenarios. Big part of the FileSystem
will be move to a
FileSource
. FileSystem
will take a role of a router between mounted
FileSystems
.
###Filesystem###
-
mount(pathOrURIScheme:String, fileSource:FileSource)
Mounts filesource to a specified path / uri scheme. After successful mount all the file filesystem operations on the subpaths will be done using registered fileSource. In case if multiple filesystems will end up being mounted to the same mounting point the last registered will be used.- pathOrURIScheme - String representing one of of the followings:
- '/' Root of the filesystem
- Path representing an entry of the existing directory in the filesystem (Assuming that filesystem root exists even if no filesource is mounted yet.)
- Custom uri scheme like "gist:"
- fileSource - Object implementing FileSource interface (described in next section)
- pathOrURIScheme - String representing one of of the followings:
-
unmount(pathOrURIScheme:String, fileSource:FileSource)
Unmounts filesource from specified path / uri scheme if it was mounted before. If this fileSource was overriding another one after unmount previously overrided filesystem will become active.
###FileSource###
Mandatory
- invalidate(path:String)
- read(path:String):Promise
- write(path:String):Promise
- list(path:String):Promise
- remove(path:String):Promise
- makeDirectory(path:String):Promise
Optional (may provide faster implementation)
- isFile(path:String):Promise
- isDirectory(path:String):Promise
- rename(path:String, name:String):Promise
- move(path):Promise
- makeTree(path):Promise
- copy(source, target):Promise
- copyTree(source, target):Promise
- listTree(path):Promise
Plugins example "define metadata";
{ "description": "Provides the gist filesystem", "dependencies": { "filesystem": "0.0", "settings": "0.0", "github": "0.0" }, "provides": [ { "ep": "filesource", "name": "gist", "pointer": "#source" } ] } "end"; var Promise = require('bespin:promise').Promise; var FileSource = require('filesystem').FileSource; var gist = require('github/yql-gist'); var settings = require('settings').settings; var user = settings.get("github-user"); var token = settings.get("github-token"); function getId(path) { return path.substr(path.lastIndexOf('/')); } exports.source = FileSource.create({ mountPoint: "/gists/", read: function(path) { var result = new Promise(); gist.read({ repo: getId(path), user: user, token: token }, function(content) { result.resolve(content); }, promise.reject) return result; }, write: function(path, content) { var result = new Promise(); gist.write({ repo: getId(path), user: user, token: token, content: content }, function(id) { result.resolve(this.mountPoint + id); }, promise.reject) return result; }, list: function(path) { var result = new Promise(); gist.write({ user: user, token: token }, function(gists) { result.resolve(gists.map(function(id) return this.mountPoint + id; )); }, promise.reject) return result; }, remove: function(path) { var result = new Promise(); gist.remove({ repo: getId(path), user: user, token: token }, result.resolve, promise.reject) return result; } makeDirectory: function(path) { // You can't have dirs in }, invalidate: function(path) { // I don't cache anything so not much to invalidate } });