Editor

<pre contenteditable="plaintext-only">. Edits trigger a re-parse; highlights update without mutating the DOM, so the caret stays put.

// Tiny reactive store
class Store {
  #state;
  #listeners = new Set();

  constructor(initial) {
    this.#state = initial;
  }

  get() {
    return this.#state;
  }

  set(next) {
    const prev = this.#state;
    this.#state = typeof next === 'function' ? next(prev) : next;
    if (!Object.is(this.#state, prev)) {
      for (const listen of this.#listeners) listen(this.#state, prev);
    }
  }

  subscribe(fn) {
    this.#listeners.add(fn);
    return () => this.#listeners.delete(fn);
  }
}

const counter = new Store(0);
counter.subscribe((next) => console.log('count:', next));
counter.set((n) => n + 1);