╭ changed ────────╮ │src/main_wasm.zig│ ╰─────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │15 setHtml(html); │ │16 } │ │17 │ │18 -// TODO: receive the Page as json from the host and parse it back into │ │19 -// a Page so initRoot can render real data. for now we initialize with │ │20 -// an empty page just so the wasm build compiles. │ │21 -var page_maybe: ?pg.Page = null; │ │18 +// the page is allocated into this arena via parseFromSliceLeaky. it has │ │19 +// to outlive `root`, because `root` holds slices into the parsed strings. │ │20 +var page_arena: ?std.heap.ArenaAllocator = null; │ │21 +var page: ?pg.Page = null; │ │22 │ │23 -fn start() !void { │ │24 - const page = page_maybe orelse pg.Page{ .user_repo = pg.UserRepoPage.empty() }; │ │23 +fn start(json: []const u8) !void { │ │24 + if (page_arena) |*a| a.deinit(); │ │25 + page_arena = std.heap.ArenaAllocator.init(allocator); │ │26 + │ │27 + // alloc_always so the parsed strings live entirely inside the arena │ │28 + // and don't borrow from the caller's json buffer. │ │29 + page = try std.json.parseFromSliceLeaky(pg.Page, (page_arena orelse unreachable).allocator(), json, .{│ │30 + .allocate = .alloc_always, │ │31 + }); │ │32 │ │26 - var next_root = try ui.initRoot(allocator, &page); │ │33 + var next_root = try ui.initRoot(allocator, &(page orelse unreachable)); │ │34 errdefer next_root.deinit(); │ │35 │ │36 if (root) |*old_root| old_root.deinit(); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────╮ │56 34 => .page_down, │ │57 35 => .end, │ │58 36 => .home, │ │59 + 37 => .arrow_left, │ │60 38 => .arrow_up, │ │61 + 39 => .arrow_right,│ │62 40 => .arrow_down, │ │63 else => return, │ │64 }; │ ╰───────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────╮ │76 extern fn _consoleLog(arg: [*]const u8, len: u32) void; │ │77 extern fn _setHtml(arg: [*]const u8, len: u32) void; │ │78 │ │70 -export fn _start() void { │ │71 - start() catch |err| { │ │79 +/// js calls this first to get a wasm pointer it can write the page json into. │ │80 +export fn _alloc(len: u32) ?[*]u8 { │ │81 + const slice = allocator.alloc(u8, len) catch return null; │ │82 + return slice.ptr; │ │83 +} │ │84 + │ │85 +export fn _start(json_ptr: [*]u8, json_len: u32) void { │ │86 + const json = json_ptr[0..json_len]; │ │87 + defer allocator.free(json); │ │88 + start(json) catch |err| { │ │89 var buf: [256]u8 = undefined; │ │90 const str = std.fmt.bufPrint(&buf, "start: {}", .{err}) catch unreachable;│ │91 consoleLog(str); │ ╰──────────────────────────────────────────────────────────────────────────────────────╯