Architecture#

        ---
title: Base classes
---
classDiagram
 class hashable {}
 hashable --|> Node
 hashable --|> Connection
 Graph *-- Node : nodes
 Node *-- Connection: outgoing_connection
 Node *-- Connection: incoming_connection
 Node *-- NodeState: state
 NodeState *-- NodeOnlineState: online
 NodeState *-- Node: node
 NodeOnlineState --|> NodeIsOffline
 NodeOnlineState --|> NodeIsOnline
 Connection *-- ConnectionState: state
 ConnectionState *-- Connection: connection
 ConnectionState *-- ConnectionSetupState: setup
 ConnectionSetupState --|> ConnectionSetup
 ConnectionSetupState --|> ConnectionNotSetup
 class Graph {
   +bool is_directed
   +set[Node] nodes
   +Any data
   +Node add(node: Node)
   +Connection connect(source: Node, connection: Connection, destination: Node)
   +Node get_by_id(node_id: str)
   +set[Node] get_by_class(class_: type[Node])
   +set[Node] get_by_data(predicate: Callable[[Any], bool])
   +Node delete(node_id: str)
   -None internal_add_node(node: Node)
   -None internal_delete_node(node: Node)
 }
 class Node {
     +str identifier
     +data Any
     +NodeState state
     +set[Connection] outgoing_connection
     +set[Connection] incoming_connection
     +Connection connect(connection: Connection, destination: Node)
     +set[Node] get_outgoing_neighbors_by_connection_data(predicate: Callable[[Any], bool])
     +set[Node] get_outgoing_neighbors_by_connection_type(type_: type[Connection])
     +set[Node] get_outgoing_neighbors_by_node_data(predicate: Callable[[Any], bool])
     +set[Node] get_outgoing_neighbors_by_node_type(type_: type[Node])
     +set[Node] get_neighbors_by_connection_data(predicate: Callable[[Any], bool], direction: Literal["all", "outgoing", "incoming"])
     +set[Node] get_neighbors_by_connection_type(type_: type[Connection], direction: Literal["all", "outgoing", "incoming"])
     +set[Node] get_neighbors_by_node_data(predicate: Callable[[Any], bool], direction: Literal["all", "outgoing", "incoming"])
     +set[Node] get_neighbors_by_node_type(type_: type[Node], direction: Literal["all", "outgoing", "incoming"])
     +set[Node] get_incoming_neighbors_by_connection_data(predicate: Callable[[Any], bool])
     +set[Node] get_incoming_neighbors_by_connection_type(type_: type[Connection])
     +set[Node] get_incoming_neighbors_by_node_data(predicate: Callable[[Any], bool])
     +set[Node] get_incoming_neighbors_by_node_type(type_: type[Node])
     -None _post_init()
     -NodeIsOnline _ensure_online()
 }
 class NodeState {
     +Node node
     +NodeOnlineState online
     +bool is_online()
 }
 class NodeOnlineState {
     +NodeState state
     +bool is_online()
 }
 class NodeIsOffline {
     +Node attach(graph: Graph)
 }
 class NodeIsOnline {
     +Graph graph
     +set[Connection] outgoing_connection
     +set[Connection] incoming_connection
     +Node detach()
     +Connection connect(connection: Connection, destination: Node)
     +int delete_outgoing_connection_by_node(node: Node)
     +int delete_incoming_connection_by_node(node: Node)
     +set[Node] get_outgoing_neighbors_by_connection_data(predicate: Callable[[Any], bool])
     +set[Node] get_outgoing_neighbors_by_connection_type(type_: type[Connection])
     +set[Node] get_outgoing_neighbors_by_node_data(predicate: Callable[[Any], bool])
     +set[Node] get_outgoing_neighbors_by_node_type(type_: type[Node])
     +set[Node] get_incoming_neighbors_by_connection_data(predicate: Callable[[Any], bool])
     +set[Node] get_incoming_neighbors_by_connection_type(type_: type[Connection])
     +set[Node] get_incoming_neighbors_by_node_data(predicate: Callable[[Any], bool])
     +set[Node] get_incoming_neighbors_by_node_type(type_: type[Node])
     +bool is_online()
     -None _clear_connect(connection: Connection, destination: Node)
     -None check_connection_state(connection: Connection)
     -None _add_connection(connection: Connection, destination: Node)
     -tuple[set[Connection], int] _filter_connection_by_node(node: Node, connection: set[Connection], direction: Literal["in", "out"])
     -ConnectionSetup _ensure_connection_setup(connection: Connection)
 }
 class Connection {
     +str identifier
     +data Any
     +ConnectionState state
 }
 class ConnectionState {
     +Connection connection
     +bool setup
     +bool is_setup()
 }
 class ConnectionSetupState {
     +ConnectionState state
     +bool is_setup()
 }
 class ConnectionNotSetup {
     +Connection setup(source: Node, destination: Node)
 }
 class ConnectionSetup {
     +Node source
     +Node destination
 }
    

State#

This library use class as state. Let’s take the Connection class for an example. A connection can be used by a Node or not. Let’s call a Connection not yet connected “Not setup”. A Connection can then be Setup or Not setup. When a Connection is not yet setup, it does not have a source or a destination. But in the same state, it can also be setup and connected to a Node.

All of the properties or function that are related to a given state are stored in their own class. For the Connection classes, its “state storage” ConnectionState (that holds all state classes related to Connection) store an online property of type ConnectionSetupState. ConnectionSetupState is an abstract class with two inherited classes: ConnectionSetup, that will be stored in ConnectionState when the Connection is setup, and ConnectionNotSetup when the Connection is not yet attached to a Node.

Node#

Node has one state. If it is “online”, it is attached to a Graph. Else, it is “offline”.

Connection#

Connection has one state. If it is “setup”, it is attached to a Node. Else, it is “not setup”.