mirror of
https://github.com/Buriburizaem0n/nezha_domains.git
synced 2026-02-05 21:20:06 +00:00
fm: store file to OPFS temporarily (#413)
This commit is contained in:
70
resource/static/file.js
Normal file
70
resource/static/file.js
Normal file
@@ -0,0 +1,70 @@
|
||||
let receivedLength = 0;
|
||||
let expectedLength = 0;
|
||||
let root;
|
||||
let draftHandle;
|
||||
let accessHandle;
|
||||
|
||||
const Operation = Object.freeze({
|
||||
WriteHeader: 1,
|
||||
WriteChunks: 2,
|
||||
DeleteFiles: 3
|
||||
});
|
||||
|
||||
onmessage = async function (event) {
|
||||
try {
|
||||
const { operation, arrayBuffer, fileName } = event.data;
|
||||
|
||||
switch (operation) {
|
||||
case Operation.WriteHeader: {
|
||||
const dataView = new DataView(arrayBuffer);
|
||||
expectedLength = Number(dataView.getBigUint64(4, false));
|
||||
receivedLength = 0;
|
||||
|
||||
// Create a new temporary file
|
||||
root = await navigator.storage.getDirectory();
|
||||
draftHandle = await root.getFileHandle(fileName, { create: true });
|
||||
accessHandle = await draftHandle.createSyncAccessHandle();
|
||||
|
||||
// Inform that file handle is created
|
||||
const dataChunk = arrayBuffer.slice(12);
|
||||
receivedLength += dataChunk.byteLength;
|
||||
accessHandle.write(dataChunk, { at: 0 });
|
||||
const progress = 'got handle';
|
||||
postMessage({ type: 'progress', progress: progress });
|
||||
break;
|
||||
}
|
||||
case Operation.WriteChunks: {
|
||||
if (!accessHandle) {
|
||||
throw new Error('accessHandle is undefined');
|
||||
}
|
||||
|
||||
const dataChunk = arrayBuffer;
|
||||
accessHandle.write(dataChunk, { at: receivedLength });
|
||||
receivedLength += dataChunk.byteLength;
|
||||
|
||||
if (receivedLength === expectedLength) {
|
||||
accessHandle.flush();
|
||||
accessHandle.close();
|
||||
|
||||
const fileBlob = await draftHandle.getFile();
|
||||
const blob = new Blob([fileBlob], { type: 'application/octet-stream' });
|
||||
|
||||
postMessage({ type: 'result', blob: blob, fileName: fileName });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Operation.DeleteFiles: {
|
||||
for await (const [name, handle] of root.entries()) {
|
||||
if (handle.kind === 'file') {
|
||||
await root.removeEntry(name);
|
||||
} else if (handle.kind === 'directory') {
|
||||
await root.removeEntry(name, { recursive: true });
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
postMessage({ error: error.message });
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user