@componentor/fs 3.0.51 → 3.0.52
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.js +35 -11
- package/dist/index.js.map +1 -1
- package/dist/workers/async-relay.worker.js +5 -2
- package/dist/workers/async-relay.worker.js.map +1 -1
- package/dist/workers/server.worker.js.map +1 -1
- package/dist/workers/sync-relay.worker.js +17 -2
- package/dist/workers/sync-relay.worker.js.map +1 -1
- package/package.json +1 -1
- package/readme.md +7 -0
package/dist/index.js
CHANGED
|
@@ -362,7 +362,12 @@ var OP = {
|
|
|
362
362
|
var SAB_OFFSETS = {
|
|
363
363
|
// Int32 - bytes in this chunk
|
|
364
364
|
TOTAL_LEN: 16,
|
|
365
|
-
// Int32 -
|
|
365
|
+
// Int32 - 0-based chunk index
|
|
366
|
+
HEARTBEAT: 28,
|
|
367
|
+
// Int32 - liveness counter; the relay worker bumps this ~1×/s
|
|
368
|
+
// while its event loop is alive (incl. mid-await of a
|
|
369
|
+
// long op) so a spin-waiting main thread can tell
|
|
370
|
+
// "slow" from "dead". Never written by the main thread.
|
|
366
371
|
HEADER_SIZE: 32
|
|
367
372
|
// Data payload starts here
|
|
368
373
|
};
|
|
@@ -2556,19 +2561,37 @@ var DEFAULT_SAB_SIZE = 2 * 1024 * 1024;
|
|
|
2556
2561
|
var instanceRegistry = /* @__PURE__ */ new Map();
|
|
2557
2562
|
var HEADER_SIZE = SAB_OFFSETS.HEADER_SIZE;
|
|
2558
2563
|
var _canAtomicsWait = typeof globalThis.WorkerGlobalScope !== "undefined";
|
|
2559
|
-
var
|
|
2560
|
-
|
|
2564
|
+
var SAB_HEARTBEAT_INDEX = SAB_OFFSETS.HEARTBEAT >> 2;
|
|
2565
|
+
var SPIN_STALL_TIMEOUT_MS = 2e4;
|
|
2566
|
+
var SPIN_NO_HEARTBEAT_TIMEOUT_MS = 3e4;
|
|
2567
|
+
function spinWait(arr, index, value, heartbeatArr) {
|
|
2561
2568
|
if (_canAtomicsWait) {
|
|
2562
2569
|
Atomics.wait(arr, index, value);
|
|
2563
|
-
|
|
2570
|
+
return;
|
|
2571
|
+
}
|
|
2572
|
+
if (!heartbeatArr) {
|
|
2564
2573
|
const start = performance.now();
|
|
2565
2574
|
while (Atomics.load(arr, index) === value) {
|
|
2566
|
-
if (performance.now() - start >
|
|
2575
|
+
if (performance.now() - start > SPIN_NO_HEARTBEAT_TIMEOUT_MS) {
|
|
2567
2576
|
throw new Error(
|
|
2568
|
-
`VFS sync operation timed out after ${
|
|
2577
|
+
`VFS sync operation timed out after ${SPIN_NO_HEARTBEAT_TIMEOUT_MS / 1e3}s \u2014 relay worker did not respond`
|
|
2569
2578
|
);
|
|
2570
2579
|
}
|
|
2571
2580
|
}
|
|
2581
|
+
return;
|
|
2582
|
+
}
|
|
2583
|
+
let lastBeat = Atomics.load(heartbeatArr, SAB_HEARTBEAT_INDEX);
|
|
2584
|
+
let lastProgress = performance.now();
|
|
2585
|
+
while (Atomics.load(arr, index) === value) {
|
|
2586
|
+
const beat = Atomics.load(heartbeatArr, SAB_HEARTBEAT_INDEX);
|
|
2587
|
+
if (beat !== lastBeat) {
|
|
2588
|
+
lastBeat = beat;
|
|
2589
|
+
lastProgress = performance.now();
|
|
2590
|
+
} else if (performance.now() - lastProgress > SPIN_STALL_TIMEOUT_MS) {
|
|
2591
|
+
throw new Error(
|
|
2592
|
+
`VFS sync operation aborted: relay worker heartbeat stalled for ${SPIN_STALL_TIMEOUT_MS / 1e3}s \u2014 worker is unresponsive`
|
|
2593
|
+
);
|
|
2594
|
+
}
|
|
2572
2595
|
}
|
|
2573
2596
|
}
|
|
2574
2597
|
var VFSFileSystem = class {
|
|
@@ -3041,7 +3064,7 @@ var VFSFileSystem = class {
|
|
|
3041
3064
|
if (signal === -1) {
|
|
3042
3065
|
throw this.initError ?? new Error("VFS initialization failed");
|
|
3043
3066
|
}
|
|
3044
|
-
spinWait(this.readySignal, 0, 0);
|
|
3067
|
+
spinWait(this.readySignal, 0, 0, this.ctrl);
|
|
3045
3068
|
const finalSignal = Atomics.load(this.readySignal, 0);
|
|
3046
3069
|
if (finalSignal === -1) {
|
|
3047
3070
|
throw this.initError ?? new Error("VFS initialization failed");
|
|
@@ -3055,7 +3078,8 @@ var VFSFileSystem = class {
|
|
|
3055
3078
|
const maxChunk = this.sab.byteLength - HEADER_SIZE;
|
|
3056
3079
|
const requestBytes = new Uint8Array(requestBuf);
|
|
3057
3080
|
const totalLenView = new BigUint64Array(this.sab, SAB_OFFSETS.TOTAL_LEN, 1);
|
|
3058
|
-
|
|
3081
|
+
const multiChunkRequest = requestBytes.byteLength > maxChunk;
|
|
3082
|
+
if (!multiChunkRequest) {
|
|
3059
3083
|
new Uint8Array(this.sab, HEADER_SIZE, requestBytes.byteLength).set(requestBytes);
|
|
3060
3084
|
Atomics.store(this.ctrl, 3, requestBytes.byteLength);
|
|
3061
3085
|
Atomics.store(totalLenView, 0, BigInt(requestBytes.byteLength));
|
|
@@ -3079,11 +3103,11 @@ var VFSFileSystem = class {
|
|
|
3079
3103
|
Atomics.notify(this.ctrl, 0);
|
|
3080
3104
|
sent += chunkSize;
|
|
3081
3105
|
if (sent < requestBytes.byteLength) {
|
|
3082
|
-
spinWait(this.ctrl, 0, sent === chunkSize ? SIGNAL.REQUEST : SIGNAL.CHUNK);
|
|
3106
|
+
spinWait(this.ctrl, 0, sent === chunkSize ? SIGNAL.REQUEST : SIGNAL.CHUNK, this.ctrl);
|
|
3083
3107
|
}
|
|
3084
3108
|
}
|
|
3085
3109
|
}
|
|
3086
|
-
spinWait(this.ctrl, 0, SIGNAL.REQUEST);
|
|
3110
|
+
spinWait(this.ctrl, 0, multiChunkRequest ? SIGNAL.CHUNK : SIGNAL.REQUEST, this.ctrl);
|
|
3087
3111
|
const signal = Atomics.load(this.ctrl, 0);
|
|
3088
3112
|
const respChunkLen = Atomics.load(this.ctrl, 3);
|
|
3089
3113
|
const respTotalLen = Number(Atomics.load(totalLenView, 0));
|
|
@@ -3099,7 +3123,7 @@ var VFSFileSystem = class {
|
|
|
3099
3123
|
while (received < respTotalLen) {
|
|
3100
3124
|
Atomics.store(this.ctrl, 0, SIGNAL.CHUNK_ACK);
|
|
3101
3125
|
Atomics.notify(this.ctrl, 0);
|
|
3102
|
-
spinWait(this.ctrl, 0, SIGNAL.CHUNK_ACK);
|
|
3126
|
+
spinWait(this.ctrl, 0, SIGNAL.CHUNK_ACK, this.ctrl);
|
|
3103
3127
|
const nextLen = Atomics.load(this.ctrl, 3);
|
|
3104
3128
|
responseBytes.set(new Uint8Array(this.sab, HEADER_SIZE, nextLen), received);
|
|
3105
3129
|
received += nextLen;
|