@zenfs/core 0.11.0 → 0.11.2

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.
package/dist/config.js CHANGED
@@ -40,7 +40,7 @@ export async function resolveMountConfig(config, _depth = 0) {
40
40
  throw new ErrnoError(Errno.EPERM, 'Backend not available: ' + backend);
41
41
  }
42
42
  checkOptions(backend, config);
43
- const mount = backend.create(config);
43
+ const mount = await backend.create(config);
44
44
  await mount.ready();
45
45
  return mount;
46
46
  }
@@ -106,8 +106,7 @@ export class FileHandle {
106
106
  throw new ErrnoError(Errno.EINVAL, 'Flag passed must allow for reading.');
107
107
  }
108
108
  const { size } = await this.stat();
109
- const data = new Uint8Array(size);
110
- await this.file.read(data, 0, size, 0);
109
+ const { buffer: data } = await this.file.read(new Uint8Array(size), 0, size, 0);
111
110
  const buffer = Buffer.from(data);
112
111
  return options.encoding ? buffer.toString(options.encoding) : buffer;
113
112
  }
@@ -7,7 +7,7 @@ import { COPYFILE_EXCL, F_OK, S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLNK, S_IFM
7
7
  import { Dir, Dirent } from './dir.js';
8
8
  import { dirname, join, parse } from './path.js';
9
9
  import { cred, fd2file, fdMap, fixError, file2fd, mounts, resolveMount } from './shared.js';
10
- function doOp(...[name, resolveSymlinks, path, ...args]) {
10
+ function wrap(...[name, resolveSymlinks, path, ...args]) {
11
11
  path = normalizePath(path);
12
12
  const { fs, path: resolvedPath } = resolveMount(resolveSymlinks && existsSync(path) ? realpathSync(path) : path);
13
13
  try {
@@ -60,12 +60,12 @@ export function existsSync(path) {
60
60
  }
61
61
  existsSync;
62
62
  export function statSync(path, options) {
63
- const stats = doOp('statSync', true, path.toString(), cred);
63
+ const stats = wrap('statSync', true, path.toString(), cred);
64
64
  return options?.bigint ? new BigIntStats(stats) : stats;
65
65
  }
66
66
  statSync;
67
67
  export function lstatSync(path, options) {
68
- const stats = doOp('statSync', false, path.toString(), cred);
68
+ const stats = wrap('statSync', false, path.toString(), cred);
69
69
  return options?.bigint ? new BigIntStats(stats) : stats;
70
70
  }
71
71
  lstatSync;
@@ -89,7 +89,7 @@ truncateSync;
89
89
  * @param path
90
90
  */
91
91
  export function unlinkSync(path) {
92
- return doOp('unlinkSync', false, path.toString(), cred);
92
+ return wrap('unlinkSync', false, path.toString(), cred);
93
93
  }
94
94
  unlinkSync;
95
95
  function _openSync(_path, _flag, _mode, resolveSymlinks = true) {
@@ -97,18 +97,18 @@ function _openSync(_path, _flag, _mode, resolveSymlinks = true) {
97
97
  // Check if the path exists, and is a file.
98
98
  let stats;
99
99
  try {
100
- stats = doOp('statSync', resolveSymlinks, path, cred);
100
+ stats = wrap('statSync', resolveSymlinks, path, cred);
101
101
  }
102
102
  catch (e) {
103
103
  // File does not exist.
104
104
  switch (pathNotExistsAction(flag)) {
105
105
  case ActionType.CREATE:
106
106
  // Ensure parent exists.
107
- const parentStats = doOp('statSync', resolveSymlinks, dirname(path), cred);
107
+ const parentStats = wrap('statSync', resolveSymlinks, dirname(path), cred);
108
108
  if (!parentStats.isDirectory()) {
109
109
  throw ErrnoError.With('ENOTDIR', dirname(path), '_open');
110
110
  }
111
- return doOp('createFileSync', resolveSymlinks, path, flag, mode, cred);
111
+ return wrap('createFileSync', resolveSymlinks, path, flag, mode, cred);
112
112
  case ActionType.THROW:
113
113
  throw ErrnoError.With('ENOENT', path, '_open');
114
114
  default:
@@ -124,16 +124,16 @@ function _openSync(_path, _flag, _mode, resolveSymlinks = true) {
124
124
  throw ErrnoError.With('EEXIST', path, '_open');
125
125
  case ActionType.TRUNCATE:
126
126
  // Delete file.
127
- doOp('unlinkSync', resolveSymlinks, path, cred);
127
+ wrap('unlinkSync', resolveSymlinks, path, cred);
128
128
  /*
129
129
  Create file. Use the same mode as the old file.
130
130
  Node itself modifies the ctime when this occurs, so this action
131
131
  will preserve that behavior if the underlying file system
132
132
  supports those properties.
133
133
  */
134
- return doOp('createFileSync', resolveSymlinks, path, flag, stats.mode, cred);
134
+ return wrap('createFileSync', resolveSymlinks, path, flag, stats.mode, cred);
135
135
  case ActionType.NOP:
136
- return doOp('openFileSync', resolveSymlinks, path, flag, cred);
136
+ return wrap('openFileSync', resolveSymlinks, path, flag, cred);
137
137
  default:
138
138
  throw new ErrnoError(Errno.EINVAL, 'Invalid FileFlag object.');
139
139
  }
@@ -185,21 +185,6 @@ export function readFileSync(path, _options = {}) {
185
185
  return options.encoding ? data.toString(options.encoding) : data;
186
186
  }
187
187
  readFileSync;
188
- /**
189
- * Synchronously writes data to a file, replacing the file
190
- * if it already exists.
191
- *
192
- * The encoding option is ignored if data is a buffer.
193
- */
194
- function _writeFileSync(fname, data, flag, mode, resolveSymlinks) {
195
- const file = _openSync(fname, flag, mode, resolveSymlinks);
196
- try {
197
- file.writeSync(data, 0, data.byteLength, 0);
198
- }
199
- finally {
200
- file.closeSync();
201
- }
202
- }
203
188
  export function writeFileSync(path, data, _options = {}) {
204
189
  const options = normalizeOptions(_options, 'utf8', 'w+', 0o644);
205
190
  const flag = parseFlag(options.flag);
@@ -213,22 +198,15 @@ export function writeFileSync(path, data, _options = {}) {
213
198
  if (!encodedData) {
214
199
  throw new ErrnoError(Errno.EINVAL, 'Data not specified');
215
200
  }
216
- _writeFileSync(typeof path == 'number' ? fd2file(path).path : path.toString(), encodedData, options.flag, options.mode, true);
217
- }
218
- writeFileSync;
219
- /**
220
- * Synchronously append data to a file, creating the file if
221
- * it not yet exists.
222
- */
223
- function _appendFileSync(fname, data, flag, mode, resolveSymlinks) {
224
- const file = _openSync(fname, flag, mode, resolveSymlinks);
201
+ const file = _openSync(typeof path == 'number' ? fd2file(path).path : path.toString(), flag, options.mode, true);
225
202
  try {
226
- file.writeSync(data, 0, data.byteLength, null);
203
+ file.writeSync(encodedData, 0, encodedData.byteLength, 0);
227
204
  }
228
205
  finally {
229
206
  file.closeSync();
230
207
  }
231
208
  }
209
+ writeFileSync;
232
210
  /**
233
211
  * Asynchronously append data to a file, creating the file if it not yet
234
212
  * exists.
@@ -250,7 +228,13 @@ export function appendFileSync(filename, data, _options = {}) {
250
228
  throw new ErrnoError(Errno.EINVAL, 'Encoding not specified');
251
229
  }
252
230
  const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
253
- _appendFileSync(typeof filename == 'number' ? fd2file(filename).path : filename.toString(), encodedData, options.flag, options.mode, true);
231
+ const file = _openSync(typeof filename == 'number' ? fd2file(filename).path : filename.toString(), flag, options.mode, true);
232
+ try {
233
+ file.writeSync(encodedData, 0, encodedData.byteLength, null);
234
+ }
235
+ finally {
236
+ file.closeSync();
237
+ }
254
238
  }
255
239
  appendFileSync;
256
240
  export function fstatSync(fd, options) {
@@ -371,18 +355,18 @@ futimesSync;
371
355
  * @param path
372
356
  */
373
357
  export function rmdirSync(path) {
374
- return doOp('rmdirSync', true, path.toString(), cred);
358
+ return wrap('rmdirSync', true, path.toString(), cred);
375
359
  }
376
360
  rmdirSync;
377
361
  export function mkdirSync(path, options) {
378
362
  const mode = typeof options == 'number' || typeof options == 'string' ? options : options?.mode;
379
363
  const recursive = typeof options == 'object' && options?.recursive;
380
- doOp('mkdirSync', true, path.toString(), normalizeMode(mode, 0o777), cred);
364
+ wrap('mkdirSync', true, path.toString(), normalizeMode(mode, 0o777), cred);
381
365
  }
382
366
  mkdirSync;
383
367
  export function readdirSync(path, options) {
384
368
  path = normalizePath(path);
385
- const entries = doOp('readdirSync', true, path, cred);
369
+ const entries = wrap('readdirSync', true, path, cred);
386
370
  for (const mount of mounts.keys()) {
387
371
  if (!mount.startsWith(path)) {
388
372
  continue;
@@ -413,7 +397,7 @@ readdirSync;
413
397
  */
414
398
  export function linkSync(existing, newpath) {
415
399
  newpath = normalizePath(newpath);
416
- return doOp('linkSync', false, existing.toString(), newpath.toString(), cred);
400
+ return wrap('linkSync', false, existing.toString(), newpath.toString(), cred);
417
401
  }
418
402
  linkSync;
419
403
  /**
@@ -147,7 +147,7 @@ export declare abstract class FileSystem {
147
147
  /**
148
148
  * @internal
149
149
  */
150
- declare abstract class SyncFileSystem extends FileSystem {
150
+ declare abstract class SyncFS extends FileSystem {
151
151
  metadata(): FileSystemMetadata;
152
152
  ready(): Promise<void>;
153
153
  exists(path: string, cred: Cred): Promise<boolean>;
@@ -165,11 +165,11 @@ declare abstract class SyncFileSystem extends FileSystem {
165
165
  /**
166
166
  * Implements the asynchronous API in terms of the synchronous API.
167
167
  */
168
- export declare function Sync<T extends abstract new (...args: any[]) => FileSystem>(FS: T): (abstract new (...args: any[]) => SyncFileSystem) & T;
168
+ export declare function Sync<T extends abstract new (...args: any[]) => FileSystem>(FS: T): (abstract new (...args: any[]) => SyncFS) & T;
169
169
  /**
170
170
  * @internal
171
171
  */
172
- declare abstract class AsyncFileSystem extends FileSystem {
172
+ declare abstract class AsyncFS extends FileSystem {
173
173
  /**
174
174
  * @hidden
175
175
  */
@@ -200,11 +200,11 @@ declare abstract class AsyncFileSystem extends FileSystem {
200
200
  * the synchronous store, if desired.
201
201
  *
202
202
  */
203
- export declare function Async<T extends abstract new (...args: any[]) => FileSystem>(FS: T): (abstract new (...args: any[]) => AsyncFileSystem) & T;
203
+ export declare function Async<T extends abstract new (...args: any[]) => FileSystem>(FS: T): (abstract new (...args: any[]) => AsyncFS) & T;
204
204
  /**
205
205
  * @internal
206
206
  */
207
- declare abstract class ReadonlyFileSystem extends FileSystem {
207
+ declare abstract class ReadonlyFS extends FileSystem {
208
208
  metadata(): FileSystemMetadata;
209
209
  rename(oldPath: string, newPath: string, cred: Cred): Promise<void>;
210
210
  renameSync(oldPath: string, newPath: string, cred: Cred): void;
@@ -224,5 +224,5 @@ declare abstract class ReadonlyFileSystem extends FileSystem {
224
224
  /**
225
225
  * Implements the non-readonly methods to throw `EROFS`
226
226
  */
227
- export declare function Readonly<T extends abstract new (...args: any[]) => FileSystem>(FS: T): (abstract new (...args: any[]) => ReadonlyFileSystem) & T;
227
+ export declare function Readonly<T extends abstract new (...args: any[]) => FileSystem>(FS: T): (abstract new (...args: any[]) => ReadonlyFS) & T;
228
228
  export {};
@@ -58,7 +58,7 @@ export class FileSystem {
58
58
  */
59
59
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
60
60
  export function Sync(FS) {
61
- class _SyncFileSystem extends FS {
61
+ class _SyncFS extends FS {
62
62
  async exists(path, cred) {
63
63
  return this.existsSync(path, cred);
64
64
  }
@@ -93,7 +93,7 @@ export function Sync(FS) {
93
93
  return this.syncSync(path, data, stats);
94
94
  }
95
95
  }
96
- return _SyncFileSystem;
96
+ return _SyncFS;
97
97
  }
98
98
  /**
99
99
  * Async() implements synchronous methods on an asynchronous file system
@@ -109,7 +109,7 @@ export function Sync(FS) {
109
109
  */
110
110
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
111
111
  export function Async(FS) {
112
- class _AsyncFileSystem extends FS {
112
+ class _AsyncFS extends FS {
113
113
  constructor() {
114
114
  super(...arguments);
115
115
  /**
@@ -150,16 +150,17 @@ export function Async(FS) {
150
150
  return this._sync.statSync(path, cred);
151
151
  }
152
152
  createFileSync(path, flag, mode, cred) {
153
- const file = this._sync.createFileSync(path, flag, mode, cred);
153
+ this._sync.createFileSync(path, flag, mode, cred);
154
154
  this.queue('createFile', path, flag, mode, cred);
155
+ return this.openFileSync(path, flag, cred);
156
+ }
157
+ openFileSync(path, flag, cred) {
158
+ const file = this._sync.openFileSync(path, flag, cred);
155
159
  const stats = file.statSync();
156
160
  const buffer = new Uint8Array(stats.size);
157
161
  file.readSync(buffer);
158
162
  return new PreloadFile(this, path, flag, stats, buffer);
159
163
  }
160
- openFileSync(path, flag, cred) {
161
- return this._sync.openFileSync(path, flag, cred);
162
- }
163
164
  unlinkSync(path, cred) {
164
165
  this._sync.unlinkSync(path, cred);
165
166
  this.queue('unlink', path, cred);
@@ -235,14 +236,14 @@ export function Async(FS) {
235
236
  this._next();
236
237
  }
237
238
  }
238
- return _AsyncFileSystem;
239
+ return _AsyncFS;
239
240
  }
240
241
  /**
241
242
  * Implements the non-readonly methods to throw `EROFS`
242
243
  */
243
244
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
244
245
  export function Readonly(FS) {
245
- class _ReadonlyFileSystem extends FS {
246
+ class _ReadonlyFS extends FS {
246
247
  metadata() {
247
248
  return { ...super.metadata(), readonly: true };
248
249
  }
@@ -290,5 +291,5 @@ export function Readonly(FS) {
290
291
  throw new ErrnoError(Errno.EROFS);
291
292
  }
292
293
  }
293
- return _ReadonlyFileSystem;
294
+ return _ReadonlyFS;
294
295
  }
package/dist/index.d.ts CHANGED
@@ -6,6 +6,8 @@ export * from './backends/Index.js';
6
6
  export * from './backends/locked.js';
7
7
  export * from './backends/overlay.js';
8
8
  export * from './backends/store/fs.js';
9
+ export * from './backends/store/simple.js';
10
+ export * from './backends/store/store.js';
9
11
  export * from './backends/backend.js';
10
12
  export * from './config.js';
11
13
  export * from './cred.js';
package/dist/index.js CHANGED
@@ -6,6 +6,8 @@ export * from './backends/Index.js';
6
6
  export * from './backends/locked.js';
7
7
  export * from './backends/overlay.js';
8
8
  export * from './backends/store/fs.js';
9
+ export * from './backends/store/simple.js';
10
+ export * from './backends/store/store.js';
9
11
  export * from './backends/backend.js';
10
12
  export * from './config.js';
11
13
  export * from './cred.js';
package/dist/mutex.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * @internal
4
4
  */
5
5
  export declare class Mutex {
6
- private _locks;
6
+ protected locks: Map<string, (() => void)[]>;
7
7
  lock(path: string): Promise<void>;
8
8
  unlock(path: string): void;
9
9
  tryLock(path: string): boolean;
package/dist/mutex.js CHANGED
@@ -5,23 +5,23 @@ import { ErrnoError, Errno } from './error.js';
5
5
  */
6
6
  export class Mutex {
7
7
  constructor() {
8
- this._locks = new Map();
8
+ this.locks = new Map();
9
9
  }
10
10
  lock(path) {
11
11
  return new Promise(resolve => {
12
- if (this._locks.has(path)) {
13
- this._locks.get(path).push(resolve);
12
+ if (this.locks.has(path)) {
13
+ this.locks.get(path).push(resolve);
14
14
  }
15
15
  else {
16
- this._locks.set(path, [resolve]);
16
+ this.locks.set(path, [resolve]);
17
17
  }
18
18
  });
19
19
  }
20
20
  unlock(path) {
21
- if (!this._locks.has(path)) {
21
+ if (!this.locks.has(path)) {
22
22
  throw new ErrnoError(Errno.EPERM, 'Can not unlock an already unlocked path', path);
23
23
  }
24
- const next = this._locks.get(path)?.shift();
24
+ const next = this.locks.get(path)?.shift();
25
25
  /*
26
26
  don't unlock - we want to queue up next for the
27
27
  end of the current task execution, but we don't
@@ -31,19 +31,19 @@ export class Mutex {
31
31
  lock won't cause starvation.
32
32
  */
33
33
  if (next) {
34
- setTimeout(next, 0);
34
+ setTimeout(next);
35
35
  return;
36
36
  }
37
- this._locks.delete(path);
37
+ this.locks.delete(path);
38
38
  }
39
39
  tryLock(path) {
40
- if (this._locks.has(path)) {
40
+ if (this.locks.has(path)) {
41
41
  return false;
42
42
  }
43
- this._locks.set(path, []);
43
+ this.locks.set(path, []);
44
44
  return true;
45
45
  }
46
46
  isLocked(path) {
47
- return this._locks.has(path);
47
+ return this.locks.has(path);
48
48
  }
49
49
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zenfs/core",
3
- "version": "0.11.0",
3
+ "version": "0.11.2",
4
4
  "description": "A filesystem in your browser",
5
5
  "main": "dist/index.js",
6
6
  "types": "src/index.ts",
@@ -16,19 +16,19 @@ const { values: options, positionals } = parseArgs({
16
16
  allowPositionals: true,
17
17
  });
18
18
 
19
- const root = positionals.at(-1) == 'make-index' ? '.' : positionals.at(-1);
19
+ const root = positionals.at(-1) || '.';
20
20
 
21
21
  if (options.help) {
22
22
  console.log(`make-index <path> [...options]
23
- path: The path to create a listing for
24
23
 
25
- options:
26
- --help, -h Outputs this help message
27
- --quiet, -q Do not output messages about individual files
28
- --verbose Output verbose messages
24
+ path: The path to create a listing for
29
25
 
30
- --output, -o <path> Path to the output file. Defaults to listing.
31
- --ignore, -i <pattern> Ignores files which match the glob <pattern>. Can be passed multiple times.
26
+ options:
27
+ --help, -h Outputs this help message
28
+ --quiet, -q The command will not generate any output, including error messages.
29
+ --verbose Output verbose messages
30
+ --output, -o <path> Path to the output file. Defaults to listing.
31
+ --ignore, -i <pattern> Ignores files which match the glob <pattern>. Can be passed multiple times.
32
32
  `);
33
33
  process.exit();
34
34
  }
@@ -66,11 +66,13 @@ function color(color, text) {
66
66
  return `\x1b[${colors[color]}m${text}\x1b[0m`;
67
67
  }
68
68
 
69
- function makeListing(path, seen = new Set()) {
69
+ function listing(path, seen = new Set()) {
70
70
  try {
71
+ if (options.verbose) console.log(`${color('blue', 'list')} ${path}`);
71
72
  const stats = statSync(path);
72
73
 
73
74
  if (stats.isFile()) {
75
+ if (options.verbose) console.log(`${color('green', 'file')} ${path}`);
74
76
  return null;
75
77
  }
76
78
 
@@ -82,8 +84,9 @@ function makeListing(path, seen = new Set()) {
82
84
  continue;
83
85
  }
84
86
 
85
- entries[file] = makeListing(full, seen);
87
+ entries[file] = listing(full, seen);
86
88
  }
89
+ if (options.verbose) console.log(`${color('bright_green', ' dir')} ${path}`);
87
90
  return entries;
88
91
  } catch (e) {
89
92
  if (!options.quiet) {
@@ -92,7 +95,7 @@ function makeListing(path, seen = new Set()) {
92
95
  }
93
96
  }
94
97
 
95
- const listing = makeListing(pathToPosix(root));
98
+ const rootListing = listing(pathToPosix(root));
96
99
  if (!options.quiet) console.log('Generated listing for ' + pathToPosix(resolve(root)));
97
100
 
98
- writeFileSync(options.output, JSON.stringify(listing));
101
+ writeFileSync(options.output, JSON.stringify(rootListing));
@@ -41,7 +41,7 @@ export interface Backend<FS extends FileSystem = FileSystem, TOptions extends ob
41
41
  /**
42
42
  * Create a new instance of the backend
43
43
  */
44
- create(options: TOptions): FS;
44
+ create(options: TOptions): FS | Promise<FS>;
45
45
 
46
46
  /**
47
47
  * A name to identify the backend.
@@ -68,6 +68,8 @@ export interface Backend<FS extends FileSystem = FileSystem, TOptions extends ob
68
68
 
69
69
  type OptionsOf<T extends Backend> = T extends Backend<FileSystem, infer TOptions> ? TOptions : never;
70
70
 
71
+ type FilesystemOf<T extends Backend> = T extends Backend<infer FS> ? FS : never;
72
+
71
73
  /**
72
74
  * @internal
73
75
  */
@@ -128,13 +130,6 @@ export async function checkOptions<T extends Backend>(backend: T, opts: Partial<
128
130
  }
129
131
  }
130
132
 
131
- export async function createBackend<B extends Backend>(backend: B, options: Partial<OptionsOf<B>> = {}): Promise<ReturnType<B['create']>> {
132
- await checkOptions(backend, options);
133
- const fs = <ReturnType<B['create']>>backend.create(options);
134
- await fs.ready();
135
- return fs;
136
- }
137
-
138
133
  /**
139
134
  * Specifies a file system backend type and its options.
140
135
  *
@@ -5,13 +5,6 @@ import { Stats } from '../stats.js';
5
5
  import { type ListingTree, FileIndex, type IndexFileInode, AsyncIndexFS } from './Index.js';
6
6
  import type { Backend } from './backend.js';
7
7
 
8
- /**
9
- * @hidden
10
- */
11
- function convertError(e: Error): never {
12
- throw new ErrnoError(Errno.EIO, e.message);
13
- }
14
-
15
8
  /**
16
9
  * Asynchronously download a file as a buffer or a JSON object.
17
10
  * Note that the third function signature with a non-specialized type is
@@ -23,16 +16,22 @@ async function fetchFile(path: string, type: 'buffer'): Promise<Uint8Array>;
23
16
  async function fetchFile<T extends object>(path: string, type: 'json'): Promise<T>;
24
17
  async function fetchFile<T extends object>(path: string, type: 'buffer' | 'json'): Promise<T | Uint8Array>;
25
18
  async function fetchFile<T extends object>(path: string, type: 'buffer' | 'json'): Promise<T | Uint8Array> {
26
- const response = await fetch(path).catch(convertError);
19
+ const response = await fetch(path).catch(e => {
20
+ throw new ErrnoError(Errno.EIO, e.message);
21
+ });
27
22
  if (!response.ok) {
28
23
  throw new ErrnoError(Errno.EIO, 'fetch failed: response returned code ' + response.status);
29
24
  }
30
25
  switch (type) {
31
26
  case 'buffer':
32
- const arrayBuffer = await response.arrayBuffer().catch(convertError);
27
+ const arrayBuffer = await response.arrayBuffer().catch(e => {
28
+ throw new ErrnoError(Errno.EIO, e.message);
29
+ });
33
30
  return new Uint8Array(arrayBuffer);
34
31
  case 'json':
35
- return response.json().catch(convertError) as Promise<T>;
32
+ return response.json().catch(e => {
33
+ throw new ErrnoError(Errno.EIO, e.message);
34
+ }) as Promise<T>;
36
35
  default:
37
36
  throw new ErrnoError(Errno.EINVAL, 'Invalid download type: ' + type);
38
37
  }
@@ -43,7 +42,9 @@ async function fetchFile<T extends object>(path: string, type: 'buffer' | 'json'
43
42
  * @hidden
44
43
  */
45
44
  async function fetchSize(path: string): Promise<number> {
46
- const response = await fetch(path, { method: 'HEAD' }).catch(convertError);
45
+ const response = await fetch(path, { method: 'HEAD' }).catch(e => {
46
+ throw new ErrnoError(Errno.EIO, e.message);
47
+ });
47
48
  if (!response.ok) {
48
49
  throw new ErrnoError(Errno.EIO, 'fetch failed: HEAD response returned code ' + response.status);
49
50
  }
@@ -210,7 +211,7 @@ export const Fetch = {
210
211
  index: {
211
212
  type: ['string', 'object'],
212
213
  required: false,
213
- 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`.',
214
+ description: 'URL to a file index as a JSON file or the file index object itself, generated with the make-index script. Defaults to `index.json`.',
214
215
  },
215
216
  baseUrl: {
216
217
  type: 'string',