@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.
- package/dist/backends/backend.d.ts +3 -4
- package/dist/backends/fetch.d.ts +8 -3
- package/dist/backends/fetch.js +3 -2
- package/dist/backends/{index/fs.d.ts → file_index.d.ts} +49 -10
- package/dist/backends/{index/fs.js → file_index.js} +84 -5
- package/dist/backends/memory.d.ts +6 -1
- package/dist/backends/memory.js +2 -1
- package/dist/backends/overlay.d.ts +16 -16
- package/dist/backends/overlay.js +59 -82
- package/dist/backends/port/fs.d.ts +6 -2
- package/dist/backends/port/fs.js +4 -2
- package/dist/backends/store/fs.js +484 -304
- package/dist/backends/store/simple.js +5 -1
- package/dist/backends/store/store.d.ts +4 -1
- package/dist/backends/store/store.js +9 -5
- package/dist/browser.min.js +4 -4
- package/dist/browser.min.js.map +4 -4
- package/dist/config.d.ts +3 -3
- package/dist/emulation/async.d.ts +0 -3
- package/dist/emulation/async.js +6 -2
- package/dist/emulation/dir.d.ts +4 -0
- package/dist/emulation/dir.js +8 -6
- package/dist/emulation/promises.d.ts +1 -3
- package/dist/emulation/promises.js +25 -2
- package/dist/emulation/sync.js +0 -1
- package/dist/emulation/watchers.d.ts +9 -4
- package/dist/emulation/watchers.js +7 -0
- package/dist/file.d.ts +17 -1
- package/dist/file.js +86 -1
- package/dist/filesystem.d.ts +0 -63
- package/dist/filesystem.js +0 -311
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -2
- package/dist/mixins/async.d.ts +39 -0
- package/dist/mixins/async.js +216 -0
- package/dist/mixins/mutexed.d.ts +33 -0
- package/dist/mixins/mutexed.js +465 -0
- package/dist/mixins/readonly.d.ts +25 -0
- package/dist/mixins/readonly.js +57 -0
- package/dist/mixins/shared.d.ts +12 -0
- package/dist/mixins/shared.js +4 -0
- package/dist/mixins/sync.d.ts +6 -0
- package/dist/mixins/sync.js +43 -0
- package/package.json +1 -1
- package/src/backends/backend.ts +3 -4
- package/src/backends/fetch.ts +7 -3
- package/src/backends/{index/fs.ts → file_index.ts} +106 -8
- package/src/backends/memory.ts +5 -1
- package/src/backends/overlay.ts +64 -90
- package/src/backends/port/fs.ts +7 -2
- package/src/backends/{index/readme.md → readme.md} +1 -1
- package/src/backends/store/fs.ts +97 -155
- package/src/backends/store/simple.ts +5 -1
- package/src/backends/store/store.ts +10 -5
- package/src/config.ts +3 -1
- package/src/emulation/async.ts +15 -6
- package/src/emulation/dir.ts +19 -16
- package/src/emulation/promises.ts +28 -6
- package/src/emulation/sync.ts +1 -2
- package/src/emulation/watchers.ts +10 -4
- package/src/file.ts +94 -1
- package/src/filesystem.ts +3 -366
- package/src/index.ts +1 -2
- package/src/mixins/async.ts +211 -0
- package/src/mixins/mutexed.ts +245 -0
- package/src/mixins/readonly.ts +97 -0
- package/src/mixins/shared.ts +20 -0
- package/src/mixins/sync.ts +59 -0
- package/dist/backends/index/index.d.ts +0 -43
- package/dist/backends/index/index.js +0 -83
- package/dist/backends/locked.d.ts +0 -92
- package/dist/backends/locked.js +0 -487
- package/src/backends/index/index.ts +0 -104
- 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
|
|
13
|
-
[K
|
|
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;
|
package/dist/emulation/async.js
CHANGED
|
@@ -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
|
|
446
|
-
|
|
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
|
/**
|
package/dist/emulation/dir.d.ts
CHANGED
|
@@ -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.
|
package/dist/emulation/dir.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
950
|
+
const dir = new Dir(path);
|
|
951
|
+
await dir._loadEntries();
|
|
952
|
+
return dir;
|
|
930
953
|
}
|
|
931
954
|
opendir;
|
|
932
955
|
/**
|
package/dist/emulation/sync.js
CHANGED
|
@@ -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?: (
|
|
9
|
-
removeListener<T extends EventEmitter.EventNames<TEvents>>(event: T, fn?: (
|
|
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
|
-
|
|
19
|
-
|
|
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..
|
package/dist/filesystem.d.ts
CHANGED
|
@@ -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
|
-
}>;
|