UNPKG

fractal-core

Version:

A minimalist and well crafted app, content or component is our conviction

238 lines 9.83 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const core_1 = require("../core"); function makeSyncQueue() { let queue = []; return { queue, addWaiter(waiter) { queue.push(waiter); }, next(data) { if (queue[0] && queue[0](data)) { queue.shift(); } }, }; } exports.makeSyncQueue = makeSyncQueue; exports.workerHandler = (type, name, syncQueue, workerAPI) => (mod) => { let _self = workerAPI ? workerAPI : self; let waiter; return { state: undefined, handle: (id, value) => __awaiter(this, void 0, void 0, function* () { if (type === 'group') { waiter = new Promise((resolve) => { syncQueue.addWaiter(data => { if (data[0] === 'setGroup') { resolve(); return true; } }); }); } _self.postMessage([type, name, 'handle', id, value]); return waiter; }), destroy: () => { _self.postMessage([type, name, 'destroy']); }, }; }; exports.workerLog = (type, workerAPI) => { let _self = workerAPI ? workerAPI : self; return (source, description) => { _self.postMessage(['log', type, source, description]); }; }; // receives messages from runWorker in the WorkerSide exports.createWorkerListener = (syncQueue, workerAPI) => (mod) => { let _self = workerAPI ? workerAPI : self; // allows to dispatch inputs from the main thread _self.onmessage = ev => { let data = ev.data; switch (data[0]) { case 'dispatchEv': mod.dispatchEv(data[1], data[2]); break; case 'dispatch': mod.dispatch(data[1]); break; case 'toComp': mod.toComp(data[1], data[2], data[3]); break; case 'setGroup': mod.setGroup(data[1], data[2], data[3]); break; case 'task': mod.task(data[1], data[2]); break; case 'destroy': mod.destroy(); _self.postMessage(['destroy']); break; case 'nest': // not implemented yet, should deserialize a component with a safe eval mod.error('workerListener', `unimplemented method`); break; case 'nestAll': // not implemented yet, should deserialize a list of components with a safe eval mod.error('workerListener', `unimplemented method`); break; case 'unnest': // not implemented yet, should deserialize a component with a safe eval mod.error('workerListener', `unimplemented method`); break; case 'unnestAll': // not implemented yet, should deserialize a list of components with a safe eval mod.error('workerListener', `unimplemented method`); break; default: mod.error('workerListener', `unknown message type recived from worker: ${data.join(', ')}`); } syncQueue.next(data); }; }; function runWorker(def) { return __awaiter(this, void 0, void 0, function* () { let worker = def.worker; let groupObjects = {}; let taskObjects = {}; let interfaceObjects = {}; let attach = (comp) => __awaiter(this, void 0, void 0, function* () { def.error('reattach', 'unimplemented method'); }); // const eventHandlerRegister = {} // API for modules (Main Thread) let moduleAPI = { on: (eventName, eventData, pullable) => ['ev', 12], off: descriptor => worker.postMessage(['off', descriptor]), emit: (eventName, data) => new Promise(() => { }), // dispatch function type used for handlers dispatchEv: (event, iData) => __awaiter(this, void 0, void 0, function* () { return worker.postMessage(['dispatchEv', event, iData]); }), dispatch: (eventData) => __awaiter(this, void 0, void 0, function* () { return worker.postMessage(['dispatch', eventData]); }), toComp: (id, inputName, data) => __awaiter(this, void 0, void 0, function* () { return worker.postMessage(['toComp', id, inputName, data]); }), destroy, attach, // delegated methods setGroup: (id, name, group) => worker.postMessage(['setGroup', id, name, group]), task: (name, data) => __awaiter(this, void 0, void 0, function* () { return worker.postMessage(['task', name, data]); }), warn: def.warn, error: def.error, }; if (def.groups) { for (let i = 0, names = Object.keys(def.groups), len = names.length; i < len; i++) { groupObjects[names[i]] = yield (yield def.groups[names[i]])(moduleAPI); } } if (def.tasks) { for (let i = 0, names = Object.keys(def.tasks), len = names.length; i < len; i++) { taskObjects[names[i]] = yield (yield def.tasks[names[i]])(moduleAPI); } } if (def.interfaces) { for (let i = 0, names = Object.keys(def.interfaces), len = names.length; i < len; i++) { interfaceObjects[names[i]] = yield (yield def.interfaces[names[i]])(moduleAPI); } } let initTrap; worker.onmessage = (ev) => __awaiter(this, void 0, void 0, function* () { let data = ev.data; switch (data[0]) { case 'initialized': initTrap(); break; case 'interface': if (data[2] === 'handle') { yield interfaceObjects[data[1]].handle('Root', data[4]); break; } else if (data[2] === 'destroy') { interfaceObjects[data[1]].destroy(); break; } case 'task': if (data[2] === 'handle') { yield taskObjects[data[1]].handle(data[3], data[4]); break; } else if (data[2] === 'destroy') { yield taskObjects[data[1]].destroy(); break; } case 'group': if (data[2] === 'handle') { yield groupObjects[data[1]].handle(data[3], data[4]); break; } else if (data[2] === 'destroy') { groupObjects[data[1]].destroy(); break; } case 'log': if (moduleAPI[data[1]]) { moduleAPI[data[1]](data[2], data[3]); break; } case 'destroy': if (def.onDestroy) { def.onDestroy(moduleAPI); } break; default: moduleAPI.error('runWorker', `unknown message type recived from worker: ${data.join(', ')}`); } }); yield new Promise(resolve => { initTrap = resolve; }); function destroy() { worker.postMessage(['destroy']); } return { worker, moduleAPI, groupObjects, taskObjects, interfaceObjects, }; }); } exports.runWorker = runWorker; exports.runInWorker = (moduleDef, exceptions, workerAPI) => __awaiter(this, void 0, void 0, function* () { let _self = workerAPI ? workerAPI : self; const syncQueue = makeSyncQueue(); const workerModule = core_1.clone(moduleDef); const workerListener = exports.createWorkerListener(syncQueue, workerAPI); // Inject into onBeforeInit hook workerModule.onBeforeInit = moduleDef.onBeforeInit ? mod => { workerListener(mod); workerModule.onBeforeInit(mod); } : workerListener; // Make a proxy for handler inside the worker for comunicating to the main thread let handlerType, handlerName, handlerTypePlural; for (handlerType of core_1.handlerTypes) { handlerTypePlural = handlerType + 's'; for (handlerName in moduleDef[handlerTypePlural]) { if (exceptions && exceptions[handlerTypePlural].indexOf(handlerName) === -1 || !exceptions) { workerModule[handlerTypePlural][handlerName] = exports.workerHandler(handlerType, handlerName, syncQueue, workerAPI); } } } const mod = yield core_1.run(workerModule); _self.postMessage(['initialized']); return mod; }); //# sourceMappingURL=worker.js.map