@componentor/fs 3.0.4 → 3.0.5
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 +9 -0
- package/dist/index.js +12 -6
- package/dist/index.js.map +1 -1
- package/dist/workers/service.worker.js +1 -2
- package/dist/workers/service.worker.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -82,6 +82,7 @@ const fs = new VFSFileSystem({
|
|
|
82
82
|
strictPermissions: false, // Enforce Unix permissions (default: false)
|
|
83
83
|
sabSize: 4194304, // SharedArrayBuffer size in bytes (default: 4MB)
|
|
84
84
|
debug: false, // Enable debug logging (default: false)
|
|
85
|
+
swScope: undefined, // Custom service worker scope (default: auto-scoped per root)
|
|
85
86
|
});
|
|
86
87
|
```
|
|
87
88
|
|
|
@@ -508,6 +509,14 @@ Make sure `opfsSync` is enabled (it's `true` by default). Files are mirrored to
|
|
|
508
509
|
|
|
509
510
|
## Changelog
|
|
510
511
|
|
|
512
|
+
### v3.0.5 (2026)
|
|
513
|
+
|
|
514
|
+
**Fixes:**
|
|
515
|
+
- Scope the internal service worker by default so it won't collide with the host application's own service worker
|
|
516
|
+
- Remove unnecessary `clients.claim()` from the service worker — it only acts as a MessagePort broker and never needs to control pages
|
|
517
|
+
- Namespace leader lock, BroadcastChannel, and SW scope by `root` so multiple `VFSFileSystem` instances with different roots don't collide
|
|
518
|
+
- Add `swScope` config option for custom service worker scope override
|
|
519
|
+
|
|
511
520
|
### v3.0.4 (2026)
|
|
512
521
|
|
|
513
522
|
**Features:**
|
package/dist/index.js
CHANGED
|
@@ -1302,6 +1302,9 @@ var VFSFileSystem = class {
|
|
|
1302
1302
|
// Config
|
|
1303
1303
|
config;
|
|
1304
1304
|
tabId;
|
|
1305
|
+
/** Namespace string derived from root — used for lock names, BroadcastChannel, and SW scope
|
|
1306
|
+
* so multiple VFS instances with different roots don't collide. */
|
|
1307
|
+
ns;
|
|
1305
1308
|
// Service worker registration for multi-tab port transfer
|
|
1306
1309
|
swReg = null;
|
|
1307
1310
|
isFollower = false;
|
|
@@ -1323,9 +1326,11 @@ var VFSFileSystem = class {
|
|
|
1323
1326
|
umask: config.umask ?? 18,
|
|
1324
1327
|
strictPermissions: config.strictPermissions ?? false,
|
|
1325
1328
|
sabSize: config.sabSize ?? DEFAULT_SAB_SIZE,
|
|
1326
|
-
debug: config.debug ?? false
|
|
1329
|
+
debug: config.debug ?? false,
|
|
1330
|
+
swScope: config.swScope
|
|
1327
1331
|
};
|
|
1328
1332
|
this.tabId = crypto.randomUUID();
|
|
1333
|
+
this.ns = `vfs-${this.config.root.replace(/[^a-zA-Z0-9]/g, "_")}`;
|
|
1329
1334
|
this.readyPromise = new Promise((resolve2) => {
|
|
1330
1335
|
this.resolveReady = resolve2;
|
|
1331
1336
|
});
|
|
@@ -1398,7 +1403,7 @@ var VFSFileSystem = class {
|
|
|
1398
1403
|
return;
|
|
1399
1404
|
}
|
|
1400
1405
|
let decided = false;
|
|
1401
|
-
navigator.locks.request(
|
|
1406
|
+
navigator.locks.request(`${this.ns}-leader`, { ifAvailable: true }, async (lock) => {
|
|
1402
1407
|
if (decided) return;
|
|
1403
1408
|
decided = true;
|
|
1404
1409
|
if (lock) {
|
|
@@ -1415,7 +1420,7 @@ var VFSFileSystem = class {
|
|
|
1415
1420
|
/** Queue for leader takeover when the current leader's lock is released */
|
|
1416
1421
|
waitForLeaderLock() {
|
|
1417
1422
|
if (!("locks" in navigator)) return;
|
|
1418
|
-
navigator.locks.request(
|
|
1423
|
+
navigator.locks.request(`${this.ns}-leader`, async () => {
|
|
1419
1424
|
console.log("[VFS] Leader lock acquired \u2014 promoting to leader");
|
|
1420
1425
|
this.holdingLeaderLock = true;
|
|
1421
1426
|
this.promoteToLeader();
|
|
@@ -1459,7 +1464,7 @@ var VFSFileSystem = class {
|
|
|
1459
1464
|
tabId: this.tabId
|
|
1460
1465
|
});
|
|
1461
1466
|
this.connectToLeader();
|
|
1462
|
-
this.leaderChangeBc = new BroadcastChannel(
|
|
1467
|
+
this.leaderChangeBc = new BroadcastChannel(`${this.ns}-leader-change`);
|
|
1463
1468
|
this.leaderChangeBc.onmessage = () => {
|
|
1464
1469
|
if (this.isFollower) {
|
|
1465
1470
|
console.log("[VFS] Leader changed \u2014 reconnecting");
|
|
@@ -1485,7 +1490,8 @@ var VFSFileSystem = class {
|
|
|
1485
1490
|
async getServiceWorker() {
|
|
1486
1491
|
if (!this.swReg) {
|
|
1487
1492
|
const swUrl = new URL("./workers/service.worker.js", import.meta.url);
|
|
1488
|
-
|
|
1493
|
+
const scope = this.config.swScope ?? new URL(`./${this.ns}/`, swUrl).href;
|
|
1494
|
+
this.swReg = await navigator.serviceWorker.register(swUrl.href, { type: "module", scope });
|
|
1489
1495
|
}
|
|
1490
1496
|
const reg = this.swReg;
|
|
1491
1497
|
if (reg.active) return reg.active;
|
|
@@ -1530,7 +1536,7 @@ var VFSFileSystem = class {
|
|
|
1530
1536
|
}
|
|
1531
1537
|
};
|
|
1532
1538
|
mc.port1.start();
|
|
1533
|
-
const bc2 = new BroadcastChannel(
|
|
1539
|
+
const bc2 = new BroadcastChannel(`${this.ns}-leader-change`);
|
|
1534
1540
|
bc2.postMessage({ type: "leader-changed" });
|
|
1535
1541
|
bc2.close();
|
|
1536
1542
|
}).catch((err) => {
|