Skip to content

Commit

Permalink
Documentation improvements for 1.4.0.
Browse files Browse the repository at this point in the history
  • Loading branch information
John Vilk committed Jul 24, 2017
1 parent b27491a commit b72de19
Show file tree
Hide file tree
Showing 18 changed files with 419 additions and 117 deletions.
90 changes: 65 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ BrowserFS is highly extensible, and ships with many filesystem backends:
* `WorkerFS`: Lets you mount the BrowserFS file system configured in the main thread in a WebWorker, or the other way around!
* `MountableFileSystem`: Lets you mount multiple file systems into a single directory hierarchy, as in *nix-based OSes.
* `OverlayFS`: Mount a read-only file system as read-write by overlaying a writable file system on top of it. Like Docker's overlayfs, it will only write changed files to the writable file system.
* `AsyncMirrorFS`: Use an asynchronous backend synchronously. Invaluable for Emscripten; let your Emscripten applications write to larger file stores with no additional effort!
* `AsyncMirror`: Use an asynchronous backend synchronously. Invaluable for Emscripten; let your Emscripten applications write to larger file stores with no additional effort!
* Note: Loads the entire contents of the file system into a synchronous backend during construction. Performs synchronous operations in-memory, and enqueues them to be mirrored onto the asynchronous backend.
* `FolderAdapter`: Wraps a file system, and scopes all interactions to a subfolder of that file system.
* `Emscripten`: Lets you mount Emscripten file systems inside BrowserFS.

More backends can be defined by separate libraries, so long as they extend the `BaseFileSystem`. Multiple backends can be active at once at different locations in the directory hierarchy.
More backends can be defined by separate libraries, so long as they extend the `BaseFileSystem` class. Multiple backends can be active at once at different locations in the directory hierarchy.

