@nicia-ai/typegraph 0.11.0 → 0.12.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.
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import { G as GraphDef } from '../manager-DGSnJa1v.cjs';
3
- import { L as Store } from '../store-DyGdpDFr.cjs';
3
+ import { U as Store } from '../store-NEa4EFFD.cjs';
4
4
  import '../types-DMzKq0d5.cjs';
5
5
  import '../types-GLkwvQvS.cjs';
6
6
  import 'drizzle-orm';
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import { G as GraphDef } from '../manager-BCLhWysp.js';
3
- import { L as Store } from '../store-nQ1ATBlN.js';
3
+ import { U as Store } from '../store-BcnA11lH.js';
4
4
  import '../types-DMzKq0d5.js';
5
5
  import '../types-1YJKodRv.js';
6
6
  import 'drizzle-orm';
@@ -1,6 +1,6 @@
1
1
  import { G as GraphDef } from '../manager-DGSnJa1v.cjs';
2
2
  import { Q as QueryAst } from '../ast-Bh2NDeaK.cjs';
3
- import { L as Store } from '../store-DyGdpDFr.cjs';
3
+ import { U as Store } from '../store-NEa4EFFD.cjs';
4
4
  import { P as ProfilerOptions, a as ProfileReport } from '../types-CVtGFpB9.cjs';
5
5
  export { D as DeclaredIndex, I as IndexRecommendation, b as ProfileSummary, c as PropertyAccessStats, d as PropertyPath, R as RecommendationPriority, U as UsageContext } from '../types-CVtGFpB9.cjs';
6
6
  import '../types-DMzKq0d5.cjs';
@@ -1,6 +1,6 @@
1
1
  import { G as GraphDef } from '../manager-BCLhWysp.js';
2
2
  import { Q as QueryAst } from '../ast-COMyNeMn.js';
3
- import { L as Store } from '../store-nQ1ATBlN.js';
3
+ import { U as Store } from '../store-BcnA11lH.js';
4
4
  import { P as ProfilerOptions, a as ProfileReport } from '../types-COPePE8_.js';
5
5
  export { D as DeclaredIndex, I as IndexRecommendation, b as ProfileSummary, c as PropertyAccessStats, d as PropertyPath, R as RecommendationPriority, U as UsageContext } from '../types-COPePE8_.js';
6
6
  import '../types-DMzKq0d5.js';
@@ -1,9 +1,9 @@
1
- import { S as SqlSchema, G as GraphBackend } from './types-1YJKodRv.js';
1
+ import { S as SqlSchema, G as GraphBackend, T as TransactionBackend } from './types-1YJKodRv.js';
2
2
  import { K as KindRegistry, G as GraphDef, E as EdgeKinds, N as NodeKinds, a as AllNodeTypes, S as SchemaManagerOptions, f as SchemaValidationResult } from './manager-BCLhWysp.js';
3
3
  import { S as SqlDialect, N as NodeType, A as AnyEdgeType, T as TemporalMode, E as EdgeType, d as EdgeRegistration, b as EdgeId, g as NodeId, i as NodeRegistration } from './types-DMzKq0d5.js';
4
+ import { z } from 'zod';
4
5
  import { V as ValueType, i as PredicateExpression, k as VectorMetricType, Q as QueryAst, J as JsonPointer, F as FieldRef, P as ParameterRef, c as JsonPointerInput, T as TraversalExpansion, l as Traversal, N as NodePredicate, m as ProjectedField, O as OrderSpec, G as GroupBySpec, o as RecursiveCyclePolicy, q as TraversalDirection, A as AggregateExpr, r as SelectiveField, s as ComposableQuery, t as SetOperationType, u as SetOperation, S as SortDirection } from './ast-COMyNeMn.js';
5
6
  import { SQL } from 'drizzle-orm';
6
- import { z } from 'zod';
7
7
 
8
8
  /**
9
9
  * Embedding type for vector search.
@@ -244,6 +244,24 @@ declare function notInSubquery(field: FieldRef, subquery: QueryAst): Predicate;
244
244
  * and ExecutableQuery classes.
245
245
  */
246
246
 
