(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular-ru/cdk/utils')) :
    typeof define === 'function' && define.amd ? define('@angular-ru/cdk/webworker', ['exports', '@angular/core', '@angular-ru/cdk/utils'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global["angular-ru"] = global["angular-ru"] || {}, global["angular-ru"].cdk = global["angular-ru"].cdk || {}, global["angular-ru"].cdk.webworker = {}), global.ng.core, global["angular-ru"].cdk.utils));
})(this, (function (exports, i0, utils) { 'use strict';

    function _interopNamespace(e) {
        if (e && e.__esModule) return e;
        var n = Object.create(null);
        if (e) {
            Object.keys(e).forEach(function (k) {
                if (k !== 'default') {
                    var d = Object.getOwnPropertyDescriptor(e, k);
                    Object.defineProperty(n, k, d.get ? d : {
                        enumerable: true,
                        get: function () { return e[k]; }
                    });
                }
            });
        }
        n["default"] = e;
        return Object.freeze(n);
    }

    var i0__namespace = /*#__PURE__*/_interopNamespace(i0);

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

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

    exports.WebWorkerThreadService = WebWorkerThreadService;

    Object.defineProperty(exports, '__esModule', { value: true });

}));
//# sourceMappingURL=angular-ru-cdk-webworker.umd.js.map
