Maze solver async

by Bret Lowrey

HTML

<script src="https://wzrd.in/standalone/expect@latest"></script>
<body>

</body>

CSS

body {
  margin: 20px auto;
  max-width: 752px;
  line-height: 1.6;
  font-size: 18px;
  color: #444;
  padding: 0 10px
}

.maze {
  width: 680px;
}

.flex-container {
    display: flex;
    justify-content: space-around;
}

.flex-item {
    padding: 0px;
    font-size: 4em;
    color: black;
    min-width: 80px;
    height: 80px;
    text-align: center;
}

JavaScript

const writeMaze = (maze, path = [], current = '') => {
	console.log(path);
	let content = `<div class='maze'>`;
  let [cX, cY] = current.split(',').map(x => Number(x));
  for (let y = 0; y < maze.length; y++) {
  	content += `<div class="flex-container">`;
    for (let x = 0; x < maze[0].length; x++) {
    	let cell = '⬜';
      if (maze[y][x] === 1) {
      	cell = '⬛';
      } 
      if (path.includes(`${x},${y}`)) {
      	cell = '▧';
      }
      if (y === cY && x === cX) {
      	cell = '▣';
      }
    	content += `<div class="flex-item">${cell}</div>`;
    }
    content += `</div>`;
  }
  content += `</div>`;
  document.body.innerHTML = content;
};

const promiseWhile = (data, condition, action) => {
  var whilst = (data) => {
    return condition(data) ?
      action(data).then(whilst) :
      Promise.resolve(data);
  }
  return whilst(data);
};

class PriorityQueue {
  constructor() {
    this.data = [];
  }

  push(value, priority = 0) {
    return this.data.push({
      value: value,
      priority: priority
    });
  }

  pop() {
    let index = 0;
    let min = Infinity;
    for (let i = 0; i < this.data.length; i++) {
      let priority = this.data[i].priority;
      if (Math.min(min, priority) === priority) {
        min = priority;
        index = i;
      }
    }
    return this.data.splice(index, 1)[0].value;
  }

  size() {
    return this.data.length;
  }
}

class DirectedGraph {
  constructor(edges) {
    this.edges = edges;
  }

  nodes() {
    return Object.keys(this.edges);
  }

  edgesOf(node) {
    return Object.keys(this.edges[node]);
  }

  cost(node, next) {
    return this.edges[node][next] ?
      this.edges[node][next] : Infinity;
  }

  generatePath(path, goal) {
    let result = [];
    let index = goal;
    while (index !== null) {
      result.push(index);
      index = path[index];
    }
    return result.reverse();
  }

  search(start, goal, neighbors, heuristic, display = []) {
    let frontier = new PriorityQueue();
   ...