# KnowledgeGraphService

- File ID: file:q6pxzf:knowledgegraphservice-cs
- Path: NexusReader.UI.Shared/Services/KnowledgeGraphService.cs
- Role: service
- Layer: frontend

## Purpose

In-memory UI/shared service that holds the current knowledge graph state (GraphDataDto), active node id, loading flag, and publishes change notifications via events for UI consumers.

## Key Details

Simple UI/shared state service that centralizes graph state and notifies subscribers; methods are small, synchronous state mutations with conditional async event invocation; SetActiveNode contains a guard no-op to avoid redundant notifications.

## Symbols

- KnowledgeGraphService: In-memory UI/shared service that holds the current knowledge graph state (GraphDataDto), active node id, loading flag, and publishes change notifications via events for UI consumers.
- UpdateGraph(): Replace CurrentGraphData with new graph data, clear loading flag, and notify subscribers that loading changed and graph updated.
- SetActiveNode(): Set the active node id (no-op if unchanged) and notify subscribers of the change.
- SetLoading(): Update the IsLoading flag and notify subscribers about loading state changes.
- Clear(): Clear the stored graph data, active node, reset loading flag, and notify graph-updated subscribers.
- KnowledgeGraphService: Service model that holds current graph state, active node id, loading flag and event publishers for UI consumers.

## Dependencies

- No resolved dependencies.

## Calls

- No resolved calls.

## Unresolved References

- dependency-target: NexusReader.Application.Queries.Graph (GraphDataDto)
- dependency-target: IKnowledgeGraphService (interface - not in this file)
- call-target: self
- call-target: self
- call-target: self
- call-target: self
- call-target: self

## Coverage

- Symbols: 6
- Executable symbols: 4
- Executable symbols with control flow: 4
- Grounded edges: 6
- Unresolved references: 7
- Control-flow fragments: 4
- Unresolved jumps: 5
- Unsupported constructs: 0
- Control-flow coverage: 100%
- Required diagrams: 2
- Generated diagrams: 6

## Control Flow Fragments

- UpdateGraph: 18 nodes, 19 edges, 2 jumps, 0 unsupported constructs
- SetActiveNode: 18 nodes, 20 edges, 1 jumps, 0 unsupported constructs
- SetLoading: 10 nodes, 10 edges, 1 jumps, 0 unsupported constructs
- Clear: 12 nodes, 12 edges, 1 jumps, 0 unsupported constructs

## Diagrams

### KnowledgeGraphService Neighborhood

```mermaid
flowchart LR
    class_zdhkb2_knowledgegraphservice("KnowledgeGraphService")
    file_q6pxzf_knowledgegraphservice_cs("KnowledgeGraphService")
    method_1ii06co_setactivenode[["SetActiveNode()"]]
    method_90e1ug_setloading[["SetLoading()"]]
    method_b27zpe_updategraph[["UpdateGraph()"]]
    method_ekp9ov_clear[["Clear()"]]
    type_pp4157_knowledgegraphservice[/"KnowledgeGraphService"/]
```

### KnowledgeGraphService Execution Overview

```mermaid
flowchart TD
    class_zdhkb2_knowledgegraphservice("KnowledgeGraphService")
    method_1ii06co_setactivenode[["SetActiveNode()"]]
    method_90e1ug_setloading[["SetLoading()"]]
    method_b27zpe_updategraph[["UpdateGraph()"]]
    method_ekp9ov_clear[["Clear()"]]
    unresolved_unresolved_120p162_call_target{"Unresolved: OnLoadingChanged"}
    unresolved_unresolved_1d66hoy_call_target{"Unresolved: OnLoadingChanged"}
    unresolved_unresolved_1m63l2b_call_target{"Unresolved: OnGraphUpdated"}
    unresolved_unresolved_6929sq_call_target{"Unresolved: OnActiveNodeChanged"}
    unresolved_unresolved_nqd2ct_call_target{"Unresolved: OnGraphUpdated"}
    class_zdhkb2_knowledgegraphservice -->|contains| method_1ii06co_setactivenode
    class_zdhkb2_knowledgegraphservice -->|contains| method_90e1ug_setloading
    class_zdhkb2_knowledgegraphservice -->|contains| method_b27zpe_updategraph
    class_zdhkb2_knowledgegraphservice -->|contains| method_ekp9ov_clear
    method_1ii06co_setactivenode -->|unresolved call| unresolved_unresolved_6929sq_call_target
    method_90e1ug_setloading -->|unresolved call| unresolved_unresolved_1d66hoy_call_target
    method_b27zpe_updategraph -->|unresolved call| unresolved_unresolved_120p162_call_target
    method_b27zpe_updategraph -->|unresolved call| unresolved_unresolved_nqd2ct_call_target
    method_ekp9ov_clear -->|unresolved call| unresolved_unresolved_1m63l2b_call_target
```