247
+ /**
248
+ * A query that can be executed within a `store.batch()` call.
249
+ *
250
+ * Both `ExecutableQuery` and `UnionableQuery` satisfy this interface.
251
+ * The result type `R` is preserved per-query in the batch return tuple.
252
+ */
253
+ type BatchableQuery<R = unknown> = Readonly<{
254
+ executeOn: (backend: GraphBackend | TransactionBackend) => Promise<readonly R[]>;
255
+ }>;
256
+ /**
257
+ * Maps a tuple of BatchableQuery types to their result types.
258
+ *
259
+ * Given `[BatchableQuery<A>, BatchableQuery<B>]`, produces
260
+ * `[readonly A[], readonly B[]]`.
261
+ */
262
+ type BatchResults<Queries extends readonly BatchableQuery<unknown>[]> = {
263
+ -readonly [K in keyof Queries]: Queries[K] extends BatchableQuery<infer R> ? readonly R[] : never;
264
+ };
247
265
  /**
248
266
  * Extracts the names of valid target node kinds for an edge traversal.
249
267
  *
@@ -340,6 +358,10 @@ type BaseFieldAccessor = Readonly<{
340
358
  notIn: (values: readonly unknown[]) => Predicate;
341
359
  }>;
342
360
  type StringFieldAccessor = BaseFieldAccessor & Readonly<{
361
+ gt: (value: string | ParameterRef) => Predicate;
362
+ gte: (value: string | ParameterRef) => Predicate;
363
+ lt: (value: string | ParameterRef) => Predicate;
364
+ lte: (value: string | ParameterRef) => Predicate;
343
365
  contains: (pattern: string | ParameterRef) => Predicate;
344
366
  startsWith: (pattern: string | ParameterRef) => Predicate;
345
367
  endsWith: (pattern: string | ParameterRef) => Predicate;
@@ -1260,7 +1282,68 @@ type SubsetNode<G extends GraphDef, K extends NodeKinds<G>> = {
1260
1282
  type SubsetEdge<G extends GraphDef, K extends EdgeKinds<G>> = {
1261
1283
  [Kind in K]: Edge<G["edges"][Kind]["type"]>;
1262
1284
  }[K];
1263
- type SubgraphOptions<G extends GraphDef, EK extends EdgeKinds<G>, NK extends NodeKinds<G>> = Readonly<{
1285
+ type EmptyShape = Readonly<Record<never, never>>;
1286
+ type NodeProjectionPropertyKey<N extends NodeType> = Exclude<keyof Node<N>, "id" | "kind" | "meta"> & string;
1287
+ type EdgeProjectionPropertyKey<E extends AnyEdgeType> = Exclude<keyof Edge<E>, "id" | "kind" | "fromKind" | "fromId" | "toKind" | "toId" | "meta"> & string;
1288
+ type SubgraphNodeProjectionField<N extends NodeType = NodeType> = NodeProjectionPropertyKey<N> | "meta";
1289
+ type SubgraphEdgeProjectionField<E extends AnyEdgeType = AnyEdgeType> = EdgeProjectionPropertyKey<E> | "meta";
1290
+ type SubgraphNodeProjectionMap<G extends GraphDef, NK extends NodeKinds<G> = NodeKinds<G>> = Readonly<{
1291
+ [K in NodeKinds<G>]?: K extends NK ? readonly SubgraphNodeProjectionField<G["nodes"][K]["type"]>[] : never;
1292
+ }>;
1293
+ type SubgraphEdgeProjectionMap<G extends GraphDef, EK extends EdgeKinds<G> = EdgeKinds<G>> = Readonly<{
1294
+ [K in EdgeKinds<G>]?: K extends EK ? readonly SubgraphEdgeProjectionField<G["edges"][K]["type"]>[] : never;
1295
+ }>;
1296
+ type SubgraphProject<G extends GraphDef, NK extends NodeKinds<G> = NodeKinds<G>, EK extends EdgeKinds<G> = EdgeKinds<G>> = Readonly<{
1297
+ /**
1298
+ * Node fields to keep per kind.
1299
+ *
1300
+ * Projected nodes always retain `kind` and `id`.
1301
+ * Use `"meta"` to include the full metadata object; omit it to exclude metadata entirely.
1302
+ * Only kinds present in `includeKinds` (or all node kinds when omitted) are valid keys.
1303
+ */
1304
+ nodes?: SubgraphNodeProjectionMap<G, NK>;
1305
+ /**
1306
+ * Edge fields to keep per kind.
1307
+ *
1308
+ * Projected edges always retain `id`, `kind`, `fromKind`, `fromId`,
1309
+ * `toKind`, and `toId`.
1310
+ * Use `"meta"` to include the full metadata object; omit it to exclude metadata entirely.
1311
+ * Only edge kinds listed in `edges` are valid keys.
1312
+ */
1313
+ edges?: SubgraphEdgeProjectionMap<G, EK>;
1314
+ }>;
1315
+ /**
1316
+ * Identity function that preserves literal types for reusable projection configs.
1317
+ *
1318
+ * Without this helper, storing a projection in a typed variable widens the
1319
+ * field arrays to `string[]`, defeating compile-time narrowing on results.
1320
+ *
1321
+ * @example
1322
+ * ```ts
1323
+ * const project = defineSubgraphProject(graph)({
1324
+ * nodes: { Task: ["title", "meta"] },
1325
+ * edges: { uses_skill: [] },
1326
+ * });
1327
+ * const result = await store.subgraph(rootId, { edges: ["uses_skill"], project });
1328
+ * // result.nodes narrowed correctly — task.status is a type error
1329
+ * ```
1330
+ */
1331
+ declare function defineSubgraphProject<G extends GraphDef>(_graph: G): <const P extends SubgraphProject<G>>(project: P) => P;
1332
+ type HasMeta<Selection extends readonly string[] | undefined> = Selection extends readonly string[] ? "meta" extends Selection[number] ? true : false : false;
1333
+ type SelectedNodeProps<N extends NodeType, Selection extends readonly string[] | undefined> = Selection extends readonly string[] ? Pick<Node<N>, Extract<Selection[number], NodeProjectionPropertyKey<N>>> : EmptyShape;
1334
+ type SelectedEdgeProps<E extends AnyEdgeType, Selection extends readonly string[] | undefined> = Selection extends readonly string[] ? Pick<Edge<E>, Extract<Selection[number], EdgeProjectionPropertyKey<E>>> : EmptyShape;
1335
+ type ProjectedNodeResult<N extends NodeType, Selection extends readonly string[] | undefined> = Readonly<Pick<Node<N>, "id" | "kind">> & Readonly<SelectedNodeProps<N, Selection>> & (HasMeta<Selection> extends true ? Readonly<{
1336
+ meta: NodeMeta;
1337
+ }> : EmptyShape);
1338
+ type ProjectedEdgeResult<E extends AnyEdgeType, Selection extends readonly string[] | undefined> = Readonly<Pick<Edge<E>, "id" | "kind" | "fromKind" | "fromId" | "toKind" | "toId">> & Readonly<SelectedEdgeProps<E, Selection>> & (HasMeta<Selection> extends true ? Readonly<{
1339
+ meta: EdgeMeta;
1340
+ }> : EmptyShape);
1341
+ type ProjectionSelection<P, Key extends "nodes" | "edges", Kind extends string> = P extends Readonly<{
1342
+ [K in Key]?: infer Map;
1343
+ }> ? Map extends Readonly<Record<string, readonly string[] | undefined>> ? Kind extends keyof Map ? Map[Kind] : undefined : undefined : undefined;
1344
+ type SubgraphNodeResultForKind<G extends GraphDef, Kind extends NodeKinds<G>, P> = ProjectionSelection<P, "nodes", Kind> extends readonly string[] ? ProjectedNodeResult<G["nodes"][Kind]["type"], ProjectionSelection<P, "nodes", Kind>> : Node<G["nodes"][Kind]["type"]>;
1345
+ type SubgraphEdgeResultForKind<G extends GraphDef, Kind extends EdgeKinds<G>, P> = ProjectionSelection<P, "edges", Kind> extends readonly string[] ? ProjectedEdgeResult<G["edges"][Kind]["type"], ProjectionSelection<P, "edges", Kind>> : Edge<G["edges"][Kind]["type"]>;
1346
+ type SubgraphOptions<G extends GraphDef, EK extends EdgeKinds<G>, NK extends NodeKinds<G>, P extends SubgraphProject<G, NK, EK> | undefined = undefined> = Readonly<{
1264
1347
  /** Edge kinds to follow during traversal. Edges not listed are not traversed. */
1265
1348
  edges: readonly EK[];
1266
1349
  /** Maximum traversal depth from root (default: 10). */
@@ -1281,10 +1364,25 @@ type SubgraphOptions<G extends GraphDef, EK extends EdgeKinds<G>, NK extends Nod
1281
1364
  direction?: "out" | "both";
1282
1365
  /** Cycle policy — reuse RecursiveCyclePolicy (default: "prevent"). */
1283
1366
  cyclePolicy?: RecursiveCyclePolicy;
1367
+ /**
1368
+ * Optional field-level projection per node/edge kind.
1369
+ *
1370
+ * Projected nodes keep `kind` and `id`; projected edges keep their structural
1371
+ * endpoint fields. Kinds omitted from `project` remain fully hydrated.
1372
+ * Projection applies to every returned entity, including the root node.
1373
+ *
1374
+ * Only kinds present in `includeKinds` (nodes) or `edges` (edges) are valid
1375
+ * projection keys. Specifying a kind outside those sets is a compile-time error.
1376
+ */
1377
+ project?: P;
1284
1378
  }>;
