@zenfs/core 1.7.2 → 1.8.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.js +3 -4
- package/dist/backends/fetch.d.ts +17 -18
- package/dist/backends/fetch.js +95 -58
- package/dist/backends/index.d.ts +2 -1
- package/dist/backends/index.js +2 -1
- package/dist/backends/memory.d.ts +1 -1
- package/dist/backends/overlay.d.ts +7 -2
- package/dist/backends/overlay.js +32 -9
- package/dist/backends/passthrough.d.ts +4 -0
- package/dist/backends/passthrough.js +128 -0
- package/dist/backends/port/fs.d.ts +9 -44
- package/dist/backends/port/fs.js +93 -116
- package/dist/backends/port/rpc.d.ts +8 -5
- package/dist/backends/port/rpc.js +9 -7
- package/dist/backends/store/file_index.d.ts +38 -0
- package/dist/backends/store/file_index.js +76 -0
- package/dist/backends/store/fs.d.ts +55 -34
- package/dist/backends/store/fs.js +417 -233
- package/dist/backends/store/index_fs.d.ts +34 -0
- package/dist/backends/store/index_fs.js +67 -0
- package/dist/backends/store/inode.d.ts +26 -8
- package/dist/backends/store/inode.js +92 -91
- package/dist/backends/store/simple.d.ts +20 -20
- package/dist/backends/store/simple.js +3 -4
- package/dist/backends/store/store.d.ts +12 -12
- package/dist/backends/store/store.js +4 -6
- package/dist/devices.d.ts +11 -10
- package/dist/devices.js +15 -11
- package/dist/file.d.ts +111 -7
- package/dist/file.js +319 -71
- package/dist/filesystem.d.ts +22 -4
- package/dist/mixins/mutexed.d.ts +7 -2
- package/dist/mixins/mutexed.js +56 -0
- package/dist/mixins/sync.d.ts +1 -1
- package/dist/stats.d.ts +12 -6
- package/dist/stats.js +14 -6
- package/dist/utils.d.ts +17 -3
- package/dist/utils.js +32 -10
- package/dist/vfs/constants.d.ts +2 -2
- package/dist/vfs/constants.js +2 -2
- package/dist/vfs/dir.js +3 -1
- package/dist/vfs/index.js +4 -1
- package/dist/vfs/promises.js +31 -11
- package/dist/vfs/shared.js +2 -0
- package/dist/vfs/sync.js +25 -13
- package/dist/vfs/types.d.ts +15 -0
- package/package.json +2 -3
- package/readme.md +2 -2
- package/scripts/test.js +73 -11
- package/tests/common/mutex.test.ts +1 -1
- package/tests/fetch/run.sh +16 -0
- package/tests/fetch/server.ts +49 -0
- package/tests/fetch/setup.ts +13 -0
- package/tests/fs/read.test.ts +10 -10
- package/tests/fs/times.test.ts +2 -2
- package/tests/setup/index.ts +38 -0
- package/tests/setup/port.ts +15 -0
- package/dist/backends/file_index.d.ts +0 -63
- package/dist/backends/file_index.js +0 -163
- package/tests/common/async.test.ts +0 -31
- package/tests/setup/cow+fetch.ts +0 -45
- /package/tests/fs/{appendFile.test.ts → append.test.ts} +0 -0
package/dist/devices.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type { FileReadResult } from '
|
|
1
|
+
import type { FileReadResult } from './file.js';
|
|
2
|
+
import type { InodeLike } from './backends/index.js';
|
|
2
3
|
import { InMemoryStore } from './backends/memory.js';
|
|
3
4
|
import { StoreFS } from './backends/store/fs.js';
|
|
4
5
|
import { File } from './file.js';
|
|
5
|
-
import type {
|
|
6
|
+
import type { CreationOptions } from './filesystem.js';
|
|
6
7
|
import { Stats } from './stats.js';
|
|
7
8
|
/**
|
|
8
9
|
* A device
|
|
@@ -18,7 +19,7 @@ export interface Device<TData = any> {
|
|
|
18
19
|
/**
|
|
19
20
|
* Which inode the device is assigned
|
|
20
21
|
*/
|
|
21
|
-
ino:
|
|
22
|
+
ino: number;
|
|
22
23
|
/**
|
|
23
24
|
* Data associated with a device.
|
|
24
25
|
* This is meant to be used by device drivers.
|
|
@@ -55,7 +56,7 @@ export interface DeviceDriver<TData = any> {
|
|
|
55
56
|
* Initializes a new device.
|
|
56
57
|
* @returns `Device.data`
|
|
57
58
|
*/
|
|
58
|
-
init?(ino:
|
|
59
|
+
init?(ino: number, options: object): {
|
|
59
60
|
data?: TData;
|
|
60
61
|
minor?: number;
|
|
61
62
|
major?: number;
|
|
@@ -94,11 +95,11 @@ export declare class DeviceFile<TData = any> extends File {
|
|
|
94
95
|
position: number;
|
|
95
96
|
constructor(fs: DeviceFS, path: string, device: Device<TData>);
|
|
96
97
|
get driver(): DeviceDriver<TData>;
|
|
97
|
-
protected get stats(): Partial<
|
|
98
|
+
protected get stats(): Partial<InodeLike>;
|
|
98
99
|
stat(): Promise<Stats>;
|
|
99
100
|
statSync(): Stats;
|
|
100
101
|
readSync(buffer: ArrayBufferView, offset?: number, length?: number, position?: number): number;
|
|
101
|
-
read<TBuffer extends
|
|
102
|
+
read<TBuffer extends ArrayBufferView>(buffer: TBuffer, offset?: number, length?: number): Promise<FileReadResult<TBuffer>>;
|
|
102
103
|
writeSync(buffer: Uint8Array, offset?: number, length?: number, position?: number): number;
|
|
103
104
|
write(buffer: Uint8Array, offset?: number, length?: number, position?: number): Promise<number>;
|
|
104
105
|
truncate(length: number): Promise<void>;
|
|
@@ -142,14 +143,14 @@ export declare class DeviceFS extends StoreFS<InMemoryStore> {
|
|
|
142
143
|
statSync(path: string): Stats;
|
|
143
144
|
openFile(path: string, flag: string): Promise<File>;
|
|
144
145
|
openFileSync(path: string, flag: string): File;
|
|
145
|
-
createFile(path: string, flag: string, mode: number): Promise<File>;
|
|
146
|
-
createFileSync(path: string, flag: string, mode: number): File;
|
|
146
|
+
createFile(path: string, flag: string, mode: number, options: CreationOptions): Promise<File>;
|
|
147
|
+
createFileSync(path: string, flag: string, mode: number, options: CreationOptions): File;
|
|
147
148
|
unlink(path: string): Promise<void>;
|
|
148
149
|
unlinkSync(path: string): void;
|
|
149
150
|
rmdir(path: string): Promise<void>;
|
|
150
151
|
rmdirSync(path: string): void;
|
|
151
|
-
mkdir(path: string, mode: number): Promise<void>;
|
|
152
|
-
mkdirSync(path: string, mode: number): void;
|
|
152
|
+
mkdir(path: string, mode: number, options: CreationOptions): Promise<void>;
|
|
153
|
+
mkdirSync(path: string, mode: number, options: CreationOptions): void;
|
|
153
154
|
readdir(path: string): Promise<string[]>;
|
|
154
155
|
readdirSync(path: string): string[];
|
|
155
156
|
link(target: string, link: string): Promise<void>;
|
package/dist/devices.js
CHANGED
|
@@ -58,7 +58,7 @@ import { StoreFS } from './backends/store/fs.js';
|
|
|
58
58
|
import { Errno, ErrnoError } from './error.js';
|
|
59
59
|
import { File } from './file.js';
|
|
60
60
|
import { Stats } from './stats.js';
|
|
61
|
-
import { decodeUTF8 } from './utils.js';
|
|
61
|
+
import { canary, decodeUTF8 } from './utils.js';
|
|
62
62
|
import { S_IFBLK, S_IFCHR } from './vfs/constants.js';
|
|
63
63
|
import { basename, dirname } from './vfs/path.js';
|
|
64
64
|
/**
|
|
@@ -159,14 +159,17 @@ export class DeviceFS extends StoreFS {
|
|
|
159
159
|
* Creates a new device at `path` relative to the `DeviceFS` root.
|
|
160
160
|
* @deprecated
|
|
161
161
|
*/
|
|
162
|
+
/* node:coverage disable */
|
|
162
163
|
createDevice(path, driver, options = {}) {
|
|
163
164
|
var _a;
|
|
164
165
|
if (this.existsSync(path)) {
|
|
165
166
|
throw ErrnoError.With('EEXIST', path, 'mknod');
|
|
166
167
|
}
|
|
167
|
-
let ino =
|
|
168
|
+
let ino = 1;
|
|
169
|
+
const silence = canary(path, 'mknod');
|
|
168
170
|
while (this.store.has(ino))
|
|
169
171
|
ino++;
|
|
172
|
+
silence();
|
|
170
173
|
const dev = {
|
|
171
174
|
driver,
|
|
172
175
|
ino,
|
|
@@ -178,6 +181,7 @@ export class DeviceFS extends StoreFS {
|
|
|
178
181
|
this.devices.set(path, dev);
|
|
179
182
|
return dev;
|
|
180
183
|
}
|
|
184
|
+
/* node:coverage enable */
|
|
181
185
|
devicesWithDriver(driver, forceIdentity) {
|
|
182
186
|
if (forceIdentity && typeof driver == 'string') {
|
|
183
187
|
throw new ErrnoError(Errno.EINVAL, 'Can not fetch devices using only a driver name');
|
|
@@ -197,7 +201,7 @@ export class DeviceFS extends StoreFS {
|
|
|
197
201
|
*/
|
|
198
202
|
_createDevice(driver, options = {}) {
|
|
199
203
|
var _a;
|
|
200
|
-
let ino =
|
|
204
|
+
let ino = 1;
|
|
201
205
|
while (this.store.has(ino))
|
|
202
206
|
ino++;
|
|
203
207
|
const dev = {
|
|
@@ -295,17 +299,17 @@ export class DeviceFS extends StoreFS {
|
|
|
295
299
|
}
|
|
296
300
|
return super.openFileSync(path, flag);
|
|
297
301
|
}
|
|
298
|
-
async createFile(path, flag, mode) {
|
|
302
|
+
async createFile(path, flag, mode, options) {
|
|
299
303
|
if (this.devices.has(path)) {
|
|
300
304
|
throw ErrnoError.With('EEXIST', path, 'createFile');
|
|
301
305
|
}
|
|
302
|
-
return super.createFile(path, flag, mode);
|
|
306
|
+
return super.createFile(path, flag, mode, options);
|
|
303
307
|
}
|
|
304
|
-
createFileSync(path, flag, mode) {
|
|
308
|
+
createFileSync(path, flag, mode, options) {
|
|
305
309
|
if (this.devices.has(path)) {
|
|
306
310
|
throw ErrnoError.With('EEXIST', path, 'createFile');
|
|
307
311
|
}
|
|
308
|
-
return super.createFileSync(path, flag, mode);
|
|
312
|
+
return super.createFileSync(path, flag, mode, options);
|
|
309
313
|
}
|
|
310
314
|
async unlink(path) {
|
|
311
315
|
if (this.devices.has(path)) {
|
|
@@ -325,17 +329,17 @@ export class DeviceFS extends StoreFS {
|
|
|
325
329
|
rmdirSync(path) {
|
|
326
330
|
return super.rmdirSync(path);
|
|
327
331
|
}
|
|
328
|
-
async mkdir(path, mode) {
|
|
332
|
+
async mkdir(path, mode, options) {
|
|
329
333
|
if (this.devices.has(path)) {
|
|
330
334
|
throw ErrnoError.With('EEXIST', path, 'mkdir');
|
|
331
335
|
}
|
|
332
|
-
return super.mkdir(path, mode);
|
|
336
|
+
return super.mkdir(path, mode, options);
|
|
333
337
|
}
|
|
334
|
-
mkdirSync(path, mode) {
|
|
338
|
+
mkdirSync(path, mode, options) {
|
|
335
339
|
if (this.devices.has(path)) {
|
|
336
340
|
throw ErrnoError.With('EEXIST', path, 'mkdir');
|
|
337
341
|
}
|
|
338
|
-
return super.mkdirSync(path, mode);
|
|
342
|
+
return super.mkdirSync(path, mode, options);
|
|
339
343
|
}
|
|
340
344
|
async readdir(path) {
|
|
341
345
|
const entries = await super.readdir(path);
|
package/dist/file.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import type { FileReadResult } from 'node:fs/promises';
|
|
2
1
|
import type { FileSystem } from './filesystem.js';
|
|
3
2
|
import './polyfills.js';
|
|
4
|
-
import { Stats } from './stats.js';
|
|
3
|
+
import { Stats, type StatsLike } from './stats.js';
|
|
5
4
|
export declare function parseFlag(flag: string | number): string;
|
|
6
5
|
export declare function flagToString(flag: number): string;
|
|
7
6
|
export declare function flagToNumber(flag: string): number;
|
|
@@ -16,6 +15,10 @@ export declare function isTruncating(flag: string): boolean;
|
|
|
16
15
|
export declare function isAppendable(flag: string): boolean;
|
|
17
16
|
export declare function isSynchronous(flag: string): boolean;
|
|
18
17
|
export declare function isExclusive(flag: string): boolean;
|
|
18
|
+
export interface FileReadResult<T extends ArrayBufferView> {
|
|
19
|
+
bytesRead: number;
|
|
20
|
+
buffer: T;
|
|
21
|
+
}
|
|
19
22
|
export declare abstract class File<FS extends FileSystem = FileSystem> {
|
|
20
23
|
/**
|
|
21
24
|
* @internal
|
|
@@ -71,7 +74,7 @@ export declare abstract class File<FS extends FileSystem = FileSystem> {
|
|
|
71
74
|
* If position is null, data will be read from the current file position.
|
|
72
75
|
* @returns Promise resolving to the new length of the buffer
|
|
73
76
|
*/
|
|
74
|
-
abstract read<TBuffer extends
|
|
77
|
+
abstract read<TBuffer extends ArrayBufferView>(buffer: TBuffer, offset?: number, length?: number, position?: number): Promise<FileReadResult<TBuffer>>;
|
|
75
78
|
/**
|
|
76
79
|
* Read data from the file.
|
|
77
80
|
* @param buffer The buffer that the data will be written to.
|
|
@@ -96,11 +99,11 @@ export declare abstract class File<FS extends FileSystem = FileSystem> {
|
|
|
96
99
|
/**
|
|
97
100
|
* Change the file timestamps of the file.
|
|
98
101
|
*/
|
|
99
|
-
abstract utimes(atime:
|
|
102
|
+
abstract utimes(atime: number, mtime: number): Promise<void>;
|
|
100
103
|
/**
|
|
101
104
|
* Change the file timestamps of the file.
|
|
102
105
|
*/
|
|
103
|
-
abstract utimesSync(atime:
|
|
106
|
+
abstract utimesSync(atime: number, mtime: number): void;
|
|
104
107
|
}
|
|
105
108
|
/**
|
|
106
109
|
* An implementation of `File` that operates completely in-memory.
|
|
@@ -209,11 +212,12 @@ export declare class PreloadFile<FS extends FileSystem> extends File<FS> {
|
|
|
209
212
|
chmodSync(mode: number): void;
|
|
210
213
|
chown(uid: number, gid: number): Promise<void>;
|
|
211
214
|
chownSync(uid: number, gid: number): void;
|
|
212
|
-
utimes(atime:
|
|
213
|
-
utimesSync(atime:
|
|
215
|
+
utimes(atime: number, mtime: number): Promise<void>;
|
|
216
|
+
utimesSync(atime: number, mtime: number): void;
|
|
214
217
|
}
|
|
215
218
|
/**
|
|
216
219
|
* For the file systems which do not sync to anything.
|
|
220
|
+
* @deprecated
|
|
217
221
|
*/
|
|
218
222
|
export declare class NoSyncFile<T extends FileSystem> extends PreloadFile<T> {
|
|
219
223
|
sync(): Promise<void>;
|
|
@@ -221,3 +225,103 @@ export declare class NoSyncFile<T extends FileSystem> extends PreloadFile<T> {
|
|
|
221
225
|
close(): Promise<void>;
|
|
222
226
|
closeSync(): void;
|
|
223
227
|
}
|
|
228
|
+
/**
|
|
229
|
+
* An implementation of `File` that uses the FS
|
|
230
|
+
*/
|
|
231
|
+
export declare class LazyFile<FS extends FileSystem> extends File<FS> {
|
|
232
|
+
readonly flag: string;
|
|
233
|
+
readonly stats: StatsLike<number>;
|
|
234
|
+
protected _buffer?: Uint8Array;
|
|
235
|
+
/**
|
|
236
|
+
* Current position
|
|
237
|
+
*/
|
|
238
|
+
protected _position: number;
|
|
239
|
+
/**
|
|
240
|
+
* Get the current file position.
|
|
241
|
+
*
|
|
242
|
+
* We emulate the following bug mentioned in the Node documentation:
|
|
243
|
+
*
|
|
244
|
+
* On Linux, positional writes don't work when the file is opened in append mode.
|
|
245
|
+
* The kernel ignores the position argument and always appends the data to the end of the file.
|
|
246
|
+
* @returns The current file position.
|
|
247
|
+
*/
|
|
248
|
+
get position(): number;
|
|
249
|
+
set position(value: number);
|
|
250
|
+
/**
|
|
251
|
+
* Whether the file has changes which have not been written to the FS
|
|
252
|
+
*/
|
|
253
|
+
protected dirty: boolean;
|
|
254
|
+
/**
|
|
255
|
+
* Whether the file is open or closed
|
|
256
|
+
*/
|
|
257
|
+
protected closed: boolean;
|
|
258
|
+
/**
|
|
259
|
+
* Creates a file with `path` and, optionally, the given contents.
|
|
260
|
+
* Note that, if contents is specified, it will be mutated by the file.
|
|
261
|
+
*/
|
|
262
|
+
constructor(fs: FS, path: string, flag: string, stats: StatsLike<number>);
|
|
263
|
+
sync(): Promise<void>;
|
|
264
|
+
syncSync(): void;
|
|
265
|
+
close(): Promise<void>;
|
|
266
|
+
closeSync(): void;
|
|
267
|
+
/**
|
|
268
|
+
* Cleans up. This will *not* sync the file data to the FS
|
|
269
|
+
*/
|
|
270
|
+
protected dispose(force?: boolean): void;
|
|
271
|
+
stat(): Promise<Stats>;
|
|
272
|
+
statSync(): Stats;
|
|
273
|
+
truncate(length: number): Promise<void>;
|
|
274
|
+
truncateSync(length: number): void;
|
|
275
|
+
protected prepareWrite(buffer: Uint8Array, offset: number, length: number, position: number): Uint8Array;
|
|
276
|
+
/**
|
|
277
|
+
* Write buffer to the file.
|
|
278
|
+
* @param buffer Uint8Array containing the data to write to the file.
|
|
279
|
+
* @param offset Offset in the buffer to start reading data from.
|
|
280
|
+
* @param length The amount of bytes to write to the file.
|
|
281
|
+
* @param position Offset from the beginning of the file where this data should be written.
|
|
282
|
+
* If position is null, the data will be written at the current position.
|
|
283
|
+
*/
|
|
284
|
+
write(buffer: Uint8Array, offset?: number, length?: number, position?: number): Promise<number>;
|
|
285
|
+
/**
|
|
286
|
+
* Write buffer to the file.
|
|
287
|
+
* @param buffer Uint8Array containing the data to write to the file.
|
|
288
|
+
* @param offset Offset in the buffer to start reading data from.
|
|
289
|
+
* @param length The amount of bytes to write to the file.
|
|
290
|
+
* @param position Offset from the beginning of the file where this data should be written.
|
|
291
|
+
* If position is null, the data will be written at the current position.
|
|
292
|
+
* @returns bytes written
|
|
293
|
+
*/
|
|
294
|
+
writeSync(buffer: Uint8Array, offset?: number, length?: number, position?: number): number;
|
|
295
|
+
/**
|
|
296
|
+
* Computes position information for reading
|
|
297
|
+
*/
|
|
298
|
+
protected prepareRead(length: number, position: number): number;
|
|
299
|
+
/**
|
|
300
|
+
* Read data from the file.
|
|
301
|
+
* @param buffer The buffer that the data will be written to.
|
|
302
|
+
* @param offset The offset within the buffer where writing will start.
|
|
303
|
+
* @param length An integer specifying the number of bytes to read.
|
|
304
|
+
* @param position An integer specifying where to begin reading from in the file.
|
|
305
|
+
* If position is unset, data will be read from the current file position.
|
|
306
|
+
*/
|
|
307
|
+
read<TBuffer extends ArrayBufferView>(buffer: TBuffer, offset?: number, length?: number, position?: number): Promise<{
|
|
308
|
+
bytesRead: number;
|
|
309
|
+
buffer: TBuffer;
|
|
310
|
+
}>;
|
|
311
|
+
/**
|
|
312
|
+
* Read data from the file.
|
|
313
|
+
* @param buffer The buffer that the data will be written to.
|
|
314
|
+
* @param offset The offset within the buffer where writing will start.
|
|
315
|
+
* @param length An integer specifying the number of bytes to read.
|
|
316
|
+
* @param position An integer specifying where to begin reading from in the file.
|
|
317
|
+
* If position is null, data will be read from the current file position.
|
|
318
|
+
* @returns number of bytes written
|
|
319
|
+
*/
|
|
320
|
+
readSync(buffer: ArrayBufferView, offset?: number, length?: number, position?: number): number;
|
|
321
|
+
chmod(mode: number): Promise<void>;
|
|
322
|
+
chmodSync(mode: number): void;
|
|
323
|
+
chown(uid: number, gid: number): Promise<void>;
|
|
324
|
+
chownSync(uid: number, gid: number): void;
|
|
325
|
+
utimes(atime: number, mtime: number): Promise<void>;
|
|
326
|
+
utimesSync(atime: number, mtime: number): void;
|
|
327
|
+
}
|