@componentor/fs 3.0.25 → 3.0.26

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.
@@ -40,8 +40,8 @@ var INODE = {
40
40
  // uint32 - byte offset into path table
41
41
  PATH_LENGTH: 8,
42
42
  // uint16 - length of path string
43
- RESERVED_10: 10,
44
- // uint16
43
+ NLINK: 10,
44
+ // uint16 - hard link count
45
45
  MODE: 12,
46
46
  // uint32 - permissions (e.g. 0o100644)
47
47
  SIZE: 16,
@@ -415,6 +415,7 @@ var VFSEngine = class {
415
415
  type,
416
416
  pathOffset,
417
417
  pathLength,
418
+ nlink: inodeView.getUint16(off + INODE.NLINK, true) || 1,
418
419
  mode: inodeView.getUint32(off + INODE.MODE, true),
419
420
  size,
420
421
  firstBlock,
@@ -449,6 +450,7 @@ var VFSEngine = class {
449
450
  type: v.getUint8(INODE.TYPE),
450
451
  pathOffset: v.getUint32(INODE.PATH_OFFSET, true),
451
452
  pathLength: v.getUint16(INODE.PATH_LENGTH, true),
453
+ nlink: v.getUint16(INODE.NLINK, true) || 1,
452
454
  mode: v.getUint32(INODE.MODE, true),
453
455
  size: v.getFloat64(INODE.SIZE, true),
454
456
  firstBlock: v.getUint32(INODE.FIRST_BLOCK, true),
@@ -475,7 +477,7 @@ var VFSEngine = class {
475
477
  v.setUint8(INODE.FLAGS + 2, 0);
476
478
  v.setUint32(INODE.PATH_OFFSET, inode.pathOffset, true);
477
479
  v.setUint16(INODE.PATH_LENGTH, inode.pathLength, true);
478
- v.setUint16(INODE.RESERVED_10, 0, true);
480
+ v.setUint16(INODE.NLINK, inode.nlink, true);
479
481
  v.setUint32(INODE.MODE, inode.mode, true);
480
482
  v.setFloat64(INODE.SIZE, inode.size, true);
481
483
  v.setUint32(INODE.FIRST_BLOCK, inode.firstBlock, true);
@@ -717,6 +719,7 @@ var VFSEngine = class {
717
719
  type,
718
720
  pathOffset: pathOff,
719
721
  pathLength: pathLen,
722
+ nlink: type === INODE_TYPE.DIRECTORY ? 2 : 1,
720
723
  mode,
721
724
  size,
722
725
  firstBlock,
@@ -869,6 +872,7 @@ var VFSEngine = class {
869
872
  if (idx === void 0) return { status: CODE_TO_STATUS.ENOENT };
870
873
  const inode = this.readInode(idx);
871
874
  if (inode.type === INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.EISDIR };
875
+ inode.nlink = Math.max(0, inode.nlink - 1);
872
876
  this.freeBlockRange(inode.firstBlock, inode.blockCount);
873
877
  inode.type = INODE_TYPE.FREE;
874
878
  this.writeInode(idx, inode);
@@ -893,7 +897,21 @@ var VFSEngine = class {
893
897
  }
894
898
  encodeStatResponse(idx) {
895
899
  const inode = this.readInode(idx);
896
- const buf = new Uint8Array(49);
900
+ let nlink = inode.nlink;
901
+ if (inode.type === INODE_TYPE.DIRECTORY) {
902
+ const path = this.readPath(inode.pathOffset, inode.pathLength);
903
+ const children = this.getDirectChildren(path);
904
+ let subdirCount = 0;
905
+ for (const child of children) {
906
+ const childIdx = this.pathIndex.get(child);
907
+ if (childIdx !== void 0) {
908
+ const childInode = this.readInode(childIdx);
909
+ if (childInode.type === INODE_TYPE.DIRECTORY) subdirCount++;
910
+ }
911
+ }
912
+ nlink = 2 + subdirCount;
913
+ }
914
+ const buf = new Uint8Array(53);
897
915
  const view = new DataView(buf.buffer);
898
916
  view.setUint8(0, inode.type);
899
917
  view.setUint32(1, inode.mode, true);
@@ -904,6 +922,7 @@ var VFSEngine = class {
904
922
  view.setUint32(37, inode.uid, true);
905
923
  view.setUint32(41, inode.gid, true);
906
924
  view.setUint32(45, idx, true);
925
+ view.setUint32(49, nlink, true);
907
926
  return { status: 0, data: buf };
908
927
  }
909
928
  // ---- MKDIR ----
@@ -1216,9 +1235,26 @@ var VFSEngine = class {
1216
1235
  const target = this.readData(inode.firstBlock, inode.blockCount, inode.size);
1217
1236
  return { status: 0, data: target };
1218
1237
  }
1219
- // ---- LINK (hard link — copies the file) ----
1238
+ // ---- LINK (hard link — copies the file data, tracks nlink) ----
1220
1239
  link(existingPath, newPath) {
1221
- return this.copy(existingPath, newPath);
1240
+ existingPath = this.normalizePath(existingPath);
1241
+ newPath = this.normalizePath(newPath);
1242
+ const srcIdx = this.resolvePathComponents(existingPath, true);
1243
+ if (srcIdx === void 0) return { status: CODE_TO_STATUS.ENOENT };
1244
+ const srcInode = this.readInode(srcIdx);
1245
+ if (srcInode.type === INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.EPERM };
1246
+ if (this.pathIndex.has(newPath)) return { status: CODE_TO_STATUS.EEXIST };
1247
+ const result = this.copy(existingPath, newPath);
1248
+ if (result.status !== 0) return result;
1249
+ srcInode.nlink++;
1250
+ this.writeInode(srcIdx, srcInode);
1251
+ const destIdx = this.pathIndex.get(newPath);
1252
+ if (destIdx !== void 0) {
1253
+ const destInode = this.readInode(destIdx);
1254
+ destInode.nlink = srcInode.nlink;
1255
+ this.writeInode(destIdx, destInode);
1256
+ }
1257
+ return { status: 0 };
1222
1258
  }
1223
1259
  // ---- OPEN (file descriptor) ----
1224
1260
  open(path, flags, tabId2) {
@@ -1550,7 +1586,7 @@ var OPFSEngine = class {
1550
1586
  return dir;
1551
1587
  }
1552
1588
  encodeStat(kind, size, mtime, ino) {
1553
- const buf = new Uint8Array(49);
1589
+ const buf = new Uint8Array(53);
1554
1590
  const view = new DataView(buf.buffer);
1555
1591
  view.setUint8(0, kind === "file" ? TYPE_FILE : TYPE_DIRECTORY);
1556
1592
  view.setUint32(1, kind === "file" ? 33188 : 16877, true);
@@ -1561,6 +1597,7 @@ var OPFSEngine = class {
1561
1597
  view.setUint32(37, this.processUid, true);
1562
1598
  view.setUint32(41, this.processGid, true);
1563
1599
  view.setUint32(45, ino, true);
1600
+ view.setUint32(49, kind === "directory" ? 2 : 1, true);
1564
1601
  return buf;
1565
1602
  }
1566
1603
  // ========== FS Operations ==========
@@ -2245,7 +2282,7 @@ function handleRequest(reqTabId, buffer) {
2245
2282
  result = engine.exists(path);
2246
2283
  break;
2247
2284
  case OP.TRUNCATE: {
2248
- const len = data ? new DataView(data.buffer, data.byteOffset, data.byteLength).getUint32(0, true) : 0;
2285
+ const len = data ? new DataView(data.buffer, data.byteOffset, data.byteLength).getFloat64(0, true) : 0;
2249
2286
  result = engine.truncate(path, len);
2250
2287
  if (result.status === 0) {
2251
2288
  syncOp = op;
@@ -2337,26 +2374,26 @@ function handleRequest(reqTabId, buffer) {
2337
2374
  break;
2338
2375
  }
2339
2376
  case OP.FREAD: {
2340
- if (!data || data.byteLength < 12) {
2377
+ if (!data || data.byteLength < 16) {
2341
2378
  result = { status: 7 };
2342
2379
  break;
2343
2380
  }
2344
2381
  const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);
2345
2382
  const fd = dv.getUint32(0, true);
2346
2383
  const length = dv.getUint32(4, true);
2347
- const pos = dv.getInt32(8, true);
2384
+ const pos = dv.getFloat64(8, true);
2348
2385
  result = engine.fread(fd, length, pos === -1 ? null : pos);
2349
2386
  break;
2350
2387
  }
2351
2388
  case OP.FWRITE: {
2352
- if (!data || data.byteLength < 8) {
2389
+ if (!data || data.byteLength < 12) {
2353
2390
  result = { status: 7 };
2354
2391
  break;
2355
2392
  }
2356
2393
  const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);
2357
2394
  const fd = dv.getUint32(0, true);
2358
- const pos = dv.getInt32(4, true);
2359
- const writeData = data.subarray(8);
2395
+ const pos = dv.getFloat64(4, true);
2396
+ const writeData = data.subarray(12);
2360
2397
  result = engine.fwrite(fd, writeData, pos === -1 ? null : pos);
2361
2398
  if (result.status === 0) {
2362
2399
  syncOp = op;
@@ -2370,13 +2407,13 @@ function handleRequest(reqTabId, buffer) {
2370
2407
  break;
2371
2408
  }
2372
2409
  case OP.FTRUNCATE: {
2373
- if (!data || data.byteLength < 8) {
2410
+ if (!data || data.byteLength < 12) {
2374
2411
  result = { status: 7 };
2375
2412
  break;
2376
2413
  }
2377
2414
  const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);
2378
2415
  const fd = dv.getUint32(0, true);
2379
- const len = dv.getUint32(4, true);
2416
+ const len = dv.getFloat64(4, true);
2380
2417
  result = engine.ftruncate(fd, len);
2381
2418
  if (result.status === 0) {
2382
2419
  syncOp = op;
@@ -2472,7 +2509,7 @@ async function handleRequestOPFS(reqTabId, buffer) {
2472
2509
  result = await oe.exists(path);
2473
2510
  break;
2474
2511
  case OP.TRUNCATE: {
2475
- const len = data ? new DataView(data.buffer, data.byteOffset, data.byteLength).getUint32(0, true) : 0;
2512
+ const len = data ? new DataView(data.buffer, data.byteOffset, data.byteLength).getFloat64(0, true) : 0;
2476
2513
  result = await oe.truncate(path, len);
2477
2514
  syncPath = path;
2478
2515
  break;
@@ -2535,23 +2572,24 @@ async function handleRequestOPFS(reqTabId, buffer) {
2535
2572
  break;
2536
2573
  }
2537
2574
  case OP.FREAD: {
2538
- if (!data || data.byteLength < 12) {
2575
+ if (!data || data.byteLength < 16) {
2539
2576
  result = { status: 7 };
2540
2577
  break;
2541
2578
  }
2542
2579
  const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);
2543
- result = await oe.fread(dv.getUint32(0, true), dv.getUint32(4, true), dv.getInt32(8, true) === -1 ? null : dv.getInt32(8, true));
2580
+ const pos = dv.getFloat64(8, true);
2581
+ result = await oe.fread(dv.getUint32(0, true), dv.getUint32(4, true), pos === -1 ? null : pos);
2544
2582
  break;
2545
2583
  }
2546
2584
  case OP.FWRITE: {
2547
- if (!data || data.byteLength < 8) {
2585
+ if (!data || data.byteLength < 12) {
2548
2586
  result = { status: 7 };
2549
2587
  break;
2550
2588
  }
2551
2589
  const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);
2552
2590
  const fd = dv.getUint32(0, true);
2553
- const pos = dv.getInt32(4, true);
2554
- result = await oe.fwrite(fd, data.subarray(8), pos === -1 ? null : pos);
2591
+ const pos = dv.getFloat64(4, true);
2592
+ result = await oe.fwrite(fd, data.subarray(12), pos === -1 ? null : pos);
2555
2593
  syncPath = oe.getPathForFd(fd) ?? void 0;
2556
2594
  break;
2557
2595
  }
@@ -2561,12 +2599,12 @@ async function handleRequestOPFS(reqTabId, buffer) {
2561
2599
  break;
2562
2600
  }
2563
2601
  case OP.FTRUNCATE: {
2564
- if (!data || data.byteLength < 8) {
2602
+ if (!data || data.byteLength < 12) {
2565
2603
  result = { status: 7 };
2566
2604
  break;
2567
2605
  }
2568
2606
  const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);
2569
- result = await oe.ftruncate(dv.getUint32(0, true), dv.getUint32(4, true));
2607
+ result = await oe.ftruncate(dv.getUint32(0, true), dv.getFloat64(4, true));
2570
2608
  syncPath = oe.getPathForFd(dv.getUint32(0, true)) ?? void 0;
2571
2609
  break;
2572
2610
  }