refactor(javascript): own application node merging in the graph domain

This commit is contained in:
morluto
2026-10-22 11:11:42 +08:00
parent 63fe0eb5db
commit 51e0df97e9
4 changed files with 112 additions and 94 deletions
@@ -1,6 +1,6 @@
import {
createJavaScriptApplicationGraph,
createJavaScriptApplicationNode,
mergeJavaScriptApplicationNodes,
type JavaScriptApplicationGraph,
} from "./javascriptApplicationGraph.js";
import type {
@@ -39,7 +39,7 @@ export interface ReconciledApplicationGraphProjection {
export const buildReconciledApplicationGraph = (
input: ReconciledGraphInput,
): ReconciledApplicationGraphProjection => {
const merged = mergeNodes([
const merged = mergeJavaScriptApplicationNodes([
...input.layers.flatMap(({ graph }) => graph.nodes),
...input.runtime.nodes,
]);
@@ -210,45 +210,6 @@ const graphCoverage = (
limits: [],
};
const mergeNodes = (nodes: readonly ApplicationNode[]): ApplicationNode[] => {
const grouped = new Map<string, ApplicationNode[]>();
for (const node of nodes) {
const group = grouped.get(node.node_id);
if (group === undefined) grouped.set(node.node_id, [node]);
else group.push(node);
}
const merged = [...grouped.values()].map((group) => {
const first = group[0];
if (first === undefined) throw new TypeError("Empty JAG node group");
if (
group.some(
({ kind, identity }) =>
kind !== first.kind ||
JSON.stringify(identity) !== JSON.stringify(first.identity),
)
)
throw new TypeError("Colliding JAG node identifiers disagree");
const observations = [
...new Map(
group
.flatMap(({ observations: values }) => values)
.map((observation) => [observation.observation_id, observation]),
).values(),
].sort((left, right) =>
compareUnicodeCodePoints(left.observation_id, right.observation_id),
);
return createJavaScriptApplicationNode({
kind: first.kind,
identity: first.identity,
observations: observations.map(
({ observation_id: _id, identifier_strategy: _strategy, ...value }) =>
value,
),
});
});
return merged;
};
const uniqueEdges = (edges: readonly ApplicationEdge[]): ApplicationEdge[] => [
...new Map(edges.map((edge) => [edge.edge_id, edge])).values(),
];