Skip to content

Commit a6a9d5c

Browse files
committed
documentation
1 parent ecef48e commit a6a9d5c

File tree

1 file changed

+71
-10
lines changed

1 file changed

+71
-10
lines changed

README.md

Lines changed: 71 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,66 @@ 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+
**Note:** If you use a custom backend, you are responsible for managing multi-threaded access - there are no magic mutexes included by default.
215+
216+
```tsx
217+
218+
type EncodingOpts = {
219+
encoding?: 'utf8';
220+
}
221+
222+
type StatLike = {
223+
type: 'file' | 'dir' | 'symlink';
224+
mode: number;
225+
size: number;
226+
ino: number | string | BigInt;
227+
mtimeMs: number;
228+
ctimeMs?: number;
229+
}
230+
231+
interface IBackend {
232+
// highly recommended - usually necessary for apps to work
233+
readFile(filepath: string, opts: EncodingOpts): Awaited<Uint8Array | string>;
234+
writeFile(filepath: string, data: Uint8Array | string, opts: EncodingOpts): void;
235+
unlink(filepath: string, opts: any): void;
236+
readdir(filepath: string, opts: any): Awaited<string[]>;
237+
mkdir(filepath: string, opts: any): void;
238+
rmdir(filepath: string, opts: any): void;
239+
240+
// recommended - often necessary for apps to work
241+
stat(filepath: string, opts: any): Awaited<StatLike>;
242+
lstat(filepath: string, opts: any): Awaited<StatLike>;
243+
244+
// suggested - used occasionally by apps
245+
rename(oldFilepath: string, newFilepath: string): void;
246+
readlink(filepath: string, opts: any): Awaited<string>;
247+
symlink(target: string, filepath: string): void;
248+
249+
// bonus - not part of the standard `fs` module
250+
backFile(filepath: string, opts: any): void;
251+
du(filepath: string): Awaited<number>;
252+
}
253+
```
254+
194255
## License
195256

196257
MIT

0 commit comments

Comments
 (0)