@zenfs/core 0.17.1 → 0.18.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 +2 -3
- package/dist/backends/fetch.js +2 -2
- package/dist/backends/file_index.d.ts +14 -15
- package/dist/backends/file_index.js +3 -9
- package/dist/backends/overlay.d.ts +21 -22
- package/dist/backends/overlay.js +111 -114
- package/dist/backends/port/fs.d.ts +21 -22
- package/dist/backends/port/fs.js +23 -23
- package/dist/backends/store/fs.d.ts +20 -21
- package/dist/backends/store/fs.js +70 -138
- package/dist/browser.min.js +4 -4
- package/dist/browser.min.js.map +4 -4
- package/dist/config.js +2 -2
- package/dist/{cred.d.ts → credentials.d.ts} +3 -2
- package/dist/credentials.js +16 -0
- package/dist/emulation/async.d.ts +19 -4
- package/dist/emulation/async.js +55 -8
- package/dist/emulation/dir.d.ts +4 -7
- package/dist/emulation/dir.js +16 -24
- package/dist/emulation/promises.d.ts +3 -3
- package/dist/emulation/promises.js +103 -46
- package/dist/emulation/shared.d.ts +0 -3
- package/dist/emulation/shared.js +0 -6
- package/dist/emulation/sync.d.ts +3 -4
- package/dist/emulation/sync.js +107 -65
- package/dist/emulation/watchers.d.ts +40 -3
- package/dist/emulation/watchers.js +115 -9
- package/dist/error.d.ts +1 -1
- package/dist/error.js +1 -1
- package/dist/filesystem.d.ts +20 -21
- package/dist/filesystem.js +4 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/mixins/async.d.ts +13 -14
- package/dist/mixins/async.js +45 -47
- package/dist/mixins/mutexed.d.ts +1 -1
- package/dist/mixins/mutexed.js +61 -53
- package/dist/mixins/readonly.d.ts +12 -13
- package/dist/mixins/readonly.js +12 -12
- package/dist/mixins/sync.js +20 -20
- package/dist/stats.d.ts +12 -5
- package/dist/stats.js +11 -2
- package/dist/utils.d.ts +3 -4
- package/dist/utils.js +7 -17
- package/package.json +2 -2
- package/src/backends/backend.ts +2 -3
- package/src/backends/fetch.ts +2 -2
- package/src/backends/file_index.ts +3 -12
- package/src/backends/overlay.ts +112 -116
- package/src/backends/port/fs.ts +25 -26
- package/src/backends/store/fs.ts +72 -151
- package/src/config.ts +3 -2
- package/src/{cred.ts → credentials.ts} +11 -2
- package/src/emulation/async.ts +72 -16
- package/src/emulation/dir.ts +21 -29
- package/src/emulation/promises.ts +107 -46
- package/src/emulation/shared.ts +0 -8
- package/src/emulation/sync.ts +109 -66
- package/src/emulation/watchers.ts +140 -10
- package/src/error.ts +1 -1
- package/src/filesystem.ts +22 -23
- package/src/index.ts +1 -1
- package/src/mixins/async.ts +54 -55
- package/src/mixins/mutexed.ts +62 -55
- package/src/mixins/readonly.ts +24 -25
- package/src/mixins/sync.ts +21 -22
- package/src/stats.ts +15 -5
- package/src/utils.ts +9 -26
- package/dist/cred.js +0 -8
|
@@ -84,10 +84,9 @@ export declare function checkOptions<T extends Backend>(backend: T, opts: Record
|
|
|
84
84
|
/**
|
|
85
85
|
* Specifies a file system backend type and its options.
|
|
86
86
|
*
|
|
87
|
-
* Individual options can recursively contain
|
|
88
|
-
* option values that require file systems.
|
|
87
|
+
* Individual options can recursively contain BackendConfiguration objects for values that require file systems.
|
|
89
88
|
*
|
|
90
|
-
* The
|
|
89
|
+
* The configuration for each file system corresponds to that file system's option object passed to its `create()` method.
|
|
91
90
|
*/
|
|
92
91
|
export type BackendConfiguration<T extends Backend> = OptionsOf<T> & Partial<SharedConfig> & {
|
|
93
92
|
backend: T;
|
package/dist/backends/fetch.js
CHANGED
|
@@ -80,10 +80,10 @@ export class FetchFS extends IndexFS {
|
|
|
80
80
|
preload(path, buffer) {
|
|
81
81
|
const stats = this.index.get(path);
|
|
82
82
|
if (!stats) {
|
|
83
|
-
throw ErrnoError.With('ENOENT', path, '
|
|
83
|
+
throw ErrnoError.With('ENOENT', path, 'preload');
|
|
84
84
|
}
|
|
85
85
|
if (!stats.isFile()) {
|
|
86
|
-
throw ErrnoError.With('EISDIR', path, '
|
|
86
|
+
throw ErrnoError.With('EISDIR', path, 'preload');
|
|
87
87
|
}
|
|
88
88
|
stats.size = buffer.length;
|
|
89
89
|
stats.fileData = buffer;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { Cred } from '../cred.js';
|
|
2
1
|
import { NoSyncFile } from '../file.js';
|
|
3
2
|
import { FileSystem } from '../filesystem.js';
|
|
4
3
|
import type { StatsLike } from '../stats.js';
|
|
@@ -45,18 +44,18 @@ export declare class Index extends Map<string, Stats> {
|
|
|
45
44
|
}
|
|
46
45
|
declare const IndexFS_base: import("../mixins/shared.js").Mixin<typeof FileSystem, {
|
|
47
46
|
metadata(): import("../filesystem.js").FileSystemMetadata;
|
|
48
|
-
rename(oldPath: string, newPath: string
|
|
49
|
-
renameSync(oldPath: string, newPath: string
|
|
50
|
-
createFile(path: string, flag: string, mode: number
|
|
51
|
-
createFileSync(path: string, flag: string, mode: number
|
|
52
|
-
unlink(path: string
|
|
53
|
-
unlinkSync(path: string
|
|
54
|
-
rmdir(path: string
|
|
55
|
-
rmdirSync(path: string
|
|
56
|
-
mkdir(path: string, mode: number
|
|
57
|
-
mkdirSync(path: string, mode: number
|
|
58
|
-
link(srcpath: string, dstpath: string
|
|
59
|
-
linkSync(srcpath: string, dstpath: string
|
|
47
|
+
rename(oldPath: string, newPath: string): Promise<void>;
|
|
48
|
+
renameSync(oldPath: string, newPath: string): void;
|
|
49
|
+
createFile(path: string, flag: string, mode: number): Promise<import("../file.js").File>;
|
|
50
|
+
createFileSync(path: string, flag: string, mode: number): import("../file.js").File;
|
|
51
|
+
unlink(path: string): Promise<void>;
|
|
52
|
+
unlinkSync(path: string): void;
|
|
53
|
+
rmdir(path: string): Promise<void>;
|
|
54
|
+
rmdirSync(path: string): void;
|
|
55
|
+
mkdir(path: string, mode: number): Promise<void>;
|
|
56
|
+
mkdirSync(path: string, mode: number): void;
|
|
57
|
+
link(srcpath: string, dstpath: string): Promise<void>;
|
|
58
|
+
linkSync(srcpath: string, dstpath: string): void;
|
|
60
59
|
sync(path: string, data: Uint8Array, stats: Readonly<Stats>): Promise<void>;
|
|
61
60
|
syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void;
|
|
62
61
|
}>;
|
|
@@ -70,8 +69,8 @@ export declare abstract class IndexFS extends IndexFS_base {
|
|
|
70
69
|
reloadFilesSync(): void;
|
|
71
70
|
stat(path: string): Promise<Stats>;
|
|
72
71
|
statSync(path: string): Stats;
|
|
73
|
-
openFile(path: string, flag: string
|
|
74
|
-
openFileSync(path: string, flag: string
|
|
72
|
+
openFile(path: string, flag: string): Promise<NoSyncFile<this>>;
|
|
73
|
+
openFileSync(path: string, flag: string): NoSyncFile<this>;
|
|
75
74
|
readdir(path: string): Promise<string[]>;
|
|
76
75
|
readdirSync(path: string): string[];
|
|
77
76
|
protected abstract getData(path: string, stats: Stats): Promise<Uint8Array>;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { isJSON } from 'utilium';
|
|
3
3
|
import { basename, dirname } from '../emulation/path.js';
|
|
4
4
|
import { Errno, ErrnoError } from '../error.js';
|
|
5
|
-
import { NoSyncFile,
|
|
5
|
+
import { NoSyncFile, isWriteable } from '../file.js';
|
|
6
6
|
import { FileSystem } from '../filesystem.js';
|
|
7
7
|
import { Readonly } from '../mixins/readonly.js';
|
|
8
8
|
import { Stats } from '../stats.js';
|
|
@@ -118,7 +118,7 @@ export class IndexFS extends Readonly(FileSystem) {
|
|
|
118
118
|
}
|
|
119
119
|
return this.index.get(path);
|
|
120
120
|
}
|
|
121
|
-
async openFile(path, flag
|
|
121
|
+
async openFile(path, flag) {
|
|
122
122
|
if (isWriteable(flag)) {
|
|
123
123
|
// You can't write to files on this file system.
|
|
124
124
|
throw new ErrnoError(Errno.EPERM, path);
|
|
@@ -128,12 +128,9 @@ export class IndexFS extends Readonly(FileSystem) {
|
|
|
128
128
|
if (!stats) {
|
|
129
129
|
throw ErrnoError.With('ENOENT', path, 'openFile');
|
|
130
130
|
}
|
|
131
|
-
if (!stats.hasAccess(flagToMode(flag), cred)) {
|
|
132
|
-
throw ErrnoError.With('EACCES', path, 'openFile');
|
|
133
|
-
}
|
|
134
131
|
return new NoSyncFile(this, path, flag, stats, stats.isDirectory() ? stats.fileData : await this.getData(path, stats));
|
|
135
132
|
}
|
|
136
|
-
openFileSync(path, flag
|
|
133
|
+
openFileSync(path, flag) {
|
|
137
134
|
if (isWriteable(flag)) {
|
|
138
135
|
// You can't write to files on this file system.
|
|
139
136
|
throw new ErrnoError(Errno.EPERM, path);
|
|
@@ -143,9 +140,6 @@ export class IndexFS extends Readonly(FileSystem) {
|
|
|
143
140
|
if (!stats) {
|
|
144
141
|
throw ErrnoError.With('ENOENT', path, 'openFile');
|
|
145
142
|
}
|
|
146
|
-
if (!stats.hasAccess(flagToMode(flag), cred)) {
|
|
147
|
-
throw ErrnoError.With('EACCES', path, 'openFile');
|
|
148
|
-
}
|
|
149
143
|
return new NoSyncFile(this, path, flag, stats, stats.isDirectory() ? stats.fileData : this.getDataSync(path, stats));
|
|
150
144
|
}
|
|
151
145
|
readdir(path) {
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
+
import type { File } from '../file.js';
|
|
1
2
|
import type { FileSystemMetadata } from '../filesystem.js';
|
|
2
3
|
import { FileSystem } from '../filesystem.js';
|
|
3
|
-
import type { File } from '../file.js';
|
|
4
4
|
import { Stats } from '../stats.js';
|
|
5
|
-
import type { Cred } from '../cred.js';
|
|
6
5
|
/**
|
|
7
6
|
* Configuration options for OverlayFS instances.
|
|
8
7
|
*/
|
|
@@ -45,25 +44,25 @@ export declare class UnmutexedOverlayFS extends FileSystem {
|
|
|
45
44
|
*/
|
|
46
45
|
_initialize(): Promise<void>;
|
|
47
46
|
getDeletionLog(): string;
|
|
48
|
-
restoreDeletionLog(log: string
|
|
49
|
-
rename(oldPath: string, newPath: string
|
|
50
|
-
renameSync(oldPath: string, newPath: string
|
|
51
|
-
stat(path: string
|
|
52
|
-
statSync(path: string
|
|
53
|
-
openFile(path: string, flag: string
|
|
54
|
-
openFileSync(path: string, flag: string
|
|
55
|
-
createFile(path: string, flag: string, mode: number
|
|
56
|
-
createFileSync(path: string, flag: string, mode: number
|
|
57
|
-
link(srcpath: string, dstpath: string
|
|
58
|
-
linkSync(srcpath: string, dstpath: string
|
|
59
|
-
unlink(path: string
|
|
60
|
-
unlinkSync(path: string
|
|
61
|
-
rmdir(path: string
|
|
62
|
-
rmdirSync(path: string
|
|
63
|
-
mkdir(path: string, mode: number
|
|
64
|
-
mkdirSync(path: string, mode: number
|
|
65
|
-
readdir(path: string
|
|
66
|
-
readdirSync(path: string
|
|
47
|
+
restoreDeletionLog(log: string): Promise<void>;
|
|
48
|
+
rename(oldPath: string, newPath: string): Promise<void>;
|
|
49
|
+
renameSync(oldPath: string, newPath: string): void;
|
|
50
|
+
stat(path: string): Promise<Stats>;
|
|
51
|
+
statSync(path: string): Stats;
|
|
52
|
+
openFile(path: string, flag: string): Promise<File>;
|
|
53
|
+
openFileSync(path: string, flag: string): File;
|
|
54
|
+
createFile(path: string, flag: string, mode: number): Promise<File>;
|
|
55
|
+
createFileSync(path: string, flag: string, mode: number): File;
|
|
56
|
+
link(srcpath: string, dstpath: string): Promise<void>;
|
|
57
|
+
linkSync(srcpath: string, dstpath: string): void;
|
|
58
|
+
unlink(path: string): Promise<void>;
|
|
59
|
+
unlinkSync(path: string): void;
|
|
60
|
+
rmdir(path: string): Promise<void>;
|
|
61
|
+
rmdirSync(path: string): void;
|
|
62
|
+
mkdir(path: string, mode: number): Promise<void>;
|
|
63
|
+
mkdirSync(path: string, mode: number): void;
|
|
64
|
+
readdir(path: string): Promise<string[]>;
|
|
65
|
+
readdirSync(path: string): string[];
|
|
67
66
|
private deletePath;
|
|
68
67
|
private updateLog;
|
|
69
68
|
private _reparseDeletionLog;
|
|
@@ -90,7 +89,7 @@ export declare class UnmutexedOverlayFS extends FileSystem {
|
|
|
90
89
|
private copyToWritable;
|
|
91
90
|
}
|
|
92
91
|
declare const OverlayFS_base: import("../mixins/shared.js").Mixin<typeof UnmutexedOverlayFS, {
|
|
93
|
-
lock(path: string): Promise<import("../mixins/mutexed.js").MutexLock>;
|
|
92
|
+
lock(path: string, syscall: string): Promise<import("../mixins/mutexed.js").MutexLock>;
|
|
94
93
|
lockSync(path: string): import("../mixins/mutexed.js").MutexLock;
|
|
95
94
|
isLocked(path: string): boolean;
|
|
96
95
|
}>;
|
package/dist/backends/overlay.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { dirname } from '../emulation/path.js';
|
|
2
|
+
import { Errno, ErrnoError } from '../error.js';
|
|
3
3
|
import { PreloadFile, parseFlag } from '../file.js';
|
|
4
|
-
import {
|
|
4
|
+
import { FileSystem } from '../filesystem.js';
|
|
5
5
|
import { Mutexed } from '../mixins/mutexed.js';
|
|
6
|
-
import {
|
|
7
|
-
import { rootCred } from '../cred.js';
|
|
6
|
+
import { Stats } from '../stats.js';
|
|
8
7
|
import { decode, encode } from '../utils.js';
|
|
9
8
|
/**
|
|
10
9
|
* @internal
|
|
@@ -48,16 +47,14 @@ export class UnmutexedOverlayFS extends FileSystem {
|
|
|
48
47
|
};
|
|
49
48
|
}
|
|
50
49
|
async sync(path, data, stats) {
|
|
51
|
-
|
|
52
|
-
await this.
|
|
53
|
-
|
|
54
|
-
await this.writable.createFile(path, 'w', 0o644, cred);
|
|
50
|
+
await this.createParentDirectories(path);
|
|
51
|
+
if (!(await this.writable.exists(path))) {
|
|
52
|
+
await this.writable.createFile(path, 'w', 0o644);
|
|
55
53
|
}
|
|
56
54
|
await this.writable.sync(path, data, stats);
|
|
57
55
|
}
|
|
58
56
|
syncSync(path, data, stats) {
|
|
59
|
-
|
|
60
|
-
this.createParentDirectoriesSync(path, cred);
|
|
57
|
+
this.createParentDirectoriesSync(path);
|
|
61
58
|
this.writable.syncSync(path, data, stats);
|
|
62
59
|
}
|
|
63
60
|
/**
|
|
@@ -70,7 +67,7 @@ export class UnmutexedOverlayFS extends FileSystem {
|
|
|
70
67
|
}
|
|
71
68
|
// Read deletion log, process into metadata.
|
|
72
69
|
try {
|
|
73
|
-
const file = await this.writable.openFile(deletionLogPath, parseFlag('r')
|
|
70
|
+
const file = await this.writable.openFile(deletionLogPath, parseFlag('r'));
|
|
74
71
|
const { size } = await file.stat();
|
|
75
72
|
const { buffer } = await file.read(new Uint8Array(size));
|
|
76
73
|
this._deleteLog = decode(buffer);
|
|
@@ -86,17 +83,17 @@ export class UnmutexedOverlayFS extends FileSystem {
|
|
|
86
83
|
getDeletionLog() {
|
|
87
84
|
return this._deleteLog;
|
|
88
85
|
}
|
|
89
|
-
async restoreDeletionLog(log
|
|
86
|
+
async restoreDeletionLog(log) {
|
|
90
87
|
this._deleteLog = log;
|
|
91
88
|
this._reparseDeletionLog();
|
|
92
|
-
await this.updateLog(''
|
|
89
|
+
await this.updateLog('');
|
|
93
90
|
}
|
|
94
|
-
async rename(oldPath, newPath
|
|
91
|
+
async rename(oldPath, newPath) {
|
|
95
92
|
this.checkInitialized();
|
|
96
93
|
this.checkPath(oldPath);
|
|
97
94
|
this.checkPath(newPath);
|
|
98
95
|
try {
|
|
99
|
-
await this.writable.rename(oldPath, newPath
|
|
96
|
+
await this.writable.rename(oldPath, newPath);
|
|
100
97
|
}
|
|
101
98
|
catch (e) {
|
|
102
99
|
if (this._deletedFiles.has(oldPath)) {
|
|
@@ -104,12 +101,12 @@ export class UnmutexedOverlayFS extends FileSystem {
|
|
|
104
101
|
}
|
|
105
102
|
}
|
|
106
103
|
}
|
|
107
|
-
renameSync(oldPath, newPath
|
|
104
|
+
renameSync(oldPath, newPath) {
|
|
108
105
|
this.checkInitialized();
|
|
109
106
|
this.checkPath(oldPath);
|
|
110
107
|
this.checkPath(newPath);
|
|
111
108
|
try {
|
|
112
|
-
this.writable.renameSync(oldPath, newPath
|
|
109
|
+
this.writable.renameSync(oldPath, newPath);
|
|
113
110
|
}
|
|
114
111
|
catch (e) {
|
|
115
112
|
if (this._deletedFiles.has(oldPath)) {
|
|
@@ -117,173 +114,173 @@ export class UnmutexedOverlayFS extends FileSystem {
|
|
|
117
114
|
}
|
|
118
115
|
}
|
|
119
116
|
}
|
|
120
|
-
async stat(path
|
|
117
|
+
async stat(path) {
|
|
121
118
|
this.checkInitialized();
|
|
122
119
|
try {
|
|
123
|
-
return await this.writable.stat(path
|
|
120
|
+
return await this.writable.stat(path);
|
|
124
121
|
}
|
|
125
122
|
catch (e) {
|
|
126
123
|
if (this._deletedFiles.has(path)) {
|
|
127
124
|
throw ErrnoError.With('ENOENT', path, 'stat');
|
|
128
125
|
}
|
|
129
|
-
const oldStat = new Stats(await this.readable.stat(path
|
|
126
|
+
const oldStat = new Stats(await this.readable.stat(path));
|
|
130
127
|
// Make the oldStat's mode writable. Preserve the topmost part of the mode, which specifies the type
|
|
131
128
|
oldStat.mode |= 0o222;
|
|
132
129
|
return oldStat;
|
|
133
130
|
}
|
|
134
131
|
}
|
|
135
|
-
statSync(path
|
|
132
|
+
statSync(path) {
|
|
136
133
|
this.checkInitialized();
|
|
137
134
|
try {
|
|
138
|
-
return this.writable.statSync(path
|
|
135
|
+
return this.writable.statSync(path);
|
|
139
136
|
}
|
|
140
137
|
catch (e) {
|
|
141
138
|
if (this._deletedFiles.has(path)) {
|
|
142
139
|
throw ErrnoError.With('ENOENT', path, 'stat');
|
|
143
140
|
}
|
|
144
|
-
const oldStat = new Stats(this.readable.statSync(path
|
|
141
|
+
const oldStat = new Stats(this.readable.statSync(path));
|
|
145
142
|
// Make the oldStat's mode writable. Preserve the topmost part of the mode, which specifies the type.
|
|
146
143
|
oldStat.mode |= 0o222;
|
|
147
144
|
return oldStat;
|
|
148
145
|
}
|
|
149
146
|
}
|
|
150
|
-
async openFile(path, flag
|
|
151
|
-
if (await this.writable.exists(path
|
|
152
|
-
return this.writable.openFile(path, flag
|
|
147
|
+
async openFile(path, flag) {
|
|
148
|
+
if (await this.writable.exists(path)) {
|
|
149
|
+
return this.writable.openFile(path, flag);
|
|
153
150
|
}
|
|
154
151
|
// Create an OverlayFile.
|
|
155
|
-
const file = await this.readable.openFile(path, parseFlag('r')
|
|
152
|
+
const file = await this.readable.openFile(path, parseFlag('r'));
|
|
156
153
|
const stats = new Stats(await file.stat());
|
|
157
154
|
const { buffer } = await file.read(new Uint8Array(stats.size));
|
|
158
155
|
return new PreloadFile(this, path, flag, stats, buffer);
|
|
159
156
|
}
|
|
160
|
-
openFileSync(path, flag
|
|
161
|
-
if (this.writable.existsSync(path
|
|
162
|
-
return this.writable.openFileSync(path, flag
|
|
157
|
+
openFileSync(path, flag) {
|
|
158
|
+
if (this.writable.existsSync(path)) {
|
|
159
|
+
return this.writable.openFileSync(path, flag);
|
|
163
160
|
}
|
|
164
161
|
// Create an OverlayFile.
|
|
165
|
-
const file = this.readable.openFileSync(path, parseFlag('r')
|
|
162
|
+
const file = this.readable.openFileSync(path, parseFlag('r'));
|
|
166
163
|
const stats = new Stats(file.statSync());
|
|
167
164
|
const data = new Uint8Array(stats.size);
|
|
168
165
|
file.readSync(data);
|
|
169
166
|
return new PreloadFile(this, path, flag, stats, data);
|
|
170
167
|
}
|
|
171
|
-
async createFile(path, flag, mode
|
|
168
|
+
async createFile(path, flag, mode) {
|
|
172
169
|
this.checkInitialized();
|
|
173
|
-
await this.writable.createFile(path, flag, mode
|
|
174
|
-
return this.openFile(path, flag
|
|
170
|
+
await this.writable.createFile(path, flag, mode);
|
|
171
|
+
return this.openFile(path, flag);
|
|
175
172
|
}
|
|
176
|
-
createFileSync(path, flag, mode
|
|
173
|
+
createFileSync(path, flag, mode) {
|
|
177
174
|
this.checkInitialized();
|
|
178
|
-
this.writable.createFileSync(path, flag, mode
|
|
179
|
-
return this.openFileSync(path, flag
|
|
175
|
+
this.writable.createFileSync(path, flag, mode);
|
|
176
|
+
return this.openFileSync(path, flag);
|
|
180
177
|
}
|
|
181
|
-
async link(srcpath, dstpath
|
|
178
|
+
async link(srcpath, dstpath) {
|
|
182
179
|
this.checkInitialized();
|
|
183
|
-
await this.writable.link(srcpath, dstpath
|
|
180
|
+
await this.writable.link(srcpath, dstpath);
|
|
184
181
|
}
|
|
185
|
-
linkSync(srcpath, dstpath
|
|
182
|
+
linkSync(srcpath, dstpath) {
|
|
186
183
|
this.checkInitialized();
|
|
187
|
-
this.writable.linkSync(srcpath, dstpath
|
|
184
|
+
this.writable.linkSync(srcpath, dstpath);
|
|
188
185
|
}
|
|
189
|
-
async unlink(path
|
|
186
|
+
async unlink(path) {
|
|
190
187
|
this.checkInitialized();
|
|
191
188
|
this.checkPath(path);
|
|
192
|
-
if (!(await this.exists(path
|
|
189
|
+
if (!(await this.exists(path))) {
|
|
193
190
|
throw ErrnoError.With('ENOENT', path, 'unlink');
|
|
194
191
|
}
|
|
195
|
-
if (await this.writable.exists(path
|
|
196
|
-
await this.writable.unlink(path
|
|
192
|
+
if (await this.writable.exists(path)) {
|
|
193
|
+
await this.writable.unlink(path);
|
|
197
194
|
}
|
|
198
195
|
// if it still exists add to the delete log
|
|
199
|
-
if (await this.exists(path
|
|
200
|
-
await this.deletePath(path
|
|
196
|
+
if (await this.exists(path)) {
|
|
197
|
+
await this.deletePath(path);
|
|
201
198
|
}
|
|
202
199
|
}
|
|
203
|
-
unlinkSync(path
|
|
200
|
+
unlinkSync(path) {
|
|
204
201
|
this.checkInitialized();
|
|
205
202
|
this.checkPath(path);
|
|
206
|
-
if (!this.existsSync(path
|
|
203
|
+
if (!this.existsSync(path)) {
|
|
207
204
|
throw ErrnoError.With('ENOENT', path, 'unlink');
|
|
208
205
|
}
|
|
209
|
-
if (this.writable.existsSync(path
|
|
210
|
-
this.writable.unlinkSync(path
|
|
206
|
+
if (this.writable.existsSync(path)) {
|
|
207
|
+
this.writable.unlinkSync(path);
|
|
211
208
|
}
|
|
212
209
|
// if it still exists add to the delete log
|
|
213
|
-
if (this.existsSync(path
|
|
214
|
-
void this.deletePath(path
|
|
210
|
+
if (this.existsSync(path)) {
|
|
211
|
+
void this.deletePath(path);
|
|
215
212
|
}
|
|
216
213
|
}
|
|
217
|
-
async rmdir(path
|
|
214
|
+
async rmdir(path) {
|
|
218
215
|
this.checkInitialized();
|
|
219
|
-
if (!(await this.exists(path
|
|
216
|
+
if (!(await this.exists(path))) {
|
|
220
217
|
throw ErrnoError.With('ENOENT', path, 'rmdir');
|
|
221
218
|
}
|
|
222
|
-
if (await this.writable.exists(path
|
|
223
|
-
await this.writable.rmdir(path
|
|
219
|
+
if (await this.writable.exists(path)) {
|
|
220
|
+
await this.writable.rmdir(path);
|
|
224
221
|
}
|
|
225
|
-
if (await this.exists(path
|
|
222
|
+
if (await this.exists(path)) {
|
|
226
223
|
// Check if directory is empty.
|
|
227
|
-
if ((await this.readdir(path
|
|
224
|
+
if ((await this.readdir(path)).length > 0) {
|
|
228
225
|
throw ErrnoError.With('ENOTEMPTY', path, 'rmdir');
|
|
229
226
|
}
|
|
230
227
|
else {
|
|
231
|
-
await this.deletePath(path
|
|
228
|
+
await this.deletePath(path);
|
|
232
229
|
}
|
|
233
230
|
}
|
|
234
231
|
}
|
|
235
|
-
rmdirSync(path
|
|
232
|
+
rmdirSync(path) {
|
|
236
233
|
this.checkInitialized();
|
|
237
|
-
if (!this.existsSync(path
|
|
234
|
+
if (!this.existsSync(path)) {
|
|
238
235
|
throw ErrnoError.With('ENOENT', path, 'rmdir');
|
|
239
236
|
}
|
|
240
|
-
if (this.writable.existsSync(path
|
|
241
|
-
this.writable.rmdirSync(path
|
|
237
|
+
if (this.writable.existsSync(path)) {
|
|
238
|
+
this.writable.rmdirSync(path);
|
|
242
239
|
}
|
|
243
|
-
if (this.existsSync(path
|
|
240
|
+
if (this.existsSync(path)) {
|
|
244
241
|
// Check if directory is empty.
|
|
245
|
-
if (this.readdirSync(path
|
|
242
|
+
if (this.readdirSync(path).length > 0) {
|
|
246
243
|
throw ErrnoError.With('ENOTEMPTY', path, 'rmdir');
|
|
247
244
|
}
|
|
248
245
|
else {
|
|
249
|
-
void this.deletePath(path
|
|
246
|
+
void this.deletePath(path);
|
|
250
247
|
}
|
|
251
248
|
}
|
|
252
249
|
}
|
|
253
|
-
async mkdir(path, mode
|
|
250
|
+
async mkdir(path, mode) {
|
|
254
251
|
this.checkInitialized();
|
|
255
|
-
if (await this.exists(path
|
|
252
|
+
if (await this.exists(path)) {
|
|
256
253
|
throw ErrnoError.With('EEXIST', path, 'mkdir');
|
|
257
254
|
}
|
|
258
255
|
// The below will throw should any of the parent directories fail to exist on _writable.
|
|
259
|
-
await this.createParentDirectories(path
|
|
260
|
-
await this.writable.mkdir(path, mode
|
|
256
|
+
await this.createParentDirectories(path);
|
|
257
|
+
await this.writable.mkdir(path, mode);
|
|
261
258
|
}
|
|
262
|
-
mkdirSync(path, mode
|
|
259
|
+
mkdirSync(path, mode) {
|
|
263
260
|
this.checkInitialized();
|
|
264
|
-
if (this.existsSync(path
|
|
261
|
+
if (this.existsSync(path)) {
|
|
265
262
|
throw ErrnoError.With('EEXIST', path, 'mkdir');
|
|
266
263
|
}
|
|
267
264
|
// The below will throw should any of the parent directories fail to exist on _writable.
|
|
268
|
-
this.createParentDirectoriesSync(path
|
|
269
|
-
this.writable.mkdirSync(path, mode
|
|
265
|
+
this.createParentDirectoriesSync(path);
|
|
266
|
+
this.writable.mkdirSync(path, mode);
|
|
270
267
|
}
|
|
271
|
-
async readdir(path
|
|
268
|
+
async readdir(path) {
|
|
272
269
|
this.checkInitialized();
|
|
273
|
-
const dirStats = await this.stat(path
|
|
270
|
+
const dirStats = await this.stat(path);
|
|
274
271
|
if (!dirStats.isDirectory()) {
|
|
275
272
|
throw ErrnoError.With('ENOTDIR', path, 'readdir');
|
|
276
273
|
}
|
|
277
274
|
// Readdir in both, check delete log on RO file system's listing, merge, return.
|
|
278
275
|
const contents = [];
|
|
279
276
|
try {
|
|
280
|
-
contents.push(...(await this.writable.readdir(path
|
|
277
|
+
contents.push(...(await this.writable.readdir(path)));
|
|
281
278
|
}
|
|
282
279
|
catch (e) {
|
|
283
280
|
// NOP.
|
|
284
281
|
}
|
|
285
282
|
try {
|
|
286
|
-
contents.push(...(await this.readable.readdir(path
|
|
283
|
+
contents.push(...(await this.readable.readdir(path)).filter((fPath) => !this._deletedFiles.has(`${path}/${fPath}`)));
|
|
287
284
|
}
|
|
288
285
|
catch (e) {
|
|
289
286
|
// NOP.
|
|
@@ -295,22 +292,22 @@ export class UnmutexedOverlayFS extends FileSystem {
|
|
|
295
292
|
return result;
|
|
296
293
|
});
|
|
297
294
|
}
|
|
298
|
-
readdirSync(path
|
|
295
|
+
readdirSync(path) {
|
|
299
296
|
this.checkInitialized();
|
|
300
|
-
const dirStats = this.statSync(path
|
|
297
|
+
const dirStats = this.statSync(path);
|
|
301
298
|
if (!dirStats.isDirectory()) {
|
|
302
299
|
throw ErrnoError.With('ENOTDIR', path, 'readdir');
|
|
303
300
|
}
|
|
304
301
|
// Readdir in both, check delete log on RO file system's listing, merge, return.
|
|
305
302
|
let contents = [];
|
|
306
303
|
try {
|
|
307
|
-
contents = contents.concat(this.writable.readdirSync(path
|
|
304
|
+
contents = contents.concat(this.writable.readdirSync(path));
|
|
308
305
|
}
|
|
309
306
|
catch (e) {
|
|
310
307
|
// NOP.
|
|
311
308
|
}
|
|
312
309
|
try {
|
|
313
|
-
contents = contents.concat(this.readable.readdirSync(path
|
|
310
|
+
contents = contents.concat(this.readable.readdirSync(path).filter((fPath) => !this._deletedFiles.has(`${path}/${fPath}`)));
|
|
314
311
|
}
|
|
315
312
|
catch (e) {
|
|
316
313
|
// NOP.
|
|
@@ -322,23 +319,23 @@ export class UnmutexedOverlayFS extends FileSystem {
|
|
|
322
319
|
return result;
|
|
323
320
|
});
|
|
324
321
|
}
|
|
325
|
-
async deletePath(path
|
|
322
|
+
async deletePath(path) {
|
|
326
323
|
this._deletedFiles.add(path);
|
|
327
|
-
await this.updateLog(`d${path}\n
|
|
324
|
+
await this.updateLog(`d${path}\n`);
|
|
328
325
|
}
|
|
329
|
-
async updateLog(addition
|
|
326
|
+
async updateLog(addition) {
|
|
330
327
|
this._deleteLog += addition;
|
|
331
328
|
if (this._deleteLogUpdatePending) {
|
|
332
329
|
this._deleteLogUpdateNeeded = true;
|
|
333
330
|
return;
|
|
334
331
|
}
|
|
335
332
|
this._deleteLogUpdatePending = true;
|
|
336
|
-
const log = await this.writable.openFile(deletionLogPath, parseFlag('w')
|
|
333
|
+
const log = await this.writable.openFile(deletionLogPath, parseFlag('w'));
|
|
337
334
|
try {
|
|
338
335
|
await log.write(encode(this._deleteLog));
|
|
339
336
|
if (this._deleteLogUpdateNeeded) {
|
|
340
337
|
this._deleteLogUpdateNeeded = false;
|
|
341
|
-
await this.updateLog(''
|
|
338
|
+
await this.updateLog('');
|
|
342
339
|
}
|
|
343
340
|
}
|
|
344
341
|
catch (e) {
|
|
@@ -378,27 +375,27 @@ export class UnmutexedOverlayFS extends FileSystem {
|
|
|
378
375
|
* With the given path, create the needed parent directories on the writable storage
|
|
379
376
|
* should they not exist. Use modes from the read-only storage.
|
|
380
377
|
*/
|
|
381
|
-
createParentDirectoriesSync(path
|
|
378
|
+
createParentDirectoriesSync(path) {
|
|
382
379
|
let parent = dirname(path), toCreate = [];
|
|
383
|
-
while (!this.writable.existsSync(parent
|
|
380
|
+
while (!this.writable.existsSync(parent)) {
|
|
384
381
|
toCreate.push(parent);
|
|
385
382
|
parent = dirname(parent);
|
|
386
383
|
}
|
|
387
384
|
toCreate = toCreate.reverse();
|
|
388
385
|
for (const p of toCreate) {
|
|
389
|
-
this.writable.mkdirSync(p, this.statSync(p
|
|
386
|
+
this.writable.mkdirSync(p, this.statSync(p).mode);
|
|
390
387
|
}
|
|
391
388
|
}
|
|
392
|
-
async createParentDirectories(path
|
|
389
|
+
async createParentDirectories(path) {
|
|
393
390
|
let parent = dirname(path), toCreate = [];
|
|
394
|
-
while (!(await this.writable.exists(parent
|
|
391
|
+
while (!(await this.writable.exists(parent))) {
|
|
395
392
|
toCreate.push(parent);
|
|
396
393
|
parent = dirname(parent);
|
|
397
394
|
}
|
|
398
395
|
toCreate = toCreate.reverse();
|
|
399
396
|
for (const p of toCreate) {
|
|
400
|
-
const stats = await this.stat(p
|
|
401
|
-
await this.writable.mkdir(p, stats.mode
|
|
397
|
+
const stats = await this.stat(p);
|
|
398
|
+
await this.writable.mkdir(p, stats.mode);
|
|
402
399
|
}
|
|
403
400
|
}
|
|
404
401
|
/**
|
|
@@ -406,53 +403,53 @@ export class UnmutexedOverlayFS extends FileSystem {
|
|
|
406
403
|
* - Ensures p is on writable before proceeding. Throws an error if it doesn't exist.
|
|
407
404
|
* - Calls f to perform operation on writable.
|
|
408
405
|
*/
|
|
409
|
-
operateOnWritable(path
|
|
410
|
-
if (!this.existsSync(path
|
|
406
|
+
operateOnWritable(path) {
|
|
407
|
+
if (!this.existsSync(path)) {
|
|
411
408
|
throw ErrnoError.With('ENOENT', path, 'operateOnWriteable');
|
|
412
409
|
}
|
|
413
|
-
if (!this.writable.existsSync(path
|
|
410
|
+
if (!this.writable.existsSync(path)) {
|
|
414
411
|
// File is on readable storage. Copy to writable storage before
|
|
415
412
|
// changing its mode.
|
|
416
|
-
this.copyToWritableSync(path
|
|
413
|
+
this.copyToWritableSync(path);
|
|
417
414
|
}
|
|
418
415
|
}
|
|
419
|
-
async operateOnWritableAsync(path
|
|
420
|
-
if (!(await this.exists(path
|
|
416
|
+
async operateOnWritableAsync(path) {
|
|
417
|
+
if (!(await this.exists(path))) {
|
|
421
418
|
throw ErrnoError.With('ENOENT', path, 'operateOnWritable');
|
|
422
419
|
}
|
|
423
|
-
if (!(await this.writable.exists(path
|
|
424
|
-
return this.copyToWritable(path
|
|
420
|
+
if (!(await this.writable.exists(path))) {
|
|
421
|
+
return this.copyToWritable(path);
|
|
425
422
|
}
|
|
426
423
|
}
|
|
427
424
|
/**
|
|
428
425
|
* Copy from readable to writable storage.
|
|
429
426
|
* PRECONDITION: File does not exist on writable storage.
|
|
430
427
|
*/
|
|
431
|
-
copyToWritableSync(path
|
|
432
|
-
const stats = this.statSync(path
|
|
428
|
+
copyToWritableSync(path) {
|
|
429
|
+
const stats = this.statSync(path);
|
|
433
430
|
if (stats.isDirectory()) {
|
|
434
|
-
this.writable.mkdirSync(path, stats.mode
|
|
431
|
+
this.writable.mkdirSync(path, stats.mode);
|
|
435
432
|
return;
|
|
436
433
|
}
|
|
437
434
|
const data = new Uint8Array(stats.size);
|
|
438
|
-
const readable = this.readable.openFileSync(path, parseFlag('r')
|
|
435
|
+
const readable = this.readable.openFileSync(path, parseFlag('r'));
|
|
439
436
|
readable.readSync(data);
|
|
440
437
|
readable.closeSync();
|
|
441
|
-
const writable = this.writable.openFileSync(path, parseFlag('w')
|
|
438
|
+
const writable = this.writable.openFileSync(path, parseFlag('w'));
|
|
442
439
|
writable.writeSync(data);
|
|
443
440
|
writable.closeSync();
|
|
444
441
|
}
|
|
445
|
-
async copyToWritable(path
|
|
446
|
-
const stats = await this.stat(path
|
|
442
|
+
async copyToWritable(path) {
|
|
443
|
+
const stats = await this.stat(path);
|
|
447
444
|
if (stats.isDirectory()) {
|
|
448
|
-
await this.writable.mkdir(path, stats.mode
|
|
445
|
+
await this.writable.mkdir(path, stats.mode);
|
|
449
446
|
return;
|
|
450
447
|
}
|
|
451
448
|
const data = new Uint8Array(stats.size);
|
|
452
|
-
const readable = await this.readable.openFile(path, parseFlag('r')
|
|
449
|
+
const readable = await this.readable.openFile(path, parseFlag('r'));
|
|
453
450
|
await readable.read(data);
|
|
454
451
|
await readable.close();
|
|
455
|
-
const writable = await this.writable.openFile(path, parseFlag('w')
|
|
452
|
+
const writable = await this.writable.openFile(path, parseFlag('w'));
|
|
456
453
|
await writable.write(data);
|
|
457
454
|
await writable.close();
|
|
458
455
|
}
|