Branch statum-js-modules (cut from master c741172). All findings below verified
against the source on this saddle. The locked brief and task #212 comment 814 are
authoritative; this plan follows them, with two implementation choices called out
where 814 left naming open.
applyErrorClasses; markdown = 1257–3335.processInner :3504 hardcodes the order class→attribute→disabled→text/html/markdown/demotion→wireAction→recurse.
Splitting stm-markdown out (it loads AFTER document) means plain registration-order
execution would demote before markdown renders — the seam needs explicit ordering.applyErrorClasses :3638 (document territory) is called by core's reportFailure :304 →
moves to core per the brief.performAction :935 rejects on HTTP error / error-directive (reportFailure :302 re-throws
unless suppressed) → stm-clear-on-success can await the __stmAction stash.src/meson.build embeds js/statum.js via mkres as /_statum/resource/statum.js
(ClientScript.vala); mkpstm rewrite_resources_in :401 does the generic pstm-res-* rewrite;
example/main.html:8 has the single pstm-res-src="statum.js" (stays UNMODIFIED — the compat
proof); frontend-demo/server.php:362 serves /statum.js off disk; index.html:405 references it,
with toast overrides right after. Markdown tests load the file via std.loadFile under a stub shim.window.statum._bridge — core's IIFE builds the public API plus this internal
object holding the shared seam (evalExpr, childScope, stateScope, renderAll, registerAttribute,
installRenderDriver, performAction, trigger*, handlers, hooks, and the forms-hosted dirty WeakSet
slot). Underscore prefix follows the existing _testMarkdown private-by-convention precedent.
"Guarded IIFE" = each module starts by checking window.statum && window.statum._bridge,
else console.error('[statum] <module> requires statum-core.js') and returns (no throw).bridge.registerAttribute(name, fn, opts) where opts.after
/ opts.before name another attribute; core resolves to the ordered handler list
processInner iterates. Document registers its handlers in today's relative order; markdown
registers stm-markdown with after:'stm-html'; document registers stm-h-demotion with
after:'stm-markdown' (present-but-late if markdown never loads — same as today's
"runs after html" guarantee). A split test pins the final order byte-for-byte to today's.meson test green:
task A deletes js/statum.js and rewires meson to the modules that exist (3 after A, 4 after B);
the example page only becomes servable again in task C when mkpstm expands the reference.handlers+trigger* (:74/:249–307) preserved exactly,
applyErrorClasses moved in. Document keeps: loop/conditional/class/attribute/disabled
handlers, render walk (render/processElement/processInner/applyDefs), text/html binding,
h-demotion, action wiring (wireAction/runElementAction/collectData/setBusyState/reapplyDisabled).
Markdown = engine :1257–3335 verbatim + the stm-markdown binding + statum.markdown.render(src) /
renderTo(el, src) sharing the binding's single code path + the _testMarkdown hatch moves with it._bridge, registerAttribute seam, render-driver install point (renderAll calls the installed
driver inside its existing try/catch; absent driver = hooks+guards still run, no walk).meson setup && ninja && meson test.stm-prefill (early in handler order): property writes only —
.value for input/select/textarea (radio name-group matching within the form), .checked for
checkbox (boolean coercion) and radio (value match); skips any element in the dirty WeakSet._bridge (per the brief, reusable by the future task-186
fix) + capture-phase input/change listeners on document, and a reset listener that
un-dirties the form's controls (doubling as the server form-reset un-dirty path).__stmAction promise stash: one-line change in statum-document.js wireAction listener
(el.__stmAction = runElementAction(el); return el.__stmAction; shape).stm-clear-on-success on a form: submit listener awaits the triggering element's stashed
promise; on resolve → form.reset() (fires the reset un-dirty path) ; rejection → leave fields.
statum.forms.reset(form) as the programmatic equivalent.__STATUM_TEST__ hatch) covering the walk (if/else/for/text) and prefill scenarios:
value, dirty-skip after input, checked, radio group, clear-on-success resolve/reject,
forms.reset, reset-event un-dirty. model.md attribute table gains stm-prefill /
stm-clear-on-success rows. meson gains the 4th resource.pstm-res-src="statum.js" on a <script> expands at build time to the four ordered
script tags (/_statum/resource/statum-core.js → document → markdown → forms), one build
warning per page naming page + expansion; explicit module tags pass through unwarned; a page
mixing statum.js with explicit module tags emits the full ordered set once, deduped, and the
warning says so. example/main.html stays byte-identical.grep -r "resource/statum.js" only matches the rewrite map + docs).pstm-res-* rewrite
untouched for non-script elements.