### UpdateGraph() Control Flow

```mermaid
flowchart TD
    method_b27zpe_updategraph__call_19_OnLoadingChanged[["OnLoadingChanged"]]
    method_b27zpe_updategraph__call_20_OnGraphUpdated[["OnGraphUpdated"]]
    method_b27zpe_updategraph__action_17_state_change_17__linear("Set CurrentGraphData")
    method_b27zpe_updategraph__action_18_state_change_18__linear("Clear IsLoading")
    method_b27zpe_updategraph__action_19_event_19__linear("Notify loading changed")
    method_b27zpe_updategraph__action_19_updategraph_await_19_1__await[["Waits for async work"]]
    method_b27zpe_updategraph__action_19_updategraph_branch_19_0__condition{"OnLoadingChanged != null) await OnLoadingChanged(false"}
    method_b27zpe_updategraph__action_19_updategraph_branch_19_0__false("false")
    method_b27zpe_updategraph__action_19_updategraph_branch_19_0__merge("merge")
    method_b27zpe_updategraph__action_19_updategraph_branch_19_0__true("true")
    method_b27zpe_updategraph__action_20_event_20__linear("Notify graph updated")
    method_b27zpe_updategraph__action_20_updategraph_await_20_3__await[["Waits for async work"]]
    method_b27zpe_updategraph__action_20_updategraph_branch_20_2__condition{"OnGraphUpdated != null) await OnGraphUpdated("}
    method_b27zpe_updategraph__action_20_updategraph_branch_20_2__false("false")
    method_b27zpe_updategraph__action_20_updategraph_branch_20_2__merge("merge")
    method_b27zpe_updategraph__action_20_updategraph_branch_20_2__true("true")
    method_b27zpe_updategraph__entry(["UpdateGraph entry"])
    method_b27zpe_updategraph__implicit_return(["return"])
    method_b27zpe_updategraph__action_17_state_change_17__linear -->|next| method_b27zpe_updategraph__action_18_state_change_18__linear
    method_b27zpe_updategraph__action_18_state_change_18__linear -->|next| method_b27zpe_updategraph__action_19_updategraph_await_19_1__await
    method_b27zpe_updategraph__action_19_event_19__linear -->|next| method_b27zpe_updategraph__action_19_updategraph_branch_19_0__condition
    method_b27zpe_updategraph__action_19_updategraph_await_19_1__await -->|next| method_b27zpe_updategraph__action_19_event_19__linear
    method_b27zpe_updategraph__action_19_updategraph_branch_19_0__condition -->|false| method_b27zpe_updategraph__action_19_updategraph_branch_19_0__false
    method_b27zpe_updategraph__action_19_updategraph_branch_19_0__condition -->|true| method_b27zpe_updategraph__action_19_updategraph_branch_19_0__true
    method_b27zpe_updategraph__action_19_updategraph_branch_19_0__false -->|next| method_b27zpe_updategraph__action_19_updategraph_branch_19_0__merge
    method_b27zpe_updategraph__action_19_updategraph_branch_19_0__merge -->|false signals loading finished| method_b27zpe_updategraph__call_19_OnLoadingChanged
    method_b27zpe_updategraph__action_19_updategraph_branch_19_0__true -->|next| method_b27zpe_updategraph__action_19_updategraph_branch_19_0__merge
    method_b27zpe_updategraph__action_20_event_20__linear -->|next| method_b27zpe_updategraph__action_20_updategraph_branch_20_2__condition
    method_b27zpe_updategraph__action_20_updategraph_await_20_3__await -->|next| method_b27zpe_updategraph__action_20_event_20__linear
    method_b27zpe_updategraph__action_20_updategraph_branch_20_2__condition -->|false| method_b27zpe_updategraph__action_20_updategraph_branch_20_2__false
    method_b27zpe_updategraph__action_20_updategraph_branch_20_2__condition -->|true| method_b27zpe_updategraph__action_20_updategraph_branch_20_2__true
    method_b27zpe_updategraph__action_20_updategraph_branch_20_2__false -->|next| method_b27zpe_updategraph__action_20_updategraph_branch_20_2__merge
    method_b27zpe_updategraph__action_20_updategraph_branch_20_2__merge -->|no args signals graph updated| method_b27zpe_updategraph__call_20_OnGraphUpdated
    method_b27zpe_updategraph__action_20_updategraph_branch_20_2__true -->|next| method_b27zpe_updategraph__action_20_updategraph_branch_20_2__merge
    method_b27zpe_updategraph__call_19_OnLoadingChanged -->|next| method_b27zpe_updategraph__action_20_updategraph_await_20_3__await
    method_b27zpe_updategraph__call_20_OnGraphUpdated -->|return| method_b27zpe_updategraph__implicit_return
    method_b27zpe_updategraph__entry -->|next| method_b27zpe_updategraph__action_17_state_change_17__linear
```

