Issho.Engine.Comments (Issho v0.4.0)

Copy Markdown View Source

The threads of comments of a room: the engine of its comments document (Issho.Comments). Its browser twin is commentsEngine, held to the same cases (test/corpus/engine_comments.json).

The state is %{"threads" => [thread]}, in the order they began:

%{
  "id" => "t1",
  "place" => %{"doc" => "board:42", "at" => %{"node" => "n7"}},
  "status" => "open",
  "resolved" => nil,
  "comments" => [
    %{
      "id" => "c1",
      "author" => %{"key" => "user:ada", "name" => "Ada", "kind" => "human"},
      "body" => "Should this go first?",
      "mentions" => ["agent:claude"],
      "at" => "2026-10-23T10:00:00Z",
      "edited" => nil,
      "reactions" => %{"👍" => ["user:ken"]}
    }
  ]
}

A thread's place is where it is, in a component's own terms (Issho.Place), or nil for the page as a whole. "resolved" is %{"by" => key, "at" => time} while it is resolved.

Operations

%{"op" => "start", "thread" => "t1", "place" => place, "comment" => comment}
%{"op" => "reply", "thread" => "t1", "comment" => comment}
%{"op" => "edit", "thread" => "t1", "comment" => "c1", "body" => "...", "mentions" => [], "at" => time}
%{"op" => "delete", "thread" => "t1", "comment" => "c1"}
%{"op" => "react", "thread" => "t1", "comment" => "c1", "emoji" => "👍"}
%{"op" => "unreact", "thread" => "t1", "comment" => "c1", "emoji" => "👍"}
%{"op" => "resolve", "thread" => "t1", "at" => time}
%{"op" => "reopen", "thread" => "t1"}
%{"op" => "place", "thread" => "t1", "place" => place}

A new comment ("comment" of start and reply) is %{"id", "author", "body", "mentions", "at"}. Its author's key is the key of whoever made the transaction (the engine's :author option), and only its author edits or deletes it; a reaction is the author's own. Deleting a thread's last comment deletes the thread. Anyone who may comment resolves, reopens and places a thread (a component places it again as its content moves).

Concurrent changes merge: a reply, an edit, a reaction to a thread or a comment that is gone does nothing, as does resolving a resolved thread. The time of a comment is its writer's: Issho.Comments holds it, and the author's name, to the writer's signed identity and the server's clock before the change is accepted.