1285
- type SubgraphResult<G extends GraphDef, NK extends NodeKinds<G> = NodeKinds<G>, EK extends EdgeKinds<G> = EdgeKinds<G>> = Readonly<{
1286
- nodes: readonly SubsetNode<G, NK>[];
1287
- edges: readonly SubsetEdge<G, EK>[];
1379
+ type SubgraphResult<G extends GraphDef, NK extends NodeKinds<G> = NodeKinds<G>, EK extends EdgeKinds<G> = EdgeKinds<G>, P extends SubgraphProject<G, NK, EK> | undefined = undefined> = Readonly<{
1380
+ nodes: readonly {
1381
+ [Kind in NK]: SubgraphNodeResultForKind<G, Kind, P>;
1382
+ }[NK][];
1383
+ edges: readonly {
1384
+ [Kind in EK]: SubgraphEdgeResultForKind<G, Kind, P>;
1385
+ }[EK][];
1288
1386
  }>;
1289
1387
 
1290
1388
  /**
@@ -1457,6 +1555,12 @@ declare class UnionableQuery<G extends GraphDef, R> {
1457
1555
  * Executes the combined query.
1458
1556
  */
1459
1557
  execute(): Promise<readonly R[]>;
1558
+ /**
1559
+ * Executes the combined query against a provided backend.
1560
+ *
1561
+ * Used by `store.batch()` to run multiple queries over a single connection.
1562
+ */
1563
+ executeOn(backend: GraphBackend | TransactionBackend): Promise<readonly R[]>;
1460
1564
  }
1461
1565
 
1462
1566
  /**
@@ -1574,6 +1678,14 @@ declare class ExecutableQuery<G extends GraphDef, Aliases extends AliasMap, Edge
1574
1678
  * @throws Error if no backend is configured
1575
1679
  */
1576
1680
  execute(): Promise<readonly R[]>;
1681
+ /**
1682
+ * Executes the query against a provided backend.
1683
+ *
1684
+ * Used by `store.batch()` to run multiple queries over a single connection
1685
+ * (e.g., within a transaction). The full compile → execute → transform
1686
+ * pipeline runs identically to `execute()`, but against the given backend.
1687
+ */
1688
+ executeOn(backend: GraphBackend | TransactionBackend): Promise<readonly R[]>;
1577
1689
  /**
1578
1690
  * Executes a paginated query using cursor-based keyset pagination.
1579
1691
  *
@@ -1931,6 +2043,40 @@ declare class Store<G extends GraphDef> {
1931
2043
  * ```
1932
2044
  */
1933
2045
  query(): QueryBuilder<G>;
2046
+ /**
2047
+ * Executes multiple queries over a single connection with snapshot consistency.
2048
+ *
2049
+ * Acquires one connection via an implicit transaction, executes each query
2050
+ * sequentially on that connection, and returns a typed tuple of results.
2051
+ * Each query preserves its own result type, projection, filtering,
2052
+ * sorting, and pagination.
2053
+ *
2054
+ * Read-only — use `bulkCreate`, `bulkInsert`, etc. for write batching.
2055
+ *
2056
+ * @example
2057
+ * ```typescript
2058
+ * const [people, companies] = await store.batch(
2059
+ * store.query()
2060
+ * .from("Person", "p")
2061
+ * .select((ctx) => ({ id: ctx.p.id, name: ctx.p.name })),
2062
+ * store.query()
2063
+ * .from("Company", "c")
2064
+ * .select((ctx) => ({ id: ctx.c.id, name: ctx.c.name }))
2065
+ * .orderBy("c", "name", "asc")
2066
+ * .limit(5),
2067
+ * );
2068
+ * // people: readonly { id: string; name: string }[]
2069
+ * // companies: readonly { id: string; name: string }[]
2070
+ * ```
2071
+ *
2072
+ * @param queries - Two or more executable queries (from `.select()` or set operations)
2073
+ * @returns A tuple with per-query typed results, preserving input order
2074
+ */
2075
+ batch<const Queries extends readonly [
2076
+ BatchableQuery<unknown>,
2077
+ BatchableQuery<unknown>,
2078
+ ...BatchableQuery<unknown>[]
2079
+ ]>(...queries: Queries): Promise<BatchResults<Queries>>;
1934
2080
  /**
1935
2081
  * Extracts a typed subgraph by traversing from a root node.
1936
2082
  *
@@ -1953,7 +2099,7 @@ declare class Store<G extends GraphDef> {
1953
2099
  * }
1954
2100
  * ```
1955
2101
  */
