Files
remanso/src/modules/macroplan/runMacroplan.ts
Julien Calixte 1b6c7542d7
All checks were successful
CI / verify (push) Successful in 2m9s
feat(notes): render macroplan code blocks as a delivery plan grid
Follows the tikz pattern: the fence emits a base64 placeholder, then
the post-render hook lazily imports the parser and grid (separate
chunks) and mounts the grid only when a placeholder exists. Mono font
forced on the block because the flag-stacking math assumes Fira Code.
2026-07-08 00:01:21 +02:00

56 lines
1.7 KiB
TypeScript

import { createApp } from "vue"
import { decodeBase64ToUTF8 } from "@/utils/decodeBase64ToUTF8"
const renderMacroplanError = (el: HTMLElement, err: unknown): void => {
const msg = err instanceof Error ? err.message : String(err)
el.textContent = ""
const box = document.createElement("div")
box.className = "macroplan-error"
const title = document.createElement("strong")
title.textContent = "Macroplan error"
const detail = document.createElement("pre")
detail.textContent = msg
box.append(title, detail)
el.appendChild(box)
}
/**
* Mount a MacroplanGrid onto every ```macroplan placeholder in scope.
* The parser (smol-toml + valibot) and the grid component only load
* when a placeholder actually exists, so notes without a plan pay nothing.
*/
export const runMacroplan = async (querySelector: string): Promise<void> => {
const elements = Array.from(
document.querySelectorAll<HTMLElement>(querySelector)
).filter((el) => !el.dataset.macroplanRendered)
if (elements.length === 0) return
const [{ parseMacroplan }, { buildPlan }, { default: MacroplanGrid }] =
await Promise.all([
import("./model/parse"),
import("./model/plan"),
import("./components/MacroplanGrid.vue")
])
for (const el of elements) {
el.dataset.macroplanRendered = "pending"
const encoded = el.dataset.macroplanSource
if (!encoded) {
el.dataset.macroplanRendered = "error"
continue
}
try {
const plan = buildPlan(parseMacroplan(decodeBase64ToUTF8(encoded)))
el.textContent = ""
createApp(MacroplanGrid, { plan }).mount(el)
el.dataset.macroplanRendered = "true"
} catch (err) {
renderMacroplanError(el, err)
el.dataset.macroplanRendered = "error"
}
}
}