Echo — JS → Mere → JS strings

A small dogfood for the JS-to-Mere string boundary in contrib/dom. Type into the textarea and press the button: the Mere closure reads dom_input_value, then writes it back via dom_set_text. The counter demo only crosses the boundary in the Mere → JS direction; this one closes the loop.

(output will appear here)

Source (echo.mere)

import "contrib/dom/dom.mere";

let input = dom_get_by_id "input" in
let display = dom_get_by_id "display" in
let btn = dom_get_by_id "go" in
let _ = dom_on_click btn (fn (u: unit) ->
  let s = dom_input_value input in
  dom_set_text display s
) in
0

The JS → Mere string path

dom_input_value reads element.value in JS, encodes the string as UTF-8, copies the bytes into a high-memory scratch buffer inside Wasm linear memory (starting at 56KB by default), and returns the offset:

// inside dom.glue.js
dom_input_value: (handleIdx) => {
  const el = handles[handleIdx];
  if (!el) return writeStr("");
  return writeStr(el.value !== undefined ? el.value : "");
},

// writeStr copies UTF-8 + null terminator into the scratch region
// and returns the byte offset (which Mere treats as a `str` value).

The returned offset is an ordinary Mere str value — once it's in s, the rest of the program (and str_* builtins) treat it like any other string. The scratch buffer is overwritten on the next dom_input_value call, so retain via substring / str_concat if you need it past the current event.