@zenfs/core 0.9.7 → 0.11.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 (90) hide show
  1. package/dist/backends/Index.d.ts +3 -3
  2. package/dist/backends/Index.js +23 -23
  3. package/dist/backends/backend.js +6 -5
  4. package/dist/backends/fetch.d.ts +84 -0
  5. package/dist/backends/fetch.js +170 -0
  6. package/dist/backends/{Locked.d.ts → locked.d.ts} +13 -13
  7. package/dist/backends/{Locked.js → locked.js} +54 -54
  8. package/dist/backends/{InMemory.d.ts → memory.d.ts} +7 -9
  9. package/dist/backends/memory.js +38 -0
  10. package/dist/backends/{Overlay.d.ts → overlay.d.ts} +12 -13
  11. package/dist/backends/{Overlay.js → overlay.js} +105 -110
  12. package/dist/backends/port/fs.d.ts +123 -0
  13. package/dist/backends/port/fs.js +239 -0
  14. package/dist/backends/port/rpc.d.ts +60 -0
  15. package/dist/backends/port/rpc.js +71 -0
  16. package/dist/backends/store/fs.d.ts +169 -0
  17. package/dist/backends/store/fs.js +743 -0
  18. package/dist/backends/store/simple.d.ts +64 -0
  19. package/dist/backends/store/simple.js +111 -0
  20. package/dist/backends/store/store.d.ts +111 -0
  21. package/dist/backends/store/store.js +62 -0
  22. package/dist/browser.min.js +4 -4
  23. package/dist/browser.min.js.map +4 -4
  24. package/dist/config.d.ts +8 -10
  25. package/dist/config.js +11 -11
  26. package/dist/emulation/async.js +6 -6
  27. package/dist/emulation/dir.js +2 -2
  28. package/dist/emulation/index.d.ts +1 -1
  29. package/dist/emulation/index.js +1 -1
  30. package/dist/emulation/path.d.ts +3 -2
  31. package/dist/emulation/path.js +19 -45
  32. package/dist/emulation/promises.d.ts +7 -12
  33. package/dist/emulation/promises.js +144 -146
  34. package/dist/emulation/shared.d.ts +5 -10
  35. package/dist/emulation/shared.js +9 -9
  36. package/dist/emulation/streams.js +3 -3
  37. package/dist/emulation/sync.js +25 -25
  38. package/dist/{ApiError.d.ts → error.d.ts} +13 -15
  39. package/dist/error.js +291 -0
  40. package/dist/file.d.ts +2 -0
  41. package/dist/file.js +11 -5
  42. package/dist/filesystem.d.ts +3 -3
  43. package/dist/filesystem.js +41 -44
  44. package/dist/index.d.ts +7 -6
  45. package/dist/index.js +7 -6
  46. package/dist/inode.d.ts +1 -1
  47. package/dist/mutex.js +2 -1
  48. package/dist/utils.d.ts +8 -7
  49. package/dist/utils.js +11 -12
  50. package/package.json +3 -3
  51. package/readme.md +17 -9
  52. package/src/backends/Index.ts +23 -23
  53. package/src/backends/backend.ts +8 -7
  54. package/src/backends/fetch.ts +229 -0
  55. package/src/backends/{Locked.ts → locked.ts} +55 -55
  56. package/src/backends/memory.ts +44 -0
  57. package/src/backends/{Overlay.ts → overlay.ts} +108 -114
  58. package/src/backends/port/fs.ts +306 -0
  59. package/src/backends/port/readme.md +59 -0
  60. package/src/backends/port/rpc.ts +144 -0
  61. package/src/backends/store/fs.ts +881 -0
  62. package/src/backends/store/readme.md +9 -0
  63. package/src/backends/store/simple.ts +144 -0
  64. package/src/backends/store/store.ts +164 -0
  65. package/src/config.ts +21 -25
  66. package/src/emulation/async.ts +6 -6
  67. package/src/emulation/dir.ts +2 -2
  68. package/src/emulation/index.ts +1 -1
  69. package/src/emulation/path.ts +25 -49
  70. package/src/emulation/promises.ts +150 -159
  71. package/src/emulation/shared.ts +13 -15
  72. package/src/emulation/streams.ts +3 -3
  73. package/src/emulation/sync.ts +28 -28
  74. package/src/{ApiError.ts → error.ts} +89 -90
  75. package/src/file.ts +13 -5
  76. package/src/filesystem.ts +44 -47
  77. package/src/index.ts +7 -6
  78. package/src/inode.ts +1 -1
  79. package/src/mutex.ts +3 -1
  80. package/src/utils.ts +16 -18
  81. package/tsconfig.json +2 -2
  82. package/dist/ApiError.js +0 -292
  83. package/dist/backends/AsyncStore.d.ts +0 -204
  84. package/dist/backends/AsyncStore.js +0 -509
  85. package/dist/backends/InMemory.js +0 -49
  86. package/dist/backends/SyncStore.d.ts +0 -213
  87. package/dist/backends/SyncStore.js +0 -445
  88. package/src/backends/AsyncStore.ts +0 -655
  89. package/src/backends/InMemory.ts +0 -56
  90. package/src/backends/SyncStore.ts +0 -589
