╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ────╮ │src/event.zig│ ╰─────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1287 try kind_map.put(hash.hashInt(hash_kind, event_id), .{ .bytes = @tagName(kind) }); │ │1288 │ │1245 - const id_set_cursor = try haxy_moment.putCursor(hash.hashInt(hash_kind, event_id_set_key)); │ │1246 - const id_set = try DB.SortedSet(.read_write).init(id_set_cursor); │ │1247 - try id_set.put(&orderKeyDesc(created_ts, event_id)); │ │1289 + const active_cursor = try haxy_moment.putCursor(hash.hashInt(hash_kind, active_event_id_set_key)); │ │1290 + const active = try DB.SortedSet(.read_write).init(active_cursor); │ │1291 + const removed_cursor = try haxy_moment.putCursor(hash.hashInt(hash_kind, removed_event_id_set_key)); │ │1292 + const removed_set = try DB.SortedSet(.read_write).init(removed_cursor); │ │1293 + const order_key = orderKeyDesc(created_ts, event_id); │ │1294 + if (removed) { │ │1295 + _ = try active.remove(&order_key); │ │1296 + try removed_set.put(&order_key); │ │1297 + } else { │ │1298 + _ = try removed_set.remove(&order_key); │ │1299 + try active.put(&order_key); │ │1300 + } │ │1301 +} │ │1302 + │ │1303 +pub fn readEventKind( │ │1304 + comptime hash_kind: hash.HashKind, │ │1305 + kind_map: anytype, │ │1306 + id: *const [event_id_size]u8, │ │1307 +) !?EventKind { │ │1308 + const cursor = try kind_map.getCursor(hash.hashInt(hash_kind, id)) orelse return null; │ │1309 + var buffer: [64]u8 = undefined; │ │1310 + return std.meta.stringToEnum(EventKind, try cursor.readBytes(&buffer)) orelse error.InvalidEventKind;│ │1311 } │ │1312 │ │1313 // the event id embedded in a set entry's order key │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ───────────────╮ │src/event/Attachment.zig│ ╰────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │11 // from there rather than from the payload. │ │12 pub const Record = struct { │ │13 event: Self, │ │14 - deleted: bool = false, │ │14 + removed: bool = false, │ │15 author_email: ?[]const u8 = null, │ │16 created_ts: u64 = 0, // the commit timestamp of the event that created this attachment│ │17 name: []const u8, │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────╮ │80 record │ │81 else blk: { │ │82 var record = existing_record_maybe orelse return error.EventNotFound;│ │83 - record.deleted = true; │ │83 + record.removed = true; │ │84 break :blk record; │ │85 }; │ │86 │ ╰─────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │106 const attachment_cursor = try event_id_to_attachment.putCursor(attachment_key); │ │107 const attachment = try DB.HashMap(.read_write).init(attachment_cursor); │ │108 try evt.upsert(Record, DB, hash_kind, attachment, record_to_write); │ │109 - try evt.indexEvent(DB, hash_kind, haxy_moment, event_id, .attach, record_to_write.created_ts); │ │109 + try evt.indexEvent(DB, hash_kind, haxy_moment, event_id, .attach, record_to_write.created_ts, record_to_write.removed);│ │110 │ │111 if (existing_cursor_maybe == null) { │ │112 const attachment_id_set_cursor = try haxy_moment.putCursor(hash.hashInt(hash_kind, id_set_key)); │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │114 try attachment_id_set.put(&evt.orderKeyDesc(record_to_write.created_ts, event_id)); │ │115 } │ │116 │ │117 - // tombstones stay in the parent's set; the views skip them │ │117 + // removed attachments stay in the parent's set; the views skip them │ │118 const parent_attachments_cursor = try parent_id_to_attachment_id_set.putCursor(hash.hashInt(hash_kind, &record_to_write.event.parent_id));│ │119 const parent_attachments = try DB.SortedSet(.read_write).init(parent_attachments_cursor); │ │120 try parent_attachments.put(&evt.orderKey(record_to_write.created_ts, event_id)); │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ────────────╮ │src/event/Comment.zig│ ╰─────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────╮ │11 // what the db stores: the event's data plus the commit-derived fields │ │12 pub const Record = struct { │ │13 event: Self, │ │14 - deleted: bool = false, │ │14 + removed: bool = false, │ │15 author_email: ?[]const u8 = null, │ │16 created_ts: u64 = 0, // the commit timestamp of the event that first created this comment│ │17 }; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────╮ │62 record │ │63 else blk: { │ │64 var record = existing_record_maybe orelse return error.EventNotFound;│ │65 - record.deleted = true; │ │65 + record.removed = true; │ │66 break :blk record; │ │67 }; │ │68 │ ╰─────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │86 const comment_cursor = try event_id_to_comment.putCursor(comment_key); │ │87 const comment = try DB.HashMap(.read_write).init(comment_cursor); │ │88 try evt.upsert(Record, DB, hash_kind, comment, record_to_write); │ │89 - try evt.indexEvent(DB, hash_kind, haxy_moment, event_id, .comment, record_to_write.created_ts); │ │89 + try evt.indexEvent(DB, hash_kind, haxy_moment, event_id, .comment, record_to_write.created_ts, record_to_write.removed);│ │90 │ │91 if (existing_cursor_maybe == null) { │ │92 const comment_id_set_cursor = try haxy_moment.putCursor(hash.hashInt(hash_kind, id_set_key)); │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ 94 try comment_id_set.put(&evt.orderKeyDesc(record_to_write.created_ts, event_id)); │ │ 95 } │ │ 96 │ │ 97 - // tombstones stay in the thread so their replies remain connected │ │ 97 + // removed comments stay in the thread so their replies remain connected │ │ 98 const thread_order_key = evt.orderKey(record_to_write.created_ts, event_id); │ │ 99 const thread_comments_cursor = try thread_id_to_comment_id_set.putCursor(hash.hashInt(hash_kind, &record_to_write.event.thread_id));│ │100 const thread_comments = try DB.SortedSet(.read_write).init(thread_comments_cursor); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │164 evt.currentMoment(repo_opts, repo)) catch return error.NotFound; │ │165 const comment = (try readById(DB, repo_opts.hash, moment, &arena, comment_id)) orelse return error.NotFound;│ │166 if (!std.mem.eql(u8, &comment.event.thread_id, thread_id)) return error.NotFound; │ │167 + if (comment.removed) return error.NotFound; │ │168 │ │169 var updated = comment.event; │ │170 updated.body = body; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