@componentor/fs 3.0.9 → 3.0.11

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/README.md CHANGED
@@ -74,7 +74,7 @@ await init(); // initializes the default singleton
74
74
  ```typescript
75
75
  const fs = new VFSFileSystem({
76
76
  root: '/', // OPFS root directory (default: '/')
77
- opfsSync: true, // Mirror VFS to real OPFS files (default: true)
77
+ mode: 'hybrid', // 'hybrid' | 'vfs' | 'opfs' (default: 'hybrid')
78
78
  opfsSyncRoot: undefined, // Custom OPFS root for mirroring (default: same as root)
79
79
  uid: 0, // User ID for file ownership (default: 0)
80
80
  gid: 0, // Group ID for file ownership (default: 0)
@@ -86,25 +86,73 @@ const fs = new VFSFileSystem({
86
86
  });
87
87
  ```
88
88
 
89
- ### OPFS Sync
89
+ ### Filesystem Modes
90
90
 
91
- When `opfsSync` is enabled (the default), VFS mutations are mirrored to real OPFS files in the background:
91
+ The `mode` option controls how the filesystem stores data:
92
92
 
93
- - **VFS OPFS**: Every write, delete, mkdir, rename is replicated to real OPFS files after the sync operation completes (zero performance impact on the hot path)
93
+ | Mode | Storage | OPFS Sync | Speed | Resilience |
94
+ |------|---------|-----------|-------|------------|
95
+ | `hybrid` (default) | VFS binary + OPFS mirror | Bidirectional | Fast | High |
96
+ | `vfs` | VFS binary only | None | Fastest | Medium |
97
+ | `opfs` | Real OPFS files only | N/A | Slower | Highest |
98
+
99
+ ```typescript
100
+ // Hybrid mode (default) — best of both worlds
101
+ const fs = new VFSFileSystem({ mode: 'hybrid' });
102
+ fs.writeFileSync('/file.txt', 'data');
103
+ // → stored in .vfs.bin AND mirrored to real OPFS files
104
+
105
+ // VFS-only mode — maximum performance, no OPFS mirroring
106
+ const fastFs = new VFSFileSystem({ mode: 'vfs' });
107
+
108
+ // OPFS-only mode — no VFS binary, operates directly on OPFS files
109
+ const safeFs = new VFSFileSystem({ mode: 'opfs' });
110
+ ```
111
+
112
+ **Hybrid mode** mirrors all VFS mutations to real OPFS files in the background:
113
+
114
+ - **VFS → OPFS**: Every write, delete, mkdir, rename is replicated after the sync operation completes (zero performance impact on the hot path)
94
115
  - **OPFS → VFS**: A `FileSystemObserver` watches for external changes and syncs them back (Chrome 129+)
95
116
 
96
117
  This allows external tools (browser DevTools, OPFS extensions) to see and modify files while VFS handles all the fast read/write operations internally.
97
118
 
119
+ #### Corruption Fallback
120
+
121
+ In `hybrid` mode, if VFS corruption is detected during initialization, the filesystem automatically falls back to `opfs` mode. The `init()` call rejects with an error describing the corruption, but all filesystem operations continue working via OPFS:
122
+
98
123
  ```typescript
99
- // OPFS sync enabled (default)
100
- const fs = new VFSFileSystem({ opfsSync: true });
101
- fs.writeFileSync('/file.txt', 'data');
102
- // → /file.txt also appears in OPFS (visible in DevTools > Application > Storage)
124
+ const fs = new VFSFileSystem(); // hybrid mode
125
+
126
+ try {
127
+ await fs.init();
128
+ } catch (err) {
129
+ // VFS was corrupt — system is now running in OPFS mode
130
+ console.warn(err.message); // "Falling back to OPFS mode: <reason>"
131
+ console.log(fs.mode); // 'opfs'
132
+ }
103
133
 
104
- // Disable for maximum performance (no OPFS mirroring)
105
- const fastFs = new VFSFileSystem({ opfsSync: false });
134
+ // Filesystem still works reads/writes go through OPFS
135
+ fs.writeFileSync('/file.txt', 'still works!');
106
136
  ```
107
137
 
