/** * @author [Tristan Valcke]{@link https://github.com/Itee} */ import { isArray, isArrayBuffer, isEmptyString, isNotArray, isNotDefined, isNotString } from 'itee-validators' import { WorkerMessageData } from './messages/WorkerMessageData' import { WorkerMessageError } from './messages/WorkerMessageError' import { WorkerMessageProgress } from './messages/WorkerMessageProgress' /** * @class * @classdesc Base worker interface that allow messaging between callee and caller */ class AbstractWorker { /** * * @param progress */ postProgress ( progress ) { if ( progress.isWorkerMessageProgress ) { postMessage( progress.toJSON() ) } else { postMessage( new WorkerMessageProgress( progress.loaded, progress.total ).toJSON() ) } } /** * * @param error */ postError ( error ) { if ( error.isWorkerMessageError ) { postMessage( error.toJSON() ) } else { postMessage( new WorkerMessageError( error ).toJSON() ) } } /** * * @param type * @param arrayBuffer */ postData ( type, arrayBuffer ) { if ( isArray( arrayBuffer ) ) { postMessage( new WorkerMessageData( type, arrayBuffer ).toJSON(), [ ...arrayBuffer ] ) } else if ( isArrayBuffer( arrayBuffer ) ) { postMessage( new WorkerMessageData( type, arrayBuffer ).toJSON(), [ arrayBuffer ] ) } else { throw new TypeError( `AbstractWorker.postData: Unable to post data of type [${ type }].` ) } } /** * * @param message * @returns {boolean} */ onMessage ( message ) { if ( isNotDefined( message ) ) { this.postError( new Error( 'Message event cannot be null or undefined !' ) ) return true } const data = message.data if ( isNotDefined( data ) ) { this.postError( new Error( 'Message data cannot be null or undefined !' ) ) return true } const dataType = data.type if ( isNotDefined( dataType ) ) { this.postError( new Error( 'Message data type cannot be null or undefined !' ) ) return true } if ( data.type === 'methodCall' ) { const methodName = data.method if ( isNotDefined( methodName ) ) { this.postError( new Error( 'Message of type "methodCall" cannot have null, undefined or empty name !' ) ) return true } if ( isNotString( methodName ) ) { this.postError( new Error( 'Message of type "methodCall" expect name to be a string !' ) ) return true } if ( isEmptyString( methodName ) ) { this.postError( new Error( 'Message of type "methodCall" expect name to be a non empty string !' ) ) return true } const methodParameters = data.parameters || [] if ( isNotArray( methodParameters ) ) { this.postError( new Error( 'Message of type "methodCall" expect parameters to be an array !' ) ) return true } this._invoke( methodName, methodParameters ) return true } } /** * * @param name * @param parameters * @private */ _invoke ( name, parameters = [] ) { try { const result = this[ name ]( ...parameters ) if ( result ) { postMessage( { type: name, result: result } ) } } catch ( error ) { this.postError( error ) } } } export { AbstractWorker }