@componentor/fs 3.0.21 → 3.0.23

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.
@@ -653,6 +653,16 @@ var VFSEngine = class {
653
653
  }
654
654
  /** Resolve symlinks in intermediate path components */
655
655
  resolvePathComponents(path, followLast = true, depth = 0) {
656
+ const result = this.resolvePathFull(path, followLast, depth);
657
+ return result?.idx;
658
+ }
659
+ /**
660
+ * Resolve a path following symlinks, returning both the inode index AND the
661
+ * fully resolved path. This is needed by readdir: when listing a symlinked
662
+ * directory, we must search for children under the resolved target path
663
+ * (where files actually exist in pathIndex), not under the symlink path.
664
+ */
665
+ resolvePathFull(path, followLast = true, depth = 0) {
656
666
  if (depth > MAX_SYMLINK_DEPTH) return void 0;
657
667
  const parts = path.split("/").filter(Boolean);
658
668
  let current = "/";
@@ -666,14 +676,16 @@ var VFSEngine = class {
666
676
  const target = decoder.decode(this.readData(inode.firstBlock, inode.blockCount, inode.size));
667
677
  const resolved = target.startsWith("/") ? target : this.resolveRelative(current, target);
668
678
  if (isLast) {
669
- return this.resolvePathComponents(resolved, true, depth + 1);
679
+ return this.resolvePathFull(resolved, true, depth + 1);
670
680
  }
671
681
  const remaining = parts.slice(i + 1).join("/");
672
682
  const newPath = resolved + (remaining ? "/" + remaining : "");
673
- return this.resolvePathComponents(newPath, followLast, depth + 1);
683
+ return this.resolvePathFull(newPath, followLast, depth + 1);
674
684
  }
675
685
  }
676
- return this.pathIndex.get(current);
686
+ const finalIdx = this.pathIndex.get(current);
687
+ if (finalIdx === void 0) return void 0;
688
+ return { idx: finalIdx, resolvedPath: current };
677
689
  }