138
+ #### Runtime Mode Switching
139
+
140
+ Use `setMode()` to switch modes at runtime. This is useful for IDE workflows where you want to recover from corruption:
141
+
142
+ ```typescript
143
+ // Corruption detected, currently in OPFS fallback mode
144
+ console.log(fs.mode); // 'opfs'
145
+
146
+ // Repair the VFS binary
147
+ await repairVFS('/my-app');
148
+
149
+ // Switch back to hybrid mode
150
+ await fs.setMode('hybrid');
151
+ console.log(fs.mode); // 'hybrid'
152
+ ```
153
+
154
+ `setMode()` terminates internal workers, allocates fresh shared memory, and reinitializes the filesystem in the requested mode.
155
+
108
156
  ## COOP/COEP Headers
109
157
 
110
158
  To enable the sync API, your page must be `crossOriginIsolated`. Add these headers:
@@ -309,6 +357,19 @@ await writer.write(new Uint8Array([1, 2, 3]));
309
357
  await writer.close();
310
358
  ```
311
359
 
360
+ ### Instance Methods
361
+
362
+ ```typescript
363
+ // Get the current filesystem mode
364
+ fs.mode: 'hybrid' | 'vfs' | 'opfs'
365
+
366
+ // Switch mode at runtime (terminates workers, reinitializes)
367
+ await fs.setMode('hybrid' | 'vfs' | 'opfs'): Promise<void>
368
+
369
+ // Non-blocking async init (waits for VFS to be ready)
370
+ await fs.init(): Promise<void>
371
+ ```
372
+
312
373
  ### Watch API
313
374
 
314
375
  ```typescript
@@ -509,6 +570,42 @@ Make sure `opfsSync` is enabled (it's `true` by default). Files are mirrored to
509
570
 
510
571
  ## Changelog
511
572
 
573
+ ### v3.0.11 (2026)
574
+
575
+ **Fixes:**
576
+ - Emit TypeScript declaration files (`dts: true` in tsup config)
577
+
578
+ ### v3.0.10 (2026)
579
+
580
+ **New: Three filesystem modes (`hybrid`, `vfs`, `opfs`)**
581
+ - `mode: 'hybrid'` (default) — VFS binary + bidirectional OPFS sync
582
+ - `mode: 'vfs'` — VFS binary only, no OPFS mirroring (fastest)
583
+ - `mode: 'opfs'` — Pure OPFS files, no VFS binary (most resilient)
584
+ - New `OPFSEngine` implements all fs operations directly on OPFS files
585
+
586
+ **Automatic corruption fallback**
587
+ - Hybrid mode auto-falls back to OPFS mode on VFS corruption
588
+ - `await fs.init()` rejects with descriptive error while system works in OPFS mode
589
+ - `fs.mode` getter reflects current mode (changes to `'opfs'` on fallback)
590
+
591
+ **Runtime mode switching**
592
+ - `await fs.setMode('hybrid' | 'vfs' | 'opfs')` for switching modes at runtime
593
+ - IDE workflow: corruption → OPFS fallback → repair → `setMode('hybrid')`
594
+
595
+ **Corruption detection improvements**
596
+ - `rebuildIndex()` validates every inode: type, path bounds, data block range, path format
597
+ - Fixed `format()` not persisting `pathTableUsed` after root inode creation
598
+
599
+ **Repair safety**
600
+ - Dedicated repair worker with `createSyncAccessHandle` — no RAM bloat
601
+ - Original `.vfs.bin` is never deleted until replacement is verified via re-mount
602
+ - Copy-then-delete swap: crash mid-copy leaves `.vfs.bin.tmp` intact for retry
603
+ - `loadFromOPFS` builds in temp file first — original untouched until verified
604
+ - Strict UTF-8 decoding for recovered paths and symlink targets (rejects invalid sequences)
605
+ - `contentLost` flag on repair entries distinguishes empty files from files with lost data
606
+ - Repair aborts after 5 critical `mkdir` failures (fail-fast threshold)
607
+ - Orphaned `.vfs.bin.tmp` files cleaned up automatically on repair entry
608
+
512
609
  ### v3.0.9 (2026)
513
610
 
514
611
  **Improvements:**