@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 +107 -10
- package/dist/index.js +227 -188
- package/dist/index.js.map +1 -1
- package/dist/workers/repair.worker.js +1678 -0
- package/dist/workers/repair.worker.js.map +1 -0
- package/dist/workers/server.worker.js +34 -6
- package/dist/workers/server.worker.js.map +1 -1
- package/dist/workers/sync-relay.worker.js +828 -14
- package/dist/workers/sync-relay.worker.js.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
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
|
-
###
|
|
89
|
+
### Filesystem Modes
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
The `mode` option controls how the filesystem stores data:
|
|
92
92
|
|
|
93
|
-
|
|
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
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
-
//
|
|
105
|
-
|
|
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:**
|