Composable Visible Views
Graphora can derive an ordered, synchronous filtered view while keeping the engine's source graph intact. This is useful for exploration controls that hide inactive nodes, restrict the graph to one domain, or suppress selected edge types without rebuilding the canonical GraphStore.
const engine = createGraphEngine({
graph,
renderer,
viewFilters: [
{
id: 'active-nodes',
kind: 'node-filter',
predicate: (node) => node.data?.active === true
},
{
id: 'production-edges',
kind: 'edge-filter',
predicate: (edge) => edge.data?.production === true
}
]
})engine.snapshot() always returns the canonical source snapshot. engine.viewSnapshot() returns the current visible snapshot used by engine rendering, picking, and layout. A filtered snapshot includes its stable view ID, view version, evaluated source version, clone-safe viewAdjacency, and frozen provenance arrays that map each visible item back to its source key. The view-specific name keeps these arrays distinct from the Map-based adjacency on core LayoutGraphSnapshot inputs.
Filters run in caller order. A node filter keeps matching nodes and immediately removes edges whose endpoints are no longer visible. An edge filter keeps matching edges without removing their endpoint nodes. Every predicate receives the nodes and edges produced by the previous stage. Predicates must be pure, synchronous, and return a boolean.
Replace or modify the pipeline with setViewFilters, updateViewFilter, and setViewFilterEnabled. refreshView() reevaluates the installed definitions against the latest source snapshot. Source mutations also refresh the view automatically. When visible membership remains the same, the snapshot rebases to the new source records without incrementing the view version.
Failure And Recovery
A failed manual filter replacement leaves the installed pipeline and current snapshot unchanged. If automatic refresh fails after the source changes, the view becomes stale and getViewState() exposes the last committed snapshot, attempted source version, and original error. While stale, viewSnapshot() and layout reject, and engine.pick() returns null so stale renderer state cannot be combined with current provenance.
Resolve the predicate error and call refreshView() (or successfully replace the filter configuration) to make the view current again. The engine retains source-backed selection, focus, and highlight IDs while their items are hidden; they are projected out of render snapshots and reappear if a later view makes them visible.
Current Boundary
This first slice supports node and edge filters only. Grouping, collapse and expand, synthetic nodes and edges, many-source provenance, and synthetic position storage remain separate runtime work. The existing clustering and collapse helpers still produce app-owned RawGraph values rather than joining this filter pipeline.
See examples/vanilla/composable-filters/ for a Canvas example that sends a filtered snapshot through the browser Worker layout, changes the rendered view, and reports source provenance from engine.pick().