╭ changed ────────╮ │src/main_wasm.zig│ ╰─────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭───────────────────────────────────────────────────────────────────────────────╮ │15 const html = try web.generateHtml(allocator, root_ptr, &session); │ │16 defer allocator.free(html); │ │17 setHtml(html); │ │18 + │ │19 + // emit the overlay (form + inputs + button) on every tick so the wasm │ │20 + // layout drives positions, not just the server's initial render. JS │ │21 + // diffs the result against the previous overlay; an unchanged overlay │ │22 + // leaves the live <form> alone — crucial since wiping it mid-click │ │23 + // would detach the submit button before the browser can dispatch the │ │24 + // form submission. │ │25 + const overlay = try web.generateOverlay(allocator, root_ptr, &session);│ │26 + defer allocator.free(overlay); │ │27 + setOverlay(overlay); │ │28 } │ │29 │ │30 // the snapshot is allocated into this arena via parseFromSliceLeaky. it │ ╰───────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────╮ │ 98 _setHtml(arg.ptr, @intCast(arg.len)); │ │ 99 } │ │100 │ │101 +fn setOverlay(arg: []const u8) void { │ │102 + _setOverlay(arg.ptr, @intCast(arg.len)); │ │103 +} │ │104 + │ │105 extern fn _consoleLog(arg: [*]const u8, len: u32) void; │ │106 extern fn _setHtml(arg: [*]const u8, len: u32) void; │ │107 +extern fn _setOverlay(arg: [*]const u8, len: u32) void; │ │108 │ │109 /// js calls this first to get a wasm pointer it can write the page json into.│ │110 export fn _alloc(len: u32) ?[*]u8 { │ ╰───────────────────────────────────────────────────────────────────────────────────╯