char-slop/berry

multipurpose self-modifiable agentic harness

git clone https://git.t4t.associates/char-slop/berry

Charlotte Somcode: streaming ANSI colorizationcada110

main
1.7 KiB49 linesraw
1import { ansiParser } from "./ansi.ts";
2
3/** Append coloured output snapshots, restarting when the result replaces or truncates the stream. */
4export function ansiOutput(element: HTMLElement): (source: string) => void {
5  let parser = ansiParser();
6  let previous = "";
7  let tail: Text | null = null;
8  let tailStyle = "";
9  element.hidden = true;
10
11  return (source) => {
12    if (source === previous) return;
13    if (!source.startsWith(previous)) {
14      parser = ansiParser();
15      previous = "";
16      tail = null;
17      element.replaceChildren();
18    }
19    const fragment = document.createDocumentFragment();
20    for (const { text, style } of parser.write(source.slice(previous.length))) {
21      const key = JSON.stringify(style);
22      let offset = 0;
23      while (offset < text.length) {
24        // bound text-node edits without making a new span for every streaming chunk
25        if (tail === null || key !== tailStyle || tail.length >= 16384) {
26          const span = document.createElement("span");
27          for (const [property, value] of Object.entries(style)) {
28            span.style.setProperty(property, value);
29          }
30          tail = document.createTextNode("");
31          tailStyle = key;
32          span.append(tail);
33          fragment.append(span);
34        }
35        let end = Math.min(text.length, offset + 16384 - tail.length);
36        if (
37          end < text.length && text.charCodeAt(end - 1) >= 0xd800 &&
38          text.charCodeAt(end - 1) <= 0xdbff && text.charCodeAt(end) >= 0xdc00 &&
39          text.charCodeAt(end) <= 0xdfff
40        ) end++;
41        tail.appendData(text.slice(offset, end));
42        offset = end;
43      }
44    }
45    element.append(fragment);
46    element.hidden = source === "";
47    previous = source;
48  };
49}