@zenfs/core 0.16.4 → 0.17.1

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 (80) hide show
  1. package/dist/backends/backend.d.ts +3 -4
  2. package/dist/backends/fetch.d.ts +8 -3
  3. package/dist/backends/fetch.js +3 -2
  4. package/dist/backends/{index/fs.d.ts → file_index.d.ts} +49 -10
  5. package/dist/backends/{index/fs.js → file_index.js} +84 -5
  6. package/dist/backends/memory.d.ts +6 -1
  7. package/dist/backends/memory.js +2 -1
  8. package/dist/backends/overlay.d.ts +16 -16
  9. package/dist/backends/overlay.js +59 -82
  10. package/dist/backends/port/fs.d.ts +6 -2
  11. package/dist/backends/port/fs.js +4 -2
  12. package/dist/backends/store/fs.js +484 -304
  13. package/dist/backends/store/simple.js +5 -1
  14. package/dist/backends/store/store.d.ts +4 -1
  15. package/dist/backends/store/store.js +9 -5
  16. package/dist/browser.min.js +4 -4
  17. package/dist/browser.min.js.map +4 -4
  18. package/dist/config.d.ts +3 -3
  19. package/dist/emulation/async.d.ts +1 -4
  20. package/dist/emulation/async.js +9 -4
  21. package/dist/emulation/dir.d.ts +4 -0
  22. package/dist/emulation/dir.js +8 -6
  23. package/dist/emulation/promises.d.ts +1 -3
  24. package/dist/emulation/promises.js +25 -2
  25. package/dist/emulation/sync.js +0 -1
  26. package/dist/emulation/watchers.d.ts +9 -4
  27. package/dist/emulation/watchers.js +7 -0
  28. package/dist/file.d.ts +17 -1
  29. package/dist/file.js +86 -1
  30. package/dist/filesystem.d.ts +4 -67
  31. package/dist/filesystem.js +2 -313
  32. package/dist/index.d.ts +2 -2
  33. package/dist/index.js +2 -2
  34. package/dist/mixins/async.d.ts +39 -0
  35. package/dist/mixins/async.js +216 -0
  36. package/dist/mixins/index.d.ts +4 -0
  37. package/dist/mixins/index.js +4 -0
  38. package/dist/mixins/mutexed.d.ts +33 -0
  39. package/dist/mixins/mutexed.js +465 -0
  40. package/dist/mixins/readonly.d.ts +25 -0
  41. package/dist/mixins/readonly.js +57 -0
  42. package/dist/mixins/shared.d.ts +12 -0
  43. package/dist/mixins/shared.js +4 -0
  44. package/dist/mixins/sync.d.ts +6 -0
  45. package/dist/mixins/sync.js +43 -0
  46. package/dist/utils.d.ts +0 -5
  47. package/dist/utils.js +0 -7
  48. package/package.json +3 -2
  49. package/src/backends/backend.ts +3 -4
  50. package/src/backends/fetch.ts +7 -3
  51. package/src/backends/{index/fs.ts → file_index.ts} +106 -8
  52. package/src/backends/memory.ts +5 -1
  53. package/src/backends/overlay.ts +64 -90
  54. package/src/backends/port/fs.ts +7 -2
  55. package/src/backends/{index/readme.md → readme.md} +1 -1
  56. package/src/backends/store/fs.ts +97 -155
  57. package/src/backends/store/simple.ts +5 -1
  58. package/src/backends/store/store.ts +10 -5
  59. package/src/config.ts +3 -1
  60. package/src/emulation/async.ts +20 -9
  61. package/src/emulation/dir.ts +19 -16
  62. package/src/emulation/promises.ts +28 -6
  63. package/src/emulation/sync.ts +1 -2
  64. package/src/emulation/watchers.ts +10 -4
  65. package/src/file.ts +94 -1
  66. package/src/filesystem.ts +5 -368
  67. package/src/index.ts +2 -2
  68. package/src/mixins/async.ts +211 -0
  69. package/src/mixins/index.ts +4 -0
  70. package/src/mixins/mutexed.ts +245 -0
  71. package/src/mixins/readonly.ts +97 -0
  72. package/src/mixins/shared.ts +20 -0
  73. package/src/mixins/sync.ts +59 -0
  74. package/src/utils.ts +0 -8
  75. package/dist/backends/index/index.d.ts +0 -43
  76. package/dist/backends/index/index.js +0 -83
  77. package/dist/backends/locked.d.ts +0 -92
  78. package/dist/backends/locked.js +0 -487
  79. package/src/backends/index/index.ts +0 -104
  80. package/src/backends/locked.ts +0 -264
