# core/plugins/diagram.shell.plugin.ts

> 61 lines of code and 8 definitions.

Tree: GovLab Docs
Language: typescript
Layer: infrastructure
Canonical: https://banes-lab.com/anatomy/docs#file-docs-core-plugins-diagram-shell-plugin-ts
Source text: https://banes-lab.com/source/docs/core/plugins/diagram.shell.plugin.ts.txt

Listed in [core/plugins](https://banes-lab.com/api/source/docs/core/plugins.md), after [core/plugins/diagram.sequence.plugin.ts](https://banes-lab.com/source/docs/core/plugins/diagram.sequence.plugin.ts.md) and before [core/plugins/diagram.structure.plugin.ts](https://banes-lab.com/source/docs/core/plugins/diagram.structure.plugin.ts.md).

## Definitions

- `render` (method_definition, line 41, exported)
- `CLASS_BY_SCRIPT_KIND` (lexical_declaration, line 14)
- `SHAPE_BY_SCRIPT_KIND` (lexical_declaration, line 20)
- `lifecycleNode` (lexical_declaration, line 26)
- `diagram` (lexical_declaration, line 35, exported)
- `appliesTo` (method_definition, line 36, exported)
- `graph` (lexical_declaration, line 45, exported)
- `edges` (lexical_declaration, line 49, exported)

## Contained in

- [core/plugins](https://banes-lab.com/anatomy/docs/folder-docs-core-plugins.md)

## Uses

- [configuration/strings/figure.strings.ts](https://banes-lab.com/source/docs/configuration/strings/figure.strings.ts.md)

## Linked from

- [configuration/strings](https://banes-lab.com/anatomy/docs/folder-docs-configuration-strings.md)

## Source

```typescript
import {
    DIAGRAM_DESCRIPTIONS,
    DIAGRAM_LEGENDS,
    DIAGRAM_TITLES,
    lifecycleTitle,
} from "#configuration/strings/figure.strings";
import type { GraphEdge, GraphNode, NodeShape } from "#types/diagram.types";
import type { ScriptNode, ScriptNodeKind } from "#types/graph.types";
import { CLASS_DEFS } from "#configuration/constants/graph.constants";
import type { DiagramKind } from "#types/figure.types";
import { emitGraph } from "#core/formatters/diagram.formatter";
import { scriptLifecycle } from "#core/converters/package.converter";

const CLASS_BY_SCRIPT_KIND: ReadonlyMap<ScriptNodeKind, string> = new Map<ScriptNodeKind, string>([
    ["script", "kEntry"],
    ["tool", "kCollab"],
    ["file", "kState"],
]);

const SHAPE_BY_SCRIPT_KIND: ReadonlyMap<ScriptNodeKind, NodeShape> = new Map<ScriptNodeKind, NodeShape>([
    ["script", "rect"],
    ["tool", "collaborator"],
    ["file", "rect"],
]);

const lifecycleNode = function lifecycleNode(node: ScriptNode): GraphNode {
    return {
        class: CLASS_BY_SCRIPT_KIND.get(node.kind) ?? "kState",
        id: node.id,
        label: node.label,
        shape: SHAPE_BY_SCRIPT_KIND.get(node.kind) ?? "rect",
    };
};

export const diagram: DiagramKind = {
    appliesTo(context) {
        return Object.keys(context.scripts ?? {}).length > 0;
    },
    id: "lifecycle",
    order: 0,
    render(context) {
        if (!context.scripts || Object.keys(context.scripts).length === 0) {
            return null;
        }
        const graph = scriptLifecycle(context.scripts);
        if (graph.edges.length === 0) {
            return null;
        }
        const edges: GraphEdge[] = graph.edges.map((edge) => ({ from: edge.from, to: edge.to, weight: "call" }));
        return {
            legend: DIAGRAM_LEGENDS.lifecycle,
            mermaid: emitGraph({
                accDescr: DIAGRAM_DESCRIPTIONS.lifecycle,
                accTitle: lifecycleTitle(context.moduleName),
                classDefs: [...CLASS_DEFS],
                direction: "TD",
                edges,
                kind: "flowchart",
                nodes: graph.nodes.map(lifecycleNode),
            }),
            sources: [],
        };
    },
    title: DIAGRAM_TITLES.lifecycle,
};
```
