Implementation:TobikoData Sqlmesh Lineage Utils
| Knowledge Sources | |
|---|---|
| Domains | Web_UI, Lineage_Visualization |
| Last Updated | 2026-02-07 20:00 GMT |
Overview
Core type definitions, constants, and ID generation utilities for lineage graph construction in React Flow.
Description
Lineage_Utils provides foundational types and utilities for building lineage visualizations. It defines branded string types for type-safe IDs (NodeId, EdgeId, PortId, HandleId, PortHandleId) using TypeScript's nominal typing pattern. The module includes type definitions for graph elements: LineageNode and LineageEdge extending React Flow types, LineageNodesMap for node storage, LineageAdjacencyList for graph structure, and LineageDetails for node metadata. It exports layout constants including default dimensions (300x32px nodes), zoom levels (0.01-1.75 range, 0.85 default, 0.5 threshold), and performance thresholds (200 nodes). The ID generation functions (toNodeID, toEdgeID, toPortID) use encodeURI and dot-notation joining to create unique identifiers from component parts, warning that these are internal-only and not URL-safe.
Usage
Use this module as the foundation for all lineage graph implementations. Import types for type safety, use ID generators for consistent identification, and reference constants for layout configuration and performance optimization decisions.
Code Reference
Source Location
- Repository: TobikoData_Sqlmesh
- File: web/common/src/components/Lineage/utils.ts
Signature
// Type definitions
export type NodeId = Branded<string, 'NodeId'>
export type EdgeId = Branded<string, 'EdgeId'>
export type PortId = Branded<string, 'PortId'>
export type HandleId = Branded<string, 'HandleId'>
export type PortHandleId = Branded<string, 'PortHandleId'>
export type LineageNodeData = Record<string, unknown>
export type LineageEdgeData = Record<string, unknown>
export type LineageAdjacencyList<TAdjacencyListKey extends string = string> =
Record<TAdjacencyListKey, TAdjacencyListKey[]>
export type LineageDetails<TAdjacencyListKey extends string, TValue> =
Record<TAdjacencyListKey, TValue>
export interface LineageNode<TNodeData extends LineageNodeData, TNodeID extends string = NodeId>
extends Node<TNodeData> {
id: TNodeID
}
export interface LineageEdge<...> extends Edge<TEdgeData> {
id: TEdgeID
source: TSourceID
target: TTargetID
sourceHandle?: TSourceHandleID
targetHandle?: TTargetHandleID
}
export type PathType = 'bezier' | 'smoothstep' | 'step' | 'straight'
// Constants
export const DEFAULT_NODE_HEIGHT = 32
export const DEFAULT_NODE_WIDTH = 300
export const DEFAULT_ZOOM = 0.85
export const MIN_ZOOM = 0.01
export const MAX_ZOOM = 1.75
export const ZOOM_THRESHOLD = 0.5
export const NODES_TRESHOLD = 200
export const NODES_TRESHOLD_ZOOM = 0.1
// ID generators
export function toInternalID<TReturn extends string>(...args: string[]): TReturn
export function toNodeID<TNodeID extends string = NodeId>(...args: string[]): TNodeID
export function toEdgeID<TEdgeID extends string = EdgeId>(...args: string[]): TEdgeID
export function toPortID<TPortId extends string = PortId>(...args: string[]): TPortId
// Transform function types
export type TransformNodeFn<TData, TNodeData extends LineageNodeData, TNodeID extends string> =
(nodeId: TNodeID, data: TData) => LineageNode<TNodeData, TNodeID>
export type TransformEdgeFn<...> = (
edgeType: string,
edgeId: TEdgeID,
sourceId: TSourceID,
targetId: TTargetID,
sourceHandleId?: TSourceHandleID,
targetHandleId?: TTargetHandleID,
) => LineageEdge<...>
Import
import {
type NodeId,
type EdgeId,
type PortId,
type LineageNode,
type LineageEdge,
type LineageNodesMap,
type LineageAdjacencyList,
type PathType,
DEFAULT_NODE_HEIGHT,
DEFAULT_NODE_WIDTH,
DEFAULT_ZOOM,
MIN_ZOOM,
MAX_ZOOM,
ZOOM_THRESHOLD,
toNodeID,
toEdgeID,
toPortID,
} from '@sqlmesh-common/components/Lineage/utils'
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| args (for ID functions) | string[] | Yes | Variable number of string segments to join into ID |
Outputs
| Name | Type | Description |
|---|---|---|
| NodeId | Branded<string> | Type-safe node identifier |
| EdgeId | Branded<string> | Type-safe edge identifier |
| PortId | Branded<string> | Type-safe port identifier |
| generatedId | string | URI-encoded ID from joined segments |
Usage Examples
import {
toNodeID,
toEdgeID,
toPortID,
type LineageNode,
type LineageEdge,
DEFAULT_NODE_WIDTH,
DEFAULT_NODE_HEIGHT,
ZOOM_THRESHOLD,
} from '@sqlmesh-common/components/Lineage/utils'
// Generate type-safe IDs
const nodeId = toNodeID('my_schema', 'my_model')
// Result: "my_schema.my_model" as NodeId
const edgeId = toEdgeID('source_model', 'target_model')
// Result: "source_model.target_model" as EdgeId
const portId = toPortID('model_name', 'column_name')
// Result: "model_name.column_name" as PortId
// Type-safe node creation
const node: LineageNode<{ name: string }, typeof nodeId> = {
id: nodeId,
type: 'model',
position: { x: 0, y: 0 },
data: { name: 'My Model' },
width: DEFAULT_NODE_WIDTH,
height: DEFAULT_NODE_HEIGHT,
}
// Type-safe edge creation
const edge: LineageEdge<{}, typeof edgeId, typeof sourceId, typeof targetId> = {
id: edgeId,
source: toNodeID('source_model'),
target: toNodeID('target_model'),
type: 'gradient',
data: {},
}
// Using constants for layout decisions
function shouldShowDetails(zoom: number): boolean {
return zoom > ZOOM_THRESHOLD // 0.5
}
function getNodeDimensions() {
return {
width: DEFAULT_NODE_WIDTH, // 300
height: DEFAULT_NODE_HEIGHT // 32
}
}
// Performance optimization
function shouldUseSimplifiedRendering(nodeCount: number, zoom: number): boolean {
return nodeCount > NODES_TRESHOLD && zoom < NODES_TRESHOLD_ZOOM
// true if more than 200 nodes and zoom less than 0.1
}
// Adjacency list example
const adjacencyList: LineageAdjacencyList<string> = {
'model_a': ['model_b', 'model_c'],
'model_b': ['model_d'],
'model_c': ['model_d'],
'model_d': []
}
// Details map example
const details: LineageDetails<string, { type: string; owner: string }> = {
'model_a': { type: 'table', owner: 'analytics' },
'model_b': { type: 'view', owner: 'analytics' },
}