@zenfs/core 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/ApiError.d.ts +51 -14
  2. package/dist/ApiError.js +60 -34
  3. package/dist/FileIndex.d.ts +32 -35
  4. package/dist/FileIndex.js +93 -109
  5. package/dist/backends/AsyncMirror.d.ts +42 -43
  6. package/dist/backends/AsyncMirror.js +146 -133
  7. package/dist/backends/AsyncStore.d.ts +29 -28
  8. package/dist/backends/AsyncStore.js +139 -189
  9. package/dist/backends/InMemory.d.ts +16 -13
  10. package/dist/backends/InMemory.js +29 -14
  11. package/dist/backends/Locked.d.ts +8 -28
  12. package/dist/backends/Locked.js +44 -148
  13. package/dist/backends/OverlayFS.d.ts +26 -34
  14. package/dist/backends/OverlayFS.js +208 -371
  15. package/dist/backends/SyncStore.d.ts +54 -72
  16. package/dist/backends/SyncStore.js +159 -161
  17. package/dist/backends/backend.d.ts +45 -29
  18. package/dist/backends/backend.js +83 -13
  19. package/dist/backends/index.d.ts +6 -7
  20. package/dist/backends/index.js +5 -6
  21. package/dist/browser.min.js +5 -7
  22. package/dist/browser.min.js.map +4 -4
  23. package/dist/emulation/callbacks.d.ts +36 -67
  24. package/dist/emulation/callbacks.js +90 -46
  25. package/dist/emulation/constants.js +1 -1
  26. package/dist/emulation/promises.d.ts +228 -129
  27. package/dist/emulation/promises.js +414 -172
  28. package/dist/emulation/shared.d.ts +10 -10
  29. package/dist/emulation/shared.js +18 -20
  30. package/dist/emulation/sync.d.ts +25 -25
  31. package/dist/emulation/sync.js +187 -73
  32. package/dist/file.d.ts +166 -170
  33. package/dist/file.js +199 -218
  34. package/dist/filesystem.d.ts +68 -241
  35. package/dist/filesystem.js +59 -383
  36. package/dist/index.d.ts +7 -44
  37. package/dist/index.js +13 -52
  38. package/dist/inode.d.ts +37 -28
  39. package/dist/inode.js +123 -65
  40. package/dist/stats.d.ts +21 -19
  41. package/dist/stats.js +35 -56
  42. package/dist/utils.d.ts +26 -9
  43. package/dist/utils.js +73 -102
  44. package/package.json +4 -3
@@ -1,36 +1,19 @@
1
1
  /* eslint-disable @typescript-eslint/no-unused-vars */
2
2
  // disable no-unused-vars since BaseFileSystem uses them a lot
3
- var _a;
4
3
  import { ApiError, ErrorCode } from './ApiError.js';
5
- import { FileFlag, ActionType } from './file.js';
6
- import * as path from './emulation/path.js';
7
- import { encode } from './utils.js';
8
4
  /**
9
- * Structure for a filesystem. **All** ZenFS FileSystems must implement
10
- * this.
5
+ * Structure for a filesystem. All ZenFS FileSystems must implement this.
11
6
  *
12
- * ### Argument Assumptions
7
+ * This class includes some default implementations
13
8
  *
14
- * You can assume the following about arguments passed to each API method:
9
+ * Assume the following about arguments passed to each API method:
15
10
  *
16
- * - Every path is an absolute path. `.`, `..`, and other items
17
- * are resolved into an absolute form.
18
- * - All arguments are present. Any optional arguments at the Node API level
19
- * have been passed in with their default values.
11
+ * - Every path is an absolute path. `.`, `..`, and other items are resolved into an absolute form.
12
+ * - All arguments are present. Any optional arguments at the Node API level have been passed in with their default values.
20
13
  */