1956
- subgraph<const EK extends EdgeKinds<G>, const NK extends NodeKinds<G> = NodeKinds<G>>(rootId: NodeId<AllNodeTypes<G>>, options: SubgraphOptions<G, EK, NK>): Promise<SubgraphResult<G, NK, EK>>;
2102
+ subgraph<const EK extends EdgeKinds<G>, const NK extends NodeKinds<G> = NodeKinds<G>, const P extends SubgraphProject<G, NK, EK> | undefined = undefined>(rootId: NodeId<AllNodeTypes<G>>, options: SubgraphOptions<G, EK, NK, P>): Promise<SubgraphResult<G, NK, EK, P>>;
1957
2103
  /**
1958
2104
  * Executes a function within a transaction.
1959
2105
  *
@@ -2055,4 +2201,4 @@ declare function createStore<G extends GraphDef>(graph: G, backend: GraphBackend
2055
2201
  */
2056
2202
  declare function createStoreWithSchema<G extends GraphDef>(graph: G, backend: GraphBackend, options?: StoreOptions & SchemaManagerOptions): Promise<[Store<G>, SchemaValidationResult]>;
2057
2203
 
2058
- export { type TypedEdgeCollection as $, type AliasMap as A, type QueryHookContext as B, type CreateQueryBuilderOptions as C, type QueryOptions as D, type EdgeAliasMap as E, type FieldAccessor as F, type GetOrCreateAction as G, type HookContext as H, type IfExistsMode as I, type SelectableEdge as J, type SelectableNode as K, Store as L, type StoreHooks as M, type Node as N, type OperationHookContext as O, type PaginateOptions as P, QueryBuilder as Q, type RecursiveTraversalOptions as R, type SelectContext as S, TraversalBuilder as T, type StoreOptions as U, type StreamOptions as V, type SubgraphOptions as W, type SubgraphResult as X, type SubsetEdge as Y, type SubsetNode as Z, type TransactionContext as _, type AggregateResult as a, UnionableQuery as a0, type UpdateEdgeInput as a1, type UpdateNodeInput as a2, createStore as a3, createStoreWithSchema as a4, embedding as a5, exists as a6, fieldRef as a7, getEmbeddingDimensions as a8, inSubquery as a9, isEmbeddingSchema as aa, isParameterRef as ab, notExists as ac, notInSubquery as ad, param as ae, type AnyEdge as b, type AnyNode as c, type ConstraintNames as d, type CreateEdgeInput as e, type CreateNodeInput as f, type Edge as g, type EdgeAccessor as h, type EdgeCollection as i, type EdgeFindByEndpointsOptions as j, type EdgeGetOrCreateByEndpointsOptions as k, type EdgeGetOrCreateByEndpointsResult as l, type EmbeddingSchema as m, type EmbeddingValue as n, ExecutableAggregateQuery as o, ExecutableQuery as p, type NodeAccessor as q, type NodeAlias as r, type NodeCollection as s, type NodeGetOrCreateByConstraintOptions as t, type NodeGetOrCreateByConstraintResult as u, type NodeRef as v, type PaginatedResult as w, type Predicate as x, PreparedQuery as y, type PropsAccessor as z };
2204
+ export { type SubsetNode as $, type AliasMap as A, type BatchResults as B, type CreateQueryBuilderOptions as C, type PropsAccessor as D, type EdgeAliasMap as E, type FieldAccessor as F, type GetOrCreateAction as G, type HookContext as H, type IfExistsMode as I, type QueryHookContext as J, type QueryOptions as K, type SelectableEdge as L, type SelectableNode as M, type Node as N, type OperationHookContext as O, type PaginateOptions as P, QueryBuilder as Q, type RecursiveTraversalOptions as R, type SelectContext as S, TraversalBuilder as T, Store as U, type StoreHooks as V, type StoreOptions as W, type StreamOptions as X, type SubgraphOptions as Y, type SubgraphResult as Z, type SubsetEdge as _, type AggregateResult as a, type TransactionContext as a0, type TypedEdgeCollection as a1, UnionableQuery as a2, type UpdateEdgeInput as a3, type UpdateNodeInput as a4, createStore as a5, createStoreWithSchema as a6, defineSubgraphProject as a7, embedding as a8, exists as a9, fieldRef as aa, getEmbeddingDimensions as ab, inSubquery as ac, isEmbeddingSchema as ad, isParameterRef as ae, notExists as af, notInSubquery as ag, param as ah, type AnyEdge as b, type AnyNode as c, type BatchableQuery as d, type ConstraintNames as e, type CreateEdgeInput as f, type CreateNodeInput as g, type Edge as h, type EdgeAccessor as i, type EdgeCollection as j, type EdgeFindByEndpointsOptions as k, type EdgeGetOrCreateByEndpointsOptions as l, type EdgeGetOrCreateByEndpointsResult as m, type EmbeddingSchema as n, type EmbeddingValue as o, ExecutableAggregateQuery as p, ExecutableQuery as q, type NodeAccessor as r, type NodeAlias as s, type NodeCollection as t, type NodeGetOrCreateByConstraintOptions as u, type NodeGetOrCreateByConstraintResult as v, type NodeRef as w, type PaginatedResult as x, type Predicate as y, PreparedQuery as z };
@@ -1,9 +1,9 @@
1
- import { S as SqlSchema, G as GraphBackend } from './types-GLkwvQvS.cjs';
1
+ import { S as SqlSchema, G as GraphBackend, T as TransactionBackend } from './types-GLkwvQvS.cjs';
2
2
  import { K as KindRegistry, G as GraphDef, E as EdgeKinds, N as NodeKinds, a as AllNodeTypes, S as SchemaManagerOptions, f as SchemaValidationResult } from './manager-DGSnJa1v.cjs';
