Something went wrong. Try again.
My version of https://github.com/vercel-labs/fx
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403const std = @import("std");
pub const Event = enum { toggle, left, right,};
pub const Depth = enum { inline_mode, full,
pub fn transition(self: Depth, event: Event) Depth { return switch (event) { .toggle => if (self == .inline_mode) .full else .inline_mode, .left, .right => if (self.active()) .full else .inline_mode, }; }
pub fn active(self: Depth) bool { return self != .inline_mode; }};
pub const ScrollDirection = enum { up, down,};
pub const ItemRow = struct { entry_id: u32, row: u32,};
pub const Snapshot = struct { depth: Depth, scroll_rows: u32, follow_tail: bool, anchor_entry_id: ?u32, anchor_pending: bool, bookmark_entry_id: ?u32, bookmark_intra_row: u32, bookmark_pending: bool, projection_cols: ?u16,};
pub const OffsetSelection = struct { state: State, offset: u32,};
pub const State = struct { depth: Depth = .inline_mode, scroll_rows: u32 = 0, follow_tail: bool = true, anchor_entry_id: ?u32 = null, anchor_pending: bool = false, bookmark_entry_id: ?u32 = null, bookmark_intra_row: u32 = 0, bookmark_pending: bool = false, projection_cols: ?u16 = null,
pub fn with_depth(self: State, requested: Depth) State { if (self.depth == requested) return self;
var next = self; next = switch (requested) { .inline_mode => next.closed(), .full => next.open_full(), }; return next; }
pub fn closed(self: State) State { var next = self.reset_viewport().clear_anchor(); next.depth = .inline_mode; return next; }
pub fn clear_anchor(self: State) State { var next = self; next.anchor_entry_id = null; next.anchor_pending = false; next.bookmark_entry_id = null; next.bookmark_intra_row = 0; next.bookmark_pending = false; next.projection_cols = null; return next; }
pub fn capture_anchor(self: State, entry_id: ?u32) State { var next = self; next.anchor_entry_id = entry_id; next.anchor_pending = entry_id != null; return next; }
pub fn retarget_anchor(self: State, entry_id: u32) State { var next = self; next.anchor_entry_id = entry_id; return next; }
pub fn select_page_boundary(self: State, entry_id: u32) State { var next = self; next.scroll_rows = 0; next.follow_tail = false; next.anchor_pending = false; next.bookmark_entry_id = entry_id; next.bookmark_intra_row = 0; next.bookmark_pending = true; return next; }
pub fn prepare_projection(self: State, cols: u16) State { var next = self; if (next.projection_cols) |previous_cols| { if (previous_cols != cols) next = next.queue_bookmark(); } next.projection_cols = cols; return next; }
pub fn defer_full_open(self: State) State { var next = self; next.bookmark_pending = !next.follow_tail; next.bookmark_entry_id = null; next.bookmark_intra_row = 0; next.depth = .inline_mode; return next; }
pub fn scroll(self: State, direction: ScrollDirection, rows: u32) State { var next = self; next.follow_tail = false; next.bookmark_pending = false; switch (direction) { .up => next.scroll_rows -|= rows, .down => next.scroll_rows +|= rows, } return next; }
pub fn select_visual_offset( self: State, total_rows: u32, visible_rows: u16, item_rows: []const ItemRow, ) OffsetSelection { var next = self; const max_offset = total_rows -| visible_rows; const anchor_rows = resolve_bookmark_row(item_rows, next.anchor_entry_id); const offset = if (next.bookmark_pending) blk: { next.bookmark_pending = false; next.follow_tail = false; const item_row = resolve_bookmark_row( item_rows, next.bookmark_entry_id, ) orelse break :blk @min(next.scroll_rows, max_offset); const item_end = next_bookmark_item_row(item_rows, item_row) orelse total_rows; const max_intra_row = item_end -| item_row -| 1; break :blk @min( item_row +| @min(next.bookmark_intra_row, max_intra_row), max_offset, ); } else if (next.anchor_pending and anchor_rows != null) blk: { next.anchor_pending = false; next.follow_tail = false; break :blk @min(anchor_rows.?, max_offset); } else if (next.follow_tail) max_offset else @min(next.scroll_rows, max_offset);
next.scroll_rows = offset; next.follow_tail = offset == max_offset; next = next.refresh_bookmark(item_rows, offset); return .{ .state = next, .offset = offset }; }
pub fn snapshot(self: State) Snapshot { return .{ .depth = self.depth, .scroll_rows = self.scroll_rows, .follow_tail = self.follow_tail, .anchor_entry_id = self.anchor_entry_id, .anchor_pending = self.anchor_pending, .bookmark_entry_id = self.bookmark_entry_id, .bookmark_intra_row = self.bookmark_intra_row, .bookmark_pending = self.bookmark_pending, .projection_cols = self.projection_cols, }; }
pub fn from_snapshot(saved: Snapshot) State { return .{ .depth = saved.depth, .scroll_rows = saved.scroll_rows, .follow_tail = saved.follow_tail, .anchor_entry_id = saved.anchor_entry_id, .anchor_pending = saved.anchor_pending, .bookmark_entry_id = saved.bookmark_entry_id, .bookmark_intra_row = saved.bookmark_intra_row, .bookmark_pending = saved.bookmark_pending, .projection_cols = saved.projection_cols, }; }
fn open_full(self: State) State { var next = if (self.bookmark_pending) self else self.reset_viewport(); next.depth = .full; // The identity remains available for retention retargeting, but a // normal open starts at the tail instead of consuming the old anchor. next.anchor_pending = false; return next; }
fn reset_viewport(self: State) State { var next = self; next.scroll_rows = 0; next.follow_tail = true; return next; }
fn queue_bookmark(self: State) State { var next = self; next.bookmark_pending = !next.follow_tail and next.bookmark_entry_id != null; return next; }
fn refresh_bookmark( self: State, item_rows: []const ItemRow, offset: u32, ) State { var selected: ?ItemRow = null; for (item_rows) |item| { if (item.row > offset) break; // Synthetic full-detail records share the never-issued id 0 and // are not addressable restore anchors. if (item.entry_id == 0) continue; selected = item; } const item = selected orelse if (item_rows.len > 0) item_rows[0] else return self; var next = self; next.bookmark_entry_id = item.entry_id; next.bookmark_intra_row = offset -| item.row; return next; }};
fn resolve_bookmark_row(item_rows: []const ItemRow, entry_id: ?u32) ?u32 { const target = entry_id orelse return null; var preceding: ?ItemRow = null; var following: ?ItemRow = null; for (item_rows) |item| { if (item.entry_id == target) return item.row; if (item.entry_id < target) { if (preceding == null or item.entry_id > preceding.?.entry_id) { preceding = item; } } else if (following == null or item.entry_id < following.?.entry_id) { following = item; } } return if (preceding) |item| item.row else if (following) |item| item.row else null;}
fn next_bookmark_item_row(item_rows: []const ItemRow, current_row: u32) ?u32 { for (item_rows) |item| { if (item.row > current_row) return item.row; } return null;}
test "transcript presentation depth preserves viewer transitions" { try std.testing.expect(std.meta.stringToEnum(Depth, "review") == null); const Case = struct { from: Depth, input: Event, expected: Depth, }; const cases = [_]Case{ .{ .from = .inline_mode, .input = .toggle, .expected = .full }, .{ .from = .full, .input = .toggle, .expected = .inline_mode }, .{ .from = .inline_mode, .input = .left, .expected = .inline_mode }, .{ .from = .full, .input = .left, .expected = .full }, .{ .from = .inline_mode, .input = .right, .expected = .inline_mode }, .{ .from = .full, .input = .right, .expected = .full }, };
for (cases) |case| { try std.testing.expectEqual( case.expected, case.from.transition(case.input), ); }}
test "transcript presentation scroll saturates and leaves follow tail" { const initial = State{ .scroll_rows = 1 }; const at_start = initial.scroll(.up, 3); try std.testing.expectEqual(@as(u32, 0), at_start.scroll_rows); try std.testing.expect(!at_start.follow_tail);
const near_end = State{ .scroll_rows = std.math.maxInt(u32) - 1 }; const at_end = near_end.scroll(.down, 3); try std.testing.expectEqual(std.math.maxInt(u32), at_end.scroll_rows);}
test "transcript presentation deferred full open retains its exact offset" { const deferred = (State{ .depth = .full, .scroll_rows = 47, .follow_tail = false, .bookmark_entry_id = 2, .bookmark_intra_row = 7, }).defer_full_open(); try std.testing.expectEqual(Depth.inline_mode, deferred.depth); try std.testing.expect(deferred.bookmark_pending); try std.testing.expectEqual(@as(?u32, null), deferred.bookmark_entry_id);
const reopened = deferred.with_depth(.full).select_visual_offset( 100, 10, &.{}, ); try std.testing.expectEqual(@as(u32, 47), reopened.offset); try std.testing.expect(!reopened.state.follow_tail);}
test "transcript presentation clamps bookmarks and selects retained neighbor" { const item_rows = [_]ItemRow{ .{ .entry_id = 10, .row = 1 }, .{ .entry_id = 30, .row = 8 }, }; const clamped = (State{ .scroll_rows = 4, .follow_tail = false, .bookmark_entry_id = 10, .bookmark_intra_row = 99, .bookmark_pending = true, }).select_visual_offset(14, 4, &item_rows); try std.testing.expectEqual(@as(u32, 7), clamped.offset);
const neighbor = (State{ .scroll_rows = 4, .follow_tail = false, .bookmark_entry_id = 20, .bookmark_pending = true, }).select_visual_offset(14, 4, &item_rows); try std.testing.expectEqual(@as(u32, 1), neighbor.offset); try std.testing.expectEqual(@as(?u32, 10), neighbor.state.bookmark_entry_id);
const following = (State{ .scroll_rows = 4, .follow_tail = false, .bookmark_entry_id = 5, .bookmark_intra_row = 1, .bookmark_pending = true, }).select_visual_offset(14, 4, &item_rows); try std.testing.expectEqual(@as(u32, 2), following.offset); try std.testing.expectEqual(@as(?u32, 10), following.state.bookmark_entry_id);}
test "transcript presentation snapshot round trips all state" { const state = State{ .depth = .full, .scroll_rows = 7, .follow_tail = false, .anchor_entry_id = 11, .anchor_pending = true, .bookmark_entry_id = 12, .bookmark_intra_row = 2, .bookmark_pending = true, .projection_cols = 40, }; try std.testing.expectEqualDeep(state, State.from_snapshot(state.snapshot()));}
test "transcript presentation bookmark skips synthetic id-0 full-detail records" { const item_rows = [_]ItemRow{ .{ .entry_id = 0, .row = 1 }, .{ .entry_id = 0, .row = 4 }, .{ .entry_id = 10, .row = 8 }, }; const selected = (State{}).select_visual_offset(14, 4, &item_rows); try std.testing.expectEqual(@as(?u32, 10), selected.state.bookmark_entry_id);
const records_only = [_]ItemRow{.{ .entry_id = 0, .row = 1 }}; const degenerate = (State{}).select_visual_offset(8, 4, &records_only); try std.testing.expectEqual(@as(?u32, 0), degenerate.state.bookmark_entry_id);}