@@ -0,0 +1,465 @@
1
+ var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
2
+ if (value !== null && value !== void 0) {
3
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
4
+ var dispose;
5
+ if (async) {
6
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
7
+ dispose = value[Symbol.asyncDispose];
8
+ }
9
+ if (dispose === void 0) {
10
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
11
+ dispose = value[Symbol.dispose];
12
+ }
13
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
14
+ env.stack.push({ value: value, dispose: dispose, async: async });
15
+ }
16
+ else if (async) {
17
+ env.stack.push({ async: true });
18
+ }
19
+ return value;
20
+ };
21
+ var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
22
+ return function (env) {
23
+ function fail(e) {
24
+ env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
25
+ env.hasError = true;
26
+ }
27
+ function next() {
28
+ while (env.stack.length) {
29
+ var rec = env.stack.pop();
30
+ try {
31
+ var result = rec.dispose && rec.dispose.call(rec.value);
32
+ if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
33
+ }
34
+ catch (e) {
35
+ fail(e);
36
+ }
37
+ }
38
+ if (env.hasError) throw env.error;
39
+ }
40
+ return next();
41
+ };
42
+ })(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
43
+ var e = new Error(message);
44
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
45
+ });
46
+ import { ErrnoError } from '../error.js';
47
+ import '../polyfills.js';
48
+ export class MutexLock {
49
+ get isLocked() {
50
+ return this._isLocked;
51
+ }
52
+ constructor(path, previous) {
53
+ this.path = path;
54
+ this.previous = previous;
55
+ this.current = Promise.withResolvers();
56
+ this._isLocked = true;
57
+ }
58
+ async done() {
59
+ await this.previous?.done();
60
+ await this.current.promise;
61
+ }
62
+ unlock() {
63
+ this.current.resolve();
64
+ this._isLocked = false;
65
+ }
66
+ [Symbol.dispose]() {
67
+ this.unlock();
68
+ }
69
+ }
70
+ /**
71
+ * This serializes access to an underlying async filesystem.
72
+ * For example, on an OverlayFS instance with an async lower
73
+ * directory operations like rename and rmdir may involve multiple
74
+ * requests involving both the upper and lower filesystems -- they
75
+ * are not executed in a single atomic step. OverlayFS uses this
76
+ * to avoid having to reason about the correctness of
77
+ * multiple requests interleaving.
78
+ *
79
+ * Note: `@ts-expect-error 2513` is needed because `FS` is not properly detected as being concrete
80
+ *
81
+ * @todo Change `using _` to `using void` pending https://github.com/tc39/proposal-discard-binding
82
+ * @internal
83
+ */
84
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
85
+ export function Mutexed(FS) {
86
+ class MutexedFS extends FS {
87
+ constructor() {
88
+ super(...arguments);
89
+ /**
90
+ * The current locks
91
+ */
92
+ this.locks = new Map();
93
+ /* eslint-enable @typescript-eslint/no-unused-vars */
94
+ }
95
+ /**
96
+ * Adds a lock for a path
97
+ */
98
+ addLock(path) {
99
+ const previous = this.locks.get(path);
100
+ const lock = new MutexLock(path, previous?.isLocked ? previous : undefined);
101
+ this.locks.set(path, lock);
102
+ return lock;
103
+ }
104
+ /**
105
+ * Locks `path` asynchronously.
106
+ * If the path is currently locked, waits for it to be unlocked.
107
+ * @internal
108
+ */
109
+ async lock(path) {
110
+ const previous = this.locks.get(path);
111
+ const lock = this.addLock(path);
112
+ await previous?.done();
113
+ return lock;
114
+ }
115
+ /**
116
+ * Locks `path` asynchronously.
117
+ * If the path is currently locked, an error will be thrown
118
+ * @internal
119
+ */
120
+ lockSync(path) {
121
+ if (this.locks.has(path)) {
122
+ // Non-null assertion: we already checked locks has path
123
+ throw ErrnoError.With('EBUSY', path, 'lockSync');
124
+ }
125
+ return this.addLock(path);
126
+ }
127
+ /**
128
+ * Whether `path` is locked
129
+ * @internal
130
+ */
131
+ isLocked(path) {
132
+ return !!this.locks.get(path)?.isLocked;
133
+ }
134
+ /* eslint-disable @typescript-eslint/no-unused-vars */
135
+ async rename(oldPath, newPath, cred) {
136
+ const env_1 = { stack: [], error: void 0, hasError: false };
137
+ try {
138
+ const _ = __addDisposableResource(env_1, await this.lock(oldPath), false);
139
+ // @ts-expect-error 2513
140
+ await super.rename(oldPath, newPath, cred);
141
+ }
142
+ catch (e_1) {
143
+ env_1.error = e_1;
144
+ env_1.hasError = true;
145
+ }
146
+ finally {
147
+ __disposeResources(env_1);
148
+ }
149
+ }
150
+ renameSync(oldPath, newPath, cred) {
151
+ const env_2 = { stack: [], error: void 0, hasError: false };
152
+ try {
153
+ const _ = __addDisposableResource(env_2, this.lockSync(oldPath), false);
154
+ // @ts-expect-error 2513
155
+ return super.renameSync(oldPath, newPath, cred);
156
+ }
157
+ catch (e_2) {
158
+ env_2.error = e_2;
159
+ env_2.hasError = true;
160
+ }
161
+ finally {
162
+ __disposeResources(env_2);
163
+ }
164
+ }
165
+ async stat(path, cred) {
166
+ const env_3 = { stack: [], error: void 0, hasError: false };
167
+ try {
168
+ const _ = __addDisposableResource(env_3, await this.lock(path), false);
169
+ // @ts-expect-error 2513
170
+ return await super.stat(path, cred);
171
+ }
172
+ catch (e_3) {
173
+ env_3.error = e_3;
174
+ env_3.hasError = true;
175
+ }
176
+ finally {
177
+ __disposeResources(env_3);
178
+ }
179
+ }
180
+ statSync(path, cred) {
181
+ const env_4 = { stack: [], error: void 0, hasError: false };
182
+ try {
183
+ const _ = __addDisposableResource(env_4, this.lockSync(path), false);
184
+ // @ts-expect-error 2513
185
+ return super.statSync(path, cred);
186
+ }
187
+ catch (e_4) {
188
+ env_4.error = e_4;
189
+ env_4.hasError = true;
190
+ }
191
+ finally {
192
+ __disposeResources(env_4);
193
+ }
194
+ }
195
+ async openFile(path, flag, cred) {
196
+ const env_5 = { stack: [], error: void 0, hasError: false };
197
+ try {
198
+ const _ = __addDisposableResource(env_5, await this.lock(path), false);
199
+ // @ts-expect-error 2513
200
+ return await super.openFile(path, flag, cred);
201
+ }
202
+ catch (e_5) {
203
+ env_5.error = e_5;
204
+ env_5.hasError = true;
205
+ }
206
+ finally {
207
+ __disposeResources(env_5);
208
+ }
209
+ }
210
+ openFileSync(path, flag, cred) {
211
+ const env_6 = { stack: [], error: void 0, hasError: false };
212
+ try {
213
+ const _ = __addDisposableResource(env_6, this.lockSync(path), false);
214
+ // @ts-expect-error 2513
215
+ return super.openFileSync(path, flag, cred);
216
+ }
217
+ catch (e_6) {
218
+ env_6.error = e_6;
219
+ env_6.hasError = true;
220
+ }
221
+ finally {
222
+ __disposeResources(env_6);
223
+ }
224
+ }
225
+ async createFile(path, flag, mode, cred) {
226
+ const env_7 = { stack: [], error: void 0, hasError: false };
227
+ try {
228
+ const _ = __addDisposableResource(env_7, await this.lock(path), false);
229
+ // @ts-expect-error 2513
230
+ return await super.createFile(path, flag, mode, cred);
231
+ }
232
+ catch (e_7) {
233
+ env_7.error = e_7;
234
+ env_7.hasError = true;
235
+ }
236
+ finally {
237
+ __disposeResources(env_7);
238
+ }
239
+ }
240
+ createFileSync(path, flag, mode, cred) {
241
+ const env_8 = { stack: [], error: void 0, hasError: false };
242
+ try {
243
+ const _ = __addDisposableResource(env_8, this.lockSync(path), false);
244
+ // @ts-expect-error 2513
245
+ return super.createFileSync(path, flag, mode, cred);
246
+ }
247
+ catch (e_8) {
248
+ env_8.error = e_8;
249
+ env_8.hasError = true;
250
+ }
251
+ finally {
252
+ __disposeResources(env_8);
253
+ }
254
+ }
255
+ async unlink(path, cred) {
256
+ const env_9 = { stack: [], error: void 0, hasError: false };
257
+ try {
258
+ const _ = __addDisposableResource(env_9, await this.lock(path), false);
259
+ // @ts-expect-error 2513
260
+ await super.unlink(path, cred);
261
+ }
262
+ catch (e_9) {
263
+ env_9.error = e_9;
264
+ env_9.hasError = true;
265
+ }
266
+ finally {
267
+ __disposeResources(env_9);
268
+ }
269
+ }
270
+ unlinkSync(path, cred) {
271
+ const env_10 = { stack: [], error: void 0, hasError: false };
272
+ try {
273
+ const _ = __addDisposableResource(env_10, this.lockSync(path), false);
274
+ // @ts-expect-error 2513
275
+ return super.unlinkSync(path, cred);
276
+ }
277
+ catch (e_10) {
278
+ env_10.error = e_10;
279
+ env_10.hasError = true;
280
+ }
281
+ finally {
282
+ __disposeResources(env_10);
283
+ }
284
+ }
285
+ async rmdir(path, cred) {
286
+ const env_11 = { stack: [], error: void 0, hasError: false };
287
+ try {
288
+ const _ = __addDisposableResource(env_11, await this.lock(path), false);
289
+ // @ts-expect-error 2513
290
+ await super.rmdir(path, cred);
291
+ }
292
+ catch (e_11) {
293
+ env_11.error = e_11;
294
+ env_11.hasError = true;
295
+ }
296
+ finally {
297
+ __disposeResources(env_11);
298
+ }
299
+ }
300
+ rmdirSync(path, cred) {
301
+ const env_12 = { stack: [], error: void 0, hasError: false };
302
+ try {
303
+ const _ = __addDisposableResource(env_12, this.lockSync(path), false);
304
+ // @ts-expect-error 2513
305
+ return super.rmdirSync(path, cred);
306
+ }
307
+ catch (e_12) {
308
+ env_12.error = e_12;
309
+ env_12.hasError = true;
310
+ }
311
+ finally {
312
+ __disposeResources(env_12);
313
+ }
314
+ }
315
+ async mkdir(path, mode, cred) {
316
+ const env_13 = { stack: [], error: void 0, hasError: false };
317
+ try {
318
+ const _ = __addDisposableResource(env_13, await this.lock(path), false);
319
+ // @ts-expect-error 2513
320
+ await super.mkdir(path, mode, cred);
321
+ }
322
+ catch (e_13) {
323
+ env_13.error = e_13;
324
+ env_13.hasError = true;
325
+ }
326
+ finally {
327
+ __disposeResources(env_13);
328
+ }
329
+ }
330
+ mkdirSync(path, mode, cred) {
331
+ const env_14 = { stack: [], error: void 0, hasError: false };
332
+ try {
333
+ const _ = __addDisposableResource(env_14, this.lockSync(path), false);
334
+ // @ts-expect-error 2513
335
+ return super.mkdirSync(path, mode, cred);
336
+ }
337
+ catch (e_14) {
338
+ env_14.error = e_14;
339
+ env_14.hasError = true;
340
+ }
341
+ finally {
342
+ __disposeResources(env_14);
343
+ }
344
+ }
345
+ async readdir(path, cred) {
346
+ const env_15 = { stack: [], error: void 0, hasError: false };
347
+ try {
348
+ const _ = __addDisposableResource(env_15, await this.lock(path), false);
349
+ // @ts-expect-error 2513
350
+ return await super.readdir(path, cred);
351
+ }
352
+ catch (e_15) {
353
+ env_15.error = e_15;
354
+ env_15.hasError = true;
355
+ }
356
+ finally {
357
+ __disposeResources(env_15);
358
+ }
359
+ }
360
+ readdirSync(path, cred) {
361
+ const env_16 = { stack: [], error: void 0, hasError: false };
362
+ try {
363
+ const _ = __addDisposableResource(env_16, this.lockSync(path), false);
364
+ // @ts-expect-error 2513
365
+ return super.readdirSync(path, cred);
366
+ }
367
+ catch (e_16) {
368
+ env_16.error = e_16;
369
+ env_16.hasError = true;
370
+ }
371
+ finally {
372
+ __disposeResources(env_16);
373
+ }
374
+ }
375
+ async exists(path, cred) {
376
+ const env_17 = { stack: [], error: void 0, hasError: false };
377
+ try {
378
+ const _ = __addDisposableResource(env_17, await this.lock(path), false);
379
+ return await super.exists(path, cred);
380
+ }
381
+ catch (e_17) {
382
+ env_17.error = e_17;
383
+ env_17.hasError = true;
384
+ }
385
+ finally {
386
+ __disposeResources(env_17);
387
+ }
388
+ }
389
+ existsSync(path, cred) {
390
+ const env_18 = { stack: [], error: void 0, hasError: false };
391
+ try {
392
+ const _ = __addDisposableResource(env_18, this.lockSync(path), false);
393
+ return super.existsSync(path, cred);
394
+ }
395
+ catch (e_18) {
396
+ env_18.error = e_18;
397
+ env_18.hasError = true;
398
+ }
399
+ finally {
400
+ __disposeResources(env_18);
401
+ }
402
+ }
403
+ async link(srcpath, dstpath, cred) {
404
+ const env_19 = { stack: [], error: void 0, hasError: false };
405
+ try {
406
+ const _ = __addDisposableResource(env_19, await this.lock(srcpath), false);
407
+ // @ts-expect-error 2513
408
+ await super.link(srcpath, dstpath, cred);
409
+ }
410
+ catch (e_19) {
411
+ env_19.error = e_19;
412
+ env_19.hasError = true;
413
+ }
414
+ finally {
415
+ __disposeResources(env_19);
416
+ }
417
+ }
418
+ linkSync(srcpath, dstpath, cred) {
419
+ const env_20 = { stack: [], error: void 0, hasError: false };
420
+ try {
421
+ const _ = __addDisposableResource(env_20, this.lockSync(srcpath), false);
422
+ // @ts-expect-error 2513
423
+ return super.linkSync(srcpath, dstpath, cred);
424
+ }
425
+ catch (e_20) {
426
+ env_20.error = e_20;
427
+ env_20.hasError = true;
428
+ }
429
+ finally {
430
+ __disposeResources(env_20);
431
+ }
432
+ }
433
+ async sync(path, data, stats) {
434
+ const env_21 = { stack: [], error: void 0, hasError: false };
435
+ try {
436
+ const _ = __addDisposableResource(env_21, await this.lock(path), false);
437
+ // @ts-expect-error 2513
438
+ await super.sync(path, data, stats);
439
+ }
440
+ catch (e_21) {
441
+ env_21.error = e_21;
442
+ env_21.hasError = true;
443
+ }
444
+ finally {
445
+ __disposeResources(env_21);
446
+ }
447
+ }
448
+ syncSync(path, data, stats) {
449
+ const env_22 = { stack: [], error: void 0, hasError: false };
450
+ try {
451
+ const _ = __addDisposableResource(env_22, this.lockSync(path), false);
452
+ // @ts-expect-error 2513
453
+ return super.syncSync(path, data, stats);
454
+ }
455
+ catch (e_22) {
456
+ env_22.error = e_22;
457
+ env_22.hasError = true;
458
+ }
459
+ finally {
460
+ __disposeResources(env_22);
461
+ }
462
+ }
463
+ }
464
+ return MutexedFS;
465
+ }
@@ -0,0 +1,25 @@
1
+ import type { Cred } from '../cred.js';
2
+ import type { File } from '../file.js';
3
+ import type { FileSystem, FileSystemMetadata } from '../filesystem.js';
4
+ import type { Stats } from '../stats.js';
5
+ import type { Mixin } from './shared.js';
6
+ /**
7
+ * Implements the non-readonly methods to throw `EROFS`
8
+ */
9
+ export declare function Readonly<T extends typeof FileSystem>(FS: T): Mixin<T, {
10
+ metadata(): FileSystemMetadata;
11
+ rename(oldPath: string, newPath: string, cred: Cred): Promise<void>;
12
+ renameSync(oldPath: string, newPath: string, cred: Cred): void;
13
+ createFile(path: string, flag: string, mode: number, cred: Cred): Promise<File>;
14
+ createFileSync(path: string, flag: string, mode: number, cred: Cred): File;
15
+ unlink(path: string, cred: Cred): Promise<void>;
16
+ unlinkSync(path: string, cred: Cred): void;
17
+ rmdir(path: string, cred: Cred): Promise<void>;
18
+ rmdirSync(path: string, cred: Cred): void;
19
+ mkdir(path: string, mode: number, cred: Cred): Promise<void>;
20
+ mkdirSync(path: string, mode: number, cred: Cred): void;
21
+ link(srcpath: string, dstpath: string, cred: Cred): Promise<void>;
22
+ linkSync(srcpath: string, dstpath: string, cred: Cred): void;
23
+ sync(path: string, data: Uint8Array, stats: Readonly<Stats>): Promise<void>;
24
+ syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void;
25
+ }>;
@@ -0,0 +1,57 @@
1
+ import { Errno, ErrnoError } from '../error.js';
2
+ /**
3
+ * Implements the non-readonly methods to throw `EROFS`
4
+ */
5
+ /* eslint-disable @typescript-eslint/require-await */
6
+ export function Readonly(FS) {
7
+ class ReadonlyFS extends FS {
8
+ metadata() {
9
+ return { ...super.metadata(), readonly: true };
10
+ }
11
+ /* eslint-disable @typescript-eslint/no-unused-vars */
12
+ async rename(oldPath, newPath, cred) {
13
+ throw new ErrnoError(Errno.EROFS);
14
+ }
15
+ renameSync(oldPath, newPath, cred) {
16
+ throw new ErrnoError(Errno.EROFS);
17
+ }
18
+ async createFile(path, flag, mode, cred) {
19
+ throw new ErrnoError(Errno.EROFS);
20
+ }
21
+ createFileSync(path, flag, mode, cred) {
22
+ throw new ErrnoError(Errno.EROFS);
23
+ }
24
+ async unlink(path, cred) {
25
+ throw new ErrnoError(Errno.EROFS);
26
+ }
27
+ unlinkSync(path, cred) {
28
+ throw new ErrnoError(Errno.EROFS);
29
+ }
30
+ async rmdir(path, cred) {
31
+ throw new ErrnoError(Errno.EROFS);
32
+ }
33
+ rmdirSync(path, cred) {
34
+ throw new ErrnoError(Errno.EROFS);
35
+ }
36
+ async mkdir(path, mode, cred) {
37
+ throw new ErrnoError(Errno.EROFS);
38
+ }
39
+ mkdirSync(path, mode, cred) {
40
+ throw new ErrnoError(Errno.EROFS);
41
+ }
42
+ async link(srcpath, dstpath, cred) {
43
+ throw new ErrnoError(Errno.EROFS);
44
+ }
45
+ linkSync(srcpath, dstpath, cred) {
46
+ throw new ErrnoError(Errno.EROFS);
47
+ }
48
+ async sync(path, data, stats) {
49
+ throw new ErrnoError(Errno.EROFS);
50
+ }
51
+ syncSync(path, data, stats) {
52
+ throw new ErrnoError(Errno.EROFS);
53
+ }
54
+ }
55
+ return ReadonlyFS;
56
+ }
57
+ /* eslint-enable @typescript-eslint/require-await */
@@ -0,0 +1,12 @@
1
+ import type { ExtractProperties } from 'utilium';
2
+ import type { FileSystem } from '../filesystem.js';
3
+ /**
4
+ * `TBase` with `TMixin` mixed-in.
5
+ * @internal @experimental
6
+ */
7
+ export type Mixin<TBase extends typeof FileSystem, TMixin> = (abstract new (...args: any[]) => TMixin) & TBase;
8
+ /**
9
+ * Asynchronous `FileSystem` methods. This is a convience type.
10
+ * @internal
11
+ */
12
+ export type _AsyncFSMethods = ExtractProperties<FileSystem, (...args: any[]) => Promise<unknown>>;
@@ -0,0 +1,4 @@
1
+ /*
2
+ Code shared by various mixins
3
+ */
4
+ export {};
@@ -0,0 +1,6 @@
1
+ import type { FileSystem } from '../filesystem.js';
2
+ import type { Mixin, _AsyncFSMethods } from './shared.js';
3
+ /**
4
+ * Implements the asynchronous API in terms of the synchronous API.
5
+ */
6
+ export declare function Sync<T extends typeof FileSystem>(FS: T): Mixin<T, _AsyncFSMethods>;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Implements the asynchronous API in terms of the synchronous API.
3
+ */
4
+ /* eslint-disable @typescript-eslint/require-await */
5
+ export function Sync(FS) {
6
+ class SyncFS extends FS {
7
+ async exists(path, cred) {
8
+ return this.existsSync(path, cred);
9
+ }
10
+ async rename(oldPath, newPath, cred) {
11
+ return this.renameSync(oldPath, newPath, cred);
12
+ }
13
+ async stat(path, cred) {
14
+ return this.statSync(path, cred);
15
+ }
16
+ async createFile(path, flag, mode, cred) {
17
+ return this.createFileSync(path, flag, mode, cred);
18
+ }
19
+ async openFile(path, flag, cred) {
20
+ return this.openFileSync(path, flag, cred);
21
+ }
22
+ async unlink(path, cred) {
23
+ return this.unlinkSync(path, cred);
24
+ }
25
+ async rmdir(path, cred) {
26
+ return this.rmdirSync(path, cred);
27
+ }
28
+ async mkdir(path, mode, cred) {
29
+ return this.mkdirSync(path, mode, cred);
30
+ }
31
+ async readdir(path, cred) {
32
+ return this.readdirSync(path, cred);
33
+ }
34
+ async link(srcpath, dstpath, cred) {
35
+ return this.linkSync(srcpath, dstpath, cred);
36
+ }
37
+ async sync(path, data, stats) {
38
+ return this.syncSync(path, data, stats);
39
+ }
40
+ }
41
+ return SyncFS;
42
+ }
43
+ /* eslint-enable @typescript-eslint/require-await */
package/dist/utils.d.ts CHANGED
@@ -82,8 +82,3 @@ export declare function normalizeOptions(options: fs.WriteFileOptions | (fs.Enco
82
82
  flag: string;
83
83
  mode: number;
84
84
  };
85
- /**
86
- * Do nothing
87
- * @internal
88
- */
89
- export declare function nop(): void;
package/dist/utils.js CHANGED
@@ -219,10 +219,3 @@ export function normalizeOptions(options, encoding = 'utf8', flag, mode = 0) {
219
219
  mode: normalizeMode('mode' in options ? options?.mode : null, mode),
220
220
  };
221
221
  }
