@nicia-ai/typegraph 0.19.0 → 0.20.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.d.cts CHANGED
@@ -3,8 +3,8 @@ import { N as NodeType, E as EdgeType } from './types-DMzKq0d5.cjs';
3
3
  export { A as AnyEdgeType, C as Cardinality, a as Collation, D as DeleteBehavior, b as EdgeId, c as EdgeProps, d as EdgeRegistration, e as EdgeTypeWithEndpoints, f as EndpointExistence, G as GraphDefaults, g as NodeId, h as NodeProps, i as NodeRegistration, S as SqlDialect, T as TemporalMode, U as UniqueConstraint, j as UniquenessScope, k as isEdgeType, l as isEdgeTypeWithEndpoints, m as isNodeType } from './types-DMzKq0d5.cjs';
4
4
  import { I as InferenceType, M as MetaEdge, O as OntologyRelation } from './types-B3mmOMJV.cjs';
5
5
  export { D as DEFAULT_SQL_SCHEMA, G as GraphBackend, a as MetaEdgeProperties, S as SqlSchema, b as SqlTableNames, T as TransactionBackend, c as createSqlSchema, i as isMetaEdge } from './types-B3mmOMJV.cjs';
6
- import { A as AliasMap, E as EdgeAliasMap, Q as QueryBuilder, T as TraversalBuilder, C as CreateQueryBuilderOptions } from './store-BnUu4qo5.cjs';
7
- export { a as AggregateResult, b as AnyEdge, c as AnyNode, B as BatchResults, d as BatchableQuery, e as ConstraintNames, f as CreateEdgeInput, g as CreateNodeInput, D as DynamicEdgeCollection, h as DynamicNodeCollection, i as Edge, j as EdgeAccessor, k as EdgeCollection, l as EdgeFindByEndpointsOptions, m as EdgeGetOrCreateByEndpointsOptions, n as EdgeGetOrCreateByEndpointsResult, o as EmbeddingSchema, p as EmbeddingValue, q as ExecutableAggregateQuery, r as ExecutableQuery, F as FieldAccessor, G as GetOrCreateAction, s as GraphEdgeCollections, t as GraphNodeCollections, H as HookContext, I as IfExistsMode, N as Node, u as NodeAccessor, v as NodeAlias, w as NodeCollection, x as NodeGetOrCreateByConstraintOptions, y as NodeGetOrCreateByConstraintResult, z as NodeRef, O as OperationHookContext, P as PaginateOptions, J as PaginatedResult, K as Predicate, L as PreparedQuery, M as PropsAccessor, R as QueryHookContext, S as QueryOptions, U as RecursiveTraversalOptions, V as SelectContext, W as SelectableEdge, X as SelectableNode, Y as Store, Z as StoreHooks, _ as StoreOptions, $ as StoreProjection, a0 as StreamOptions, a1 as SubgraphEdgeResult, a2 as SubgraphNodeResult, a3 as SubgraphOptions, a4 as SubgraphResult, a5 as SubsetEdge, a6 as SubsetNode, a7 as TransactionContext, a8 as TypedEdgeCollection, a9 as UnionableQuery, aa as UpdateEdgeInput, ab as UpdateNodeInput, ac as createStore, ad as createStoreWithSchema, ae as defineSubgraphProject, af as embedding, ag as exists, ah as fieldRef, ai as getEmbeddingDimensions, aj as inSubquery, ak as isEmbeddingSchema, al as isParameterRef, am as notExists, an as notInSubquery, ao as param } from './store-BnUu4qo5.cjs';
6
+ import { A as AliasMap, E as EdgeAliasMap, Q as QueryBuilder, T as TraversalBuilder, C as CreateQueryBuilderOptions } from './store-DRRvALu8.cjs';
7
+ export { a as AggregateResult, b as AlgorithmCyclePolicy, c as AnyEdge, d as AnyNode, B as BaseTraversalOptions, e as BatchResults, f as BatchableQuery, g as ConstraintNames, h as CreateEdgeInput, i as CreateNodeInput, D as DegreeOptions, j as DynamicEdgeCollection, k as DynamicNodeCollection, l as Edge, m as EdgeAccessor, n as EdgeCollection, o as EdgeFindByEndpointsOptions, p as EdgeGetOrCreateByEndpointsOptions, q as EdgeGetOrCreateByEndpointsResult, r as EmbeddingSchema, s as EmbeddingValue, t as ExecutableAggregateQuery, u as ExecutableQuery, F as FieldAccessor, G as GetOrCreateAction, v as GraphAlgorithms, w as GraphEdgeCollections, x as GraphNodeCollections, H as HookContext, I as IfExistsMode, N as NeighborsOptions, y as Node, z as NodeAccessor, J as NodeAlias, K as NodeCollection, L as NodeGetOrCreateByConstraintOptions, M as NodeGetOrCreateByConstraintResult, O as NodeIdentifier, P as NodeRef, R as OperationHookContext, S as PaginateOptions, U as PaginatedResult, V as PathNode, W as Predicate, X as PreparedQuery, Y as PropsAccessor, Z as QueryHookContext, _ as QueryOptions, $ as ReachableNode, a0 as ReachableOptions, a1 as RecursiveTraversalOptions, a2 as SelectContext, a3 as SelectableEdge, a4 as SelectableNode, a5 as ShortestPathOptions, a6 as ShortestPathResult, a7 as Store, a8 as StoreHooks, a9 as StoreOptions, aa as StoreProjection, ab as StreamOptions, ac as SubgraphEdgeResult, ad as SubgraphNodeResult, ae as SubgraphOptions, af as SubgraphResult, ag as SubsetEdge, ah as SubsetNode, ai as TemporalAlgorithmOptions, aj as TransactionContext, ak as TraversalDirection, al as TypedEdgeCollection, am as UnionableQuery, an as UpdateEdgeInput, ao as UpdateNodeInput, ap as createStore, aq as createStoreWithSchema, ar as defineSubgraphProject, as as embedding, at as exists, au as fieldRef, av as getEmbeddingDimensions, aw as inSubquery, ax as isEmbeddingSchema, ay as isParameterRef, az as notExists, aA as notInSubquery, aB as param } from './store-DRRvALu8.cjs';
8
8
  import { G as GraphDef, K as KindRegistry } from './manager-Bj1UEnhE.cjs';
