@zenfs/core 0.17.1 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +23 -26
- package/dist/backends/overlay.js +117 -120
- package/dist/backends/port/fs.d.ts +22 -24
- package/dist/backends/port/fs.js +25 -26
- 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 +102 -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 +106 -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/file.d.ts +22 -13
- package/dist/file.js +16 -7
- 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 +72 -10
- package/dist/mixins/mutexed.js +375 -371
- package/dist/mixins/readonly.d.ts +12 -13
- package/dist/mixins/readonly.js +12 -12
- package/dist/mixins/shared.d.ts +1 -0
- package/dist/mixins/shared.js +1 -0
- package/dist/mixins/sync.js +20 -20
- package/dist/stats.d.ts +12 -6
- package/dist/stats.js +15 -6
- package/dist/utils.d.ts +5 -5
- package/dist/utils.js +7 -17
- package/package.json +2 -2
- package/readme.md +1 -1
- 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 +118 -124
- package/src/backends/port/fs.ts +29 -30
- 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 +106 -46
- package/src/emulation/shared.ts +0 -8
- package/src/emulation/sync.ts +108 -66
- package/src/emulation/watchers.ts +140 -10
- package/src/error.ts +1 -1
- package/src/file.ts +16 -11
- package/src/filesystem.ts +22 -23
- package/src/index.ts +1 -1
- package/src/mixins/async.ts +54 -55
- package/src/mixins/mutexed.ts +194 -182
- package/src/mixins/readonly.ts +24 -25
- package/src/mixins/shared.ts +3 -2
- package/src/mixins/sync.ts +21 -22
- package/src/stats.ts +17 -8
- package/src/utils.ts +12 -27
- package/dist/cred.js +0 -8
package/src/mixins/mutexed.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import type { Cred } from '../cred.js';
|
|
2
1
|
import { ErrnoError } from '../error.js';
|
|
3
2
|
import type { File } from '../file.js';
|
|
4
|
-
import type { FileSystem } from '../filesystem.js';
|
|
3
|
+
import type { FileSystem, FileSystemMetadata } from '../filesystem.js';
|
|
5
4
|
import '../polyfills.js';
|
|
6
5
|
import type { Stats } from '../stats.js';
|
|
7
|
-
import type {
|
|
6
|
+
import type { Concrete } from '../utils.js';
|
|
8
7
|
|
|
9
8
|
export class MutexLock {
|
|
10
9
|
protected current = Promise.withResolvers<void>();
|
|
@@ -14,10 +13,7 @@ export class MutexLock {
|
|
|
14
13
|
return this._isLocked;
|
|
15
14
|
}
|
|
16
15
|
|
|
17
|
-
public constructor(
|
|
18
|
-
public readonly path: string,
|
|
19
|
-
protected readonly previous?: MutexLock
|
|
20
|
-
) {}
|
|
16
|
+
public constructor(protected readonly previous?: MutexLock) {}
|
|
21
17
|
|
|
22
18
|
public async done(): Promise<void> {
|
|
23
19
|
await this.previous?.done();
|
|
@@ -35,211 +31,227 @@ export class MutexLock {
|
|
|
35
31
|
}
|
|
36
32
|
|
|
37
33
|
/**
|
|
38
|
-
*
|
|
39
|
-
* For example, on an OverlayFS instance with an async lower
|
|
40
|
-
* directory operations like rename and rmdir may involve multiple
|
|
41
|
-
* requests involving both the upper and lower filesystems -- they
|
|
42
|
-
* are not executed in a single atomic step. OverlayFS uses this
|
|
43
|
-
* to avoid having to reason about the correctness of
|
|
44
|
-
* multiple requests interleaving.
|
|
45
|
-
*
|
|
46
|
-
* Note: `@ts-expect-error 2513` is needed because `FS` is not properly detected as being concrete
|
|
47
|
-
*
|
|
48
|
-
* @todo Change `using _` to `using void` pending https://github.com/tc39/proposal-discard-binding
|
|
49
|
-
* @internal
|
|
34
|
+
* @hidden
|
|
50
35
|
*/
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
T
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
> {
|
|
62
|
-
class MutexedFS extends FS {
|
|
63
|
-
/**
|
|
64
|
-
* The current locks
|
|
65
|
-
*/
|
|
66
|
-
private locks: Map<string, MutexLock> = new Map();
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Adds a lock for a path
|
|
70
|
-
*/
|
|
71
|
-
protected addLock(path: string): MutexLock {
|
|
72
|
-
const previous = this.locks.get(path);
|
|
73
|
-
const lock = new MutexLock(path, previous?.isLocked ? previous : undefined);
|
|
74
|
-
this.locks.set(path, lock);
|
|
75
|
-
return lock;
|
|
76
|
-
}
|
|
36
|
+
export class __MutexedFS<T extends FileSystem> implements FileSystem {
|
|
37
|
+
/**
|
|
38
|
+
* @internal
|
|
39
|
+
*/
|
|
40
|
+
public _fs!: T;
|
|
41
|
+
|
|
42
|
+
public async ready(): Promise<void> {
|
|
43
|
+
return await this._fs.ready();
|
|
44
|
+
}
|
|
77
45
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
* @internal
|
|
82
|
-
*/
|
|
83
|
-
public async lock(path: string): Promise<MutexLock> {
|
|
84
|
-
const previous = this.locks.get(path);
|
|
85
|
-
const lock = this.addLock(path);
|
|
86
|
-
await previous?.done();
|
|
87
|
-
return lock;
|
|
88
|
-
}
|
|
46
|
+
public metadata(): FileSystemMetadata {
|
|
47
|
+
return this._fs.metadata();
|
|
48
|
+
}
|
|
89
49
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
50
|
+
/**
|
|
51
|
+
* The current locks
|
|
52
|
+
*/
|
|
53
|
+
private currentLock?: MutexLock;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Adds a lock for a path
|
|
57
|
+
*/
|
|
58
|
+
protected addLock(): MutexLock {
|
|
59
|
+
const lock = new MutexLock(this.currentLock);
|
|
60
|
+
this.currentLock = lock;
|
|
61
|
+
return lock;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Locks `path` asynchronously.
|
|
66
|
+
* If the path is currently locked, waits for it to be unlocked.
|
|
67
|
+
* @internal
|
|
68
|
+
*/
|
|
69
|
+
public async lock(path: string, syscall: string): Promise<MutexLock> {
|
|
70
|
+
const previous = this.currentLock;
|
|
71
|
+
const lock = this.addLock();
|
|
72
|
+
const stack = new Error().stack;
|
|
73
|
+
setTimeout(() => {
|
|
74
|
+
if (lock.isLocked) {
|
|
75
|
+
const error = ErrnoError.With('EDEADLK', path, syscall);
|
|
76
|
+
error.stack += stack?.slice('Error'.length);
|
|
77
|
+
throw error;
|
|
99
78
|
}
|
|
79
|
+
}, 5000);
|
|
80
|
+
await previous?.done();
|
|
81
|
+
return lock;
|
|
82
|
+
}
|
|
100
83
|
|
|
101
|
-
|
|
84
|
+
/**
|
|
85
|
+
* Locks `path` asynchronously.
|
|
86
|
+
* If the path is currently locked, an error will be thrown
|
|
87
|
+
* @internal
|
|
88
|
+
*/
|
|
89
|
+
public lockSync(path: string, syscall: string): MutexLock {
|
|
90
|
+
if (this.currentLock) {
|
|
91
|
+
throw ErrnoError.With('EBUSY', path, syscall);
|
|
102
92
|
}
|
|
103
93
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
* @internal
|
|
107
|
-
*/
|
|
108
|
-
public isLocked(path: string): boolean {
|
|
109
|
-
return !!this.locks.get(path)?.isLocked;
|
|
110
|
-
}
|
|
94
|
+
return this.addLock();
|
|
95
|
+
}
|
|
111
96
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Whether `path` is locked
|
|
99
|
+
* @internal
|
|
100
|
+
*/
|
|
101
|
+
public get isLocked(): boolean {
|
|
102
|
+
return !!this.currentLock?.isLocked;
|
|
103
|
+
}
|
|
118
104
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
105
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
106
|
+
public async rename(oldPath: string, newPath: string): Promise<void> {
|
|
107
|
+
using _ = await this.lock(oldPath, 'rename');
|
|
108
|
+
await this._fs.rename(oldPath, newPath);
|
|
109
|
+
}
|
|
124
110
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
111
|
+
public renameSync(oldPath: string, newPath: string): void {
|
|
112
|
+
using _ = this.lockSync(oldPath, 'rename');
|
|
113
|
+
return this._fs.renameSync(oldPath, newPath);
|
|
114
|
+
}
|
|
130
115
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
116
|
+
public async stat(path: string): Promise<Stats> {
|
|
117
|
+
using _ = await this.lock(path, 'stat');
|
|
118
|
+
return await this._fs.stat(path);
|
|
119
|
+
}
|
|
136
120
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
121
|
+
public statSync(path: string): Stats {
|
|
122
|
+
using _ = this.lockSync(path, 'stat');
|
|
123
|
+
return this._fs.statSync(path);
|
|
124
|
+
}
|
|
142
125
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
126
|
+
public async openFile(path: string, flag: string): Promise<File> {
|
|
127
|
+
using _ = await this.lock(path, 'openFile');
|
|
128
|
+
const file = await this._fs.openFile(path, flag);
|
|
129
|
+
file.fs = this;
|
|
130
|
+
return file;
|
|
131
|
+
}
|
|
148
132
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
133
|
+
public openFileSync(path: string, flag: string): File {
|
|
134
|
+
using _ = this.lockSync(path, 'openFile');
|
|
135
|
+
const file = this._fs.openFileSync(path, flag);
|
|
136
|
+
file.fs = this;
|
|
137
|
+
return file;
|
|
138
|
+
}
|
|
154
139
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
140
|
+
public async createFile(path: string, flag: string, mode: number): Promise<File> {
|
|
141
|
+
using _ = await this.lock(path, 'createFile');
|
|
142
|
+
const file = await this._fs.createFile(path, flag, mode);
|
|
143
|
+
file.fs = this;
|
|
144
|
+
return file;
|
|
145
|
+
}
|
|
160
146
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
147
|
+
public createFileSync(path: string, flag: string, mode: number): File {
|
|
148
|
+
using _ = this.lockSync(path, 'createFile');
|
|
149
|
+
const file = this._fs.createFileSync(path, flag, mode);
|
|
150
|
+
file.fs = this;
|
|
151
|
+
return file;
|
|
152
|
+
}
|
|
166
153
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
154
|
+
public async unlink(path: string): Promise<void> {
|
|
155
|
+
using _ = await this.lock(path, 'unlink');
|
|
156
|
+
await this._fs.unlink(path);
|
|
157
|
+
}
|
|
172
158
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}
|
|
159
|
+
public unlinkSync(path: string): void {
|
|
160
|
+
using _ = this.lockSync(path, 'unlink');
|
|
161
|
+
return this._fs.unlinkSync(path);
|
|
162
|
+
}
|
|
178
163
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
}
|
|
164
|
+
public async rmdir(path: string): Promise<void> {
|
|
165
|
+
using _ = await this.lock(path, 'rmdir');
|
|
166
|
+
await this._fs.rmdir(path);
|
|
167
|
+
}
|
|
184
168
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
169
|
+
public rmdirSync(path: string): void {
|
|
170
|
+
using _ = this.lockSync(path, 'rmdir');
|
|
171
|
+
return this._fs.rmdirSync(path);
|
|
172
|
+
}
|
|
190
173
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
}
|
|
174
|
+
public async mkdir(path: string, mode: number): Promise<void> {
|
|
175
|
+
using _ = await this.lock(path, 'mkdir');
|
|
176
|
+
await this._fs.mkdir(path, mode);
|
|
177
|
+
}
|
|
196
178
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
}
|
|
179
|
+
public mkdirSync(path: string, mode: number): void {
|
|
180
|
+
using _ = this.lockSync(path, 'mkdir');
|
|
181
|
+
return this._fs.mkdirSync(path, mode);
|
|
182
|
+
}
|
|
202
183
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
}
|
|
184
|
+
public async readdir(path: string): Promise<string[]> {
|
|
185
|
+
using _ = await this.lock(path, 'readdir');
|
|
186
|
+
return await this._fs.readdir(path);
|
|
187
|
+
}
|
|
208
188
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
189
|
+
public readdirSync(path: string): string[] {
|
|
190
|
+
using _ = this.lockSync(path, 'readdir');
|
|
191
|
+
return this._fs.readdirSync(path);
|
|
192
|
+
}
|
|
213
193
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
194
|
+
public async exists(path: string): Promise<boolean> {
|
|
195
|
+
using _ = await this.lock(path, 'exists');
|
|
196
|
+
return await this._fs.exists(path);
|
|
197
|
+
}
|
|
218
198
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
}
|
|
199
|
+
public existsSync(path: string): boolean {
|
|
200
|
+
using _ = this.lockSync(path, 'exists');
|
|
201
|
+
return this._fs.existsSync(path);
|
|
202
|
+
}
|
|
224
203
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
}
|
|
204
|
+
public async link(srcpath: string, dstpath: string): Promise<void> {
|
|
205
|
+
using _ = await this.lock(srcpath, 'link');
|
|
206
|
+
await this._fs.link(srcpath, dstpath);
|
|
207
|
+
}
|
|
230
208
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
209
|
+
public linkSync(srcpath: string, dstpath: string): void {
|
|
210
|
+
using _ = this.lockSync(srcpath, 'link');
|
|
211
|
+
return this._fs.linkSync(srcpath, dstpath);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
public async sync(path: string, data: Uint8Array, stats: Readonly<Stats>): Promise<void> {
|
|
215
|
+
using _ = await this.lock(path, 'sync');
|
|
216
|
+
await this._fs.sync(path, data, stats);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
public syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void {
|
|
220
|
+
using _ = this.lockSync(path, 'sync');
|
|
221
|
+
return this._fs.syncSync(path, data, stats);
|
|
222
|
+
}
|
|
223
|
+
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
224
|
+
}
|
|
236
225
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
226
|
+
/**
|
|
227
|
+
* This serializes access to an underlying async filesystem.
|
|
228
|
+
* For example, on an OverlayFS instance with an async lower
|
|
229
|
+
* directory operations like rename and rmdir may involve multiple
|
|
230
|
+
* requests involving both the upper and lower filesystems -- they
|
|
231
|
+
* are not executed in a single atomic step. OverlayFS uses this
|
|
232
|
+
* to avoid having to reason about the correctness of
|
|
233
|
+
* multiple requests interleaving.
|
|
234
|
+
*
|
|
235
|
+
* Note:
|
|
236
|
+
* Instead of extending the passed class, `MutexedFS` stores it internally.
|
|
237
|
+
* This is to avoid a deadlock caused when a mathod calls another one
|
|
238
|
+
* The problem is discussed extensivly in [#78](https://github.com/zen-fs/core/issues/78)
|
|
239
|
+
* Instead of extending `FileSystem`,
|
|
240
|
+
* `MutexedFS` implements it in order to make sure all of the methods are passed through
|
|
241
|
+
*
|
|
242
|
+
* @todo Change `using _` to `using void` pending https://github.com/tc39/proposal-discard-binding
|
|
243
|
+
* @internal
|
|
244
|
+
*/
|
|
245
|
+
export function Mutexed<const T extends Concrete<typeof FileSystem>>(
|
|
246
|
+
FS: T
|
|
247
|
+
): typeof __MutexedFS<InstanceType<T>> & {
|
|
248
|
+
new (...args: ConstructorParameters<T>): __MutexedFS<InstanceType<T>>;
|
|
249
|
+
} {
|
|
250
|
+
class MutexedFS extends __MutexedFS<InstanceType<T>> {
|
|
251
|
+
public constructor(...args: ConstructorParameters<T>) {
|
|
252
|
+
super();
|
|
253
|
+
this._fs = new FS(...args) as InstanceType<T>;
|
|
241
254
|
}
|
|
242
|
-
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
243
255
|
}
|
|
244
256
|
return MutexedFS;
|
|
245
257
|
}
|
package/src/mixins/readonly.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { Cred } from '../cred.js';
|
|
2
1
|
import { Errno, ErrnoError } from '../error.js';
|
|
3
2
|
import type { File } from '../file.js';
|
|
4
3
|
import type { FileSystem, FileSystemMetadata } from '../filesystem.js';
|
|
@@ -15,18 +14,18 @@ export function Readonly<T extends typeof FileSystem>(
|
|
|
15
14
|
T,
|
|
16
15
|
{
|
|
17
16
|
metadata(): FileSystemMetadata;
|
|
18
|
-
rename(oldPath: string, newPath: string
|
|
19
|
-
renameSync(oldPath: string, newPath: string
|
|
20
|
-
createFile(path: string, flag: string, mode: number
|
|
21
|
-
createFileSync(path: string, flag: string, mode: number
|
|
22
|
-
unlink(path: string
|
|
23
|
-
unlinkSync(path: string
|
|
24
|
-
rmdir(path: string
|
|
25
|
-
rmdirSync(path: string
|
|
26
|
-
mkdir(path: string, mode: number
|
|
27
|
-
mkdirSync(path: string, mode: number
|
|
28
|
-
link(srcpath: string, dstpath: string
|
|
29
|
-
linkSync(srcpath: string, dstpath: string
|
|
17
|
+
rename(oldPath: string, newPath: string): Promise<void>;
|
|
18
|
+
renameSync(oldPath: string, newPath: string): void;
|
|
19
|
+
createFile(path: string, flag: string, mode: number): Promise<File>;
|
|
20
|
+
createFileSync(path: string, flag: string, mode: number): File;
|
|
21
|
+
unlink(path: string): Promise<void>;
|
|
22
|
+
unlinkSync(path: string): void;
|
|
23
|
+
rmdir(path: string): Promise<void>;
|
|
24
|
+
rmdirSync(path: string): void;
|
|
25
|
+
mkdir(path: string, mode: number): Promise<void>;
|
|
26
|
+
mkdirSync(path: string, mode: number): void;
|
|
27
|
+
link(srcpath: string, dstpath: string): Promise<void>;
|
|
28
|
+
linkSync(srcpath: string, dstpath: string): void;
|
|
30
29
|
sync(path: string, data: Uint8Array, stats: Readonly<Stats>): Promise<void>;
|
|
31
30
|
syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void;
|
|
32
31
|
}
|
|
@@ -36,51 +35,51 @@ export function Readonly<T extends typeof FileSystem>(
|
|
|
36
35
|
return { ...super.metadata(), readonly: true };
|
|
37
36
|
}
|
|
38
37
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
39
|
-
public async rename(oldPath: string, newPath: string
|
|
38
|
+
public async rename(oldPath: string, newPath: string): Promise<void> {
|
|
40
39
|
throw new ErrnoError(Errno.EROFS);
|
|
41
40
|
}
|
|
42
41
|
|
|
43
|
-
public renameSync(oldPath: string, newPath: string
|
|
42
|
+
public renameSync(oldPath: string, newPath: string): void {
|
|
44
43
|
throw new ErrnoError(Errno.EROFS);
|
|
45
44
|
}
|
|
46
45
|
|
|
47
|
-
public async createFile(path: string, flag: string, mode: number
|
|
46
|
+
public async createFile(path: string, flag: string, mode: number): Promise<File> {
|
|
48
47
|
throw new ErrnoError(Errno.EROFS);
|
|
49
48
|
}
|
|
50
49
|
|
|
51
|
-
public createFileSync(path: string, flag: string, mode: number
|
|
50
|
+
public createFileSync(path: string, flag: string, mode: number): File {
|
|
52
51
|
throw new ErrnoError(Errno.EROFS);
|
|
53
52
|
}
|
|
54
53
|
|
|
55
|
-
public async unlink(path: string
|
|
54
|
+
public async unlink(path: string): Promise<void> {
|
|
56
55
|
throw new ErrnoError(Errno.EROFS);
|
|
57
56
|
}
|
|
58
57
|
|
|
59
|
-
public unlinkSync(path: string
|
|
58
|
+
public unlinkSync(path: string): void {
|
|
60
59
|
throw new ErrnoError(Errno.EROFS);
|
|
61
60
|
}
|
|
62
61
|
|
|
63
|
-
public async rmdir(path: string
|
|
62
|
+
public async rmdir(path: string): Promise<void> {
|
|
64
63
|
throw new ErrnoError(Errno.EROFS);
|
|
65
64
|
}
|
|
66
65
|
|
|
67
|
-
public rmdirSync(path: string
|
|
66
|
+
public rmdirSync(path: string): void {
|
|
68
67
|
throw new ErrnoError(Errno.EROFS);
|
|
69
68
|
}
|
|
70
69
|
|
|
71
|
-
public async mkdir(path: string, mode: number
|
|
70
|
+
public async mkdir(path: string, mode: number): Promise<void> {
|
|
72
71
|
throw new ErrnoError(Errno.EROFS);
|
|
73
72
|
}
|
|
74
73
|
|
|
75
|
-
public mkdirSync(path: string, mode: number
|
|
74
|
+
public mkdirSync(path: string, mode: number): void {
|
|
76
75
|
throw new ErrnoError(Errno.EROFS);
|
|
77
76
|
}
|
|
78
77
|
|
|
79
|
-
public async link(srcpath: string, dstpath: string
|
|
78
|
+
public async link(srcpath: string, dstpath: string): Promise<void> {
|
|
80
79
|
throw new ErrnoError(Errno.EROFS);
|
|
81
80
|
}
|
|
82
81
|
|
|
83
|
-
public linkSync(srcpath: string, dstpath: string
|
|
82
|
+
public linkSync(srcpath: string, dstpath: string): void {
|
|
84
83
|
throw new ErrnoError(Errno.EROFS);
|
|
85
84
|
}
|
|
86
85
|
|
package/src/mixins/shared.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
1
2
|
/*
|
|
2
3
|
Code shared by various mixins
|
|
3
4
|
*/
|
|
@@ -9,12 +10,12 @@ import type { FileSystem } from '../filesystem.js';
|
|
|
9
10
|
* `TBase` with `TMixin` mixed-in.
|
|
10
11
|
* @internal @experimental
|
|
11
12
|
*/
|
|
12
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
13
13
|
export type Mixin<TBase extends typeof FileSystem, TMixin> = (abstract new (...args: any[]) => TMixin) & TBase;
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Asynchronous `FileSystem` methods. This is a convience type.
|
|
17
17
|
* @internal
|
|
18
18
|
*/
|
|
19
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
20
19
|
export type _AsyncFSMethods = ExtractProperties<FileSystem, (...args: any[]) => Promise<unknown>>;
|
|
20
|
+
|
|
21
|
+
export type ConcreteFS = ExtractProperties<FileSystem, any>;
|
package/src/mixins/sync.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import type { Cred } from '../cred.js';
|
|
2
1
|
import type { File } from '../file.js';
|
|
3
|
-
import type { Stats } from '../stats.js';
|
|
4
2
|
import type { FileSystem } from '../filesystem.js';
|
|
3
|
+
import type { Stats } from '../stats.js';
|
|
5
4
|
import type { Mixin, _AsyncFSMethods } from './shared.js';
|
|
6
5
|
|
|
7
6
|
/**
|
|
@@ -10,44 +9,44 @@ import type { Mixin, _AsyncFSMethods } from './shared.js';
|
|
|
10
9
|
/* eslint-disable @typescript-eslint/require-await */
|
|
11
10
|
export function Sync<T extends typeof FileSystem>(FS: T): Mixin<T, _AsyncFSMethods> {
|
|
12
11
|
abstract class SyncFS extends FS implements _AsyncFSMethods {
|
|
13
|
-
public async exists(path: string
|
|
14
|
-
return this.existsSync(path
|
|
12
|
+
public async exists(path: string): Promise<boolean> {
|
|
13
|
+
return this.existsSync(path);
|
|
15
14
|
}
|
|
16
15
|
|
|
17
|
-
public async rename(oldPath: string, newPath: string
|
|
18
|
-
return this.renameSync(oldPath, newPath
|
|
16
|
+
public async rename(oldPath: string, newPath: string): Promise<void> {
|
|
17
|
+
return this.renameSync(oldPath, newPath);
|
|
19
18
|
}
|
|
20
19
|
|
|
21
|
-
public async stat(path: string
|
|
22
|
-
return this.statSync(path
|
|
20
|
+
public async stat(path: string): Promise<Stats> {
|
|
21
|
+
return this.statSync(path);
|
|
23
22
|
}
|
|
24
23
|
|
|
25
|
-
public async createFile(path: string, flag: string, mode: number
|
|
26
|
-
return this.createFileSync(path, flag, mode
|
|
24
|
+
public async createFile(path: string, flag: string, mode: number): Promise<File> {
|
|
25
|
+
return this.createFileSync(path, flag, mode);
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
public async openFile(path: string, flag: string
|
|
30
|
-
return this.openFileSync(path, flag
|
|
28
|
+
public async openFile(path: string, flag: string): Promise<File> {
|
|
29
|
+
return this.openFileSync(path, flag);
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
public async unlink(path: string
|
|
34
|
-
return this.unlinkSync(path
|
|
32
|
+
public async unlink(path: string): Promise<void> {
|
|
33
|
+
return this.unlinkSync(path);
|
|
35
34
|
}
|
|
36
35
|
|
|
37
|
-
public async rmdir(path: string
|
|
38
|
-
return this.rmdirSync(path
|
|
36
|
+
public async rmdir(path: string): Promise<void> {
|
|
37
|
+
return this.rmdirSync(path);
|
|
39
38
|
}
|
|
40
39
|
|
|
41
|
-
public async mkdir(path: string, mode: number
|
|
42
|
-
return this.mkdirSync(path, mode
|
|
40
|
+
public async mkdir(path: string, mode: number): Promise<void> {
|
|
41
|
+
return this.mkdirSync(path, mode);
|
|
43
42
|
}
|
|
44
43
|
|
|
45
|
-
public async readdir(path: string
|
|
46
|
-
return this.readdirSync(path
|
|
44
|
+
public async readdir(path: string): Promise<string[]> {
|
|
45
|
+
return this.readdirSync(path);
|
|
47
46
|
}
|
|
48
47
|
|
|
49
|
-
public async link(srcpath: string, dstpath: string
|
|
50
|
-
return this.linkSync(srcpath, dstpath
|
|
48
|
+
public async link(srcpath: string, dstpath: string): Promise<void> {
|
|
49
|
+
return this.linkSync(srcpath, dstpath);
|
|
51
50
|
}
|
|
52
51
|
|
|
53
52
|
public async sync(path: string, data: Uint8Array, stats: Readonly<Stats>): Promise<void> {
|