╭ changed ──╮ │src/web.zig│ ╰───────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │26 .{ .path = "term.ttf", .content_type = "font/ttf", .body = @embedFile("embed/term.ttf") }, │ │27 .{ .path = "haxy.wasm", .content_type = "application/wasm", .body = @embedFile("embed/haxy.wasm") }, │ │28 }; │ │29 - │ │30 -pub fn run( │ │31 - io: std.Io, │ │32 - allocator: std.mem.Allocator, │ │33 - net_server: *std.Io.net.Server, │ │34 - tasks: *std.Io.Group, │ │35 - admin_repo_path: []const u8, │ │36 - session_store: SessionStore, │ │37 - err: *std.Io.Writer, │ │38 -) void { │ │39 - const Listener = struct { │ │40 - io: std.Io, │ │41 - allocator: std.mem.Allocator, │ │42 - net_server: *std.Io.net.Server, │ │43 - tasks: *std.Io.Group, │ │44 - admin_repo_path: []const u8, │ │45 - session_store: SessionStore, │ │46 - err: *std.Io.Writer, │ │47 - │ │48 - fn run(ctx: @This()) void { │ │49 - while (true) { │ │50 - const stream = ctx.net_server.accept(ctx.io) catch |accept_err| { │ │51 - if (accept_err == error.Canceled) return; │ │52 - logError(ctx.err, "web ui accept failed: {s}\n", .{@errorName(accept_err)}); │ │53 - continue; │ │54 - }; │ │55 - │ │56 - const Connection = struct { │ │57 - io: std.Io, │ │58 - allocator: std.mem.Allocator, │ │59 - stream: std.Io.net.Stream, │ │60 - admin_repo_path: []const u8, │ │61 - session_store: SessionStore, │ │62 - err: *std.Io.Writer, │ │63 - │ │64 - fn run(conn: @This()) void { │ │65 - defer conn.stream.close(conn.io); │ │66 - handleConnection(conn.io, conn.allocator, conn.stream, conn.admin_repo_path, conn.session_store, conn.err) catch |request_err| {│ │67 - logError(conn.err, "web ui request failed: {s}\n", .{@errorName(request_err)}); │ │68 - }; │ │69 - } │ │70 - }; │ │71 - │ │72 - ctx.tasks.async(ctx.io, Connection.run, .{Connection{ │ │73 - .io = ctx.io, │ │74 - .allocator = ctx.allocator, │ │75 - .stream = stream, │ │76 - .admin_repo_path = ctx.admin_repo_path, │ │77 - .session_store = ctx.session_store, │ │78 - .err = ctx.err, │ │79 - }}); │ │80 - } │ │81 - } │ │82 - }; │ │83 - │ │84 - tasks.async(io, Listener.run, .{Listener{ │ │85 - .io = io, │ │86 - .allocator = allocator, │ │87 - .net_server = net_server, │ │88 - .tasks = tasks, │ │89 - .admin_repo_path = admin_repo_path, │ │90 - .session_store = session_store, │ │91 - .err = err, │ │92 - }}); │ │93 -} │ │29 │ │95 -fn handleConnection( │ │30 +pub fn handleConnection( │ │31 io: std.Io, │ │32 allocator: std.mem.Allocator, │ │33 stream: std.Io.net.Stream, │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────╮ │381 return null; │ │382 } │ │383 │ │449 -fn logError(err: *std.Io.Writer, comptime fmt: []const u8, args: anytype) void { │ │450 - err.print(fmt, args) catch return; │ │451 - err.flush() catch {}; │ │452 -} │ │453 - │ │384 // emits the TUI grid cells as static HTML. each web-native Scroll becomes its │ │385 // own absolutely-positioned, natively-scrollable <div> holding its full content,│ │386 // rendered recursively so nested scrolls work. │ ╰──────────────────────────────────────────────────────────────────────────────────────╯