Skip to content

Commit 1f07e10

Browse files
committed
documentation
1 parent ecef48e commit 1f07e10

File tree

1 file changed

+69
-10
lines changed

1 file changed

+69
-10
lines changed

README.md

Lines changed: 69 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,17 @@ const fs = new FS("testfs")
5959

6060
Options object:
6161

62-
| Param | Type [= default] | Description |
63-
| --------------- | ------------------ | --------------------------------------------------------------------- |
64-
| `wipe` | boolean = false | Delete the database and start with an empty filesystem |
65-
| `url` | string = undefined | Let `readFile` requests fall back to an HTTP request to this base URL |
66-
| `urlauto` | boolean = false | Fall back to HTTP for every read of a missing file, even if unbacked |
67-
| `fileDbName` | string | Customize the database name |
68-
| `fileStoreName` | string | Customize the store name |
69-
| `lockDbName` | string | Customize the database name for the lock mutex |
70-
| `lockStoreName` | string | Customize the store name for the lock mutex |
71-
| `defer` | boolean = false | If true, avoids mutex contention during initialization |
62+
| Param | Type [= default] | Description |
63+
| --------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
64+
| `wipe` | boolean = false | Delete the database and start with an empty filesystem |
65+
| `url` | string = undefined | Let `readFile` requests fall back to an HTTP request to this base URL |
66+
| `urlauto` | boolean = false | Fall back to HTTP for every read of a missing file, even if unbacked |
67+
| `fileDbName` | string | Customize the database name |
68+
| `fileStoreName` | string | Customize the store name |
69+
| `lockDbName` | string | Customize the database name for the lock mutex |
70+
| `lockStoreName` | string | Customize the store name for the lock mutex |
71+
| `defer` | boolean = false | If true, avoids mutex contention during initialization |
72+
| `backend` | IBackend | If present, none of the other arguments (except `defer`) have any effect, and instead of using the normal LightningFS stuff, LightningFS acts as a wrapper around the provided custom backend. |
7273

7374
#### Advanced usage
7475

@@ -191,6 +192,64 @@ Returns the size of a file or directory in bytes.
191192

192193
All the same functions as above, but instead of passing a callback they return a promise.
193194

195+
## Providing a custom `backend` (advanced usage)
196+
197+
There are only two reasons I can think of that you would want to do this:
198+
199+
1. The `fs` module is normally a singleton. LightningFS allows you to safely(ish) hotswap between various data sources by calling `init` multiple times with different options. (It keeps track of file system operations in flight and waits until there's an idle moment to do the switch.)
200+
201+
2. LightningFS normalizes all the lovely variations of node's `fs` arguments:
202+
203+
- `fs.writeFile('filename.txt', 'Hello', cb)`
204+
- `fs.writeFile('filename.txt', 'Hello', 'utf8', cb)`
205+
- `fs.writeFile('filename.txt', 'Hello', { encoding: 'utf8' }, cb)`
206+
- `fs.promises.writeFile('filename.txt', 'Hello')`
207+
- `fs.promises.writeFile('filename.txt', 'Hello', 'utf8')`
208+
- `fs.promises.writeFile('filename.txt', 'Hello', { encoding: 'utf8' })`
209+
210+
And it normalizes filepaths. And will convert plain `StatLike` objects into `Stat` objects with methods like `isFile`, `isDirectory`, etc.
211+
212+
If that fits your needs, then you can provide a `backend` option and LightningFS will use that. Implement as few/many methods as you need for your application to work.
213+
214+
```tsx
215+
216+
type EncodingOpts = {
217+
encoding?: 'utf8';
218+
}
219+
220+
type StatLike = {
221+
type: 'file' | 'dir' | 'symlink';
222+
mode: number;
223+
size: number;
224+
ino: number | string | BigInt;
225+
mtimeMs: number;
226+
ctimeMs?: number;
227+
}
228+
229+
interface IBackend {
230+
// highly recommended - usually necessary for apps to work
231+
readFile(filepath: string, opts: EncodingOpts): Awaited<Uint8Array | string>;
232+
writeFile(filepath: string, data: Uint8Array | string, opts: EncodingOpts): void;
233+
unlink(filepath: string, opts: any): void;
234+
readdir(filepath: string, opts: any): Awaited<string[]>;
235+
mkdir(filepath: string, opts: any): void;
236+
rmdir(filepath: string, opts: any): void;
237+
238+
// recommended - often necessary for apps to work
239+
stat(filepath: string, opts: any): Awaited<StatLike>;
240+
lstat(filepath: string, opts: any): Awaited<StatLike>;
241+
242+
// suggested - used occasionally by apps
243+
rename(oldFilepath: string, newFilepath: string): void;
244+
readlink(filepath: string, opts: any): Awaited<string>;
245+
symlink(target: string, filepath: string): void;
246+
247+
// bonus - not part of the standard `fs` module
248+
backFile(filepath: string, opts: any): void;
249+
du(filepath: string): Awaited<number>;
250+
}
251+
```
252+
194253
## License
195254

196255
MIT

0 commit comments

Comments
 (0)