@zenfs/core 0.18.0 → 1.0.0-rc.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/overlay.d.ts +3 -5
- package/dist/backends/overlay.js +9 -9
- package/dist/backends/port/fs.d.ts +1 -2
- package/dist/backends/port/fs.js +2 -3
- package/dist/browser.min.js +4 -4
- package/dist/browser.min.js.map +3 -3
- package/dist/emulation/promises.js +14 -15
- package/dist/emulation/sync.js +13 -14
- package/dist/file.d.ts +22 -13
- package/dist/file.js +16 -7
- package/dist/mixins/mutexed.d.ts +72 -10
- package/dist/mixins/mutexed.js +375 -379
- package/dist/mixins/shared.d.ts +1 -0
- package/dist/mixins/shared.js +1 -0
- package/dist/stats.d.ts +2 -3
- package/dist/stats.js +4 -4
- package/dist/utils.d.ts +2 -1
- package/package.json +1 -1
- package/readme.md +1 -1
- package/src/backends/overlay.ts +9 -11
- package/src/backends/port/fs.ts +4 -4
- package/src/emulation/promises.ts +14 -15
- package/src/emulation/sync.ts +13 -14
- package/src/file.ts +16 -11
- package/src/mixins/mutexed.ts +194 -189
- package/src/mixins/shared.ts +3 -2
- package/src/stats.ts +4 -5
- package/src/utils.ts +3 -1
|
@@ -54,7 +54,6 @@ import * as constants from './constants.js';
|
|
|
54
54
|
import { Dir, Dirent } from './dir.js';
|
|
55
55
|
import { dirname, join, parse } from './path.js';
|
|
56
56
|
import { _statfs, fd2file, fdMap, file2fd, fixError, mounts, resolveMount } from './shared.js';
|
|
57
|
-
import { credentials } from '../credentials.js';
|
|
58
57
|
import { ReadStream, WriteStream } from './streams.js';
|
|
59
58
|
import { FSWatcher, emitChange } from './watchers.js';
|
|
60
59
|
export * as constants from './constants.js';
|
|
@@ -213,7 +212,7 @@ export class FileHandle {
|
|
|
213
212
|
}
|
|
214
213
|
async stat(opts) {
|
|
215
214
|
const stats = await this.file.stat();
|
|
216
|
-
if (!stats.hasAccess(constants.R_OK
|
|
215
|
+
if (!stats.hasAccess(constants.R_OK)) {
|
|
217
216
|
throw ErrnoError.With('EACCES', this.file.path, 'stat');
|
|
218
217
|
}
|
|
219
218
|
return opts?.bigint ? new BigIntStats(stats) : stats;
|
|
@@ -357,7 +356,7 @@ export async function rename(oldPath, newPath) {
|
|
|
357
356
|
newPath = normalizePath(newPath);
|
|
358
357
|
const src = resolveMount(oldPath);
|
|
359
358
|
const dst = resolveMount(newPath);
|
|
360
|
-
if (!(await stat(dirname(oldPath))).hasAccess(constants.W_OK
|
|
359
|
+
if (!(await stat(dirname(oldPath))).hasAccess(constants.W_OK)) {
|
|
361
360
|
throw ErrnoError.With('EACCES', oldPath, 'rename');
|
|
362
361
|
}
|
|
363
362
|
try {
|
|
@@ -396,7 +395,7 @@ export async function stat(path, options) {
|
|
|
396
395
|
const { fs, path: resolved } = resolveMount((await exists(path)) ? await realpath(path) : path);
|
|
397
396
|
try {
|
|
398
397
|
const stats = await fs.stat(resolved);
|
|
399
|
-
if (!stats.hasAccess(constants.R_OK
|
|
398
|
+
if (!stats.hasAccess(constants.R_OK)) {
|
|
400
399
|
throw ErrnoError.With('EACCES', path, 'stat');
|
|
401
400
|
}
|
|
402
401
|
return options?.bigint ? new BigIntStats(stats) : stats;
|
|
@@ -449,7 +448,7 @@ export async function unlink(path) {
|
|
|
449
448
|
path = normalizePath(path);
|
|
450
449
|
const { fs, path: resolved } = resolveMount(path);
|
|
451
450
|
try {
|
|
452
|
-
if (!(await fs.stat(resolved)).hasAccess(constants.W_OK
|
|
451
|
+
if (!(await fs.stat(resolved)).hasAccess(constants.W_OK)) {
|
|
453
452
|
throw ErrnoError.With('EACCES', resolved, 'unlink');
|
|
454
453
|
}
|
|
455
454
|
await fs.unlink(resolved);
|
|
@@ -476,7 +475,7 @@ async function _open(path, _flag, _mode = 0o644, resolveSymlinks) {
|
|
|
476
475
|
}
|
|
477
476
|
// Create the file
|
|
478
477
|
const parentStats = await fs.stat(dirname(resolved));
|
|
479
|
-
if (!parentStats.hasAccess(constants.W_OK
|
|
478
|
+
if (!parentStats.hasAccess(constants.W_OK)) {
|
|
480
479
|
throw ErrnoError.With('EACCES', dirname(path), '_open');
|
|
481
480
|
}
|
|
482
481
|
if (!parentStats.isDirectory()) {
|
|
@@ -484,7 +483,7 @@ async function _open(path, _flag, _mode = 0o644, resolveSymlinks) {
|
|
|
484
483
|
}
|
|
485
484
|
return new FileHandle(await fs.createFile(resolved, flag, mode));
|
|
486
485
|
}
|
|
487
|
-
if (!stats.hasAccess(flagToMode(flag)
|
|
486
|
+
if (!stats.hasAccess(flagToMode(flag))) {
|
|
488
487
|
throw ErrnoError.With('EACCES', path, '_open');
|
|
489
488
|
}
|
|
490
489
|
if (isExclusive(flag)) {
|
|
@@ -610,7 +609,7 @@ export async function rmdir(path) {
|
|
|
610
609
|
path = (await exists(path)) ? await realpath(path) : path;
|
|
611
610
|
const { fs, path: resolved } = resolveMount(path);
|
|
612
611
|
try {
|
|
613
|
-
if (!(await fs.stat(resolved)).hasAccess(constants.W_OK
|
|
612
|
+
if (!(await fs.stat(resolved)).hasAccess(constants.W_OK)) {
|
|
614
613
|
throw ErrnoError.With('EACCES', resolved, 'rmdir');
|
|
615
614
|
}
|
|
616
615
|
await fs.rmdir(resolved);
|
|
@@ -630,7 +629,7 @@ export async function mkdir(path, options) {
|
|
|
630
629
|
const errorPaths = { [resolved]: path };
|
|
631
630
|
try {
|
|
632
631
|
if (!options?.recursive) {
|
|
633
|
-
if (!(await fs.stat(dirname(resolved))).hasAccess(constants.W_OK
|
|
632
|
+
if (!(await fs.stat(dirname(resolved))).hasAccess(constants.W_OK)) {
|
|
634
633
|
throw ErrnoError.With('EACCES', dirname(resolved), 'mkdir');
|
|
635
634
|
}
|
|
636
635
|
await fs.mkdir(resolved, mode);
|
|
@@ -643,7 +642,7 @@ export async function mkdir(path, options) {
|
|
|
643
642
|
errorPaths[dir] = origDir;
|
|
644
643
|
}
|
|
645
644
|
for (const dir of dirs) {
|
|
646
|
-
if (!(await fs.stat(dirname(dir))).hasAccess(constants.W_OK
|
|
645
|
+
if (!(await fs.stat(dirname(dir))).hasAccess(constants.W_OK)) {
|
|
647
646
|
throw ErrnoError.With('EACCES', dirname(dir), 'mkdir');
|
|
648
647
|
}
|
|
649
648
|
await fs.mkdir(dir, mode);
|
|
@@ -658,7 +657,7 @@ export async function mkdir(path, options) {
|
|
|
658
657
|
mkdir;
|
|
659
658
|
export async function readdir(path, options) {
|
|
660
659
|
path = normalizePath(path);
|
|
661
|
-
if (!(await stat(path)).hasAccess(constants.R_OK
|
|
660
|
+
if (!(await stat(path)).hasAccess(constants.R_OK)) {
|
|
662
661
|
throw ErrnoError.With('EACCES', path, 'readdir');
|
|
663
662
|
}
|
|
664
663
|
path = (await exists(path)) ? await realpath(path) : path;
|
|
@@ -695,11 +694,11 @@ readdir;
|
|
|
695
694
|
*/
|
|
696
695
|
export async function link(targetPath, linkPath) {
|
|
697
696
|
targetPath = normalizePath(targetPath);
|
|
698
|
-
if (!(await stat(dirname(targetPath))).hasAccess(constants.R_OK
|
|
697
|
+
if (!(await stat(dirname(targetPath))).hasAccess(constants.R_OK)) {
|
|
699
698
|
throw ErrnoError.With('EACCES', dirname(targetPath), 'link');
|
|
700
699
|
}
|
|
701
700
|
linkPath = normalizePath(linkPath);
|
|
702
|
-
if (!(await stat(dirname(linkPath))).hasAccess(constants.W_OK
|
|
701
|
+
if (!(await stat(dirname(linkPath))).hasAccess(constants.W_OK)) {
|
|
703
702
|
throw ErrnoError.With('EACCES', dirname(linkPath), 'link');
|
|
704
703
|
}
|
|
705
704
|
const { fs, path } = resolveMount(targetPath);
|
|
@@ -708,7 +707,7 @@ export async function link(targetPath, linkPath) {
|
|
|
708
707
|
throw ErrnoError.With('EXDEV', linkPath, 'link');
|
|
709
708
|
}
|
|
710
709
|
try {
|
|
711
|
-
if (!(await fs.stat(path)).hasAccess(constants.W_OK
|
|
710
|
+
if (!(await fs.stat(path)).hasAccess(constants.W_OK)) {
|
|
712
711
|
throw ErrnoError.With('EACCES', path, 'link');
|
|
713
712
|
}
|
|
714
713
|
return await fs.link(path, link.path);
|
|
@@ -938,7 +937,7 @@ watch;
|
|
|
938
937
|
*/
|
|
939
938
|
export async function access(path, mode = constants.F_OK) {
|
|
940
939
|
const stats = await stat(path);
|
|
941
|
-
if (!stats.hasAccess(mode
|
|
940
|
+
if (!stats.hasAccess(mode)) {
|
|
942
941
|
throw new ErrnoError(Errno.EACCES);
|
|
943
942
|
}
|
|
944
943
|
}
|
package/dist/emulation/sync.js
CHANGED
|
@@ -52,7 +52,6 @@ import * as constants from './constants.js';
|
|
|
52
52
|
import { Dir, Dirent } from './dir.js';
|
|
53
53
|
import { dirname, join, parse } from './path.js';
|
|
54
54
|
import { _statfs, fd2file, fdMap, file2fd, fixError, mounts, resolveMount } from './shared.js';
|
|
55
|
-
import { credentials } from '../credentials.js';
|
|
56
55
|
import { emitChange } from './watchers.js';
|
|
57
56
|
/**
|
|
58
57
|
* Synchronous rename.
|
|
@@ -64,7 +63,7 @@ export function renameSync(oldPath, newPath) {
|
|
|
64
63
|
newPath = normalizePath(newPath);
|
|
65
64
|
const oldMount = resolveMount(oldPath);
|
|
66
65
|
const newMount = resolveMount(newPath);
|
|
67
|
-
if (!statSync(dirname(oldPath)).hasAccess(constants.W_OK
|
|
66
|
+
if (!statSync(dirname(oldPath)).hasAccess(constants.W_OK)) {
|
|
68
67
|
throw ErrnoError.With('EACCES', oldPath, 'rename');
|
|
69
68
|
}
|
|
70
69
|
try {
|
|
@@ -105,7 +104,7 @@ export function statSync(path, options) {
|
|
|
105
104
|
const { fs, path: resolved } = resolveMount(existsSync(path) ? realpathSync(path) : path);
|
|
106
105
|
try {
|
|
107
106
|
const stats = fs.statSync(resolved);
|
|
108
|
-
if (!stats.hasAccess(constants.R_OK
|
|
107
|
+
if (!stats.hasAccess(constants.R_OK)) {
|
|
109
108
|
throw ErrnoError.With('EACCES', path, 'stat');
|
|
110
109
|
}
|
|
111
110
|
return options?.bigint ? new BigIntStats(stats) : stats;
|
|
@@ -159,7 +158,7 @@ export function unlinkSync(path) {
|
|
|
159
158
|
path = normalizePath(path);
|
|
160
159
|
const { fs, path: resolved } = resolveMount(path);
|
|
161
160
|
try {
|
|
162
|
-
if (!fs.statSync(resolved).hasAccess(constants.W_OK
|
|
161
|
+
if (!fs.statSync(resolved).hasAccess(constants.W_OK)) {
|
|
163
162
|
throw ErrnoError.With('EACCES', resolved, 'unlink');
|
|
164
163
|
}
|
|
165
164
|
fs.unlinkSync(resolved);
|
|
@@ -181,7 +180,7 @@ function _openSync(path, _flag, _mode, resolveSymlinks = true) {
|
|
|
181
180
|
}
|
|
182
181
|
// Create the file
|
|
183
182
|
const parentStats = fs.statSync(dirname(resolved));
|
|
184
|
-
if (!parentStats.hasAccess(constants.W_OK
|
|
183
|
+
if (!parentStats.hasAccess(constants.W_OK)) {
|
|
185
184
|
throw ErrnoError.With('EACCES', dirname(path), '_open');
|
|
186
185
|
}
|
|
187
186
|
if (!parentStats.isDirectory()) {
|
|
@@ -190,7 +189,7 @@ function _openSync(path, _flag, _mode, resolveSymlinks = true) {
|
|
|
190
189
|
return fs.createFileSync(resolved, flag, mode);
|
|
191
190
|
}
|
|
192
191
|
const stats = fs.statSync(resolved);
|
|
193
|
-
if (!stats.hasAccess(mode
|
|
192
|
+
if (!stats.hasAccess(mode) || !stats.hasAccess(flagToMode(flag))) {
|
|
194
193
|
throw ErrnoError.With('EACCES', path, '_open');
|
|
195
194
|
}
|
|
196
195
|
if (isExclusive(flag)) {
|
|
@@ -440,7 +439,7 @@ export function rmdirSync(path) {
|
|
|
440
439
|
path = normalizePath(path);
|
|
441
440
|
const { fs, path: resolved } = resolveMount(existsSync(path) ? realpathSync(path) : path);
|
|
442
441
|
try {
|
|
443
|
-
if (!fs.statSync(resolved).hasAccess(constants.W_OK
|
|
442
|
+
if (!fs.statSync(resolved).hasAccess(constants.W_OK)) {
|
|
444
443
|
throw ErrnoError.With('EACCES', resolved, 'rmdir');
|
|
445
444
|
}
|
|
446
445
|
fs.rmdirSync(resolved);
|
|
@@ -460,7 +459,7 @@ export function mkdirSync(path, options) {
|
|
|
460
459
|
const errorPaths = { [resolved]: path };
|
|
461
460
|
try {
|
|
462
461
|
if (!options?.recursive) {
|
|
463
|
-
if (!fs.statSync(dirname(resolved)).hasAccess(constants.W_OK
|
|
462
|
+
if (!fs.statSync(dirname(resolved)).hasAccess(constants.W_OK)) {
|
|
464
463
|
throw ErrnoError.With('EACCES', dirname(resolved), 'mkdir');
|
|
465
464
|
}
|
|
466
465
|
return fs.mkdirSync(resolved, mode);
|
|
@@ -471,7 +470,7 @@ export function mkdirSync(path, options) {
|
|
|
471
470
|
errorPaths[dir] = original;
|
|
472
471
|
}
|
|
473
472
|
for (const dir of dirs) {
|
|
474
|
-
if (!fs.statSync(dirname(dir)).hasAccess(constants.W_OK
|
|
473
|
+
if (!fs.statSync(dirname(dir)).hasAccess(constants.W_OK)) {
|
|
475
474
|
throw ErrnoError.With('EACCES', dirname(dir), 'mkdir');
|
|
476
475
|
}
|
|
477
476
|
fs.mkdirSync(dir, mode);
|
|
@@ -488,7 +487,7 @@ export function readdirSync(path, options) {
|
|
|
488
487
|
path = normalizePath(path);
|
|
489
488
|
const { fs, path: resolved } = resolveMount(existsSync(path) ? realpathSync(path) : path);
|
|
490
489
|
let entries;
|
|
491
|
-
if (!statSync(path).hasAccess(constants.R_OK
|
|
490
|
+
if (!statSync(path).hasAccess(constants.R_OK)) {
|
|
492
491
|
throw ErrnoError.With('EACCES', path, 'readdir');
|
|
493
492
|
}
|
|
494
493
|
try {
|
|
@@ -527,11 +526,11 @@ readdirSync;
|
|
|
527
526
|
*/
|
|
528
527
|
export function linkSync(targetPath, linkPath) {
|
|
529
528
|
targetPath = normalizePath(targetPath);
|
|
530
|
-
if (!statSync(dirname(targetPath)).hasAccess(constants.R_OK
|
|
529
|
+
if (!statSync(dirname(targetPath)).hasAccess(constants.R_OK)) {
|
|
531
530
|
throw ErrnoError.With('EACCES', dirname(targetPath), 'link');
|
|
532
531
|
}
|
|
533
532
|
linkPath = normalizePath(linkPath);
|
|
534
|
-
if (!statSync(dirname(linkPath)).hasAccess(constants.W_OK
|
|
533
|
+
if (!statSync(dirname(linkPath)).hasAccess(constants.W_OK)) {
|
|
535
534
|
throw ErrnoError.With('EACCES', dirname(linkPath), 'link');
|
|
536
535
|
}
|
|
537
536
|
const { fs, path } = resolveMount(targetPath);
|
|
@@ -540,7 +539,7 @@ export function linkSync(targetPath, linkPath) {
|
|
|
540
539
|
throw ErrnoError.With('EXDEV', linkPath, 'link');
|
|
541
540
|
}
|
|
542
541
|
try {
|
|
543
|
-
if (!fs.statSync(path).hasAccess(constants.W_OK
|
|
542
|
+
if (!fs.statSync(path).hasAccess(constants.W_OK)) {
|
|
544
543
|
throw ErrnoError.With('EACCES', path, 'link');
|
|
545
544
|
}
|
|
546
545
|
return fs.linkSync(path, linkPath);
|
|
@@ -672,7 +671,7 @@ realpathSync;
|
|
|
672
671
|
*/
|
|
673
672
|
export function accessSync(path, mode = 0o600) {
|
|
674
673
|
const stats = statSync(path);
|
|
675
|
-
if (!stats.hasAccess(mode
|
|
674
|
+
if (!stats.hasAccess(mode)) {
|
|
676
675
|
throw new ErrnoError(Errno.EACCES);
|
|
677
676
|
}
|
|
678
677
|
}
|
package/dist/file.d.ts
CHANGED
|
@@ -37,13 +37,28 @@ export declare function isSynchronous(flag: string): boolean;
|
|
|
37
37
|
export declare function isExclusive(flag: string): boolean;
|
|
38
38
|
export declare abstract class File {
|
|
39
39
|
/**
|
|
40
|
-
*
|
|
40
|
+
* @internal
|
|
41
|
+
* The file system that created the file
|
|
41
42
|
*/
|
|
42
|
-
|
|
43
|
+
fs: FileSystem;
|
|
44
|
+
/**
|
|
45
|
+
* The path to the file
|
|
46
|
+
*/
|
|
47
|
+
readonly path: string;
|
|
48
|
+
constructor(
|
|
49
|
+
/**
|
|
50
|
+
* @internal
|
|
51
|
+
* The file system that created the file
|
|
52
|
+
*/
|
|
53
|
+
fs: FileSystem,
|
|
43
54
|
/**
|
|
44
55
|
* The path to the file
|
|
45
56
|
*/
|
|
46
|
-
|
|
57
|
+
path: string);
|
|
58
|
+
/**
|
|
59
|
+
* Get the current file position.
|
|
60
|
+
*/
|
|
61
|
+
abstract position: number;
|
|
47
62
|
/**
|
|
48
63
|
* Asynchronous `stat`.
|
|
49
64
|
*/
|
|
@@ -183,12 +198,9 @@ export declare abstract class File {
|
|
|
183
198
|
export declare class PreloadFile<FS extends FileSystem> extends File {
|
|
184
199
|
/**
|
|
185
200
|
* The file system that created the file.
|
|
201
|
+
* @internal
|
|
186
202
|
*/
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Path to the file
|
|
190
|
-
*/
|
|
191
|
-
readonly path: string;
|
|
203
|
+
fs: FS;
|
|
192
204
|
readonly flag: string;
|
|
193
205
|
readonly stats: Stats;
|
|
194
206
|
protected _buffer: Uint8Array;
|
|
@@ -219,12 +231,9 @@ export declare class PreloadFile<FS extends FileSystem> extends File {
|
|
|
219
231
|
constructor(
|
|
220
232
|
/**
|
|
221
233
|
* The file system that created the file.
|
|
234
|
+
* @internal
|
|
222
235
|
*/
|
|
223
|
-
fs: FS,
|
|
224
|
-
/**
|
|
225
|
-
* Path to the file
|
|
226
|
-
*/
|
|
227
|
-
path: string, flag: string, stats: Stats, _buffer?: Uint8Array);
|
|
236
|
+
fs: FS, path: string, flag: string, stats: Stats, _buffer?: Uint8Array);
|
|
228
237
|
/**
|
|
229
238
|
* Get the underlying buffer for this file. Mutating not recommended and will mess up dirty tracking.
|
|
230
239
|
*/
|
package/dist/file.js
CHANGED
|
@@ -105,6 +105,19 @@ export function isExclusive(flag) {
|
|
|
105
105
|
return flag.indexOf('x') !== -1;
|
|
106
106
|
}
|
|
107
107
|
export class File {
|
|
108
|
+
constructor(
|
|
109
|
+
/**
|
|
110
|
+
* @internal
|
|
111
|
+
* The file system that created the file
|
|
112
|
+
*/
|
|
113
|
+
fs,
|
|
114
|
+
/**
|
|
115
|
+
* The path to the file
|
|
116
|
+
*/
|
|
117
|
+
path) {
|
|
118
|
+
this.fs = fs;
|
|
119
|
+
this.path = path;
|
|
120
|
+
}
|
|
108
121
|
[Symbol.asyncDispose]() {
|
|
109
122
|
return this.close();
|
|
110
123
|
}
|
|
@@ -149,15 +162,11 @@ export class PreloadFile extends File {
|
|
|
149
162
|
constructor(
|
|
150
163
|
/**
|
|
151
164
|
* The file system that created the file.
|
|
165
|
+
* @internal
|
|
152
166
|
*/
|
|
153
|
-
fs,
|
|
154
|
-
|
|
155
|
-
* Path to the file
|
|
156
|
-
*/
|
|
157
|
-
path, flag, stats, _buffer = new Uint8Array(new ArrayBuffer(0, fs.metadata().noResizableBuffers ? {} : { maxByteLength: size_max }))) {
|
|
158
|
-
super();
|
|
167
|
+
fs, path, flag, stats, _buffer = new Uint8Array(new ArrayBuffer(0, fs.metadata().noResizableBuffers ? {} : { maxByteLength: size_max }))) {
|
|
168
|
+
super(fs, path);
|
|
159
169
|
this.fs = fs;
|
|
160
|
-
this.path = path;
|
|
161
170
|
this.flag = flag;
|
|
162
171
|
this.stats = stats;
|
|
163
172
|
this._buffer = _buffer;
|
package/dist/mixins/mutexed.d.ts
CHANGED
|
@@ -1,17 +1,76 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { File } from '../file.js';
|
|
2
|
+
import type { FileSystem, FileSystemMetadata } from '../filesystem.js';
|
|
2
3
|
import '../polyfills.js';
|
|
3
|
-
import type {
|
|
4
|
+
import type { Stats } from '../stats.js';
|
|
5
|
+
import type { Concrete } from '../utils.js';
|
|
4
6
|
export declare class MutexLock {
|
|
5
|
-
readonly path: string;
|
|
6
7
|
protected readonly previous?: MutexLock | undefined;
|
|
7
8
|
protected current: PromiseWithResolvers<void>;
|
|
8
9
|
protected _isLocked: boolean;
|
|
9
10
|
get isLocked(): boolean;
|
|
10
|
-
constructor(
|
|
11
|
+
constructor(previous?: MutexLock | undefined);
|
|
11
12
|
done(): Promise<void>;
|
|
12
13
|
unlock(): void;
|
|
13
14
|
[Symbol.dispose](): void;
|
|
14
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* @hidden
|
|
18
|
+
*/
|
|
19
|
+
export declare class __MutexedFS<T extends FileSystem> implements FileSystem {
|
|
20
|
+
/**
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
23
|
+
_fs: T;
|
|
24
|
+
ready(): Promise<void>;
|
|
25
|
+
metadata(): FileSystemMetadata;
|
|
26
|
+
/**
|
|
27
|
+
* The current locks
|
|
28
|
+
*/
|
|
29
|
+
private currentLock?;
|
|
30
|
+
/**
|
|
31
|
+
* Adds a lock for a path
|
|
32
|
+
*/
|
|
33
|
+
protected addLock(): MutexLock;
|
|
34
|
+
/**
|
|
35
|
+
* Locks `path` asynchronously.
|
|
36
|
+
* If the path is currently locked, waits for it to be unlocked.
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
39
|
+
lock(path: string, syscall: string): Promise<MutexLock>;
|
|
40
|
+
/**
|
|
41
|
+
* Locks `path` asynchronously.
|
|
42
|
+
* If the path is currently locked, an error will be thrown
|
|
43
|
+
* @internal
|
|
44
|
+
*/
|
|
45
|
+
lockSync(path: string, syscall: string): MutexLock;
|
|
46
|
+
/**
|
|
47
|
+
* Whether `path` is locked
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
50
|
+
get isLocked(): boolean;
|
|
51
|
+
rename(oldPath: string, newPath: string): Promise<void>;
|
|
52
|
+
renameSync(oldPath: string, newPath: string): void;
|
|
53
|
+
stat(path: string): Promise<Stats>;
|
|
54
|
+
statSync(path: string): Stats;
|
|
55
|
+
openFile(path: string, flag: string): Promise<File>;
|
|
56
|
+
openFileSync(path: string, flag: string): File;
|
|
57
|
+
createFile(path: string, flag: string, mode: number): Promise<File>;
|
|
58
|
+
createFileSync(path: string, flag: string, mode: number): File;
|
|
59
|
+
unlink(path: string): Promise<void>;
|
|
60
|
+
unlinkSync(path: string): void;
|
|
61
|
+
rmdir(path: string): Promise<void>;
|
|
62
|
+
rmdirSync(path: string): void;
|
|
63
|
+
mkdir(path: string, mode: number): Promise<void>;
|
|
64
|
+
mkdirSync(path: string, mode: number): void;
|
|
65
|
+
readdir(path: string): Promise<string[]>;
|
|
66
|
+
readdirSync(path: string): string[];
|
|
67
|
+
exists(path: string): Promise<boolean>;
|
|
68
|
+
existsSync(path: string): boolean;
|
|
69
|
+
link(srcpath: string, dstpath: string): Promise<void>;
|
|
70
|
+
linkSync(srcpath: string, dstpath: string): void;
|
|
71
|
+
sync(path: string, data: Uint8Array, stats: Readonly<Stats>): Promise<void>;
|
|
72
|
+
syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void;
|
|
73
|
+
}
|
|
15
74
|
/**
|
|
16
75
|
* This serializes access to an underlying async filesystem.
|
|
17
76
|
* For example, on an OverlayFS instance with an async lower
|
|
@@ -21,13 +80,16 @@ export declare class MutexLock {
|
|
|
21
80
|
* to avoid having to reason about the correctness of
|
|
22
81
|
* multiple requests interleaving.
|
|
23
82
|
*
|
|
24
|
-
* Note:
|
|
83
|
+
* Note:
|
|
84
|
+
* Instead of extending the passed class, `MutexedFS` stores it internally.
|
|
85
|
+
* This is to avoid a deadlock caused when a mathod calls another one
|
|
86
|
+
* The problem is discussed extensivly in [#78](https://github.com/zen-fs/core/issues/78)
|
|
87
|
+
* Instead of extending `FileSystem`,
|
|
88
|
+
* `MutexedFS` implements it in order to make sure all of the methods are passed through
|
|
25
89
|
*
|
|
26
90
|
* @todo Change `using _` to `using void` pending https://github.com/tc39/proposal-discard-binding
|
|
27
91
|
* @internal
|
|
28
92
|
*/
|
|
29
|
-
export declare function Mutexed<T extends
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
isLocked(path: string): boolean;
|
|
33
|
-
}>;
|
|
93
|
+
export declare function Mutexed<const T extends Concrete<typeof FileSystem>>(FS: T): typeof __MutexedFS<InstanceType<T>> & {
|
|
94
|
+
new (...args: ConstructorParameters<T>): __MutexedFS<InstanceType<T>>;
|
|
95
|
+
};
|