@zenfs/core 0.12.1 → 0.12.3
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 +1 -1
- package/dist/backends/fetch.d.ts +1 -1
- package/dist/backends/index/fs.d.ts +2 -1
- package/dist/backends/index/index.d.ts +2 -1
- package/dist/backends/overlay.d.ts +4 -3
- package/dist/backends/overlay.js +1 -1
- package/dist/backends/port/fs.d.ts +5 -1
- package/dist/backends/port/fs.js +13 -10
- package/dist/browser.min.js +4 -8
- package/dist/browser.min.js.map +3 -3
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/cred.d.ts +2 -1
- package/dist/emulation/async.d.ts +6 -5
- package/dist/emulation/index.d.ts +1 -1
- package/dist/emulation/index.js +1 -1
- package/dist/emulation/promises.d.ts +5 -5
- package/dist/emulation/promises.js +31 -51
- package/dist/emulation/shared.d.ts +8 -2
- package/dist/emulation/shared.js +18 -1
- package/dist/emulation/streams.d.ts +1 -1
- package/dist/emulation/sync.d.ts +5 -5
- package/dist/emulation/sync.js +94 -76
- package/dist/error.d.ts +1 -1
- package/dist/error.js +1 -1
- package/dist/file.d.ts +7 -23
- package/dist/file.js +33 -80
- package/dist/filesystem.d.ts +35 -31
- package/dist/filesystem.js +10 -14
- package/dist/stats.d.ts +17 -17
- package/dist/stats.js +42 -49
- package/dist/utils.d.ts +2 -2
- package/license.md +2 -26
- package/package.json +2 -2
- package/readme.md +1 -1
- package/src/backends/backend.ts +1 -1
- package/src/backends/fetch.ts +1 -1
- package/src/backends/index/fs.ts +2 -1
- package/src/backends/index/index.ts +2 -1
- package/src/backends/overlay.ts +7 -4
- package/src/backends/port/fs.ts +14 -10
- package/src/config.ts +1 -1
- package/src/cred.ts +2 -1
- package/src/emulation/async.ts +8 -7
- package/src/emulation/index.ts +1 -1
- package/src/emulation/promises.ts +40 -54
- package/src/emulation/shared.ts +24 -3
- package/src/emulation/streams.ts +1 -1
- package/src/emulation/sync.ts +100 -87
- package/src/error.ts +1 -1
- package/src/file.ts +35 -88
- package/src/filesystem.ts +40 -32
- package/src/stats.ts +47 -59
- package/src/utils.ts +2 -2
package/src/filesystem.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { ErrnoError, Errno } from './error.js';
|
|
|
3
3
|
import { rootCred, type Cred } from './cred.js';
|
|
4
4
|
import { join } from './emulation/path.js';
|
|
5
5
|
import { PreloadFile, parseFlag, type File } from './file.js';
|
|
6
|
-
import type
|
|
6
|
+
import { ZenFsType, type Stats } from './stats.js';
|
|
7
7
|
|
|
8
8
|
export type FileContents = ArrayBufferView | string;
|
|
9
9
|
|
|
@@ -44,17 +44,35 @@ export interface FileSystemMetadata {
|
|
|
44
44
|
* @default false
|
|
45
45
|
*/
|
|
46
46
|
noAsyncCache: boolean;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* The optimal block size to use with the file system
|
|
50
|
+
* @default 4096
|
|
51
|
+
*/
|
|
52
|
+
blockSize?: number;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Total number of (file) nodes available
|
|
56
|
+
*/
|
|
57
|
+
totalNodes?: number;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Number of free (file) nodes available
|
|
61
|
+
*/
|
|
62
|
+
freeNodes?: number;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The type of the FS
|
|
66
|
+
*/
|
|
67
|
+
type: number;
|
|
47
68
|
}
|
|
48
69
|
|
|
49
70
|
/**
|
|
50
71
|
* Structure for a filesystem. All ZenFS backends must extend this.
|
|
51
72
|
*
|
|
52
|
-
* This class includes
|
|
53
|
-
*
|
|
54
|
-
* Assume the following about arguments passed to each API method:
|
|
73
|
+
* This class includes default implementations for `exists` and `existsSync`
|
|
55
74
|
*
|
|
56
|
-
*
|
|
57
|
-
* - All arguments are present. Any optional arguments at the Node API level have been passed in with their default values.
|
|
75
|
+
* If you are extending this class, note that every path is an absolute path and all arguments are present.
|
|
58
76
|
*/
|
|
59
77
|
export abstract class FileSystem {
|
|
60
78
|
/**
|
|
@@ -68,17 +86,16 @@ export abstract class FileSystem {
|
|
|
68
86
|
freeSpace: 0,
|
|
69
87
|
noResizableBuffers: false,
|
|
70
88
|
noAsyncCache: false,
|
|
89
|
+
type: ZenFsType,
|
|
71
90
|
};
|
|
72
91
|
}
|
|
73
92
|
|
|
74
|
-
|
|
75
|
-
public constructor(options?: object) {}
|
|
93
|
+
public constructor() {}
|
|
76
94
|
|
|
77
95
|
public async ready(): Promise<void> {}
|
|
78
96
|
|
|
79
97
|
/**
|
|
80
|
-
* Asynchronous rename.
|
|
81
|
-
* are given to the completion callback.
|
|
98
|
+
* Asynchronous rename.
|
|
82
99
|
*/
|
|
83
100
|
public abstract rename(oldPath: string, newPath: string, cred: Cred): Promise<void>;
|
|
84
101
|
/**
|
|
@@ -97,29 +114,27 @@ export abstract class FileSystem {
|
|
|
97
114
|
public abstract statSync(path: string, cred: Cred): Stats;
|
|
98
115
|
|
|
99
116
|
/**
|
|
100
|
-
* Opens the file at path
|
|
101
|
-
* @param
|
|
117
|
+
* Opens the file at `path` with the given flag. The file must exist.
|
|
118
|
+
* @param path The path to open.
|
|
102
119
|
* @param flag The flag to use when opening the file.
|
|
103
120
|
*/
|
|
104
121
|
public abstract openFile(path: string, flag: string, cred: Cred): Promise<File>;
|
|
105
122
|
|
|
106
123
|
/**
|
|
107
|
-
* Opens the file at path
|
|
108
|
-
* @param
|
|
124
|
+
* Opens the file at `path` with the given flag. The file must exist.
|
|
125
|
+
* @param path The path to open.
|
|
109
126
|
* @param flag The flag to use when opening the file.
|
|
110
127
|
* @return A File object corresponding to the opened file.
|
|
111
128
|
*/
|
|
112
129
|
public abstract openFileSync(path: string, flag: string, cred: Cred): File;
|
|
113
130
|
|
|
114
131
|
/**
|
|
115
|
-
* Create the file at path
|
|
116
|
-
* flag.
|
|
132
|
+
* Create the file at `path` with the given mode. Then, open it with the given flag.
|
|
117
133
|
*/
|
|
118
134
|
public abstract createFile(path: string, flag: string, mode: number, cred: Cred): Promise<File>;
|
|
119
135
|
|
|
120
136
|
/**
|
|
121
|
-
* Create the file at path
|
|
122
|
-
* flag.
|
|
137
|
+
* Create the file at `path` with the given mode. Then, open it with the given flag.
|
|
123
138
|
*/
|
|
124
139
|
public abstract createFileSync(path: string, flag: string, mode: number, cred: Cred): File;
|
|
125
140
|
|
|
@@ -142,21 +157,16 @@ export abstract class FileSystem {
|
|
|
142
157
|
public abstract rmdirSync(path: string, cred: Cred): void;
|
|
143
158
|
/**
|
|
144
159
|
* Asynchronous `mkdir`.
|
|
145
|
-
* @param mode Mode to make the directory using.
|
|
146
|
-
* the filesystem doesn't support permissions.
|
|
160
|
+
* @param mode Mode to make the directory using.
|
|
147
161
|
*/
|
|
148
162
|
public abstract mkdir(path: string, mode: number, cred: Cred): Promise<void>;
|
|
149
163
|
/**
|
|
150
164
|
* Synchronous `mkdir`.
|
|
151
|
-
* @param mode Mode to make the directory using.
|
|
152
|
-
* the filesystem doesn't support permissions.
|
|
165
|
+
* @param mode Mode to make the directory using.
|
|
153
166
|
*/
|
|
154
167
|
public abstract mkdirSync(path: string, mode: number, cred: Cred): void;
|
|
155
168
|
/**
|
|
156
169
|
* Asynchronous `readdir`. Reads the contents of a directory.
|
|
157
|
-
*
|
|
158
|
-
* The callback gets two arguments `(err, files)` where `files` is an array of
|
|
159
|
-
* the names of the files in the directory excluding `'.'` and `'..'`.
|
|
160
170
|
*/
|
|
161
171
|
public abstract readdir(path: string, cred: Cred): Promise<string[]>;
|
|
162
172
|
/**
|
|
@@ -325,13 +335,11 @@ type AsyncOperation = {
|
|
|
325
335
|
/**
|
|
326
336
|
* Async() implements synchronous methods on an asynchronous file system
|
|
327
337
|
*
|
|
328
|
-
* Implementing classes must define
|
|
329
|
-
* by:
|
|
330
|
-
*
|
|
331
|
-
*
|
|
332
|
-
*
|
|
333
|
-
* - During application loading, the contents of the async file system can be reloaded into
|
|
334
|
-
* the synchronous store, if desired.
|
|
338
|
+
* Implementing classes must define `_sync` for the synchronous file system used as a cache.
|
|
339
|
+
* Synchronous methods on an asynchronous FS are implemented by:
|
|
340
|
+
* - Performing operations over the in-memory copy,
|
|
341
|
+
* while asynchronously pipelining them to the backing store.
|
|
342
|
+
* - During loading, the contents of the async file system are eloaded into the synchronous store.
|
|
335
343
|
*
|
|
336
344
|
*/
|
|
337
345
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
package/src/stats.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type * as Node from 'fs';
|
|
2
|
-
import { Cred } from './cred.js';
|
|
3
|
-
import { S_IFDIR, S_IFLNK, S_IFMT, S_IFREG, S_IRWXG, S_IRWXO, S_IRWXU } from './emulation/constants.js';
|
|
2
|
+
import type { Cred } from './cred.js';
|
|
3
|
+
import { S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLNK, S_IFMT, S_IFREG, S_IFSOCK, S_IRWXG, S_IRWXO, S_IRWXU } from './emulation/constants.js';
|
|
4
|
+
import { size_max } from './inode.js';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Indicates the type of the given file. Applied to 'mode'.
|
|
@@ -60,21 +61,15 @@ export interface StatsLike<T extends number | bigint = number | bigint> {
|
|
|
60
61
|
* Common code used by both Stats and BigIntStats.
|
|
61
62
|
*/
|
|
62
63
|
export abstract class StatsCommon<T extends number | bigint> implements Node.StatsBase<T>, StatsLike {
|
|
63
|
-
protected abstract _isBigint:
|
|
64
|
-
|
|
65
|
-
protected get _typename(): string {
|
|
66
|
-
return this._isBigint ? 'bigint' : 'number';
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
protected get _typename_inverse(): string {
|
|
70
|
-
return this._isBigint ? 'number' : 'bigint';
|
|
71
|
-
}
|
|
64
|
+
protected abstract _isBigint: T extends bigint ? true : false;
|
|
72
65
|
|
|
73
66
|
protected _convert(arg: number | bigint | string | boolean): T {
|
|
74
67
|
return (this._isBigint ? BigInt(arg) : Number(arg)) as T;
|
|
75
68
|
}
|
|
76
69
|
|
|
77
|
-
public blocks: T
|
|
70
|
+
public get blocks(): T {
|
|
71
|
+
return this._convert(Math.ceil(Number(this.size) / 512));
|
|
72
|
+
}
|
|
78
73
|
|
|
79
74
|
/**
|
|
80
75
|
* Unix-style file mode (e.g. 0o644) that includes the type of the item.
|
|
@@ -184,17 +179,15 @@ export abstract class StatsCommon<T extends number | bigint> implements Node.Sta
|
|
|
184
179
|
* Creates a new stats instance from a stats-like object. Can be used to copy stats (note)
|
|
185
180
|
*/
|
|
186
181
|
constructor({ atimeMs, mtimeMs, ctimeMs, birthtimeMs, uid, gid, size, mode, ino }: Partial<StatsLike> = {}) {
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
this.
|
|
191
|
-
this.
|
|
192
|
-
this.
|
|
193
|
-
this.
|
|
194
|
-
this.
|
|
195
|
-
this.
|
|
196
|
-
this.size = resolveT(size, 0);
|
|
197
|
-
this.ino = resolveT(ino, 0);
|
|
182
|
+
const now = Date.now();
|
|
183
|
+
this.atimeMs = this._convert(atimeMs ?? now);
|
|
184
|
+
this.mtimeMs = this._convert(mtimeMs ?? now);
|
|
185
|
+
this.ctimeMs = this._convert(ctimeMs ?? now);
|
|
186
|
+
this.birthtimeMs = this._convert(birthtimeMs ?? now);
|
|
187
|
+
this.uid = this._convert(uid ?? 0);
|
|
188
|
+
this.gid = this._convert(gid ?? 0);
|
|
189
|
+
this.size = this._convert(size ?? 0);
|
|
190
|
+
this.ino = this._convert(ino ?? 0);
|
|
198
191
|
const itemType: FileType = Number(mode) & S_IFMT || FileType.FILE;
|
|
199
192
|
|
|
200
193
|
if (mode) {
|
|
@@ -209,8 +202,6 @@ export abstract class StatsCommon<T extends number | bigint> implements Node.Sta
|
|
|
209
202
|
this.mode = this._convert(0o777);
|
|
210
203
|
}
|
|
211
204
|
}
|
|
212
|
-
// number of 512B blocks allocated
|
|
213
|
-
this.blocks = this._convert(Math.ceil(Number(size) / 512));
|
|
214
205
|
// Check if mode also includes top-most bits, which indicate the file's type.
|
|
215
206
|
if ((this.mode & S_IFMT) == 0) {
|
|
216
207
|
this.mode = (this.mode | this._convert(itemType)) as T;
|
|
@@ -241,19 +232,19 @@ export abstract class StatsCommon<T extends number | bigint> implements Node.Sta
|
|
|
241
232
|
// Currently unsupported
|
|
242
233
|
|
|
243
234
|
public isSocket(): boolean {
|
|
244
|
-
return
|
|
235
|
+
return (this.mode & S_IFMT) === S_IFSOCK;
|
|
245
236
|
}
|
|
246
237
|
|
|
247
238
|
public isBlockDevice(): boolean {
|
|
248
|
-
return
|
|
239
|
+
return (this.mode & S_IFMT) === S_IFBLK;
|
|
249
240
|
}
|
|
250
241
|
|
|
251
242
|
public isCharacterDevice(): boolean {
|
|
252
|
-
return
|
|
243
|
+
return (this.mode & S_IFMT) === S_IFCHR;
|
|
253
244
|
}
|
|
254
245
|
|
|
255
246
|
public isFIFO(): boolean {
|
|
256
|
-
return
|
|
247
|
+
return (this.mode & S_IFMT) === S_IFIFO;
|
|
257
248
|
}
|
|
258
249
|
|
|
259
250
|
/**
|
|
@@ -315,16 +306,16 @@ export abstract class StatsCommon<T extends number | bigint> implements Node.Sta
|
|
|
315
306
|
}
|
|
316
307
|
|
|
317
308
|
public get atimeNs(): bigint {
|
|
318
|
-
return BigInt(this.atimeMs);
|
|
309
|
+
return BigInt(this.atimeMs) * 1000n;
|
|
319
310
|
}
|
|
320
311
|
public get mtimeNs(): bigint {
|
|
321
|
-
return BigInt(this.mtimeMs);
|
|
312
|
+
return BigInt(this.mtimeMs) * 1000n;
|
|
322
313
|
}
|
|
323
314
|
public get ctimeNs(): bigint {
|
|
324
|
-
return BigInt(this.ctimeMs);
|
|
315
|
+
return BigInt(this.ctimeMs) * 1000n;
|
|
325
316
|
}
|
|
326
317
|
public get birthtimeNs(): bigint {
|
|
327
|
-
return BigInt(this.birthtimeMs);
|
|
318
|
+
return BigInt(this.birthtimeMs) * 1000n;
|
|
328
319
|
}
|
|
329
320
|
}
|
|
330
321
|
|
|
@@ -334,41 +325,35 @@ export abstract class StatsCommon<T extends number | bigint> implements Node.Sta
|
|
|
334
325
|
* Attribute descriptions are from `man 2 stat'
|
|
335
326
|
* @see http://nodejs.org/api/fs.html#fs_class_fs_stats
|
|
336
327
|
* @see http://man7.org/linux/man-pages/man2/stat.2.html
|
|
328
|
+
* @internal
|
|
337
329
|
*/
|
|
338
330
|
export class Stats extends StatsCommon<number> implements Node.Stats, StatsLike {
|
|
339
|
-
protected _isBigint = false;
|
|
340
|
-
|
|
341
|
-
/**
|
|
342
|
-
* Clones the stats object.
|
|
343
|
-
* @deprecated use `new Stats(stats)`
|
|
344
|
-
*/
|
|
345
|
-
public static clone(stats: Stats): Stats {
|
|
346
|
-
return new Stats(stats);
|
|
347
|
-
}
|
|
331
|
+
protected _isBigint = false as const;
|
|
348
332
|
}
|
|
349
333
|
Stats satisfies typeof Node.Stats;
|
|
350
334
|
|
|
351
335
|
/**
|
|
352
336
|
* Stats with bigint
|
|
353
337
|
* @todo Implement with bigint instead of wrapping Stats
|
|
338
|
+
* @internal
|
|
354
339
|
*/
|
|
355
340
|
export class BigIntStats extends StatsCommon<bigint> implements Node.BigIntStats, StatsLike {
|
|
356
|
-
protected _isBigint = true;
|
|
357
|
-
|
|
358
|
-
/**
|
|
359
|
-
* Clone a stats object.
|
|
360
|
-
* @deprecated use `new BigIntStats(stats)`
|
|
361
|
-
*/
|
|
362
|
-
public static clone(stats: BigIntStats | Stats): BigIntStats {
|
|
363
|
-
return new BigIntStats(stats);
|
|
364
|
-
}
|
|
341
|
+
protected _isBigint = true as const;
|
|
365
342
|
}
|
|
366
343
|
|
|
344
|
+
/**
|
|
345
|
+
* @internal
|
|
346
|
+
*/
|
|
347
|
+
export const ZenFsType = 0x7a656e6673; // 'z' 'e' 'n' 'f' 's'
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* @hidden
|
|
351
|
+
*/
|
|
367
352
|
export class StatsFs implements Node.StatsFsBase<number> {
|
|
368
353
|
/** Type of file system. */
|
|
369
|
-
public type: number =
|
|
354
|
+
public type: number = 0x7a656e6673;
|
|
370
355
|
/** Optimal transfer block size. */
|
|
371
|
-
public bsize: number =
|
|
356
|
+
public bsize: number = 4096;
|
|
372
357
|
/** Total data blocks in file system. */
|
|
373
358
|
public blocks: number = 0;
|
|
374
359
|
/** Free blocks in file system. */
|
|
@@ -376,16 +361,19 @@ export class StatsFs implements Node.StatsFsBase<number> {
|
|
|
376
361
|
/** Available blocks for unprivileged users */
|
|
377
362
|
public bavail: number = 0;
|
|
378
363
|
/** Total file nodes in file system. */
|
|
379
|
-
public files: number =
|
|
364
|
+
public files: number = size_max;
|
|
380
365
|
/** Free file nodes in file system. */
|
|
381
|
-
public ffree: number =
|
|
366
|
+
public ffree: number = size_max;
|
|
382
367
|
}
|
|
383
368
|
|
|
369
|
+
/**
|
|
370
|
+
* @hidden
|
|
371
|
+
*/
|
|
384
372
|
export class BigIntStatsFs implements Node.StatsFsBase<bigint> {
|
|
385
373
|
/** Type of file system. */
|
|
386
|
-
public type: bigint =
|
|
374
|
+
public type: bigint = 0x7a656e6673n;
|
|
387
375
|
/** Optimal transfer block size. */
|
|
388
|
-
public bsize: bigint =
|
|
376
|
+
public bsize: bigint = 4096n;
|
|
389
377
|
/** Total data blocks in file system. */
|
|
390
378
|
public blocks: bigint = 0n;
|
|
391
379
|
/** Free blocks in file system. */
|
|
@@ -393,7 +381,7 @@ export class BigIntStatsFs implements Node.StatsFsBase<bigint> {
|
|
|
393
381
|
/** Available blocks for unprivileged users */
|
|
394
382
|
public bavail: bigint = 0n;
|
|
395
383
|
/** Total file nodes in file system. */
|
|
396
|
-
public files: bigint =
|
|
384
|
+
public files: bigint = BigInt(size_max);
|
|
397
385
|
/** Free file nodes in file system. */
|
|
398
|
-
public ffree: bigint =
|
|
386
|
+
public ffree: bigint = BigInt(size_max);
|
|
399
387
|
}
|
package/src/utils.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { OptionalTuple } from 'utilium';
|
|
2
2
|
import { ErrnoError, Errno } from './error.js';
|
|
3
|
-
import { Cred } from './cred.js';
|
|
3
|
+
import type { Cred } from './cred.js';
|
|
4
4
|
import { dirname, resolve, type AbsolutePath } from './emulation/path.js';
|
|
5
|
-
import { FileSystem } from './filesystem.js';
|
|
5
|
+
import type { FileSystem } from './filesystem.js';
|
|
6
6
|
import type * as fs from 'node:fs';
|
|
7
7
|
|
|
8
8
|
declare global {
|