|
| 1 | +/// <reference lib="webworker" /> |
| 2 | + |
| 3 | +declare const self: ServiceWorkerGlobalScope |
| 4 | + |
| 5 | +type StoreName = string |
| 6 | +type FileId = string |
| 7 | +type CachedStore = Record<FileId, Blob> |
| 8 | +type FileCache = Record<StoreName, CachedStore> |
| 9 | + |
| 10 | +const fileCache: FileCache = Object.create(null) |
| 11 | + |
| 12 | +function getCache(name: StoreName): CachedStore { |
| 13 | + fileCache[name] ??= Object.create(null) |
| 14 | + return fileCache[name] |
| 15 | +} |
| 16 | + |
| 17 | +self.addEventListener('install', (event: ExtendableEvent) => { |
| 18 | + event.waitUntil(Promise.resolve().then(() => self.skipWaiting())) |
| 19 | +}) |
| 20 | + |
| 21 | +self.addEventListener('activate', (event: ExtendableEvent) => { |
| 22 | + event.waitUntil(self.clients.claim()) |
| 23 | +}) |
| 24 | + |
| 25 | +type AllFilesMessage = { |
| 26 | + type: 'uppy/ALL_FILES' |
| 27 | + store: StoreName |
| 28 | + files: CachedStore |
| 29 | +} |
| 30 | + |
| 31 | +function sendMessageToAllClients(msg: AllFilesMessage): void { |
| 32 | + self.clients.matchAll().then((clientList) => { |
| 33 | + clientList.forEach((client) => { |
| 34 | + client.postMessage(msg) |
| 35 | + }) |
| 36 | + }) |
| 37 | +} |
| 38 | + |
| 39 | +type AddFilePayload = { id: FileId; data: Blob } |
| 40 | + |
| 41 | +function addFile(store: StoreName, file: AddFilePayload): void { |
| 42 | + getCache(store)[file.id] = file.data |
| 43 | +} |
| 44 | + |
| 45 | +function removeFile(store: StoreName, fileID: FileId): void { |
| 46 | + delete getCache(store)[fileID] |
| 47 | +} |
| 48 | + |
| 49 | +function getFiles(store: StoreName): void { |
| 50 | + sendMessageToAllClients({ |
| 51 | + type: 'uppy/ALL_FILES', |
| 52 | + store, |
| 53 | + files: getCache(store), |
| 54 | + }) |
| 55 | +} |
| 56 | + |
| 57 | +type IncomingMessage = |
| 58 | + | { type: 'uppy/ADD_FILE'; store: StoreName; file: AddFilePayload } |
| 59 | + | { type: 'uppy/REMOVE_FILE'; store: StoreName; fileID: FileId } |
| 60 | + | { type: 'uppy/GET_FILES'; store: StoreName } |
| 61 | + |
| 62 | +self.addEventListener('message', (event: ExtendableMessageEvent) => { |
| 63 | + const data = event.data as IncomingMessage | undefined |
| 64 | + switch (data?.type) { |
| 65 | + case 'uppy/ADD_FILE': |
| 66 | + addFile(data.store, data.file) |
| 67 | + break |
| 68 | + case 'uppy/REMOVE_FILE': |
| 69 | + removeFile(data.store, data.fileID) |
| 70 | + break |
| 71 | + case 'uppy/GET_FILES': |
| 72 | + getFiles(data.store) |
| 73 | + break |
| 74 | + default: |
| 75 | + throw new Error( |
| 76 | + `[ServiceWorker] Unsupported event.data.type. Got: ${(data as any)?.type}`, |
| 77 | + ) |
| 78 | + } |
| 79 | +}) |
0 commit comments