3
3
  import { S as SqlDialect, N as NodeType, A as AnyEdgeType, T as TemporalMode, E as EdgeType, d as EdgeRegistration, b as EdgeId, g as NodeId, i as NodeRegistration } from './types-DMzKq0d5.cjs';
4
+ import { z } from 'zod';
4
5
  import { V as ValueType, i as PredicateExpression, k as VectorMetricType, Q as QueryAst, J as JsonPointer, F as FieldRef, P as ParameterRef, c as JsonPointerInput, T as TraversalExpansion, l as Traversal, N as NodePredicate, m as ProjectedField, O as OrderSpec, G as GroupBySpec, o as RecursiveCyclePolicy, q as TraversalDirection, A as AggregateExpr, r as SelectiveField, s as ComposableQuery, t as SetOperationType, u as SetOperation, S as SortDirection } from './ast-Bh2NDeaK.cjs';
5
6
  import { SQL } from 'drizzle-orm';
6
- import { z } from 'zod';
7
7
 
8
8
  /**
9
9
  * Embedding type for vector search.
@@ -244,6 +244,24 @@ declare function notInSubquery(field: FieldRef, subquery: QueryAst): Predicate;
244
244
  * and ExecutableQuery classes.
245
245
  */
246
246
 
247
+ /**
248
+ * A query that can be executed within a `store.batch()` call.
249
+ *
250
+ * Both `ExecutableQuery` and `UnionableQuery` satisfy this interface.
251
+ * The result type `R` is preserved per-query in the batch return tuple.
252
+ */
253
+ type BatchableQuery<R = unknown> = Readonly<{
254
+ executeOn: (backend: GraphBackend | TransactionBackend) => Promise<readonly R[]>;
255
+ }>;
256
+ /**
257
+ * Maps a tuple of BatchableQuery types to their result types.
258
+ *
259
+ * Given `[BatchableQuery<A>, BatchableQuery<B>]`, produces
260
+ * `[readonly A[], readonly B[]]`.
261
+ */
262
+ type BatchResults<Queries extends readonly BatchableQuery<unknown>[]> = {
263
+ -readonly [K in keyof Queries]: Queries[K] extends BatchableQuery<infer R> ? readonly R[] : never;
264
+ };
247
265
  /**
248
266
  * Extracts the names of valid target node kinds for an edge traversal.
249
267
  *
@@ -340,6 +358,10 @@ type BaseFieldAccessor = Readonly<{
340
358
  notIn: (values: readonly unknown[]) => Predicate;
341
359
  }>;
342
360
  type StringFieldAccessor = BaseFieldAccessor & Readonly<{
361
+ gt: (value: string | ParameterRef) => Predicate;
362
+ gte: (value: string | ParameterRef) => Predicate;
363
+ lt: (value: string | ParameterRef) => Predicate;
364
+ lte: (value: string | ParameterRef) => Predicate;
343
365
  contains: (pattern: string | ParameterRef) => Predicate;
344
366
  startsWith: (pattern: string | ParameterRef) => Predicate;
345
367
  endsWith: (pattern: string | ParameterRef) => Predicate;
@@ -1260,7 +1282,68 @@ type SubsetNode<G extends GraphDef, K extends NodeKinds<G>> = {
1260
1282
  type SubsetEdge<G extends GraphDef, K extends EdgeKinds<G>> = {
1261
1283
  [Kind in K]: Edge<G["edges"][Kind]["type"]>;
1262
1284
  }[K];
1263
- type SubgraphOptions<G extends GraphDef, EK extends EdgeKinds<G>, NK extends NodeKinds<G>> = Readonly<{
1285
+ type EmptyShape = Readonly<Record<never, never>>;
1286
+ type NodeProjectionPropertyKey<N extends NodeType> = Exclude<keyof Node<N>, "id" | "kind" | "meta"> & string;
1287
+ type EdgeProjectionPropertyKey<E extends AnyEdgeType> = Exclude<keyof Edge<E>, "id" | "kind" | "fromKind" | "fromId" | "toKind" | "toId" | "meta"> & string;
1288
+ type SubgraphNodeProjectionField<N extends NodeType = NodeType> = NodeProjectionPropertyKey<N> | "meta";
1289
+ type SubgraphEdgeProjectionField<E extends AnyEdgeType = AnyEdgeType> = EdgeProjectionPropertyKey<E> | "meta";
1290
+ type SubgraphNodeProjectionMap<G extends GraphDef, NK extends NodeKinds<G> = NodeKinds<G>> = Readonly<{
1291
+ [K in NodeKinds<G>]?: K extends NK ? readonly SubgraphNodeProjectionField<G["nodes"][K]["type"]>[] : never;
1292
+ }>;
1293
+ type SubgraphEdgeProjectionMap<G extends GraphDef, EK extends EdgeKinds<G> = EdgeKinds<G>> = Readonly<{
1294
+ [K in EdgeKinds<G>]?: K extends EK ? readonly SubgraphEdgeProjectionField<G["edges"][K]["type"]>[] : never;
1295
+ }>;
1296
+ type SubgraphProject<G extends GraphDef, NK extends NodeKinds<G> = NodeKinds<G>, EK extends EdgeKinds<G> = EdgeKinds<G>> = Readonly<{
1297
+ /**
1298
+ * Node fields to keep per kind.
1299
+ *
1300
+ * Projected nodes always retain `kind` and `id`.
1301
+ * Use `"meta"` to include the full metadata object; omit it to exclude metadata entirely.
1302
+ * Only kinds present in `includeKinds` (or all node kinds when omitted) are valid keys.
1303
+ */
1304
+ nodes?: SubgraphNodeProjectionMap<G, NK>;
1305
+ /**
1306
+ * Edge fields to keep per kind.
1307
+ *
1308
+ * Projected edges always retain `id`, `kind`, `fromKind`, `fromId`,
1309
+ * `toKind`, and `toId`.
1310
+ * Use `"meta"` to include the full metadata object; omit it to exclude metadata entirely.
1311
+ * Only edge kinds listed in `edges` are valid keys.
1312
+ */
1313
+ edges?: SubgraphEdgeProjectionMap<G, EK>;
1314
+ }>;
1315
+ /**
1316
+ * Identity function that preserves literal types for reusable projection configs.
1317
+ *
1318
+ * Without this helper, storing a projection in a typed variable widens the
1319
+ * field arrays to `string[]`, defeating compile-time narrowing on results.
1320
+ *
1321
+ * @example
1322
+ * ```ts
1323
+ * const project = defineSubgraphProject(graph)({
1324
+ * nodes: { Task: ["title", "meta"] },
1325
+ * edges: { uses_skill: [] },
1326
+ * });
1327
+ * const result = await store.subgraph(rootId, { edges: ["uses_skill"], project });
1328
+ * // result.nodes narrowed correctly — task.status is a type error
1329
+ * ```
1330
+ */
1331
+ declare function defineSubgraphProject<G extends GraphDef>(_graph: G): <const P extends SubgraphProject<G>>(project: P) => P;
1332
+ type HasMeta<Selection extends readonly string[] | undefined> = Selection extends readonly string[] ? "meta" extends Selection[number] ? true : false : false;
1333
+ type SelectedNodeProps<N extends NodeType, Selection extends readonly string[] | undefined> = Selection extends readonly string[] ? Pick<Node<N>, Extract<Selection[number], NodeProjectionPropertyKey<N>>> : EmptyShape;
1334
+ type SelectedEdgeProps<E extends AnyEdgeType, Selection extends readonly string[] | undefined> = Selection extends readonly string[] ? Pick<Edge<E>, Extract<Selection[number], EdgeProjectionPropertyKey<E>>> : EmptyShape;
1335
+ type ProjectedNodeResult<N extends NodeType, Selection extends readonly string[] | undefined> = Readonly<Pick<Node<N>, "id" | "kind">> & Readonly<SelectedNodeProps<N, Selection>> & (HasMeta<Selection> extends true ? Readonly<{
1336
+ meta: NodeMeta;
1337
+ }> : EmptyShape);
1338
+ type ProjectedEdgeResult<E extends AnyEdgeType, Selection extends readonly string[] | undefined> = Readonly<Pick<Edge<E>, "id" | "kind" | "fromKind" | "fromId" | "toKind" | "toId">> & Readonly<SelectedEdgeProps<E, Selection>> & (HasMeta<Selection> extends true ? Readonly<{
1339
+ meta: EdgeMeta;
1340
+ }> : EmptyShape);
1341
+ type ProjectionSelection<P, Key extends "nodes" | "edges", Kind extends string> = P extends Readonly<{
1342
+ [K in Key]?: infer Map;
1343
+ }> ? Map extends Readonly<Record<string, readonly string[] | undefined>> ? Kind extends keyof Map ? Map[Kind] : undefined : undefined : undefined;
1344
+ type SubgraphNodeResultForKind<G extends GraphDef, Kind extends NodeKinds<G>, P> = ProjectionSelection<P, "nodes", Kind> extends readonly string[] ? ProjectedNodeResult<G["nodes"][Kind]["type"], ProjectionSelection<P, "nodes", Kind>> : Node<G["nodes"][Kind]["type"]>;
1345
+ type SubgraphEdgeResultForKind<G extends GraphDef, Kind extends EdgeKinds<G>, P> = ProjectionSelection<P, "edges", Kind> extends readonly string[] ? ProjectedEdgeResult<G["edges"][Kind]["type"], ProjectionSelection<P, "edges", Kind>> : Edge<G["edges"][Kind]["type"]>;
1346
+ type SubgraphOptions<G extends GraphDef, EK extends EdgeKinds<G>, NK extends NodeKinds<G>, P extends SubgraphProject<G, NK, EK> | undefined = undefined> = Readonly<{
1264
1347
  /** Edge kinds to follow during traversal. Edges not listed are not traversed. */
1265
1348
  edges: readonly EK[];
1266
1349
  /** Maximum traversal depth from root (default: 10). */
@@ -1281,10 +1364,25 @@ type SubgraphOptions<G extends GraphDef, EK extends EdgeKinds<G>, NK extends Nod
1281
1364
  direction?: "out" | "both";
1282
1365
  /** Cycle policy — reuse RecursiveCyclePolicy (default: "prevent"). */
1283
1366
  cyclePolicy?: RecursiveCyclePolicy;
1367
+ /**
1368
+ * Optional field-level projection per node/edge kind.
1369
+ *
1370
+ * Projected nodes keep `kind` and `id`; projected edges keep their structural
1371
+ * endpoint fields. Kinds omitted from `project` remain fully hydrated.
1372
+ * Projection applies to every returned entity, including the root node.
1373
+ *
1374
+ * Only kinds present in `includeKinds` (nodes) or `edges` (edges) are valid
1375
+ * projection keys. Specifying a kind outside those sets is a compile-time error.
1376
+ */
1377
+ project?: P;
1284
1378
  }>;
