@nicia-ai/typegraph 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -3526,9 +3526,6 @@ function defineSubgraphProject(_graph) {
3526
3526
  }
3527
3527
  async function executeSubgraph(params) {
3528
3528
  const { options } = params;
3529
- if (options.edges.length === 0) {
3530
- return { nodes: [], edges: [] };
3531
- }
3532
3529
  const maxDepth = Math.min(
3533
3530
  options.maxDepth ?? DEFAULT_SUBGRAPH_MAX_DEPTH,
3534
3531
  MAX_EXPLICIT_RECURSIVE_DEPTH
@@ -3565,15 +3562,29 @@ async function executeSubgraph(params) {
3565
3562
  fetchSubgraphNodes(ctx, reachableCte, includedIdsCte, nodeProjectionPlan),
3566
3563
  fetchSubgraphEdges(ctx, reachableCte, includedIdsCte, edgeProjectionPlan)
3567
3564
  ]);
3568
- const nodes = nodeRows.map(
3569
- (row) => mapSubgraphNodeRow(row, nodeProjectionPlan)
3570
- );
3571
- const edges = edgeRows.map(
3572
- (row) => mapSubgraphEdgeRow(row, edgeProjectionPlan)
3573
- );
3565
+ const nodesMap = /* @__PURE__ */ new Map();
3566
+ for (const row of nodeRows) {
3567
+ const node = mapSubgraphNodeRow(row, nodeProjectionPlan);
3568
+ nodesMap.set(node.id, node);
3569
+ }
3570
+ const adjacency = /* @__PURE__ */ new Map();
3571
+ const reverseAdjacency = /* @__PURE__ */ new Map();
3572
+ for (const row of edgeRows) {
3573
+ const edge = mapSubgraphEdgeRow(row, edgeProjectionPlan);
3574
+ insertAdjacencyEntry(adjacency, edge.fromId, edge.kind, edge);
3575
+ insertAdjacencyEntry(
3576
+ reverseAdjacency,
3577
+ edge.toId,
3578
+ edge.kind,
3579
+ edge
3580
+ );
3581
+ }
3582
+ const root = nodesMap.get(ctx.rootId);
3574
3583
  return {
3575
- nodes,
3576
- edges
3584
+ root,
3585
+ nodes: nodesMap,
3586
+ adjacency,
3587
+ reverseAdjacency
3577
3588
  };
3578
3589
  }
3579
3590
  var introspectorCache = /* @__PURE__ */ new WeakMap();
@@ -3813,6 +3824,19 @@ function buildProjectedPropertyColumns(alias, plan, dialect) {
3813
3824
  }
3814
3825
  return columns;
3815
3826
  }
3827
+ function insertAdjacencyEntry(index, nodeId, edgeKind, edge) {
3828
+ let kindMap = index.get(nodeId);
3829
+ if (kindMap === void 0) {
3830
+ kindMap = /* @__PURE__ */ new Map();
3831
+ index.set(nodeId, kindMap);
3832
+ }
3833
+ const edges = kindMap.get(edgeKind);
3834
+ if (edges === void 0) {
3835
+ kindMap.set(edgeKind, [edge]);
3836
+ } else {
3837
+ edges.push(edge);
3838
+ }
3839
+ }
3816
3840
  function applyProjectedFields(target, row, kindPlan) {
3817
3841
  for (const fieldPlan of kindPlan.propertyFields) {
3818
3842
  target[fieldPlan.field] = decodeSelectedValue(
@@ -11924,22 +11948,26 @@ var Store = class {
11924
11948
  * Extracts a typed subgraph by traversing from a root node.
11925
11949
  *
11926
11950
  * Performs a BFS traversal from `rootId` following the specified edge kinds,
11927
- * then returns all reachable nodes and the edges connecting them.
11951
+ * returning an indexed result with adjacency maps for immediate traversal.
11928
11952
  *
11929
11953
  * @example
11930
11954
  * ```typescript
11931
- * const result = await store.subgraph(run.id, {
11955
+ * const sg = await store.subgraph(run.id, {
11932
11956
  * edges: ["has_task", "runs_agent", "uses_skill"],
11933
11957
  * maxDepth: 4,
11934
- * includeKinds: ["Run", "Task", "Agent", "Skill"],
11935
11958
  * });
11936
11959
  *
11937
- * for (const node of result.nodes) {
11938
- * switch (node.kind) {
11939
- * case "Task": console.log(node.name); break;
11940
- * case "Agent": console.log(node.model); break;
11941
- * }
11942
- * }
11960
+ * // Root node (the traversal starting point)
11961
+ * console.log(sg.root?.kind);
11962
+ *
11963
+ * // Lookup by ID
11964
+ * const task = sg.nodes.get(taskId);
11965
+ *
11966
+ * // Forward adjacency: edges of a kind from a node
11967
+ * const taskEdges = sg.adjacency.get(run.id)?.get("has_task") ?? [];
11968
+ *
11969
+ * // Reverse adjacency: edges of a kind pointing to a node
11970
+ * const parentEdges = sg.reverseAdjacency.get(taskId)?.get("has_task") ?? [];
11943
11971
  * ```
11944
11972
  */
11945
11973
  async subgraph(rootId, options) {