### SetActiveNode() Control Flow

```mermaid
flowchart TD
    method_1ii06co_setactivenode__call_27_OnActiveNodeChanged[["OnActiveNodeChanged"]]
    method_1ii06co_setactivenode__action_25_guard_clause_25__condition{"ActiveNodeId == nodeId"}
    method_1ii06co_setactivenode__action_25_guard_clause_25__false("continue")
    method_1ii06co_setactivenode__action_25_guard_clause_25__merge("merge")
    method_1ii06co_setactivenode__action_25_guard_clause_25__true("return (no change)")
    method_1ii06co_setactivenode__action_25_setactivenode_guard_clause_25_0__condition{"ActiveNodeId == nodeId"}
    method_1ii06co_setactivenode__action_25_setactivenode_guard_clause_25_0__false("continue")
    method_1ii06co_setactivenode__action_25_setactivenode_guard_clause_25_0__merge("merge")
    method_1ii06co_setactivenode__action_25_setactivenode_guard_clause_25_0__true("exit")
    method_1ii06co_setactivenode__action_26_state_change_26__linear("Set ActiveNodeId")
    method_1ii06co_setactivenode__action_27_event_27__linear("Notify active node changed")
    method_1ii06co_setactivenode__action_27_setactivenode_await_27_2__await[["Waits for async work"]]
    method_1ii06co_setactivenode__action_27_setactivenode_branch_27_1__condition{"OnActiveNodeChanged != null) await OnActiveNodeChanged(nodeId"}
    method_1ii06co_setactivenode__action_27_setactivenode_branch_27_1__false("false")
    method_1ii06co_setactivenode__action_27_setactivenode_branch_27_1__merge("merge")
    method_1ii06co_setactivenode__action_27_setactivenode_branch_27_1__true("true")
    method_1ii06co_setactivenode__entry(["SetActiveNode entry"])
    method_1ii06co_setactivenode__implicit_return(["return"])
    method_1ii06co_setactivenode__action_25_guard_clause_25__condition -->|continue| method_1ii06co_setactivenode__action_25_guard_clause_25__false
    method_1ii06co_setactivenode__action_25_guard_clause_25__condition -->|return no change| method_1ii06co_setactivenode__action_25_guard_clause_25__true
    method_1ii06co_setactivenode__action_25_guard_clause_25__false -->|next| method_1ii06co_setactivenode__action_25_guard_clause_25__merge
    method_1ii06co_setactivenode__action_25_guard_clause_25__merge -->|next| method_1ii06co_setactivenode__action_25_setactivenode_guard_clause_25_0__condition
    method_1ii06co_setactivenode__action_25_guard_clause_25__true -->|next| method_1ii06co_setactivenode__action_25_guard_clause_25__merge
    method_1ii06co_setactivenode__action_25_setactivenode_guard_clause_25_0__condition -->|continue| method_1ii06co_setactivenode__action_25_setactivenode_guard_clause_25_0__false
    method_1ii06co_setactivenode__action_25_setactivenode_guard_clause_25_0__condition -->|exit| method_1ii06co_setactivenode__action_25_setactivenode_guard_clause_25_0__true
    method_1ii06co_setactivenode__action_25_setactivenode_guard_clause_25_0__false -->|next| method_1ii06co_setactivenode__action_25_setactivenode_guard_clause_25_0__merge
    method_1ii06co_setactivenode__action_25_setactivenode_guard_clause_25_0__merge -->|next| method_1ii06co_setactivenode__action_26_state_change_26__linear
    method_1ii06co_setactivenode__action_25_setactivenode_guard_clause_25_0__true -->|next| method_1ii06co_setactivenode__action_25_setactivenode_guard_clause_25_0__merge
    method_1ii06co_setactivenode__action_26_state_change_26__linear -->|next| method_1ii06co_setactivenode__action_27_setactivenode_await_27_2__await
    method_1ii06co_setactivenode__action_27_event_27__linear -->|next| method_1ii06co_setactivenode__action_27_setactivenode_branch_27_1__condition
    method_1ii06co_setactivenode__action_27_setactivenode_await_27_2__await -->|next| method_1ii06co_setactivenode__action_27_event_27__linear
    method_1ii06co_setactivenode__action_27_setactivenode_branch_27_1__condition -->|false| method_1ii06co_setactivenode__action_27_setactivenode_branch_27_1__false
    method_1ii06co_setactivenode__action_27_setactivenode_branch_27_1__condition -->|true| method_1ii06co_setactivenode__action_27_setactivenode_branch_27_1__true
    method_1ii06co_setactivenode__action_27_setactivenode_branch_27_1__false -->|next| method_1ii06co_setactivenode__action_27_setactivenode_branch_27_1__merge
    method_1ii06co_setactivenode__action_27_setactivenode_branch_27_1__merge -->|nodeId string| method_1ii06co_setactivenode__call_27_OnActiveNodeChanged
    method_1ii06co_setactivenode__action_27_setactivenode_branch_27_1__true -->|next| method_1ii06co_setactivenode__action_27_setactivenode_branch_27_1__merge
    method_1ii06co_setactivenode__call_27_OnActiveNodeChanged -->|return| method_1ii06co_setactivenode__implicit_return
    method_1ii06co_setactivenode__entry -->|next| method_1ii06co_setactivenode__action_25_guard_clause_25__condition
```

