fix: fall back to copy when OPFS move() throws on WebKit and retry failed worker downloads on the main thread
This commit is contained in:
@@ -76,12 +76,16 @@ self.onmessage = async (e) => {
|
|||||||
access.close();
|
access.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finalize: .part → permanent name. Prefer the native rename; fall back
|
// Finalize: .part → permanent name. Prefer the native rename, but treat
|
||||||
// to a chunked copy (still fully inside the worker, small fixed buffers).
|
// ANY move() failure as "unavailable" and fall back to a chunked copy —
|
||||||
|
// WebKit's move() has a different signature/behavior than Chrome's and
|
||||||
|
// throws TypeError ("Not enough arguments") rather than being absent.
|
||||||
try { await dir.removeEntry(filename); } catch { /* no previous copy */ }
|
try { await dir.removeEntry(filename); } catch { /* no previous copy */ }
|
||||||
|
let renamed = false;
|
||||||
if (typeof partHandle.move === 'function') {
|
if (typeof partHandle.move === 'function') {
|
||||||
await partHandle.move(filename);
|
try { await partHandle.move(filename); renamed = true; } catch { /* copy below */ }
|
||||||
} else {
|
}
|
||||||
|
if (!renamed) {
|
||||||
const finalHandle = await dir.getFileHandle(filename, { create: true });
|
const finalHandle = await dir.getFileHandle(filename, { create: true });
|
||||||
const out = await finalHandle.createSyncAccessHandle();
|
const out = await finalHandle.createSyncAccessHandle();
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -154,18 +154,21 @@
|
|||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Fallback: buffer entirely (older browsers)
|
// No createWritable on this browser — main-thread OPFS writes are
|
||||||
const buf = await response.arrayBuffer();
|
// impossible (sync access handles are worker-only). Surface a real
|
||||||
const writable = await tmpHandle.createWritable();
|
// error instead of the old branch that called the missing API.
|
||||||
await writable.write(buf);
|
throw new Error('Offline saving is not supported in this browser');
|
||||||
await writable.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rename tmp → final. Prefer the native rename; else stream-copy so
|
// Rename tmp → final. Prefer the native rename; else stream-copy so
|
||||||
// the whole file is never buffered in main-thread memory at once.
|
// the whole file is never buffered in main-thread memory at once.
|
||||||
|
// move() failures (WebKit's signature differs from Chrome's and
|
||||||
|
// throws TypeError) fall back to the copy path too.
|
||||||
|
let renamed = false;
|
||||||
if (typeof tmpHandle.move === 'function') {
|
if (typeof tmpHandle.move === 'function') {
|
||||||
await tmpHandle.move(filename);
|
try { await tmpHandle.move(filename); renamed = true; } catch { /* copy below */ }
|
||||||
} else {
|
}
|
||||||
|
if (!renamed) {
|
||||||
const finalHandle = await dir.getFileHandle(filename, { create: true });
|
const finalHandle = await dir.getFileHandle(filename, { create: true });
|
||||||
const finalWritable = await finalHandle.createWritable();
|
const finalWritable = await finalHandle.createWritable();
|
||||||
const tmpFile = await tmpHandle.getFile();
|
const tmpFile = await tmpHandle.getFile();
|
||||||
|
|||||||
Reference in New Issue
Block a user