For more information, see the [API documentation for BrowserFS](https://jvilk.com/browserfs/1.3.0/index.html).

Expand All @@ -52,6 +52,8 @@ and re-build.

### Using

Using `BrowserFS.configure()`, you can easily configure BrowserFS to use a variety of file system types.

Here's a simple usage example using the LocalStorage-backed file system:

```html
Expand All @@ -64,10 +66,16 @@ Here's a simple usage example using the LocalStorage-backed file system:
// You can pass in an arbitrary object if you do not wish to pollute
// the global namespace.
BrowserFS.install(window);
// Constructs an instance of the LocalStorage-backed file system.
var lsfs = new BrowserFS.FileSystem.LocalStorage();
// Initialize it as the root file system.
BrowserFS.initialize(lsfs);
// Configures BrowserFS to use the LocalStorage file system.
BrowserFS.configure({
fs: "LocalStorage"
}, function(e) {
if (e) {
// An error happened!
throw e;
}
// Otherwise, BrowserFS is ready-to-use!
});
</script>
```

Expand All @@ -82,6 +90,38 @@ fs.writeFile('/test.txt', 'Cool, I can do this in the browser!', function(err) {
});
```

The following code mounts a zip file to `/zip`, in-memory storage to `/tmp`, and IndexedDB browser-local storage to `/home`:

```js
// Note: This is the new fetch API in the browser. You can use XHR too.
fetch('mydata.zip').then(function(response) {
return response.arraybuffer();
}).then(function(zipData) {
var Buffer = BrowserFS.BFSRequire('buffer').Buffer;

BrowserFS.configure({
fs: "MountableFileSystem",
options: {
"/zip": {
fs: "ZipFS",
options: {
// Wrap as Buffer object.
zipData: Buffer.from(zipData)
}
},
"/tmp": { fs: "InMemory" },
"/home": { fs: "IndexedDB" }
}
}, function(e) {
if (e) {
// An error occurred.
throw e;
}
// Otherwise, BrowserFS is ready to use!
});
});
```

### Using with Browserify and Webpack

BrowserFS is published as a UMD module, so you can either include it on your webpage in a `script` tag or bundle it with your favorite
Expand Down Expand Up @@ -154,17 +194,13 @@ simply `require('browserfs/dist/node/index')` instead.
You can use any *synchronous* BrowserFS file systems with Emscripten!
Persist particular folders in the Emscripten file system to `localStorage`, or enable Emscripten to synchronously download files from another folder as they are requested.

Include `browserfs.min.js` into the page, and add code similar to the following to your `Module`'s `preRun` array:
Include `browserfs.min.js` into the page, and configure BrowserFS prior to running your Emscripten code. Then, add code similar to the following to your `Module`'s `preRun` array:

```javascript
/**
* Mounts a localStorage-backed file system into the /data folder of Emscripten's file system.
*/
function setupBFS() {
// Constructs an instance of the LocalStorage-backed file system.
var lsfs = new BrowserFS.FileSystem.LocalStorage();
// Initialize it as the root file system.
BrowserFS.initialize(lsfs);
// Grab the BrowserFS Emscripten FS plugin.
var BFS = new BrowserFS.EmscriptenFS();
// Create the folder that we'll turn into a mount point.
Expand All @@ -184,20 +220,24 @@ If you wish to use an asynchronous BrowserFS backend with Emscripten (e.g. Dropb
* @param dropboxClient An authenticated DropboxJS client.
*/
function asyncSetup(dropboxClient, cb) {
var dbfs = new BrowserFS.FileSystem.Dropbox(dropboxClient);
// Wrap in AsyncMirrorFS.
var asyncMirror = new BrowserFS.FileSystem.AsyncMirror(
new BrowserFS.FileSystem.InMemory(), dbfs);

// Downloads the entire contents of the Dropbox backend into memory.
// You'll probably want to use an app folder, and check that you
// aren't pulling in a huge amount of data here.
asyncMirror.initialize(function(err) {
// Initialize it as the root file system.
BrowserFS.initialize(asyncMirror);
// BFS is ready for Emscripten!
cb();
});
// This wraps Dropbox in the AsyncMirror file system.
// BrowserFS will download all of Dropbox into an
// InMemory file system, and mirror operations to
// the two to keep them in sync.
BrowserFS.configure({
fs: "AsyncMirror",
options: {
sync: {
fs: "InMemory"
},
async: {
fs: "Dropbox",
options: {
client: dropboxClient
}
}
}
}, cb);
}
function setupBFS() {
// Grab the BrowserFS Emscripten FS plugin.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@
"test": "npm-run-all test:prepare test:karma",
"watch-test": "npm-run-all test:prepare --parallel watch:scripts test:watch test:karma",
"prepublish": "npm run dist",
"docs": "typedoc --mode file --out doc --excludePrivate --readme src/DOCS.md --name BrowserFS src"
"docs": "typedoc --mode modules --out doc --excludePrivate --readme src/DOCS.md --name BrowserFS --module umd src"
},
"dependencies": {
"async": "^2.1.4",
Expand Down
140 changes: 121 additions & 19 deletions src/DOCS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,118 @@ BrowserFS is an in-browser file system that emulates the [Node JS file system AP

The [README](https://github.com/jvilk/browserfs) provides an overview of how to integrate BrowserFS into your project. This API documentation will focus on how to use BrowserFS once you have added it to your project.

## BrowserFS Interface
## Configuring BrowserFS

The main BrowserFS interface is [documented here](interfaces/browserfs.html).
The main BrowserFS interface is [documented here](modules/_core_browserfs_.html).

Before you can use BrowserFS, you must initialize it with a single root file system backend using `BrowserFS.initialize`. Think of this as your "storage device".
Before you can use BrowserFS, you need to answer the following questions:

If you need to use multiple "storage devices", instantiate multiple file system backend types, mount them into a `MountableFileSystem` backend, and then use that as the root file system for BrowserFS.
1. **What file system backends do I want to use?**
2. **What configuration options do I pass to each?**

### What Backend(s) to Use?

Before you can use BrowserFS, you must initialize it with a single root file system backend. Think of each backend
as a "storage device". It can be read-only (a zip file or an ISO), read-write (browser-local IndexedDB storage),
and it can even be cloud storage (Dropbox).

If you need to use multiple "storage devices", you can use the `MountableFileSystem` backend to "mount" backends at
different locations in the directory hierarchy.

There are all sorts of adapter file systems available to make it easy to access files stored in Emscripten, files stored in a different context (e.g., a web worker), isolate file operations to a particular folder, access asynchronous storage backends synchronously, and more!

Check out the "Overview" of backends below for a list of backends and their capabilities.

### What Configuration Options For Each?

Different backends require different configuration options. Review the documentation page for each backend you want to use, and note the options passed to its `Create()` method. Some are optional, others are required.

### Putting It All Together

Once you know the backend(s) you want to use, and the options to pass to each, you can configure BrowserFS with a single configuration object:

```javascript
BrowserFS.configure({
fs: "name of file system type" // from Backends table below,
options: {
// options for the file system
}
}, function (e) {
if (e) {
// An error occurred.
throw e;
}
// Otherwise, you can interact with the configured backends via our Node FS polyfill!
var fs = BrowserFS.BFSRequire('fs');
fs.readdir('/', function(e, contents) {
// etc.
});
});
```

In the case where a file system's options object takes another file system, you can nest another configuration object
in place of the actual file system object:

```javascript
var Buffer = BrowserFS.BFSRequire('buffer').Buffer;
BrowserFS.configure({
fs: "OverlayFS",
options: {
readable: {
fs: "ZipFS",
options: {
zipData: Buffer.from(zipDataAsArrayBuffer)
}
},
writable: {
fs: "LocalStorage"
}
}
}, function(e) {

});
```

Using this method, it's easy to configure mount points in the `MountableFileSystem`:

```javascript
BrowserFS.configure({
fs: "MountableFileSystem",
options: {
'/tmp': { fs: "InMemory" },
'/home': { fs: "IndexedDB" },
'/mnt/usb0': { fs: "LocalStorage" }
}
}, function(e) {

});
```

### Advanced Usage

If `BrowserFS.configure` is not to your liking, you can manually instantiate file system backends and pass the root backend to BrowserFS via its `BrowserFS.initialize()` function.

```javascript
BrowserFS.FileSystem.LocalStorage.Create(function(e, lsfs) {
BrowserFS.FileSystem.InMemory.Create(function(e, inMemory) {
BrowserFS.FileSystem.IndexedDB.Create({}, function(e, idbfs) {
BrowserFS.FileSystem.MountableFileSystem.Create({
'/tmp': inMemory,
'/home': idbfs,
'/mnt/usb0': lsfs
}, function(e, mfs) {
BrowserFS.initialize(mfs);
// BFS is now ready to use!
});
});
});
});
```

## Usage with Emscripten

Once you have configured BrowserFS, you can mount it into the Emscripten file system. More details are in the BrowserFS [README](https://github.com/jvilk/browserfs).

## Overview of Backends

**Key:**
Expand All @@ -22,7 +124,7 @@ There are all sorts of adapter file systems available to make it easy to access
* ✗ means 'no'
* ? means 'depends on configuration'

Note that any asynchronous file system can be accessed synchronously using the [AsyncMirror](classes/asyncmirror.html) file system.
Note that any asynchronous file system can be accessed synchronously using the [AsyncMirror](classes/_backend_asyncmirror_.asyncmirror.html) file system at the cost of preloading the entire file system into some synchronous backend (e.g., `InMemory`).

<table>
<tr>
Expand All @@ -38,98 +140,98 @@ Note that any asynchronous file system can be accessed synchronously using the [
<th>Links</th>
</tr>
<tr>
<td><a href="classes/asyncmirror.html">AsyncMirror</a></td>
<td><a href="classes/_backend_asyncmirror_.asyncmirror.html">AsyncMirror</a></td>
<td>✓</td>
<td>✓</td>
<td>✗</td>
<td>✗</td>
</tr>
<tr>
<td><a href="classes/dropboxfilesystem.html">Dropbox</a></td>
<td><a href="classes/_backend_dropbox_.dropboxfilesystem.html">Dropbox</a></td>
<td>✓</td>
<td>✗</td>
<td>✗</td>
<td>✗</td>
</tr>
<tr>
<td><a href="classes/emscriptenfilesystem.html">Emscripten</a></td>
<td><a href="classes/_backend_emscripten_.emscriptenfilesystem.html">Emscripten</a></td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<td><a href="classes/folderadapter.html">FolderAdapter</a></td>
<td><a href="classes/_backend_folderadapter_.folderadapter.html">FolderAdapter</a></td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>✗</td>
</tr>
<tr>
<td><a href="classes/html5fs.html">HTML5FS</a></td>
<td><a href="classes/_backend_html5fs_.html5fs.html">HTML5FS</a></td>
<td>✓</td>
<td>✗</td>
<td>✗</td>
<td>✗</td>
</tr>
<tr>
<td><a href="classes/indexeddbfilesystem.html">IndexedDB</a></td>
<td><a href="classes/_backend_indexeddb_.indexeddbfilesystem.html">IndexedDB</a></td>
<td>✓</td>
<td>✗</td>
<td>✗</td>
<td>✗</td>
</tr>
<tr>
<td><a href="classes/inmemoryfilesystem.html">InMemory</a></td>
<td><a href="classes/_backend_inmemory_.inmemoryfilesystem.html">InMemory</a></td>
<td>✓</td>
<td>✓</td>
<td>✗</td>
<td>✗</td>
</tr>
<tr>
<td><a href="classes/isofs.html">IsoFS</a></td>
<td><a href="classes/_backend_isofs_.isofs.html">IsoFS</a></td>
<td>✗</td>
<td>✓</td>
<td>✗</td>
<td>✗</td>
</tr>
<tr>
<td><a href="classes/localstoragefilesystem.html">LocalStorage</a></td>
<td><a href="classes/_backend_localstorage_.localstoragefilesystem.html">LocalStorage</a></td>
<td>✓</td>
<td>✓</td>
<td>✗</td>
<td>✗</td>
</tr>
<tr>
<td><a href="classes/mountablefilesystem.html">MountableFileSystem</a></td>
<td><a href="classes/_backend_mountablefilesystem_.mountablefilesystem.html">MountableFileSystem</a></td>
<td>?</td>
<td>?</td>
<td>?</td>
<td>?</td>
</tr>
<tr>
<td><a href="classes/overlayfs.html">OverlayFS</a></td>
<td><a href="classes/_backend_overlayfs_.overlayfs.html">OverlayFS</a></td>
<td>✓</td>
<td>?</td>
<td>?</td>
<td>✗</td>
</tr>
<tr>
<td><a href="classes/xmlhttprequest.html">XmlHttpRequest</a></td>
<td><a href="classes/_backend_xmlhttprequest_.xmlhttprequest.html">XmlHttpRequest</a></td>
<td>✗</td>
<td>✓</td>
<td>✗</td>
<td>✗</td>
</tr>
<tr>
<td><a href="classes/workerfs.html">WorkerFS</a></td>
<td><a href="classes/_backend_workerfs_.workerfs.html">WorkerFS</a></td>
<td>?</td>
<td>✗</td>
<td>?</td>
<td>?</td>
</tr>
<tr>
<td><a href="classes/zipfs.html">ZipFS</a></td>
<td><a href="classes/_backend_zipfs_.zipfs.html">ZipFS</a></td>
<td>✗</td>
<td>✓</td>
<td>✗</td>
Expand Down

0 comments on commit b72de19

Please sign in to comment.