You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
2.3 KiB
90 lines
2.3 KiB
export interface WorkerOptions {
|
|
credentials?: 'omit' | 'same-origin' | 'include';
|
|
name?: string;
|
|
type?: 'classic' | 'module';
|
|
}
|
|
|
|
declare var Worker: {
|
|
prototype: Worker;
|
|
new (stringUrl: string, options?: WorkerOptions): Worker;
|
|
};
|
|
|
|
interface HashingRequest {
|
|
blob: any;
|
|
resolve: (...d: any) => void;
|
|
reject: (...d: any) => void;
|
|
};
|
|
|
|
export class ParallelHasher {
|
|
private _queue: HashingRequest[] = [];
|
|
private _hashWorker: any;
|
|
private _processing?: HashingRequest;
|
|
|
|
private _ready: boolean = true;
|
|
|
|
constructor(workerUri: string, workerOptions?: WorkerOptions) {
|
|
const self = this;
|
|
|
|
if (Worker) {
|
|
self._hashWorker = new Worker(workerUri, workerOptions);
|
|
self._hashWorker.onmessage = self._recievedMessage.bind(self);
|
|
self._hashWorker.onerror = (err: any) => {
|
|
self._ready = false;
|
|
console.error('Hash worker failure', err);
|
|
};
|
|
} else {
|
|
self._ready = false;
|
|
console.error('Web Workers are not supported in this browser');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Hash a blob of data in the worker
|
|
* @param blob Data to hash
|
|
* @returns Promise of the Hashed result
|
|
*/
|
|
public hash(blob: any) {
|
|
const self = this;
|
|
let promise;
|
|
|
|
promise = new Promise((resolve, reject) => {
|
|
self._queue.push({
|
|
blob,
|
|
resolve,
|
|
reject,
|
|
});
|
|
|
|
self._processNext();
|
|
});
|
|
|
|
return promise;
|
|
}
|
|
|
|
/** Terminate any existing hash requests */
|
|
public terminate() {
|
|
this._ready = false;
|
|
this._hashWorker.terminate();
|
|
}
|
|
|
|
// Processes the next item in the queue
|
|
private _processNext() {
|
|
if (this._ready && !this._processing && this._queue.length > 0) {
|
|
this._processing = this._queue.pop();
|
|
this._hashWorker.postMessage(this._processing!.blob);
|
|
}
|
|
}
|
|
|
|
// Hash result is returned from the worker
|
|
private _recievedMessage(evt: any) {
|
|
const data = evt.data;
|
|
|
|
if (data.success) {
|
|
this._processing?.resolve(data.result);
|
|
} else {
|
|
this._processing?.reject(data.result);
|
|
}
|
|
|
|
this._processing = undefined;
|
|
this._processNext();
|
|
}
|
|
}
|
|
|