import CryptoWorkerMethods from './crypto_methods'; type Task = { taskID: number, task: string, args: any[] }; class CryptoWorker extends CryptoWorkerMethods { private webWorker: Worker | boolean = false; private taskID = 0; private awaiting: { [id: number]: { resolve: any, reject: any, taskName: string } } = {} as any; private pending: Array = []; private debug = false; private utils: {[name: string]: (...args: any[]) => any} = {}; constructor() { super(); console.log('CW constructor'); /// #if MTPROTO_WORKER Promise.all([ import('./crypto_utils').then(utils => { Object.assign(this.utils, { 'sha1-hash': utils.sha1HashSync, 'sha256-hash': utils.sha256HashSync, 'pbkdf2': utils.hash_pbkdf2, 'aes-encrypt': utils.aesEncryptSync, 'aes-decrypt': utils.aesDecryptSync, 'rsa-encrypt': utils.rsaEncrypt, 'factorize': utils.pqPrimeFactorization, 'mod-pow': utils.bytesModPow, 'gzipUncompress': utils.gzipUncompress, }); }), import('./srp').then(srp => { this.utils.computeSRP = srp.computeSRP; })/* , import('../bin_utils').then(utils => { this.utils.unzip = utils.gzipUncompress; }) */ ]); return; /// #else if(window.Worker) { import('./crypto.worker.js').then((worker: any) => { var tmpWorker = new worker.default(); //var tmpWorker = new Worker(); tmpWorker.onmessage = (e: any) => { if(!this.webWorker) { this.webWorker = tmpWorker; console.info('CW set webWorker'); this.releasePending(); } else { this.finalizeTask(e.data.taskID, e.data.result); } }; tmpWorker.onerror = (error: any) => { console.error('CW error', error); this.webWorker = false; }; }); } /// #endif } /// #if !MTPROTO_WORKER private finalizeTask(taskID: number, result: any) { let deferred = this.awaiting[taskID]; if(deferred !== undefined) { this.debug && console.log('CW done', deferred.taskName, result); deferred.resolve(result); delete this.awaiting[taskID]; } } /// #endif public performTaskWorker(task: string, ...args: any[]) { this.debug && console.log('CW start', task, args); /// #if MTPROTO_WORKER return Promise.resolve(this.utils[task](...args)); /// #else return new Promise((resolve, reject) => { this.awaiting[this.taskID] = {resolve, reject, taskName: task}; let params = { task, taskID: this.taskID, args }; //(this.webWorker as Worker).postMessage(params); this.pending.push(params); this.releasePending(); this.taskID++; }); /// #endif } /// #if !MTPROTO_WORKER private releasePending() { if(this.webWorker) { this.pending.forEach(pending => { (this.webWorker as Worker).postMessage(pending); }); this.pending.length = 0; } } /// #endif } const cryptoWorker = new CryptoWorker(); //(window as any).CryptoWorker = cryptoWorker; export default cryptoWorker;