9
9
  export { A as AllEdgeTypes, a as AllNodeTypes, E as EdgeKinds, b as GetEdgeType, c as GetNodeType, N as NodeKinds, S as SchemaManagerOptions, d as SchemaValidationResult, e as defineGraph, g as getEdgeKinds, f as getNodeKinds, i as isGraphDef } from './manager-Bj1UEnhE.cjs';
10
10
  export { B as BackendDisposedError, C as CardinalityError, a as CompilerInvariantError, b as ConfigurationError, D as DatabaseOperationError, c as DisjointError, E as EdgeNotFoundError, d as EndpointError, e as EndpointNotFoundError, f as ErrorCategory, K as KindNotFoundError, M as MigrationError, N as NodeConstraintNotFoundError, g as NodeNotFoundError, R as RestrictedDeleteError, S as SchemaMismatchError, T as TypeGraphError, h as TypeGraphErrorOptions, U as UniquenessError, i as UnsupportedPredicateError, V as ValidationError, j as ValidationErrorDetails, k as ValidationIssue, l as VersionConflictError, m as getErrorSuggestion, n as isConstraintError, o as isSystemError, p as isTypeGraphError, q as isUserRecoverable } from './index-DXkEXpNz.cjs';
package/dist/index.d.ts CHANGED
@@ -3,8 +3,8 @@ import { N as NodeType, E as EdgeType } from './types-DMzKq0d5.js';
3
3
  export { A as AnyEdgeType, C as Cardinality, a as Collation, D as DeleteBehavior, b as EdgeId, c as EdgeProps, d as EdgeRegistration, e as EdgeTypeWithEndpoints, f as EndpointExistence, G as GraphDefaults, g as NodeId, h as NodeProps, i as NodeRegistration, S as SqlDialect, T as TemporalMode, U as UniqueConstraint, j as UniquenessScope, k as isEdgeType, l as isEdgeTypeWithEndpoints, m as isNodeType } from './types-DMzKq0d5.js';
4
4
  import { I as InferenceType, M as MetaEdge, O as OntologyRelation } from './types-ThB4cFLp.js';
5
5
  export { D as DEFAULT_SQL_SCHEMA, G as GraphBackend, a as MetaEdgeProperties, S as SqlSchema, b as SqlTableNames, T as TransactionBackend, c as createSqlSchema, i as isMetaEdge } from './types-ThB4cFLp.js';
6
- import { A as AliasMap, E as EdgeAliasMap, Q as QueryBuilder, T as TraversalBuilder, C as CreateQueryBuilderOptions } from './store-CCOwNft_.js';
7
- export { a as AggregateResult, b as AnyEdge, c as AnyNode, B as BatchResults, d as BatchableQuery, e as ConstraintNames, f as CreateEdgeInput, g as CreateNodeInput, D as DynamicEdgeCollection, h as DynamicNodeCollection, i as Edge, j as EdgeAccessor, k as EdgeCollection, l as EdgeFindByEndpointsOptions, m as EdgeGetOrCreateByEndpointsOptions, n as EdgeGetOrCreateByEndpointsResult, o as EmbeddingSchema, p as EmbeddingValue, q as ExecutableAggregateQuery, r as ExecutableQuery, F as FieldAccessor, G as GetOrCreateAction, s as GraphEdgeCollections, t as GraphNodeCollections, H as HookContext, I as IfExistsMode, N as Node, u as NodeAccessor, v as NodeAlias, w as NodeCollection, x as NodeGetOrCreateByConstraintOptions, y as NodeGetOrCreateByConstraintResult, z as NodeRef, O as OperationHookContext, P as PaginateOptions, J as PaginatedResult, K as Predicate, L as PreparedQuery, M as PropsAccessor, R as QueryHookContext, S as QueryOptions, U as RecursiveTraversalOptions, V as SelectContext, W as SelectableEdge, X as SelectableNode, Y as Store, Z as StoreHooks, _ as StoreOptions, $ as StoreProjection, a0 as StreamOptions, a1 as SubgraphEdgeResult, a2 as SubgraphNodeResult, a3 as SubgraphOptions, a4 as SubgraphResult, a5 as SubsetEdge, a6 as SubsetNode, a7 as TransactionContext, a8 as TypedEdgeCollection, a9 as UnionableQuery, aa as UpdateEdgeInput, ab as UpdateNodeInput, ac as createStore, ad as createStoreWithSchema, ae as defineSubgraphProject, af as embedding, ag as exists, ah as fieldRef, ai as getEmbeddingDimensions, aj as inSubquery, ak as isEmbeddingSchema, al as isParameterRef, am as notExists, an as notInSubquery, ao as param } from './store-CCOwNft_.js';
6
+ import { A as AliasMap, E as EdgeAliasMap, Q as QueryBuilder, T as TraversalBuilder, C as CreateQueryBuilderOptions } from './store-BMrRi_mY.js';
7
+ export { a as AggregateResult, b as AlgorithmCyclePolicy, c as AnyEdge, d as AnyNode, B as BaseTraversalOptions, e as BatchResults, f as BatchableQuery, g as ConstraintNames, h as CreateEdgeInput, i as CreateNodeInput, D as DegreeOptions, j as DynamicEdgeCollection, k as DynamicNodeCollection, l as Edge, m as EdgeAccessor, n as EdgeCollection, o as EdgeFindByEndpointsOptions, p as EdgeGetOrCreateByEndpointsOptions, q as EdgeGetOrCreateByEndpointsResult, r as EmbeddingSchema, s as EmbeddingValue, t as ExecutableAggregateQuery, u as ExecutableQuery, F as FieldAccessor, G as GetOrCreateAction, v as GraphAlgorithms, w as GraphEdgeCollections, x as GraphNodeCollections, H as HookContext, I as IfExistsMode, N as NeighborsOptions, y as Node, z as NodeAccessor, J as NodeAlias, K as NodeCollection, L as NodeGetOrCreateByConstraintOptions, M as NodeGetOrCreateByConstraintResult, O as NodeIdentifier, P as NodeRef, R as OperationHookContext, S as PaginateOptions, U as PaginatedResult, V as PathNode, W as Predicate, X as PreparedQuery, Y as PropsAccessor, Z as QueryHookContext, _ as QueryOptions, $ as ReachableNode, a0 as ReachableOptions, a1 as RecursiveTraversalOptions, a2 as SelectContext, a3 as SelectableEdge, a4 as SelectableNode, a5 as ShortestPathOptions, a6 as ShortestPathResult, a7 as Store, a8 as StoreHooks, a9 as StoreOptions, aa as StoreProjection, ab as StreamOptions, ac as SubgraphEdgeResult, ad as SubgraphNodeResult, ae as SubgraphOptions, af as SubgraphResult, ag as SubsetEdge, ah as SubsetNode, ai as TemporalAlgorithmOptions, aj as TransactionContext, ak as TraversalDirection, al as TypedEdgeCollection, am as UnionableQuery, an as UpdateEdgeInput, ao as UpdateNodeInput, ap as createStore, aq as createStoreWithSchema, ar as defineSubgraphProject, as as embedding, at as exists, au as fieldRef, av as getEmbeddingDimensions, aw as inSubquery, ax as isEmbeddingSchema, ay as isParameterRef, az as notExists, aA as notInSubquery, aB as param } from './store-BMrRi_mY.js';
8
8
  import { G as GraphDef, K as KindRegistry } from './manager-Chhrq1vl.js';
