UNPKG

parallel-es

Version:
1,183 lines (1,063 loc) 82.4 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(require("os"), require("child_process")); else if(typeof define === 'function' && define.amd) define(["os", "child_process"], factory); else if(typeof exports === 'object') exports["parallel-es"] = factory(require("os"), require("child_process")); else root["parallel-es"] = factory(root["os"], root["child_process"]); })(this, function(__WEBPACK_EXTERNAL_MODULE_21__, __WEBPACK_EXTERNAL_MODULE_49__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // identity function for calling harmony imports with the correct context /******/ __webpack_require__.i = function(value) { return value; }; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 22); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /** * @module parallel */ /** */ /** * Represents a function call */ class FunctionCall { static create(func, ...args) { return new FunctionCall(func, args); } /** * Creates a function call for a function with with many arguments * @param func the function to call * @param params the parameters to pass * @returns the function call */ static createUnchecked(func, ...params) { return new FunctionCall(func, params); } /** * Creates a function call instance from its serialized representation * @param serialized the serialized function call * @returns {FunctionCall} the function call */ static fromSerialized(serialized) { return new FunctionCall(serialized.functionId, serialized.parameters); } constructor(func, params) { this.func = func; this.params = params; } } /* harmony export (immutable) */ __webpack_exports__["a"] = FunctionCall; /***/ }), /* 1 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony export (immutable) */ __webpack_exports__["a"] = functionId; /* harmony export (immutable) */ __webpack_exports__["b"] = isFunctionId; /** * @module parallel */ /** */ /** * Creates a function id * @param namespace the namespace of the id * @param id the unique id for this namespace * @returns the function id */ function functionId(namespace, id) { return { _______isFunctionId: true, identifier: `${namespace}-${id}` }; } /** * Tests if the given object is a function id * @param obj the object to test for * @returns true if the object is a function id */ function isFunctionId(obj) { return !!obj && obj._______isFunctionId === true; } /***/ }), /* 2 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__function_function_id__ = __webpack_require__(1); const ParallelWorkerFunctionIds = { FILTER: __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0__function_function_id__["a" /* functionId */])("parallel", 0), IDENTITY: __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0__function_function_id__["a" /* functionId */])("parallel", 1), MAP: __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0__function_function_id__["a" /* functionId */])("parallel", 2), PARALLEL_JOB_EXECUTOR: __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0__function_function_id__["a" /* functionId */])("parallel", 3), RANGE: __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0__function_function_id__["a" /* functionId */])("parallel", 4), REDUCE: __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0__function_function_id__["a" /* functionId */])("parallel", 5), TIMES: __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0__function_function_id__["a" /* functionId */])("parallel", 6), TO_ITERATOR: __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0__function_function_id__["a" /* functionId */])("parallel", 7) }; /* harmony export (immutable) */ __webpack_exports__["a"] = ParallelWorkerFunctionIds; /***/ }), /* 3 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony export (immutable) */ __webpack_exports__["a"] = toIterator; /* harmony export (immutable) */ __webpack_exports__["b"] = toArray; /* harmony export (immutable) */ __webpack_exports__["c"] = flattenArray; /* harmony export (immutable) */ __webpack_exports__["d"] = concatInPlace; /** * Creates an iterator that iterates over the given array * @param data the array * @param T element type * @returns the iterator */ /** * Creates an iterator that iterates over the given array * @param data the array * @param T element type * @returns the iterator */ function toIterator(data) { return data[Symbol.iterator](); } /** * Converts the given iterator to an array * @param iterator the iterator that is to be converted into an array * @param T element type * @returns {T[]} the array representation of the given iterator */ function toArray(iterator) { const result = []; let current; /* tslint:disable:no-conditional-assignment */ while (!(current = iterator.next()).done) { result.push(current.value); } return result; } /** * Flattens the given array. * @param deepArray the array to flatten * @param type of the array elements * @returns returns an array containing all the values contained in the sub arrays of deep array. */ function flattenArray(deepArray) { if (deepArray.length === 0) { return []; } const [head, ...tail] = deepArray; return Array.prototype.concat.apply(head, tail); } /** * Appends the toAppend array to the target array. The result is stored in the target array (therefore, in place) * @param target the first element to concat and as well as the target of the concatenation operation * @param toAppend the array to append to target */ function concatInPlace(target, toAppend) { const insertionIndex = target.length; target.length += toAppend.length; for (let i = 0; i < toAppend.length; ++i) { target[insertionIndex + i] = toAppend[i]; } return target; } /***/ }), /* 4 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony export (immutable) */ __webpack_exports__["a"] = isSerializedFunctionCall; /** * @module parallel */ /** */ /** * Tests if the given object is a serialized function call * @param potentialFunc a potentially serialized function call * @returns {boolean} true if it is a serialized function call, false otherwise */ function isSerializedFunctionCall(potentialFunc) { return !!potentialFunc && potentialFunc.______serializedFunctionCall === true; } /***/ }), /* 5 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony export (immutable) */ __webpack_exports__["h"] = initializeWorkerMessage; /* harmony export (immutable) */ __webpack_exports__["i"] = scheduleTaskMessage; /* harmony export (immutable) */ __webpack_exports__["d"] = requestFunctionMessage; /* harmony export (immutable) */ __webpack_exports__["n"] = functionResponseMessage; /* harmony export (immutable) */ __webpack_exports__["g"] = workerResultMessage; /* harmony export (immutable) */ __webpack_exports__["f"] = functionExecutionError; /* harmony export (immutable) */ __webpack_exports__["j"] = stopMessage; /* harmony export (immutable) */ __webpack_exports__["c"] = isScheduleTask; /* harmony export (immutable) */ __webpack_exports__["b"] = isInitializeMessage; /* harmony export (immutable) */ __webpack_exports__["k"] = isFunctionRequest; /* harmony export (immutable) */ __webpack_exports__["e"] = isFunctionResponse; /* harmony export (immutable) */ __webpack_exports__["l"] = isWorkerResult; /* harmony export (immutable) */ __webpack_exports__["m"] = isFunctionExecutionError; /* harmony export (immutable) */ __webpack_exports__["a"] = isStopMesssage; /** * Creates an initialize worker message * @param id the unique id of the worker * @returns the initialize worker message */ function initializeWorkerMessage(id) { return { type: 0 /* InitializeWorker */, workerId: id }; } /** * Creates a message to schedule the given task on a worker slave * @param task the task to schedule * @returns the schedule message */ function scheduleTaskMessage(task) { return { task, type: 1 /* ScheduleTask */ }; } /** * Creates an {@link IFunctionRequest} message that requests the given function ids from the worker thread * @param functionId the id of a function to request * @param otherFunctionIds additional ids to request from the worker slave * @returns the function request message */ function requestFunctionMessage(functionId, ...otherFunctionIds) { return { functionIds: [functionId, ...otherFunctionIds], type: 2 /* FunctionRequest */ }; } /** * Creates a function response message containing the passed function definitions * @param functions the function definitions to respond to the worker slave * @returns the function response message */ function functionResponseMessage(functions, ...missingFunctionIds) { return { functions, missingFunctions: missingFunctionIds, type: 3 /* FunctionResponse */ }; } /** * Creates a worker result message for the given result * @param result the computed result for the scheduled task * @returns the message */ function workerResultMessage(result) { return { result, type: 4 /* WorkerResult */ }; } /** * Creates a function execution error message containing the given error * @param error the error object thrown by the task computation * @returns the message */ function functionExecutionError(error) { const errorObject = {}; for (const prop of Object.getOwnPropertyNames(error)) { errorObject[prop] = JSON.stringify(error[prop]); } return { error: errorObject, type: 5 /* FunctionExecutionError */ }; } /** * Creates a stop message * @returns the message */ function stopMessage() { return { type: 6 /* Stop */ }; } /** * Tests if the given message is an {@link IScheduleTaskMessage} message * @param message the message to test * @returns {boolean} {@code true} if the message is an {@link IScheduleTaskMessage} */ function isScheduleTask(message) { return message.type === 1 /* ScheduleTask */; } /** * Tests if the given message is an {@link IInitializeWorkerMessage} message * @param message the message to test * @returns {boolean} {@code true} if the message is an {@link IInitializeWorkerMessage} */ function isInitializeMessage(message) { return message.type === 0 /* InitializeWorker */; } /** * Tests if the given message is an {@link IFunctionRequest} message * @param message the message to test * @returns {boolean} {@code true} if the message is an {@link IFunctionRequest} */ function isFunctionRequest(message) { return message.type === 2 /* FunctionRequest */; } /** * Tests if the given message is an {@link IFunctionResponse} message * @param message the message to test * @returns {boolean} {@code true} if the message is an {@link IFunctionResponse} */ function isFunctionResponse(message) { return message.type === 3 /* FunctionResponse */; } /** * Tests if the given message is an {@link IWorkerResultMessage} message * @param message the message to test * @returns {boolean} {@code true} if the message is an {@link IWorkerResultMessage} */ function isWorkerResult(message) { return message.type === 4 /* WorkerResult */; } /** * Tests if the given message is an {@link IFunctionExecutionError} message * @param message the message to test * @returns {boolean} {@code true} if the message is an {@link IFunctionExecutionError} */ function isFunctionExecutionError(message) { return message.type === 5 /* FunctionExecutionError */; } /** * Tests if the given message is a stop message * @param message the message to test * @returns {boolean} {@code true} if the message is a stop message */ function isStopMesssage(message) { return message.type === 6 /* Stop */; } /***/ }), /* 6 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__scheduled_parallel_stream__ = __webpack_require__(39); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__resolved_parallel_stream__ = __webpack_require__(38); /** * Generic parallel stream that can be coordinated using the provided next, resolve and reject callbacks. * @param TSubResult type of the sub results * @param TEndResult type of the end result */ class ParallelStream { /** * Creates a new, generic parallel stream * @param executor the executor function that gets passed the next, resolve and reject functions */ constructor(executor) { /** * Registered handlers that should be called for each sub result * @type {Array} * @private */ this.nextHandlers = []; const next = (subResult, worker, valuesPerWorker) => this._next(subResult, worker, valuesPerWorker); const reject = (reason) => this.reject(reason); const resolve = (result) => this.resolve(result); executor(next, resolve, reject); this.promise = new Promise((res, rej) => { this.resolve = res; this.reject = rej; }); } /** * Creates a new parallel that is based on the given input stream but transforms the end result using the given transformer * @param inputStream the input stream on which the returned stream is based on * @param transformer the transformer used to transform the end result * @param TIn type of the input elements for this stream * @param TIntermediate type of the end results from the input stream * @param TResult end result after applying the transformer. * @returns parallel stream that is based on the given input stream but with the transformed end result */ static transform(inputStream, transformer) { let next; let resolve; let reject; const transformedStream = new ParallelStream((nxt, rsolve, rject) => { next = nxt; resolve = rsolve; reject = rject; }); inputStream.subscribe(next, reject, (result) => resolve(transformer(result))); return transformedStream; } /** * Creates a new parallel stream for the given set of tasks. * @param tasks the set of tasks that compute the results of the stream * @param defaultResult the default result * @param joiner the joiner to use to join two computed task results * @param TTaskResult type of the task results * @param TEndResult result of the created stream. Created by applying the end results of the stream to the joiner * @returns stream for the given set of tasks */ static fromTasks(tasks, defaultResult, joiner) { if (tasks.length === 0) { return new __WEBPACK_IMPORTED_MODULE_1__resolved_parallel_stream__["a" /* ResolvedParallelStream */](defaultResult); } return new __WEBPACK_IMPORTED_MODULE_0__scheduled_parallel_stream__["a" /* ScheduledParallelStream */](tasks, defaultResult, joiner); } subscribe(onNext, onError, onComplete) { this.nextHandlers.push(onNext); if (onError || onComplete) { this.promise.then(onComplete, onError); } return this; } then(onfulfilled, onrejected) { return this.promise.then(onfulfilled, onrejected); } catch(onrejected) { return this.promise.catch(onrejected); } _next(subResult, taskIndex, valuesPerTask) { for (const nextHandler of this.nextHandlers) { nextHandler.apply(undefined, arguments); } } } /* harmony export (immutable) */ __webpack_exports__["a"] = ParallelStream; /***/ }), /* 7 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /** * A very simple implementation of a map. Do not use with complex objects as Key. * @param K type of the key * @param V type of the value */ /** * A very simple implementation of a map. Do not use with complex objects as Key. * @param K type of the key * @param V type of the value */ class SimpleMap { constructor() { this.data = {}; } /** * Gets the value for the given key if available * @param key the key to look up * @returns the looked up value or undefined if the map does not contain any value associated with the given key */ get(key) { const internalKey = this.toInternalKey(key); return this.has(key) ? this.data[internalKey] : undefined; } /** * Tests if the map contains value stored by the given key * @param key the key * @returns true if the map contains a value by the given key, false otherwise */ has(key) { return this.hasOwnProperty.call(this.data, this.toInternalKey(key)); } /** * Sets the value for the given key. If the map already contains a value stored by the given key, then this value is * overridden * @param key the key * @param value the value to associate with the given key */ set(key, value) { this.data[this.toInternalKey(key)] = value; } /** * Clears all values from the map */ clear() { this.data = {}; } toInternalKey(key) { return `@${key}`; } } /* harmony export (immutable) */ __webpack_exports__["a"] = SimpleMap; /***/ }), /* 8 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /** * @module parallel */ /** */ /** * Serializer for function calls */ class FunctionCallSerializer { /** * Creates a new instances that uses the given function registry to lookup the unique id of a function * @param functionRegistry the registry for function lookup */ constructor(functionRegistry) { this.functionRegistry = functionRegistry; } /** * Serializes a call to the given function and using the passed parameters * @param call the function call to serialize * @returns a serialized representation of a call to the passed function using the given parameters */ serializeFunctionCall(call) { const funcId = this.functionRegistry.getOrSetId(call.func); return { ______serializedFunctionCall: true, functionId: funcId, parameters: call.params }; } } /* harmony export (immutable) */ __webpack_exports__["a"] = FunctionCallSerializer; /***/ }), /* 9 */, /* 10 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__dependent_parallel_chain_state__ = __webpack_require__(24); /** * State of a parallel chain whose job has been scheduled on the thread pool (or even where the computation already has completed). * @param TElement type of the elements produced by the stream */ class ScheduledParallelChainState { /** * Creates a new state that is based on the given stream * @param stream the stream for the scheduled tasks * @param options the options used for the scheduled job * @param environment the environment used for the scheduled job */ constructor(stream, options, environment) { this.options = options; this.environment = environment; this.stream = stream; } resolve() { return this; } chainOperation(operation) { return new __WEBPACK_IMPORTED_MODULE_0__dependent_parallel_chain_state__["a" /* DependentParallelChainState */](this.stream, this.options, this.environment, [operation]); } addEnvironment(environment) { return new __WEBPACK_IMPORTED_MODULE_0__dependent_parallel_chain_state__["a" /* DependentParallelChainState */](this.stream, this.options, this.environment.add(environment)); } } /* harmony export (immutable) */ __webpack_exports__["a"] = ScheduledParallelChainState; /***/ }), /* 11 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__slave_parallel_worker_functions__ = __webpack_require__(2); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__function_function_call__ = __webpack_require__(0); /** * Generator for arrays. * Splits the array elements onto separate tasks. * @param T type of the array elements */ class ParallelCollectionGenerator { /** * Creates a new instance over the given collection * @param collection */ constructor(collection) { this.collection = collection; } get length() { return this.collection.length; } serializeSlice(index, numberOfItems, functionCallSerializer) { const start = numberOfItems * index; const end = start + numberOfItems; return functionCallSerializer.serializeFunctionCall(__WEBPACK_IMPORTED_MODULE_1__function_function_call__["a" /* FunctionCall */].createUnchecked(__WEBPACK_IMPORTED_MODULE_0__slave_parallel_worker_functions__["a" /* ParallelWorkerFunctionIds */].TO_ITERATOR, this.collection.slice(start, end))); } } /* harmony export (immutable) */ __webpack_exports__["a"] = ParallelCollectionGenerator; /***/ }), /* 12 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__common_function_function_id__ = __webpack_require__(1); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return __WEBPACK_IMPORTED_MODULE_0__common_function_function_id__["b"]; }); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__common_function_function_call__ = __webpack_require__(0); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return __WEBPACK_IMPORTED_MODULE_1__common_function_function_call__["a"]; }); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__common_function_serialized_function_call__ = __webpack_require__(4); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return __WEBPACK_IMPORTED_MODULE_2__common_function_serialized_function_call__["a"]; }); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__common_function_function_call_serializer__ = __webpack_require__(8); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "d", function() { return __WEBPACK_IMPORTED_MODULE_3__common_function_function_call_serializer__["a"]; }); /***/ }), /* 13 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__util_simple_map__ = __webpack_require__(7); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__function_id__ = __webpack_require__(1); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_function_name__ = __webpack_require__(41); /** * Lookup table for resolving dynamic functions and their definitions */ class DynamicFunctionRegistry { constructor() { this.ids = new __WEBPACK_IMPORTED_MODULE_0__util_simple_map__["a" /* SimpleMap */](); this.definitions = new __WEBPACK_IMPORTED_MODULE_0__util_simple_map__["a" /* SimpleMap */](); this.lastId = 0; } /** * Returns the unique id for the passed in function or assigns a new id to the given function and returns the newly assigned id * @param func the function for which the unique id should be determined * @returns the id of this function */ getOrSetId(func) { if (__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_1__function_id__["b" /* isFunctionId */])(func)) { return func; } const source = func.toString(); let identifier = this.ids.get(source); if (typeof (identifier) === "undefined") { identifier = __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_1__function_id__["a" /* functionId */])("dynamic", ++this.lastId); this.initDefinition(func, identifier); } return identifier; } /** * Returns the definition of the function with the given id or undefined, if the id is not assigned to any function definition * @param id the id of the function to resolve * @returns the resolved function definition or undefined * @throws if the function is a static function and therefore no definition exists. */ getDefinition(id) { return this.definitions.get(id.identifier); } initDefinition(func, id) { const source = func.toString(); const name = __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_2__util_function_name__["a" /* getFunctionName */])(func); const args = source.substring(source.indexOf("(") + 1, source.indexOf(")")).split(","); const body = source.substring(source.indexOf("{") + 1, source.lastIndexOf("}")).trim(); const definition = { argumentNames: args.map(arg => arg.trim()), body, id, name: name ? name : undefined }; this.ids.set(source, id); this.definitions.set(id.identifier, definition); } } /* harmony export (immutable) */ __webpack_exports__["a"] = DynamicFunctionRegistry; /***/ }), /* 14 */, /* 15 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony export (immutable) */ __webpack_exports__["a"] = parallelFactory; /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__parallel_options__ = __webpack_require__(31); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__generator_parallel_collection_generator__ = __webpack_require__(11); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__generator_parallel_range_generator__ = __webpack_require__(28); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__generator_parallel_times_generator__ = __webpack_require__(29); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__chain_parallel_chain_factory__ = __webpack_require__(25); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__function_function_id__ = __webpack_require__(1); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__function_function_call__ = __webpack_require__(0); function parallelFactory(defaultOptions) { function mergeOptions(userOptions) { if (userOptions) { if (userOptions.hasOwnProperty("threadPool") && typeof (userOptions.threadPool) === "undefined") { throw new Error("The thread pool is mandatory and cannot be unset"); } if (userOptions.hasOwnProperty("functionCallSerializer") && typeof (userOptions.functionCallSerializer) === "undefined") { throw new Error("The function call serializer is mandatory and cannot be unset"); } __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0__parallel_options__["a" /* validateOptions */])(userOptions); } return Object.assign({}, defaultOptions, userOptions); } return { defaultOptions(options) { if (options) { defaultOptions = mergeOptions(options); } else { return Object.assign({}, defaultOptions); } }, from(collection, options) { return __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_4__chain_parallel_chain_factory__["a" /* createParallelChain */])(new __WEBPACK_IMPORTED_MODULE_1__generator_parallel_collection_generator__["a" /* ParallelCollectionGenerator */](collection), mergeOptions(options)); }, range(start, end, step, options) { const generator = __WEBPACK_IMPORTED_MODULE_2__generator_parallel_range_generator__["a" /* ParallelRangeGenerator */].create(start, end, step); return __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_4__chain_parallel_chain_factory__["a" /* createParallelChain */])(generator, mergeOptions(options)); }, times(n, generator, env, options) { if (env) { return __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_4__chain_parallel_chain_factory__["a" /* createParallelChain */])(__WEBPACK_IMPORTED_MODULE_3__generator_parallel_times_generator__["a" /* ParallelTimesGenerator */].create(n, generator), mergeOptions(options), env); } return __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_4__chain_parallel_chain_factory__["a" /* createParallelChain */])(__WEBPACK_IMPORTED_MODULE_3__generator_parallel_times_generator__["a" /* ParallelTimesGenerator */].create(n, generator), mergeOptions(options)); }, run(func, ...params) { let functionCall; if (__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_5__function_function_id__["b" /* isFunctionId */])(func)) { functionCall = __WEBPACK_IMPORTED_MODULE_6__function_function_call__["a" /* FunctionCall */].create(func, params); } else { functionCall = __WEBPACK_IMPORTED_MODULE_6__function_function_call__["a" /* FunctionCall */].create(func, params); } const serializedCall = defaultOptions.functionCallSerializer.serializeFunctionCall(functionCall); const task = { main: serializedCall, usedFunctionIds: [serializedCall.functionId] }; return defaultOptions.threadPool.run(task); } }; } /***/ }), /* 16 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__abstract_parallel_scheduler__ = __webpack_require__(32); /** * Default implementation of a parallel scheduler. * By default, creates 4 times as many tasks as the hardware concurrency allows ({@link IParallelOptions.maxConcurrencyLevel}). * * If the options define {@link IParallelOptions.maxValuesPerTask} or {@link IParallelOptions.minValuesPerTask}, then the * values are adjusted accordingly. */ class DefaultParallelScheduler extends __WEBPACK_IMPORTED_MODULE_0__abstract_parallel_scheduler__["a" /* AbstractParallelScheduler */] { getScheduling(totalNumberOfValues, options) { let maxDegreeOfParallelism; if (options.maxDegreeOfParallelism) { maxDegreeOfParallelism = options.maxDegreeOfParallelism; } else { maxDegreeOfParallelism = options.threadPool.maxThreads * 4; } let valuesPerTask = totalNumberOfValues / maxDegreeOfParallelism; if (options.minValuesPerTask) { valuesPerTask = Math.min(Math.max(valuesPerTask, options.minValuesPerTask), totalNumberOfValues); } if (options.maxValuesPerTask) { valuesPerTask = Math.min(valuesPerTask, options.maxValuesPerTask); } valuesPerTask = Math.ceil(valuesPerTask); return { numberOfTasks: valuesPerTask === 0 ? 0 : Math.ceil(totalNumberOfValues / valuesPerTask), valuesPerTask }; } } /* harmony export (immutable) */ __webpack_exports__["a"] = DefaultParallelScheduler; /***/ }), /* 17 */, /* 18 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__task_worker_task__ = __webpack_require__(40); /** * Default thread pool implementation that processes the scheduled functions in FIFO order. */ class DefaultThreadPool { constructor(workerThreadFactory, options) { this.workerThreadFactory = workerThreadFactory; this.workers = []; this.idleWorkers = []; this.queue = []; this.maxThreadsLimit = options.maxConcurrencyLevel; } get maxThreads() { return this.maxThreadsLimit; } set maxThreads(limit) { if (typeof (limit) !== "number" || limit % 1 !== 0 || limit <= 0) { throw new Error(`The maxThreads limit (${limit}) has to be a positive integer larger than zero.`); } this.maxThreadsLimit = limit; } run(taskDefinition) { const task = new __WEBPACK_IMPORTED_MODULE_0__task_worker_task__["a" /* WorkerTask */](taskDefinition); this.queue.unshift(task); this.schedulePendingTasks(); return task; } /** * Schedules the tasks in the queue onto the available workers. * A new worker is spawned when no more idle workers are available and the number of workers has not yet reached the concurrency limit. * If no more idle workers are available and the concurrency limit has been reached then the tasks are left in queue. */ schedulePendingTasks() { while (this.queue.length) { let worker; if (this.idleWorkers.length === 0 && this.workers.length < this.maxThreadsLimit) { worker = this.workerThreadFactory.spawn(); this.workers.push(worker); } else if (this.idleWorkers.length > 0) { worker = this.idleWorkers.pop(); } if (!worker) { return; } const task = this.queue.pop(); this.runTaskOnWorker(task, worker); } } /** * Starts the given task on the given worker. Resolves the task when the computation succeeds, rejects it otherwise. * The task is resolved when the computation has succeeded or is rejected if the computation failed * @param task the task to run on the given worker * @param worker the worker to use to execute the task */ runTaskOnWorker(task, worker) { if (task.isCancellationRequested) { task.resolveCancelled(); this.releaseWorker(worker); } else { worker.run(task.definition, (error, result) => { if (error) { task.reject(error); } else { task.resolve(result); } this.releaseWorker(worker); }); } } releaseWorker(worker) { this.idleWorkers.push(worker); this.schedulePendingTasks(); } } /* harmony export (immutable) */ __webpack_exports__["a"] = DefaultThreadPool; /***/ }), /* 19 */, /* 20 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_child_process__ = __webpack_require__(49); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_child_process___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_child_process__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__common_worker_default_worker_thread__ = __webpack_require__(44); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__child_process_worker_thread_slave_communication_channel__ = __webpack_require__(48); class NodeWorkerThreadFactory { constructor(functionLookupTable) { this.functionLookupTable = functionLookupTable; } spawn() { const child = __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0_child_process__["fork"])(this.getSlaveFileName()); const workerThread = new __WEBPACK_IMPORTED_MODULE_1__common_worker_default_worker_thread__["a" /* DefaultWorkerThread */](this.functionLookupTable, new __WEBPACK_IMPORTED_MODULE_2__child_process_worker_thread_slave_communication_channel__["a" /* ChildProcessWorkerThreadSlaveCommunicationChannel */](child)); workerThread.initialize(); return workerThread; } /** * Hackedy Hack... Issue is, webpack handles calls to require resolve and replaces the call with the module id * but that's not what we want. We actually want the require resolve call to be left until execution. * NoParse is neither an option because then no requires / imports are resolved * @returns {string} the file name of the slave */ getSlaveFileName() { return eval("require").resolve("./node-slave.parallel"); } } /* harmony export (immutable) */ __webpack_exports__["a"] = NodeWorkerThreadFactory; /***/ }), /* 21 */ /***/ (function(module, exports) { module.exports = require("os"); /***/ }), /* 22 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_os__ = __webpack_require__(21); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_os___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_os__); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__common_function_dynamic_function_registry__ = __webpack_require__(13); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__common_function_function_call_serializer__ = __webpack_require__(8); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__node_worker_node_worker_thread_factory__ = __webpack_require__(20); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_thread_pool_default_thread_pool__ = __webpack_require__(18); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__common_parallel_parallel_impl__ = __webpack_require__(15); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__common_parallel_scheduling_default_parallel_scheduler__ = __webpack_require__(16); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__shared__ = __webpack_require__(12); /* harmony namespace reexport (by provided) */ __webpack_require__.d(__webpack_exports__, "isFunctionId", function() { return __WEBPACK_IMPORTED_MODULE_7__shared__["a"]; }); /* harmony namespace reexport (by provided) */ __webpack_require__.d(__webpack_exports__, "FunctionCall", function() { return __WEBPACK_IMPORTED_MODULE_7__shared__["b"]; }); /* harmony namespace reexport (by provided) */ __webpack_require__.d(__webpack_exports__, "isSerializedFunctionCall", function() { return __WEBPACK_IMPORTED_MODULE_7__shared__["c"]; }); /* harmony namespace reexport (by provided) */ __webpack_require__.d(__webpack_exports__, "FunctionCallSerializer", function() { return __WEBPACK_IMPORTED_MODULE_7__shared__["d"]; }); const functionLookupTable = new __WEBPACK_IMPORTED_MODULE_1__common_function_dynamic_function_registry__["a" /* DynamicFunctionRegistry */](); const maxConcurrencyLevel = __WEBPACK_IMPORTED_MODULE_0_os__["cpus"]().length; const functionCallSerializer = new __WEBPACK_IMPORTED_MODULE_2__common_function_function_call_serializer__["a" /* FunctionCallSerializer */](functionLookupTable); const threadPool = new __WEBPACK_IMPORTED_MODULE_4__common_thread_pool_default_thread_pool__["a" /* DefaultThreadPool */](new __WEBPACK_IMPORTED_MODULE_3__node_worker_node_worker_thread_factory__["a" /* NodeWorkerThreadFactory */](functionLookupTable), { maxConcurrencyLevel }); /** * The global parallel instance. */ const parallel = __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_5__common_parallel_parallel_impl__["a" /* parallelFactory */])({ functionCallSerializer, scheduler: new __WEBPACK_IMPORTED_MODULE_6__common_parallel_scheduling_default_parallel_scheduler__["a" /* DefaultParallelScheduler */](), threadPool }); /* harmony default export */ __webpack_exports__["default"] = (parallel); /***/ }), /* 23 */, /* 24 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__scheduled_parallel_chain_state__ = __webpack_require__(10); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__generator_parallel_collection_generator__ = __webpack_require__(11); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_arrays__ = __webpack_require__(3); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__stream_parallel_stream_impl__ = __webpack_require__(6); /** * The state of a parallel chain if additional operations should be performed on an already scheduled parallel chain. * * The state needs to wait for the previous parallel job to complete and then take that result to continue the additional * computations. * * @param TPrevious Type of the array elements of the dependent stream * @param TElement Type of the array elements of the resulting array */ class DependentParallelChainState { /** * Creates a new dependent stream * @param previousStream the stream upon which the new stream depends on * @param options the options used by this parallel job * @param environment the environment used by the job * @param operations the operations to performed when the previous stream has completed */ constructor(previousStream, options, environment, operations = []) { this.previousStream = previousStream; this.options = options; this.environment = environment; this.operations = operations; } resolve() { let next; let resolve; let reject; const stream = new __WEBPACK_IMPORTED_MODULE_3__stream_parallel_stream_impl__["a" /* ParallelStream */]((nxt, rsolve, rject) => { next = nxt; resolve = rsolve; reject = rject; }); this.previousStream.then(result => { const tasks = this.options.scheduler.schedule({ environment: this.environment, generator: new __WEBPACK_IMPORTED_MODULE_1__generator_parallel_collection_generator__["a" /* ParallelCollectionGenerator */](result), operations: this.operations, options: this.options }); const wrappedStream = __WEBPACK_IMPORTED_MODULE_3__stream_parallel_stream_impl__["a" /* ParallelStream */].fromTasks(tasks, [], __WEBPACK_IMPORTED_MODULE_2__util_arrays__["d" /* concatInPlace */]); wrappedStream.subscribe(next, reject, resolve); }, reject); return new __WEBPACK_IMPORTED_MODULE_0__scheduled_parallel_chain_state__["a" /* ScheduledParallelChainState */](stream, this.options, this.environment); } chainOperation(operation) { return new DependentParallelChainState(this.previousStream, this.options, this.environment, [...this.operations, operation]); } addEnvironment(environment) { return new DependentParallelChainState(this.previousStream, this.options, this.environment.add(environment), this.operations); } } /* harmony export (immutable) */ __webpack_exports__["a"] = DependentParallelChainState; /***/ }), /* 25 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony export (immutable) */ __webpack_exports__["a"] = createParallelChain; /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__pending_parallel_chain_state__ = __webpack_require__(27); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__parallel_chain_impl__ = __webpack_require__(26); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__parallel_environment_definition__ = __webpack_require__(30); function createParallelChain(generator, options, sharedEnv, operations = []) { let environment; if (sharedEnv instanceof Array) { environment = undefined; operations = sharedEnv; } else { environment = sharedEnv; } const chain = new __WEBPACK_IMPORTED_MODULE_1__parallel_chain_impl__["a" /* ParallelChainImpl */](new __WEBPACK_IMPORTED_MODULE_0__pending_parallel_chain_state__["a" /* PendingParallelChainState */](generator, options, __WEBPACK_IMPORTED_MODULE_2__parallel_environment_definition__["a" /* ParallelEnvironmentDefinition */].of(), operations)); return environment ? chain.inEnvironment(environment) : chain; } /***/ }), /* 26 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__slave_parallel_worker_functions__ = __webpack_require__(2); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__function_function_call__ = __webpack_require__(0); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__stream_parallel_stream_impl__ = __webpack_require__(6); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__function_function_id__ = __webpack_require__(1); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__function_serialized_function_call__ = __webpack_require__(4); /** * Implementation of a {@link IParallelChain} * * The implementation uses an internal state ({@link IParallelChainState}) to distinguishes between a not yet scheduled job ({@link PendingParallelChainState}), * a job that has been scheduled but potentially not yet completed ({@link ScheduledParallelChainState}) and a job that * is waiting for another one to complete, but has not yet been scheduled ({@link DependentParallelChainState}). * * @param TIn type of the elements created by the generator * @param TEnv type of the job environment * @param TOut type of the elements in the resulting array */ class ParallelChainImpl { /** * Creates a new parallel chain with the given state * @param state the state of the chain */ constructor(state) { this.state = state; } // region Chaining inEnvironment(newEnv, ...params) { let env; if (typeof newEnv === "function" || __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_3__function_function_id__["b" /* isFunctionId */])(newEnv)) { env = __WEBPACK_IMPORTED_MODULE_1__function_function_call__["a" /* FunctionCall */].createUnchecked(newEnv, ...params); } else if (__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_4__function_serialized_function_call__["a" /* isSerializedFunctionCall */])(newEnv)) { env = __WEBPACK_IMPORTED_MODULE_1__function_function_call__["a" /* FunctionCall */].fromSerialized(newEnv); } else { env = newEnv; } return new ParallelChainImpl(this.state.addEnvironment(env)); } map(mapper) { return this._chain(__WEBPACK_IMPORTED_MODULE_1__function_function_call__["a" /* FunctionCall */].createUnchecked(__WEBPACK_IMPORTED_MODULE_0__slave_parallel_worker_functions__["a" /* ParallelWorkerFunctionIds */].MAP), __WEBPACK_IMPORTED_MODULE_1__function_function_call__["a" /* FunctionCall */].createUnchecked(mapper)); } reduce(defaultValue, accumulator, combiner) { const combineOperation = combiner || accumulator; const reduced = this._chain(__WEBPACK_IMPORTED_MODULE_1__function_function_call__["a" /* FunctionCall */].createUnchecked(__WEBPACK_IMPORTED_MODULE_0__slave_parallel_worker_functions__["a" /* ParallelWorkerFunctionIds */].REDUCE, defaultValue), __WEBPACK_IMPORTED_MODULE_1__function_function_call__["a" /* FunctionCall */].createUnchecked(accumulator)).resolveChain(); r