@zenfs/core 2.2.3 → 2.3.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 +6 -9
- package/dist/backends/cow.js +4 -4
- package/dist/backends/fetch.js +8 -6
- package/dist/backends/memory.js +4 -2
- package/dist/backends/passthrough.js +2 -0
- package/dist/backends/port.d.ts +16 -89
- package/dist/backends/port.js +35 -171
- package/dist/backends/single_buffer.d.ts +4 -2
- package/dist/backends/single_buffer.js +169 -196
- package/dist/backends/store/fs.js +50 -73
- package/dist/backends/store/map.js +1 -2
- package/dist/backends/store/store.js +23 -27
- package/dist/config.js +2 -3
- package/dist/context.js +2 -2
- package/dist/internal/devices.js +7 -10
- package/dist/internal/file_index.js +3 -8
- package/dist/internal/filesystem.js +19 -12
- package/dist/internal/index_fs.js +3 -4
- package/dist/internal/inode.d.ts +2 -0
- package/dist/internal/inode.js +148 -185
- package/dist/internal/rpc.d.ts +143 -0
- package/dist/internal/rpc.js +251 -0
- package/dist/mixins/async.js +5 -6
- package/dist/mixins/mutexed.js +16 -10
- package/dist/path.js +3 -4
- package/dist/polyfills.js +51 -22
- package/dist/readline.js +32 -30
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +11 -5
- package/dist/vfs/acl.d.ts +2 -0
- package/dist/vfs/acl.js +48 -66
- package/dist/vfs/async.js +4 -4
- package/dist/vfs/dir.js +12 -8
- package/dist/vfs/file.js +22 -18
- package/dist/vfs/ioctl.js +39 -62
- package/dist/vfs/promises.js +48 -39
- package/dist/vfs/shared.js +4 -5
- package/dist/vfs/stats.js +104 -77
- package/dist/vfs/streams.js +11 -8
- package/dist/vfs/sync.js +23 -26
- package/dist/vfs/watchers.js +9 -3
- package/dist/vfs/xattr.js +6 -12
- package/package.json +1 -1
- package/scripts/test.js +14 -7
- package/tests/backend/fetch.test.ts +14 -14
- package/tests/backend/port.test.ts +25 -17
- package/tests/common/handle.test.ts +5 -3
- package/tests/fetch/run.sh +2 -1
- package/tests/fs/scaling.test.ts +32 -0
- package/tests/fs/watch.test.ts +2 -5
- package/tests/setup/single-buffer.ts +1 -1
- package/tests/tsconfig.json +3 -2
- package/types/uint8array.d.ts +64 -0
package/dist/vfs/promises.js
CHANGED
|
@@ -70,6 +70,13 @@ import { ReadStream, WriteStream } from './streams.js';
|
|
|
70
70
|
import { emitChange, FSWatcher } from './watchers.js';
|
|
71
71
|
export * as constants from './constants.js';
|
|
72
72
|
export class FileHandle {
|
|
73
|
+
context;
|
|
74
|
+
fd;
|
|
75
|
+
_buffer;
|
|
76
|
+
/**
|
|
77
|
+
* Current position
|
|
78
|
+
*/
|
|
79
|
+
_position = 0;
|
|
73
80
|
/**
|
|
74
81
|
* Get the current file position.
|
|
75
82
|
*
|
|
@@ -85,21 +92,27 @@ export class FileHandle {
|
|
|
85
92
|
set position(value) {
|
|
86
93
|
this._position = value;
|
|
87
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Whether the file has changes which have not been written to the FS
|
|
97
|
+
*/
|
|
98
|
+
dirty = false;
|
|
99
|
+
/**
|
|
100
|
+
* Whether the file is open or closed
|
|
101
|
+
*/
|
|
102
|
+
closed = false;
|
|
103
|
+
/** The path relative to the context's root */
|
|
104
|
+
path;
|
|
105
|
+
/** The internal FS associated with the handle */
|
|
106
|
+
fs;
|
|
107
|
+
/** The path relative to the `FileSystem`'s root */
|
|
108
|
+
internalPath;
|
|
109
|
+
/** The flag the handle was opened with */
|
|
110
|
+
flag;
|
|
111
|
+
/** Stats for the handle */
|
|
112
|
+
inode;
|
|
88
113
|
constructor(context, fd) {
|
|
89
114
|
this.context = context;
|
|
90
115
|
this.fd = fd;
|
|
91
|
-
/**
|
|
92
|
-
* Current position
|
|
93
|
-
*/
|
|
94
|
-
this._position = 0;
|
|
95
|
-
/**
|
|
96
|
-
* Whether the file has changes which have not been written to the FS
|
|
97
|
-
*/
|
|
98
|
-
this.dirty = false;
|
|
99
|
-
/**
|
|
100
|
-
* Whether the file is open or closed
|
|
101
|
-
*/
|
|
102
|
-
this.closed = false;
|
|
103
116
|
const sync = fromFD(context, fd);
|
|
104
117
|
Object.assign(this, pick(sync, 'path', 'fs', 'internalPath', 'flag', 'inode'));
|
|
105
118
|
}
|
|
@@ -253,9 +266,9 @@ export class FileHandle {
|
|
|
253
266
|
buffer = buffer.buffer;
|
|
254
267
|
}
|
|
255
268
|
const pos = Number.isSafeInteger(position) ? position : this.position;
|
|
256
|
-
buffer
|
|
257
|
-
offset
|
|
258
|
-
return this._read(buffer, offset, length
|
|
269
|
+
buffer ||= new Uint8Array(this.inode.size);
|
|
270
|
+
offset ??= 0;
|
|
271
|
+
return this._read(buffer, offset, length ?? buffer.byteLength - offset, pos);
|
|
259
272
|
}
|
|
260
273
|
async readFile(_options) {
|
|
261
274
|
const options = normalizeOptions(_options, null, 'r', 0o444);
|
|
@@ -309,7 +322,7 @@ export class FileHandle {
|
|
|
309
322
|
throw UV('EBADF', 'stat', this.path);
|
|
310
323
|
if (checkAccess && !hasAccess(this.context, this.inode, constants.R_OK))
|
|
311
324
|
throw UV('EACCES', 'stat', this.path);
|
|
312
|
-
return
|
|
325
|
+
return opts?.bigint ? new BigIntStats(this.inode) : new Stats(this.inode);
|
|
313
326
|
}
|
|
314
327
|
/**
|
|
315
328
|
* Write buffer to the file.
|
|
@@ -362,11 +375,11 @@ export class FileHandle {
|
|
|
362
375
|
}
|
|
363
376
|
else {
|
|
364
377
|
buffer = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
365
|
-
offset = options
|
|
378
|
+
offset = options ?? 0;
|
|
366
379
|
length = typeof lenOrEnc == 'number' ? lenOrEnc : buffer.byteLength;
|
|
367
380
|
position = typeof position === 'number' ? position : null;
|
|
368
381
|
}
|
|
369
|
-
position
|
|
382
|
+
position ??= this.position;
|
|
370
383
|
const bytesWritten = await this._write(buffer, offset, length, position);
|
|
371
384
|
this._emitChange();
|
|
372
385
|
return { buffer: data, bytesWritten };
|
|
@@ -516,7 +529,7 @@ export async function stat(path, options) {
|
|
|
516
529
|
const stats = await fs.stat(resolved).catch(rethrow($ex));
|
|
517
530
|
if (checkAccess && !hasAccess(this, stats, constants.R_OK))
|
|
518
531
|
throw UV('EACCES', $ex);
|
|
519
|
-
return
|
|
532
|
+
return options?.bigint ? new BigIntStats(stats) : new Stats(stats);
|
|
520
533
|
}
|
|
521
534
|
stat;
|
|
522
535
|
export async function lstat(path, options) {
|
|
@@ -526,7 +539,7 @@ export async function lstat(path, options) {
|
|
|
526
539
|
const stats = await fs.stat(resolved).catch(rethrow($ex));
|
|
527
540
|
if (checkAccess && !hasAccess(this, stats, constants.R_OK))
|
|
528
541
|
throw UV('EACCES', $ex);
|
|
529
|
-
return
|
|
542
|
+
return options?.bigint ? new BigIntStats(stats) : new Stats(stats);
|
|
530
543
|
}
|
|
531
544
|
lstat;
|
|
532
545
|
export async function truncate(path, len = 0) {
|
|
@@ -562,7 +575,6 @@ unlink;
|
|
|
562
575
|
* @internal
|
|
563
576
|
*/
|
|
564
577
|
async function _open($, path, opt) {
|
|
565
|
-
var _a;
|
|
566
578
|
path = normalizePath(path);
|
|
567
579
|
const mode = normalizeMode(opt.mode, 0o644), flag = flags.parse(opt.flag);
|
|
568
580
|
const $ex = { syscall: 'open', path };
|
|
@@ -578,7 +590,7 @@ async function _open($, path, opt) {
|
|
|
578
590
|
throw UV('ENOTDIR', 'open', dirname(path));
|
|
579
591
|
if (!opt.allowDirectory && mode & constants.S_IFDIR)
|
|
580
592
|
throw UV('EISDIR', 'open', path);
|
|
581
|
-
const { euid: uid, egid: gid } =
|
|
593
|
+
const { euid: uid, egid: gid } = $?.credentials ?? defaultContext.credentials;
|
|
582
594
|
const inode = await fs.createFile(resolved, {
|
|
583
595
|
mode,
|
|
584
596
|
uid: parentStats.mode & constants.S_ISUID ? parentStats.uid : uid,
|
|
@@ -699,10 +711,9 @@ export async function rmdir(path) {
|
|
|
699
711
|
}
|
|
700
712
|
rmdir;
|
|
701
713
|
export async function mkdir(path, options) {
|
|
702
|
-
|
|
703
|
-
const { euid: uid, egid: gid } = (_a = this === null || this === void 0 ? void 0 : this.credentials) !== null && _a !== void 0 ? _a : defaultContext.credentials;
|
|
714
|
+
const { euid: uid, egid: gid } = this?.credentials ?? defaultContext.credentials;
|
|
704
715
|
options = typeof options === 'object' ? options : { mode: options };
|
|
705
|
-
const mode = normalizeMode(options
|
|
716
|
+
const mode = normalizeMode(options?.mode, 0o777);
|
|
706
717
|
path = await realpath.call(this, path);
|
|
707
718
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
708
719
|
const __create = async (path, resolved, parent) => {
|
|
@@ -718,7 +729,7 @@ export async function mkdir(path, options) {
|
|
|
718
729
|
emitChange(this, 'rename', path);
|
|
719
730
|
return inode;
|
|
720
731
|
};
|
|
721
|
-
if (!
|
|
732
|
+
if (!options?.recursive) {
|
|
722
733
|
await __create(path, resolved, await fs.stat(dirname(resolved)).catch(rethrow({ path: dirname(path) })));
|
|
723
734
|
return;
|
|
724
735
|
}
|
|
@@ -847,9 +858,9 @@ export async function readlink(path, options) {
|
|
|
847
858
|
if (!isSymbolicLink(handle.inode))
|
|
848
859
|
throw UV('EINVAL', 'readlink', path);
|
|
849
860
|
const value = await handle.readFile();
|
|
850
|
-
const encoding = typeof options == 'object' ? options
|
|
861
|
+
const encoding = typeof options == 'object' ? options?.encoding : options;
|
|
851
862
|
// always defaults to utf-8 to avoid wrangler (cloudflare) worker "unknown encoding" exception
|
|
852
|
-
return encoding == 'buffer' ? value : value.toString((encoding
|
|
863
|
+
return encoding == 'buffer' ? value : value.toString((encoding ?? 'utf-8'));
|
|
853
864
|
}
|
|
854
865
|
catch (e_6) {
|
|
855
866
|
env_6.error = e_6;
|
|
@@ -1029,8 +1040,7 @@ async function _resolve($, path, preserveSymlinks) {
|
|
|
1029
1040
|
return await _resolve($, target);
|
|
1030
1041
|
}
|
|
1031
1042
|
export async function realpath(path, options) {
|
|
1032
|
-
|
|
1033
|
-
const encoding = typeof options == 'string' ? options : ((_a = options === null || options === void 0 ? void 0 : options.encoding) !== null && _a !== void 0 ? _a : 'utf8');
|
|
1043
|
+
const encoding = typeof options == 'string' ? options : (options?.encoding ?? 'utf8');
|
|
1034
1044
|
path = normalizePath(path);
|
|
1035
1045
|
const { fullPath } = await _resolve(this, path);
|
|
1036
1046
|
if (encoding == 'utf8' || encoding == 'utf-8')
|
|
@@ -1047,8 +1057,7 @@ export function watch(filename, options = {}) {
|
|
|
1047
1057
|
const eventQueue = [];
|
|
1048
1058
|
let done = false;
|
|
1049
1059
|
watcher.on('change', (eventType, filename) => {
|
|
1050
|
-
|
|
1051
|
-
(_a = eventQueue.shift()) === null || _a === void 0 ? void 0 : _a({ value: { eventType, filename }, done: false });
|
|
1060
|
+
eventQueue.shift()?.({ value: { eventType, filename }, done: false });
|
|
1052
1061
|
});
|
|
1053
1062
|
function cleanup() {
|
|
1054
1063
|
done = true;
|
|
@@ -1093,7 +1102,7 @@ access;
|
|
|
1093
1102
|
export async function rm(path, options) {
|
|
1094
1103
|
path = normalizePath(path);
|
|
1095
1104
|
const stats = await lstat.call(this, path).catch((error) => {
|
|
1096
|
-
if (error.code == 'ENOENT' &&
|
|
1105
|
+
if (error.code == 'ENOENT' && options?.force)
|
|
1097
1106
|
return undefined;
|
|
1098
1107
|
throw error;
|
|
1099
1108
|
});
|
|
@@ -1101,7 +1110,7 @@ export async function rm(path, options) {
|
|
|
1101
1110
|
return;
|
|
1102
1111
|
switch (stats.mode & constants.S_IFMT) {
|
|
1103
1112
|
case constants.S_IFDIR:
|
|
1104
|
-
if (options
|
|
1113
|
+
if (options?.recursive) {
|
|
1105
1114
|
for (const entry of await readdir.call(this, path)) {
|
|
1106
1115
|
await rm.call(this, join(path, entry), options);
|
|
1107
1116
|
}
|
|
@@ -1122,7 +1131,7 @@ export async function rm(path, options) {
|
|
|
1122
1131
|
}
|
|
1123
1132
|
rm;
|
|
1124
1133
|
export async function mkdtemp(prefix, options) {
|
|
1125
|
-
const encoding = typeof options === 'object' ? options
|
|
1134
|
+
const encoding = typeof options === 'object' ? options?.encoding : options || 'utf8';
|
|
1126
1135
|
const fsName = `${prefix}${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
1127
1136
|
const resolvedPath = '/tmp/' + fsName;
|
|
1128
1137
|
await mkdir.call(this, resolvedPath);
|
|
@@ -1173,11 +1182,11 @@ export async function cp(source, destination, opts) {
|
|
|
1173
1182
|
source = normalizePath(source);
|
|
1174
1183
|
destination = normalizePath(destination);
|
|
1175
1184
|
const srcStats = await lstat.call(this, source); // Use lstat to follow symlinks if not dereferencing
|
|
1176
|
-
if (
|
|
1185
|
+
if (opts?.errorOnExist && (await exists.call(this, destination)))
|
|
1177
1186
|
throw UV('EEXIST', 'cp', destination);
|
|
1178
1187
|
switch (srcStats.mode & constants.S_IFMT) {
|
|
1179
1188
|
case constants.S_IFDIR: {
|
|
1180
|
-
if (!
|
|
1189
|
+
if (!opts?.recursive)
|
|
1181
1190
|
throw UV('EISDIR', 'cp', source);
|
|
1182
1191
|
const [entries] = await Promise.all([
|
|
1183
1192
|
readdir.call(this, source, { withFileTypes: true }),
|
|
@@ -1205,7 +1214,7 @@ export async function cp(source, destination, opts) {
|
|
|
1205
1214
|
throw UV('ENOSYS', 'cp', source);
|
|
1206
1215
|
}
|
|
1207
1216
|
// Optionally preserve timestamps
|
|
1208
|
-
if (opts
|
|
1217
|
+
if (opts?.preserveTimestamps) {
|
|
1209
1218
|
await utimes.call(this, destination, srcStats.atime, srcStats.mtime);
|
|
1210
1219
|
}
|
|
1211
1220
|
}
|
|
@@ -1213,7 +1222,7 @@ cp;
|
|
|
1213
1222
|
export async function statfs(path, opts) {
|
|
1214
1223
|
path = normalizePath(path);
|
|
1215
1224
|
const { fs } = resolveMount(path, this);
|
|
1216
|
-
return Promise.resolve(_statfs(fs, opts
|
|
1225
|
+
return Promise.resolve(_statfs(fs, opts?.bigint));
|
|
1217
1226
|
}
|
|
1218
1227
|
export function glob(pattern, opt) {
|
|
1219
1228
|
pattern = Array.isArray(pattern) ? pattern : [pattern];
|
package/dist/vfs/shared.js
CHANGED
|
@@ -51,7 +51,7 @@ export function umount(mountPoint) {
|
|
|
51
51
|
* @internal @hidden
|
|
52
52
|
*/
|
|
53
53
|
export function resolveMount(path, ctx) {
|
|
54
|
-
const root =
|
|
54
|
+
const root = ctx?.root || defaultContext.root;
|
|
55
55
|
path = normalizePath(join(root, path));
|
|
56
56
|
const sortedMounts = [...mounts].sort((a, b) => (a[0].length > b[0].length ? -1 : 1)); // descending order of the string length
|
|
57
57
|
for (const [mountPoint, fs] of sortedMounts) {
|
|
@@ -91,13 +91,12 @@ export function _statfs(fs, bigint) {
|
|
|
91
91
|
* @category Backends and Configuration
|
|
92
92
|
*/
|
|
93
93
|
export function chroot(path) {
|
|
94
|
-
|
|
95
|
-
const $ = this !== null && this !== void 0 ? this : defaultContext;
|
|
94
|
+
const $ = this ?? defaultContext;
|
|
96
95
|
if (!credentialsAllowRoot($.credentials))
|
|
97
96
|
throw withErrno('EPERM', 'Can not chroot() as non-root user');
|
|
98
|
-
|
|
97
|
+
$.root ??= '/';
|
|
99
98
|
const newRoot = join($.root, path);
|
|
100
|
-
for (const handle of
|
|
99
|
+
for (const handle of $.descriptors?.values() ?? []) {
|
|
101
100
|
if (!handle.path.startsWith($.root))
|
|
102
101
|
throw UV('EBUSY', 'chroot', handle.path);
|
|
103
102
|
handle.path = handle.path.slice($.root.length);
|
package/dist/vfs/stats.js
CHANGED
|
@@ -14,72 +14,109 @@ export class StatsCommon {
|
|
|
14
14
|
return this._convert(Math.ceil(Number(this.size) / 512));
|
|
15
15
|
}
|
|
16
16
|
set blocks(value) { }
|
|
17
|
+
/**
|
|
18
|
+
* Unix-style file mode (e.g. 0o644) that includes the type of the item.
|
|
19
|
+
*/
|
|
20
|
+
mode;
|
|
21
|
+
/**
|
|
22
|
+
* ID of device containing file
|
|
23
|
+
*/
|
|
24
|
+
dev = this._convert(0);
|
|
25
|
+
/**
|
|
26
|
+
* Inode number
|
|
27
|
+
*/
|
|
28
|
+
ino = this._convert(0);
|
|
29
|
+
/**
|
|
30
|
+
* Device ID (if special file)
|
|
31
|
+
*/
|
|
32
|
+
rdev = this._convert(0);
|
|
33
|
+
/**
|
|
34
|
+
* Number of hard links
|
|
35
|
+
*/
|
|
36
|
+
nlink = this._convert(1);
|
|
37
|
+
/**
|
|
38
|
+
* Block size for file system I/O
|
|
39
|
+
*/
|
|
40
|
+
blksize = this._convert(4096);
|
|
41
|
+
/**
|
|
42
|
+
* User ID of owner
|
|
43
|
+
*/
|
|
44
|
+
uid = this._convert(0);
|
|
45
|
+
/**
|
|
46
|
+
* Group ID of owner
|
|
47
|
+
*/
|
|
48
|
+
gid = this._convert(0);
|
|
49
|
+
/**
|
|
50
|
+
* Time of last access, since epoch
|
|
51
|
+
*/
|
|
52
|
+
atimeMs;
|
|
17
53
|
get atime() {
|
|
18
54
|
return new Date(Number(this.atimeMs));
|
|
19
55
|
}
|
|
20
56
|
set atime(value) {
|
|
21
57
|
this.atimeMs = this._convert(value.getTime());
|
|
22
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Time of last modification, since epoch
|
|
61
|
+
*/
|
|
62
|
+
mtimeMs;
|
|
23
63
|
get mtime() {
|
|
24
64
|
return new Date(Number(this.mtimeMs));
|
|
25
65
|
}
|
|
26
66
|
set mtime(value) {
|
|
27
67
|
this.mtimeMs = this._convert(value.getTime());
|
|
28
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Time of last time file status was changed, since epoch
|
|
71
|
+
*/
|
|
72
|
+
ctimeMs;
|
|
29
73
|
get ctime() {
|
|
30
74
|
return new Date(Number(this.ctimeMs));
|
|
31
75
|
}
|
|
32
76
|
set ctime(value) {
|
|
33
77
|
this.ctimeMs = this._convert(value.getTime());
|
|
34
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Time of file creation, since epoch
|
|
81
|
+
*/
|
|
82
|
+
birthtimeMs;
|
|
35
83
|
get birthtime() {
|
|
36
84
|
return new Date(Number(this.birthtimeMs));
|
|
37
85
|
}
|
|
38
86
|
set birthtime(value) {
|
|
39
87
|
this.birthtimeMs = this._convert(value.getTime());
|
|
40
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Size of the item in bytes.
|
|
91
|
+
* For directories/symlinks, this is normally the size of the struct that represents the item.
|
|
92
|
+
*/
|
|
93
|
+
size;
|
|
94
|
+
/**
|
|
95
|
+
* @internal Used by inodes
|
|
96
|
+
*/
|
|
97
|
+
data;
|
|
98
|
+
/**
|
|
99
|
+
* @internal Used by inodes
|
|
100
|
+
*/
|
|
101
|
+
flags;
|
|
102
|
+
/**
|
|
103
|
+
* @internal Used by inodes
|
|
104
|
+
*/
|
|
105
|
+
version;
|
|
41
106
|
/**
|
|
42
107
|
* Creates a new stats instance from a stats-like object. Can be used to copy stats (note)
|
|
43
108
|
*/
|
|
44
109
|
constructor({ atimeMs, mtimeMs, ctimeMs, birthtimeMs, uid, gid, size, mode, ino, ...rest } = {}) {
|
|
45
|
-
/**
|
|
46
|
-
* ID of device containing file
|
|
47
|
-
*/
|
|
48
|
-
this.dev = this._convert(0);
|
|
49
|
-
/**
|
|
50
|
-
* Inode number
|
|
51
|
-
*/
|
|
52
|
-
this.ino = this._convert(0);
|
|
53
|
-
/**
|
|
54
|
-
* Device ID (if special file)
|
|
55
|
-
*/
|
|
56
|
-
this.rdev = this._convert(0);
|
|
57
|
-
/**
|
|
58
|
-
* Number of hard links
|
|
59
|
-
*/
|
|
60
|
-
this.nlink = this._convert(1);
|
|
61
|
-
/**
|
|
62
|
-
* Block size for file system I/O
|
|
63
|
-
*/
|
|
64
|
-
this.blksize = this._convert(4096);
|
|
65
|
-
/**
|
|
66
|
-
* User ID of owner
|
|
67
|
-
*/
|
|
68
|
-
this.uid = this._convert(0);
|
|
69
|
-
/**
|
|
70
|
-
* Group ID of owner
|
|
71
|
-
*/
|
|
72
|
-
this.gid = this._convert(0);
|
|
73
110
|
const now = Date.now();
|
|
74
|
-
this.atimeMs = this._convert(atimeMs
|
|
75
|
-
this.mtimeMs = this._convert(mtimeMs
|
|
76
|
-
this.ctimeMs = this._convert(ctimeMs
|
|
77
|
-
this.birthtimeMs = this._convert(birthtimeMs
|
|
78
|
-
this.uid = this._convert(uid
|
|
79
|
-
this.gid = this._convert(gid
|
|
80
|
-
this.size = this._convert(size
|
|
81
|
-
this.ino = this._convert(ino
|
|
82
|
-
this.mode = this._convert(mode
|
|
111
|
+
this.atimeMs = this._convert(atimeMs ?? now);
|
|
112
|
+
this.mtimeMs = this._convert(mtimeMs ?? now);
|
|
113
|
+
this.ctimeMs = this._convert(ctimeMs ?? now);
|
|
114
|
+
this.birthtimeMs = this._convert(birthtimeMs ?? now);
|
|
115
|
+
this.uid = this._convert(uid ?? 0);
|
|
116
|
+
this.gid = this._convert(gid ?? 0);
|
|
117
|
+
this.size = this._convert(size ?? 0);
|
|
118
|
+
this.ino = this._convert(ino ?? 0);
|
|
119
|
+
this.mode = this._convert(mode ?? 0o644 & c.S_IFREG);
|
|
83
120
|
if ((this.mode & c.S_IFMT) == 0) {
|
|
84
121
|
this.mode = (this.mode | this._convert(c.S_IFREG));
|
|
85
122
|
}
|
|
@@ -154,20 +191,14 @@ export function _chown(stats, uid, gid) {
|
|
|
154
191
|
* @see http://man7.org/linux/man-pages/man2/stat.2.html
|
|
155
192
|
*/
|
|
156
193
|
export class Stats extends StatsCommon {
|
|
157
|
-
|
|
158
|
-
super(...arguments);
|
|
159
|
-
this._isBigint = false;
|
|
160
|
-
}
|
|
194
|
+
_isBigint = false;
|
|
161
195
|
}
|
|
162
196
|
Stats;
|
|
163
197
|
/**
|
|
164
198
|
* Stats with bigint
|
|
165
199
|
*/
|
|
166
200
|
export class BigIntStats extends StatsCommon {
|
|
167
|
-
|
|
168
|
-
super(...arguments);
|
|
169
|
-
this._isBigint = true;
|
|
170
|
-
}
|
|
201
|
+
_isBigint = true;
|
|
171
202
|
}
|
|
172
203
|
/**
|
|
173
204
|
* Determines if the file stats have changed by comparing relevant properties.
|
|
@@ -190,41 +221,37 @@ export const ZenFsType = 0x7a656e6673; // 'z' 'e' 'n' 'f' 's'
|
|
|
190
221
|
* @hidden
|
|
191
222
|
*/
|
|
192
223
|
export class StatsFs {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
this.ffree = c.size_max;
|
|
208
|
-
}
|
|
224
|
+
/** Type of file system. */
|
|
225
|
+
type = 0x7a656e6673;
|
|
226
|
+
/** Optimal transfer block size. */
|
|
227
|
+
bsize = 4096;
|
|
228
|
+
/** Total data blocks in file system. */
|
|
229
|
+
blocks = 0;
|
|
230
|
+
/** Free blocks in file system. */
|
|
231
|
+
bfree = 0;
|
|
232
|
+
/** Available blocks for unprivileged users */
|
|
233
|
+
bavail = 0;
|
|
234
|
+
/** Total file nodes in file system. */
|
|
235
|
+
files = c.size_max;
|
|
236
|
+
/** Free file nodes in file system. */
|
|
237
|
+
ffree = c.size_max;
|
|
209
238
|
}
|
|
210
239
|
/**
|
|
211
240
|
* @hidden
|
|
212
241
|
*/
|
|
213
242
|
export class BigIntStatsFs {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
this.ffree = BigInt(c.size_max);
|
|
229
|
-
}
|
|
243
|
+
/** Type of file system. */
|
|
244
|
+
type = BigInt('0x7a656e6673');
|
|
245
|
+
/** Optimal transfer block size. */
|
|
246
|
+
bsize = BigInt(4096);
|
|
247
|
+
/** Total data blocks in file system. */
|
|
248
|
+
blocks = BigInt(0);
|
|
249
|
+
/** Free blocks in file system. */
|
|
250
|
+
bfree = BigInt(0);
|
|
251
|
+
/** Available blocks for unprivileged users */
|
|
252
|
+
bavail = BigInt(0);
|
|
253
|
+
/** Total file nodes in file system. */
|
|
254
|
+
files = BigInt(c.size_max);
|
|
255
|
+
/** Free file nodes in file system. */
|
|
256
|
+
ffree = BigInt(c.size_max);
|
|
230
257
|
}
|
package/dist/vfs/streams.js
CHANGED
|
@@ -5,12 +5,13 @@ import { Readable, Writable } from 'readable-stream';
|
|
|
5
5
|
* A ReadStream implementation that wraps an underlying global ReadableStream.
|
|
6
6
|
*/
|
|
7
7
|
export class ReadStream extends Readable {
|
|
8
|
+
pending = true;
|
|
9
|
+
_path = '<unknown>';
|
|
10
|
+
_bytesRead = 0;
|
|
11
|
+
reader;
|
|
12
|
+
ready;
|
|
8
13
|
constructor(opts = {}, handleOrPromise) {
|
|
9
|
-
|
|
10
|
-
super({ ...opts, encoding: (_a = opts.encoding) !== null && _a !== void 0 ? _a : undefined });
|
|
11
|
-
this.pending = true;
|
|
12
|
-
this._path = '<unknown>';
|
|
13
|
-
this._bytesRead = 0;
|
|
14
|
+
super({ ...opts, encoding: opts.encoding ?? undefined });
|
|
14
15
|
this.ready = Promise.resolve(handleOrPromise)
|
|
15
16
|
.then(handle => {
|
|
16
17
|
this._path = handle.path;
|
|
@@ -64,11 +65,13 @@ export class ReadStream extends Readable {
|
|
|
64
65
|
* A WriteStream implementation that wraps an underlying global WritableStream.
|
|
65
66
|
*/
|
|
66
67
|
export class WriteStream extends Writable {
|
|
68
|
+
pending = true;
|
|
69
|
+
_path = '<unknown>';
|
|
70
|
+
_bytesWritten = 0;
|
|
71
|
+
writer;
|
|
72
|
+
ready;
|
|
67
73
|
constructor(opts = {}, handleOrPromise) {
|
|
68
74
|
super(opts);
|
|
69
|
-
this.pending = true;
|
|
70
|
-
this._path = '<unknown>';
|
|
71
|
-
this._bytesWritten = 0;
|
|
72
75
|
this.ready = Promise.resolve(handleOrPromise)
|
|
73
76
|
.then(handle => {
|
|
74
77
|
this._path = handle.path;
|