kieler / elkjs

ELK's layout algorithms for JavaScript

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

_Worker is not a constructor when importing another worker with Vite and Yarn3 and PNP

jbaccarelli-equinix opened this issue · comments

HI, im clueless of what's going on here and i've tried all i could think of ...

I'm trying to offload a few operations to a web worker before even calling Elk to do anything, but if i dare import a worker it seems that elk stops knowing how to import it's own?

i have a function like this, where i use Vite default worker import mechanism to import my worker:

onst getMaximoElements = async ({
  data,
  hiddenNodes,
}: Props): Promise<{
  nodes: Node[]
  edges: Edge[]
}> => {
  let nodes: Node] = []
  let edges: Edge[] = []

  const worker = new Worker(new URL('./worker.ts', import.meta.url), {
    type: 'module',
  })

  if (data) {

    await new Promise<void>((resolve) => {
      worker.postMessage({ data, hiddenNodes })
      worker.onmessage = ({
        data: { nodes: workerNodes, edges: workerEdges },
      }) => {
        nodes = workerNodes
        edges = workerEdges
        resolve()
      }
    })

  }

  return {
    nodes,
    edges,
  }
}

Later i do as usual with Elk:

const elk = new ELK({
  defaultLayoutOptions: {
    'elk.algorithm': 'layered',
    'elk.layered.nodePlacement.strategy': 'SIMPLE',
    'elk.direction': 'DOWN',
    'elk.layered.spacing.nodeNodeBetweenLayers': '100',
  },
})

And if i try to do both things i get this error at const elk = new ELK({ "Uncaught TypeError: _Worker is not a constructor"

If i remove the first worker import it works again.

I tried adding

elkjs@*:
    dependencies:
      web-worker: "*"

To .yarnrc but it doesn't help, any ideas of what else i can try?

Sadly, I have currently no idea. In this ticket, elkjs is initialized with a web-worker. Does this work for you?

Sadly, I have currently no idea. In this ticket, elkjs is initialized with a web-worker. Does this work for you?

It does make it work but i had to copy the whole worker minified to my project which takes up like 2mb 😅

Finally noticed that one of the answers in the other ticket was the solution, and didn't require me to copy the worker file :)

creating the elk layout like this is enough:

import ELK from 'elkjs/lib/elk-api' // It's important and necessary to import the library like this


const elk = new ELK({
  defaultLayoutOptions: {
    'elk.algorithm': 'layered',
    'elk.layered.nodePlacement.strategy': 'SIMPLE',
    'elk.direction': 'DOWN',
    'elk.layered.spacing.nodeNodeBetweenLayers': '100',
  },
  workerFactory: () =>
    new Worker(new URL('elkjs/lib/elk-worker.min.js', import.meta.url)),
})