@zenfs/core 0.12.0 → 0.12.2
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 +15 -5
- package/dist/backends/index/fs.d.ts +1 -0
- package/dist/backends/index/index.d.ts +5 -0
- package/dist/backends/index/index.js +1 -0
- package/dist/backends/overlay.js +1 -1
- package/dist/backends/port/fs.d.ts +3 -1
- package/dist/browser.min.js +4 -4
- package/dist/browser.min.js.map +4 -4
- package/dist/config.d.ts +33 -11
- package/dist/config.js +16 -7
- package/dist/emulation/async.d.ts +5 -4
- package/dist/emulation/async.js +3 -2
- package/dist/emulation/index.d.ts +1 -1
- package/dist/emulation/index.js +1 -1
- package/dist/emulation/path.d.ts +4 -1
- package/dist/emulation/promises.d.ts +4 -4
- package/dist/emulation/promises.js +27 -27
- package/dist/emulation/shared.d.ts +6 -0
- package/dist/emulation/shared.js +19 -1
- package/dist/emulation/sync.d.ts +4 -4
- package/dist/emulation/sync.js +76 -38
- package/dist/file.d.ts +5 -10
- package/dist/file.js +38 -55
- package/dist/filesystem.d.ts +45 -3
- package/dist/filesystem.js +37 -8
- package/dist/stats.d.ts +16 -16
- package/dist/stats.js +42 -49
- package/package.json +2 -2
- package/src/backends/backend.ts +15 -6
- package/src/backends/index/index.ts +5 -0
- package/src/backends/overlay.ts +1 -1
- package/src/config.ts +62 -21
- package/src/emulation/async.ts +19 -18
- package/src/emulation/index.ts +1 -1
- package/src/emulation/path.ts +4 -1
- package/src/emulation/promises.ts +33 -31
- package/src/emulation/shared.ts +22 -1
- package/src/emulation/sync.ts +83 -54
- package/src/error.ts +1 -1
- package/src/file.ts +39 -57
- package/src/filesystem.ts +133 -51
- package/src/stats.ts +48 -60
package/dist/file.js
CHANGED
|
@@ -183,7 +183,7 @@ export class PreloadFile extends File {
|
|
|
183
183
|
/**
|
|
184
184
|
* Path to the file
|
|
185
185
|
*/
|
|
186
|
-
path, flag, stats, _buffer = new Uint8Array(new ArrayBuffer(0, { maxByteLength: size_max }))) {
|
|
186
|
+
path, flag, stats, _buffer = new Uint8Array(new ArrayBuffer(0, fs.metadata().noResizableBuffers ? {} : { maxByteLength: size_max }))) {
|
|
187
187
|
super();
|
|
188
188
|
this.fs = fs;
|
|
189
189
|
this.path = path;
|
|
@@ -191,7 +191,7 @@ export class PreloadFile extends File {
|
|
|
191
191
|
this.stats = stats;
|
|
192
192
|
this._buffer = _buffer;
|
|
193
193
|
this._position = 0;
|
|
194
|
-
this.
|
|
194
|
+
this.dirty = false;
|
|
195
195
|
/*
|
|
196
196
|
Note:
|
|
197
197
|
This invariant is *not* maintained once the file starts getting modified.
|
|
@@ -203,7 +203,7 @@ export class PreloadFile extends File {
|
|
|
203
203
|
if (isReadable(this.flag)) {
|
|
204
204
|
throw new Error(`Size mismatch: buffer length ${_buffer.byteLength}, stats size ${this.stats.size}`);
|
|
205
205
|
}
|
|
206
|
-
this.
|
|
206
|
+
this.dirty = true;
|
|
207
207
|
}
|
|
208
208
|
/**
|
|
209
209
|
* Get the underlying buffer for this file. Mutating not recommended and will mess up dirty tracking.
|
|
@@ -234,18 +234,18 @@ export class PreloadFile extends File {
|
|
|
234
234
|
this._position = newPos;
|
|
235
235
|
}
|
|
236
236
|
async sync() {
|
|
237
|
-
if (!this.
|
|
237
|
+
if (!this.dirty) {
|
|
238
238
|
return;
|
|
239
239
|
}
|
|
240
240
|
await this.fs.sync(this.path, this._buffer, this.stats);
|
|
241
|
-
this.
|
|
241
|
+
this.dirty = false;
|
|
242
242
|
}
|
|
243
243
|
syncSync() {
|
|
244
|
-
if (!this.
|
|
244
|
+
if (!this.dirty) {
|
|
245
245
|
return;
|
|
246
246
|
}
|
|
247
247
|
this.fs.syncSync(this.path, this._buffer, this.stats);
|
|
248
|
-
this.
|
|
248
|
+
this.dirty = false;
|
|
249
249
|
}
|
|
250
250
|
async close() {
|
|
251
251
|
await this.sync();
|
|
@@ -267,39 +267,32 @@ export class PreloadFile extends File {
|
|
|
267
267
|
}
|
|
268
268
|
/**
|
|
269
269
|
* Asynchronous truncate.
|
|
270
|
-
* @param
|
|
270
|
+
* @param length
|
|
271
271
|
*/
|
|
272
|
-
async truncate(
|
|
273
|
-
this.truncateSync(
|
|
274
|
-
|
|
275
|
-
return this.sync();
|
|
276
|
-
}
|
|
272
|
+
async truncate(length) {
|
|
273
|
+
this.truncateSync(length);
|
|
274
|
+
return this.sync();
|
|
277
275
|
}
|
|
278
276
|
/**
|
|
279
277
|
* Synchronous truncate.
|
|
280
|
-
* @param
|
|
278
|
+
* @param length
|
|
281
279
|
*/
|
|
282
|
-
truncateSync(
|
|
283
|
-
this.
|
|
280
|
+
truncateSync(length) {
|
|
281
|
+
this.dirty = true;
|
|
284
282
|
if (!isWriteable(this.flag)) {
|
|
285
283
|
throw new ErrnoError(Errno.EPERM, 'File not opened with a writeable mode.');
|
|
286
284
|
}
|
|
287
285
|
this.stats.mtimeMs = Date.now();
|
|
288
|
-
if (
|
|
289
|
-
const
|
|
290
|
-
// Write will set stats.size
|
|
291
|
-
this.writeSync(
|
|
292
|
-
if (isSynchronous(this.flag)) {
|
|
293
|
-
this.syncSync();
|
|
294
|
-
}
|
|
286
|
+
if (length > this._buffer.length) {
|
|
287
|
+
const data = new Uint8Array(length - this._buffer.length);
|
|
288
|
+
// Write will set stats.size and handle syncing.
|
|
289
|
+
this.writeSync(data, 0, data.length, this._buffer.length);
|
|
295
290
|
return;
|
|
296
291
|
}
|
|
297
|
-
this.stats.size =
|
|
298
|
-
// Truncate
|
|
299
|
-
this._buffer = this._buffer.
|
|
300
|
-
|
|
301
|
-
this.syncSync();
|
|
302
|
-
}
|
|
292
|
+
this.stats.size = length;
|
|
293
|
+
// Truncate.
|
|
294
|
+
this._buffer = this._buffer.slice(0, length);
|
|
295
|
+
this.syncSync();
|
|
303
296
|
}
|
|
304
297
|
/**
|
|
305
298
|
* Write buffer to the file.
|
|
@@ -332,21 +325,21 @@ export class PreloadFile extends File {
|
|
|
332
325
|
* @returns bytes written
|
|
333
326
|
*/
|
|
334
327
|
writeSync(buffer, offset = 0, length = this.stats.size, position = 0) {
|
|
335
|
-
this.
|
|
328
|
+
this.dirty = true;
|
|
336
329
|
position ?? (position = this.position);
|
|
337
330
|
if (!isWriteable(this.flag)) {
|
|
338
331
|
throw new ErrnoError(Errno.EPERM, 'File not opened with a writeable mode.');
|
|
339
332
|
}
|
|
340
|
-
const
|
|
341
|
-
if (
|
|
342
|
-
this.stats.size =
|
|
343
|
-
if (
|
|
344
|
-
if (this._buffer.buffer.resizable && this._buffer.buffer.maxByteLength <=
|
|
345
|
-
this._buffer.buffer.resize(
|
|
333
|
+
const end = position + length;
|
|
334
|
+
if (end > this.stats.size) {
|
|
335
|
+
this.stats.size = end;
|
|
336
|
+
if (end > this._buffer.byteLength) {
|
|
337
|
+
if (this._buffer.buffer.resizable && this._buffer.buffer.maxByteLength <= end) {
|
|
338
|
+
this._buffer.buffer.resize(end);
|
|
346
339
|
}
|
|
347
340
|
else {
|
|
348
341
|
// Extend the buffer!
|
|
349
|
-
const newBuffer = new Uint8Array(new ArrayBuffer(
|
|
342
|
+
const newBuffer = new Uint8Array(new ArrayBuffer(end, this.fs.metadata().noResizableBuffers ? {} : { maxByteLength: size_max }));
|
|
350
343
|
newBuffer.set(this._buffer);
|
|
351
344
|
this._buffer = newBuffer;
|
|
352
345
|
}
|
|
@@ -356,11 +349,8 @@ export class PreloadFile extends File {
|
|
|
356
349
|
this._buffer.set(slice, position);
|
|
357
350
|
const bytesWritten = slice.byteLength;
|
|
358
351
|
this.stats.mtimeMs = Date.now();
|
|
359
|
-
if (isSynchronous(this.flag)) {
|
|
360
|
-
this.syncSync();
|
|
361
|
-
return bytesWritten;
|
|
362
|
-
}
|
|
363
352
|
this.position = position + bytesWritten;
|
|
353
|
+
this.syncSync();
|
|
364
354
|
return bytesWritten;
|
|
365
355
|
}
|
|
366
356
|
/**
|
|
@@ -392,6 +382,7 @@ export class PreloadFile extends File {
|
|
|
392
382
|
if (!isReadable(this.flag)) {
|
|
393
383
|
throw new ErrnoError(Errno.EPERM, 'File not opened with a readable mode.');
|
|
394
384
|
}
|
|
385
|
+
this.dirty = true;
|
|
395
386
|
position ?? (position = this.position);
|
|
396
387
|
let end = position + length;
|
|
397
388
|
if (end > this.stats.size) {
|
|
@@ -400,6 +391,7 @@ export class PreloadFile extends File {
|
|
|
400
391
|
this.stats.atimeMs = Date.now();
|
|
401
392
|
this._position = end;
|
|
402
393
|
const bytesRead = end - position;
|
|
394
|
+
this.syncSync();
|
|
403
395
|
if (bytesRead == 0) {
|
|
404
396
|
// No copy/read. Return immediatly for better performance
|
|
405
397
|
return bytesRead;
|
|
@@ -419,7 +411,7 @@ export class PreloadFile extends File {
|
|
|
419
411
|
* @param mode
|
|
420
412
|
*/
|
|
421
413
|
chmodSync(mode) {
|
|
422
|
-
this.
|
|
414
|
+
this.dirty = true;
|
|
423
415
|
this.stats.chmod(mode);
|
|
424
416
|
this.syncSync();
|
|
425
417
|
}
|
|
@@ -437,7 +429,7 @@ export class PreloadFile extends File {
|
|
|
437
429
|
* @param gid
|
|
438
430
|
*/
|
|
439
431
|
chownSync(uid, gid) {
|
|
440
|
-
this.
|
|
432
|
+
this.dirty = true;
|
|
441
433
|
this.stats.chown(uid, gid);
|
|
442
434
|
this.syncSync();
|
|
443
435
|
}
|
|
@@ -445,27 +437,18 @@ export class PreloadFile extends File {
|
|
|
445
437
|
this.utimesSync(atime, mtime);
|
|
446
438
|
}
|
|
447
439
|
utimesSync(atime, mtime) {
|
|
448
|
-
this.
|
|
440
|
+
this.dirty = true;
|
|
449
441
|
this.stats.atime = atime;
|
|
450
442
|
this.stats.mtime = mtime;
|
|
451
443
|
this.syncSync();
|
|
452
444
|
}
|
|
453
|
-
isDirty() {
|
|
454
|
-
return this._dirty;
|
|
455
|
-
}
|
|
456
|
-
/**
|
|
457
|
-
* Resets the dirty bit. Should only be called after a sync has completed successfully.
|
|
458
|
-
*/
|
|
459
|
-
resetDirty() {
|
|
460
|
-
this._dirty = false;
|
|
461
|
-
}
|
|
462
445
|
_setType(type) {
|
|
463
|
-
this.
|
|
446
|
+
this.dirty = true;
|
|
464
447
|
this.stats.mode = (this.stats.mode & ~S_IFMT) | type;
|
|
465
448
|
return this.sync();
|
|
466
449
|
}
|
|
467
450
|
_setTypeSync(type) {
|
|
468
|
-
this.
|
|
451
|
+
this.dirty = true;
|
|
469
452
|
this.stats.mode = (this.stats.mode & ~S_IFMT) | type;
|
|
470
453
|
this.syncSync();
|
|
471
454
|
}
|
package/dist/filesystem.d.ts
CHANGED
|
@@ -22,6 +22,35 @@ export interface FileSystemMetadata {
|
|
|
22
22
|
* The available space
|
|
23
23
|
*/
|
|
24
24
|
freeSpace: number;
|
|
25
|
+
/**
|
|
26
|
+
* If set, disables File from using a resizable array buffer.
|
|
27
|
+
* @default false
|
|
28
|
+
*/
|
|
29
|
+
noResizableBuffers: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* If set, disables caching on async file systems.
|
|
32
|
+
* This means *sync operations will not work*.
|
|
33
|
+
* It has no affect on sync file systems.
|
|
34
|
+
* @default false
|
|
35
|
+
*/
|
|
36
|
+
noAsyncCache: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* The optimal block size to use with the file system
|
|
39
|
+
* @default 4096
|
|
40
|
+
*/
|
|
41
|
+
blockSize?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Total number of (file) nodes available
|
|
44
|
+
*/
|
|
45
|
+
totalNodes?: number;
|
|
46
|
+
/**
|
|
47
|
+
* Number of free (file) nodes available
|
|
48
|
+
*/
|
|
49
|
+
freeNodes?: number;
|
|
50
|
+
/**
|
|
51
|
+
* The type of the FS
|
|
52
|
+
*/
|
|
53
|
+
type?: number;
|
|
25
54
|
}
|
|
26
55
|
/**
|
|
27
56
|
* Structure for a filesystem. All ZenFS backends must extend this.
|
|
@@ -35,10 +64,15 @@ export interface FileSystemMetadata {
|
|
|
35
64
|
*/
|
|
36
65
|
export declare abstract class FileSystem {
|
|
37
66
|
/**
|
|
38
|
-
*
|
|
67
|
+
* Numeric type, used for statfs
|
|
68
|
+
* @internal @protected
|
|
69
|
+
*/
|
|
70
|
+
_type?: number;
|
|
71
|
+
/**
|
|
72
|
+
* Get metadata about the current file system
|
|
39
73
|
*/
|
|
40
74
|
metadata(): FileSystemMetadata;
|
|
41
|
-
constructor(
|
|
75
|
+
constructor();
|
|
42
76
|
ready(): Promise<void>;
|
|
43
77
|
/**
|
|
44
78
|
* Asynchronous rename. No arguments other than a possible exception
|
|
@@ -168,12 +202,20 @@ declare abstract class SyncFS extends FileSystem {
|
|
|
168
202
|
export declare function Sync<T extends abstract new (...args: any[]) => FileSystem>(FS: T): (abstract new (...args: any[]) => SyncFS) & T;
|
|
169
203
|
/**
|
|
170
204
|
* @internal
|
|
205
|
+
* Note: `_*` should be treated like protected.
|
|
206
|
+
* Protected can't be used because of TS quirks however.
|
|
171
207
|
*/
|
|
172
208
|
declare abstract class AsyncFS extends FileSystem {
|
|
173
209
|
/**
|
|
210
|
+
* @access protected
|
|
211
|
+
* @hidden
|
|
212
|
+
*/
|
|
213
|
+
_disableSync: boolean;
|
|
214
|
+
/**
|
|
215
|
+
* @access protected
|
|
174
216
|
* @hidden
|
|
175
217
|
*/
|
|
176
|
-
abstract _sync
|
|
218
|
+
abstract _sync?: FileSystem;
|
|
177
219
|
queueDone(): Promise<void>;
|
|
178
220
|
metadata(): FileSystemMetadata;
|
|
179
221
|
ready(): Promise<void>;
|
package/dist/filesystem.js
CHANGED
|
@@ -14,7 +14,7 @@ import { PreloadFile, parseFlag } from './file.js';
|
|
|
14
14
|
*/
|
|
15
15
|
export class FileSystem {
|
|
16
16
|
/**
|
|
17
|
-
* Get metadata about the current file
|
|
17
|
+
* Get metadata about the current file system
|
|
18
18
|
*/
|
|
19
19
|
metadata() {
|
|
20
20
|
return {
|
|
@@ -22,11 +22,12 @@ export class FileSystem {
|
|
|
22
22
|
readonly: false,
|
|
23
23
|
totalSpace: 0,
|
|
24
24
|
freeSpace: 0,
|
|
25
|
+
noResizableBuffers: false,
|
|
26
|
+
noAsyncCache: false,
|
|
27
|
+
type: this._type,
|
|
25
28
|
};
|
|
26
29
|
}
|
|
27
|
-
constructor(
|
|
28
|
-
// unused
|
|
29
|
-
}
|
|
30
|
+
constructor() { }
|
|
30
31
|
async ready() { }
|
|
31
32
|
/**
|
|
32
33
|
* Test whether or not the given path exists by checking with the file system.
|
|
@@ -37,7 +38,7 @@ export class FileSystem {
|
|
|
37
38
|
return true;
|
|
38
39
|
}
|
|
39
40
|
catch (e) {
|
|
40
|
-
return
|
|
41
|
+
return e.code != 'ENOENT';
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
/**
|
|
@@ -49,7 +50,7 @@ export class FileSystem {
|
|
|
49
50
|
return true;
|
|
50
51
|
}
|
|
51
52
|
catch (e) {
|
|
52
|
-
return
|
|
53
|
+
return e.code != 'ENOENT';
|
|
53
54
|
}
|
|
54
55
|
}
|
|
55
56
|
}
|
|
@@ -117,6 +118,7 @@ export function Async(FS) {
|
|
|
117
118
|
*/
|
|
118
119
|
this._queue = [];
|
|
119
120
|
this._isInitialized = false;
|
|
121
|
+
this._disableSync = false;
|
|
120
122
|
}
|
|
121
123
|
get _queueRunning() {
|
|
122
124
|
return !!this._queue.length;
|
|
@@ -128,11 +130,12 @@ export function Async(FS) {
|
|
|
128
130
|
});
|
|
129
131
|
}
|
|
130
132
|
async ready() {
|
|
131
|
-
await this._sync.ready();
|
|
132
133
|
await super.ready();
|
|
133
|
-
if (this._isInitialized) {
|
|
134
|
+
if (this._isInitialized || this._disableSync) {
|
|
134
135
|
return;
|
|
135
136
|
}
|
|
137
|
+
this.checkSync();
|
|
138
|
+
await this._sync.ready();
|
|
136
139
|
try {
|
|
137
140
|
await this.crossCopy('/');
|
|
138
141
|
this._isInitialized = true;
|
|
@@ -142,19 +145,37 @@ export function Async(FS) {
|
|
|
142
145
|
throw e;
|
|
143
146
|
}
|
|
144
147
|
}
|
|
148
|
+
metadata() {
|
|
149
|
+
return {
|
|
150
|
+
...super.metadata(),
|
|
151
|
+
noAsyncCache: this._disableSync,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
checkSync(path, syscall) {
|
|
155
|
+
if (this._disableSync) {
|
|
156
|
+
throw new ErrnoError(Errno.ENOTSUP, 'Sync caching has been disabled for this async file system', path, syscall);
|
|
157
|
+
}
|
|
158
|
+
if (!this._sync) {
|
|
159
|
+
throw new ErrnoError(Errno.ENOTSUP, 'No sync cache is attached to this async file system', path, syscall);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
145
162
|
renameSync(oldPath, newPath, cred) {
|
|
163
|
+
this.checkSync(oldPath, 'rename');
|
|
146
164
|
this._sync.renameSync(oldPath, newPath, cred);
|
|
147
165
|
this.queue('rename', oldPath, newPath, cred);
|
|
148
166
|
}
|
|
149
167
|
statSync(path, cred) {
|
|
168
|
+
this.checkSync(path, 'stat');
|
|
150
169
|
return this._sync.statSync(path, cred);
|
|
151
170
|
}
|
|
152
171
|
createFileSync(path, flag, mode, cred) {
|
|
172
|
+
this.checkSync(path, 'createFile');
|
|
153
173
|
this._sync.createFileSync(path, flag, mode, cred);
|
|
154
174
|
this.queue('createFile', path, flag, mode, cred);
|
|
155
175
|
return this.openFileSync(path, flag, cred);
|
|
156
176
|
}
|
|
157
177
|
openFileSync(path, flag, cred) {
|
|
178
|
+
this.checkSync(path, 'openFile');
|
|
158
179
|
const file = this._sync.openFileSync(path, flag, cred);
|
|
159
180
|
const stats = file.statSync();
|
|
160
181
|
const buffer = new Uint8Array(stats.size);
|
|
@@ -162,35 +183,43 @@ export function Async(FS) {
|
|
|
162
183
|
return new PreloadFile(this, path, flag, stats, buffer);
|
|
163
184
|
}
|
|
164
185
|
unlinkSync(path, cred) {
|
|
186
|
+
this.checkSync(path, 'unlinkSync');
|
|
165
187
|
this._sync.unlinkSync(path, cred);
|
|
166
188
|
this.queue('unlink', path, cred);
|
|
167
189
|
}
|
|
168
190
|
rmdirSync(path, cred) {
|
|
191
|
+
this.checkSync(path, 'rmdir');
|
|
169
192
|
this._sync.rmdirSync(path, cred);
|
|
170
193
|
this.queue('rmdir', path, cred);
|
|
171
194
|
}
|
|
172
195
|
mkdirSync(path, mode, cred) {
|
|
196
|
+
this.checkSync(path, 'mkdir');
|
|
173
197
|
this._sync.mkdirSync(path, mode, cred);
|
|
174
198
|
this.queue('mkdir', path, mode, cred);
|
|
175
199
|
}
|
|
176
200
|
readdirSync(path, cred) {
|
|
201
|
+
this.checkSync(path, 'readdir');
|
|
177
202
|
return this._sync.readdirSync(path, cred);
|
|
178
203
|
}
|
|
179
204
|
linkSync(srcpath, dstpath, cred) {
|
|
205
|
+
this.checkSync(srcpath, 'link');
|
|
180
206
|
this._sync.linkSync(srcpath, dstpath, cred);
|
|
181
207
|
this.queue('link', srcpath, dstpath, cred);
|
|
182
208
|
}
|
|
183
209
|
syncSync(path, data, stats) {
|
|
210
|
+
this.checkSync(path, 'sync');
|
|
184
211
|
this._sync.syncSync(path, data, stats);
|
|
185
212
|
this.queue('sync', path, data, stats);
|
|
186
213
|
}
|
|
187
214
|
existsSync(path, cred) {
|
|
215
|
+
this.checkSync(path, 'exists');
|
|
188
216
|
return this._sync.existsSync(path, cred);
|
|
189
217
|
}
|
|
190
218
|
/**
|
|
191
219
|
* @internal
|
|
192
220
|
*/
|
|
193
221
|
async crossCopy(path) {
|
|
222
|
+
this.checkSync(path, 'crossCopy');
|
|
194
223
|
const stats = await this.stat(path, rootCred);
|
|
195
224
|
if (stats.isDirectory()) {
|
|
196
225
|
if (path !== '/') {
|
package/dist/stats.d.ts
CHANGED
|
@@ -57,11 +57,9 @@ export interface StatsLike<T extends number | bigint = number | bigint> {
|
|
|
57
57
|
* Common code used by both Stats and BigIntStats.
|
|
58
58
|
*/
|
|
59
59
|
export declare abstract class StatsCommon<T extends number | bigint> implements Node.StatsBase<T>, StatsLike {
|
|
60
|
-
protected abstract _isBigint:
|
|
61
|
-
protected get _typename(): string;
|
|
62
|
-
protected get _typename_inverse(): string;
|
|
60
|
+
protected abstract _isBigint: T extends bigint ? true : false;
|
|
63
61
|
protected _convert(arg: number | bigint | string | boolean): T;
|
|
64
|
-
blocks: T;
|
|
62
|
+
get blocks(): T;
|
|
65
63
|
/**
|
|
66
64
|
* Unix-style file mode (e.g. 0o644) that includes the type of the item.
|
|
67
65
|
* Type of the item can be FILE, DIRECTORY, SYMLINK, or SOCKET
|
|
@@ -184,27 +182,26 @@ export declare abstract class StatsCommon<T extends number | bigint> implements
|
|
|
184
182
|
* Attribute descriptions are from `man 2 stat'
|
|
185
183
|
* @see http://nodejs.org/api/fs.html#fs_class_fs_stats
|
|
186
184
|
* @see http://man7.org/linux/man-pages/man2/stat.2.html
|
|
185
|
+
* @internal
|
|
187
186
|
*/
|
|
188
187
|
export declare class Stats extends StatsCommon<number> implements Node.Stats, StatsLike {
|
|
189
|
-
protected _isBigint:
|
|
190
|
-
/**
|
|
191
|
-
* Clones the stats object.
|
|
192
|
-
* @deprecated use `new Stats(stats)`
|
|
193
|
-
*/
|
|
194
|
-
static clone(stats: Stats): Stats;
|
|
188
|
+
protected _isBigint: false;
|
|
195
189
|
}
|
|
196
190
|
/**
|
|
197
191
|
* Stats with bigint
|
|
198
192
|
* @todo Implement with bigint instead of wrapping Stats
|
|
193
|
+
* @internal
|
|
199
194
|
*/
|
|
200
195
|
export declare class BigIntStats extends StatsCommon<bigint> implements Node.BigIntStats, StatsLike {
|
|
201
|
-
protected _isBigint:
|
|
202
|
-
/**
|
|
203
|
-
* Clone a stats object.
|
|
204
|
-
* @deprecated use `new BigIntStats(stats)`
|
|
205
|
-
*/
|
|
206
|
-
static clone(stats: BigIntStats | Stats): BigIntStats;
|
|
196
|
+
protected _isBigint: true;
|
|
207
197
|
}
|
|
198
|
+
/**
|
|
199
|
+
* @internal
|
|
200
|
+
*/
|
|
201
|
+
export declare const ZenFsType = 525687744115;
|
|
202
|
+
/**
|
|
203
|
+
* @hidden
|
|
204
|
+
*/
|
|
208
205
|
export declare class StatsFs implements Node.StatsFsBase<number> {
|
|
209
206
|
/** Type of file system. */
|
|
210
207
|
type: number;
|
|
@@ -221,6 +218,9 @@ export declare class StatsFs implements Node.StatsFsBase<number> {
|
|
|
221
218
|
/** Free file nodes in file system. */
|
|
222
219
|
ffree: number;
|
|
223
220
|
}
|
|
221
|
+
/**
|
|
222
|
+
* @hidden
|
|
223
|
+
*/
|
|
224
224
|
export declare class BigIntStatsFs implements Node.StatsFsBase<bigint> {
|
|
225
225
|
/** Type of file system. */
|
|
226
226
|
type: bigint;
|
package/dist/stats.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { S_IFDIR, S_IFLNK, S_IFMT, S_IFREG, S_IRWXG, S_IRWXO, S_IRWXU } from './emulation/constants.js';
|
|
1
|
+
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';
|
|
2
|
+
import { size_max } from './inode.js';
|
|
2
3
|
/**
|
|
3
4
|
* Indicates the type of the given file. Applied to 'mode'.
|
|
4
5
|
*/
|
|
@@ -13,15 +14,12 @@ export var FileType;
|
|
|
13
14
|
* Common code used by both Stats and BigIntStats.
|
|
14
15
|
*/
|
|
15
16
|
export class StatsCommon {
|
|
16
|
-
get _typename() {
|
|
17
|
-
return this._isBigint ? 'bigint' : 'number';
|
|
18
|
-
}
|
|
19
|
-
get _typename_inverse() {
|
|
20
|
-
return this._isBigint ? 'number' : 'bigint';
|
|
21
|
-
}
|
|
22
17
|
_convert(arg) {
|
|
23
18
|
return (this._isBigint ? BigInt(arg) : Number(arg));
|
|
24
19
|
}
|
|
20
|
+
get blocks() {
|
|
21
|
+
return this._convert(Math.ceil(Number(this.size) / 512));
|
|
22
|
+
}
|
|
25
23
|
get atime() {
|
|
26
24
|
return new Date(Number(this.atimeMs));
|
|
27
25
|
}
|
|
@@ -78,16 +76,15 @@ export class StatsCommon {
|
|
|
78
76
|
* group ID of owner
|
|
79
77
|
*/
|
|
80
78
|
this.gid = this._convert(0);
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
this.
|
|
84
|
-
this.
|
|
85
|
-
this.
|
|
86
|
-
this.
|
|
87
|
-
this.
|
|
88
|
-
this.
|
|
89
|
-
this.
|
|
90
|
-
this.ino = resolveT(ino, 0);
|
|
79
|
+
const now = Date.now();
|
|
80
|
+
this.atimeMs = this._convert(atimeMs ?? now);
|
|
81
|
+
this.mtimeMs = this._convert(mtimeMs ?? now);
|
|
82
|
+
this.ctimeMs = this._convert(ctimeMs ?? now);
|
|
83
|
+
this.birthtimeMs = this._convert(birthtimeMs ?? now);
|
|
84
|
+
this.uid = this._convert(uid ?? 0);
|
|
85
|
+
this.gid = this._convert(gid ?? 0);
|
|
86
|
+
this.size = this._convert(size ?? 0);
|
|
87
|
+
this.ino = this._convert(ino ?? 0);
|
|
91
88
|
const itemType = Number(mode) & S_IFMT || FileType.FILE;
|
|
92
89
|
if (mode) {
|
|
93
90
|
this.mode = this._convert(mode);
|
|
@@ -102,8 +99,6 @@ export class StatsCommon {
|
|
|
102
99
|
this.mode = this._convert(0o777);
|
|
103
100
|
}
|
|
104
101
|
}
|
|
105
|
-
// number of 512B blocks allocated
|
|
106
|
-
this.blocks = this._convert(Math.ceil(Number(size) / 512));
|
|
107
102
|
// Check if mode also includes top-most bits, which indicate the file's type.
|
|
108
103
|
if ((this.mode & S_IFMT) == 0) {
|
|
109
104
|
this.mode = (this.mode | this._convert(itemType));
|
|
@@ -129,16 +124,16 @@ export class StatsCommon {
|
|
|
129
124
|
}
|
|
130
125
|
// Currently unsupported
|
|
131
126
|
isSocket() {
|
|
132
|
-
return
|
|
127
|
+
return (this.mode & S_IFMT) === S_IFSOCK;
|
|
133
128
|
}
|
|
134
129
|
isBlockDevice() {
|
|
135
|
-
return
|
|
130
|
+
return (this.mode & S_IFMT) === S_IFBLK;
|
|
136
131
|
}
|
|
137
132
|
isCharacterDevice() {
|
|
138
|
-
return
|
|
133
|
+
return (this.mode & S_IFMT) === S_IFCHR;
|
|
139
134
|
}
|
|
140
135
|
isFIFO() {
|
|
141
|
-
return
|
|
136
|
+
return (this.mode & S_IFMT) === S_IFIFO;
|
|
142
137
|
}
|
|
143
138
|
/**
|
|
144
139
|
* Checks if a given user/group has access to this item
|
|
@@ -194,16 +189,16 @@ export class StatsCommon {
|
|
|
194
189
|
}
|
|
195
190
|
}
|
|
196
191
|
get atimeNs() {
|
|
197
|
-
return BigInt(this.atimeMs);
|
|
192
|
+
return BigInt(this.atimeMs) * 1000n;
|
|
198
193
|
}
|
|
199
194
|
get mtimeNs() {
|
|
200
|
-
return BigInt(this.mtimeMs);
|
|
195
|
+
return BigInt(this.mtimeMs) * 1000n;
|
|
201
196
|
}
|
|
202
197
|
get ctimeNs() {
|
|
203
|
-
return BigInt(this.ctimeMs);
|
|
198
|
+
return BigInt(this.ctimeMs) * 1000n;
|
|
204
199
|
}
|
|
205
200
|
get birthtimeNs() {
|
|
206
|
-
return BigInt(this.birthtimeMs);
|
|
201
|
+
return BigInt(this.birthtimeMs) * 1000n;
|
|
207
202
|
}
|
|
208
203
|
}
|
|
209
204
|
/**
|
|
@@ -212,44 +207,39 @@ export class StatsCommon {
|
|
|
212
207
|
* Attribute descriptions are from `man 2 stat'
|
|
213
208
|
* @see http://nodejs.org/api/fs.html#fs_class_fs_stats
|
|
214
209
|
* @see http://man7.org/linux/man-pages/man2/stat.2.html
|
|
210
|
+
* @internal
|
|
215
211
|
*/
|
|
216
212
|
export class Stats extends StatsCommon {
|
|
217
213
|
constructor() {
|
|
218
214
|
super(...arguments);
|
|
219
215
|
this._isBigint = false;
|
|
220
216
|
}
|
|
221
|
-
/**
|
|
222
|
-
* Clones the stats object.
|
|
223
|
-
* @deprecated use `new Stats(stats)`
|
|
224
|
-
*/
|
|
225
|
-
static clone(stats) {
|
|
226
|
-
return new Stats(stats);
|
|
227
|
-
}
|
|
228
217
|
}
|
|
229
218
|
Stats;
|
|
230
219
|
/**
|
|
231
220
|
* Stats with bigint
|
|
232
221
|
* @todo Implement with bigint instead of wrapping Stats
|
|
222
|
+
* @internal
|
|
233
223
|
*/
|
|
234
224
|
export class BigIntStats extends StatsCommon {
|
|
235
225
|
constructor() {
|
|
236
226
|
super(...arguments);
|
|
237
227
|
this._isBigint = true;
|
|
238
228
|
}
|
|
239
|
-
/**
|
|
240
|
-
* Clone a stats object.
|
|
241
|
-
* @deprecated use `new BigIntStats(stats)`
|
|
242
|
-
*/
|
|
243
|
-
static clone(stats) {
|
|
244
|
-
return new BigIntStats(stats);
|
|
245
|
-
}
|
|
246
229
|
}
|
|
230
|
+
/**
|
|
231
|
+
* @internal
|
|
232
|
+
*/
|
|
233
|
+
export const ZenFsType = 0x7a656e6673; // 'z' 'e' 'n' 'f' 's'
|
|
234
|
+
/**
|
|
235
|
+
* @hidden
|
|
236
|
+
*/
|
|
247
237
|
export class StatsFs {
|
|
248
238
|
constructor() {
|
|
249
239
|
/** Type of file system. */
|
|
250
|
-
this.type =
|
|
240
|
+
this.type = 0x7a656e6673;
|
|
251
241
|
/** Optimal transfer block size. */
|
|
252
|
-
this.bsize =
|
|
242
|
+
this.bsize = 4096;
|
|
253
243
|
/** Total data blocks in file system. */
|
|
254
244
|
this.blocks = 0;
|
|
255
245
|
/** Free blocks in file system. */
|
|
@@ -257,17 +247,20 @@ export class StatsFs {
|
|
|
257
247
|
/** Available blocks for unprivileged users */
|
|
258
248
|
this.bavail = 0;
|
|
259
249
|
/** Total file nodes in file system. */
|
|
260
|
-
this.files =
|
|
250
|
+
this.files = size_max;
|
|
261
251
|
/** Free file nodes in file system. */
|
|
262
|
-
this.ffree =
|
|
252
|
+
this.ffree = size_max;
|
|
263
253
|
}
|
|
264
254
|
}
|
|
255
|
+
/**
|
|
256
|
+
* @hidden
|
|
257
|
+
*/
|
|
265
258
|
export class BigIntStatsFs {
|
|
266
259
|
constructor() {
|
|
267
260
|
/** Type of file system. */
|
|
268
|
-
this.type =
|
|
261
|
+
this.type = 0x7a656e6673n;
|
|
269
262
|
/** Optimal transfer block size. */
|
|
270
|
-
this.bsize =
|
|
263
|
+
this.bsize = 4096n;
|
|
271
264
|
/** Total data blocks in file system. */
|
|
272
265
|
this.blocks = 0n;
|
|
273
266
|
/** Free blocks in file system. */
|
|
@@ -275,8 +268,8 @@ export class BigIntStatsFs {
|
|
|
275
268
|
/** Available blocks for unprivileged users */
|
|
276
269
|
this.bavail = 0n;
|
|
277
270
|
/** Total file nodes in file system. */
|
|
278
|
-
this.files =
|
|
271
|
+
this.files = BigInt(size_max);
|
|
279
272
|
/** Free file nodes in file system. */
|
|
280
|
-
this.ffree =
|
|
273
|
+
this.ffree = BigInt(size_max);
|
|
281
274
|
}
|
|
282
275
|
}
|