@startuml
!includeurl https://raw.githubusercontent.com/skleanthous/C4-PlantumlSkin/master/build/output/c4.puml

title Containers Diagram for Equinox (+Propulsion)
caption Packages / Elements breakdown of an event sourced system using Equinox

rectangle "Ingesters" as ingesters <<External System>> 
rectangle "Input Feeds" as inputs <<External System>> 
actor "Applications" as apps <<Internal>>

together {
    frame "Consistent Processing" <<Container>> as services {
        rectangle "Equinox" <<Component>> as equinox
        rectangle "Aggregate Roots" as aggs <<Container>>
    }
    frame "Read Models" <<External Container>> as caches {
        database "REDIS"    as red <<External>>
        database "SQL"      as sql <<External>>
        database "CosmosDB" as cdb <<External>>
        database "etc etc"  as etc <<External>>
    }
}

frame "Consistent Event Stores" as stores <<Expanded>> {
    frame "Cosmos" as cosmos <<Internal>> {
        rectangle "Equinox.Cosmos" <<Component>> as cs
        rectangle "Propulsion.Cosmos" <<External Component>> as cr
        rectangle "Azure.Cosmos" <<ExternalComponent>> as cc
    }
    frame "EventStore" <<Internal>> {
        rectangle "Equinox.EventStore" <<Component>> as es
        rectangle "Propulsion.EventStore" <<External Component>> as er
        rectangle "EventStore.ClientAPI" <<External Component>> as esc
    }
    frame "Integration Test Support" <<Internal>> {
        rectangle "Equinox.MemoryStore" <<Component>> as ms 
    }
    interface IStream <<Component>>
    rectangle "Equinox.Core" as core <<External>> {
        rectangle "System.MemoryCache" <<External Container>>
        interface ICache <<Component>>
    }
    frame "SqlStreamStore" as ssss <<Internal>> {
        rectangle "Equinox.SqlStreamStore.MsSql" <<Component>> as ssm
        rectangle "Equinox.SqlStreamStore.MySql" <<Component>> as ssy
        rectangle "Equinox.SqlStreamStore.Postgres" <<Component>> as ssp
        rectangle "Equinox.SqlStreamStore" <<External Component>> as sss
        rectangle "SqlStreamStore" <<External Component>>
    }
}

rectangle "Reactors" as reactors <<External System>> 
rectangle "Publishers" as publishers <<External System>> 
rectangle "Output Feeds" as outputs <<External System>> 

apps         .> caches     : reference\neventually consistent
apps        <-> aggs       : transact\nagainst

aggs         -> equinox    : use
equinox      -> IStream    : Query/\nTransact

stores     .>   publishers : are followed by
stores     .U.> reactors   : trigger

ingesters  <.   inputs     : sync from external
ingesters    -> aggs       : reconcile into
ingesters    .> caches     : push into

reactors  <-U-> aggs       : feed back into
reactors     .> caches     : maintain views in
reactors   <-   ms         : can react to
reactors   <-   cr         : can react to
reactors   <-   er         : can react to
reactors     .> publishers : trigger

publishers   .> outputs    : emit notifications to
publishers   .> outputs    : render events to
publishers <--  cr         : can feed from
publishers <--  er         : can feed from

ms           .> IStream    : implements
es           -> ICache
es           .> IStream    : implements
es           -> esc
cs          --> ICache
cs           .> IStream    : implements
cs          <-> cc
sss          -> ICache
sss          .> IStream    : implements

ssm          -> sss        : is a
ssy          -> sss        : is a
ssp          -> sss        : is a
sss         <-> SqlStreamStore

services   -[hidden]D-> reactors

ingesters  -[hidden]D-> services
publishers -[hidden]D-> es

IStream    -[hidden]D-> ssss

red        -[hidden]R-> sql
sql        -[hidden]R-> cdb
cdb        -[hidden]R-> etc

@enduml