@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.
- package/dist/index.d.mts +92 -11
- package/dist/index.js +1234 -483
- package/dist/index.js.map +1 -1
- package/dist/workers/async-relay.worker.js +5 -5
- package/dist/workers/async-relay.worker.js.map +1 -1
- package/dist/workers/repair.worker.js +42 -6
- package/dist/workers/repair.worker.js.map +1 -1
- package/dist/workers/server.worker.js +47 -11
- package/dist/workers/server.worker.js.map +1 -1
- package/dist/workers/sync-relay.worker.js +61 -23
- package/dist/workers/sync-relay.worker.js.map +1 -1
- package/package.json +1 -1
|
@@ -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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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).
|
|
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 <
|
|
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.
|
|
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 <
|
|
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.
|
|
2359
|
-
const writeData = data.subarray(
|
|
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 <
|
|
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.
|
|
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).
|
|
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 <
|
|
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
|
-
|
|
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 <
|
|
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.
|
|
2554
|
-
result = await oe.fwrite(fd, data.subarray(
|
|
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 <
|
|
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.
|
|
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
|
}
|