export interface LogEntry { render: () => HTMLElement[]; } export class LogLines implements LogEntry { lines: string[] constructor (...lines: string[]) { this.lines = lines } render (): HTMLElement[] { const p = document.createElement('p') this.lines.forEach(line => { const div = document.createElement('div') div.innerText = line p.appendChild(div) }) return [p] } } export class CompositeLog implements LogEntry { entries: LogEntry[] constructor (...entries: LogEntry[]) { this.entries = entries } render (): HTMLElement[] { return this.entries.map(entry => entry.render()).reduce((results: HTMLElement[], next: HTMLElement[]) => results.concat(next), []) } } export function log (entry: LogEntry): void { entry.render().forEach(elem => document.querySelector('#log')?.appendChild(elem)) }