@zenfs/core 0.16.4 → 0.17.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 (74) 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 +0 -3
  20. package/dist/emulation/async.js +6 -2
  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 +0 -63
  31. package/dist/filesystem.js +0 -311
  32. package/dist/index.d.ts +1 -2
  33. package/dist/index.js +1 -2
  34. package/dist/mixins/async.d.ts +39 -0
  35. package/dist/mixins/async.js +216 -0
  36. package/dist/mixins/mutexed.d.ts +33 -0
  37. package/dist/mixins/mutexed.js +465 -0
  38. package/dist/mixins/readonly.d.ts +25 -0
  39. package/dist/mixins/readonly.js +57 -0
  40. package/dist/mixins/shared.d.ts +12 -0
  41. package/dist/mixins/shared.js +4 -0
  42. package/dist/mixins/sync.d.ts +6 -0
  43. package/dist/mixins/sync.js +43 -0
  44. package/package.json +1 -1
  45. package/src/backends/backend.ts +3 -4
  46. package/src/backends/fetch.ts +7 -3
  47. package/src/backends/{index/fs.ts → file_index.ts} +106 -8
  48. package/src/backends/memory.ts +5 -1
  49. package/src/backends/overlay.ts +64 -90
  50. package/src/backends/port/fs.ts +7 -2
  51. package/src/backends/{index/readme.md → readme.md} +1 -1
  52. package/src/backends/store/fs.ts +97 -155
  53. package/src/backends/store/simple.ts +5 -1
  54. package/src/backends/store/store.ts +10 -5
  55. package/src/config.ts +3 -1
  56. package/src/emulation/async.ts +15 -6
  57. package/src/emulation/dir.ts +19 -16
  58. package/src/emulation/promises.ts +28 -6
  59. package/src/emulation/sync.ts +1 -2
  60. package/src/emulation/watchers.ts +10 -4
  61. package/src/file.ts +94 -1
  62. package/src/filesystem.ts +3 -366
  63. package/src/index.ts +1 -2
  64. package/src/mixins/async.ts +211 -0
  65. package/src/mixins/mutexed.ts +245 -0
  66. package/src/mixins/readonly.ts +97 -0
  67. package/src/mixins/shared.ts +20 -0
  68. package/src/mixins/sync.ts +59 -0
  69. package/dist/backends/index/index.d.ts +0 -43
  70. package/dist/backends/index/index.js +0 -83
  71. package/dist/backends/locked.d.ts +0 -92
  72. package/dist/backends/locked.js +0 -487
  73. package/src/backends/index/index.ts +0 -104
  74. package/src/backends/locked.ts +0 -264
package/dist/config.d.ts CHANGED
@@ -9,9 +9,9 @@ export type MountConfiguration<T extends Backend> = FilesystemOf<T> | BackendCon
9
9
  * @see MountConfiguration
10
10
  */
11
11
  export declare function resolveMountConfig<T extends Backend>(config: MountConfiguration<T>, _depth?: number): Promise<FilesystemOf<T>>;
12
- export type ConfigMounts = {
13
- [K in AbsolutePath]: Backend;
14
- };
12
+ export interface ConfigMounts {
13
+ [K: AbsolutePath]: Backend;
14
+ }
15
15
  /**
16
16
  * Configuration
17
17
  */
