Внутреннее устройство репозитория — как файлы связаны и в каком порядке выполняется пайплайн. Про фичи и семантику диаграмм смотри README.md, здесь — только "как это работает изнутри".
Обновляй этот файл, если правка меняет что-то из описанного ниже: порядок стадий в
index.mjs, состав промежуточных структур (funcs / varDefs / peripherals / fileRecords),
формат graph-data.js, связь source ↔ generated файлов, или сам факт разбиения на файлы.
Небольшие правки внутри одной стадии (новый паттерн парсинга, новый tier, изменение верстки
страницы) документировать здесь не нужно — это и так видно из кода.
Файл — линейный скрипт ~1800 строк, не разбитый на модули; функции выше по файлу — примитивы (обход AST, работа со строками), ниже — стадии, которые используют накопленное состояние. Порядок выполнения:
-
Parse (
walkDir,extractIncludes,extractFunctions,extractFileScopeVars,buildCommentIndex/docCommentFor) — tree-sitter парсит каждый файл; комментарии индексируются отдельно и приклеиваются к соседней декларации. -
Analyze (
analyzeFunction,buildCfg,classifyAccess,resolveVar,periph,isrBaseName) — по каждой функции строится CFG и множество read/write обращений к глобалам; имена резолвятся в ключи черезfuncKey/resolveVar; макро-периферия (X->field, не резолвящаяся в реальную переменную) распознаётся отдельно от обычных globals. Результат копится в module-levelMapах:funcs,varDefs,peripherals,fileRecords. -
Score/tier (
varTier,sizeTier,fnClass,varClass) — на основе накопленных связей считается важность переменной (кол-во читателей/писателей) для визуальных tier'ов. -
Build diagrams (
build*Diagram— overview/aggregate/include/file/level0/function/cfg, все async) — каждая функция берёт срез изfuncs/varDefs/peripheralsи генерирует DOT через общие эмиттеры (dotFnNode/dotVarNode/dotPeriphNode/dotFileNode/dotEdge/..., рядом сbuildLevel0Diagram), затемrenderDotAllсчитает раскладку на сборке через WASM (@hpcc-js/wasm-graphviz) сразу всеми движками изLEVEL0_ENGINES(neato/dot/fdp). Все семь типов диаграмм — на graphviz; выбор движка по умолчанию зависит от формы графа, не единый для всех: file/level0/overview —neato(хаб-структуры, циклы через периферию, ранговая раскладка сминает их в столбцы), include/function/cfg —dot(файлы/вызовы/control-flow — DAG с одной точкой входа или явной иерархией, ранговая раскладка тут как раз к месту). Переключение движка в браузере (setupEngineSwitchableвviewer.js) — подмена уже готового SVG, не пересчёт. Раньше большие file-диаграммы сворачивались в кликабельные grey-box группы (groupedDiagramBlock/setupGroupedDiagram) — эта механика убрана вместе с переходом file-диаграмм на graphviz: он не упирается в то же ограничение по размеру, что раньше было у ELK, так что сворачивать стало незачем. -
Render —
htmlPage/diagramBlockSvgоборачивают diagram-код в HTML; в конце скрипта (после определения всех функций) идут три плоских блока без обёртки в function: записьgraph-data.js(per-node metadata для тултипов),index.html, по одной странице на файл и на функцию вfilesDir/funcsDir.mermaid+ELK полностью убраны (были рантаймом в
viewer.jsдо перехода всех диаграмм на graphviz): нет ни зависимостей (mermaid/@mermaid-js/layout-elk/esbuild), ниviewer-entry.mjs/dist/, ни копированияmermaid-elk.min.jsв сгенерированный сайт.
Всё состояние — module-level переменные, а не передаваемые аргументы; стадии друг за другом читают то, что накопили предыдущие. Добавлять новую стадию — значит вставлять код в нужную точку этой последовательности, а не создавать отдельный файл.
viewer.js— исходник клиентского runtime (hover, pin, zoom, breadcrumbs).graph-html/app.js— это копияviewer.js, сделаннаяfs.copyFileSyncв концеindex.mjsпри генерации примера вgraph-html/. Править надо толькоviewer.js;graph-html/app.jsперезатирается при следующей генерации и не должен расходиться с ним.graph-html/целиком — закоммиченный пример вывода инструмента (сгенерированный сайт), не исходный код.graph-html/index.html,graph-html/graph-data.js— артефакты, не редактируются руками.codegraph.ps1/codegraph.cmd— самостоятельный drop-in лаунчер для чужих проектов: клонирует этот репозиторий в%LOCALAPPDATA%\code-graph, ставит зависимости и запускаетnode index.mjs. Он не импортирует ничего из этого репо напрямую — держи в уме, что правки в способе вызоваindex.mjs(аргументы, порядок) нужно синхронизировать вручную.
graph-data.js— единственный мост между build-time (index.mjs) и runtime (viewer.js): плоскийwindow.GRAPH.nodes, ключ — id ноды (fnId/varId/periphId/file_<name>), значение — всё нужное для тултипа. Если добавляешь новое поле для тултипа, оно должно появиться и здесь (в блоке "graph-data.js" вindex.mjs), и в чтении на сторонеviewer.js.- Каждая HTML-страница самодостаточна: уже готовый SVG инлайнится прямо в разметку
(
diagramBlockSvg), плюс скрытый<script type="application/json" class="engine-data">с SVG остальных движков для мгновенного переключения в браузере.app.js/graph-data.js— общие ассеты между страницами; у graphviz-диаграмм собственного бандла в браузере нет —@hpcc-js/wasm-graphvizнужен только на сборке (в Node), не подключается ни на одной странице.