@componentor/fs 3.0.41 → 3.0.42

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.
@@ -1362,6 +1362,40 @@ var VFSEngine = class {
1362
1362
  this.handle.flush();
1363
1363
  return { status: 0 };
1364
1364
  }
1365
+ // ---- FCHMOD ----
1366
+ // fd-based chmod: look up the inode directly from the fd table and mutate
1367
+ // its mode bits. Native Node does the same thing at the libuv layer.
1368
+ fchmod(fd, mode) {
1369
+ const entry = this.fdTable.get(fd);
1370
+ if (!entry) return { status: CODE_TO_STATUS.EBADF };
1371
+ const inode = this.readInode(entry.inodeIdx);
1372
+ inode.mode = inode.mode & S_IFMT | mode & 4095;
1373
+ inode.ctime = Date.now();
1374
+ this.writeInode(entry.inodeIdx, inode);
1375
+ return { status: 0 };
1376
+ }
1377
+ // ---- FCHOWN ----
1378
+ fchown(fd, uid, gid) {
1379
+ const entry = this.fdTable.get(fd);
1380
+ if (!entry) return { status: CODE_TO_STATUS.EBADF };
1381
+ const inode = this.readInode(entry.inodeIdx);
1382
+ inode.uid = uid;
1383
+ inode.gid = gid;
1384
+ inode.ctime = Date.now();
1385
+ this.writeInode(entry.inodeIdx, inode);
1386
+ return { status: 0 };
1387
+ }
1388
+ // ---- FUTIMES ----
1389
+ futimes(fd, atime, mtime) {
1390
+ const entry = this.fdTable.get(fd);
1391
+ if (!entry) return { status: CODE_TO_STATUS.EBADF };
1392
+ const inode = this.readInode(entry.inodeIdx);
1393
+ inode.atime = atime;
1394
+ inode.mtime = mtime;
1395
+ inode.ctime = Date.now();
1396
+ this.writeInode(entry.inodeIdx, inode);
1397
+ return { status: 0 };
1398
+ }
1365
1399
  // ---- OPENDIR ----
1366
1400
  opendir(path, tabId2) {
1367
1401
  path = this.normalizePath(path);
@@ -1856,7 +1890,9 @@ var OPFSEngine = class {
1856
1890
  if (!entry) return { status: ENOENT, data: null };
1857
1891
  return { status: OK, data: encoder2.encode(path) };
1858
1892
  }
1859
- // OPFS doesn't support permissions — these are no-ops
1893
+ // OPFS doesn't support permissions/ownership/timestamps — these succeed as
1894
+ // no-ops when the target exists, mirroring the VFS engine's behavior so
1895
+ // callers can write code that works in both modes.
1860
1896
  async chmod(path, _mode) {
1861
1897
  path = this.normalizePath(path);
1862
1898
  const entry = await this.getEntry(path);
@@ -1875,6 +1911,17 @@ var OPFSEngine = class {
1875
1911
  if (!entry) return { status: ENOENT, data: null };
1876
1912
  return { status: OK, data: null };
1877
1913
  }
1914
+ // fd-based variants: validate the fd and succeed. There's nowhere to store
1915
+ // mode/uid/gid/timestamps in OPFS, so they're accepted and discarded.
1916
+ async fchmod(fd, _mode) {
1917
+ return this.fdTable.has(fd) ? { status: OK, data: null } : { status: EBADF, data: null };
1918
+ }
1919
+ async fchown(fd, _uid, _gid) {
1920
+ return this.fdTable.has(fd) ? { status: OK, data: null } : { status: EBADF, data: null };
1921
+ }
1922
+ async futimes(fd, _atime, _mtime) {
1923
+ return this.fdTable.has(fd) ? { status: OK, data: null } : { status: EBADF, data: null };
1924
+ }
1878
1925
  // OPFS has no symlinks or hard links
1879
1926
  async symlink(_target, _linkPath) {
1880
1927
  return { status: EINVAL, data: null };
@@ -2018,7 +2065,10 @@ var OP = {
2018
2065
  FTRUNCATE: 27,
2019
2066
  FSYNC: 28,
2020
2067
  OPENDIR: 29,
2021
- MKDTEMP: 30
2068
+ MKDTEMP: 30,
2069
+ FCHMOD: 31,
2070
+ FCHOWN: 32,
2071
+ FUTIMES: 33
2022
2072
  };
2023
2073
  var SAB_OFFSETS = {
2024
2074
  CONTROL: 0,
@@ -2446,6 +2496,53 @@ function handleRequest(reqTabId, buffer) {
2446
2496
  syncPath = new TextDecoder().decode(result.data instanceof Uint8Array ? result.data : new Uint8Array(0));
2447
2497
  }
2448
2498
  break;
2499
+ case OP.FCHMOD: {
2500
+ if (!data || data.byteLength < 8) {
2501
+ result = { status: 7 };
2502
+ break;
2503
+ }
2504
+ const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);
2505
+ const fd = dv.getUint32(0, true);
2506
+ const mode = dv.getUint32(4, true);
2507
+ result = engine.fchmod(fd, mode);
2508
+ if (result.status === 0) {
2509
+ syncOp = OP.CHMOD;
2510
+ syncPath = engine.getPathForFd(fd) ?? void 0;
2511
+ }
2512
+ break;
2513
+ }
2514
+ case OP.FCHOWN: {
2515
+ if (!data || data.byteLength < 12) {
2516
+ result = { status: 7 };
2517
+ break;
2518
+ }
2519
+ const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);
2520
+ const fd = dv.getUint32(0, true);
2521
+ const uid = dv.getUint32(4, true);
2522
+ const gid = dv.getUint32(8, true);
2523
+ result = engine.fchown(fd, uid, gid);
2524
+ if (result.status === 0) {
2525
+ syncOp = OP.CHOWN;
2526
+ syncPath = engine.getPathForFd(fd) ?? void 0;
2527
+ }
2528
+ break;
2529
+ }
2530
+ case OP.FUTIMES: {
2531
+ if (!data || data.byteLength < 24) {
2532
+ result = { status: 7 };
2533
+ break;
2534
+ }
2535
+ const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);
2536
+ const fd = dv.getUint32(0, true);
2537
+ const atime = dv.getFloat64(8, true);
2538
+ const mtime = dv.getFloat64(16, true);
2539
+ result = engine.futimes(fd, atime, mtime);
2540
+ if (result.status === 0) {
2541
+ syncOp = OP.UTIMES;
2542
+ syncPath = engine.getPathForFd(fd) ?? void 0;
2543
+ }
2544
+ break;
2545
+ }
2449
2546
  default:
2450
2547
  result = { status: 7 };
2451
2548
  }