9
9
  export { A as AllEdgeTypes, a as AllNodeTypes, E as EdgeKinds, b as GetEdgeType, c as GetNodeType, N as NodeKinds, S as SchemaManagerOptions, d as SchemaValidationResult, e as defineGraph, g as getEdgeKinds, f as getNodeKinds, i as isGraphDef } from './manager-Chhrq1vl.js';
10
10
  export { B as BackendDisposedError, C as CardinalityError, a as CompilerInvariantError, b as ConfigurationError, D as DatabaseOperationError, c as DisjointError, E as EdgeNotFoundError, d as EndpointError, e as EndpointNotFoundError, f as ErrorCategory, K as KindNotFoundError, M as MigrationError, N as NodeConstraintNotFoundError, g as NodeNotFoundError, R as RestrictedDeleteError, S as SchemaMismatchError, T as TypeGraphError, h as TypeGraphErrorOptions, U as UniquenessError, i as UnsupportedPredicateError, V as ValidationError, j as ValidationErrorDetails, k as ValidationIssue, l as VersionConflictError, m as getErrorSuggestion, n as isConstraintError, o as isSystemError, p as isTypeGraphError, q as isUserRecoverable } from './index-DXkEXpNz.js';
package/dist/index.js CHANGED
@@ -3451,6 +3451,116 @@ function decodeByValueType(value, valueType) {
3451
3451
  }
3452
3452
  }
3453
3453
  }
