╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ──────╮ │src/ui/Repo.zig│ ╰───────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │170 var any_repo = rp.AnyRepo(repo_kind, .{}).open(io, gpa, .{ .path = src.path }) catch break :read; │ │171 defer any_repo.deinit(io, gpa); │ │172 switch (any_repo) { │ │173 - inline else => |*opened| break :blk .{ │ │174 - try Files.init(repo_kind, opened.self_repo_opts, arena, opened, io, gpa, rf.identity, requested_ref_or_oid, requested_ref_value, files_dir, files_after), │ │175 - try Commits.init(repo_kind, opened.self_repo_opts, arena, opened, io, gpa, rf.identity, requested_ref_or_oid, requested_ref_value, commits_after), │ │176 - try Refs.init(repo_kind, opened.self_repo_opts, arena, opened, io, gpa, rf.identity, refs_kind, refs_after), │ │177 - try Issues.init(repo_kind, opened.self_repo_opts, arena, opened, rf.identity, issues_tag, issues_selected), │ │173 + inline else => |*opened| { │ │174 + // local mode: bring the event db up to date with the events branch │ │175 + if (session.local != null) evt.syncLocalEvents(repo_kind, opened.self_repo_opts, io, gpa, opened) catch {}; │ │176 + break :blk .{ │ │177 + try Files.init(repo_kind, opened.self_repo_opts, arena, opened, io, gpa, rf.identity, requested_ref_or_oid, requested_ref_value, files_dir, files_after),│ │178 + try Commits.init(repo_kind, opened.self_repo_opts, arena, opened, io, gpa, rf.identity, requested_ref_or_oid, requested_ref_value, commits_after), │ │179 + try Refs.init(repo_kind, opened.self_repo_opts, arena, opened, io, gpa, rf.identity, refs_kind, refs_after), │ │180 + try Issues.init(repo_kind, opened.self_repo_opts, arena, opened, io, rf.identity, issues_tag, issues_selected), │ │181 + }; │ │182 }, │ │183 } │ │184 }, │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ─────────────╮ │src/ui/Repo/Issues.zig│ ╰──────────────────────╯ ╭───────────────────────────────────────────────────╮ │59 comptime repo_opts: rp.RepoOpts(repo_kind),│ │60 arena: *std.heap.ArenaAllocator, │ │61 repo: *rp.Repo(repo_kind, repo_opts), │ │62 + io: std.Io, │ │63 identity: []const u8, │ │64 tag: []const u8, │ │65 selected_id: []const u8, │ ╰───────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────╮ │66 ) !Self { │ │67 const empty = try emptyResult(arena.allocator(), identity, tag, selected_id);│ │67 - if (repo_kind == .git) return empty; │ │68 │ │69 const aa = arena.allocator(); │ │70 - const DB = rp.Repo(repo_kind, repo_opts).DB; │ │70 + const DB = evt.EventDB(repo_opts.hash); │ │71 const rooted = empty.selected_id.len != 0; │ │72 const tagged = empty.tag.len != 0; │ │73 // an explicitly named issue or tag that doesn't exist is a bad url │ ╰─────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │74 // (NotFound -> 404); the bare route falls through to an empty listing. │ │75 const strict = rooted or tagged; │ │76 │ │77 - // a repo with no consumed events has no moment yet. │ │78 - const haxy_moment = evt.currentMoment(repo_opts, repo) catch { │ │79 - if (strict) return error.NotFound; │ │80 - return empty; │ │77 + // a local repo's events live in the event db next to it (consumed from the │ │78 + // events branch at startup); a server repo has them consumed into its own │ │79 + // db. a repo with no consumed events has no moment yet. │ │80 + const gpa = arena.child_allocator; │ │81 + var event_db_maybe = try evt.LocalEventDB(repo_opts.hash).open(io, gpa, repo.core.repo_dir); │ │82 + defer if (event_db_maybe) |*event_db| event_db.deinit(io, gpa); │ │83 + const haxy_moment = blk: { │ │84 + if (event_db_maybe) |*event_db| break :blk evt.currentMomentFromDb(repo_opts.hash, event_db.db) catch {│ │85 + if (strict) return error.NotFound; │ │86 + return empty; │ │87 + }; │ │88 + if (repo_kind == .git) return empty; │ │89 + break :blk evt.currentMoment(repo_opts, repo) catch { │ │90 + if (strict) return error.NotFound; │ │91 + return empty; │ │92 + }; │ │93 }; │ │94 │ │95 // the ordered set to window: the tag's issue set when filtered, else the │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ──╮ │src/web.zig│ ╰───────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │343 .remote => |remote| blk: { │ │344 // open the admin repo to read live user/repo data. │ │345 repo_maybe = try rp.Repo(.xit, evt.admin_repo_opts).open(io, allocator, .{ .path = remote.admin_repo_path });│ │346 - var session = try ui.Session.init(&page_arena, &repo_maybe.?, session_data); │ │346 + const repo = if (repo_maybe) |*repo| repo else unreachable; │ │347 + var session = try ui.Session.init(&page_arena, repo, session_data); │ │348 // give the page builders filesystem access to the on-disk repos (a │ │349 // sibling "repos" dir next to the admin repo) so the Repo page can │ │350 // read its files. │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