222
- /**
223
- * Do nothing
224
- * @internal
225
- */
226
- export function nop() {
227
- // do nothing
228
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zenfs/core",
3
- "version": "0.16.4",
3
+ "version": "0.17.1",
4
4
  "description": "A filesystem, anywhere",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -40,7 +40,8 @@
40
40
  "exports": {
41
41
  ".": "./dist/index.js",
42
42
  "./*": "./dist/*",
43
- "./promises": "./dist/emulation/promises.js"
43
+ "./promises": "./dist/emulation/promises.js",
44
+ "./mixins": "./dist/mixins/index.js"
44
45
  },
45
46
  "scripts": {
46
47
  "format": "prettier --write .",
@@ -66,12 +66,11 @@ export interface Backend<FS extends FileSystem = FileSystem, TOptions extends ob
66
66
  /**
67
67
  * Whether the backend is available in the current environment.
68
68
  * It supports checking synchronously and asynchronously
69
- * Sync:
69
+ *
70
70
  * Returns 'true' if this backend is available in the current
71
- * environment. For example, a `localStorage`-backed filesystem will return
72
- * 'false' if the browser does not support that API.
71
+ * environment. For example, a backend using a browser API will return
72
+ * 'false' if the API is unavailable
73
73
  *
74
- * Defaults to 'false', as the FileSystem base class isn't usable alone.
75
74
  */
76
75
  isAvailable(): boolean | Promise<boolean>;
77
76
  }