3454
+ function buildReachableCte(options) {
3455
+ const trackPath = options.cyclePolicy === "prevent" || options.includePath;
3456
+ const edgeKindFilter = compileKindFilter(
3457
+ sql.raw("e.kind"),
3458
+ options.edgeKinds
3459
+ );
3460
+ const currentTimestamp = options.dialect.currentTimestamp();
3461
+ const nodeTemporalFilter = compileTemporalFilter({
3462
+ mode: options.temporalMode,
3463
+ asOf: options.asOf,
3464
+ tableAlias: "n",
3465
+ currentTimestamp
3466
+ });
3467
+ const edgeTemporalFilter = compileTemporalFilter({
3468
+ mode: options.temporalMode,
3469
+ asOf: options.asOf,
3470
+ tableAlias: "e",
3471
+ currentTimestamp
3472
+ });
3473
+ const initialPath = trackPath ? options.dialect.initializePath(sql.raw("n.id")) : void 0;
3474
+ const pathExtension = trackPath ? options.dialect.extendPath(sql.raw("r.path"), sql.raw("n.id")) : void 0;
3475
+ const cycleCheck = options.cyclePolicy === "prevent" ? options.dialect.cycleCheck(sql.raw("n.id"), sql.raw("r.path")) : void 0;
3476
+ const baseColumns = [sql`n.id`, sql`n.kind`, sql`0 AS depth`];
3477
+ if (initialPath !== void 0) {
3478
+ baseColumns.push(sql`${initialPath} AS path`);
3479
+ }
3480
+ const baseCase = sql`SELECT ${sql.join(baseColumns, sql`, `)} FROM ${options.schema.nodesTable} n WHERE n.graph_id = ${options.graphId} AND n.id = ${options.sourceId} AND ${nodeTemporalFilter}`;
3481
+ const recursiveColumns = [
3482
+ sql`n.id`,
3483
+ sql`n.kind`,
3484
+ sql`r.depth + 1 AS depth`
3485
+ ];
3486
+ if (pathExtension !== void 0) {
3487
+ recursiveColumns.push(sql`${pathExtension} AS path`);
3488
+ }
3489
+ const recursiveWhere = [
3490
+ sql`e.graph_id = ${options.graphId}`,
3491
+ edgeKindFilter,
3492
+ edgeTemporalFilter,
3493
+ nodeTemporalFilter,
3494
+ sql`r.depth < ${options.maxHops}`
3495
+ ];
3496
+ if (cycleCheck !== void 0) recursiveWhere.push(cycleCheck);
3497
+ const forceWorktableOuterJoinOrder = options.dialect.capabilities.forceRecursiveWorktableOuterJoinOrder;
3498
+ const recursiveCase = compileRecursiveBranch({
3499
+ recursiveColumns,
3500
+ whereClauses: recursiveWhere,
3501
+ direction: options.direction,
3502
+ forceWorktableOuterJoinOrder,
3503
+ schema: options.schema
3504
+ });
3505
+ return sql`WITH RECURSIVE reachable AS (${baseCase} UNION ALL ${recursiveCase})`;
3506
+ }
3507
+ function compileRecursiveBranch(options) {
3508
+ const selectClause = sql`SELECT ${sql.join([...options.recursiveColumns], sql`, `)}`;
3509
+ switch (options.direction) {
3510
+ case "out": {
3511
+ return buildDirectionalBranch({
3512
+ selectClause,
3513
+ whereClauses: options.whereClauses,
3514
+ joinField: "from_id",
3515
+ targetField: "to_id",
3516
+ targetKindField: "to_kind",
3517
+ forceWorktableOuterJoinOrder: options.forceWorktableOuterJoinOrder,
3518
+ schema: options.schema
3519
+ });
3520
+ }
3521
+ case "in": {
3522
+ return buildDirectionalBranch({
3523
+ selectClause,
3524
+ whereClauses: options.whereClauses,
3525
+ joinField: "to_id",
3526
+ targetField: "from_id",
3527
+ targetKindField: "from_kind",
3528
+ forceWorktableOuterJoinOrder: options.forceWorktableOuterJoinOrder,
3529
+ schema: options.schema
3530
+ });
3531
+ }
3532
+ case "both": {
3533
+ return buildBidirectionalBranch({
3534
+ selectClause,
3535
+ whereClauses: options.whereClauses,
3536
+ forceWorktableOuterJoinOrder: options.forceWorktableOuterJoinOrder,
3537
+ schema: options.schema
3538
+ });
3539
+ }
3540
+ }
3541
+ }
3542
+ function buildDirectionalBranch(options) {
3543
+ const nodeJoin = sql`JOIN ${options.schema.nodesTable} n ON n.graph_id = e.graph_id AND n.id = e.${sql.raw(options.targetField)} AND n.kind = e.${sql.raw(options.targetKindField)}`;
3544
+ if (options.forceWorktableOuterJoinOrder) {
3545
+ const allWhere = [
3546
+ ...options.whereClauses,
3547
+ sql`e.${sql.raw(options.joinField)} = r.id`
3548
+ ];
3549
+ return sql`${options.selectClause} FROM reachable r CROSS JOIN ${options.schema.edgesTable} e ${nodeJoin} WHERE ${sql.join(allWhere, sql` AND `)}`;
3550
+ }
3551
+ return sql`${options.selectClause} FROM reachable r JOIN ${options.schema.edgesTable} e ON e.${sql.raw(options.joinField)} = r.id ${nodeJoin} WHERE ${sql.join([...options.whereClauses], sql` AND `)}`;
3552
+ }
3553
+ function buildBidirectionalBranch(options) {
3554
+ const nodeJoin = sql`JOIN ${options.schema.nodesTable} n ON n.graph_id = e.graph_id AND ((e.to_id = r.id AND n.id = e.from_id AND n.kind = e.from_kind) OR (e.from_id = r.id AND n.id = e.to_id AND n.kind = e.to_kind))`;
3555
+ if (options.forceWorktableOuterJoinOrder) {
3556
+ const allWhere = [
3557
+ ...options.whereClauses,
3558
+ sql`(e.from_id = r.id OR e.to_id = r.id)`
3559
+ ];
3560
+ return sql`${options.selectClause} FROM reachable r CROSS JOIN ${options.schema.edgesTable} e ${nodeJoin} WHERE ${sql.join(allWhere, sql` AND `)}`;
3561
+ }
3562
+ return sql`${options.selectClause} FROM reachable r JOIN ${options.schema.edgesTable} e ON (e.from_id = r.id OR e.to_id = r.id) ${nodeJoin} WHERE ${sql.join([...options.whereClauses], sql` AND `)}`;
3563
+ }
3454
3564
 
3455
3565
  // src/store/row-mappers.ts