### SetLoading() Control Flow

```mermaid
flowchart TD
    method_90e1ug_setloading__call_33_OnLoadingChanged[["OnLoadingChanged"]]
    method_90e1ug_setloading__action_32_state_change_32__linear("Set IsLoading")
    method_90e1ug_setloading__action_33_event_33__linear("Notify loading changed")
    method_90e1ug_setloading__action_33_setloading_await_33_1__await[["Waits for async work"]]
    method_90e1ug_setloading__action_33_setloading_branch_33_0__condition{"OnLoadingChanged != null) await OnLoadingChanged(isLoading"}
    method_90e1ug_setloading__action_33_setloading_branch_33_0__false("false")
    method_90e1ug_setloading__action_33_setloading_branch_33_0__merge("merge")
    method_90e1ug_setloading__action_33_setloading_branch_33_0__true("true")
    method_90e1ug_setloading__entry(["SetLoading entry"])
    method_90e1ug_setloading__implicit_return(["return"])
    method_90e1ug_setloading__action_32_state_change_32__linear -->|next| method_90e1ug_setloading__action_33_setloading_await_33_1__await
    method_90e1ug_setloading__action_33_event_33__linear -->|next| method_90e1ug_setloading__action_33_setloading_branch_33_0__condition
    method_90e1ug_setloading__action_33_setloading_await_33_1__await -->|next| method_90e1ug_setloading__action_33_event_33__linear
    method_90e1ug_setloading__action_33_setloading_branch_33_0__condition -->|false| method_90e1ug_setloading__action_33_setloading_branch_33_0__false
    method_90e1ug_setloading__action_33_setloading_branch_33_0__condition -->|true| method_90e1ug_setloading__action_33_setloading_branch_33_0__true
    method_90e1ug_setloading__action_33_setloading_branch_33_0__false -->|next| method_90e1ug_setloading__action_33_setloading_branch_33_0__merge
    method_90e1ug_setloading__action_33_setloading_branch_33_0__merge -->|isLoading bool| method_90e1ug_setloading__call_33_OnLoadingChanged
    method_90e1ug_setloading__action_33_setloading_branch_33_0__true -->|next| method_90e1ug_setloading__action_33_setloading_branch_33_0__merge
    method_90e1ug_setloading__call_33_OnLoadingChanged -->|return| method_90e1ug_setloading__implicit_return
    method_90e1ug_setloading__entry -->|next| method_90e1ug_setloading__action_32_state_change_32__linear
```