@@ -147,11 +147,11 @@ export declare class IndexDirInode<TData> extends IndexInode<TData> {
147
147
  add(path: string, inode: IndexInode<TData>): boolean;
148
148
  /**
149
149
  * Removes the given item from the directory listing.
150
- * @param p Name of item to remove from the directory listing.
150
+ * @param path Name of item to remove from the directory listing.
151
151
  * @return Returns the item
152
152
  * removed, or null if the item did not exist.
153
153
  */
154
- remove(p: string): IndexInode<TData> | void;
154
+ remove(path: string): IndexInode<TData> | void;
155
155
  }
156
156
  declare const IndexFS_base: (abstract new (...args: any[]) => {
157
157
  metadata(): import("../filesystem.js").FileSystemMetadata;
@@ -169,7 +169,7 @@ declare const IndexFS_base: (abstract new (...args: any[]) => {
169
169
  linkSync(srcpath: string, dstpath: string, cred: Cred): void;
170
170
  sync(path: string, data: Uint8Array, stats: Readonly<Stats>): Promise<void>;
171
171
  syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void;
172
- ready(): Promise<any>;
172
+ ready(): Promise<void>;
173
173
  stat(path: string, cred: Cred): Promise<Stats>;
174
174
  statSync(path: string, cred: Cred): Stats;
175
175
  openFile(path: string, flag: string, cred: Cred): Promise<import("../file.js").File>;
@@ -1,4 +1,4 @@
1
- import { ApiError, ErrorCode } from '../ApiError.js';
1
+ import { ErrnoError, Errno } from '../error.js';
2
2
  import { basename, dirname, join } from '../emulation/path.js';
3
3
  import { NoSyncFile, flagToMode, isWriteable } from '../file.js';
4
4
  import { FileSystem, Readonly } from '../filesystem.js';
@@ -91,10 +91,10 @@ export class FileIndex {
91
91
  */
92
92
  add(path, inode) {
93
93
  if (!inode) {
94
- throw new Error('Inode must be specified');
94
+ throw new ErrnoError(Errno.EINVAL, 'Inode must be specified', path, 'FileIndex.add');
95
95
  }
96
96
  if (!path.startsWith('/')) {
97
- throw new Error('Path must be absolute, got: ' + path);
97
+ throw new ErrnoError(Errno.EINVAL, 'Path not absolute', path, 'FileIndex.add');
98
98
  }
99
99
  // Check if it already exists.
100
100
  if (this._index.has(path)) {
@@ -287,16 +287,16 @@ export class IndexDirInode extends IndexInode {
287
287
  }
288
288
  /**
289
289
  * Removes the given item from the directory listing.
290
- * @param p Name of item to remove from the directory listing.
290
+ * @param path Name of item to remove from the directory listing.
291
291
  * @return Returns the item
292
292
  * removed, or null if the item did not exist.
293
293
  */
294
- remove(p) {
295
- const item = this._listing.get(p);
294
+ remove(path) {
295
+ const item = this._listing.get(path);
296
296
  if (!item) {
297
297
  return;
298
298
  }
299
- this._listing.delete(p);
299
+ this._listing.delete(path);
300
300
  return item;
301
301
  }
302
302
  }
@@ -308,7 +308,7 @@ export class IndexFS extends Readonly(FileSystem) {
308
308
  async stat(path) {
309
309
  const inode = this._index.get(path);
310
310
  if (!inode) {
311
- throw ApiError.With('ENOENT', path, 'stat');
311
+ throw ErrnoError.With('ENOENT', path, 'stat');
312
312
  }
313
313
  if (inode.isDirectory()) {
314
314
  return inode.stats;
@@ -316,12 +316,12 @@ export class IndexFS extends Readonly(FileSystem) {
316
316
  if (inode.isFile()) {
317
317
  return this.statFileInode(inode, path);
318
318
  }
319
- throw new ApiError(ErrorCode.EINVAL, 'Invalid inode.');
319
+ throw new ErrnoError(Errno.EINVAL, 'Invalid inode.');
320
320
  }
321
321
  statSync(path) {
322
322
  const inode = this._index.get(path);
323
323
  if (!inode) {
324
- throw ApiError.With('ENOENT', path, 'stat');
324
+ throw ErrnoError.With('ENOENT', path, 'stat');
325
325
  }
326
326
  if (inode.isDirectory()) {
327
327
  return inode.stats;
@@ -329,20 +329,20 @@ export class IndexFS extends Readonly(FileSystem) {
329
329
  if (inode.isFile()) {
330
330
  return this.statFileInodeSync(inode, path);
331
331
  }
332
- throw new ApiError(ErrorCode.EINVAL, 'Invalid inode.');
332
+ throw new ErrnoError(Errno.EINVAL, 'Invalid inode.');
333
333
  }
334
334
  async openFile(path, flag, cred) {
335
335
  if (isWriteable(flag)) {
336
336
  // You can't write to files on this file system.
337
- throw new ApiError(ErrorCode.EPERM, path);
337
+ throw new ErrnoError(Errno.EPERM, path);
338
338
  }
339
339
  // Check if the path exists, and is a file.
340
340
  const inode = this._index.get(path);
341
341
  if (!inode) {
342
- throw ApiError.With('ENOENT', path, 'openFile');
342
+ throw ErrnoError.With('ENOENT', path, 'openFile');
343
343
  }
344
344
  if (!inode.toStats().hasAccess(flagToMode(flag), cred)) {
345
- throw ApiError.With('EACCES', path, 'openFile');
345
+ throw ErrnoError.With('EACCES', path, 'openFile');
346
346
  }
347
347
  if (inode.isDirectory()) {
348
348
  const stats = inode.stats;
@@ -353,15 +353,15 @@ export class IndexFS extends Readonly(FileSystem) {
353
353
  openFileSync(path, flag, cred) {
354
354
  if (isWriteable(flag)) {
355
355
  // You can't write to files on this file system.
356
- throw new ApiError(ErrorCode.EPERM, path);
356
+ throw new ErrnoError(Errno.EPERM, path);
357
357
  }
358
358
  // Check if the path exists, and is a file.
359
359
  const inode = this._index.get(path);
360
360
  if (!inode) {
361
- throw ApiError.With('ENOENT', path, 'openFile');
361
+ throw ErrnoError.With('ENOENT', path, 'openFile');
362
362
  }
363
363
  if (!inode.toStats().hasAccess(flagToMode(flag), cred)) {
364
- throw ApiError.With('EACCES', path, 'openFile');
364
+ throw ErrnoError.With('EACCES', path, 'openFile');
365
365
  }
366
366
  if (inode.isDirectory()) {
367
367
  const stats = inode.stats;
@@ -373,23 +373,23 @@ export class IndexFS extends Readonly(FileSystem) {
373
373
  // Check if it exists.
374
374
  const inode = this._index.get(path);
375
375
  if (!inode) {
376
- throw ApiError.With('ENOENT', path, 'readdir');
376
+ throw ErrnoError.With('ENOENT', path, 'readdir');
377
377
  }
378
378
  if (inode.isDirectory()) {
379
379
  return inode.listing;
380
380
  }
381
- throw ApiError.With('ENOTDIR', path, 'readdir');
381
+ throw ErrnoError.With('ENOTDIR', path, 'readdir');
382
382
  }
383
383
  readdirSync(path) {
384
384
  // Check if it exists.
385
385
  const inode = this._index.get(path);
386
386
  if (!inode) {
387
- throw ApiError.With('ENOENT', path, 'readdir');
387
+ throw ErrnoError.With('ENOENT', path, 'readdir');
388
388
  }
389
389
  if (inode.isDirectory()) {
390
390
  return inode.listing;
391
391
  }
392
- throw ApiError.With('ENOTDIR', path, 'readdir');
392
+ throw ErrnoError.With('ENOTDIR', path, 'readdir');
393
393
  }
394
394
  }
395
395
  export class SyncIndexFS extends IndexFS {
@@ -402,9 +402,9 @@ export class SyncIndexFS extends IndexFS {
402
402
  }
403
403
  export class AsyncIndexFS extends IndexFS {
404
404
  statFileInodeSync(inode, path) {
405
- throw ApiError.With('ENOSYS', path, 'AsyncIndexFS.statFileInodeSync');
405
+ throw ErrnoError.With('ENOSYS', path, 'AsyncIndexFS.statFileInodeSync');
406
406
  }
407
407
  openFileInodeSync(inode, path, flag) {
408
- throw ApiError.With('ENOSYS', path, 'AsyncIndexFS.openFileInodeSync');
408
+ throw ErrnoError.With('ENOSYS', path, 'AsyncIndexFS.openFileInodeSync');
409
409
  }
410
410
  }
@@ -1,4 +1,4 @@
1
- import { ApiError, ErrorCode } from '../ApiError.js';
1
+ import { ErrnoError, Errno } from '../error.js';
2
2
  import { levenshtein } from '../utils.js';
3
3
  /**
4
4
  * @internal
@@ -12,7 +12,7 @@ export function isBackend(arg) {
12
12
  */
13
13
  export async function checkOptions(backend, opts) {
14
14
  if (typeof opts != 'object' || opts === null) {
15
- throw new ApiError(ErrorCode.EINVAL, 'Invalid options');
15
+ throw new ErrnoError(Errno.EINVAL, 'Invalid options');
16
16
  }
17
17
  // Check for required options.
18
18
  for (const [optName, opt] of Object.entries(backend.options)) {
@@ -31,12 +31,12 @@ export async function checkOptions(backend, opts) {
31
31
  })
32
32
  .filter(o => o.distance < 5)
33
33
  .sort((a, b) => a.distance - b.distance);
34
- throw new ApiError(ErrorCode.EINVAL, `${backend.name}: Required option '${optName}' not provided.${incorrectOptions.length > 0 ? ` You provided '${incorrectOptions[0].str}', did you mean '${optName}'.` : ''}`);
34
+ throw new ErrnoError(Errno.EINVAL, `${backend.name}: Required option '${optName}' not provided.${incorrectOptions.length > 0 ? ` You provided '${incorrectOptions[0].str}', did you mean '${optName}'.` : ''}`);
35
35
  }
36
36
  // Option provided, check type.
37
37
  const typeMatches = Array.isArray(opt.type) ? opt.type.indexOf(typeof providedValue) != -1 : typeof providedValue == opt.type;
38
38
  if (!typeMatches) {
39
- throw new ApiError(ErrorCode.EINVAL, `${backend.name}: Value provided for option ${optName} is not the proper type. Expected ${Array.isArray(opt.type) ? `one of {${opt.type.join(', ')}}` : opt.type}, but received ${typeof providedValue}`);
39
+ throw new ErrnoError(Errno.EINVAL, `${backend.name}: Value provided for option ${optName} is not the proper type. Expected ${Array.isArray(opt.type) ? `one of {${opt.type.join(', ')}}` : opt.type}, but received ${typeof providedValue}`);
40
40
  }
41
41
  if (opt.validator) {
42
42
  await opt.validator(providedValue);
@@ -47,7 +47,8 @@ export async function checkOptions(backend, opts) {
47
47
  export async function createBackend(backend, options = {}) {
48
48
  await checkOptions(backend, options);
49
49
  const fs = backend.create(options);
50
- return fs.ready();
50
+ await fs.ready();
51
+ return fs;
51
52
  }
52
53
  /**
53
54
  * @internal
@@ -0,0 +1,84 @@
1
+ import { NoSyncFile } from '../file.js';
2
+ import type { FileSystemMetadata } from '../filesystem.js';
3
+ import { Stats } from '../stats.js';
4
+ import { type ListingTree, type IndexFileInode, AsyncIndexFS } from './Index.js';
5
+ /**
6
+ * Configuration options for FetchFS.
7
+ */
8
+ export interface FetchOptions {
9
+ /**
10
+ * URL to a file index as a JSON file or the file index object itself.
11
+ * Defaults to `index.json`.
12
+ */
13
+ index?: string | ListingTree;
14
+ /** Used as the URL prefix for fetched files.
15
+ * Default: Fetch files relative to the index.
16
+ */
17
+ baseUrl?: string;
18
+ }
19
+ /**
20
+ * A simple filesystem backed by HTTP using the fetch API.
21
+ *
22
+ *
23
+ * Listings objects look like the following:
24
+ *
25
+ * ```json
26
+ * {
27
+ * "home": {
28
+ * "jvilk": {
29
+ * "someFile.txt": null,
30
+ * "someDir": {
31
+ * // Empty directory
32
+ * }
33
+ * }
34
+ * }
35
+ * }
36
+ * ```
37
+ *
38
+ * This example has the folder `/home/jvilk` with subfile `someFile.txt` and subfolder `someDir`.
39
+ */
40
+ export declare class FetchFS extends AsyncIndexFS<Stats> {
41
+ readonly prefixUrl: string;
42
+ protected _init: Promise<void>;
43
+ protected _initialize(index: string | ListingTree): Promise<void>;
44
+ ready(): Promise<void>;
45
+ constructor({ index, baseUrl }: FetchOptions);
46
+ metadata(): FileSystemMetadata;
47
+ empty(): void;
48
+ /**
49
+ * Special function: Preload the given file into the index.
50
+ * @param path
51
+ * @param buffer
52
+ */
53
+ preloadFile(path: string, buffer: Uint8Array): void;
54
+ protected statFileInode(inode: IndexFileInode<Stats>, path: string): Promise<Stats>;
55
+ protected openFileInode(inode: IndexFileInode<Stats>, path: string, flag: string): Promise<NoSyncFile<this>>;
56
+ private _getRemotePath;
57
+ /**
58
+ * Asynchronously download the given file.
59
+ */
60
+ protected _fetchFile(path: string, type: 'buffer'): Promise<Uint8Array>;
61
+ protected _fetchFile(path: string, type: 'json'): Promise<object>;
62
+ protected _fetchFile(path: string, type: 'buffer' | 'json'): Promise<object>;
63
+ /**
64
+ * Only requests the HEAD content, for the file size.
65
+ */
66
+ protected _fetchSize(path: string): Promise<number>;
67
+ }
68
+ export declare const Fetch: {
69
+ readonly name: "Fetch";
70
+ readonly options: {
71
+ readonly index: {
72
+ readonly type: readonly ["string", "object"];
73
+ readonly required: false;
74
+ readonly description: "URL to a file index as a JSON file or the file index object itself, generated with the make_http_index script. Defaults to `index.json`.";
75
+ };
76
+ readonly baseUrl: {
77
+ readonly type: "string";
78
+ readonly required: false;
79
+ readonly description: "Used as the URL prefix for fetched files. Default: Fetch files relative to the index.";
80
+ };
81
+ };
82
+ readonly isAvailable: () => boolean;
83
+ readonly create: (options: FetchOptions) => FetchFS;
84
+ };
@@ -0,0 +1,170 @@
1
+ import { ErrnoError, Errno } from '../error.js';
2
+ import { NoSyncFile } from '../file.js';
3
+ import { Stats } from '../stats.js';
4
+ import { FileIndex, AsyncIndexFS } from './Index.js';
5
+ /**
6
+ * @hidden
7
+ */
8
+ function convertError(e) {
9
+ throw new ErrnoError(Errno.EIO, e.message);
10
+ }
11
+ async function fetchFile(path, type) {
12
+ const response = await fetch(path).catch(convertError);
13
+ if (!response.ok) {
14
+ throw new ErrnoError(Errno.EIO, 'fetch failed: response returned code ' + response.status);
15
+ }
16
+ switch (type) {
17
+ case 'buffer':
18
+ const arrayBuffer = await response.arrayBuffer().catch(convertError);
19
+ return new Uint8Array(arrayBuffer);
20
+ case 'json':
21
+ return response.json().catch(convertError);
22
+ default:
23
+ throw new ErrnoError(Errno.EINVAL, 'Invalid download type: ' + type);
24
+ }
25
+ }
26
+ /**
27
+ * Asynchronously retrieves the size of the given file in bytes.
28
+ * @hidden
29
+ */
30
+ async function fetchSize(path) {
31
+ const response = await fetch(path, { method: 'HEAD' }).catch(convertError);
32
+ if (!response.ok) {
33
+ throw new ErrnoError(Errno.EIO, 'fetch failed: HEAD response returned code ' + response.status);
34
+ }
35
+ return parseInt(response.headers.get('Content-Length') || '-1', 10);
36
+ }
37
+ /**
38
+ * A simple filesystem backed by HTTP using the fetch API.
39
+ *
40
+ *
41
+ * Listings objects look like the following:
42
+ *
43
+ * ```json
44
+ * {
45
+ * "home": {
46
+ * "jvilk": {
47
+ * "someFile.txt": null,
48
+ * "someDir": {
49
+ * // Empty directory
50
+ * }
51
+ * }
52
+ * }
53
+ * }
54
+ * ```
55
+ *
56
+ * This example has the folder `/home/jvilk` with subfile `someFile.txt` and subfolder `someDir`.
57
+ */
58
+ export class FetchFS extends AsyncIndexFS {
59
+ async _initialize(index) {
60
+ if (typeof index != 'string') {
61
+ this._index = FileIndex.FromListing(index);
62
+ return;
63
+ }
64
+ try {
65
+ const response = await fetch(index);
66
+ this._index = FileIndex.FromListing((await response.json()));
67
+ }
68
+ catch (e) {
69
+ throw new ErrnoError(Errno.EINVAL, 'Invalid or unavailable file listing tree');
70
+ }
71
+ }
72
+ async ready() {
73
+ await this._init;
74
+ }
75
+ constructor({ index = 'index.json', baseUrl = '' }) {
76
+ super({});
77
+ // prefix url must end in a directory separator.
78
+ if (baseUrl.at(-1) != '/') {
79
+ baseUrl += '/';
80
+ }
81
+ this.prefixUrl = baseUrl;
82
+ this._init = this._initialize(index);
83
+ }
84
+ metadata() {
85
+ return {
86
+ ...super.metadata(),
87
+ name: FetchFS.name,
88
+ readonly: true,
89
+ };
90
+ }
91
+ empty() {
92
+ for (const file of this._index.files()) {
93
+ delete file.data.fileData;
94
+ }
95
+ }
96
+ /**
97
+ * Special function: Preload the given file into the index.
98
+ * @param path
99
+ * @param buffer
100
+ */
101
+ preloadFile(path, buffer) {
102
+ const inode = this._index.get(path);
103
+ if (!inode) {
104
+ throw ErrnoError.With('ENOENT', path, 'preloadFile');
105
+ }
106
+ if (!inode.isFile()) {
107
+ throw ErrnoError.With('EISDIR', path, 'preloadFile');
108
+ }
109
+ const stats = inode.data;
110
+ stats.size = buffer.length;
111
+ stats.fileData = buffer;
112
+ }
113
+ async statFileInode(inode, path) {
114
+ const stats = inode.data;
115
+ // At this point, a non-opened file will still have default stats from the listing.
116
+ if (stats.size < 0) {
117
+ stats.size = await this._fetchSize(path);
118
+ }
119
+ return stats;
120
+ }
121
+ async openFileInode(inode, path, flag) {
122
+ const stats = inode.data;
123
+ // Use existing file contents. This maintains the previously-used flag.
124
+ if (stats.fileData) {
125
+ return new NoSyncFile(this, path, flag, new Stats(stats), stats.fileData);
126
+ }
127
+ // @todo be lazier about actually requesting the file
128
+ const data = await this._fetchFile(path, 'buffer');
129
+ // we don't initially have file sizes
130
+ stats.size = data.length;
131
+ stats.fileData = data;
132
+ return new NoSyncFile(this, path, flag, new Stats(stats), data);
133
+ }
134
+ _getRemotePath(filePath) {
135
+ if (filePath.charAt(0) === '/') {
136
+ filePath = filePath.slice(1);
137
+ }
138
+ return this.prefixUrl + filePath;
139
+ }
140
+ _fetchFile(path, type) {
141
+ return fetchFile(this._getRemotePath(path), type);
142
+ }
143
+ /**
144
+ * Only requests the HEAD content, for the file size.
145
+ */
146
+ _fetchSize(path) {
147
+ return fetchSize(this._getRemotePath(path));
148
+ }
149
+ }
150
+ export const Fetch = {
151
+ name: 'Fetch',
152
+ options: {
153
+ index: {
154
+ type: ['string', 'object'],
155
+ required: false,
156
+ description: 'URL to a file index as a JSON file or the file index object itself, generated with the make_http_index script. Defaults to `index.json`.',
157
+ },
158
+ baseUrl: {
159
+ type: 'string',
160
+ required: false,
161
+ description: 'Used as the URL prefix for fetched files. Default: Fetch files relative to the index.',
162
+ },
163
+ },
164
+ isAvailable() {
165
+ return typeof globalThis.fetch == 'function';
166
+ },
167
+ create(options) {
168
+ return new FetchFS(options);
169
+ },
170
+ };
@@ -16,26 +16,26 @@ export declare class LockedFS<FS extends FileSystem> implements FileSystem {
16
16
  readonly fs: FS;
17
17
  private _mu;
18
18
  constructor(fs: FS);
19
- ready(): Promise<this>;
19
+ ready(): Promise<void>;
20
20
  metadata(): FileSystemMetadata;
21
21
  rename(oldPath: string, newPath: string, cred: Cred): Promise<void>;
22
22
  renameSync(oldPath: string, newPath: string, cred: Cred): void;
23
- stat(p: string, cred: Cred): Promise<Stats>;
24
- statSync(p: string, cred: Cred): Stats;
23
+ stat(path: string, cred: Cred): Promise<Stats>;
24
+ statSync(path: string, cred: Cred): Stats;
25
25
  openFile(path: string, flag: string, cred: Cred): Promise<File>;
26
26
  openFileSync(path: string, flag: string, cred: Cred): File;
27
27
  createFile(path: string, flag: string, mode: number, cred: Cred): Promise<File>;
28
28
  createFileSync(path: string, flag: string, mode: number, cred: Cred): File;
29
- unlink(p: string, cred: Cred): Promise<void>;
30
- unlinkSync(p: string, cred: Cred): void;
31
- rmdir(p: string, cred: Cred): Promise<void>;
32
- rmdirSync(p: string, cred: Cred): void;
33
- mkdir(p: string, mode: number, cred: Cred): Promise<void>;
34
- mkdirSync(p: string, mode: number, cred: Cred): void;
35
- readdir(p: string, cred: Cred): Promise<string[]>;
36
- readdirSync(p: string, cred: Cred): string[];
37
- exists(p: string, cred: Cred): Promise<boolean>;
38
- existsSync(p: string, cred: Cred): boolean;
29
+ unlink(path: string, cred: Cred): Promise<void>;
30
+ unlinkSync(path: string, cred: Cred): void;
31
+ rmdir(path: string, cred: Cred): Promise<void>;
32
+ rmdirSync(path: string, cred: Cred): void;
33
+ mkdir(path: string, mode: number, cred: Cred): Promise<void>;
34
+ mkdirSync(path: string, mode: number, cred: Cred): void;
35
+ readdir(path: string, cred: Cred): Promise<string[]>;
36
+ readdirSync(path: string, cred: Cred): string[];
37
+ exists(path: string, cred: Cred): Promise<boolean>;
38
+ existsSync(path: string, cred: Cred): boolean;
39
39
  link(srcpath: string, dstpath: string, cred: Cred): Promise<void>;
40
40
  linkSync(srcpath: string, dstpath: string, cred: Cred): void;
41
41
  sync(path: string, data: Uint8Array, stats: Readonly<Stats>): Promise<void>;