BrainPath Query Planner
Query planner resolves a brain:// address to a sequence of operations that map the available inputs to the requested data. See the full BrainPath Specification.
// editable brain:// input — a textarea (not <input>) so long paths wrap and it
// auto-grows to fit its content.
viewof address = {
const ta = html`<textarea class="sf-input" spellcheck="false" autocomplete="off" rows="1" wrap="soft">${PRESETS[0][1]}</textarea>`;
const grow = () => { ta.style.height = "auto"; ta.style.height = (ta.scrollHeight + 2) + "px"; };
ta.addEventListener("input", grow);
ta.addEventListener("keydown", (e) => { if (e.key === "Enter") e.preventDefault(); });
requestAnimationFrame(grow);
return ta;
}presetChips = {
const wrap = html`<div class="sf-presets"></div>`;
for (const [label, val] of PRESETS) {
const chip = html`<span class="sf-preset">${label}</span>`;
chip.onclick = () => {
viewof address.value = val;
viewof address.dispatchEvent(new Event("input", { bubbles: true }));
};
wrap.append(chip);
}
return wrap;
}planView = {
const a = address;
const p = parsePath(a);
const res = p.ok ? plan(p, cacheOn) : null;
const model = buildModel(p, res, a, cacheOn);
const bpmn = planToBPMN(model);
const dlHref = bpmn ? URL.createObjectURL(new Blob([bpmn], { type: "application/xml" })) : "#";
const div = html`<div></div>`;
div.innerHTML = cardHTML(model, dlHref);
// wire the in-card cache switch to the reactive cacheOn
const sw = div.querySelector(".sf-switch");
if (sw) {
sw.onclick = () => { mutable cacheOn = !cacheOn; };
sw.onkeydown = (e) => { if (e.key === " " || e.key === "Enter") { e.preventDefault(); mutable cacheOn = !cacheOn; } };
}
return div;
}