@@ -369,9 +369,6 @@ export declare function watchFile(path: fs.PathLike, options: {
369
369
  * @todo Implement
370
370
  */
371
371
  export declare function unwatchFile(path: fs.PathLike, listener?: (curr: Stats, prev: Stats) => void): void;
372
- /**
373
- * @todo Implement
374
- */
375
372
  export declare function watch(path: fs.PathLike, listener?: (event: string, filename: string) => any): fs.FSWatcher;
376
373
  export declare function watch(path: fs.PathLike, options: {
377
374
  persistent?: boolean;
@@ -6,6 +6,7 @@ import { R_OK } from './constants.js';
6
6
  import * as promises from './promises.js';
7
7
  import { fd2file } from './shared.js';
8
8
  import { ReadStream, WriteStream } from './streams.js';
9
+ import { FSWatcher } from './watchers.js';
9
10
  /**
10
11
  * Asynchronous rename. No arguments other than a possible exception are given
11
12
  * to the completion callback.
@@ -442,8 +443,11 @@ export function unwatchFile(path, listener = nop) {
442
443
  throw ErrnoError.With('ENOSYS', path.toString(), 'unwatchFile');
443
444
  }
444
445
  unwatchFile;
445
- export function watch(path, options, listener = nop) {
446
- throw ErrnoError.With('ENOSYS', path.toString(), 'watch');
446
+ export function watch(path, options, listener) {
447
+ const watcher = new FSWatcher(typeof options == 'object' ? options : {});
448
+ listener = typeof options == 'function' ? options : listener;
449
+ watcher.on('change', listener || nop);
450
+ return watcher;
447
451
  }
448
452
  watch;
449
453
  /**
@@ -24,6 +24,10 @@ export declare class Dir implements _Dir {
24
24
  protected closed: boolean;
25
25
  protected checkClosed(): void;
26
26
  protected _entries: Dirent[];
27
+ /**
28
+ * @internal
29
+ */
30
+ _loadEntries(): Promise<void>;
27
31
  constructor(path: string);
28
32
  /**
29
33
  * Asynchronously close the directory's underlying resource handle.
@@ -44,6 +44,12 @@ export class Dir {
44
44
  throw new ErrnoError(Errno.EBADF, 'Can not use closed Dir');
45
45
  }
46
46
  }
47
+ /**
48
+ * @internal
49
+ */
50
+ async _loadEntries() {
51
+ this._entries ?? (this._entries = await readdir(this.path, { withFileTypes: true }));
52
+ }
47
53
  constructor(path) {
48
54
  this.path = path;
49
55
  this.closed = false;
@@ -64,9 +70,7 @@ export class Dir {
64
70
  this.closed = true;
65
71
  }
66
72
  async _read() {
67
- if (!this._entries) {
68
- this._entries = await readdir(this.path, { withFileTypes: true });
69
- }
73
+ await this._loadEntries();
70
74
  if (!this._entries.length) {
71
75
  return null;
72
76
  }
@@ -84,9 +88,7 @@ export class Dir {
84
88
  * Directory entries returned by this function are in no particular order as provided by the operating system's underlying directory mechanisms.
85
89
  */
86
90
  readSync() {
87
- if (!this._entries) {
88
- this._entries = readdirSync(this.path, { withFileTypes: true });
89
- }
91
+ this._entries ?? (this._entries = readdirSync(this.path, { withFileTypes: true }));
90
92
  if (!this._entries.length) {
91
93
  return null;
92
94
  }
@@ -379,9 +379,6 @@ export declare function lutimes(path: fs.PathLike, atime: fs.TimeLike, mtime: fs
379
379
  */
380
380
  export declare function realpath(path: fs.PathLike, options: fs.BufferEncodingOption): Promise<Buffer>;
381
381
  export declare function realpath(path: fs.PathLike, options?: fs.EncodingOption | BufferEncoding): Promise<string>;
382
- /**
383
- * @todo Implement
384
- */
385
382
  export declare function watch(filename: fs.PathLike, options?: fs.WatchOptions | BufferEncoding): AsyncIterable<FileChangeInfo<string>>;
386
383
  export declare function watch(filename: fs.PathLike, options: fs.WatchOptions | fs.BufferEncodingOption): AsyncIterable<FileChangeInfo<Buffer>>;
387
384
  export declare function watch(filename: fs.PathLike, options?: fs.WatchOptions | string): AsyncIterable<FileChangeInfo<string>> | AsyncIterable<FileChangeInfo<Buffer>>;
@@ -417,6 +414,7 @@ export declare function copyFile(src: fs.PathLike, dest: fs.PathLike, mode?: num
417
414
  * @param path The path to the directory.
418
415
  * @param options Options for opening the directory.
419
416
  * @returns A `Dir` object representing the opened directory.
417
+ * @todo Use options
420
418
  */
421
419
  export declare function opendir(path: fs.PathLike, options?: fs.OpenDirOptions): Promise<Dir>;
422
420
  /**
@@ -43,6 +43,7 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
43
43
  var e = new Error(message);
44
44
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
45
45
  });
46
+ /* eslint-disable @typescript-eslint/no-redundant-type-constituents */
46
47
  import { Buffer } from 'buffer';
47
48
  import { Errno, ErrnoError } from '../error.js';
48
49
  import { isAppendable, isExclusive, isReadable, isTruncating, isWriteable, parseFlag } from '../file.js';
@@ -54,6 +55,7 @@ import { Dir, Dirent } from './dir.js';
54
55
  import { dirname, join, parse } from './path.js';
55
56
  import { _statfs, cred, fd2file, fdMap, file2fd, fixError, mounts, resolveMount } from './shared.js';
56
57
  import { ReadStream, WriteStream } from './streams.js';
58
+ import { FSWatcher } from './watchers.js';
57
59
  export * as constants from './constants.js';
58
60
  export class FileHandle {
59
61
  constructor(fdOrFile) {
@@ -850,7 +852,25 @@ export async function realpath(path, options) {
850
852
  }
851
853
  realpath;
852
854
  export function watch(filename, options = {}) {
853
- throw ErrnoError.With('ENOSYS', filename.toString(), 'watch');
855
+ return {
856
+ [Symbol.asyncIterator]() {
857
+ const watcher = new FSWatcher(typeof options != 'string' ? options : { encoding: options });
858
+ function withDone(done) {
859
+ return function () {
860
+ const event = Promise.withResolvers();
861
+ watcher.on('change', (eventType, filename) => {
862
+ event.resolve({ value: { eventType, filename }, done });
863
+ });
864
+ return event.promise;
865
+ };
866
+ }
867
+ return {
868
+ next: withDone(false),
869
+ return: withDone(true),
870
+ throw: withDone(true),
871
+ };
872
+ },
873
+ };
854
874
  }
855
875
  watch;
856
876
  /**
@@ -923,10 +943,13 @@ copyFile;
923
943
  * @param path The path to the directory.
924
944
  * @param options Options for opening the directory.
925
945
  * @returns A `Dir` object representing the opened directory.
946
+ * @todo Use options
926
947
  */
927
948
  export async function opendir(path, options) {
928
949
  path = normalizePath(path);
929
- return new Dir(path);
950
+ const dir = new Dir(path);
951
+ await dir._loadEntries();
952
+ return dir;
930
953
  }
931
954
  opendir;
932
955
  /**
@@ -223,7 +223,6 @@ function _readFileSync(fname, flag, resolveSymlinks) {
223
223
  // Allocate buffer.
224
224
  const data = new Uint8Array(stat.size);
225
225
  file.readSync(data, 0, stat.size, 0);
226
- file.closeSync();
227
226
  return data;
228
227
  }
229
228
  catch (e_2) {
@@ -5,8 +5,8 @@ import { EventEmitter } from 'eventemitter3';
5
5
  import type { EventEmitter as NodeEventEmitter } from 'node:events';
6
6
  import type * as fs from 'node:fs';
7
7
  declare class Watcher<TEvents extends Record<string, unknown[]> = Record<string, unknown[]>> extends EventEmitter<TEvents> implements NodeEventEmitter {
8
- off<T extends EventEmitter.EventNames<TEvents>>(event: T, fn?: ((...args: any[]) => void) | undefined, context?: any, once?: boolean | undefined): this;
9
- removeListener<T extends EventEmitter.EventNames<TEvents>>(event: T, fn?: ((...args: any[]) => void) | undefined, context?: any, once?: boolean | undefined): this;
8
+ off<T extends EventEmitter.EventNames<TEvents>>(event: T, fn?: (...args: any[]) => void, context?: any, once?: boolean): this;
9
+ removeListener<T extends EventEmitter.EventNames<TEvents>>(event: T, fn?: (...args: any[]) => void, context?: any, once?: boolean): this;
10
10
  setMaxListeners(): never;
11
11
  getMaxListeners(): never;
12
12
  prependListener(): never;
@@ -15,11 +15,16 @@ declare class Watcher<TEvents extends Record<string, unknown[]> = Record<string,
15
15
  ref(): this;
16
16
  unref(): this;
17
17
  }
18
- export declare class FSWatcher extends Watcher<{
19
- change: [eventType: string, filename: string | Buffer];
18
+ /**
19
+ * @todo Actually emit events
20
+ */
21
+ export declare class FSWatcher<T extends string | Buffer = string | Buffer> extends Watcher<{
22
+ change: [eventType: fs.WatchEventType, filename: T];
20
23
  close: [];
21
24
  error: [error: Error];
22
25
  }> implements fs.FSWatcher {
26
+ readonly options: fs.WatchOptions;
27
+ constructor(options: fs.WatchOptions);
23
28
  close(): void;
24
29
  }
25
30
  export declare class StatWatcher extends Watcher implements fs.StatWatcher {
@@ -31,7 +31,14 @@ class Watcher extends EventEmitter {
31
31
  return this;
32
32
  }
33
33
  }
34
+ /**
35
+ * @todo Actually emit events
36
+ */
34
37
  export class FSWatcher extends Watcher {
38
+ constructor(options) {
39
+ super();
40
+ this.options = options;
41
+ }
35
42
  close() { }
36
43
  }
37
44
  export class StatWatcher extends Watcher {
package/dist/file.d.ts CHANGED
@@ -179,7 +179,6 @@ export declare abstract class File {
179
179
  * An implementation of the File interface that operates on a file that is
180
180
  * completely in-memory. PreloadFiles are backed by a Uint8Array.
181
181
  *
182
- * @todo 'close' lever that disables functionality once closed.
183
182
  */
184
183
  export declare class PreloadFile<FS extends FileSystem> extends File {
185
184
  /**
@@ -193,8 +192,18 @@ export declare class PreloadFile<FS extends FileSystem> extends File {
193
192
  readonly flag: string;
194
193
  readonly stats: Stats;
195
194
  protected _buffer: Uint8Array;
195
+ /**
196
+ * Current position
197
+ */
196
198
  protected _position: number;
199
+ /**
200
+ * Whether the file has changes which have not been written to the FS
201
+ */
197
202
  protected dirty: boolean;
203
+ /**
204
+ * Whether the file is open or closed
205
+ */
206
+ protected closed: boolean;
198
207
  /**
199
208
  * Creates a file with the given path and, optionally, the given contents. Note
200
209
  * that, if contents is specified, it will be mutated by the file!
@@ -239,6 +248,11 @@ export declare class PreloadFile<FS extends FileSystem> extends File {
239
248
  syncSync(): void;
240
249
  close(): Promise<void>;
241
250
  closeSync(): void;
251
+ /**
252
+ * Cleans up
253
+ * This will *not* sync the file data to the FS
254
+ */
255
+ protected dispose(force?: boolean): void;
242
256
  /**
243
257
  * Asynchronous `stat`.
244
258
  */
@@ -340,6 +354,8 @@ export declare class PreloadFile<FS extends FileSystem> extends File {
340
354
  utimesSync(atime: Date, mtime: Date): void;
341
355
  _setType(type: FileType): Promise<void>;
342
356
  _setTypeSync(type: FileType): void;
357
+ [Symbol.asyncDispose](): Promise<void>;
358
+ [Symbol.dispose](): void;
343
359
  }
344
360
  /**
345
361
  * For the filesystems which do not sync to anything..
package/dist/file.js CHANGED
@@ -132,7 +132,6 @@ export class File {
132
132
  * An implementation of the File interface that operates on a file that is
133
133
  * completely in-memory. PreloadFiles are backed by a Uint8Array.
134
134
  *
135
- * @todo 'close' lever that disables functionality once closed.
136
135
  */
137
136
  export class PreloadFile extends File {
138
137
  /**
@@ -162,8 +161,18 @@ export class PreloadFile extends File {
162
161
  this.flag = flag;
163
162
  this.stats = stats;
164
163
  this._buffer = _buffer;
164
+ /**
165
+ * Current position
166
+ */
165
167
  this._position = 0;
168
+ /**
169
+ * Whether the file has changes which have not been written to the FS
170
+ */
166
171
  this.dirty = false;
172
+ /**
173
+ * Whether the file is open or closed
174
+ */
175
+ this.closed = false;
167
176
  /*
168
177
  Note:
169
178
  This invariant is *not* maintained once the file starts getting modified.
@@ -206,6 +215,9 @@ export class PreloadFile extends File {
206
215
  this._position = newPos;
207
216
  }
208
217
  async sync() {
218
+ if (this.closed) {
219
+ throw ErrnoError.With('EBADF', this.path, 'File.sync');
220
+ }
209
221
  if (!this.dirty) {
210
222
  return;
211
223
  }
@@ -213,6 +225,9 @@ export class PreloadFile extends File {
213
225
  this.dirty = false;
214
226
  }
215
227
  syncSync() {
228
+ if (this.closed) {
229
+ throw ErrnoError.With('EBADF', this.path, 'File.sync');
230
+ }
216
231
  if (!this.dirty) {
217
232
  return;
218
233
  }
@@ -220,24 +235,58 @@ export class PreloadFile extends File {
220
235
  this.dirty = false;
221
236
  }
222
237
  async close() {
238
+ if (this.closed) {
239
+ throw ErrnoError.With('EBADF', this.path, 'File.close');
240
+ }
223
241
  await this.sync();
242
+ this.dispose();
224
243
  }
225
244
  closeSync() {
245
+ if (this.closed) {
246
+ throw ErrnoError.With('EBADF', this.path, 'File.close');
247
+ }
226
248
  this.syncSync();
249
+ this.dispose();
250
+ }
251
+ /**
252
+ * Cleans up
253
+ * This will *not* sync the file data to the FS
254
+ */
255
+ dispose(force) {
256
+ if (this.closed) {
257
+ throw ErrnoError.With('EBADF', this.path, 'File.dispose');
258
+ }
259
+ if (this.dirty && !force) {
260
+ throw ErrnoError.With('EBUSY', this.path, 'File.dispose');
261
+ }
262
+ // @ts-expect-error 2790
263
+ delete this._buffer;
264
+ // @ts-expect-error 2790
265
+ delete this.stats;
266
+ this.closed = true;
227
267
  }
228
268
  /**
229
269
  * Asynchronous `stat`.
230
270
  */
231
271
  stat() {
272
+ if (this.closed) {
273
+ throw ErrnoError.With('EBADF', this.path, 'File.stat');
274
+ }
232
275
  return Promise.resolve(new Stats(this.stats));
233
276
  }
234
277
  /**
235
278
  * Synchronous `stat`.
236
279
  */
237
280
  statSync() {
281
+ if (this.closed) {
282
+ throw ErrnoError.With('EBADF', this.path, 'File.stat');
283
+ }
238
284
  return new Stats(this.stats);
239
285
  }
240
286
  _truncate(length) {
287
+ if (this.closed) {
288
+ throw ErrnoError.With('EBADF', this.path, 'File.truncate');
289
+ }
241
290
  this.dirty = true;
242
291
  if (!isWriteable(this.flag)) {
243
292
  throw new ErrnoError(Errno.EPERM, 'File not opened with a writeable mode.');
@@ -270,6 +319,9 @@ export class PreloadFile extends File {
270
319
  this.syncSync();
271
320
  }
272
321
  _write(buffer, offset = 0, length = this.stats.size, position = this.position) {
322
+ if (this.closed) {
323
+ throw ErrnoError.With('EBADF', this.path, 'File.write');
324
+ }
273
325
  this.dirty = true;
274
326
  if (!isWriteable(this.flag)) {
275
327
  throw new ErrnoError(Errno.EPERM, 'File not opened with a writeable mode.');
@@ -331,6 +383,9 @@ export class PreloadFile extends File {
331
383
  return bytesWritten;
332
384
  }
333
385
  _read(buffer, offset = 0, length = this.stats.size, position) {
386
+ if (this.closed) {
387
+ throw ErrnoError.With('EBADF', this.path, 'File.read');
388
+ }
334
389
  if (!isReadable(this.flag)) {
335
390
  throw new ErrnoError(Errno.EPERM, 'File not opened with a readable mode.');
336
391
  }
@@ -387,6 +442,9 @@ export class PreloadFile extends File {
387
442
  * @param mode the mode
388
443
  */
389
444
  async chmod(mode) {
445
+ if (this.closed) {
446
+ throw ErrnoError.With('EBADF', this.path, 'File.chmod');
447
+ }
390
448
  this.dirty = true;
391
449
  this.stats.chmod(mode);
392
450
  await this.sync();
@@ -396,6 +454,9 @@ export class PreloadFile extends File {
396
454
  * @param mode
397
455
  */
398
456
  chmodSync(mode) {
457
+ if (this.closed) {
458
+ throw ErrnoError.With('EBADF', this.path, 'File.chmod');
459
+ }
399
460
  this.dirty = true;
400
461
  this.stats.chmod(mode);
401
462
  this.syncSync();
@@ -406,6 +467,9 @@ export class PreloadFile extends File {
406
467
  * @param gid
407
468
  */
408
469
  async chown(uid, gid) {
470
+ if (this.closed) {
471
+ throw ErrnoError.With('EBADF', this.path, 'File.chown');
472
+ }
409
473
  this.dirty = true;
410
474
  this.stats.chown(uid, gid);
411
475
  await this.sync();
@@ -416,32 +480,53 @@ export class PreloadFile extends File {
416
480
  * @param gid
417
481
  */
418
482
  chownSync(uid, gid) {
483
+ if (this.closed) {
484
+ throw ErrnoError.With('EBADF', this.path, 'File.chown');
485
+ }
419
486
  this.dirty = true;
420
487
  this.stats.chown(uid, gid);
421
488
  this.syncSync();
422
489
  }
423
490
  async utimes(atime, mtime) {
491
+ if (this.closed) {
492
+ throw ErrnoError.With('EBADF', this.path, 'File.utimes');
493
+ }
424
494
  this.dirty = true;
425
495
  this.stats.atime = atime;
426
496
  this.stats.mtime = mtime;
427
497
  await this.sync();
428
498
  }
429
499
  utimesSync(atime, mtime) {
500
+ if (this.closed) {
501
+ throw ErrnoError.With('EBADF', this.path, 'File.utimes');
502
+ }
430
503
  this.dirty = true;
431
504
  this.stats.atime = atime;
432
505
  this.stats.mtime = mtime;
433
506
  this.syncSync();
434
507
  }
435
508
  async _setType(type) {
509
+ if (this.closed) {
510
+ throw ErrnoError.With('EBADF', this.path, 'File._setType');
511
+ }
436
512
  this.dirty = true;
437
513
  this.stats.mode = (this.stats.mode & ~S_IFMT) | type;
438
514
  await this.sync();
439
515
  }
440
516
  _setTypeSync(type) {
517
+ if (this.closed) {
518
+ throw ErrnoError.With('EBADF', this.path, 'File._setType');
519
+ }
441
520
  this.dirty = true;
442
521
  this.stats.mode = (this.stats.mode & ~S_IFMT) | type;
443
522
  this.syncSync();
444
523
  }
524
+ async [Symbol.asyncDispose]() {
525
+ await this.close();
526
+ }
527
+ [Symbol.dispose]() {
528
+ this.closeSync();
529
+ }
445
530
  }
446
531
  /**
447
532
  * For the filesystems which do not sync to anything..
@@ -1,4 +1,3 @@
1
- import type { ExtractProperties } from 'utilium';
2
1
  import { type Cred } from './cred.js';
3
2
  import { type File } from './file.js';
4
3
  import { type Stats } from './stats.js';
@@ -169,65 +168,3 @@ export declare abstract class FileSystem {
169
168
  */
170
169
  abstract syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void;
171
170
  }
172
- /**
173
- * `TBase` with `TMixin` mixed-in.
174
- * @internal @experimental
175
- */
176
- export type Mixin<TBase extends typeof FileSystem, TMixin> = (abstract new (...args: any[]) => TMixin) & TBase;
177
- /**
178
- * Asynchronous `FileSystem` methods. This is a convience type.
179
- * @internal
180
- */
181
- export type _AsyncFSMethods = ExtractProperties<FileSystem, (...args: any[]) => Promise<unknown>>;
182
- /**
183
- * Implements the asynchronous API in terms of the synchronous API.
184
- */
185
- export declare function Sync<T extends typeof FileSystem>(FS: T): Mixin<T, _AsyncFSMethods>;
186
- /**
187
- * Async() implements synchronous methods on an asynchronous file system
188
- *
189
- * Implementing classes must define `_sync` for the synchronous file system used as a cache.
190
- * Synchronous methods on an asynchronous FS are implemented by:
191
- * - Performing operations over the in-memory copy,
192
- * while asynchronously pipelining them to the backing store.
193
- * - During loading, the contents of the async file system are preloaded into the synchronous store.
194
- *
195
- */
196
- export declare function Async<T extends typeof FileSystem>(FS: T): Mixin<T, {
197
- /**
198
- * @internal @protected
199
- */
200
- _sync?: FileSystem;
201
- queueDone(): Promise<void>;
202
- ready(): Promise<void>;
203
- renameSync(oldPath: string, newPath: string, cred: Cred): void;
204
- statSync(path: string, cred: Cred): Stats;
205
- createFileSync(path: string, flag: string, mode: number, cred: Cred): File;
206
- openFileSync(path: string, flag: string, cred: Cred): File;
207
- unlinkSync(path: string, cred: Cred): void;
208
- rmdirSync(path: string, cred: Cred): void;
209
- mkdirSync(path: string, mode: number, cred: Cred): void;
210
- readdirSync(path: string, cred: Cred): string[];
211
- linkSync(srcpath: string, dstpath: string, cred: Cred): void;
212
- syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void;
213
- }>;
214
- /**
215
- * Implements the non-readonly methods to throw `EROFS`
216
- */
217
- export declare function Readonly<T extends typeof FileSystem>(FS: T): Mixin<T, {
218
- metadata(): FileSystemMetadata;
219
- rename(oldPath: string, newPath: string, cred: Cred): Promise<void>;
220
- renameSync(oldPath: string, newPath: string, cred: Cred): void;
221
- createFile(path: string, flag: string, mode: number, cred: Cred): Promise<File>;
222
- createFileSync(path: string, flag: string, mode: number, cred: Cred): File;
223
- unlink(path: string, cred: Cred): Promise<void>;
224
- unlinkSync(path: string, cred: Cred): void;
225
- rmdir(path: string, cred: Cred): Promise<void>;
226
- rmdirSync(path: string, cred: Cred): void;
227
- mkdir(path: string, mode: number, cred: Cred): Promise<void>;
228
- mkdirSync(path: string, mode: number, cred: Cred): void;
229
- link(srcpath: string, dstpath: string, cred: Cred): Promise<void>;
230
- linkSync(srcpath: string, dstpath: string, cred: Cred): void;
231
- sync(path: string, data: Uint8Array, stats: Readonly<Stats>): Promise<void>;
232
- syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void;
233
- }>;