How do I write a Depth First Search on the BPM Moddle Data?

I’m working on an interface in TypeScript that allows users to select a task that was previously defined anywhere in the Modeler. To do this created a simple recursive loop that searches for any task that was previously defined from current task. It looks like this this.

export function findPreviousTasks(accumulator: ModdleElement[], currentTask: ModdleElement): ModdleElement[] {
  const start = currentTask.incoming[0].sourceRef;

  if (start.$type === ElementType.StartEvent) {
    return accumulator;
  }

  if (start.$type === ElementType.UserTask) {
    accumulator.push(start);
  }

  return findPreviousWorkflowTasks(accumulator, start);
}

But this didn’t take into account gates, so now I’m trying to rewrite this using a Depth First Search. And I was looking for advice. I’m guessing I would start with something simple like how do I get all the tasks$ that I need to search through.

I’ve tried looking at the moddle json for help but it didn’t seem to point me in the right directions, bpmn-moddle/bpmn.json at master · bpmn-io/bpmn-moddle · GitHub

Any suggestions here would be appreciated.

So I’ve found another solution which is closer. Not exactly a real tree traversal but does the trick. I’m looking for feedback on how I might improve this search.

Comments welcomed.

export function findPreviousTasks(accumulator: ModdleElement[], currentTask: ModdleElement): ModdleElement[] {
  const start = currentTask.incoming;

  start.forEach((item: ModdleElement) => {
    if (item.sourceRef.$type === ElementType.StartEvent || accumulator.find((visited) => visited.id === item.sourceRef.id)) {
      return accumulator;
    }
    if (item.sourceRef.$type === ElementType.UserTask) {
      accumulator.push(item.sourceRef);
    }

    return findPreviousWorkflowTasks(accumulator, item.sourceRef);
  });
  return accumulator;
}