### Clear() Control Flow

```mermaid
flowchart TD
    method_ekp9ov_clear__call_41_OnGraphUpdated[["OnGraphUpdated"]]
    method_ekp9ov_clear__action_38_state_change_38__linear("Clear CurrentGraphData")
    method_ekp9ov_clear__action_39_state_change_39__linear("Clear ActiveNodeId")
    method_ekp9ov_clear__action_40_state_change_40__linear("Clear IsLoading")
    method_ekp9ov_clear__action_41_clear_await_41_1__await[["Waits for async work"]]
    method_ekp9ov_clear__action_41_clear_branch_41_0__condition{"OnGraphUpdated != null) await OnGraphUpdated("}
    method_ekp9ov_clear__action_41_clear_branch_41_0__false("false")
    method_ekp9ov_clear__action_41_clear_branch_41_0__merge("merge")
    method_ekp9ov_clear__action_41_clear_branch_41_0__true("true")
    method_ekp9ov_clear__action_41_event_41__linear("Notify graph updated (cleared)")
    method_ekp9ov_clear__entry(["Clear entry"])
    method_ekp9ov_clear__implicit_return(["return"])
    method_ekp9ov_clear__action_38_state_change_38__linear -->|next| method_ekp9ov_clear__action_39_state_change_39__linear
    method_ekp9ov_clear__action_39_state_change_39__linear -->|next| method_ekp9ov_clear__action_40_state_change_40__linear
    method_ekp9ov_clear__action_40_state_change_40__linear -->|next| method_ekp9ov_clear__action_41_clear_await_41_1__await
    method_ekp9ov_clear__action_41_clear_await_41_1__await -->|next| method_ekp9ov_clear__action_41_event_41__linear
    method_ekp9ov_clear__action_41_clear_branch_41_0__condition -->|false| method_ekp9ov_clear__action_41_clear_branch_41_0__false
    method_ekp9ov_clear__action_41_clear_branch_41_0__condition -->|true| method_ekp9ov_clear__action_41_clear_branch_41_0__true
    method_ekp9ov_clear__action_41_clear_branch_41_0__false -->|next| method_ekp9ov_clear__action_41_clear_branch_41_0__merge
    method_ekp9ov_clear__action_41_clear_branch_41_0__merge -->|no args signals graph cleared / updated| method_ekp9ov_clear__call_41_OnGraphUpdated
    method_ekp9ov_clear__action_41_clear_branch_41_0__true -->|next| method_ekp9ov_clear__action_41_clear_branch_41_0__merge
    method_ekp9ov_clear__action_41_event_41__linear -->|next| method_ekp9ov_clear__action_41_clear_branch_41_0__condition
    method_ekp9ov_clear__call_41_OnGraphUpdated -->|return| method_ekp9ov_clear__implicit_return
    method_ekp9ov_clear__entry -->|next| method_ekp9ov_clear__action_38_state_change_38__linear
```

## Diagram Validation

- Status: warn
- Warning: Control-flow extraction left 5 unresolved jumps.
