╭ changed ─╮ │src/ui.zig│ ╰──────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────╮ │20 }; │ │21 │ │22 // per-connection mutable state. each SSH session / web session / local TUI │ │23 -// run gets its own │ │23 +// run gets its own. `data` is the subset that round-trips between server │ │24 +// and wasm; the other fields are runtime context only and stay local. │ │25 pub const Session = struct { │ │25 - user_id: ?[]const u8 = null, │ │26 + data: SessionData = .{}, │ │27 arena: ?*std.heap.ArenaAllocator = null, │ │28 haxy_moment: ?DB.HashMap(.read_only) = null, │ │29 +}; │ │30 + │ │31 +// the serializable part of session │ │32 +pub const SessionData = struct { │ │33 + user_id: ?[]const u8 = null, │ │34 + // a transient outcome to surface from the last /login POST attempt │ │35 + login_failure: ?Home.Auth.Login.Failure = null, │ │36 }; │ │37 │ │38 +// what the server hands to the client (and what main_wasm parses on _start). │ │39 +// keeps Page free of any per-request session state. │ │40 +pub const Snapshot = struct { │ │41 + page: Page, │ │42 + session: SessionData = .{}, │ │43 +}; │ │44 + │ │45 pub fn run(io: std.Io, allocator: std.mem.Allocator, page: *const Page, session: *Session) !void {│ │46 var root = try initRoot(allocator, page, session); │ │47 defer root.deinit(allocator); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │450 // when only a min is set (e.g. the wasm path passes viewport rows │ │451 // as min_height with no max), we can still vertically center while │ │452 // letting taller content extend past the min. │ │438 - const width = if (constraint.max_size.width) |w| w │ │439 - else if (constraint.min_size.width) |min_w| @max(min_w, child_grid.size.width) │ │440 - else child_grid.size.width; │ │441 - const height = if (constraint.max_size.height) |h| h │ │442 - else if (constraint.min_size.height) |min_h| @max(min_h, child_grid.size.height) │ │443 - else child_grid.size.height; │ │453 + const width = if (constraint.max_size.width) |w| w else if (constraint.min_size.width) |min_w| @max(min_w, child_grid.size.width) else child_grid.size.width; │ │454 + const height = if (constraint.max_size.height) |h| h else if (constraint.min_size.height) |min_h| @max(min_h, child_grid.size.height) else child_grid.size.height;│ │455 if (width == 0 or height == 0) return; │ │456 │ │457 const offset_x: usize = if (self.direction == .horiz or self.direction == .both) │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