{"version":3,"file":"WorkerManager.mjs","sources":["../../../src/loader/parsers/WorkerManager.ts"],"sourcesContent":["import CheckImageBitmapWorker from 'worker:./workers/checkImageBitmap.worker.ts';\nimport LoadImageBitmapWorker from 'worker:./workers/loadImageBitmap.worker.ts';\n\nlet UUID = 0;\nlet MAX_WORKERS: number;\n\ntype LoadImageBitmapResult = {\n    data?: ImageBitmap,\n    error?: Error,\n    uuid: number,\n    id: string,\n};\n\nclass WorkerManagerClass\n{\n    public worker: Worker;\n    private resolveHash: {\n        [key: string]: {\n            resolve: (...param: any[]) => void;\n            reject: (...param: any[]) => void;\n        }\n    };\n    private readonly workerPool: Worker[];\n    private readonly queue: {\n        id: string;\n        arguments: any[];\n        resolve: (...param: any[]) => void;\n        reject: (...param: any[]) => void;\n    }[];\n    private _initialized = false;\n    private _createdWorkers = 0;\n    private _isImageBitmapSupported?: Promise<boolean>;\n\n    constructor()\n    {\n        this.workerPool = [];\n        this.queue = [];\n\n        this.resolveHash = {};\n    }\n\n    public isImageBitmapSupported(): Promise<boolean>\n    {\n        if (this._isImageBitmapSupported !== undefined) return this._isImageBitmapSupported;\n\n        this._isImageBitmapSupported = new Promise((resolve) =>\n        {\n            const { worker } = new CheckImageBitmapWorker();\n\n            worker.addEventListener('message', (event: MessageEvent<boolean>) =>\n            {\n                worker.terminate();\n                CheckImageBitmapWorker.revokeObjectURL();\n                resolve(event.data);\n            });\n        });\n\n        return this._isImageBitmapSupported;\n    }\n\n    public loadImageBitmap(src: string): Promise<ImageBitmap>\n    {\n        return this._run('loadImageBitmap', [src]) as Promise<ImageBitmap>;\n    }\n\n    private async _initWorkers()\n    {\n        if (this._initialized) return;\n\n        this._initialized = true;\n    }\n\n    private getWorker(): Worker\n    {\n        if (MAX_WORKERS === undefined)\n        {\n            MAX_WORKERS = navigator.hardwareConcurrency || 4;\n        }\n        let worker = this.workerPool.pop();\n\n        if (!worker && this._createdWorkers < MAX_WORKERS)\n        {\n            // only create as many as MAX_WORKERS allows..\n            this._createdWorkers++;\n            worker = (new LoadImageBitmapWorker()).worker;\n\n            worker.addEventListener('message', (event: MessageEvent) =>\n            {\n                this.complete(event.data);\n\n                this.returnWorker(event.target as Worker);\n                this.next();\n            });\n        }\n\n        return worker;\n    }\n\n    private returnWorker(worker: Worker)\n    {\n        this.workerPool.push(worker);\n    }\n\n    private complete(data: LoadImageBitmapResult): void\n    {\n        if (data.error !== undefined)\n        {\n            this.resolveHash[data.uuid].reject(data.error);\n        }\n        else\n        {\n            this.resolveHash[data.uuid].resolve(data.data);\n        }\n\n        this.resolveHash[data.uuid] = null;\n    }\n\n    private async _run(id: string, args: any[]): Promise<any>\n    {\n        await this._initWorkers();\n        // push into the queue...\n\n        const promise = new Promise((resolve, reject) =>\n        {\n            this.queue.push({ id, arguments: args, resolve, reject });\n        });\n\n        this.next();\n\n        return promise;\n    }\n\n    private next(): void\n    {\n        // nothing to do\n        if (!this.queue.length) return;\n\n        const worker = this.getWorker();\n\n        // no workers available...\n        if (!worker)\n        {\n            return;\n        }\n\n        const toDo = this.queue.pop();\n\n        const id = toDo.id;\n\n        this.resolveHash[UUID] = { resolve: toDo.resolve, reject: toDo.reject };\n\n        worker.postMessage({\n            data: toDo.arguments,\n            uuid: UUID++,\n            id,\n        });\n    }\n}\n\nconst WorkerManager = new WorkerManagerClass();\n\nexport {\n    WorkerManager,\n};\n"],"names":["CheckImageBitmapWorker","LoadImageBitmapWorker"],"mappings":";;AAGA,IAAI,OAAO,GACP;AASJ,MAAM,mBACN;AAAA,EAmBI,cACA;AALA,SAAQ,eAAe,IACvB,KAAQ,kBAAkB,GAKjB,KAAA,aAAa,CAAA,GAClB,KAAK,QAAQ,IAEb,KAAK,cAAc;EACvB;AAAA,EAEO,yBACP;AACQ,WAAA,KAAK,4BAA4B,SAAkB,KAAK,2BAE5D,KAAK,0BAA0B,IAAI,QAAQ,CAAC,YAC5C;AACI,YAAM,EAAE,OAAA,IAAW,IAAIA;AAEhB,aAAA,iBAAiB,WAAW,CAAC,UACpC;AACI,eAAO,UACP,GAAAA,eAAuB,gBACvB,GAAA,QAAQ,MAAM,IAAI;AAAA,MAAA,CACrB;AAAA,IAAA,CACJ,GAEM,KAAK;AAAA,EAChB;AAAA,EAEO,gBAAgB,KACvB;AACI,WAAO,KAAK,KAAK,mBAAmB,CAAC,GAAG,CAAC;AAAA,EAC7C;AAAA,EAEA,MAAc,eACd;AACQ,SAAK,iBAET,KAAK,eAAe;AAAA,EACxB;AAAA,EAEQ,YACR;AACQ,oBAAgB,WAEhB,cAAc,UAAU,uBAAuB;AAE/C,QAAA,SAAS,KAAK,WAAW,IAAI;AAEjC,WAAI,CAAC,UAAU,KAAK,kBAAkB,gBAGlC,KAAK,mBACL,SAAU,IAAIC,mBAAyB,QAEvC,OAAO,iBAAiB,WAAW,CAAC,UACpC;AACS,WAAA,SAAS,MAAM,IAAI,GAExB,KAAK,aAAa,MAAM,MAAgB,GACxC,KAAK,KAAK;AAAA,IAAA,CACb,IAGE;AAAA,EACX;AAAA,EAEQ,aAAa,QACrB;AACS,SAAA,WAAW,KAAK,MAAM;AAAA,EAC/B;AAAA,EAEQ,SAAS,MACjB;AACQ,SAAK,UAAU,SAEf,KAAK,YAAY,KAAK,IAAI,EAAE,OAAO,KAAK,KAAK,IAI7C,KAAK,YAAY,KAAK,IAAI,EAAE,QAAQ,KAAK,IAAI,GAGjD,KAAK,YAAY,KAAK,IAAI,IAAI;AAAA,EAClC;AAAA,EAEA,MAAc,KAAK,IAAY,MAC/B;AACI,UAAM,KAAK;AAGX,UAAM,UAAU,IAAI,QAAQ,CAAC,SAAS,WACtC;AACS,WAAA,MAAM,KAAK,EAAE,IAAI,WAAW,MAAM,SAAS,QAAQ;AAAA,IAAA,CAC3D;AAED,WAAA,KAAK,KAEE,GAAA;AAAA,EACX;AAAA,EAEQ,OACR;AAEQ,QAAA,CAAC,KAAK,MAAM;AAAQ;AAElB,UAAA,SAAS,KAAK;AAGpB,QAAI,CAAC;AAED;AAGJ,UAAM,OAAO,KAAK,MAAM,IAAI,GAEtB,KAAK,KAAK;AAEhB,SAAK,YAAY,IAAI,IAAI,EAAE,SAAS,KAAK,SAAS,QAAQ,KAAK,UAE/D,OAAO,YAAY;AAAA,MACf,MAAM,KAAK;AAAA,MACX,MAAM;AAAA,MACN;AAAA,IAAA,CACH;AAAA,EACL;AACJ;AAEM,MAAA,gBAAgB,IAAI,mBAAmB;"}