alexandrepiveteau / elm-ordt / Ordt.Weave

Weaves are collections specifically designed to handle wefts and operations. They keep causality information about events in a distributed system, and offer some methods to replicate, merge and edit parts of the history.

The site identifiers can be any comparable type. This includes Int, Float, Time, Char, String, and tuples or lists of comparable types.

Weaves


type Weave comparable o

Represents a weave of operations. Each operation has some extra information about knowledge it had from other sites when it was integrated.

defaultIndex : Basics.Int

Default index when writing an operation.

Indices could be set to smaller than this, but for all the methods that require the insertion of a new operation at the start of a yarn, this is the index that will be used.

Build

empty : Weave comparable o

Create a weave that will indicate that no events have occured yet in the distributed system.

-- size empty == 0
-- isEmpty empty == True

singleton : comparable -> o -> Weave comparable o

Create a weave that will contain only a single operation, with no dependencies and knowledge of the rest of the weave.

-- size singleton "Alice" "Hello" == 1

push : comparable -> o -> Set comparable -> Weave comparable o -> Weave comparable o

Append an operation to a certain site, and indicate with a Dict the operations that are explicitly acknowledged by this push.

This is not for arbitrary insertions in the past !

This function appends your operation at the end of the yarn you specify.

Internally, some implicit references will be added if necessary, for transitive acknowledgements or acknowledgements of the previous operations of this site. If you add at a certain site, the index for this particular site will use max(get weft site, nextWeaveIndexFor site).

An important note - you can not reference the future in an operation you're adding now. Indeed, this could otherwise lead to some pretty severe inconsitencies - what if you reference the future of your friend, and he references yours ? You don't have a directed acyclic graph anymore !

type CounterOperation
    = Increment
    | Decrement

ack =
    Weft.singleton "Alice" Weave.defaultIndex

weave =
    Weave.empty
        |> Weave.push "Alice" Increment Weft.empty
        |> Weave.push "Bob" Decrement Weft.empty
        |> Weave.push "Charlie" Increment ack

Query

isEmpty : Weave comparable o -> Basics.Bool

Determine if a weave is empty.

size : Weave comparable o -> Basics.Int

Determine the number of operations in this weave.

yarn : comparable -> Weave comparable o -> List o

Get the yarn associated with a certain site identifier.

weft : Weave comparable o -> Ordt.Weft.Weft comparable

Get the weft representing the knowledge that this weave has of the whole distributed system. This does not necessarily mean that this weave has access to all the prior operations though, as some site-specific garbage collection might have occurred.

Transform

map : (Ordt.Weft.Weft comparable -> a -> b) -> Weave comparable a -> Weave comparable b

Map a function onto a weave, creating a weave with transformed operations.

foldl : (Ordt.Weft.Weft comparable -> o -> b -> b) -> b -> Weave comparable o -> b

Reduce the topologically sorted operations of a weave, starting with the most recent one.

type Operation
    = Increment
    | Decrement

acc weft op count =
    case op of
        Increment ->
            count + 1

        Decrement ->
            count - 1

-- foldr acc 0 (Weave.singleton "Alice" Increment) == 1

foldr : (Ordt.Weft.Weft comparable -> o -> b -> b) -> b -> Weave comparable o -> b

Reduce the topologically sorted operations of a weave, starting with the oldest one.

type GrowableSetOperation a
    = AddValue a

acc weft op (SetValue v) =
    Set.insert v acc

-- foldl acc Set.empty (Weave.singleton "Alice" (AddValue 3)) == Set.singleton 3

filter : (Ordt.Weft.Weft comparable -> o -> Basics.Bool) -> Weave comparable o -> Weave comparable o

Keep operations that satisfy the test.

filterMap : (Ordt.Weft.Weft comparable -> a -> Maybe b) -> Weave comparable a -> Weave comparable b

Filter out certain operations. For example, you might want to exclude some unnecessary or illegal operations from the weave.

Encoders

encode : (comparable -> Json.Encode.Value) -> (o -> Json.Encode.Value) -> Weave comparable o -> Json.Encode.Value

Turn a Weave into a JSON value.

decoder : Json.Decode.Decoder comparable -> Json.Decode.Decoder o -> Json.Decode.Decoder (Weave comparable o)

Decode a JSON value into a Weave.