1285
- type SubgraphResult<G extends GraphDef, NK extends NodeKinds<G> = NodeKinds<G>, EK extends EdgeKinds<G> = EdgeKinds<G>> = Readonly<{
1286
- nodes: readonly SubsetNode<G, NK>[];
1287
- edges: readonly SubsetEdge<G, EK>[];
1379
+ type SubgraphResult<G extends GraphDef, NK extends NodeKinds<G> = NodeKinds<G>, EK extends EdgeKinds<G> = EdgeKinds<G>, P extends SubgraphProject<G, NK, EK> | undefined = undefined> = Readonly<{
1380
+ nodes: readonly {
1381
+ [Kind in NK]: SubgraphNodeResultForKind<G, Kind, P>;
1382
+ }[NK][];
1383
+ edges: readonly {
1384
+ [Kind in EK]: SubgraphEdgeResultForKind<G, Kind, P>;
1385
+ }[EK][];
1288
1386
  }>;
1289
1387
 
1290
1388
  /**
@@ -1457,6 +1555,12 @@ declare class UnionableQuery<G extends GraphDef, R> {
1457
1555
  * Executes the combined query.
1458
1556
  */
1459
1557
  execute(): Promise<readonly R[]>;
1558
+ /**
1559
+ * Executes the combined query against a provided backend.
1560
+ *
1561
+ * Used by `store.batch()` to run multiple queries over a single connection.
1562
+ */
1563
+ executeOn(backend: GraphBackend | TransactionBackend): Promise<readonly R[]>;
1460
1564
  }
