How to Compare Two Diagram Snapshots in Archify: A Complete Guide to the Diff Engine
Archify compares two diagram snapshots by exporting structured JSON graph states via exportSnapshot() and reachabilitySnapshot(), then computing a deterministic client-side diff of node IDs and edges to highlight structural changes.
The tt-a1i/archify repository implements a client-side architecture visualization tool that enables engineers to analyze system topology and traffic patterns. When you need to compare two diagram snapshots in Archify, the platform executes a three-stage pipeline that captures graph states, computes differentials, and renders visual changes without requiring a server round-trip.
The Three-Stage Comparison Pipeline
Archify’s snapshot comparison is architected as a pure data-driven diff that operates entirely within the browser. The process unfolds through distinct phases of data extraction, algorithmic comparison, and UI rendering.
Stage 1: Exporting Structured Snapshots
The comparison begins by serializing the current graph state into a portable JSON format. Archify exposes specialized export methods depending on the lens context:
Archify.routeProbe.exportSnapshot(): Captures the current route-focused view, including the ordered list of node IDs, edge arrays withfromandtoindices, hop counts, and source/target identifiers.Archify.focus.reachabilitySnapshot(): Exports reachability data for upstream or downstream analysis, containing directionality flags, depth parameters, and the subgraph’s node-edge topology.
Before any comparison occurs, Archify validates the exported payload. In experiments/mco-showcase/mco-runtime.html (lines 5805‑5811), the runtime verifies that the snapshot object contains the expected schema—specifically checking for the presence of nodeIds and edges arrays—to prevent malformed data from entering the diff engine.
Stage 2: Computing the Differential
Once two snapshots are available, Archify’s core comparison algorithm executes a set-based diff on the graph structures:
- Edge Normalization: The algorithm maps each snapshot’s edge array into normalized strings using
nodeIdslookups (e.g.,${nodeIds[from]}→${nodeIds[to]}), creating comparable edge signatures. - Set Operations: It constructs
Setobjects for both snapshots’ edges and performs intersection and difference operations to classify elements as added, removed, or unchanged. - Semantic Filtering: When the user selects the Compare lens with two semantic kinds, the diff limits results to direct authored links between those kinds. Selecting a single kind displays the full traffic pattern for that entity.
This approach ensures that even large architecture diagrams can be compared in milliseconds, as the complexity scales linearly with the number of edges rather than requiring expensive graph isomorphism calculations.
Stage 3: Rendering the Visual Diff
The computed diff drives the visualization layer through specific UI hooks. In experiments/mco-showcase/mco-runtime.html (lines 6824‑6833), the codebase invokes viewerCount('viewer.lens.compare', ...) to update the interface with counts of changed elements.
The rendering engine applies data attributes such as data-share-route and data-share-reach to diagram nodes, enabling CSS to style additions, deletions, and unchanged elements with distinct visual treatments. Added edges typically render in highlight colors, removed edges are dimmed, and stable structures retain their standard styling.
Key Source Files and Implementation Details
Several critical locations in the tt-a1i/archify repository define the snapshot comparison behavior:
experiments/mco-showcase/mco-runtime.html(lines 5805‑5811): Validates route snapshots before they can be used in comparison operations, ensuring schema compliance.experiments/mco-showcase/mco-runtime.html(lines 6824‑6833): Implements the UI counters for the compare lens, displaying the volume of structural changes to the user.scripts/write-deterministic-zip.mjs: Ensures consistent file ordering in exported archives, which guarantees that snapshots produce identical checksums when no changes have occurred.scripts/package-smoke.mjs: Executes thearchify comparecommand in the test harness, providing end-to-end validation of the snapshot diff functionality.
Practical Implementation: Comparing Snapshots in Code
The following JavaScript demonstrates the client-side pattern for generating and comparing Archify snapshots:
// Generate snapshots from the current viewer state
const routeSnapshot = Archify.routeProbe?.exportSnapshot?.();
const reachSnapshot = Archify.focus?.reachabilitySnapshot?.();
// Validate snapshot structure (as seen in mco-runtime.html)
function validateSnapshot(snap) {
return snap
&& Array.isArray(snap.nodeIds)
&& Array.isArray(snap.edges)
&& snap.edges.every(e => typeof e.from === 'number' && typeof e.to === 'number');
}
// Compute differential between two snapshots
function compareSnapshots(snapA, snapB) {
const normalizeEdge = e => `${snapA.nodeIds[e.from]}→${snapA.nodeIds[e.to]}`;
const normalizeEdgeB = e => `${snapB.nodeIds[e.from]}→${snapB.nodeIds[e.to]}`;
const setA = new Set(snapA.edges.map(normalizeEdge));
const setB = new Set(snapB.edges.map(normalizeEdgeB));
return {
added: [...setB].filter(e => !setA.has(e)),
removed: [...setA].filter(e => !setB.has(e)),
unchanged: [...setA].filter(e => setB.has(e))
};
}
// Update UI with comparison results
if (validateSnapshot(routeSnapshot) && validateSnapshot(reachSnapshot)) {
const diff = compareSnapshots(routeSnapshot, reachSnapshot);
viewerCount('viewer.lens.compare', diff.added.length + diff.removed.length);
renderDiffOnDiagram(diff);
}
Summary
- Archify’s comparison engine relies on
exportSnapshot()andreachabilitySnapshot()methods to serialize graph states into standardized JSON structures. - The diff algorithm operates client-side by comparing normalized edge signatures derived from
nodeIdsarrays, classifying changes as added, removed, or unchanged. - Validation logic in
mco-runtime.html(lines 5805‑5811) ensures data integrity before comparison, while UI counters (lines 6824‑6833) display the magnitude of detected changes. - The system supports semantic-kind filtering, allowing comparisons to focus on specific relationship types when two kinds are selected in the compare lens.
- All processing occurs without server dependencies, making the tool suitable for offline analysis of sensitive architecture diagrams.
Frequently Asked Questions
What data structure does an Archify snapshot use?
An Archify snapshot is a plain JavaScript object containing an array of nodeIds (strings) and an edges array where each element specifies from and to indices that reference positions in the nodeIds array. Route snapshots additionally include hop, source, and target properties, while reachability snapshots contain direction and depth metadata.
How does Archify validate snapshots before comparison?
According to the source code in experiments/mco-showcase/mco-runtime.html (lines 5805‑5811), the validation routine checks that the input is a non-null object containing array properties for nodeIds and edges, and verifies that every edge object has numeric from and to properties. This schema validation prevents runtime errors during the diff computation.
Can Archify compare snapshots from different diagram types?
Yes, provided both snapshots conform to the expected schema. The comparison algorithm is agnostic to the semantic meaning of the diagram; it only compares the graph topology (nodes and edges). However, the Compare lens in the UI may filter results to show only direct links between selected semantic kinds, which could yield empty results if the snapshots contain no overlapping relationship types.
Where is the comparison logic located in the source code?
The core comparison routines are implemented in experiments/mco-showcase/mco-runtime.html, specifically around lines 6824‑6833 where the viewerCount function handles the compare lens counts. The underlying snapshot generation methods are attached to the global Archify object (via routeProbe and focus namespaces), while build-time consistency checks reside in scripts/write-deterministic-zip.mjs and scripts/package-smoke.mjs.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →