Skip to content

Commit 69f6f9f

Browse files
committed
Update README
1 parent 11ff6f5 commit 69f6f9f

File tree

6 files changed

+51
-54
lines changed

6 files changed

+51
-54
lines changed

README.md

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,46 @@
1-
# isomorphic-pgp
1+
# @isomorphic-git/lightning-fs
22

3-
A lightweight library for creating and verifying OpenPGP signatures
3+
A lean and fast 'fs' for the browser
44

55
## Motivation
66

7-
PGP is the cryptographic standard used to sign git commits, and I wanted to provide `isomorphic-git` users a way
8-
to tap into that power without sacrificing bundle size or worrying about LGPL restrictions.
9-
So I wrote an entirely new JavaScript library with that narrow use case in mind.
7+
I wanted to see if I could make something faster than [BrowserFS](https://github.com/jvilk/BrowserFS) or [filer](https://github.com/filerjs/filer) that still implements enough of the `fs` API to run the [`isomorphic-git`](https://github.com/isomorphic-git/isomorphic-git) test suite in browsers.
108

11-
## IMPORTANT!!!
9+
## Comparison with other libraries
1210

13-
Please read and understand the limitations of the [`sign-and-verify`](https://github.com/wmhilton/isomorphic-pgp/tree/master/src/sign-and-verify) module before using it.
11+
This library does not even come close to implementing the full [`fs`](https://nodejs.org/api/fs.html) API.
12+
Instead, it only implements [the subset used by isomorphic-git 'fs' plugin interface](https://isomorphic-git.org/docs/en/plugin_fs).
1413

15-
## Comparison with other libraries
14+
Unlike BrowserFS, which has a dozen backends and is highly configurable, `lightning-fs` has a single configuration that should Just Work for most users.
1615

17-
This library does not implement encryption or decryption - only signing and verifying signatures.
16+
## Philosophy
1817

19-
| | Size | License | Sign | Verify | Encrypt | Decrypt |
20-
|---|------|---------|------|--------|---------|---------|
21-
| isomorphic-pgp | [~17 kb](https://bundlephobia.com/result?p=@isomorphic-git/[email protected]) | MIT | 🗹 | 🗹 |||
22-
| OpenPGP.js | [~170 kb](https://bundlephobia.com/[email protected]) | LGPL | 🗹 | 🗹 | 🗹 | 🗹 |
23-
| kbpgp | [~160 kb](https://bundlephobia.com/[email protected]) | BSD | 🗹 | 🗹 | 🗹 | 🗹 |
18+
### Basic requirements:
2419

25-
## Usage
20+
1. needs to work in all modern browsers
21+
2. needs to work with large-ish files and directories
22+
3. needs to persist data
23+
4. needs to enable performant web apps
24+
25+
Req #3 excludes pure in-memory solutions. Req #4 excludes `localStorage` because it blocks the DOM and cannot be run in a webworker. Req #1 excludes WebSQL and Chrome's FileSystem API. So that leaves us with IndexedDB as the only usable storage technology.
26+
27+
### Optimization targets (in order of priority):
2628

27-
See individual READMEs for each package:
29+
1. speed (time it takes to execute file system operations)
30+
2. bundle size (time it takes to download the library)
31+
3. memory usage (will it work on mobile)
32+
33+
In order to get improve #1, I ended up making a hybrid in-memory / IndexedDB system:
34+
- `mkdir`, `rmdir`, `readdir`, and `stat` are pure in-memory operations that take 0ms
35+
- `writeFile`, `readFile`, and `unlink` are throttled by IndexedDB
36+
37+
The in-memory portion of the filesystem is persisted to IndexedDB with a debounce of 500ms.
38+
The files themselves are not currently cached in memory, because I don't want to waste a lot of memory.
39+
Applications can always *add* an LRU cache on top of `lightning-fs` - if I add one internally and it isn't tuned well for your application, it might be much harder to work around.
40+
41+
## Usage
2842

29-
- [parser](https://github.com/wmhilton/isomorphic-pgp/tree/master/src/parser)
30-
- [util](https://github.com/wmhilton/isomorphic-pgp/tree/master/src/util)
31-
- [sign-and-verify](https://github.com/wmhilton/isomorphic-pgp/tree/master/src/sign-and-verify)
32-
- [generate](https://github.com/wmhilton/isomorphic-pgp/tree/master/src/generate)
43+
TODO
3344

3445
## License
3546

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
"publishConfig": {
33
"access": "public"
44
},
5-
"name": "@isomorphic-git/idb-fs",
5+
"name": "@isomorphic-git/lightning-fs",
66
"version": "0.0.0",
77
"description": "A lean and fast 'fs' for the browser",
8-
"main": "index.js",
8+
"main": "src/index.js",
99
"bin": {
1010
"superblocktxt": "src/superblocktxt.js"
1111
},
@@ -36,7 +36,7 @@
3636
},
3737
"repository": {
3838
"type": "git",
39-
"url": "git+https://github.com/isomorphic-git/idb-fs.git"
39+
"url": "git+https://github.com/isomorphic-git/lightning-fs.git"
4040
},
4141
"files": [
4242
"**/*.js",
@@ -52,7 +52,7 @@
5252
"author": "William Hilton <[email protected]>",
5353
"license": "MIT",
5454
"bugs": {
55-
"url": "https://github.com/isomorphic-git/idb-fs/issues"
55+
"url": "https://github.com/isomorphic-git/lightning-fs/issues"
5656
},
57-
"homepage": "https://github.com/isomorphic-git/idb-fs#readme"
57+
"homepage": "https://github.com/isomorphic-git/lightning-fs#readme"
5858
}

src/CacheFS.js

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,47 +5,41 @@ const STAT = 0;
55

66
module.exports = class CacheFS {
77
constructor() {
8-
const root = this._makeRoot();
9-
this._root = new Map([["/", root]]);
8+
this._root = new Map([["/", this._makeRoot()]]);
109
}
11-
_makeRoot(root) {
12-
root = root || new Map();
13-
let stat = { mode: 0o777, type: "dir", size: 0, mtimeMs: Date.now() };
14-
root.set(STAT, stat);
10+
_makeRoot(root = new Map()) {
11+
root.set(STAT, { mode: 0o777, type: "dir", size: 0, mtimeMs: Date.now() });
1512
return root
1613
}
1714
loadSuperBlock(superblock) {
1815
if (typeof superblock === 'string') {
19-
let root = this.parse(superblock)
20-
root = this._makeRoot(root);
21-
this._root = new Map([["/", root]]);
16+
this._root = new Map([["/", this._makeRoot(this.parse(superblock))]]);
2217
} else {
2318
this._root = superblock
2419
}
2520
}
26-
print(root) {
27-
root = root || this._root.get("/")
21+
print(root = this._root.get("/")) {
2822
let str = "";
2923
const printTree = (root, indent) => {
3024
for (let [file, node] of root) {
3125
if (file === 0) continue;
3226
let stat = node.get(STAT);
3327
let mode = stat.mode.toString(8);
28+
str += `${"\t".repeat(indent)}${file}\t${mode}`
3429
if (stat.type === "file") {
35-
str += `\n${"\t".repeat(indent)}${file}\t${mode}\t${stat.size}\t${
36-
stat.mtimeMs
37-
}`;
30+
str += `\t${stat.size}\t${stat.mtimeMs}\n`;
3831
} else {
39-
str += `\n${"\t".repeat(indent)}${file}\t${mode}`;
32+
str += `\n`
4033
printTree(node, indent + 1);
4134
}
4235
}
4336
};
4437
printTree(root, 0);
45-
return str.trimStart() + '\n';
38+
return str;
4639
}
4740
parse(print) {
4841
function mk(stat) {
42+
// TODO: Use a better heuristic for determining whether file or dir
4943
if (stat.length === 1) {
5044
let [mode] = stat
5145
mode = parseInt(mode, 8);
@@ -68,7 +62,6 @@ module.exports = class CacheFS {
6862
{ indent: 0, node: null }
6963
];
7064
for (let line of lines) {
71-
// let [, prefix, filename, stat]
7265
let prefix = line.match(/^\t*/)[0];
7366
let indent = prefix.length;
7467
line = line.slice(indent);

src/HttpBackend.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module.exports = class IdbBackend {
1+
module.exports = class HttpBackend {
22
constructor(url) {
33
this._url = url;
44
}

src/__tests__/fallback.spec.js

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,7 @@ describe("http fallback", () => {
2222
done();
2323
});
2424
});
25-
it("read child dir /0", done => {
26-
fs.readdir("/0", (err, data) => {
27-
expect(err).toBe(null);
28-
expect(data).toEqual(['a.txt', 'b.txt', 'c.txt'])
29-
done();
30-
});
31-
});
32-
it("read child dir /1", done => {
25+
it("read child dir", done => {
3326
fs.readdir("/1", (err, data) => {
3427
expect(err).toBe(null);
3528
expect(data).toEqual(['d.txt', 'e.txt', 'f.txt'])
@@ -63,9 +56,9 @@ describe("http fallback", () => {
6356

6457
describe("writeFile", () => {
6558
it("writing a file overwrites the server version", done => {
66-
fs.writeFile("/a.txt", "welcome", (err) => {
59+
fs.writeFile("/b.txt", "welcome", (err) => {
6760
expect(err).toBe(null)
68-
fs.readFile("/a.txt", 'utf8', (err, data) => {
61+
fs.readFile("/b.txt", 'utf8', (err, data) => {
6962
expect(err).toBe(null);
7063
expect(data).toEqual('welcome');
7164
done();

src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const IdbBackend = require("./IdbBackend.js");
1010
const HttpBackend = require("./HttpBackend.js")
1111
const clock = require("./clock.js");
1212

13-
export default class FS {
13+
module.exports = class FS {
1414
constructor(name, { wipe, url } = {}) {
1515
this._backend = new IdbBackend(name);
1616
this._cache = new CacheFS(name);

0 commit comments

Comments
 (0)