@@ -2632,6 +2729,33 @@ async function handleRequestOPFS(reqTabId, buffer) {
2632
2729
  syncPath = new TextDecoder().decode(result.data instanceof Uint8Array ? result.data : new Uint8Array(0));
2633
2730
  }
2634
2731
  break;
2732
+ case OP.FCHMOD: {
2733
+ if (!data || data.byteLength < 8) {
2734
+ result = { status: 7 };
2735
+ break;
2736
+ }
2737
+ const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);
2738
+ result = await oe.fchmod(dv.getUint32(0, true), dv.getUint32(4, true));
2739
+ break;
2740
+ }
2741
+ case OP.FCHOWN: {
2742
+ if (!data || data.byteLength < 12) {
2743
+ result = { status: 7 };
2744
+ break;
2745
+ }
2746
+ const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);
2747
+ result = await oe.fchown(dv.getUint32(0, true), dv.getUint32(4, true), dv.getUint32(8, true));
2748
+ break;
2749
+ }
2750
+ case OP.FUTIMES: {
2751
+ if (!data || data.byteLength < 24) {
2752
+ result = { status: 7 };
2753
+ break;
2754
+ }
2755
+ const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);
2756
+ result = await oe.futimes(dv.getUint32(0, true), dv.getFloat64(8, true), dv.getFloat64(16, true));
2757
+ break;
2758
+ }
2635
2759
  default:
2636
2760
  result = { status: 7 };
2637
2761
  }
@@ -3053,6 +3177,7 @@ function broadcastWatch(op, path, newPath) {
3053
3177
  case OP.CHMOD:
3054
3178
  case OP.CHOWN:
3055
3179
  case OP.UTIMES:
3180
+ case OP.COPY:
3056
3181
  eventType = "change";
3057
3182
  break;
3058
3183
  case OP.UNLINK:
@@ -3062,7 +3187,6 @@ function broadcastWatch(op, path, newPath) {
3062
3187
  case OP.MKDTEMP:
3063
3188
  case OP.SYMLINK:
3064
3189
  case OP.LINK:
3065
- case OP.COPY:
3066
3190
  eventType = "rename";
3067
3191
  break;
3068
3192
  default: