robbederks/downzip

View on GitHub
src/downzip.js

Summary

Maintainability
A
0 mins
Test Coverage
F
0%
import registerServiceWorker from 'service-worker-loader!./downzip-sw'
import WorkerUtils from './WorkerUtils'
const Utils = new WorkerUtils('DownZip-Main')

const SCOPE = 'downzip'
const TIMEOUT_MS = 5000
const KEEPALIVE_INTERVAL_MS = 5000

class DownZip {
    constructor(){
        this.worker = null
    }

    async register(options = {}) {
        // Allow passing mapScriptUrl to service-worker-loader
        const defaultMapScriptUrl = scriptUrl => scriptUrl
        const mapScriptUrl = options.mapScriptUrl || defaultMapScriptUrl

        // Register service worker and let it intercept our scope
        await registerServiceWorker(mapScriptUrl, {
            scope: `./${SCOPE}/`
        }).then(result => {
            Utils.log('[DownZip] Service worker registered successfully:', result)
            this.worker = result.installing || result.active
        }).catch(error => {
            Utils.error('[DownZip] Service workers not loaded:', error)
        })

        // Start keep-alive timer
        setInterval(async () => {
            this.sendMessage('TICK')
        }, KEEPALIVE_INTERVAL_MS)
    }
    

    sendMessage(command, data, port){
        this.worker.postMessage({
            command,
            data
        }, port ? [port] : undefined)
    }

    // Files array is in the following format: [{name: '', downloadUrl: '', size: 0}, ...]
    async downzip(id, name, files){
        // Check if worker got created in the constructor
        if(!this.worker){
            Utils.error("[DownZip] No service worker registered!")
            return
        }

        return new Promise(((resolve, reject) => {
            // Return download URL on acknowledge via messageChannel
            const messageChannel = new MessageChannel()
            messageChannel.port1.addEventListener('message', () => resolve(`${SCOPE}/download-${id}`))
            messageChannel.port1.start()

            // Init this task in our service worker
            this.sendMessage('INITIALIZE', {
                id,
                files,
                name
            }, messageChannel.port2)

            // Start timeout timer
            setTimeout(reject, TIMEOUT_MS)
        }))
    }
}

export default DownZip