A map that people and agents change together: values at paths, and
lists of items by their id, in the order the authority accepts them. It
is the engine of shared state (Issho.State), the reference for writing
an engine, and the engine of Issho's own tests.
%{"op" => "set", "path" => ["plan", "title"], "value" => "Q3"}
%{"op" => "delete", "path" => ["plan", "draft"]}
%{"op" => "increment", "path" => ["votes"], "by" => 1}
%{"op" => "insert", "path" => ["columns", "todo"], "value" => %{"id" => "c1", "title" => "Plan"}}
%{"op" => "move", "path" => ["columns", "todo"], "id" => "c1", "to" => ["columns", "done"], "after" => "c7"}A path is a list of up to 16 strings. Through a map, a string is a key;
through a list, it is the id of an item: ["columns", "todo", "c1", "title"] is the title of the card c1 in the list todo. set makes
the maps on its way; delete of a missing key does nothing, and of an
item removes it from its list.
Lists
A list of items is a list of maps, each with an "id" of its own (a
string), as a kanban's cards, a checklist's entries, a retro's notes:
insertputs an item ("value") in the list at"path", made if it is missing:"after"or"before"an item's id,"at""start"or"end"(the end unless given). An item whose id the list has already is refused (duplicate_id).movetakes the item"id"from the list at"path"to the list at"to"(the same list unless given), placed asinsertplaces it.
Concurrent changes merge: an item placed after one that is gone goes to
the end; a change, move or delete of an item that is gone does nothing,
as does a change through it. So two people who add cards at once both
have theirs, and a card one person moves while another deletes it is
deleted. Concurrent sets of one path follow the authority's order;
increments add up.
The initial content is a map (or nil, an empty one). Options:
:max_depth of values (32).
Version 2 added lists of items; a document of version 1 upgrades as it is.