1461
1565
 
1462
1566
  /**
@@ -1574,6 +1678,14 @@ declare class ExecutableQuery<G extends GraphDef, Aliases extends AliasMap, Edge
1574
1678
  * @throws Error if no backend is configured
1575
1679
  */
1576
1680
  execute(): Promise<readonly R[]>;
1681
+ /**
1682
+ * Executes the query against a provided backend.
1683
+ *
1684
+ * Used by `store.batch()` to run multiple queries over a single connection
1685
+ * (e.g., within a transaction). The full compile → execute → transform
1686
+ * pipeline runs identically to `execute()`, but against the given backend.
1687
+ */
1688
+ executeOn(backend: GraphBackend | TransactionBackend): Promise<readonly R[]>;
1577
1689
  /**
1578
1690
  * Executes a paginated query using cursor-based keyset pagination.
1579
1691
  *
@@ -1931,6 +2043,40 @@ declare class Store<G extends GraphDef> {
1931
2043
  * ```
1932
2044
  */
1933
2045
  query(): QueryBuilder<G>;
2046
+ /**
2047
+ * Executes multiple queries over a single connection with snapshot consistency.
2048
+ *
2049
+ * Acquires one connection via an implicit transaction, executes each query
2050
+ * sequentially on that connection, and returns a typed tuple of results.
2051
+ * Each query preserves its own result type, projection, filtering,
2052
+ * sorting, and pagination.
2053
+ *
2054
+ * Read-only — use `bulkCreate`, `bulkInsert`, etc. for write batching.
2055
+ *
2056
+ * @example
2057
+ * ```typescript
2058
+ * const [people, companies] = await store.batch(
2059
+ * store.query()
2060
+ * .from("Person", "p")
2061
+ * .select((ctx) => ({ id: ctx.p.id, name: ctx.p.name })),
2062
+ * store.query()
2063
+ * .from("Company", "c")
2064
+ * .select((ctx) => ({ id: ctx.c.id, name: ctx.c.name }))
2065
+ * .orderBy("c", "name", "asc")
2066
+ * .limit(5),
2067
+ * );
2068
+ * // people: readonly { id: string; name: string }[]
2069
+ * // companies: readonly { id: string; name: string }[]
2070
+ * ```
2071
+ *
2072
+ * @param queries - Two or more executable queries (from `.select()` or set operations)
2073
+ * @returns A tuple with per-query typed results, preserving input order
2074
+ */
2075
+ batch<const Queries extends readonly [
2076
+ BatchableQuery<unknown>,
2077
+ BatchableQuery<unknown>,
2078
+ ...BatchableQuery<unknown>[]
2079
+ ]>(...queries: Queries): Promise<BatchResults<Queries>>;
1934
2080
  /**
1935
2081
  * Extracts a typed subgraph by traversing from a root node.
1936
2082
  *
@@ -1953,7 +2099,7 @@ declare class Store<G extends GraphDef> {
1953
2099
  * }
1954
2100
  * ```
1955
2101
  */
1956
- subgraph<const EK extends EdgeKinds<G>, const NK extends NodeKinds<G> = NodeKinds<G>>(rootId: NodeId<AllNodeTypes<G>>, options: SubgraphOptions<G, EK, NK>): Promise<SubgraphResult<G, NK, EK>>;
2102
+ subgraph<const EK extends EdgeKinds<G>, const NK extends NodeKinds<G> = NodeKinds<G>, const P extends SubgraphProject<G, NK, EK> | undefined = undefined>(rootId: NodeId<AllNodeTypes<G>>, options: SubgraphOptions<G, EK, NK, P>): Promise<SubgraphResult<G, NK, EK, P>>;
1957
2103
  /**
1958
2104
  * Executes a function within a transaction.
1959
2105
  *
@@ -2055,4 +2201,4 @@ declare function createStore<G extends GraphDef>(graph: G, backend: GraphBackend
2055
2201
  */
2056
2202
  declare function createStoreWithSchema<G extends GraphDef>(graph: G, backend: GraphBackend, options?: StoreOptions & SchemaManagerOptions): Promise<[Store<G>, SchemaValidationResult]>;
2057
2203
 
