Repository: mermaid-js/mermaid
File: packages/mermaid/src/diagrams/treemap/db.ts (TypeScript)

Code before:
import { getConfig as commonGetConfig } from '../../config.js';
import { cleanAndMerge } from '../../utils.js';
import { isLabelStyle } from '../../rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js';
import {
  clear as commonClear,
  getAccDescription,
  getAccTitle,
  getDiagramTitle,
  setAccDescription,
  setAccTitle,
  setDiagramTitle,
} from '../common/commonDb.js';
export class TreeMapDB implements DiagramDB {
  private data: TreemapData;
  private state: ImperativeState<TreemapData>;

  constructor() {
    this.data = {
      nodes: [],
      levels: new Map(),
      outerNodes: [],
      classes: new Map(),
    };

    this.state = new ImperativeState<TreemapData>(() => structuredClone(this.data));
  }

  public getNodes() {
    return this.state.records.nodes;
  }

  public getConfig() {
    // Use type assertion with unknown as intermediate step
    const defaultConfig = DEFAULT_CONFIG as unknown as { treemap: Required<TreemapDiagramConfig> };
    const userConfig = commonGetConfig() as unknown as { treemap?: Partial<TreemapDiagramConfig> };

    return cleanAndMerge({
      ...defaultConfig.treemap,
      ...(userConfig.treemap ?? {}),
    }) as Required<TreemapDiagramConfig>;
  }

  public addNode(node: TreemapNode, level: number) {
    const data = this.state.records;
    data.nodes.push(node);
    data.levels.set(node, level);

    if (level === 0) {
      data.outerNodes.push(node);
    }


Review comment (suggestion):
This is an antipattern for class based diagrams. 
The class itself does the purpose of ImperativeState, and ImperativeState was designed to manage _all_ state, so having `data` outside breaks that pattern. 

For class based diagrams, we just have to write everything as members of the class directly. No need to use ImperativeState, or a `data` object. 

Code after:
import { getConfig as commonGetConfig } from '../../config.js';
import { cleanAndMerge } from '../../utils.js';
import { isLabelStyle } from '../../rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js';
import {
  clear as commonClear,
  getAccDescription,
  getAccTitle,
  getDiagramTitle,
  setAccDescription,
  setAccTitle,
  setDiagramTitle,
} from '../common/commonDb.js';
export class TreeMapDB implements DiagramDB {
  private nodes: TreemapNode[] = [];
  private levels: Map<TreemapNode, number> = new Map<TreemapNode, number>();
  private outerNodes: TreemapNode[] = [];
  private classes: Map<string, DiagramStyleClassDef> = new Map<string, DiagramStyleClassDef>();
  private root?: TreemapNode;

  public getNodes() {
    return this.nodes;
  }

  public getConfig() {
    const defaultConfig = DEFAULT_CONFIG as unknown as { treemap: Required<TreemapDiagramConfig> };
    const userConfig = commonGetConfig() as unknown as { treemap?: Partial<TreemapDiagramConfig> };
    return cleanAndMerge({
      ...defaultConfig.treemap,
      ...(userConfig.treemap ?? {}),
    }) as Required<TreemapDiagramConfig>;
  }

  public addNode(node: TreemapNode, level: number) {
    this.nodes.push(node);
    this.levels.set(node, level);
    if (level === 0) {
      this.outerNodes.push(node);
      this.root ??= node;
    }
  }

  public getRoot() {
    return { name: '', children: this.outerNodes };
  }

  public addClass(id: string, _style: string) {
    const styleClass = this.classes.get(id) ?? { id, styles: [], textStyles: [] };
    const styles = _style.replace(/\\,/g, '§§§').replace(/,/g, ';').replace(/§§§/g, ',').split(';');
    if (styles) {
      styles.forEach((s) => {
        if (isLabelStyle(s)) {