2024-07-14 18:04:03 +02:00
|
|
|
self.accessHandle = undefined;
|
|
|
|
self.messageQueue = [];
|
|
|
|
self.busy = false;
|
|
|
|
|
|
|
|
|
2024-02-07 04:11:56 +01:00
|
|
|
self.addEventListener('message', async e => {
|
2024-07-14 18:04:03 +02:00
|
|
|
// Put message into queue if busy
|
|
|
|
if (self.busy) {
|
|
|
|
self.messageQueue.push(e.data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
await digestMessage(e.data);
|
|
|
|
});
|
|
|
|
|
|
|
|
async function digestMessage(message) {
|
|
|
|
self.busy = true;
|
2024-02-07 04:11:56 +01:00
|
|
|
try {
|
2024-07-14 18:04:03 +02:00
|
|
|
switch (message.type) {
|
2024-02-15 18:05:48 +01:00
|
|
|
case "check-support":
|
|
|
|
await checkSupport();
|
|
|
|
break;
|
2024-07-14 18:04:03 +02:00
|
|
|
case "chunk":
|
|
|
|
await onChunk(message.id, message.chunk, message.offset);
|
2024-02-07 04:11:56 +01:00
|
|
|
break;
|
|
|
|
case "get-file":
|
2024-07-14 18:04:03 +02:00
|
|
|
await onGetFile(message.id);
|
2024-02-07 04:11:56 +01:00
|
|
|
break;
|
2024-02-09 03:34:07 +01:00
|
|
|
case "delete-file":
|
2024-07-14 18:04:03 +02:00
|
|
|
await onDeleteFile(message.id);
|
|
|
|
break;
|
|
|
|
case "clear-directory":
|
|
|
|
await onClearDirectory();
|
2024-02-09 03:34:07 +01:00
|
|
|
break;
|
2024-02-07 04:11:56 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (e) {
|
|
|
|
self.postMessage({type: "error", error: e});
|
|
|
|
}
|
2024-07-14 18:04:03 +02:00
|
|
|
|
|
|
|
// message is digested. Digest next message.
|
|
|
|
await messageDigested();
|
|
|
|
}
|
|
|
|
|
|
|
|
async function messageDigested() {
|
|
|
|
if (!self.messageQueue.length) {
|
|
|
|
// no chunk in queue -> set flag to false and stop
|
|
|
|
this.busy = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Digest next message in queue
|
|
|
|
await this.digestMessage(self.messageQueue.pop());
|
|
|
|
}
|
2024-02-07 04:11:56 +01:00
|
|
|
|
2024-02-15 18:05:48 +01:00
|
|
|
async function checkSupport() {
|
|
|
|
try {
|
2024-07-14 18:04:03 +02:00
|
|
|
const accessHandle = await getAccessHandle("test");
|
2024-02-15 18:05:48 +01:00
|
|
|
self.postMessage({type: "support", supported: true});
|
2024-07-14 18:04:03 +02:00
|
|
|
accessHandle.close();
|
2024-02-15 18:05:48 +01:00
|
|
|
}
|
|
|
|
catch (e) {
|
|
|
|
self.postMessage({type: "support", supported: false});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-14 18:04:03 +02:00
|
|
|
async function getFileHandle(id) {
|
|
|
|
const dirHandle = await navigator.storage.getDirectory();
|
|
|
|
return await dirHandle.getFileHandle(id, {create: true});
|
2024-02-07 04:11:56 +01:00
|
|
|
}
|
|
|
|
|
2024-07-14 18:04:03 +02:00
|
|
|
async function getAccessHandle(id) {
|
|
|
|
const fileHandle = await getFileHandle(id);
|
2024-02-07 04:11:56 +01:00
|
|
|
|
2024-07-14 18:04:03 +02:00
|
|
|
if (!self.accessHandle) {
|
|
|
|
// Create FileSystemSyncAccessHandle on the file.
|
|
|
|
self.accessHandle = await fileHandle.createSyncAccessHandle();
|
|
|
|
}
|
|
|
|
|
|
|
|
return self.accessHandle;
|
2024-02-07 04:11:56 +01:00
|
|
|
}
|
|
|
|
|
2024-07-14 18:04:03 +02:00
|
|
|
async function onChunk(id, chunk, offset) {
|
|
|
|
const accessHandle = await getAccessHandle(id);
|
2024-02-07 04:11:56 +01:00
|
|
|
|
|
|
|
// Write the message to the end of the file.
|
2024-07-14 18:04:03 +02:00
|
|
|
let encodedMessage = new DataView(chunk);
|
2024-02-07 04:11:56 +01:00
|
|
|
accessHandle.write(encodedMessage, { at: offset });
|
2024-02-09 03:34:07 +01:00
|
|
|
|
2024-07-14 18:04:03 +02:00
|
|
|
self.postMessage({type: "chunk-written", offset: offset});
|
2024-02-07 04:11:56 +01:00
|
|
|
}
|
|
|
|
|
2024-07-14 18:04:03 +02:00
|
|
|
async function onGetFile(id) {
|
|
|
|
const fileHandle = await getFileHandle(id);
|
2024-02-07 04:11:56 +01:00
|
|
|
let file = await fileHandle.getFile();
|
|
|
|
|
|
|
|
self.postMessage({type: "file", file: file});
|
2024-02-09 03:34:07 +01:00
|
|
|
}
|
|
|
|
|
2024-07-14 18:04:03 +02:00
|
|
|
async function onDeleteFile(id) {
|
|
|
|
const accessHandle = await getAccessHandle(id);
|
2024-02-09 03:34:07 +01:00
|
|
|
|
|
|
|
// Truncate the file to 0 bytes
|
|
|
|
accessHandle.truncate(0);
|
|
|
|
|
|
|
|
// Persist changes to disk.
|
|
|
|
accessHandle.flush();
|
|
|
|
|
|
|
|
// Always close FileSystemSyncAccessHandle if done.
|
|
|
|
accessHandle.close();
|
|
|
|
|
2024-07-14 18:04:03 +02:00
|
|
|
self.postMessage({type: "file-deleted", id: id});
|
|
|
|
}
|
|
|
|
|
|
|
|
async function onClearDirectory() {
|
|
|
|
const dirHandle = await navigator.storage.getDirectory();
|
|
|
|
|
|
|
|
// Iterate through directory entries and truncate all entries to 0
|
|
|
|
for await (const [id, fileHandle] of dirHandle.entries()) {
|
|
|
|
const accessHandle = await fileHandle.createSyncAccessHandle();
|
|
|
|
|
|
|
|
// Truncate the file to 0 bytes
|
|
|
|
accessHandle.truncate(0);
|
|
|
|
|
|
|
|
// Persist changes to disk.
|
|
|
|
accessHandle.flush();
|
|
|
|
|
|
|
|
// Always close FileSystemSyncAccessHandle if done.
|
|
|
|
accessHandle.close();
|
|
|
|
}
|
2024-02-07 04:11:56 +01:00
|
|
|
}
|