3456
3566
  function nullToUndefined2(value) {
@@ -3541,6 +3651,8 @@ async function executeSubgraph(params) {
3541
3651
  excludeRoot: options.excludeRoot ?? false,
3542
3652
  direction: options.direction ?? "out",
3543
3653
  cyclePolicy: options.cyclePolicy ?? "prevent",
3654
+ temporalMode: options.temporalMode ?? params.graph.defaults.temporalMode,
3655
+ asOf: options.asOf,
3544
3656
  dialect: params.dialect,
3545
3657
  schema: params.schema ?? DEFAULT_SQL_SCHEMA,
3546
3658
  backend: params.backend
@@ -3558,7 +3670,19 @@ async function executeSubgraph(params) {
3558
3670
  (kind, field2) => schemaIntrospector.getEdgeFieldTypeInfo(kind, field2),
3559
3671
  "edge"
3560
3672
  );
3561
- const reachableCte = buildReachableCte(ctx);
3673
+ const reachableCte = buildReachableCte({
3674
+ graphId: ctx.graphId,
3675
+ sourceId: ctx.rootId,
3676
+ edgeKinds: ctx.edgeKinds,
3677
+ maxHops: ctx.maxDepth,
3678
+ direction: ctx.direction,
3679
+ cyclePolicy: ctx.cyclePolicy,
3680
+ includePath: false,
3681
+ temporalMode: ctx.temporalMode,
3682
+ ...ctx.asOf !== void 0 && { asOf: ctx.asOf },
3683
+ dialect: ctx.dialect,
3684
+ schema: ctx.schema
3685
+ });
3562
3686
  const includedIdsCte = buildIncludedIdsCte(ctx);
3563
3687
  const [nodeRows, edgeRows] = await Promise.all([
3564
3688
  fetchSubgraphNodes(ctx, reachableCte, includedIdsCte, nodeProjectionPlan),
@@ -3656,79 +3780,6 @@ function getIncludedNodeKinds(graph, includeKinds) {
3656
3780
  function dedupeStrings(values) {
3657
3781
  return [...new Set(values)];
3658
3782
  }
3659
- function buildReachableCte(ctx) {
3660
- const shouldTrackPath = ctx.cyclePolicy === "prevent";
3661
- const edgeKindFilter = compileKindFilter(sql.raw("e.kind"), ctx.edgeKinds);
3662
- const initialPath = shouldTrackPath ? ctx.dialect.initializePath(sql.raw("n.id")) : void 0;
3663
- const pathExtension = shouldTrackPath ? ctx.dialect.extendPath(sql.raw("r.path"), sql.raw("n.id")) : void 0;
3664
- const cycleCheck = shouldTrackPath ? ctx.dialect.cycleCheck(sql.raw("n.id"), sql.raw("r.path")) : void 0;
3665
- const baseColumns = [sql`n.id`, sql`n.kind`, sql`0 AS depth`];
3666
- if (initialPath !== void 0) {
3667
- baseColumns.push(sql`${initialPath} AS path`);
3668
- }
3669
- const baseCase = sql`SELECT ${sql.join(baseColumns, sql`, `)} FROM ${ctx.schema.nodesTable} n WHERE n.graph_id = ${ctx.graphId} AND n.id = ${ctx.rootId} AND n.deleted_at IS NULL`;
3670
- const recursiveColumns = [
3671
- sql`n.id`,
3672
- sql`n.kind`,
3673
- sql`r.depth + 1 AS depth`
3674
- ];
3675
- if (pathExtension !== void 0) {
3676
- recursiveColumns.push(sql`${pathExtension} AS path`);
3677
- }
3678
- const recursiveWhereClauses = [
3679
- sql`e.graph_id = ${ctx.graphId}`,
3680
- edgeKindFilter,
3681
- sql`e.deleted_at IS NULL`,
3682
- sql`n.deleted_at IS NULL`,
3683
- sql`r.depth < ${ctx.maxDepth}`
3684
- ];
3685
- if (cycleCheck !== void 0) {
3686
- recursiveWhereClauses.push(cycleCheck);
3687
- }
3688
- const forceWorktableOuterJoinOrder = ctx.dialect.capabilities.forceRecursiveWorktableOuterJoinOrder;
3689
- const recursiveCase = ctx.direction === "both" ? compileBidirectionalBranch({
3690
- recursiveColumns,
3691
- whereClauses: recursiveWhereClauses,
3692
- forceWorktableOuterJoinOrder,
3693
- schema: ctx.schema
3694
- }) : compileRecursiveBranch({
3695
- recursiveColumns,
3696
- whereClauses: recursiveWhereClauses,
3697
- joinField: "from_id",
3698
- targetField: "to_id",
3699
- targetKindField: "to_kind",
3700
- forceWorktableOuterJoinOrder,
3701
- schema: ctx.schema
3702
- });
3703
- return sql`WITH RECURSIVE reachable AS (${baseCase} UNION ALL ${recursiveCase})`;
3704
- }
3705
- function compileRecursiveBranch(params) {
3706
- const columns = [...params.recursiveColumns];
3707
- const selectClause = sql`SELECT ${sql.join(columns, sql`, `)}`;
3708
- const nodeJoin = sql`JOIN ${params.schema.nodesTable} n ON n.graph_id = e.graph_id AND n.id = e.${sql.raw(params.targetField)} AND n.kind = e.${sql.raw(params.targetKindField)}`;
3709
- if (params.forceWorktableOuterJoinOrder) {
3710
- const allWhere = [
3711
- ...params.whereClauses,
3712
- sql`e.${sql.raw(params.joinField)} = r.id`
3713
- ];
3714
- return sql`${selectClause} FROM reachable r CROSS JOIN ${params.schema.edgesTable} e ${nodeJoin} WHERE ${sql.join(allWhere, sql` AND `)}`;
3715
- }
3716
- const where = [...params.whereClauses];
3717
- return sql`${selectClause} FROM reachable r JOIN ${params.schema.edgesTable} e ON e.${sql.raw(params.joinField)} = r.id ${nodeJoin} WHERE ${sql.join(where, sql` AND `)}`;
3718
- }
3719
- function compileBidirectionalBranch(params) {
3720
- const columns = [...params.recursiveColumns];
3721
- const selectClause = sql`SELECT ${sql.join(columns, sql`, `)}`;
3722
- const nodeJoin = sql`JOIN ${params.schema.nodesTable} n ON n.graph_id = e.graph_id AND ((e.to_id = r.id AND n.id = e.from_id AND n.kind = e.from_kind) OR (e.from_id = r.id AND n.id = e.to_id AND n.kind = e.to_kind))`;
3723
- if (params.forceWorktableOuterJoinOrder) {
3724
- const allWhere = [
3725
- ...params.whereClauses,
3726
- sql`(e.from_id = r.id OR e.to_id = r.id)`
3727
- ];
3728
- return sql`${selectClause} FROM reachable r CROSS JOIN ${params.schema.edgesTable} e ${nodeJoin} WHERE ${sql.join(allWhere, sql` AND `)}`;
3729
- }
3730
- return sql`${selectClause} FROM reachable r JOIN ${params.schema.edgesTable} e ON (e.from_id = r.id OR e.to_id = r.id) ${nodeJoin} WHERE ${sql.join([...params.whereClauses], sql` AND `)}`;
3731
- }
3732
3783
  function buildIncludedIdsCte(ctx) {
3733
3784
  const filters = [];
3734
3785
  if (ctx.includeKinds !== void 0 && ctx.includeKinds.length > 0) {
@@ -3760,6 +3811,12 @@ async function fetchSubgraphNodes(ctx, reachableCte, includedIdsCte, projectionP
3760
3811
  }
3761
3812
  async function fetchSubgraphEdges(ctx, reachableCte, includedIdsCte, projectionPlan) {
3762
3813
  const edgeKindFilter = compileKindFilter(sql.raw("e.kind"), ctx.edgeKinds);
3814
+ const edgeTemporalFilter = compileTemporalFilter({
3815
+ mode: ctx.temporalMode,
3816
+ asOf: ctx.asOf,
3817
+ tableAlias: "e",
3818
+ currentTimestamp: ctx.dialect.currentTimestamp()
3819
+ });
3763
3820
  const columns = [
3764
3821
  sql`e.id`,
3765
3822
  sql`e.kind`,
@@ -3777,7 +3834,7 @@ async function fetchSubgraphEdges(ctx, reachableCte, includedIdsCte, projectionP
3777
3834
  ]),
3778
3835
  ...buildProjectedPropertyColumns("e", projectionPlan, ctx.dialect)
3779
3836
  ];
3780
- const query = sql`${reachableCte}${includedIdsCte} SELECT ${sql.join(columns, sql`, `)} FROM ${ctx.schema.edgesTable} e WHERE e.graph_id = ${ctx.graphId} AND ${edgeKindFilter} AND e.deleted_at IS NULL AND e.from_id IN (SELECT id FROM included_ids) AND e.to_id IN (SELECT id FROM included_ids)`;
3837
+ const query = sql`${reachableCte}${includedIdsCte} SELECT ${sql.join(columns, sql`, `)} FROM ${ctx.schema.edgesTable} e WHERE e.graph_id = ${ctx.graphId} AND ${edgeKindFilter} AND ${edgeTemporalFilter} AND e.from_id IN (SELECT id FROM included_ids) AND e.to_id IN (SELECT id FROM included_ids)`;
3781
3838
  return ctx.backend.execute(query);
3782
3839
  }
3783
3840
  function buildMetadataColumns(alias, plan, columns) {
@@ -8922,6 +8979,246 @@ function extractEdgeTypes(graph) {
8922
8979
  return result;
8923
8980
  }
8924
8981
 
8982
+ // src/store/algorithms/context.ts
8983
+ var DEFAULT_ALGORITHM_MAX_HOPS = 10;
8984
+ var DEFAULT_NEIGHBOR_DEPTH = 1;
8985
+ function resolveTemporalOptions(ctx, options) {
8986
+ return {
8987
+ temporalMode: options.temporalMode ?? ctx.defaultTemporalMode,
8988
+ ...options.asOf !== void 0 && { asOf: options.asOf }
8989
+ };
8990
+ }
8991
+ function resolveTemporalFilter(ctx, options, tableAlias) {
8992
+ const resolved = resolveTemporalOptions(ctx, options);
8993
+ const filterOptions = {
8994
+ mode: resolved.temporalMode,
8995
+ asOf: resolved.asOf,
8996
+ tableAlias,
8997
+ currentTimestamp: ctx.dialect.currentTimestamp()
8998
+ };
8999
+ return compileTemporalFilter(filterOptions);
9000
+ }
9001
+ function resolveMaxHops(rawMaxHops, fallback, optionName) {
9002
+ const value = rawMaxHops ?? fallback;
9003
+ if (!Number.isFinite(value) || !Number.isInteger(value)) {
9004
+ throw new ConfigurationError(
9005
+ `Graph algorithm ${optionName} must be a finite integer, got ${String(value)}.`,
9006
+ { option: optionName, value }
9007
+ );
9008
+ }
9009
+ if (value < 1) {
9010
+ throw new ConfigurationError(
9011
+ `Graph algorithm ${optionName} must be at least 1, got ${value}.`,
9012
+ { option: optionName, value }
9013
+ );
9014
+ }
9015
+ if (value > MAX_EXPLICIT_RECURSIVE_DEPTH) {
9016
+ throw new ConfigurationError(
9017
+ `Graph algorithm ${optionName} (${value}) exceeds the maximum of ${MAX_EXPLICIT_RECURSIVE_DEPTH}.`,
9018
+ { option: optionName, value, limit: MAX_EXPLICIT_RECURSIVE_DEPTH }
9019
+ );
9020
+ }
9021
+ return value;
9022
+ }
9023
+ function assertEdgeKinds(edges) {
9024
+ if (edges.length === 0) {
9025
+ throw new ConfigurationError(
9026
+ `Graph algorithms require at least one edge kind in 'edges'.`,
9027
+ { edges }
9028
+ );
9029
+ }
9030
+ }
9031
+
9032
+ // src/store/algorithms/degree.ts
9033
+ async function executeDegree(ctx, nodeId, options = {}) {
9034
+ const direction = options.direction ?? "both";
9035
+ const whereClauses = [
9036
+ sql`graph_id = ${ctx.graphId}`,
9037
+ resolveTemporalFilter(ctx, options),
9038
+ compileDirectionFilter(direction, nodeId)
9039
+ ];
9040
+ if (options.edges !== void 0) {
9041
+ whereClauses.push(compileKindFilter(sql.raw("kind"), options.edges));
9042
+ }
9043
+ const countExpr = direction === "both" ? sql`COUNT(DISTINCT id)` : sql`COUNT(*)`;
9044
+ const query = sql`SELECT ${countExpr} AS count FROM ${ctx.schema.edgesTable} WHERE ${sql.join(whereClauses, sql` AND `)}`;
9045
+ const rows = await ctx.backend.execute(query);
9046
+ return Number(rows[0]?.count ?? 0);
9047
+ }
9048
+ function compileDirectionFilter(direction, nodeId) {
9049
+ switch (direction) {
9050
+ case "out": {
9051
+ return sql`from_id = ${nodeId}`;
9052
+ }
9053
+ case "in": {
9054
+ return sql`to_id = ${nodeId}`;
9055
+ }
9056
+ case "both": {
9057
+ return sql`(from_id = ${nodeId} OR to_id = ${nodeId})`;
9058
+ }
9059
+ }
9060
+ }
9061
+ async function executeReachable(ctx, sourceId, options) {
9062
+ assertEdgeKinds(options.edges);
9063
+ const maxHops = resolveMaxHops(
9064
+ options.maxHops,
9065
+ DEFAULT_ALGORITHM_MAX_HOPS,
9066
+ "maxHops"
9067
+ );
9068
+ const cte = buildReachableCte({
9069
+ graphId: ctx.graphId,
9070
+ sourceId,
9071
+ edgeKinds: options.edges,
9072
+ maxHops,
9073
+ direction: options.direction ?? "out",
9074
+ cyclePolicy: options.cyclePolicy ?? "prevent",
9075
+ includePath: false,
9076
+ ...resolveTemporalOptions(ctx, options),
9077
+ dialect: ctx.dialect,
9078
+ schema: ctx.schema
9079
+ });
9080
+ const sourceFilter = options.excludeSource === true ? sql` WHERE id != ${sourceId}` : sql``;
9081
+ const query = sql`${cte} SELECT id, kind, MIN(depth) AS depth FROM reachable${sourceFilter} GROUP BY id, kind ORDER BY depth ASC, id ASC`;
9082
+ const rows = await ctx.backend.execute(query);
9083
+ return rows.map((row) => ({
9084
+ id: row.id,
9085
+ kind: row.kind,
9086
+ depth: Number(row.depth)
9087
+ }));
9088
+ }
9089
+ async function executeCanReach(ctx, sourceId, targetId, options) {
9090
+ assertEdgeKinds(options.edges);
9091
+ const maxHops = resolveMaxHops(
9092
+ options.maxHops,
9093
+ DEFAULT_ALGORITHM_MAX_HOPS,
9094
+ "maxHops"
9095
+ );
9096
+ const cte = buildReachableCte({
9097
+ graphId: ctx.graphId,
9098
+ sourceId,
9099
+ edgeKinds: options.edges,
9100
+ maxHops,
9101
+ direction: options.direction ?? "out",
9102
+ cyclePolicy: options.cyclePolicy ?? "prevent",
9103
+ includePath: false,
9104
+ ...resolveTemporalOptions(ctx, options),
9105
+ dialect: ctx.dialect,
9106
+ schema: ctx.schema
9107
+ });
9108
+ const query = sql`${cte} SELECT 1 AS hit FROM reachable WHERE id = ${targetId} LIMIT 1`;
9109
+ const rows = await ctx.backend.execute(query);
9110
+ return rows.length > 0;
9111
+ }
9112
+ async function executeNeighbors(ctx, sourceId, options) {
9113
+ const depth = resolveMaxHops(options.depth, DEFAULT_NEIGHBOR_DEPTH, "depth");
9114
+ return executeReachable(ctx, sourceId, {
9115
+ edges: options.edges,
9116
+ maxHops: depth,
9117
+ direction: options.direction ?? "out",
9118
+ cyclePolicy: options.cyclePolicy ?? "prevent",
9119
+ ...options.temporalMode !== void 0 && {
9120
+ temporalMode: options.temporalMode
9121
+ },
9122
+ ...options.asOf !== void 0 && { asOf: options.asOf },
9123
+ excludeSource: true
9124
+ });
9125
+ }
9126
+ async function executeShortestPath(ctx, sourceId, targetId, options) {
9127
+ assertEdgeKinds(options.edges);
9128
+ const maxHops = resolveMaxHops(
9129
+ options.maxHops,
9130
+ DEFAULT_ALGORITHM_MAX_HOPS,
9131
+ "maxHops"
9132
+ );
9133
+ if (sourceId === targetId) {
9134
+ const source = await fetchNodeKind(ctx, sourceId, options);
9135
+ if (source === void 0) return void 0;
9136
+ return { nodes: [source], depth: 0 };
9137
+ }
9138
+ const cte = buildReachableCte({
9139
+ graphId: ctx.graphId,
9140
+ sourceId,
9141
+ edgeKinds: options.edges,
9142
+ maxHops,
9143
+ direction: options.direction ?? "out",
9144
+ cyclePolicy: options.cyclePolicy ?? "prevent",
9145
+ includePath: true,
9146
+ ...resolveTemporalOptions(ctx, options),
9147
+ dialect: ctx.dialect,
9148
+ schema: ctx.schema
9149
+ });
9150
+ const pathContainsCheck = sql`NOT (${ctx.dialect.cycleCheck(sql.raw("r.id"), sql.raw("h.path"))})`;
9151
+ const query = sql`${cte}, hit AS (SELECT id, kind, depth, path FROM reachable WHERE id = ${targetId} ORDER BY depth ASC LIMIT 1) SELECT h.id AS hit_id, h.kind AS hit_kind, h.depth AS hit_depth, h.path AS hit_path, r.id AS node_id, r.kind AS node_kind FROM hit h LEFT JOIN reachable r ON ${pathContainsCheck}`;
9152
+ const rows = await ctx.backend.execute(query);
9153
+ const first = rows[0];
9154
+ if (first === void 0) return void 0;
9155
+ const pathIds = normalizePath(first.hit_path);
9156
+ const kindById = buildKindIndex(rows);
9157
+ const pathNodes = pathIds.map((id) => ({
9158
+ id,
9159
+ kind: kindById.get(id) ?? ""
9160
+ }));
9161
+ return { nodes: pathNodes, depth: Number(first.hit_depth) };
9162
+ }
9163
+ function buildKindIndex(rows) {
9164
+ const map = /* @__PURE__ */ new Map();
9165
+ for (const row of rows) {
9166
+ if (row.node_id !== void 0 && row.node_kind !== void 0) {
9167
+ map.set(row.node_id, row.node_kind);
9168
+ }
9169
+ }
9170
+ return map;
9171
+ }
9172
+ async function fetchNodeKind(ctx, nodeId, options) {
9173
+ const temporalFilter = resolveTemporalFilter(ctx, options);
9174
+ const query = sql`SELECT id, kind FROM ${ctx.schema.nodesTable} WHERE graph_id = ${ctx.graphId} AND id = ${nodeId} AND ${temporalFilter} LIMIT 1`;
9175
+ const rows = await ctx.backend.execute(query);
9176
+ const row = rows[0];
9177
+ if (row === void 0) return void 0;
9178
+ return { id: row.id, kind: row.kind };
9179
+ }
9180
+
9181
+ // src/store/algorithms/index.ts
9182
+ function resolveNodeId(value) {
9183
+ return typeof value === "string" ? value : value.id;
9184
+ }
9185
+ function createGraphAlgorithms(params) {
9186
+ const ctx = {
9187
+ graphId: params.graphId,
9188
+ backend: params.backend,
9189
+ dialect: getDialect(params.backend.dialect),
9190
+ schema: params.schema ?? (params.backend.tableNames ? createSqlSchema(params.backend.tableNames) : createSqlSchema()),
9191
+ defaultTemporalMode: params.defaultTemporalMode
9192
+ };
9193
+ return {
9194
+ shortestPath(from, to, options) {
9195
+ return executeShortestPath(
9196
+ ctx,
9197
+ resolveNodeId(from),
9198
+ resolveNodeId(to),
9199
+ options
9200
+ );
9201
+ },
9202
+ reachable(from, options) {
9203
+ return executeReachable(ctx, resolveNodeId(from), options);
9204
+ },
9205
+ canReach(from, to, options) {
9206
+ return executeCanReach(
9207
+ ctx,
9208
+ resolveNodeId(from),
9209
+ resolveNodeId(to),
9210
+ options
9211
+ );
9212
+ },
9213
+ neighbors(node, options) {
9214
+ return executeNeighbors(ctx, resolveNodeId(node), options);
9215
+ },
9216
+ degree(node, options) {
9217
+ return executeDegree(ctx, resolveNodeId(node), options ?? {});
9218
+ }
9219
+ };
9220
+ }
9221
+
8925
9222
  // src/store/collections/edge-collection.ts
8926
9223
  function narrowEdge(edge) {
8927
9224
  return edge;
@@ -11689,6 +11986,7 @@ var Store = class {
11689
11986
  #defaultTraversalExpansion;
11690
11987
  #nodeCollections;
11691
11988
  #edgeCollections;
11989
+ #algorithms;
11692
11990
  constructor(graph, backend, options) {
11693
11991
  this.#graph = graph;
11694
11992
  this.#backend = backend;
@@ -11770,6 +12068,38 @@ var Store = class {
11770
12068
  }
11771
12069
  return this.#edgeCollections;
11772
12070
  }
12071
+ // === Graph Algorithms ===
12072
+ /**
12073
+ * Tier 1 graph algorithms: shortest path, reachability, neighborhoods, and
12074
+ * degree centrality.
12075
+ *
12076
+ * Each call compiles to a single recursive-CTE query against the backend.
12077
+ * The facade is built lazily on first access and cached for the lifetime
12078
+ * of the store.
12079
+ *
12080
+ * @example
12081
+ * ```typescript
12082
+ * const path = await store.algorithms.shortestPath(alice, bob, {
12083
+ * edges: ["knows"],
12084
+ * });
12085
+ *
12086
+ * const friends = await store.algorithms.neighbors(alice, {
12087
+ * edges: ["knows"],
12088
+ * depth: 2,
12089
+ * });
12090
+ * ```
12091
+ */
12092
+ get algorithms() {
12093
+ if (this.#algorithms === void 0) {
12094
+ this.#algorithms = createGraphAlgorithms({
12095
+ graphId: this.graphId,
12096
+ backend: this.#backend,
12097
+ schema: this.#schema,
12098
+ defaultTemporalMode: this.#graph.defaults.temporalMode
12099
+ });
12100
+ }
12101
+ return this.#algorithms;
12102
+ }
11773
12103
  // === Dynamic Collection Access ===
11774
12104
  /**
11775
12105
  * Returns the node collection for the given kind, or undefined if the kind
@@ -12048,6 +12378,7 @@ var Store = class {
12048
12378
  await (this.#backend.capabilities.transactions ? this.#backend.transaction(async (tx) => doClear(tx)) : doClear(this.#backend));
12049
12379
  this.#nodeCollections = void 0;
12050
12380
  this.#edgeCollections = void 0;
12381
+ this.#algorithms = void 0;
12051
12382
  }
12052
12383
  // === Lifecycle ===
12053
12384
  /**