@x12i/hybrid-graph
v0.2.0
Published
Tier 2: Edge-native graph database with recursive CTE traversals and referential integrity built on @x12i/hybrid-docstore
Downloads
340
Maintainers
Readme
@x12i/hybrid-graph
The Tier 2 graph layer of the @x12i Edge Data Stack. Sits atop @x12i/hybrid-docstore to provide a graph database interface for Nodes, Edges, and recursive CTE traversals compiled directly to SQLite WITH RECURSIVE queries at the edge.
Features
- Built Atop Tier 1: Does not communicate with D1/R2 directly; uses an instance of
HybridDocStoreto managenodesandedgescollections. - Node Content Offloading: Nodes inherit Tier 1 transparent offloading rules for heavy properties (e.g., node content, documents, media).
- Referential Integrity Cascades: When a node is deleted via
graph.deleteNode(id), all associated incoming and outgoing edges are automatically queried and removed first to prevent dangling edges. - Edge-Native Recursive CTE Traversals: Multi-hop graph discovery is compiled into parameterized SQLite
WITH RECURSIVEqueries executed inside SQLite at the edge, featuring cycle protection (instr(path, ...)). - Traversal Separation: Traversals yield lightweight nodes for relationship discovery; heavy payloads are hydrated as a subsequent step via Tier 1
.withContent(). - Zero-Config .env Support: Automatically connects using the same
.envvariables as@x12i/hybrid-docstore, including an optionalHYBRID_DB_FOLDER.
Quick Start
import { createGraphFromEnv } from '@x12i/hybrid-graph';
// Reads from .env automatically
const graph = await createGraphFromEnv();
// 1. Create Nodes (heavy payload 'content' is offloaded to storage)
const author = await graph.addNode({ label: 'User', name: 'Alice' });
const book = await graph.addNode({
label: 'Book',
title: 'Edge Graph Computing',
content: Buffer.from('Full manuscript chapter 1...'),
});
// 2. Link Nodes
await graph.link(author, book, 'AUTHORED', { year: 2026 });
// 3. Multi-hop Traversal (Recursive CTE executed in SQLite at the edge)
const reachable = await graph.traverse(author, { maxDepth: 3 });
// 4. Subsequent Hydration via Tier 1
const bookNodes = reachable.filter((n) => n.label === 'Book');
const hydratedBooks = await graph.docstore
.collection('nodes', { heavyProperties: ['content'] })
.find({ id: { $in: bookNodes.map((b) => b.id) } })
.withContent(['content']);