@componentor/fs 3.0.28 → 3.0.30

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/index.d.mts CHANGED
@@ -311,6 +311,18 @@ type AsyncRequestFn = (op: number, path: string, flags?: number, data?: Uint8Arr
311
311
  data: Uint8Array | null;
312
312
  }>;
313
313
 
314
+ /**
315
+ * VFSFileSystem — main thread API.
316
+ *
317
+ * Provides Node.js-compatible sync and async filesystem methods.
318
+ * Sync methods use SAB + Atomics to block until the server responds.
319
+ * Async methods use postMessage to the async relay worker.
320
+ *
321
+ * On import, workers are spawned immediately. Every method blocks
322
+ * (or waits) until the worker is ready. This is by design — the library
323
+ * primarily runs inside workers where blocking is fine.
324
+ */
325
+
314
326
  declare class VFSFileSystem {
315
327
  private sab;
316
328
  private ctrl;
@@ -388,8 +400,9 @@ declare class VFSFileSystem {
388
400
  rmdirSync(filePath: PathLike, options?: RmdirOptions): void;
389
401
  rmSync(filePath: PathLike, options?: RmOptions): void;
390
402
  unlinkSync(filePath: PathLike): void;
391
- readdirSync(filePath: PathLike, options?: ReaddirOptions | Encoding | null): string[] | Dirent[];
403
+ readdirSync(filePath: PathLike, options?: ReaddirOptions | Encoding | null): string[] | Uint8Array[] | Dirent[];
392
404
  globSync(pattern: string, options?: GlobOptions): string[];
405
+ opendirSync(filePath: PathLike): Dir;
393
406
  statSync(filePath: PathLike, options?: StatOptions): Stats | BigIntStats;
394
407
  lstatSync(filePath: PathLike, options?: StatOptions): Stats | BigIntStats;
395
408
  renameSync(oldPath: PathLike, newPath: PathLike): void;
@@ -410,6 +423,8 @@ declare class VFSFileSystem {
410
423
  /** chown on an open file descriptor. No-op in this VFS (permissions are cosmetic). */
411
424
  fchownSync(_fd: number, _uid: number, _gid: number): void;
412
425
  utimesSync(filePath: PathLike, atime: Date | number, mtime: Date | number): void;
426
+ /** utimes on an open file descriptor. No-op in this VFS (cannot resolve fd to path). */
427
+ futimesSync(_fd: number, _atime: Date | number, _mtime: Date | number): void;
413
428
  /** Like utimesSync but operates on the symlink itself. In this VFS, delegates to utimesSync. */
414
429
  lutimesSync(filePath: string, atime: Date | number, mtime: Date | number): void;
415
430
  symlinkSync(target: PathLike, linkPath: PathLike, type?: string | null): void;
@@ -515,12 +530,73 @@ declare class VFSFileSystem {
515
530
  cp(src: string, dest: string, options: CpOptions, callback: (err: Error | null) => void): void;
516
531
  fdatasync(fd: number, callback: (err: Error | null) => void): void;
517
532
  fsync(fd: number, callback: (err: Error | null) => void): void;
533
+ fstat(fd: number, callback: (err: Error | null, stats?: Stats) => void): void;
534
+ fstat(fd: number, options: any, callback: (err: Error | null, stats?: Stats) => void): void;
535
+ ftruncate(fd: number, callback: (err: Error | null) => void): void;
536
+ ftruncate(fd: number, len: number, callback: (err: Error | null) => void): void;
537
+ read(fd: number, buffer: Uint8Array, offset: number, length: number, position: number | null, callback: (err: Error | null, bytesRead?: number, buffer?: Uint8Array) => void): void;
538
+ write(fd: number, buffer: Uint8Array, offset: number, length: number, position: number | null, callback: (err: Error | null, bytesWritten?: number, buffer?: Uint8Array) => void): void;
539
+ write(fd: number, data: string, position: number | null | undefined, encoding: string | undefined, callback: (err: Error | null, bytesWritten?: number, data?: string) => void): void;
540
+ close(fd: number, callback?: (err: Error | null) => void): void;
518
541
  exists(filePath: string, callback: (exists: boolean) => void): void;
542
+ opendir(filePath: string, callback: (err: Error | null, dir?: Dir) => void): void;
543
+ glob(pattern: string, callback: (err: Error | null, matches?: string[]) => void): void;
544
+ glob(pattern: string, options: GlobOptions, callback: (err: Error | null, matches?: string[]) => void): void;
545
+ futimes(fd: number, atime: Date | number, mtime: Date | number, callback: (err: Error | null) => void): void;
546
+ fchmod(fd: number, mode: number, callback: (err: Error | null) => void): void;
547
+ fchown(fd: number, uid: number, gid: number, callback: (err: Error | null) => void): void;
548
+ lchmod(filePath: string, mode: number, callback: (err: Error | null) => void): void;
549
+ lchown(filePath: string, uid: number, gid: number, callback: (err: Error | null) => void): void;
550
+ lutimes(filePath: string, atime: Date | number, mtime: Date | number, callback: (err: Error | null) => void): void;
519
551
  }
520
552
  declare class VFSPromises {
521
553
  private _async;
522
554
  private _ns;
523
555
  constructor(asyncRequest: AsyncRequestFn, ns: string);
556
+ /** Node.js compat: fs.promises.constants (same as fs.constants) */
557
+ get constants(): {
558
+ readonly F_OK: 0;
559
+ readonly R_OK: 4;
560
+ readonly W_OK: 2;
561
+ readonly X_OK: 1;
562
+ readonly COPYFILE_EXCL: 1;
563
+ readonly COPYFILE_FICLONE: 2;
564
+ readonly COPYFILE_FICLONE_FORCE: 4;
565
+ readonly O_RDONLY: 0;
566
+ readonly O_WRONLY: 1;
567
+ readonly O_RDWR: 2;
568
+ readonly O_CREAT: 64;
569
+ readonly O_EXCL: 128;
570
+ readonly O_TRUNC: 512;
571
+ readonly O_APPEND: 1024;
572
+ readonly O_NOCTTY: 256;
573
+ readonly O_NONBLOCK: 2048;
574
+ readonly O_SYNC: 4096;
575
+ readonly O_DSYNC: 4096;
576
+ readonly O_DIRECTORY: 65536;
577
+ readonly O_NOFOLLOW: 131072;
578
+ readonly O_NOATIME: 262144;
579
+ readonly S_IFMT: 61440;
580
+ readonly S_IFREG: 32768;
581
+ readonly S_IFDIR: 16384;
582
+ readonly S_IFCHR: 8192;
583
+ readonly S_IFBLK: 24576;
584
+ readonly S_IFIFO: 4096;
585
+ readonly S_IFLNK: 40960;
586
+ readonly S_IFSOCK: 49152;
587
+ readonly S_IRWXU: 448;
588
+ readonly S_IRUSR: 256;
589
+ readonly S_IWUSR: 128;
590
+ readonly S_IXUSR: 64;
591
+ readonly S_IRWXG: 56;
592
+ readonly S_IRGRP: 32;
593
+ readonly S_IWGRP: 16;
594
+ readonly S_IXGRP: 8;
595
+ readonly S_IRWXO: 7;
596
+ readonly S_IROTH: 4;
597
+ readonly S_IWOTH: 2;
598
+ readonly S_IXOTH: 1;
599
+ };
524
600
  readFile(filePath: PathLike, options?: ReadOptions | Encoding | null): Promise<string | Uint8Array<ArrayBufferLike>>;
525
601
  writeFile(filePath: PathLike, data: string | Uint8Array, options?: WriteOptions | Encoding): Promise<void>;
526
602
  appendFile(filePath: PathLike, data: string | Uint8Array, options?: WriteOptions | Encoding): Promise<void>;
@@ -528,7 +604,7 @@ declare class VFSPromises {
528
604
  rmdir(filePath: PathLike, options?: RmdirOptions): Promise<void>;
529
605
  rm(filePath: PathLike, options?: RmOptions): Promise<void>;
530
606
  unlink(filePath: PathLike): Promise<void>;
531
- readdir(filePath: PathLike, options?: ReaddirOptions | Encoding | null): Promise<string[] | Dirent[]>;
607
+ readdir(filePath: PathLike, options?: ReaddirOptions | Encoding | null): Promise<Uint8Array<ArrayBufferLike>[] | string[] | Dirent[]>;
532
608
  glob(pattern: string, options?: GlobOptions): Promise<string[]>;
533
609
  stat(filePath: PathLike, options?: StatOptions): Promise<BigIntStats | Stats>;
534
610
  lstat(filePath: PathLike, options?: StatOptions): Promise<BigIntStats | Stats>;
@@ -550,6 +626,8 @@ declare class VFSPromises {
550
626
  /** chown on an open file descriptor. No-op in this VFS (permissions are cosmetic). */
551
627
  fchown(_fd: number, _uid: number, _gid: number): Promise<void>;
552
628
  utimes(filePath: PathLike, atime: Date | number, mtime: Date | number): Promise<void>;
629
+ /** utimes on an open file descriptor. No-op in this VFS (cannot resolve fd to path). */
630
+ futimes(_fd: number, _atime: Date | number, _mtime: Date | number): Promise<void>;
553
631
  /** Like utimes but operates on the symlink itself. In this VFS, delegates to utimes. */
554
632
  lutimes(filePath: string, atime: Date | number, mtime: Date | number): Promise<void>;
555
633
  symlink(target: PathLike, linkPath: PathLike, type?: string | null): Promise<void>;
@@ -856,4 +934,4 @@ declare function getDefaultFS(): VFSFileSystem;
856
934
  /** Async init helper — avoids blocking main thread */
857
935
  declare function init(): Promise<void>;
858
936
 
859
- export { type BigIntStats, type CpOptions, type Dir, type Dirent, type Encoding, FSError, type FSMode, type FSReadStream, type FSWatcher, type FSWriteStream, type FileHandle, type LoadResult, type MkdirOptions, NodeReadable, NodeWritable, type OpenAsBlobOptions, type PathLike, type ReadOptions, type ReadStreamOptions, type ReaddirOptions, type RepairResult, type RmOptions, type RmdirOptions, SimpleEventEmitter, type StatFs, type StatOptions, type Stats, type UnpackResult, type VFSConfig, VFSFileSystem, type VFSLimits, type WatchEventType, type WatchFileListener, type WatchListener, type WatchOptions, type WriteOptions, type WriteStreamOptions, constants, createError, createFS, getDefaultFS, init, loadFromOPFS, path, repairVFS, statusToError, unpackToOPFS };
937
+ export { type BigIntStats, type CpOptions, type Dir, type Dirent, type Encoding, FSError, type FSMode, type FSReadStream, type FSWatcher, type FSWriteStream, type FileHandle, type LoadResult, type MkdirOptions, NodeReadable, NodeWritable, type OpenAsBlobOptions, type PathLike, type ReadOptions, NodeReadable as ReadStream, type ReadStreamOptions, type ReaddirOptions, type RepairResult, type RmOptions, type RmdirOptions, SimpleEventEmitter, type StatFs, type StatOptions, type Stats, type UnpackResult, type VFSConfig, VFSFileSystem, type VFSLimits, type WatchEventType, type WatchFileListener, type WatchListener, type WatchOptions, type WriteOptions, NodeWritable as WriteStream, type WriteStreamOptions, constants, createError, createFS, getDefaultFS, init, loadFromOPFS, path, repairVFS, statusToError, unpackToOPFS };
package/dist/index.js CHANGED
@@ -1176,6 +1176,21 @@ async function readFile(asyncRequest, filePath, options) {
1176
1176
  }
1177
1177
  }
1178
1178
 
1179
+ // src/methods/chmod.ts
1180
+ function chmodSync(syncRequest, filePath, mode) {
1181
+ const modeBuf = new Uint8Array(4);
1182
+ new DataView(modeBuf.buffer).setUint32(0, mode, true);
1183
+ const buf = encodeRequest(OP.CHMOD, filePath, 0, modeBuf);
1184
+ const { status } = syncRequest(buf);
1185
+ if (status !== 0) throw statusToError(status, "chmod", filePath);
1186
+ }
1187
+ async function chmod(asyncRequest, filePath, mode) {
1188
+ const modeBuf = new Uint8Array(4);
1189
+ new DataView(modeBuf.buffer).setUint32(0, mode, true);
1190
+ const { status } = await asyncRequest(OP.CHMOD, filePath, 0, modeBuf);
1191
+ if (status !== 0) throw statusToError(status, "chmod", filePath);
1192
+ }
1193
+
1179
1194
  // src/methods/writeFile.ts
1180
1195
  var encoder3 = new TextEncoder();
1181
1196
  function writeFileSync(syncRequest, filePath, data, options) {
@@ -1191,9 +1206,12 @@ function writeFileSync(syncRequest, filePath, data, options) {
1191
1206
  const buf = encodeRequest(OP.WRITE, filePath, flags, encoded);
1192
1207
  const { status } = syncRequest(buf);
1193
1208
  if (status !== 0) throw statusToError(status, "write", filePath);
1209
+ if (opts?.mode !== void 0) {
1210
+ chmodSync(syncRequest, filePath, opts.mode);
1211
+ }
1194
1212
  return;
1195
1213
  }
1196
- const fd = openSync(syncRequest, filePath, flag);
1214
+ const fd = openSync(syncRequest, filePath, flag, opts?.mode);
1197
1215
  try {
1198
1216
  writeSyncFd(syncRequest, fd, encoded, 0, encoded.byteLength, 0);
1199
1217
  } finally {
@@ -1213,9 +1231,12 @@ async function writeFile(asyncRequest, filePath, data, options) {
1213
1231
  const { status } = await asyncRequest(OP.WRITE, filePath, flags, encoded);
1214
1232
  if (signal?.aborted) throw new DOMException("The operation was aborted", "AbortError");
1215
1233
  if (status !== 0) throw statusToError(status, "write", filePath);
1234
+ if (opts?.mode !== void 0) {
1235
+ await chmod(asyncRequest, filePath, opts.mode);
1236
+ }
1216
1237
  return;
1217
1238
  }
1218
- const handle = await open(asyncRequest, filePath, flag);
1239
+ const handle = await open(asyncRequest, filePath, flag, opts?.mode);
1219
1240
  try {
1220
1241
  await handle.writeFile(encoded);
1221
1242
  if (signal?.aborted) throw new DOMException("The operation was aborted", "AbortError");
@@ -1371,6 +1392,10 @@ async function unlink(asyncRequest, filePath) {
1371
1392
  }
1372
1393
 
1373
1394
  // src/methods/readdir.ts
1395
+ var textEncoder = new TextEncoder();
1396
+ function namesToBuffers(names) {
1397
+ return names.map((n) => textEncoder.encode(n));
1398
+ }
1374
1399
  function readdirBaseSync(syncRequest, filePath, withFileTypes) {
1375
1400
  const flags = withFileTypes ? 1 : 0;
1376
1401
  const buf = encodeRequest(OP.READDIR, filePath, flags);
@@ -1456,28 +1481,46 @@ async function readdirRecursiveAsync(asyncRequest, basePath, prefix, withFileTyp
1456
1481
  return results;
1457
1482
  }
1458
1483
  function readdirSync(syncRequest, filePath, options) {
1459
- const opts = typeof options === "string" ? { } : options;
1484
+ const opts = typeof options === "string" ? { encoding: options } : options;
1485
+ const asBuffer = opts?.encoding === "buffer";
1460
1486
  if (opts?.recursive) {
1461
- return readdirRecursiveSync(
1487
+ const result2 = readdirRecursiveSync(
1462
1488
  syncRequest,
1463
1489
  filePath,
1464
1490
  "",
1465
1491
  !!opts?.withFileTypes
1466
1492
  );
1493
+ if (asBuffer && !opts?.withFileTypes) {
1494
+ return namesToBuffers(result2);
1495
+ }
1496
+ return result2;
1467
1497
  }
1468
- return readdirBaseSync(syncRequest, filePath, !!opts?.withFileTypes);
1498
+ const result = readdirBaseSync(syncRequest, filePath, !!opts?.withFileTypes);
1499
+ if (asBuffer && !opts?.withFileTypes) {
1500
+ return namesToBuffers(result);
1501
+ }
1502
+ return result;
1469
1503
  }
1470
1504
  async function readdir(asyncRequest, filePath, options) {
1471
- const opts = typeof options === "string" ? { } : options;
1505
+ const opts = typeof options === "string" ? { encoding: options } : options;
1506
+ const asBuffer = opts?.encoding === "buffer";
1472
1507
  if (opts?.recursive) {
1473
- return readdirRecursiveAsync(
1508
+ const result2 = await readdirRecursiveAsync(
1474
1509
  asyncRequest,
1475
1510
  filePath,
1476
1511
  "",
1477
1512
  !!opts?.withFileTypes
1478
1513
  );
1514
+ if (asBuffer && !opts?.withFileTypes) {
1515
+ return namesToBuffers(result2);
1516
+ }
1517
+ return result2;
1518
+ }
1519
+ const result = await readdirBaseAsync(asyncRequest, filePath, !!opts?.withFileTypes);
1520
+ if (asBuffer && !opts?.withFileTypes) {
1521
+ return namesToBuffers(result);
1479
1522
  }
1480
- return readdirBaseAsync(asyncRequest, filePath, !!opts?.withFileTypes);
1523
+ return result;
1481
1524
  }
1482
1525
 
1483
1526
  // src/methods/stat.ts
@@ -1576,21 +1619,6 @@ async function realpath(asyncRequest, filePath) {
1576
1619
  return decoder5.decode(data);
1577
1620
  }
1578
1621
 
1579
- // src/methods/chmod.ts
1580
- function chmodSync(syncRequest, filePath, mode) {
1581
- const modeBuf = new Uint8Array(4);
1582
- new DataView(modeBuf.buffer).setUint32(0, mode, true);
1583
- const buf = encodeRequest(OP.CHMOD, filePath, 0, modeBuf);
1584
- const { status } = syncRequest(buf);
1585
- if (status !== 0) throw statusToError(status, "chmod", filePath);
1586
- }
1587
- async function chmod(asyncRequest, filePath, mode) {
1588
- const modeBuf = new Uint8Array(4);
1589
- new DataView(modeBuf.buffer).setUint32(0, mode, true);
1590
- const { status } = await asyncRequest(OP.CHMOD, filePath, 0, modeBuf);
1591
- if (status !== 0) throw statusToError(status, "chmod", filePath);
1592
- }
1593
-
1594
1622
  // src/methods/chown.ts
1595
1623
  function chownSync(syncRequest, filePath, uid, gid) {
1596
1624
  const ownerBuf = new Uint8Array(8);
@@ -2326,6 +2354,12 @@ var VFSFileSystem = class {
2326
2354
  this.rejectReady = reject;
2327
2355
  });
2328
2356
  this.promises = new VFSPromises(this._async, ns);
2357
+ const boundRealpath = this.realpath.bind(this);
2358
+ boundRealpath.native = boundRealpath;
2359
+ this.realpath = boundRealpath;
2360
+ const boundRealpathSync = this.realpathSync.bind(this);
2361
+ boundRealpathSync.native = boundRealpathSync;
2362
+ this.realpathSync = boundRealpathSync;
2329
2363
  instanceRegistry.set(ns, this);
2330
2364
  this.bootstrap();
2331
2365
  }
@@ -2799,6 +2833,25 @@ var VFSFileSystem = class {
2799
2833
  globSync(pattern, options) {
2800
2834
  return globSync(this._sync, pattern, options);
2801
2835
  }
2836
+ opendirSync(filePath) {
2837
+ const dirPath = toPathString(filePath);
2838
+ const entries = this.readdirSync(dirPath, { withFileTypes: true });
2839
+ let index = 0;
2840
+ return {
2841
+ path: dirPath,
2842
+ async read() {
2843
+ if (index >= entries.length) return null;
2844
+ return entries[index++];
2845
+ },
2846
+ async close() {
2847
+ },
2848
+ async *[Symbol.asyncIterator]() {
2849
+ for (const entry of entries) {
2850
+ yield entry;
2851
+ }
2852
+ }
2853
+ };
2854
+ }
2802
2855
  statSync(filePath, options) {
2803
2856
  return statSync(this._sync, toPathString(filePath), options);
2804
2857
  }
@@ -2951,6 +3004,9 @@ var VFSFileSystem = class {
2951
3004
  utimesSync(filePath, atime, mtime) {
2952
3005
  utimesSync(this._sync, toPathString(filePath), atime, mtime);
2953
3006
  }
3007
+ /** utimes on an open file descriptor. No-op in this VFS (cannot resolve fd to path). */
3008
+ futimesSync(_fd, _atime, _mtime) {
3009
+ }
2954
3010
  /** Like utimesSync but operates on the symlink itself. In this VFS, delegates to utimesSync. */
2955
3011
  lutimesSync(filePath, atime, mtime) {
2956
3012
  utimesSync(this._sync, filePath, atime, mtime);
@@ -3026,9 +3082,9 @@ var VFSFileSystem = class {
3026
3082
  }
3027
3083
  try {
3028
3084
  const bytesRead = this.readvSync(fd, buffers, pos);
3029
- cb(null, bytesRead, buffers);
3085
+ setTimeout(() => cb(null, bytesRead, buffers), 0);
3030
3086
  } catch (err) {
3031
- cb(err);
3087
+ setTimeout(() => cb(err), 0);
3032
3088
  }
3033
3089
  }
3034
3090
  writev(fd, buffers, positionOrCallback, callback) {
@@ -3043,9 +3099,9 @@ var VFSFileSystem = class {
3043
3099
  }
3044
3100
  try {
3045
3101
  const bytesWritten = this.writevSync(fd, buffers, pos);
3046
- cb(null, bytesWritten, buffers);
3102
+ setTimeout(() => cb(null, bytesWritten, buffers), 0);
3047
3103
  } catch (err) {
3048
- cb(err);
3104
+ setTimeout(() => cb(err), 0);
3049
3105
  }
3050
3106
  }
3051
3107
  // ---- statfs methods ----
@@ -3446,17 +3502,72 @@ var VFSFileSystem = class {
3446
3502
  fdatasync(fd, callback) {
3447
3503
  try {
3448
3504
  this.fdatasyncSync(fd);
3449
- callback(null);
3505
+ setTimeout(() => callback(null), 0);
3450
3506
  } catch (err) {
3451
- callback(err);
3507
+ setTimeout(() => callback(err), 0);
3452
3508
  }
3453
3509
  }
3454
3510
  fsync(fd, callback) {
3455
3511
  try {
3456
3512
  this.fsyncSync(fd);
3457
- callback(null);
3513
+ setTimeout(() => callback(null), 0);
3514
+ } catch (err) {
3515
+ setTimeout(() => callback(err), 0);
3516
+ }
3517
+ }
3518
+ fstat(fd, optionsOrCallback, callback) {
3519
+ const cb = typeof optionsOrCallback === "function" ? optionsOrCallback : callback;
3520
+ try {
3521
+ const result = this.fstatSync(fd);
3522
+ setTimeout(() => cb(null, result), 0);
3523
+ } catch (err) {
3524
+ setTimeout(() => cb(err), 0);
3525
+ }
3526
+ }
3527
+ ftruncate(fd, lenOrCallback, callback) {
3528
+ const cb = typeof lenOrCallback === "function" ? lenOrCallback : callback;
3529
+ const len = typeof lenOrCallback === "function" ? 0 : lenOrCallback;
3530
+ try {
3531
+ this.ftruncateSync(fd, len);
3532
+ setTimeout(() => cb(null), 0);
3533
+ } catch (err) {
3534
+ setTimeout(() => cb(err), 0);
3535
+ }
3536
+ }
3537
+ read(fd, buffer, offset, length, position, callback) {
3538
+ try {
3539
+ const bytesRead = this.readSync(fd, buffer, offset, length, position);
3540
+ setTimeout(() => callback(null, bytesRead, buffer), 0);
3458
3541
  } catch (err) {
3459
- callback(err);
3542
+ setTimeout(() => callback(err), 0);
3543
+ }
3544
+ }
3545
+ write(fd, bufferOrString, offsetOrPosition, lengthOrEncoding, position, callback) {
3546
+ const cb = [offsetOrPosition, lengthOrEncoding, position, callback].find((a) => typeof a === "function");
3547
+ try {
3548
+ let bytesWritten;
3549
+ if (typeof bufferOrString === "string") {
3550
+ const pos = typeof offsetOrPosition === "function" ? void 0 : offsetOrPosition;
3551
+ const enc = typeof lengthOrEncoding === "function" ? void 0 : lengthOrEncoding;
3552
+ bytesWritten = this.writeSync(fd, bufferOrString, pos, enc);
3553
+ } else {
3554
+ const off = typeof offsetOrPosition === "function" ? void 0 : offsetOrPosition;
3555
+ const len = typeof lengthOrEncoding === "function" ? void 0 : lengthOrEncoding;
3556
+ const pos = typeof position === "function" ? void 0 : position;
3557
+ bytesWritten = this.writeSync(fd, bufferOrString, off, len, pos);
3558
+ }
3559
+ setTimeout(() => cb(null, bytesWritten, bufferOrString), 0);
3560
+ } catch (err) {
3561
+ setTimeout(() => cb(err), 0);
3562
+ }
3563
+ }
3564
+ close(fd, callback) {
3565
+ try {
3566
+ this.closeSync(fd);
3567
+ if (callback) setTimeout(() => callback(null), 0);
3568
+ } catch (err) {
3569
+ if (callback) setTimeout(() => callback(err), 0);
3570
+ else throw err;
3460
3571
  }
3461
3572
  }
3462
3573
  exists(filePath, callback) {
@@ -3465,6 +3576,47 @@ var VFSFileSystem = class {
3465
3576
  () => setTimeout(() => callback(false), 0)
3466
3577
  );
3467
3578
  }
3579
+ opendir(filePath, callback) {
3580
+ this.promises.opendir(filePath).then(
3581
+ (dir) => setTimeout(() => callback(null, dir), 0),
3582
+ (err) => setTimeout(() => callback(err), 0)
3583
+ );
3584
+ }
3585
+ glob(pattern, optionsOrCallback, callback) {
3586
+ const cb = typeof optionsOrCallback === "function" ? optionsOrCallback : callback;
3587
+ const opts = typeof optionsOrCallback === "function" ? void 0 : optionsOrCallback;
3588
+ this.promises.glob(pattern, opts).then(
3589
+ (result) => setTimeout(() => cb(null, result), 0),
3590
+ (err) => setTimeout(() => cb(err), 0)
3591
+ );
3592
+ }
3593
+ futimes(fd, atime, mtime, callback) {
3594
+ setTimeout(() => callback(null), 0);
3595
+ }
3596
+ fchmod(fd, mode, callback) {
3597
+ setTimeout(() => callback(null), 0);
3598
+ }
3599
+ fchown(fd, uid, gid, callback) {
3600
+ setTimeout(() => callback(null), 0);
3601
+ }
3602
+ lchmod(filePath, mode, callback) {
3603
+ this.promises.lchmod(filePath, mode).then(
3604
+ () => setTimeout(() => callback(null), 0),
3605
+ (err) => setTimeout(() => callback(err), 0)
3606
+ );
3607
+ }
3608
+ lchown(filePath, uid, gid, callback) {
3609
+ this.promises.lchown(filePath, uid, gid).then(
3610
+ () => setTimeout(() => callback(null), 0),
3611
+ (err) => setTimeout(() => callback(err), 0)
3612
+ );
3613
+ }
3614
+ lutimes(filePath, atime, mtime, callback) {
3615
+ this.promises.lutimes(filePath, atime, mtime).then(
3616
+ () => setTimeout(() => callback(null), 0),
3617
+ (err) => setTimeout(() => callback(err), 0)
3618
+ );
3619
+ }
3468
3620
  };
3469
3621
  var VFSPromises = class {
3470
3622
  _async;
@@ -3473,6 +3625,10 @@ var VFSPromises = class {
3473
3625
  this._async = asyncRequest;
3474
3626
  this._ns = ns;
3475
3627
  }
3628
+ /** Node.js compat: fs.promises.constants (same as fs.constants) */
3629
+ get constants() {
3630
+ return constants;
3631
+ }
3476
3632
  readFile(filePath, options) {
3477
3633
  return readFile(this._async, toPathString(filePath), options);
3478
3634
  }
@@ -3602,6 +3758,9 @@ var VFSPromises = class {
3602
3758
  utimes(filePath, atime, mtime) {
3603
3759
  return utimes(this._async, toPathString(filePath), atime, mtime);
3604
3760
  }
3761
+ /** utimes on an open file descriptor. No-op in this VFS (cannot resolve fd to path). */
3762
+ async futimes(_fd, _atime, _mtime) {
3763
+ }
3605
3764
  /** Like utimes but operates on the symlink itself. In this VFS, delegates to utimes. */
3606
3765
  lutimes(filePath, atime, mtime) {
3607
3766
  return utimes(this._async, filePath, atime, mtime);
@@ -5332,6 +5491,6 @@ function init() {
5332
5491
  return getDefaultFS().init();
5333
5492
  }
5334
5493
 
5335
- export { FSError, NodeReadable, NodeWritable, SimpleEventEmitter, VFSFileSystem, constants, createError, createFS, getDefaultFS, init, loadFromOPFS, path_exports as path, repairVFS, statusToError, unpackToOPFS };
5494
+ export { FSError, NodeReadable, NodeWritable, NodeReadable as ReadStream, SimpleEventEmitter, VFSFileSystem, NodeWritable as WriteStream, constants, createError, createFS, getDefaultFS, init, loadFromOPFS, path_exports as path, repairVFS, statusToError, unpackToOPFS };
5336
5495
  //# sourceMappingURL=index.js.map
5337
5496
  //# sourceMappingURL=index.js.map