2058
- export { type TypedEdgeCollection as $, type AliasMap as A, type QueryHookContext as B, type CreateQueryBuilderOptions as C, type QueryOptions as D, type EdgeAliasMap as E, type FieldAccessor as F, type GetOrCreateAction as G, type HookContext as H, type IfExistsMode as I, type SelectableEdge as J, type SelectableNode as K, Store as L, type StoreHooks as M, type Node as N, type OperationHookContext as O, type PaginateOptions as P, QueryBuilder as Q, type RecursiveTraversalOptions as R, type SelectContext as S, TraversalBuilder as T, type StoreOptions as U, type StreamOptions as V, type SubgraphOptions as W, type SubgraphResult as X, type SubsetEdge as Y, type SubsetNode as Z, type TransactionContext as _, type AggregateResult as a, UnionableQuery as a0, type UpdateEdgeInput as a1, type UpdateNodeInput as a2, createStore as a3, createStoreWithSchema as a4, embedding as a5, exists as a6, fieldRef as a7, getEmbeddingDimensions as a8, inSubquery as a9, isEmbeddingSchema as aa, isParameterRef as ab, notExists as ac, notInSubquery as ad, param as ae, type AnyEdge as b, type AnyNode as c, type ConstraintNames as d, type CreateEdgeInput as e, type CreateNodeInput as f, type Edge as g, type EdgeAccessor as h, type EdgeCollection as i, type EdgeFindByEndpointsOptions as j, type EdgeGetOrCreateByEndpointsOptions as k, type EdgeGetOrCreateByEndpointsResult as l, type EmbeddingSchema as m, type EmbeddingValue as n, ExecutableAggregateQuery as o, ExecutableQuery as p, type NodeAccessor as q, type NodeAlias as r, type NodeCollection as s, type NodeGetOrCreateByConstraintOptions as t, type NodeGetOrCreateByConstraintResult as u, type NodeRef as v, type PaginatedResult as w, type Predicate as x, PreparedQuery as y, type PropsAccessor as z };
2204
+ export { type SubsetNode as $, type AliasMap as A, type BatchResults as B, type CreateQueryBuilderOptions as C, type PropsAccessor as D, type EdgeAliasMap as E, type FieldAccessor as F, type GetOrCreateAction as G, type HookContext as H, type IfExistsMode as I, type QueryHookContext as J, type QueryOptions as K, type SelectableEdge as L, type SelectableNode as M, type Node as N, type OperationHookContext as O, type PaginateOptions as P, QueryBuilder as Q, type RecursiveTraversalOptions as R, type SelectContext as S, TraversalBuilder as T, Store as U, type StoreHooks as V, type StoreOptions as W, type StreamOptions as X, type SubgraphOptions as Y, type SubgraphResult as Z, type SubsetEdge as _, type AggregateResult as a, type TransactionContext as a0, type TypedEdgeCollection as a1, UnionableQuery as a2, type UpdateEdgeInput as a3, type UpdateNodeInput as a4, createStore as a5, createStoreWithSchema as a6, defineSubgraphProject as a7, embedding as a8, exists as a9, fieldRef as aa, getEmbeddingDimensions as ab, inSubquery as ac, isEmbeddingSchema as ad, isParameterRef as ae, notExists as af, notInSubquery as ag, param as ah, type AnyEdge as b, type AnyNode as c, type BatchableQuery as d, type ConstraintNames as e, type CreateEdgeInput as f, type CreateNodeInput as g, type Edge as h, type EdgeAccessor as i, type EdgeCollection as j, type EdgeFindByEndpointsOptions as k, type EdgeGetOrCreateByEndpointsOptions as l, type EdgeGetOrCreateByEndpointsResult as m, type EmbeddingSchema as n, type EmbeddingValue as o, ExecutableAggregateQuery as p, ExecutableQuery as q, type NodeAccessor as r, type NodeAlias as s, type NodeCollection as t, type NodeGetOrCreateByConstraintOptions as u, type NodeGetOrCreateByConstraintResult as v, type NodeRef as w, type PaginatedResult as x, type Predicate as y, PreparedQuery as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nicia-ai/typegraph",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "TypeScript-first embedded knowledge graph library with ontological reasoning",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -122,8 +122,8 @@
122
122
  "node": ">=22"
123
123
  },
124
124
  "peerDependencies": {
125
- "better-sqlite3": ">=9.0.0",
126
- "drizzle-orm": ">=0.35.0",
125
+ "better-sqlite3": ">=9.0.0 <13.0.0",
126
+ "drizzle-orm": ">=0.35.0 <1.0.0",
127
127
  "zod": "^4.0.0"
128
128
  },
129
129
  "peerDependenciesMeta": {
@@ -132,25 +132,25 @@
132
132
  }
133
133
  },
134
134
  "dependencies": {
135
- "nanoid": "^5.1.6"
135
+ "nanoid": "^5.1.7"
136
136
  },
137
137
  "devDependencies": {
138
138
  "@stryker-mutator/core": "^9.6.0",
139
139
  "@stryker-mutator/vitest-runner": "^9.6.0",
140
140
  "@types/better-sqlite3": "^7.6.13",
141
141
  "@types/node": "^24.12.0",
142
- "@types/pg": "^8.18.0",
143
- "@vitest/coverage-v8": "^4.0.18",
144
- "better-sqlite3": "^12.6.2",
142
+ "@types/pg": "^8.20.0",
143
+ "@vitest/coverage-v8": "^4.1.2",
144
+ "better-sqlite3": "^12.8.0",
145
145
  "drizzle-orm": "^0.45.1",
146
- "eslint": "^9.39.4",
146
+ "eslint": "^10.1.0",
147
147
  "fast-check": "^4.6.0",
148
148
  "pg": "^8.20.0",
149
- "sqlite-vec": "0.1.7-alpha.2",
149
+ "sqlite-vec": "^0.1.7",
150
150
  "tsd": "^0.33.0",
151
151
  "tsup": "^8.5.1",
152
152
  "typescript": "^5.9.3",
153
- "vitest": "^4.0.18",
153
+ "vitest": "^4.1.2",
154
154
  "zod": "^4.3.6",
155
155
  "@typegraph/eslint-config": "0.1.0"
156
156
  },