678
690
  resolveRelative(from, target) {
679
691
  const dir = from.substring(0, from.lastIndexOf("/")) || "/";
@@ -872,10 +884,10 @@ var VFSEngine = class {
872
884
  if (idx === void 0) return { status: CODE_TO_STATUS.ENOENT, data: null };
873
885
  return this.encodeStatResponse(idx);
874
886
  }
875
- // ---- LSTAT (no symlink follow) ----
887
+ // ---- LSTAT (no symlink follow for the FINAL component) ----
876
888
  lstat(path) {
877
889
  path = this.normalizePath(path);
878
- const idx = this.pathIndex.get(path);
890
+ const idx = this.resolvePathComponents(path, false);
879
891
  if (idx === void 0) return { status: CODE_TO_STATUS.ENOENT, data: null };
880
892
  return this.encodeStatResponse(idx);
881
893
  }
@@ -962,12 +974,12 @@ var VFSEngine = class {
962
974
  // ---- READDIR ----
963
975
  readdir(path, flags = 0) {
964
976
  path = this.normalizePath(path);
965
- const idx = this.resolvePathComponents(path, true);
966
- if (idx === void 0) return { status: CODE_TO_STATUS.ENOENT, data: null };
967
- const inode = this.readInode(idx);
977
+ const resolved = this.resolvePathFull(path, true);
978
+ if (!resolved) return { status: CODE_TO_STATUS.ENOENT, data: null };
979
+ const inode = this.readInode(resolved.idx);
968
980
  if (inode.type !== INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.ENOTDIR, data: null };
969
981
  const withFileTypes = (flags & 1) !== 0;
970
- const children = this.getDirectChildren(path);
982
+ const children = this.getDirectChildren(resolved.resolvedPath);
971
983
  if (withFileTypes) {
972
984
  let totalSize2 = 4;
973
985
  const entries = [];
@@ -2573,6 +2585,35 @@ async function handleRequestOPFS(reqTabId, buffer) {
2573
2585
  default:
2574
2586
  result = { status: 7 };
2575
2587
  }
2588
+ const ENOENT_STATUS = 1;
2589
+ const READ_OPS = [OP.READ, OP.STAT, OP.LSTAT, OP.READDIR, OP.EXISTS, OP.ACCESS, OP.REALPATH, OP.READLINK];
2590
+ if (result.status === ENOENT_STATUS && READ_OPS.includes(op)) {
2591
+ const vfsResult = (() => {
2592
+ switch (op) {
2593
+ case OP.READ:
2594
+ return engine.read(path);
2595
+ case OP.STAT:
2596
+ return engine.stat(path);
2597
+ case OP.LSTAT:
2598
+ return engine.lstat(path);
2599
+ case OP.READDIR:
2600
+ return engine.readdir(path, flags);
2601
+ case OP.EXISTS:
2602
+ return engine.exists(path);
2603
+ case OP.ACCESS:
2604
+ return engine.access(path, flags);
2605
+ case OP.REALPATH:
2606
+ return engine.realpath(path);
2607
+ case OP.READLINK:
2608
+ return engine.readlink(path);
2609
+ default:
2610
+ return null;
2611
+ }
2612
+ })();
2613
+ if (vfsResult && vfsResult.status !== ENOENT_STATUS) {
2614
+ result = vfsResult;
2615
+ }
2616
+ }
2576
2617
  const ret = {
2577
2618
  status: result.status,
2578
2619
  data: result.data instanceof Uint8Array ? result.data : void 0
@@ -2690,7 +2731,7 @@ async function leaderLoop() {
2690
2731
  if (debug) {
2691
2732
  console.log(`[leaderLoop] readPayload=${(lt1 - lt0).toFixed(3)}ms handleRequest=${(lt2 - lt1).toFixed(3)}ms writeResponse=${(lt3 - lt2).toFixed(3)}ms TOTAL=${(lt3 - lt0).toFixed(3)}ms`);
2692
2733
  }
2693
- const waitResult = Atomics.wait(ctrl, 0, SIGNAL.RESPONSE, 10);
2734
+ const waitResult = Atomics.wait(ctrl, 0, SIGNAL.RESPONSE, 100);
2694
2735
  if (waitResult === "timed-out") {
2695
2736
  Atomics.store(ctrl, 0, SIGNAL.IDLE);
2696
2737
  }
@@ -2702,12 +2743,8 @@ async function leaderLoop() {
2702
2743
  const asyncResult = handleRequest(tabId, payload.buffer);
2703
2744
  writeDirectResponse(asyncSab, asyncCtrl, asyncResult.status, asyncResult.data);
2704
2745
  if (asyncResult._op !== void 0) notifyOPFSSync(asyncResult._op, asyncResult._path, asyncResult._newPath);
2705
- for (let i = 0; i < 500; i++) {
2706
- if (Atomics.load(asyncCtrl, 0) === SIGNAL.IDLE) break;
2707
- Atomics.wait(asyncCtrl, 0, Atomics.load(asyncCtrl, 0), 10);
2708
- }
2709
2746
  if (Atomics.load(asyncCtrl, 0) !== SIGNAL.IDLE) {
2710
- Atomics.store(asyncCtrl, 0, SIGNAL.IDLE);
2747
+ Atomics.wait(asyncCtrl, 0, SIGNAL.RESPONSE, 5e3);
2711
2748
  }
2712
2749
  processed = true;
2713
2750
  continue;
@@ -2742,7 +2779,7 @@ async function leaderLoopOPFS() {
2742
2779
  const payload = readPayload(sab, ctrl);
2743
2780
  const reqResult = await handleRequestOPFS(tabId, payload.buffer);
2744
2781
  writeDirectResponse(sab, ctrl, reqResult.status, reqResult.data);
2745
- const waitResult = Atomics.wait(ctrl, 0, SIGNAL.RESPONSE, 10);
2782
+ const waitResult = Atomics.wait(ctrl, 0, SIGNAL.RESPONSE, 100);
2746
2783
  if (waitResult === "timed-out") {
2747
2784
  Atomics.store(ctrl, 0, SIGNAL.IDLE);
2748
2785
  }
@@ -2753,7 +2790,7 @@ async function leaderLoopOPFS() {
2753
2790
  const payload = readPayload(asyncSab, asyncCtrl);
2754
2791
  const asyncResult = await handleRequestOPFS(tabId, payload.buffer);
2755
2792
  writeDirectResponse(asyncSab, asyncCtrl, asyncResult.status, asyncResult.data);
2756
- const waitResult = Atomics.wait(asyncCtrl, 0, SIGNAL.RESPONSE, 10);
2793
+ const waitResult = Atomics.wait(asyncCtrl, 0, SIGNAL.RESPONSE, 100);
2757
2794
  if (waitResult === "timed-out") {
2758
2795
  Atomics.store(asyncCtrl, 0, SIGNAL.IDLE);
2759
2796
  }
@@ -2781,7 +2818,7 @@ async function followerLoop() {
2781
2818
  const payload = readPayload(sab, ctrl);
2782
2819
  const response = await forwardToLeader(payload);
2783
2820
  writeResponse(sab, ctrl, new Uint8Array(response));
2784
- const result = Atomics.wait(ctrl, 0, SIGNAL.RESPONSE, 10);
2821
+ const result = Atomics.wait(ctrl, 0, SIGNAL.RESPONSE, 100);
2785
2822
  if (result === "timed-out") {
2786
2823
  Atomics.store(ctrl, 0, SIGNAL.IDLE);
2787
2824
  }
@@ -2791,7 +2828,7 @@ async function followerLoop() {
2791
2828
  const payload = readPayload(asyncSab, asyncCtrl);
2792
2829
  const response = await forwardToLeader(payload);
2793
2830
  writeResponse(asyncSab, asyncCtrl, new Uint8Array(response));
2794
- const result = Atomics.wait(asyncCtrl, 0, SIGNAL.RESPONSE, 10);
2831
+ const result = Atomics.wait(asyncCtrl, 0, SIGNAL.RESPONSE, 100);
2795
2832
  if (result === "timed-out") {
2796
2833
  Atomics.store(asyncCtrl, 0, SIGNAL.IDLE);
2797
2834
  }
@@ -3222,4 +3259,4 @@ self.onmessage = async (e) => {
3222
3259
  return;
3223
3260
  }
3224
3261
  };
3225
- //# sourceMappingURL=sync-relay.worker.js.map
3262
+ //# sourceMappingURL=sync-relay.worker.js.map// FORCE_CACHE_BUST_1775761372