21
14
  export class FileSystem {
22
- constructor(options) {
23
- // unused
24
- }
25
- }
26
- /**
27
- * Basic filesystem class. Most filesystems should extend this class, as it
28
- * provides default implementations for a handful of methods.
29
- */
30
- export class BaseFileSystem extends FileSystem {
31
- constructor(options) {
32
- super();
33
- this._ready = Promise.resolve(this);
15
+ static get Name() {
16
+ return this.name;
34
17
  }
35
18
  get metadata() {
36
19
  return {
@@ -38,418 +21,111 @@ export class BaseFileSystem extends FileSystem {
38
21
  readonly: false,
39
22
  synchronous: false,
40
23
  supportsProperties: false,
41
- supportsLinks: false,
42
24
  totalSpace: 0,
43
25
  freeSpace: 0,
44
26
  };
45
27
  }
46
- whenReady() {
47
- return this._ready;
48
- }
49
- /**
50
- * Opens the file at path p with the given flag. The file must exist.
51
- * @param p The path to open.
52
- * @param flag The flag to use when opening the file.
53
- */
54
- async openFile(p, flag, cred) {
55
- throw new ApiError(ErrorCode.ENOTSUP);
28
+ constructor(options) {
29
+ // unused
56
30
  }
57
31
  /**
58
- * Create the file at path p with the given mode. Then, open it with the given
59
- * flag.
32
+ * Test whether or not the given path exists by checking with the file system.
60
33
  */
61
- async createFile(p, flag, mode, cred) {
62
- throw new ApiError(ErrorCode.ENOTSUP);
63
- }
64
- async open(p, flag, mode, cred) {
34
+ async exists(path, cred) {
65
35
  try {
66
- const stats = await this.stat(p, cred);
67
- switch (flag.pathExistsAction()) {
68
- case ActionType.THROW_EXCEPTION:
69
- throw ApiError.EEXIST(p);
70
- case ActionType.TRUNCATE_FILE:
71
- // NOTE: In a previous implementation, we deleted the file and
72
- // re-created it. However, this created a race condition if another
73
- // asynchronous request was trying to read the file, as the file
74
- // would not exist for a small period of time.
75
- const fd = await this.openFile(p, flag, cred);
76
- if (!fd)
77
- throw new Error('BFS has reached an impossible code path; please file a bug.');
78
- await fd.truncate(0);
79
- await fd.sync();
80
- return fd;
81
- case ActionType.NOP:
82
- return this.openFile(p, flag, cred);
83
- default:
84
- throw new ApiError(ErrorCode.EINVAL, 'Invalid FileFlag object.');
85
- }
86
- // File exists.
36
+ await this.stat(path, cred);
37
+ return true;
87
38
  }
88
39
  catch (e) {
89
- // File does not exist.
90
- switch (flag.pathNotExistsAction()) {
91
- case ActionType.CREATE_FILE:
92
- // Ensure parent exists.
93
- const parentStats = await this.stat(path.dirname(p), cred);
94
- if (parentStats && !parentStats.isDirectory()) {
95
- throw ApiError.ENOTDIR(path.dirname(p));
96
- }
97
- return this.createFile(p, flag, mode, cred);
98
- case ActionType.THROW_EXCEPTION:
99
- throw ApiError.ENOENT(p);
100
- default:
101
- throw new ApiError(ErrorCode.EINVAL, 'Invalid FileFlag object.');
102
- }
40
+ return false;
103
41
  }
104
42
  }
105
- async access(p, mode, cred) {
106
- throw new ApiError(ErrorCode.ENOTSUP);
107
- }
108
- accessSync(p, mode, cred) {
109
- throw new ApiError(ErrorCode.ENOTSUP);
110
- }
111
- async rename(oldPath, newPath, cred) {
112
- throw new ApiError(ErrorCode.ENOTSUP);
113
- }
114
- renameSync(oldPath, newPath, cred) {
115
- throw new ApiError(ErrorCode.ENOTSUP);
116
- }
117
- async stat(p, cred) {
118
- throw new ApiError(ErrorCode.ENOTSUP);
119
- }
120
- statSync(p, cred) {
121
- throw new ApiError(ErrorCode.ENOTSUP);
122
- }
123
- /**
124
- * Opens the file at path p with the given flag. The file must exist.
125
- * @param p The path to open.
126
- * @param flag The flag to use when opening the file.
127
- * @return A File object corresponding to the opened file.
128
- */
129
- openFileSync(p, flag, cred) {
130
- throw new ApiError(ErrorCode.ENOTSUP);
131
- }
132
43
  /**
133
- * Create the file at path p with the given mode. Then, open it with the given
134
- * flag.
44
+ * Test whether or not the given path exists by checking with the file system.
135
45
  */
136
- createFileSync(p, flag, mode, cred) {
137
- throw new ApiError(ErrorCode.ENOTSUP);
138
- }
139
- openSync(p, flag, mode, cred) {
140
- // Check if the path exists, and is a file.
141
- let stats;
142
- try {
143
- stats = this.statSync(p, cred);
144
- }
145
- catch (e) {
146
- // File does not exist.
147
- switch (flag.pathNotExistsAction()) {
148
- case ActionType.CREATE_FILE:
149
- // Ensure parent exists.
150
- const parentStats = this.statSync(path.dirname(p), cred);
151
- if (!parentStats.isDirectory()) {
152
- throw ApiError.ENOTDIR(path.dirname(p));
153
- }
154
- return this.createFileSync(p, flag, mode, cred);
155
- case ActionType.THROW_EXCEPTION:
156
- throw ApiError.ENOENT(p);
157
- default:
158
- throw new ApiError(ErrorCode.EINVAL, 'Invalid FileFlag object.');
159
- }
160
- }
161
- if (!stats.hasAccess(mode, cred)) {
162
- throw ApiError.EACCES(p);
163
- }
164
- // File exists.
165
- switch (flag.pathExistsAction()) {
166
- case ActionType.THROW_EXCEPTION:
167
- throw ApiError.EEXIST(p);
168
- case ActionType.TRUNCATE_FILE:
169
- // Delete file.
170
- this.unlinkSync(p, cred);
171
- // Create file. Use the same mode as the old file.
172
- // Node itself modifies the ctime when this occurs, so this action
173
- // will preserve that behavior if the underlying file system
174
- // supports those properties.
175
- return this.createFileSync(p, flag, stats.mode, cred);
176
- case ActionType.NOP:
177
- return this.openFileSync(p, flag, cred);
178
- default:
179
- throw new ApiError(ErrorCode.EINVAL, 'Invalid FileFlag object.');
180
- }
181
- }
182
- async unlink(p, cred) {
183
- throw new ApiError(ErrorCode.ENOTSUP);
184
- }
185
- unlinkSync(p, cred) {
186
- throw new ApiError(ErrorCode.ENOTSUP);
187
- }
188
- async rmdir(p, cred) {
189
- throw new ApiError(ErrorCode.ENOTSUP);
190
- }
191
- rmdirSync(p, cred) {
192
- throw new ApiError(ErrorCode.ENOTSUP);
193
- }
194
- async mkdir(p, mode, cred) {
195
- throw new ApiError(ErrorCode.ENOTSUP);
196
- }
197
- mkdirSync(p, mode, cred) {
198
- throw new ApiError(ErrorCode.ENOTSUP);
199
- }
200
- async readdir(p, cred) {
201
- throw new ApiError(ErrorCode.ENOTSUP);
202
- }
203
- readdirSync(p, cred) {
204
- throw new ApiError(ErrorCode.ENOTSUP);
205
- }
206
- async exists(p, cred) {
46
+ existsSync(path, cred) {
207
47
  try {
208
- await this.stat(p, cred);
48
+ this.statSync(path, cred);
209
49
  return true;
210
50
  }
211
51
  catch (e) {
212
52
  return false;
213
53
  }
214
54
  }
215
- existsSync(p, cred) {
216
- try {
217
- this.statSync(p, cred);
218
- return true;
219
- }
220
- catch (e) {
221
- return false;
222
- }
55
+ }
56
+ /**
57
+ * Implements the asynchronous API in terms of the synchronous API.
58
+ */
59
+ export class SyncFileSystem extends FileSystem {
60
+ get metadata() {
61
+ return { ...super.metadata, synchronous: true };
223
62
  }
224
- async realpath(p, cred) {
225
- if (this.metadata.supportsLinks) {
226
- // The path could contain symlinks. Split up the path,
227
- // resolve any symlinks, return the resolved string.
228
- const splitPath = p.split(path.sep);
229
- // TODO: Simpler to just pass through file, find sep and such.
230
- for (let i = 0; i < splitPath.length; i++) {
231
- const addPaths = splitPath.slice(0, i + 1);
232
- splitPath[i] = path.join(...addPaths);
233
- }
234
- return splitPath.join(path.sep);
235
- }
236
- else {
237
- // No symlinks. We just need to verify that it exists.
238
- if (!(await this.exists(p, cred))) {
239
- throw ApiError.ENOENT(p);
240
- }
241
- return p;
242
- }
63
+ async ready() {
64
+ return this;
243
65
  }
244
- realpathSync(p, cred) {
245
- if (this.metadata.supportsLinks) {
246
- // The path could contain symlinks. Split up the path,
247
- // resolve any symlinks, return the resolved string.
248
- const splitPath = p.split(path.sep);
249
- // TODO: Simpler to just pass through file, find sep and such.
250
- for (let i = 0; i < splitPath.length; i++) {
251
- const addPaths = splitPath.slice(0, i + 1);
252
- splitPath[i] = path.join(...addPaths);
253
- }
254
- return splitPath.join(path.sep);
255
- }
256
- else {
257
- // No symlinks. We just need to verify that it exists.
258
- if (this.existsSync(p, cred)) {
259
- return p;
260
- }
261
- else {
262
- throw ApiError.ENOENT(p);
263
- }
264
- }
66
+ async rename(oldPath, newPath, cred) {
67
+ return this.renameSync(oldPath, newPath, cred);
265
68
  }
266
- async truncate(p, len, cred) {
267
- const fd = await this.open(p, FileFlag.getFileFlag('r+'), 0o644, cred);
268
- try {
269
- await fd.truncate(len);
270
- }
271
- finally {
272
- await fd.close();
273
- }
69
+ async stat(path, cred) {
70
+ return this.statSync(path, cred);
274
71
  }
275
- truncateSync(p, len, cred) {
276
- const fd = this.openSync(p, FileFlag.getFileFlag('r+'), 0o644, cred);
277
- // Need to safely close FD, regardless of whether or not truncate succeeds.
278
- try {
279
- fd.truncateSync(len);
280
- }
281
- finally {
282
- fd.closeSync();
283
- }
72
+ async createFile(path, flag, mode, cred) {
73
+ return this.createFileSync(path, flag, mode, cred);
284
74
  }
285
- async readFile(fname, flag, cred) {
286
- // Get file.
287
- const fd = await this.open(fname, flag, 0o644, cred);
288
- try {
289
- const stat = await fd.stat();
290
- // Allocate buffer.
291
- const buf = new Uint8Array(stat.size);
292
- await fd.read(buf, 0, stat.size, 0);
293
- await fd.close();
294
- return buf;
295
- }
296
- finally {
297
- await fd.close();
298
- }
75
+ async openFile(path, flag, cred) {
76
+ return this.openFileSync(path, flag, cred);
299
77
  }
300
- readFileSync(fname, flag, cred) {
301
- // Get file.
302
- const fd = this.openSync(fname, flag, 0o644, cred);
303
- try {
304
- const stat = fd.statSync();
305
- // Allocate buffer.
306
- const buf = new Uint8Array(stat.size);
307
- fd.readSync(buf, 0, stat.size, 0);
308
- fd.closeSync();
309
- return buf;
310
- }
311
- finally {
312
- fd.closeSync();
313
- }
78
+ async unlink(path, cred) {
79
+ return this.unlinkSync(path, cred);
314
80
  }
315
- async writeFile(fname, data, flag, mode, cred) {
316
- // Get file.
317
- const fd = await this.open(fname, flag, mode, cred);
318
- try {
319
- if (typeof data === 'string') {
320
- data = encode(data);
321
- }
322
- // Write into file.
323
- await fd.write(data, 0, data.length, 0);
324
- }
325
- finally {
326
- await fd.close();
327
- }
81
+ async rmdir(path, cred) {
82
+ return this.rmdirSync(path, cred);
328
83
  }
329
- writeFileSync(fname, data, flag, mode, cred) {
330
- // Get file.
331
- const fd = this.openSync(fname, flag, mode, cred);
332
- try {
333
- if (typeof data === 'string') {
334
- data = encode(data);
335
- }
336
- // Write into file.
337
- fd.writeSync(data, 0, data.length, 0);
338
- }
339
- finally {
340
- fd.closeSync();
341
- }
84
+ async mkdir(path, mode, cred) {
85
+ return this.mkdirSync(path, mode, cred);
342
86
  }
343
- async appendFile(fname, data, flag, mode, cred) {
344
- const fd = await this.open(fname, flag, mode, cred);
345
- try {
346
- if (typeof data === 'string') {
347
- data = encode(data);
348
- }
349
- await fd.write(data, 0, data.length, null);
350
- }
351
- finally {
352
- await fd.close();
353
- }
87
+ async readdir(path, cred) {
88
+ return this.readdirSync(path, cred);
354
89
  }
355
- appendFileSync(fname, data, flag, mode, cred) {
356
- const fd = this.openSync(fname, flag, mode, cred);
357
- try {
358
- if (typeof data === 'string') {
359
- data = encode(data);
360
- }
361
- fd.writeSync(data, 0, data.length, null);
362
- }
363
- finally {
364
- fd.closeSync();
365
- }
90
+ async link(srcpath, dstpath, cred) {
91
+ return this.linkSync(srcpath, dstpath, cred);
366
92
  }
367
- async chmod(p, mode, cred) {
368
- throw new ApiError(ErrorCode.ENOTSUP);
93
+ async sync(path, data, stats) {
94
+ return this.syncSync(path, data, stats);
369
95
  }
370
- chmodSync(p, mode, cred) {
96
+ }
97
+ export class AsyncFileSystem extends FileSystem {
98
+ renameSync(oldPath, newPath, cred) {
371
99
  throw new ApiError(ErrorCode.ENOTSUP);
372
100
  }
373
- async chown(p, new_uid, new_gid, cred) {
101
+ statSync(path, cred) {
374
102
  throw new ApiError(ErrorCode.ENOTSUP);
375
103
  }
376
- chownSync(p, new_uid, new_gid, cred) {
104
+ createFileSync(path, flag, mode, cred) {
377
105
  throw new ApiError(ErrorCode.ENOTSUP);
378
106
  }
379
- async utimes(p, atime, mtime, cred) {
107
+ openSync(path, flags, mode, cred) {
380
108
  throw new ApiError(ErrorCode.ENOTSUP);
381
109
  }
382
- utimesSync(p, atime, mtime, cred) {
110
+ openFileSync(path, flag, cred) {
383
111
  throw new ApiError(ErrorCode.ENOTSUP);
384
112
  }
385
- async link(srcpath, dstpath, cred) {
113
+ unlinkSync(path, cred) {
386
114
  throw new ApiError(ErrorCode.ENOTSUP);
387
115
  }
388
- linkSync(srcpath, dstpath, cred) {
116
+ rmdirSync(path, cred) {
389
117
  throw new ApiError(ErrorCode.ENOTSUP);
390
118
  }
391
- async symlink(srcpath, dstpath, type, cred) {
119
+ mkdirSync(path, mode, cred) {
392
120
  throw new ApiError(ErrorCode.ENOTSUP);
393
121
  }
394
- symlinkSync(srcpath, dstpath, type, cred) {
122
+ readdirSync(path, cred) {
395
123
  throw new ApiError(ErrorCode.ENOTSUP);
396
124
  }
397
- async readlink(p, cred) {
125
+ linkSync(srcpath, dstpath, cred) {
398
126
  throw new ApiError(ErrorCode.ENOTSUP);
399
127
  }
400
- readlinkSync(p, cred) {
128
+ syncSync(path, data, stats) {
401
129
  throw new ApiError(ErrorCode.ENOTSUP);
402
130
  }
403
131
  }
404
- _a = BaseFileSystem;
405
- BaseFileSystem.Name = _a.name;
406
- /**
407
- * Implements the asynchronous API in terms of the synchronous API.
408
- */
409
- export class SynchronousFileSystem extends BaseFileSystem {
410
- get metadata() {
411
- return { ...super.metadata, synchronous: true };
412
- }
413
- async access(p, mode, cred) {
414
- return this.accessSync(p, mode, cred);
415
- }
416
- async rename(oldPath, newPath, cred) {
417
- return this.renameSync(oldPath, newPath, cred);
418
- }
419
- async stat(p, cred) {
420
- return this.statSync(p, cred);
421
- }
422
- async open(p, flags, mode, cred) {
423
- return this.openSync(p, flags, mode, cred);
424
- }
425
- async unlink(p, cred) {
426
- return this.unlinkSync(p, cred);
427
- }
428
- async rmdir(p, cred) {
429
- return this.rmdirSync(p, cred);
430
- }
431
- async mkdir(p, mode, cred) {
432
- return this.mkdirSync(p, mode, cred);
433
- }
434
- async readdir(p, cred) {
435
- return this.readdirSync(p, cred);
436
- }
437
- async chmod(p, mode, cred) {
438
- return this.chmodSync(p, mode, cred);
439
- }
440
- async chown(p, new_uid, new_gid, cred) {
441
- return this.chownSync(p, new_uid, new_gid, cred);
442
- }
443
- async utimes(p, atime, mtime, cred) {
444
- return this.utimesSync(p, atime, mtime, cred);
445
- }
446
- async link(srcpath, dstpath, cred) {
447
- return this.linkSync(srcpath, dstpath, cred);
448
- }
449
- async symlink(srcpath, dstpath, type, cred) {
450
- return this.symlinkSync(srcpath, dstpath, type, cred);
451
- }
452
- async readlink(p, cred) {
453
- return this.readlinkSync(p, cred);
454
- }
455
- }
package/dist/index.d.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  /**
2
2
  * ZenFS's main module. This is exposed in the browser via the ZenFS global.
3
3
  */
4
- import fs from './emulation/fs.js';
5
- import { FileSystem, type NoArgCallback, type TwoArgCallback } from './filesystem.js';
4
+ import * as fs from './emulation/index.js';
5
+ import { FileSystem } from './filesystem.js';
6
6
  import { backends } from './backends/index.js';
7
+ import { type Backend, type BackendConfig } from './backends/backend.js';
7
8
  /**
8
9
  * Initializes ZenFS with the given file systems.
9
10
  */
@@ -14,55 +15,17 @@ export declare function initialize(mounts: {
14
15
  * Defines a mapping of mount points to their configurations
15
16
  */
16
17
  export interface ConfigMapping {
17
- [mountPoint: string]: FileSystem | FileSystemConfiguration | keyof typeof backends;
18
+ [mountPoint: string]: FileSystem | BackendConfig | keyof typeof backends | Backend;
18
19
  }
19
20
  /**
20
21
  * A configuration for ZenFS
21
22
  */
22
- export type Configuration = FileSystem | FileSystemConfiguration | ConfigMapping;
23
+ export type Configuration = FileSystem | BackendConfig | ConfigMapping;
23
24
  /**
24
- * Creates a file system with the given configuration, and initializes ZenFS with it.
25
- * See the FileSystemConfiguration type for more info on the configuration object.
25
+ * Creates filesystems with the given configuration, and initializes ZenFS with it.
26
+ * See the Configuration type for more info on the configuration object.
26
27
  */
27
28
  export declare function configure(config: Configuration): Promise<void>;
28
- export declare function configure(config: Configuration, cb: NoArgCallback): void;
29
- /**
30
- * Asynchronously creates a file system with the given configuration, and initializes ZenFS with it.
31
- * See the FileSystemConfiguration type for more info on the configuration object.
32
- * Note: unlike configure, the .then is provided with the file system
33
- */
34
- /**
35
- * Specifies a file system backend type and its options.
36
- *
37
- * Individual options can recursively contain FileSystemConfiguration objects for
38
- * option values that require file systems.
39
- *
40
- * For example, to mirror Dropbox to Storage with AsyncMirror, use the following
41
- * object:
42
- *
43
- * ```javascript
44
- * var config = {
45
- * fs: "AsyncMirror",
46
- * options: {
47
- * sync: {fs: "Storage"},
48
- * async: {fs: "Dropbox", options: {client: anAuthenticatedDropboxSDKClient }}
49
- * }
50
- * };
51
- * ```
52
- *
53
- * The option object for each file system corresponds to that file system's option object passed to its `Create()` method.
54
- */
55
- export interface FileSystemConfiguration {
56
- fs: string;
57
- options?: object;
58
- }
59
- /**
60
- * Retrieve a file system with the given configuration. Will return a promise if invoked without a callback
61
- * @param config A FileSystemConfiguration object. See FileSystemConfiguration for details.
62
- * @param cb Called when the file system is constructed, or when an error occurs.
63
- */
64
- export declare function getFileSystem(config: FileSystemConfiguration): Promise<FileSystem>;
65
- export declare function getFileSystem(config: FileSystemConfiguration, cb: TwoArgCallback<FileSystem>): void;
66
29
  export * from './backends/index.js';
67
30
  export * from './backends/AsyncStore.js';
68
31
  export * from './backends/SyncStore.js';
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * ZenFS's main module. This is exposed in the browser via the ZenFS global.
3
3
  */
4
- import fs from './emulation/fs.js';
4
+ import * as fs from './emulation/index.js';
5
5
  import { FileSystem } from './filesystem.js';
6
6
  import { backends } from './backends/index.js';
7
- import { ErrorCode, ApiError } from './ApiError.js';
8
7
  import { Cred } from './cred.js';
8
+ import { isBackend, resolveBackendConfig } from './backends/backend.js';
9
9
  import { setCred } from './emulation/shared.js';
10
10
  /**
11
11
  * Initializes ZenFS with the given file systems.
@@ -14,8 +14,12 @@ export function initialize(mounts, uid = 0, gid = 0) {
14
14
  setCred(new Cred(uid, gid, uid, gid, uid, gid));
15
15
  return fs.initialize(mounts);
16
16
  }
17
- async function _configure(config) {
18
- if ('fs' in config || config instanceof FileSystem) {
17
+ /**
18
+ * Creates filesystems with the given configuration, and initializes ZenFS with it.
19
+ * See the Configuration type for more info on the configuration object.
20
+ */
21
+ export async function configure(config) {
22
+ if ('backend' in config || config instanceof FileSystem) {
19
23
  // single FS
20
24
  config = { '/': config };
21
25
  }
@@ -28,57 +32,14 @@ async function _configure(config) {
28
32
  continue;
29
33
  }
30
34
  if (typeof value == 'string') {
31
- value = { fs: value };
35
+ value = { backend: backends[value] };
32
36
  }
33
- config[point] = await getFileSystem(value);
34
- }
35
- return initialize(config);
36
- }
37
- export function configure(config, cb) {
38
- // Promise version
39
- if (typeof cb != 'function') {
40
- return _configure(config);
41
- }
42
- // Callback version
43
- _configure(config)
44
- .then(() => cb())
45
- .catch(err => cb(err));
46
- return;
47
- }
48
- async function _getFileSystem({ fs: fsName, options = {} }) {
49
- if (!fsName) {
50
- throw new ApiError(ErrorCode.EPERM, 'Missing "fs" property on configuration object.');
51
- }
52
- if (typeof options !== 'object' || options === null) {
53
- throw new ApiError(ErrorCode.EINVAL, 'Invalid "options" property on configuration object.');
54
- }
55
- const props = Object.keys(options).filter(k => k != 'fs');
56
- for (const prop of props) {
57
- const opt = options[prop];
58
- if (opt === null || typeof opt !== 'object' || !('fs' in opt)) {
59
- continue;
37
+ if (isBackend(value)) {
38
+ value = { backend: value };
60
39
  }
61
- const fs = await _getFileSystem(opt);
62
- options[prop] = fs;
63
- }
64
- const fsc = backends[fsName];
65
- if (!fsc) {
66
- throw new ApiError(ErrorCode.EPERM, `File system ${fsName} is not available in ZenFS.`);
67
- }
68
- else {
69
- return fsc.Create(options);
40
+ config[point] = await resolveBackendConfig(value);
70
41
  }
71
- }
72
- export function getFileSystem(config, cb) {
73
- // Promise version
74
- if (typeof cb != 'function') {
75
- return _getFileSystem(config);
76
- }
77
- // Callback version
78
- _getFileSystem(config)
79
- .then(fs => cb(null, fs))
80
- .catch(err => cb(err));
81
- return;
42
+ return initialize(config);
82
43
  }
83
44
  export * from './backends/index.js';
84
45
  export * from './backends/AsyncStore.js';