@eroc/core
Advanced tools
Comparing version 4.3.0 to 4.3.1
@@ -1,2 +0,2 @@ | ||
/* @eroc/core v4.3.0 2021-09-15T19:01:12.070Z licensed MIT */ | ||
/* @eroc/core v4.3.1 2021-09-25T17:34:47.706Z licensed MIT */ | ||
const startEventRecorder = (core) => { | ||
@@ -314,3 +314,3 @@ const events = []; | ||
const workerGlueCode = "/**\n * Use it as a constructor\n * or as a decorator for an existing object\n * or as a base class for extend\n * cannot be used as a mixin for a constructor's prototype\n * without calling the constructor\n */\nfunction EventEmitter3(obj) {\n (obj || this)._callbacks = Object.create(null);\n if (obj) {return Object.assign(obj, EventEmitter3.prototype);}\n}\n\n/**\n * Listen on the given `eventName` with `fn`\n *\n * @param {String | Symbol} eventName\n * @param {Function} fn\n * @api public\n */\n\nEventEmitter3.prototype.on = function (eventName, fn) {\n (this._callbacks[eventName] = this._callbacks[eventName] || [])\n .push(fn);\n};\n\n/**\n * Adds an `eventName` listener that will be invoked once then removed\n *\n * @param {String | Symbol} eventName\n * @param {Function} fn\n * @api public\n */\n\nEventEmitter3.prototype.once = function (eventName, fn) {\n const once = (data) => {\n this.off(eventName, once);\n fn(data);\n };\n\n once.fn = fn; // makes it possible to remove with off\n this.on(eventName, once);\n};\n\n/**\n * Remove a callback for `eventName` or\n * all callbacks for `eventName` or\n * all callbacks for all events\n *\n * @param {String | Symbol} eventName\n * @param {Function} fn\n * @api public\n */\n\nEventEmitter3.prototype.off = function (eventName, fn) {\n // all\n if (!eventName) {\n this._callbacks = Object.create(null);\n return;\n }\n\n // specific event\n const callbacks = this._callbacks[eventName];\n if (!callbacks) {\n return;\n }\n\n // remove all handlers\n if (!fn) {\n delete this._callbacks[eventName];\n return;\n }\n\n // remove specific handler\n const index = callbacks.findIndex(function (cb) {\n return (cb === fn || cb.fn === fn);\n });\n if (index > -1) {\n // Remove event specific arrays for the eventName type that no\n // one is subscribed for, to avoid memory leak.\n if (callbacks.length === 1) {\n delete this._callbacks[eventName];\n } else {\n callbacks.splice(index, 1);\n }\n }\n};\n\n/**\n * Emit `eventName` with data\n *\n * @param {String | Symbol} eventName\n * @param {any} data\n */\n\nEventEmitter3.prototype.emit = function (eventName, data) {\n const callbacks = this._callbacks[eventName];\n if (!callbacks) {\n return;\n }\n const frozenCallbacks = Array.from(callbacks);\n frozenCallbacks.forEach(callback => {\n callback(data);\n });\n};\n\n/**\n * Return array of callbacks for `eventName`\n *\n * @param {String | Symbol} eventName\n * @return {Array} listeners\n * @api public\n */\n\nEventEmitter3.prototype.listeners = function (eventName) {\n return this._callbacks[eventName] || [];\n};\n\n/**\n * True if this emitter has `eventName` handlers\n *\n * @param {String | Symbol} eventName\n * @return {Boolean}\n * @api public\n */\n\nEventEmitter3.prototype.hasListeners = function (eventName) {\n return Boolean(this.listeners(eventName).length);\n};\n\n/**\n * Returns an array of event names for which the emitter has registered listeners\n *\n * @return {Array <String || Symbol>}\n * @api public\n */\nEventEmitter3.prototype.eventNames = function () {\n return Reflect.ownKeys(this._callbacks);\n};\n\n/**\n * Returns an array of event anmes of type string\n * for which the emitter has registered listeners\n *\n * @return {Array <String>}\n * @api public\n */\nEventEmitter3.prototype.eventNamesStrings = function () {\n return Object.keys(this._callbacks);\n};\n\n// prefix to avoid variable name collision\r\nconst CORE_ACTION_KEY = `action`;\r\n\r\n// actions\r\nconst CORE_EVENT = `CORE_EVENT`;\r\nconst CORE_START = `CORE_START`;\r\nconst CORE_STARTED = `CORE_STARTED`;\r\nconst CORE_STOP = `CORE_STOP`;\r\nconst CORE_STOPPED = `CORE_STOPPED`;\r\nconst CORE_GET_STATE = `CORE_GET_STATE`;\r\nconst CORE_SET_STATE = `CORE_SET_STATE`;\r\nconst CORE_ERROR = `CORE_ERROR`;\n\nlet localEmitter;\r\nlet localInstance;\r\n\r\nself.addEventListener(`error`, function (errorEvent) {\r\n errorEvent.preventDefault();\r\n let asString;\r\n if (errorEvent.message) {\r\n asString = errorEvent.message;\r\n } else {\r\n asString = String(errorEvent);\r\n }\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_ERROR,\r\n error: asString,\r\n });\r\n});\r\n\r\nself.addEventListener(`message`, async function(messageEvent) {\r\n const message = messageEvent.data;\r\n if (!Object.prototype.hasOwnProperty.call(message, CORE_ACTION_KEY)) {\r\n return;\r\n }\r\n const action = message[CORE_ACTION_KEY];\r\n if (action === CORE_EVENT) {\r\n if (!localInstance) {\r\n return;\r\n }\r\n // avoid infinite loop\r\n localEmitter.originalEmit(message.name, message.data);\r\n return;\r\n }\r\n if (action === CORE_START) {\r\n localEmitter = new EventEmitter3();\r\n localEmitter.originalEmit = localEmitter.emit;\r\n localEmitter.emit = function (eventName, data) {\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_EVENT,\r\n name: eventName,\r\n data,\r\n });\r\n localEmitter.originalEmit(eventName, data);\r\n };\r\n \r\n Promise.resolve().then(() => {\r\n return start(localEmitter, message.data);\r\n }).then(instance => {\r\n localInstance = instance;\r\n }).catch(errorModuleStart => {\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_ERROR,\r\n time: Date.now(),\r\n phase: `module.start`,\r\n error: errorModuleStart,\r\n });\r\n }).then(() => {\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_STARTED,\r\n });\r\n });\r\n return;\r\n }\r\n if (action === CORE_STOP) {\r\n if (!localInstance) {\r\n // should never happen\r\n return;\r\n }\r\n Promise.resolve().then(() => {\r\n if (typeof stop === `function`) {\r\n return stop(wrapper.instance);\r\n }\r\n }).catch(errorModuleStop => {\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_ERROR,\r\n time: Date.now(),\r\n phase: `module.stop`,\r\n error: errorModuleStop,\r\n });\r\n }).then(() => {\r\n localInstance = undefined;\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_STOPPED,\r\n });\r\n });\r\n return;\r\n }\r\n\r\n if (action === CORE_SET_STATE) {\r\n Promise.resolve().then(() => {\r\n if (typeof restoreState === `function`) {\r\n return restoreState(localInstance, message.data);\r\n }\r\n }).then(() => {\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_GET_STATE,\r\n });\r\n }).catch(errorModuleRestoreState => {\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_ERROR,\r\n time: Date.now(),\r\n phase: `module.restoreState`,\r\n error: errorModuleRestoreState,\r\n });\r\n });\r\n return;\r\n }\r\n if (action === CORE_GET_STATE) {\r\n Promise.resolve().then(() => {\r\n if (typeof getState === `function`) {\r\n return getState(localInstance);\r\n }\r\n }).then((result) => {\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_SET_STATE,\r\n data: result, // core will handle undefined\r\n });\r\n }).catch(errorModuleRestoreState => {\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_ERROR,\r\n time: Date.now(),\r\n phase: `module.restoreState`,\r\n error: errorModuleRestoreState,\r\n });\r\n });\r\n return;\r\n }\r\n\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_ERROR,\r\n error: `action ${action} not implemented`,\r\n });\r\n});\r\n\r\n// module code below (defintion of start and stop)\n"; | ||
const workerGlueCode = "/**\n * Use it as a constructor\n * or as a decorator for an existing object\n * or as a base class for extend\n * cannot be used as a mixin for a constructor's prototype\n * without calling the constructor\n */\nfunction EventEmitter3(obj) {\n (obj || this)._callbacks = Object.create(null);\n if (obj) {return Object.assign(obj, EventEmitter3.prototype);}\n}\n\n/**\n * Listen on the given `eventName` with `fn`\n *\n * @param {String | Symbol} eventName\n * @param {Function} fn\n * @api public\n */\n\nEventEmitter3.prototype.on = function (eventName, fn) {\n (this._callbacks[eventName] = this._callbacks[eventName] || [])\n .push(fn);\n};\n\n/**\n * Adds an `eventName` listener that will be invoked once then removed\n *\n * @param {String | Symbol} eventName\n * @param {Function} fn\n * @api public\n */\n\nEventEmitter3.prototype.once = function (eventName, fn) {\n const once = (data) => {\n this.off(eventName, once);\n fn(data);\n };\n\n once.fn = fn; // makes it possible to remove with off\n this.on(eventName, once);\n};\n\n/**\n * Remove a callback for `eventName` or\n * all callbacks for `eventName` or\n * all callbacks for all events\n *\n * @param {String | Symbol} eventName\n * @param {Function} fn\n * @api public\n */\n\nEventEmitter3.prototype.off = function (eventName, fn) {\n // all\n if (!eventName) {\n this._callbacks = Object.create(null);\n return;\n }\n\n // specific event\n const callbacks = this._callbacks[eventName];\n if (!callbacks) {\n return;\n }\n\n // remove all handlers\n if (!fn) {\n delete this._callbacks[eventName];\n return;\n }\n\n // remove specific handler\n const index = callbacks.findIndex(function (cb) {\n return (cb === fn || cb.fn === fn);\n });\n if (index > -1) {\n // Remove event specific arrays for the eventName type that no\n // one is subscribed for, to avoid memory leak.\n if (callbacks.length === 1) {\n delete this._callbacks[eventName];\n } else {\n callbacks.splice(index, 1);\n }\n }\n};\n\n/**\n * Emit `eventName` with data\n *\n * @param {String | Symbol} eventName\n * @param {any} data\n */\n\nEventEmitter3.prototype.emit = function (eventName, data) {\n const callbacks = this._callbacks[eventName];\n if (!callbacks) {\n return;\n }\n const frozenCallbacks = Array.from(callbacks);\n frozenCallbacks.forEach(callback => {\n callback(data);\n });\n};\n\n/**\n * Return array of callbacks for `eventName`\n *\n * @param {String | Symbol} eventName\n * @return {Array} listeners\n * @api public\n */\n\nEventEmitter3.prototype.listeners = function (eventName) {\n return this._callbacks[eventName] || [];\n};\n\n/**\n * True if this emitter has `eventName` handlers\n *\n * @param {String | Symbol} eventName\n * @return {Boolean}\n * @api public\n */\n\nEventEmitter3.prototype.hasListeners = function (eventName) {\n return Boolean(this.listeners(eventName).length);\n};\n\n/**\n * Returns an array of event names for which the emitter has registered listeners\n *\n * @return {Array <String || Symbol>}\n * @api public\n */\nEventEmitter3.prototype.eventNames = function () {\n return Reflect.ownKeys(this._callbacks);\n};\n\n/**\n * Returns an array of event anmes of type string\n * for which the emitter has registered listeners\n *\n * @return {Array <String>}\n * @api public\n */\nEventEmitter3.prototype.eventNamesStrings = function () {\n return Object.keys(this._callbacks);\n};\n\n// prefix to avoid variable name collision\nconst CORE_ACTION_KEY = `action`;\n\n// actions\nconst CORE_EVENT = `CORE_EVENT`;\nconst CORE_START = `CORE_START`;\nconst CORE_STARTED = `CORE_STARTED`;\nconst CORE_STOP = `CORE_STOP`;\nconst CORE_STOPPED = `CORE_STOPPED`;\nconst CORE_GET_STATE = `CORE_GET_STATE`;\nconst CORE_SET_STATE = `CORE_SET_STATE`;\nconst CORE_ERROR = `CORE_ERROR`;\n\nlet localEmitter;\nlet localInstance;\n\nself.addEventListener(`error`, function (errorEvent) {\n errorEvent.preventDefault();\n let asString;\n if (errorEvent.message) {\n asString = errorEvent.message;\n } else {\n asString = String(errorEvent);\n }\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_ERROR,\n error: asString,\n });\n});\n\nself.addEventListener(`message`, async function(messageEvent) {\n const message = messageEvent.data;\n if (!Object.prototype.hasOwnProperty.call(message, CORE_ACTION_KEY)) {\n return;\n }\n const action = message[CORE_ACTION_KEY];\n if (action === CORE_EVENT) {\n if (!localInstance) {\n return;\n }\n // avoid infinite loop\n localEmitter.originalEmit(message.name, message.data);\n return;\n }\n if (action === CORE_START) {\n localEmitter = new EventEmitter3();\n localEmitter.originalEmit = localEmitter.emit;\n localEmitter.emit = function (eventName, data) {\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_EVENT,\n name: eventName,\n data,\n });\n localEmitter.originalEmit(eventName, data);\n };\n \n Promise.resolve().then(() => {\n return start(localEmitter, message.data);\n }).then(instance => {\n localInstance = instance;\n }).catch(errorModuleStart => {\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_ERROR,\n time: Date.now(),\n phase: `module.start`,\n error: errorModuleStart,\n });\n }).then(() => {\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_STARTED,\n });\n });\n return;\n }\n if (action === CORE_STOP) {\n if (!localInstance) {\n // should never happen\n return;\n }\n Promise.resolve().then(() => {\n if (typeof stop === `function`) {\n return stop(wrapper.instance);\n }\n }).catch(errorModuleStop => {\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_ERROR,\n time: Date.now(),\n phase: `module.stop`,\n error: errorModuleStop,\n });\n }).then(() => {\n localInstance = undefined;\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_STOPPED,\n });\n });\n return;\n }\n\n if (action === CORE_SET_STATE) {\n Promise.resolve().then(() => {\n if (typeof restoreState === `function`) {\n return restoreState(localInstance, message.data);\n }\n }).then(() => {\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_GET_STATE,\n });\n }).catch(errorModuleRestoreState => {\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_ERROR,\n time: Date.now(),\n phase: `module.restoreState`,\n error: errorModuleRestoreState,\n });\n });\n return;\n }\n if (action === CORE_GET_STATE) {\n Promise.resolve().then(() => {\n if (typeof getState === `function`) {\n return getState(localInstance);\n }\n }).then((result) => {\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_SET_STATE,\n data: result, // core will handle undefined\n });\n }).catch(errorModuleRestoreState => {\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_ERROR,\n time: Date.now(),\n phase: `module.restoreState`,\n error: errorModuleRestoreState,\n });\n });\n return;\n }\n\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_ERROR,\n error: `action ${action} not implemented`,\n });\n});\n\n// module code below (defintion of start and stop)\n"; | ||
@@ -425,10 +425,17 @@ // @ts-check | ||
} | ||
if (worker) { | ||
return core.startWorker(module, name, data, workerReady); | ||
} | ||
if (!module.start) { | ||
return Promise.reject(`module must have start defined`); | ||
} | ||
const earlyWrapper = { | ||
module, | ||
name, | ||
}; | ||
core.moduleInstances.set(name, earlyWrapper); | ||
@@ -442,6 +449,4 @@ const emitter = new EventEmitter3(); | ||
}).then(instance => { | ||
core.moduleInstances.set(name, { | ||
module, | ||
Object.assign(earlyWrapper, { | ||
instance, | ||
name, | ||
emitter, | ||
@@ -452,2 +457,3 @@ }); | ||
}).catch(errorModuleStart => { | ||
core.moduleInstances.delete(name); | ||
core.emit(ERROR, { | ||
@@ -462,2 +468,9 @@ time: Date.now(), | ||
startWorker(moduleUrl, name, data, workerReady) { | ||
const earlyWrapper = { | ||
module: moduleUrl, | ||
name, | ||
}; | ||
core.moduleInstances.set(name, earlyWrapper); | ||
return new Promise(function (resolve, reject) { | ||
@@ -484,3 +497,3 @@ let workerRessourcePromise; | ||
core.listenForWorkerMessage(name, moduleInsideWorker, resolve); | ||
core.listenForWorkerMessage(name, moduleInsideWorker, resolve, earlyWrapper); | ||
moduleInsideWorker.postMessage({ | ||
@@ -491,2 +504,3 @@ [CORE_ACTION_KEY]: CORE_START, | ||
}).catch(errorModuleStart => { | ||
core.moduleInstances.delete(name); | ||
core.emit(ERROR, { | ||
@@ -503,3 +517,3 @@ time: Date.now(), | ||
listenForWorkerMessage(name, worker, resolve) { | ||
listenForWorkerMessage(name, worker, resolve, earlyWrapper) { | ||
worker.addEventListener(`message`, function (messageEvent) { | ||
@@ -512,3 +526,3 @@ const message = messageEvent.data; | ||
if (action === CORE_STARTED) { | ||
core.moduleInstances.set(name, { | ||
Object.assign(earlyWrapper, { | ||
worker, | ||
@@ -515,0 +529,0 @@ name, |
@@ -1,2 +0,2 @@ | ||
/* @eroc/core v4.3.0 2021-09-15T19:01:12.070Z licensed MIT */ | ||
/* @eroc/core v4.3.1 2021-09-25T17:34:47.706Z licensed MIT */ | ||
var Core = (function (exports) { | ||
@@ -317,3 +317,3 @@ 'use strict'; | ||
const workerGlueCode = "/**\n * Use it as a constructor\n * or as a decorator for an existing object\n * or as a base class for extend\n * cannot be used as a mixin for a constructor's prototype\n * without calling the constructor\n */\nfunction EventEmitter3(obj) {\n (obj || this)._callbacks = Object.create(null);\n if (obj) {return Object.assign(obj, EventEmitter3.prototype);}\n}\n\n/**\n * Listen on the given `eventName` with `fn`\n *\n * @param {String | Symbol} eventName\n * @param {Function} fn\n * @api public\n */\n\nEventEmitter3.prototype.on = function (eventName, fn) {\n (this._callbacks[eventName] = this._callbacks[eventName] || [])\n .push(fn);\n};\n\n/**\n * Adds an `eventName` listener that will be invoked once then removed\n *\n * @param {String | Symbol} eventName\n * @param {Function} fn\n * @api public\n */\n\nEventEmitter3.prototype.once = function (eventName, fn) {\n const once = (data) => {\n this.off(eventName, once);\n fn(data);\n };\n\n once.fn = fn; // makes it possible to remove with off\n this.on(eventName, once);\n};\n\n/**\n * Remove a callback for `eventName` or\n * all callbacks for `eventName` or\n * all callbacks for all events\n *\n * @param {String | Symbol} eventName\n * @param {Function} fn\n * @api public\n */\n\nEventEmitter3.prototype.off = function (eventName, fn) {\n // all\n if (!eventName) {\n this._callbacks = Object.create(null);\n return;\n }\n\n // specific event\n const callbacks = this._callbacks[eventName];\n if (!callbacks) {\n return;\n }\n\n // remove all handlers\n if (!fn) {\n delete this._callbacks[eventName];\n return;\n }\n\n // remove specific handler\n const index = callbacks.findIndex(function (cb) {\n return (cb === fn || cb.fn === fn);\n });\n if (index > -1) {\n // Remove event specific arrays for the eventName type that no\n // one is subscribed for, to avoid memory leak.\n if (callbacks.length === 1) {\n delete this._callbacks[eventName];\n } else {\n callbacks.splice(index, 1);\n }\n }\n};\n\n/**\n * Emit `eventName` with data\n *\n * @param {String | Symbol} eventName\n * @param {any} data\n */\n\nEventEmitter3.prototype.emit = function (eventName, data) {\n const callbacks = this._callbacks[eventName];\n if (!callbacks) {\n return;\n }\n const frozenCallbacks = Array.from(callbacks);\n frozenCallbacks.forEach(callback => {\n callback(data);\n });\n};\n\n/**\n * Return array of callbacks for `eventName`\n *\n * @param {String | Symbol} eventName\n * @return {Array} listeners\n * @api public\n */\n\nEventEmitter3.prototype.listeners = function (eventName) {\n return this._callbacks[eventName] || [];\n};\n\n/**\n * True if this emitter has `eventName` handlers\n *\n * @param {String | Symbol} eventName\n * @return {Boolean}\n * @api public\n */\n\nEventEmitter3.prototype.hasListeners = function (eventName) {\n return Boolean(this.listeners(eventName).length);\n};\n\n/**\n * Returns an array of event names for which the emitter has registered listeners\n *\n * @return {Array <String || Symbol>}\n * @api public\n */\nEventEmitter3.prototype.eventNames = function () {\n return Reflect.ownKeys(this._callbacks);\n};\n\n/**\n * Returns an array of event anmes of type string\n * for which the emitter has registered listeners\n *\n * @return {Array <String>}\n * @api public\n */\nEventEmitter3.prototype.eventNamesStrings = function () {\n return Object.keys(this._callbacks);\n};\n\n// prefix to avoid variable name collision\r\nconst CORE_ACTION_KEY = `action`;\r\n\r\n// actions\r\nconst CORE_EVENT = `CORE_EVENT`;\r\nconst CORE_START = `CORE_START`;\r\nconst CORE_STARTED = `CORE_STARTED`;\r\nconst CORE_STOP = `CORE_STOP`;\r\nconst CORE_STOPPED = `CORE_STOPPED`;\r\nconst CORE_GET_STATE = `CORE_GET_STATE`;\r\nconst CORE_SET_STATE = `CORE_SET_STATE`;\r\nconst CORE_ERROR = `CORE_ERROR`;\n\nlet localEmitter;\r\nlet localInstance;\r\n\r\nself.addEventListener(`error`, function (errorEvent) {\r\n errorEvent.preventDefault();\r\n let asString;\r\n if (errorEvent.message) {\r\n asString = errorEvent.message;\r\n } else {\r\n asString = String(errorEvent);\r\n }\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_ERROR,\r\n error: asString,\r\n });\r\n});\r\n\r\nself.addEventListener(`message`, async function(messageEvent) {\r\n const message = messageEvent.data;\r\n if (!Object.prototype.hasOwnProperty.call(message, CORE_ACTION_KEY)) {\r\n return;\r\n }\r\n const action = message[CORE_ACTION_KEY];\r\n if (action === CORE_EVENT) {\r\n if (!localInstance) {\r\n return;\r\n }\r\n // avoid infinite loop\r\n localEmitter.originalEmit(message.name, message.data);\r\n return;\r\n }\r\n if (action === CORE_START) {\r\n localEmitter = new EventEmitter3();\r\n localEmitter.originalEmit = localEmitter.emit;\r\n localEmitter.emit = function (eventName, data) {\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_EVENT,\r\n name: eventName,\r\n data,\r\n });\r\n localEmitter.originalEmit(eventName, data);\r\n };\r\n \r\n Promise.resolve().then(() => {\r\n return start(localEmitter, message.data);\r\n }).then(instance => {\r\n localInstance = instance;\r\n }).catch(errorModuleStart => {\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_ERROR,\r\n time: Date.now(),\r\n phase: `module.start`,\r\n error: errorModuleStart,\r\n });\r\n }).then(() => {\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_STARTED,\r\n });\r\n });\r\n return;\r\n }\r\n if (action === CORE_STOP) {\r\n if (!localInstance) {\r\n // should never happen\r\n return;\r\n }\r\n Promise.resolve().then(() => {\r\n if (typeof stop === `function`) {\r\n return stop(wrapper.instance);\r\n }\r\n }).catch(errorModuleStop => {\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_ERROR,\r\n time: Date.now(),\r\n phase: `module.stop`,\r\n error: errorModuleStop,\r\n });\r\n }).then(() => {\r\n localInstance = undefined;\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_STOPPED,\r\n });\r\n });\r\n return;\r\n }\r\n\r\n if (action === CORE_SET_STATE) {\r\n Promise.resolve().then(() => {\r\n if (typeof restoreState === `function`) {\r\n return restoreState(localInstance, message.data);\r\n }\r\n }).then(() => {\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_GET_STATE,\r\n });\r\n }).catch(errorModuleRestoreState => {\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_ERROR,\r\n time: Date.now(),\r\n phase: `module.restoreState`,\r\n error: errorModuleRestoreState,\r\n });\r\n });\r\n return;\r\n }\r\n if (action === CORE_GET_STATE) {\r\n Promise.resolve().then(() => {\r\n if (typeof getState === `function`) {\r\n return getState(localInstance);\r\n }\r\n }).then((result) => {\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_SET_STATE,\r\n data: result, // core will handle undefined\r\n });\r\n }).catch(errorModuleRestoreState => {\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_ERROR,\r\n time: Date.now(),\r\n phase: `module.restoreState`,\r\n error: errorModuleRestoreState,\r\n });\r\n });\r\n return;\r\n }\r\n\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_ERROR,\r\n error: `action ${action} not implemented`,\r\n });\r\n});\r\n\r\n// module code below (defintion of start and stop)\n"; | ||
const workerGlueCode = "/**\n * Use it as a constructor\n * or as a decorator for an existing object\n * or as a base class for extend\n * cannot be used as a mixin for a constructor's prototype\n * without calling the constructor\n */\nfunction EventEmitter3(obj) {\n (obj || this)._callbacks = Object.create(null);\n if (obj) {return Object.assign(obj, EventEmitter3.prototype);}\n}\n\n/**\n * Listen on the given `eventName` with `fn`\n *\n * @param {String | Symbol} eventName\n * @param {Function} fn\n * @api public\n */\n\nEventEmitter3.prototype.on = function (eventName, fn) {\n (this._callbacks[eventName] = this._callbacks[eventName] || [])\n .push(fn);\n};\n\n/**\n * Adds an `eventName` listener that will be invoked once then removed\n *\n * @param {String | Symbol} eventName\n * @param {Function} fn\n * @api public\n */\n\nEventEmitter3.prototype.once = function (eventName, fn) {\n const once = (data) => {\n this.off(eventName, once);\n fn(data);\n };\n\n once.fn = fn; // makes it possible to remove with off\n this.on(eventName, once);\n};\n\n/**\n * Remove a callback for `eventName` or\n * all callbacks for `eventName` or\n * all callbacks for all events\n *\n * @param {String | Symbol} eventName\n * @param {Function} fn\n * @api public\n */\n\nEventEmitter3.prototype.off = function (eventName, fn) {\n // all\n if (!eventName) {\n this._callbacks = Object.create(null);\n return;\n }\n\n // specific event\n const callbacks = this._callbacks[eventName];\n if (!callbacks) {\n return;\n }\n\n // remove all handlers\n if (!fn) {\n delete this._callbacks[eventName];\n return;\n }\n\n // remove specific handler\n const index = callbacks.findIndex(function (cb) {\n return (cb === fn || cb.fn === fn);\n });\n if (index > -1) {\n // Remove event specific arrays for the eventName type that no\n // one is subscribed for, to avoid memory leak.\n if (callbacks.length === 1) {\n delete this._callbacks[eventName];\n } else {\n callbacks.splice(index, 1);\n }\n }\n};\n\n/**\n * Emit `eventName` with data\n *\n * @param {String | Symbol} eventName\n * @param {any} data\n */\n\nEventEmitter3.prototype.emit = function (eventName, data) {\n const callbacks = this._callbacks[eventName];\n if (!callbacks) {\n return;\n }\n const frozenCallbacks = Array.from(callbacks);\n frozenCallbacks.forEach(callback => {\n callback(data);\n });\n};\n\n/**\n * Return array of callbacks for `eventName`\n *\n * @param {String | Symbol} eventName\n * @return {Array} listeners\n * @api public\n */\n\nEventEmitter3.prototype.listeners = function (eventName) {\n return this._callbacks[eventName] || [];\n};\n\n/**\n * True if this emitter has `eventName` handlers\n *\n * @param {String | Symbol} eventName\n * @return {Boolean}\n * @api public\n */\n\nEventEmitter3.prototype.hasListeners = function (eventName) {\n return Boolean(this.listeners(eventName).length);\n};\n\n/**\n * Returns an array of event names for which the emitter has registered listeners\n *\n * @return {Array <String || Symbol>}\n * @api public\n */\nEventEmitter3.prototype.eventNames = function () {\n return Reflect.ownKeys(this._callbacks);\n};\n\n/**\n * Returns an array of event anmes of type string\n * for which the emitter has registered listeners\n *\n * @return {Array <String>}\n * @api public\n */\nEventEmitter3.prototype.eventNamesStrings = function () {\n return Object.keys(this._callbacks);\n};\n\n// prefix to avoid variable name collision\nconst CORE_ACTION_KEY = `action`;\n\n// actions\nconst CORE_EVENT = `CORE_EVENT`;\nconst CORE_START = `CORE_START`;\nconst CORE_STARTED = `CORE_STARTED`;\nconst CORE_STOP = `CORE_STOP`;\nconst CORE_STOPPED = `CORE_STOPPED`;\nconst CORE_GET_STATE = `CORE_GET_STATE`;\nconst CORE_SET_STATE = `CORE_SET_STATE`;\nconst CORE_ERROR = `CORE_ERROR`;\n\nlet localEmitter;\nlet localInstance;\n\nself.addEventListener(`error`, function (errorEvent) {\n errorEvent.preventDefault();\n let asString;\n if (errorEvent.message) {\n asString = errorEvent.message;\n } else {\n asString = String(errorEvent);\n }\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_ERROR,\n error: asString,\n });\n});\n\nself.addEventListener(`message`, async function(messageEvent) {\n const message = messageEvent.data;\n if (!Object.prototype.hasOwnProperty.call(message, CORE_ACTION_KEY)) {\n return;\n }\n const action = message[CORE_ACTION_KEY];\n if (action === CORE_EVENT) {\n if (!localInstance) {\n return;\n }\n // avoid infinite loop\n localEmitter.originalEmit(message.name, message.data);\n return;\n }\n if (action === CORE_START) {\n localEmitter = new EventEmitter3();\n localEmitter.originalEmit = localEmitter.emit;\n localEmitter.emit = function (eventName, data) {\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_EVENT,\n name: eventName,\n data,\n });\n localEmitter.originalEmit(eventName, data);\n };\n \n Promise.resolve().then(() => {\n return start(localEmitter, message.data);\n }).then(instance => {\n localInstance = instance;\n }).catch(errorModuleStart => {\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_ERROR,\n time: Date.now(),\n phase: `module.start`,\n error: errorModuleStart,\n });\n }).then(() => {\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_STARTED,\n });\n });\n return;\n }\n if (action === CORE_STOP) {\n if (!localInstance) {\n // should never happen\n return;\n }\n Promise.resolve().then(() => {\n if (typeof stop === `function`) {\n return stop(wrapper.instance);\n }\n }).catch(errorModuleStop => {\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_ERROR,\n time: Date.now(),\n phase: `module.stop`,\n error: errorModuleStop,\n });\n }).then(() => {\n localInstance = undefined;\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_STOPPED,\n });\n });\n return;\n }\n\n if (action === CORE_SET_STATE) {\n Promise.resolve().then(() => {\n if (typeof restoreState === `function`) {\n return restoreState(localInstance, message.data);\n }\n }).then(() => {\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_GET_STATE,\n });\n }).catch(errorModuleRestoreState => {\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_ERROR,\n time: Date.now(),\n phase: `module.restoreState`,\n error: errorModuleRestoreState,\n });\n });\n return;\n }\n if (action === CORE_GET_STATE) {\n Promise.resolve().then(() => {\n if (typeof getState === `function`) {\n return getState(localInstance);\n }\n }).then((result) => {\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_SET_STATE,\n data: result, // core will handle undefined\n });\n }).catch(errorModuleRestoreState => {\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_ERROR,\n time: Date.now(),\n phase: `module.restoreState`,\n error: errorModuleRestoreState,\n });\n });\n return;\n }\n\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_ERROR,\n error: `action ${action} not implemented`,\n });\n});\n\n// module code below (defintion of start and stop)\n"; | ||
@@ -428,10 +428,17 @@ // @ts-check | ||
} | ||
if (worker) { | ||
return core.startWorker(module, name, data, workerReady); | ||
} | ||
if (!module.start) { | ||
return Promise.reject(`module must have start defined`); | ||
} | ||
const earlyWrapper = { | ||
module, | ||
name, | ||
}; | ||
core.moduleInstances.set(name, earlyWrapper); | ||
@@ -445,6 +452,4 @@ const emitter = new EventEmitter3(); | ||
}).then(instance => { | ||
core.moduleInstances.set(name, { | ||
module, | ||
Object.assign(earlyWrapper, { | ||
instance, | ||
name, | ||
emitter, | ||
@@ -455,2 +460,3 @@ }); | ||
}).catch(errorModuleStart => { | ||
core.moduleInstances.delete(name); | ||
core.emit(ERROR, { | ||
@@ -465,2 +471,9 @@ time: Date.now(), | ||
startWorker(moduleUrl, name, data, workerReady) { | ||
const earlyWrapper = { | ||
module: moduleUrl, | ||
name, | ||
}; | ||
core.moduleInstances.set(name, earlyWrapper); | ||
return new Promise(function (resolve, reject) { | ||
@@ -487,3 +500,3 @@ let workerRessourcePromise; | ||
core.listenForWorkerMessage(name, moduleInsideWorker, resolve); | ||
core.listenForWorkerMessage(name, moduleInsideWorker, resolve, earlyWrapper); | ||
moduleInsideWorker.postMessage({ | ||
@@ -494,2 +507,3 @@ [CORE_ACTION_KEY]: CORE_START, | ||
}).catch(errorModuleStart => { | ||
core.moduleInstances.delete(name); | ||
core.emit(ERROR, { | ||
@@ -506,3 +520,3 @@ time: Date.now(), | ||
listenForWorkerMessage(name, worker, resolve) { | ||
listenForWorkerMessage(name, worker, resolve, earlyWrapper) { | ||
worker.addEventListener(`message`, function (messageEvent) { | ||
@@ -515,3 +529,3 @@ const message = messageEvent.data; | ||
if (action === CORE_STARTED) { | ||
core.moduleInstances.set(name, { | ||
Object.assign(earlyWrapper, { | ||
worker, | ||
@@ -518,0 +532,0 @@ name, |
@@ -0,0 +0,0 @@ /** |
export {workerGlueCode}; | ||
const workerGlueCode = "/**\n * Use it as a constructor\n * or as a decorator for an existing object\n * or as a base class for extend\n * cannot be used as a mixin for a constructor's prototype\n * without calling the constructor\n */\nfunction EventEmitter3(obj) {\n (obj || this)._callbacks = Object.create(null);\n if (obj) {return Object.assign(obj, EventEmitter3.prototype);}\n}\n\n/**\n * Listen on the given `eventName` with `fn`\n *\n * @param {String | Symbol} eventName\n * @param {Function} fn\n * @api public\n */\n\nEventEmitter3.prototype.on = function (eventName, fn) {\n (this._callbacks[eventName] = this._callbacks[eventName] || [])\n .push(fn);\n};\n\n/**\n * Adds an `eventName` listener that will be invoked once then removed\n *\n * @param {String | Symbol} eventName\n * @param {Function} fn\n * @api public\n */\n\nEventEmitter3.prototype.once = function (eventName, fn) {\n const once = (data) => {\n this.off(eventName, once);\n fn(data);\n };\n\n once.fn = fn; // makes it possible to remove with off\n this.on(eventName, once);\n};\n\n/**\n * Remove a callback for `eventName` or\n * all callbacks for `eventName` or\n * all callbacks for all events\n *\n * @param {String | Symbol} eventName\n * @param {Function} fn\n * @api public\n */\n\nEventEmitter3.prototype.off = function (eventName, fn) {\n // all\n if (!eventName) {\n this._callbacks = Object.create(null);\n return;\n }\n\n // specific event\n const callbacks = this._callbacks[eventName];\n if (!callbacks) {\n return;\n }\n\n // remove all handlers\n if (!fn) {\n delete this._callbacks[eventName];\n return;\n }\n\n // remove specific handler\n const index = callbacks.findIndex(function (cb) {\n return (cb === fn || cb.fn === fn);\n });\n if (index > -1) {\n // Remove event specific arrays for the eventName type that no\n // one is subscribed for, to avoid memory leak.\n if (callbacks.length === 1) {\n delete this._callbacks[eventName];\n } else {\n callbacks.splice(index, 1);\n }\n }\n};\n\n/**\n * Emit `eventName` with data\n *\n * @param {String | Symbol} eventName\n * @param {any} data\n */\n\nEventEmitter3.prototype.emit = function (eventName, data) {\n const callbacks = this._callbacks[eventName];\n if (!callbacks) {\n return;\n }\n const frozenCallbacks = Array.from(callbacks);\n frozenCallbacks.forEach(callback => {\n callback(data);\n });\n};\n\n/**\n * Return array of callbacks for `eventName`\n *\n * @param {String | Symbol} eventName\n * @return {Array} listeners\n * @api public\n */\n\nEventEmitter3.prototype.listeners = function (eventName) {\n return this._callbacks[eventName] || [];\n};\n\n/**\n * True if this emitter has `eventName` handlers\n *\n * @param {String | Symbol} eventName\n * @return {Boolean}\n * @api public\n */\n\nEventEmitter3.prototype.hasListeners = function (eventName) {\n return Boolean(this.listeners(eventName).length);\n};\n\n/**\n * Returns an array of event names for which the emitter has registered listeners\n *\n * @return {Array <String || Symbol>}\n * @api public\n */\nEventEmitter3.prototype.eventNames = function () {\n return Reflect.ownKeys(this._callbacks);\n};\n\n/**\n * Returns an array of event anmes of type string\n * for which the emitter has registered listeners\n *\n * @return {Array <String>}\n * @api public\n */\nEventEmitter3.prototype.eventNamesStrings = function () {\n return Object.keys(this._callbacks);\n};\n\n// prefix to avoid variable name collision\r\nconst CORE_ACTION_KEY = `action`;\r\n\r\n// actions\r\nconst CORE_EVENT = `CORE_EVENT`;\r\nconst CORE_START = `CORE_START`;\r\nconst CORE_STARTED = `CORE_STARTED`;\r\nconst CORE_STOP = `CORE_STOP`;\r\nconst CORE_STOPPED = `CORE_STOPPED`;\r\nconst CORE_GET_STATE = `CORE_GET_STATE`;\r\nconst CORE_SET_STATE = `CORE_SET_STATE`;\r\nconst CORE_ERROR = `CORE_ERROR`;\n\nlet localEmitter;\r\nlet localInstance;\r\n\r\nself.addEventListener(`error`, function (errorEvent) {\r\n errorEvent.preventDefault();\r\n let asString;\r\n if (errorEvent.message) {\r\n asString = errorEvent.message;\r\n } else {\r\n asString = String(errorEvent);\r\n }\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_ERROR,\r\n error: asString,\r\n });\r\n});\r\n\r\nself.addEventListener(`message`, async function(messageEvent) {\r\n const message = messageEvent.data;\r\n if (!Object.prototype.hasOwnProperty.call(message, CORE_ACTION_KEY)) {\r\n return;\r\n }\r\n const action = message[CORE_ACTION_KEY];\r\n if (action === CORE_EVENT) {\r\n if (!localInstance) {\r\n return;\r\n }\r\n // avoid infinite loop\r\n localEmitter.originalEmit(message.name, message.data);\r\n return;\r\n }\r\n if (action === CORE_START) {\r\n localEmitter = new EventEmitter3();\r\n localEmitter.originalEmit = localEmitter.emit;\r\n localEmitter.emit = function (eventName, data) {\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_EVENT,\r\n name: eventName,\r\n data,\r\n });\r\n localEmitter.originalEmit(eventName, data);\r\n };\r\n \r\n Promise.resolve().then(() => {\r\n return start(localEmitter, message.data);\r\n }).then(instance => {\r\n localInstance = instance;\r\n }).catch(errorModuleStart => {\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_ERROR,\r\n time: Date.now(),\r\n phase: `module.start`,\r\n error: errorModuleStart,\r\n });\r\n }).then(() => {\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_STARTED,\r\n });\r\n });\r\n return;\r\n }\r\n if (action === CORE_STOP) {\r\n if (!localInstance) {\r\n // should never happen\r\n return;\r\n }\r\n Promise.resolve().then(() => {\r\n if (typeof stop === `function`) {\r\n return stop(wrapper.instance);\r\n }\r\n }).catch(errorModuleStop => {\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_ERROR,\r\n time: Date.now(),\r\n phase: `module.stop`,\r\n error: errorModuleStop,\r\n });\r\n }).then(() => {\r\n localInstance = undefined;\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_STOPPED,\r\n });\r\n });\r\n return;\r\n }\r\n\r\n if (action === CORE_SET_STATE) {\r\n Promise.resolve().then(() => {\r\n if (typeof restoreState === `function`) {\r\n return restoreState(localInstance, message.data);\r\n }\r\n }).then(() => {\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_GET_STATE,\r\n });\r\n }).catch(errorModuleRestoreState => {\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_ERROR,\r\n time: Date.now(),\r\n phase: `module.restoreState`,\r\n error: errorModuleRestoreState,\r\n });\r\n });\r\n return;\r\n }\r\n if (action === CORE_GET_STATE) {\r\n Promise.resolve().then(() => {\r\n if (typeof getState === `function`) {\r\n return getState(localInstance);\r\n }\r\n }).then((result) => {\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_SET_STATE,\r\n data: result, // core will handle undefined\r\n });\r\n }).catch(errorModuleRestoreState => {\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_ERROR,\r\n time: Date.now(),\r\n phase: `module.restoreState`,\r\n error: errorModuleRestoreState,\r\n });\r\n });\r\n return;\r\n }\r\n\r\n self.postMessage({\r\n [CORE_ACTION_KEY]: CORE_ERROR,\r\n error: `action ${action} not implemented`,\r\n });\r\n});\r\n\r\n// module code below (defintion of start and stop)\n" | ||
const workerGlueCode = "/**\n * Use it as a constructor\n * or as a decorator for an existing object\n * or as a base class for extend\n * cannot be used as a mixin for a constructor's prototype\n * without calling the constructor\n */\nfunction EventEmitter3(obj) {\n (obj || this)._callbacks = Object.create(null);\n if (obj) {return Object.assign(obj, EventEmitter3.prototype);}\n}\n\n/**\n * Listen on the given `eventName` with `fn`\n *\n * @param {String | Symbol} eventName\n * @param {Function} fn\n * @api public\n */\n\nEventEmitter3.prototype.on = function (eventName, fn) {\n (this._callbacks[eventName] = this._callbacks[eventName] || [])\n .push(fn);\n};\n\n/**\n * Adds an `eventName` listener that will be invoked once then removed\n *\n * @param {String | Symbol} eventName\n * @param {Function} fn\n * @api public\n */\n\nEventEmitter3.prototype.once = function (eventName, fn) {\n const once = (data) => {\n this.off(eventName, once);\n fn(data);\n };\n\n once.fn = fn; // makes it possible to remove with off\n this.on(eventName, once);\n};\n\n/**\n * Remove a callback for `eventName` or\n * all callbacks for `eventName` or\n * all callbacks for all events\n *\n * @param {String | Symbol} eventName\n * @param {Function} fn\n * @api public\n */\n\nEventEmitter3.prototype.off = function (eventName, fn) {\n // all\n if (!eventName) {\n this._callbacks = Object.create(null);\n return;\n }\n\n // specific event\n const callbacks = this._callbacks[eventName];\n if (!callbacks) {\n return;\n }\n\n // remove all handlers\n if (!fn) {\n delete this._callbacks[eventName];\n return;\n }\n\n // remove specific handler\n const index = callbacks.findIndex(function (cb) {\n return (cb === fn || cb.fn === fn);\n });\n if (index > -1) {\n // Remove event specific arrays for the eventName type that no\n // one is subscribed for, to avoid memory leak.\n if (callbacks.length === 1) {\n delete this._callbacks[eventName];\n } else {\n callbacks.splice(index, 1);\n }\n }\n};\n\n/**\n * Emit `eventName` with data\n *\n * @param {String | Symbol} eventName\n * @param {any} data\n */\n\nEventEmitter3.prototype.emit = function (eventName, data) {\n const callbacks = this._callbacks[eventName];\n if (!callbacks) {\n return;\n }\n const frozenCallbacks = Array.from(callbacks);\n frozenCallbacks.forEach(callback => {\n callback(data);\n });\n};\n\n/**\n * Return array of callbacks for `eventName`\n *\n * @param {String | Symbol} eventName\n * @return {Array} listeners\n * @api public\n */\n\nEventEmitter3.prototype.listeners = function (eventName) {\n return this._callbacks[eventName] || [];\n};\n\n/**\n * True if this emitter has `eventName` handlers\n *\n * @param {String | Symbol} eventName\n * @return {Boolean}\n * @api public\n */\n\nEventEmitter3.prototype.hasListeners = function (eventName) {\n return Boolean(this.listeners(eventName).length);\n};\n\n/**\n * Returns an array of event names for which the emitter has registered listeners\n *\n * @return {Array <String || Symbol>}\n * @api public\n */\nEventEmitter3.prototype.eventNames = function () {\n return Reflect.ownKeys(this._callbacks);\n};\n\n/**\n * Returns an array of event anmes of type string\n * for which the emitter has registered listeners\n *\n * @return {Array <String>}\n * @api public\n */\nEventEmitter3.prototype.eventNamesStrings = function () {\n return Object.keys(this._callbacks);\n};\n\n// prefix to avoid variable name collision\nconst CORE_ACTION_KEY = `action`;\n\n// actions\nconst CORE_EVENT = `CORE_EVENT`;\nconst CORE_START = `CORE_START`;\nconst CORE_STARTED = `CORE_STARTED`;\nconst CORE_STOP = `CORE_STOP`;\nconst CORE_STOPPED = `CORE_STOPPED`;\nconst CORE_GET_STATE = `CORE_GET_STATE`;\nconst CORE_SET_STATE = `CORE_SET_STATE`;\nconst CORE_ERROR = `CORE_ERROR`;\n\nlet localEmitter;\nlet localInstance;\n\nself.addEventListener(`error`, function (errorEvent) {\n errorEvent.preventDefault();\n let asString;\n if (errorEvent.message) {\n asString = errorEvent.message;\n } else {\n asString = String(errorEvent);\n }\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_ERROR,\n error: asString,\n });\n});\n\nself.addEventListener(`message`, async function(messageEvent) {\n const message = messageEvent.data;\n if (!Object.prototype.hasOwnProperty.call(message, CORE_ACTION_KEY)) {\n return;\n }\n const action = message[CORE_ACTION_KEY];\n if (action === CORE_EVENT) {\n if (!localInstance) {\n return;\n }\n // avoid infinite loop\n localEmitter.originalEmit(message.name, message.data);\n return;\n }\n if (action === CORE_START) {\n localEmitter = new EventEmitter3();\n localEmitter.originalEmit = localEmitter.emit;\n localEmitter.emit = function (eventName, data) {\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_EVENT,\n name: eventName,\n data,\n });\n localEmitter.originalEmit(eventName, data);\n };\n \n Promise.resolve().then(() => {\n return start(localEmitter, message.data);\n }).then(instance => {\n localInstance = instance;\n }).catch(errorModuleStart => {\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_ERROR,\n time: Date.now(),\n phase: `module.start`,\n error: errorModuleStart,\n });\n }).then(() => {\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_STARTED,\n });\n });\n return;\n }\n if (action === CORE_STOP) {\n if (!localInstance) {\n // should never happen\n return;\n }\n Promise.resolve().then(() => {\n if (typeof stop === `function`) {\n return stop(wrapper.instance);\n }\n }).catch(errorModuleStop => {\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_ERROR,\n time: Date.now(),\n phase: `module.stop`,\n error: errorModuleStop,\n });\n }).then(() => {\n localInstance = undefined;\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_STOPPED,\n });\n });\n return;\n }\n\n if (action === CORE_SET_STATE) {\n Promise.resolve().then(() => {\n if (typeof restoreState === `function`) {\n return restoreState(localInstance, message.data);\n }\n }).then(() => {\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_GET_STATE,\n });\n }).catch(errorModuleRestoreState => {\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_ERROR,\n time: Date.now(),\n phase: `module.restoreState`,\n error: errorModuleRestoreState,\n });\n });\n return;\n }\n if (action === CORE_GET_STATE) {\n Promise.resolve().then(() => {\n if (typeof getState === `function`) {\n return getState(localInstance);\n }\n }).then((result) => {\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_SET_STATE,\n data: result, // core will handle undefined\n });\n }).catch(errorModuleRestoreState => {\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_ERROR,\n time: Date.now(),\n phase: `module.restoreState`,\n error: errorModuleRestoreState,\n });\n });\n return;\n }\n\n self.postMessage({\n [CORE_ACTION_KEY]: CORE_ERROR,\n error: `action ${action} not implemented`,\n });\n});\n\n// module code below (defintion of start and stop)\n" |
{ | ||
"name": "@eroc/core", | ||
"version": "4.3.0", | ||
"version": "4.3.1", | ||
"description": "Lightweight framework for scalable applications", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
@@ -0,0 +0,0 @@ # core [![Build Status](https://travis-ci.org/mauriciosoares/core.js.svg?branch=master)](https://travis-ci.org/mauriciosoares/core.js) [![Coverage Status](https://img.shields.io/coveralls/mauriciosoares/core.js.svg)](https://coveralls.io/r/mauriciosoares/core.js) [![Code Climate](https://codeclimate.com/github/mauriciosoares/core.js/badges/gpa.svg)](https://codeclimate.com/github/mauriciosoares/core.js) |
@@ -129,10 +129,17 @@ // @ts-check | ||
} | ||
if (worker) { | ||
return core.startWorker(module, name, data, workerReady); | ||
} | ||
if (!module.start) { | ||
return Promise.reject(`module must have start defined`); | ||
} | ||
const earlyWrapper = { | ||
module, | ||
name, | ||
}; | ||
core.moduleInstances.set(name, earlyWrapper); | ||
@@ -146,6 +153,4 @@ const emitter = new EventEmitter(); | ||
}).then(instance => { | ||
core.moduleInstances.set(name, { | ||
module, | ||
Object.assign(earlyWrapper, { | ||
instance, | ||
name, | ||
emitter, | ||
@@ -156,2 +161,3 @@ }); | ||
}).catch(errorModuleStart => { | ||
core.moduleInstances.delete(name); | ||
core.emit(ERROR, { | ||
@@ -166,2 +172,9 @@ time: Date.now(), | ||
startWorker(moduleUrl, name, data, workerReady) { | ||
const earlyWrapper = { | ||
module: moduleUrl, | ||
name, | ||
}; | ||
core.moduleInstances.set(name, earlyWrapper); | ||
return new Promise(function (resolve, reject) { | ||
@@ -188,3 +201,3 @@ let workerRessourcePromise; | ||
core.listenForWorkerMessage(name, moduleInsideWorker, resolve); | ||
core.listenForWorkerMessage(name, moduleInsideWorker, resolve, earlyWrapper); | ||
moduleInsideWorker.postMessage({ | ||
@@ -195,2 +208,3 @@ [CORE_ACTION_KEY]: CORE_START, | ||
}).catch(errorModuleStart => { | ||
core.moduleInstances.delete(name); | ||
core.emit(ERROR, { | ||
@@ -207,3 +221,3 @@ time: Date.now(), | ||
listenForWorkerMessage(name, worker, resolve) { | ||
listenForWorkerMessage(name, worker, resolve, earlyWrapper) { | ||
worker.addEventListener(`message`, function (messageEvent) { | ||
@@ -216,3 +230,3 @@ const message = messageEvent.data; | ||
if (action === CORE_STARTED) { | ||
core.moduleInstances.set(name, { | ||
Object.assign(earlyWrapper, { | ||
worker, | ||
@@ -219,0 +233,0 @@ name, |
@@ -0,0 +0,0 @@ export { replayEvents }; |
@@ -0,0 +0,0 @@ export { useDefaultLogging }; |
@@ -0,0 +0,0 @@ "use strict"; |
@@ -0,0 +0,0 @@ export { |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
136460
16
2614