All files / src/workers process.js

0% Statements 0/43
0% Branches 0/1
0% Functions 0/1
0% Lines 0/43

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44                                                                                       
// import { Changes } from './changes.js';
const processes = {};

export const Process = {
  spawn(modules, fun, args) {
    const moduleCodes = modules.map((t) => {
      const m = t.toString();
      const prefix = 'const export';
      return {
        name: m.slice(m.indexOf(prefix) + prefix.length, m.indexOf('= {')).trim(),
        module: `'use strict';(function() { return ${m.replace('export const', 'const')}; })()`,
      };
    });
    const processKey = [].concat(modules).map((t) => t.name).join('|');
    const code = `(${fun})`;
    const updatedArgs = { ...args };
    const argKeys = Object.keys(args);
    const replacements = {};
    for (const i of argKeys) {
      if (typeof updatedArgs[i] !== 'function') { continue; }
      let funCode = `${updatedArgs[i]}`;
      if (!funCode.startsWith('function') && !funCode.startsWith('() =>')) {
        funCode = `function ${funCode}`;
      }
      replacements[i] = `(${funCode})`;
      updatedArgs[i] = null;
    }
    const oldp = processes[processKey];
    const worker = !oldp || oldp.running ? new Worker('./worker.js') : oldp.worker;
    const p = new Promise((res) => {
      processes[processKey] = { running: true, worker };
      worker.postMessage({ modules: moduleCodes, fun: code, args: updatedArgs, replacements });
      worker.onmessage = (e) => {
        for (const i of Object.keys(replacements)) {
          e.data[i] = args[i];
        }
        res(e.data);
        processes[processKey] = { running: false, worker };
      };
    });
    return p;
  },
};