@componentor/fs 3.0.52 → 3.0.53

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
@@ -348,6 +348,12 @@ declare class VFSFileSystem {
348
348
  private rejectReady;
349
349
  private initError;
350
350
  private isReady;
351
+ /** True while a leader transition is in flight (promotion to leader, etc.).
352
+ * Cleared the moment the new sync-relay signals `ready`. Consumers can
353
+ * combine this with `isReady` to know when sync FS ops are safe again. */
354
+ private transitioning;
355
+ /** Listeners awaiting the next `ready` signal (used by `whenReady()`). */
356
+ private readyListeners;
351
357
  private config;
352
358
  private tabId;
353
359
  private _mode;
@@ -514,6 +520,23 @@ declare class VFSFileSystem {
514
520
  * Rejects with corruption error if VFS was corrupt (but system falls back to OPFS mode).
515
521
  * Callers can catch and continue — the fs API works in OPFS mode after rejection. */
516
522
  init(): Promise<void>;
523
+ /** True only while the filesystem is fully ready for synchronous operations
524
+ * AND no leader transition is in progress. Reflects the moment-in-time state;
525
+ * use `whenReady()` to await readiness reliably. */
526
+ get ready(): boolean;
527
+ /** Resolves once the filesystem is fully ready for synchronous operations,
528
+ * including any in-flight leader transition (promotion-to-leader, etc.).
529
+ * If already ready and no transition is pending, resolves immediately.
530
+ *
531
+ * Use this when coordinating with other Web-Lock-based systems (e.g. a
532
+ * parent app that elects its own leader independently of the FS) — the
533
+ * timing of the two elections isn't synchronized, so the FS may still be
534
+ * reinitialising when the parent's lock fires. Calling `whenReady()`
535
+ * after your own leader-acquisition guarantees the FS is back in a state
536
+ * where sync ops won't stall the 20-second relay-worker heartbeat. */
537
+ whenReady(): Promise<void>;
538
+ /** Internal — called by lifecycle handlers when sync-relay says 'ready'. */
539
+ private fireReadyListeners;
517
540
  /** Switch the filesystem mode at runtime.
518
541
  *
519
542
  * Typical flow for IDE corruption recovery:
package/dist/index.js CHANGED
@@ -2616,6 +2616,12 @@ var VFSFileSystem = class {
2616
2616
  rejectReady;
2617
2617
  initError = null;
2618
2618
  isReady = false;
2619
+ /** True while a leader transition is in flight (promotion to leader, etc.).
2620
+ * Cleared the moment the new sync-relay signals `ready`. Consumers can
2621
+ * combine this with `isReady` to know when sync FS ops are safe again. */
2622
+ transitioning = false;
2623
+ /** Listeners awaiting the next `ready` signal (used by `whenReady()`). */
2624
+ readyListeners = /* @__PURE__ */ new Set();
2619
2625
  // Config (definite assignment — always set when constructor doesn't return singleton)
2620
2626
  config;
2621
2627
  tabId;
@@ -2691,8 +2697,10 @@ var VFSFileSystem = class {
2691
2697
  const msg = e.data;
2692
2698
  if (msg.type === "ready") {
2693
2699
  this.isReady = true;
2700
+ this.transitioning = false;
2694
2701
  this.initAsyncRelay();
2695
2702
  this.resolveReady();
2703
+ this.fireReadyListeners();
2696
2704
  if (!this.isFollower) {
2697
2705
  this.initLeaderBroker();
2698
2706
  }
@@ -2963,6 +2971,7 @@ var VFSFileSystem = class {
2963
2971
  promoteToLeader() {
2964
2972
  this.isFollower = false;
2965
2973
  this.isReady = false;
2974
+ this.transitioning = true;
2966
2975
  this.brokerInitialized = false;
2967
2976
  if (this.brokerHeartbeatTimer) {
2968
2977
  clearInterval(this.brokerHeartbeatTimer);
@@ -2999,7 +3008,9 @@ var VFSFileSystem = class {
2999
3008
  const msg = e.data;
3000
3009
  if (msg.type === "ready") {
3001
3010
  this.isReady = true;
3011
+ this.transitioning = false;
3002
3012
  this.resolveReady();
3013
+ this.fireReadyListeners();
3003
3014
  this.initLeaderBroker();
3004
3015
  } else if (msg.type === "init-failed") {
3005
3016
  if (msg.error?.startsWith("Corrupt VFS:")) {
@@ -3614,6 +3625,44 @@ var VFSFileSystem = class {
3614
3625
  }
3615
3626
  });
3616
3627
  }
3628
+ /** True only while the filesystem is fully ready for synchronous operations
3629
+ * AND no leader transition is in progress. Reflects the moment-in-time state;
3630
+ * use `whenReady()` to await readiness reliably. */
3631
+ get ready() {
3632
+ return this.isReady && !this.transitioning;
3633
+ }
3634
+ /** Resolves once the filesystem is fully ready for synchronous operations,
3635
+ * including any in-flight leader transition (promotion-to-leader, etc.).
3636
+ * If already ready and no transition is pending, resolves immediately.
3637
+ *
3638
+ * Use this when coordinating with other Web-Lock-based systems (e.g. a
3639
+ * parent app that elects its own leader independently of the FS) — the
3640
+ * timing of the two elections isn't synchronized, so the FS may still be
3641
+ * reinitialising when the parent's lock fires. Calling `whenReady()`
3642
+ * after your own leader-acquisition guarantees the FS is back in a state
3643
+ * where sync ops won't stall the 20-second relay-worker heartbeat. */
3644
+ whenReady() {
3645
+ if (this.isReady && !this.transitioning) return Promise.resolve();
3646
+ if (this.transitioning) {
3647
+ return new Promise((resolve2) => {
3648
+ this.readyListeners.add(resolve2);
3649
+ });
3650
+ }
3651
+ return this.readyPromise.then(() => {
3652
+ });
3653
+ }
3654
+ /** Internal — called by lifecycle handlers when sync-relay says 'ready'. */
3655
+ fireReadyListeners() {
3656
+ const listeners = Array.from(this.readyListeners);
3657
+ this.readyListeners.clear();
3658
+ for (const l of listeners) {
3659
+ try {
3660
+ l();
3661
+ } catch (e) {
3662
+ console.warn("[VFS] readyListener threw:", e);
3663
+ }
3664
+ }
3665
+ }
3617
3666
  /** Switch the filesystem mode at runtime.
3618
3667
  *
3619
3668
  * Typical flow for IDE corruption recovery:
@@ -3651,7 +3700,9 @@ var VFSFileSystem = class {
3651
3700
  const msg = e.data;
3652
3701
  if (msg.type === "ready") {
3653
3702
  this.isReady = true;
3703
+ this.transitioning = false;
3654
3704
  this.resolveReady();
3705
+ this.fireReadyListeners();
3655
3706
  if (!this.isFollower) {
3656
3707
  this.initLeaderBroker();
3657
3708
  }