import * as i0 from '@angular/core';
import { Injectable } from '@angular/core';
import { isNotNil } from '@angular-ru/cdk/utils';

class WebWorkerThreadService {
    constructor() {
        this.workerFunctionToUrlMap = new WeakMap();
        this.promiseToWorkerMap = new WeakMap();
    }
    static createWorkerUrl(resolve) {
        const resolveString = resolve.toString();
        const webWorkerTemplate = `
            self.addEventListener('message', function(e) {
                postMessage((${resolveString})(e.data));
            });
        `;
        const blob = new Blob([webWorkerTemplate], { type: 'text/javascript' });
        return URL.createObjectURL(blob);
    }
    run(workerFunction, data) {
        const url = this.getOrCreateWorkerUrl(workerFunction);
        return this.runUrl(url, data);
    }
    runUrl(url, data) {
        const worker = new Worker(url);
        const promise = this.createPromiseForWorker(worker, data);
        const promiseCleaner = this.createPromiseCleaner(promise);
        this.promiseToWorkerMap.set(promise, worker);
        promise.then(promiseCleaner).catch(promiseCleaner);
        return promise;
    }
    terminate(promise) {
        return this.removePromise(promise);
    }
    getWorker(promise) {
        return this.promiseToWorkerMap.get(promise);
    }
    createPromiseForWorker(worker, data) {
        return new Promise((resolve, reject) => {
            worker.addEventListener('message', (event) => resolve(event.data));
            worker.addEventListener('error', reject);
            worker.postMessage(data);
        });
    }
    getOrCreateWorkerUrl(fn) {
        if (!this.workerFunctionToUrlMap.has(fn)) {
            const url = WebWorkerThreadService.createWorkerUrl(fn);
            this.workerFunctionToUrlMap.set(fn, url);
            return url;
        }
        return this.workerFunctionToUrlMap.get(fn);
    }
    createPromiseCleaner(promise) {
        return (event) => {
            this.removePromise(promise);
            return event;
        };
    }
    removePromise(promise) {
        const worker = this.promiseToWorkerMap.get(promise);
        if (isNotNil(worker)) {
            worker?.terminate();
        }
        this.promiseToWorkerMap.delete(promise);
        return promise;
    }
}
/** @nocollapse */ WebWorkerThreadService.ɵfac = function WebWorkerThreadService_Factory(t) { return new (t || WebWorkerThreadService)(); };
/** @nocollapse */ WebWorkerThreadService.ɵprov = /** @pureOrBreakMyCode */ i0.ɵɵdefineInjectable({ token: WebWorkerThreadService, factory: WebWorkerThreadService.ɵfac });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(WebWorkerThreadService, [{
        type: Injectable
    }], null, null); })();

/**
 * Generated bundle index. Do not edit.
 */

export { WebWorkerThreadService };
//# sourceMappingURL=angular-ru-cdk-webworker.mjs.map
