@nicia-ai/typegraph 0.1.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/LICENSE +21 -0
- package/README.md +47 -0
- package/dist/ast-BVyihVbP.d.cts +564 -0
- package/dist/ast-BVyihVbP.d.ts +564 -0
- package/dist/backend/drizzle/index.cjs +41 -0
- package/dist/backend/drizzle/index.cjs.map +1 -0
- package/dist/backend/drizzle/index.d.cts +12 -0
- package/dist/backend/drizzle/index.d.ts +12 -0
- package/dist/backend/drizzle/index.js +12 -0
- package/dist/backend/drizzle/index.js.map +1 -0
- package/dist/backend/drizzle/postgres.cjs +27 -0
- package/dist/backend/drizzle/postgres.cjs.map +1 -0
- package/dist/backend/drizzle/postgres.d.cts +37 -0
- package/dist/backend/drizzle/postgres.d.ts +37 -0
- package/dist/backend/drizzle/postgres.js +10 -0
- package/dist/backend/drizzle/postgres.js.map +1 -0
- package/dist/backend/drizzle/schema/postgres.cjs +40 -0
- package/dist/backend/drizzle/schema/postgres.cjs.map +1 -0
- package/dist/backend/drizzle/schema/postgres.d.cts +2419 -0
- package/dist/backend/drizzle/schema/postgres.d.ts +2419 -0
- package/dist/backend/drizzle/schema/postgres.js +7 -0
- package/dist/backend/drizzle/schema/postgres.js.map +1 -0
- package/dist/backend/drizzle/schema/sqlite.cjs +40 -0
- package/dist/backend/drizzle/schema/sqlite.cjs.map +1 -0
- package/dist/backend/drizzle/schema/sqlite.d.cts +2647 -0
- package/dist/backend/drizzle/schema/sqlite.d.ts +2647 -0
- package/dist/backend/drizzle/schema/sqlite.js +7 -0
- package/dist/backend/drizzle/schema/sqlite.js.map +1 -0
- package/dist/backend/drizzle/sqlite.cjs +27 -0
- package/dist/backend/drizzle/sqlite.cjs.map +1 -0
- package/dist/backend/drizzle/sqlite.d.cts +36 -0
- package/dist/backend/drizzle/sqlite.d.ts +36 -0
- package/dist/backend/drizzle/sqlite.js +10 -0
- package/dist/backend/drizzle/sqlite.js.map +1 -0
- package/dist/backend/postgres/index.cjs +53 -0
- package/dist/backend/postgres/index.cjs.map +1 -0
- package/dist/backend/postgres/index.d.cts +12 -0
- package/dist/backend/postgres/index.d.ts +12 -0
- package/dist/backend/postgres/index.js +12 -0
- package/dist/backend/postgres/index.js.map +1 -0
- package/dist/backend/sqlite/index.cjs +117 -0
- package/dist/backend/sqlite/index.cjs.map +1 -0
- package/dist/backend/sqlite/index.d.cts +71 -0
- package/dist/backend/sqlite/index.d.ts +71 -0
- package/dist/backend/sqlite/index.js +78 -0
- package/dist/backend/sqlite/index.js.map +1 -0
- package/dist/chunk-2QHQ2C4P.js +146 -0
- package/dist/chunk-2QHQ2C4P.js.map +1 -0
- package/dist/chunk-3A5TKOEJ.js +306 -0
- package/dist/chunk-3A5TKOEJ.js.map +1 -0
- package/dist/chunk-4PIEL2VO.js +162 -0
- package/dist/chunk-4PIEL2VO.js.map +1 -0
- package/dist/chunk-536PH5FT.js +342 -0
- package/dist/chunk-536PH5FT.js.map +1 -0
- package/dist/chunk-DBFCKELK.cjs +156 -0
- package/dist/chunk-DBFCKELK.cjs.map +1 -0
- package/dist/chunk-DDM2FZRJ.cjs +1143 -0
- package/dist/chunk-DDM2FZRJ.cjs.map +1 -0
- package/dist/chunk-DGUM43GV.js +10 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/chunk-F32HCHYA.cjs +680 -0
- package/dist/chunk-F32HCHYA.cjs.map +1 -0
- package/dist/chunk-IIAT36MI.js +353 -0
- package/dist/chunk-IIAT36MI.js.map +1 -0
- package/dist/chunk-JDAET5LO.js +236 -0
- package/dist/chunk-JDAET5LO.js.map +1 -0
- package/dist/chunk-JEQ2X3Z6.cjs +12 -0
- package/dist/chunk-JEQ2X3Z6.cjs.map +1 -0
- package/dist/chunk-JKTO7TW3.js +299 -0
- package/dist/chunk-JKTO7TW3.js.map +1 -0
- package/dist/chunk-K7SQ3SWP.js +497 -0
- package/dist/chunk-K7SQ3SWP.js.map +1 -0
- package/dist/chunk-L642L24T.js +142 -0
- package/dist/chunk-L642L24T.js.map +1 -0
- package/dist/chunk-MFVCSNIY.cjs +308 -0
- package/dist/chunk-MFVCSNIY.cjs.map +1 -0
- package/dist/chunk-MNO33ASC.cjs +240 -0
- package/dist/chunk-MNO33ASC.cjs.map +1 -0
- package/dist/chunk-N4AOJ3VF.cjs +154 -0
- package/dist/chunk-N4AOJ3VF.cjs.map +1 -0
- package/dist/chunk-P5CNM325.cjs +508 -0
- package/dist/chunk-P5CNM325.cjs.map +1 -0
- package/dist/chunk-RYT4H46I.js +646 -0
- package/dist/chunk-RYT4H46I.js.map +1 -0
- package/dist/chunk-SV5H3XM5.cjs +321 -0
- package/dist/chunk-SV5H3XM5.cjs.map +1 -0
- package/dist/chunk-TXHKFLWX.cjs +344 -0
- package/dist/chunk-TXHKFLWX.cjs.map +1 -0
- package/dist/chunk-UJAGXJDG.cjs +170 -0
- package/dist/chunk-UJAGXJDG.cjs.map +1 -0
- package/dist/chunk-VXRVGFCI.js +1128 -0
- package/dist/chunk-VXRVGFCI.js.map +1 -0
- package/dist/chunk-YM5AL65Y.cjs +357 -0
- package/dist/chunk-YM5AL65Y.cjs.map +1 -0
- package/dist/index.cjs +8334 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1365 -0
- package/dist/index.d.ts +1365 -0
- package/dist/index.js +8105 -0
- package/dist/index.js.map +1 -0
- package/dist/indexes/index.cjs +67 -0
- package/dist/indexes/index.cjs.map +1 -0
- package/dist/indexes/index.d.cts +62 -0
- package/dist/indexes/index.d.ts +62 -0
- package/dist/indexes/index.js +6 -0
- package/dist/indexes/index.js.map +1 -0
- package/dist/interchange/index.cjs +612 -0
- package/dist/interchange/index.cjs.map +1 -0
- package/dist/interchange/index.d.cts +288 -0
- package/dist/interchange/index.d.ts +288 -0
- package/dist/interchange/index.js +598 -0
- package/dist/interchange/index.js.map +1 -0
- package/dist/profiler/index.cjs +793 -0
- package/dist/profiler/index.cjs.map +1 -0
- package/dist/profiler/index.d.cts +283 -0
- package/dist/profiler/index.d.ts +283 -0
- package/dist/profiler/index.js +785 -0
- package/dist/profiler/index.js.map +1 -0
- package/dist/store-60Lcfi0w.d.ts +2263 -0
- package/dist/store-Bifii8MZ.d.cts +2263 -0
- package/dist/test-helpers-BjyRYJZX.d.ts +22 -0
- package/dist/test-helpers-NoQXhleQ.d.cts +22 -0
- package/dist/types-BRzHlhKC.d.cts +14 -0
- package/dist/types-BRzHlhKC.d.ts +14 -0
- package/dist/types-BrSfFSpW.d.cts +158 -0
- package/dist/types-CX4cLd7M.d.ts +152 -0
- package/dist/types-CjZ7g_7v.d.ts +442 -0
- package/dist/types-DDOSfrih.d.cts +442 -0
- package/dist/types-D_3mEv2y.d.ts +158 -0
- package/dist/types-a5rAxC92.d.cts +152 -0
- package/package.json +201 -0
|
@@ -0,0 +1,2263 @@
|
|
|
1
|
+
import { G as GraphBackend, S as SchemaVersionRow } from './types-CjZ7g_7v.js';
|
|
2
|
+
import { N as NodeType, E as EdgeType, p as NodeRegistration, h as EdgeRegistration, D as DeleteBehavior, T as TemporalMode, i as EdgeTypeWithEndpoints, G as GraphDefaults, A as AnyEdgeType, n as NodeId, V as ValueType, P as PredicateExpression, z as VectorMetricType, Q as QueryAst, J as JsonPointer, F as FieldRef, k as JsonPointerInput, B as Traversal, H as NodePredicate, I as ProjectedField, O as OrderSpec, K as GroupBySpec, L as TraversalDirection, c as AggregateExpr, W as ComposableQuery, X as SetOperationType, Y as SetOperation, S as SortDirection, r as UniquenessScope, f as Collation, e as Cardinality, j as EndpointExistence } from './ast-BVyihVbP.js';
|
|
3
|
+
import { SQL } from 'drizzle-orm';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { S as SqlDialect } from './types-BRzHlhKC.js';
|
|
6
|
+
|
|
7
|
+
/** Brand key for MetaEdge */
|
|
8
|
+
declare const META_EDGE_BRAND: "__metaEdge";
|
|
9
|
+
/**
|
|
10
|
+
* How a meta-edge affects queries and validation.
|
|
11
|
+
*/
|
|
12
|
+
type InferenceType = "subsumption" | "hierarchy" | "substitution" | "constraint" | "composition" | "association" | "none";
|
|
13
|
+
/**
|
|
14
|
+
* Properties of a meta-edge.
|
|
15
|
+
*/
|
|
16
|
+
type MetaEdgeProperties = Readonly<{
|
|
17
|
+
transitive: boolean;
|
|
18
|
+
symmetric: boolean;
|
|
19
|
+
reflexive: boolean;
|
|
20
|
+
inverse: string | undefined;
|
|
21
|
+
inference: InferenceType;
|
|
22
|
+
description: string | undefined;
|
|
23
|
+
}>;
|
|
24
|
+
/**
|
|
25
|
+
* A meta-edge definition.
|
|
26
|
+
*
|
|
27
|
+
* Meta-edges represent type-level relationships (between kinds),
|
|
28
|
+
* not instance-level relationships (between nodes).
|
|
29
|
+
*/
|
|
30
|
+
type MetaEdge<K extends string = string> = Readonly<{
|
|
31
|
+
[META_EDGE_BRAND]: true;
|
|
32
|
+
name: K;
|
|
33
|
+
properties: MetaEdgeProperties;
|
|
34
|
+
}>;
|
|
35
|
+
/**
|
|
36
|
+
* A relation in the ontology (instance of meta-edge between types).
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* // Podcast subClassOf Media
|
|
41
|
+
* subClassOf(Podcast, Media)
|
|
42
|
+
*
|
|
43
|
+
* // Person equivalentTo schema:Person
|
|
44
|
+
* equivalentTo(Person, "https://schema.org/Person")
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
type OntologyRelation = Readonly<{
|
|
48
|
+
metaEdge: MetaEdge;
|
|
49
|
+
from: NodeType | EdgeType | string;
|
|
50
|
+
to: NodeType | EdgeType | string;
|
|
51
|
+
}>;
|
|
52
|
+
/**
|
|
53
|
+
* Checks if a value is a MetaEdge.
|
|
54
|
+
*/
|
|
55
|
+
declare function isMetaEdge(value: unknown): value is MetaEdge;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Embedding type for vector search.
|
|
59
|
+
*
|
|
60
|
+
* Creates a Zod-compatible schema for vector embeddings with
|
|
61
|
+
* dimension validation and metadata for query compilation.
|
|
62
|
+
*/
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Symbol used to brand embedding values at the type level.
|
|
66
|
+
* This allows TypeScript to distinguish embedding arrays from regular
|
|
67
|
+
* number arrays in the query builder type system.
|
|
68
|
+
*/
|
|
69
|
+
declare const EMBEDDING_BRAND: unique symbol;
|
|
70
|
+
/**
|
|
71
|
+
* Branded embedding type for type-level distinction.
|
|
72
|
+
* At runtime this is just `readonly number[]`, but TypeScript can
|
|
73
|
+
* distinguish it from regular arrays for query builder typing.
|
|
74
|
+
*/
|
|
75
|
+
type EmbeddingValue = readonly number[] & {
|
|
76
|
+
readonly [EMBEDDING_BRAND]: true;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Symbol key for storing embedding dimensions on the schema.
|
|
80
|
+
* This allows the schema introspector to detect embedding types
|
|
81
|
+
* and extract dimension information.
|
|
82
|
+
*/
|
|
83
|
+
declare const EMBEDDING_DIMENSIONS_KEY: "_embeddingDimensions";
|
|
84
|
+
/**
|
|
85
|
+
* A Zod schema for vector embeddings with attached dimension metadata.
|
|
86
|
+
* Uses the branded EmbeddingValue type for type-level distinction.
|
|
87
|
+
*/
|
|
88
|
+
type EmbeddingSchema<D extends number = number> = z.ZodType<EmbeddingValue> & Readonly<{
|
|
89
|
+
[EMBEDDING_DIMENSIONS_KEY]: D;
|
|
90
|
+
}>;
|
|
91
|
+
/**
|
|
92
|
+
* Creates a Zod schema for vector embeddings.
|
|
93
|
+
*
|
|
94
|
+
* The dimension is validated at runtime and attached as metadata
|
|
95
|
+
* for the schema introspector and query compiler.
|
|
96
|
+
*
|
|
97
|
+
* @param dimensions - The number of dimensions (e.g., 384, 512, 768, 1536, 3072)
|
|
98
|
+
* @returns A Zod schema that validates embedding arrays
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* // OpenAI ada-002 embeddings
|
|
103
|
+
* const Document = defineNode("Document", {
|
|
104
|
+
* schema: z.object({
|
|
105
|
+
* title: z.string(),
|
|
106
|
+
* embedding: embedding(1536),
|
|
107
|
+
* }),
|
|
108
|
+
* });
|
|
109
|
+
*
|
|
110
|
+
* // Sentence transformers
|
|
111
|
+
* const Sentence = defineNode("Sentence", {
|
|
112
|
+
* schema: z.object({
|
|
113
|
+
* text: z.string(),
|
|
114
|
+
* embedding: embedding(384), // all-MiniLM-L6-v2
|
|
115
|
+
* }),
|
|
116
|
+
* });
|
|
117
|
+
*
|
|
118
|
+
* // Optional embeddings are supported
|
|
119
|
+
* const Article = defineNode("Article", {
|
|
120
|
+
* schema: z.object({
|
|
121
|
+
* content: z.string(),
|
|
122
|
+
* embedding: embedding(1536).optional(),
|
|
123
|
+
* }),
|
|
124
|
+
* });
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
declare function embedding<D extends number>(dimensions: D): EmbeddingSchema<D>;
|
|
128
|
+
/**
|
|
129
|
+
* Checks if a value is an embedding schema.
|
|
130
|
+
*/
|
|
131
|
+
declare function isEmbeddingSchema(value: unknown): value is EmbeddingSchema;
|
|
132
|
+
/**
|
|
133
|
+
* Gets the dimensions from an embedding schema.
|
|
134
|
+
* Returns undefined if the schema is not an embedding schema.
|
|
135
|
+
*/
|
|
136
|
+
declare function getEmbeddingDimensions(schema: z.ZodType): number | undefined;
|
|
137
|
+
|
|
138
|
+
/** Brand key for GraphDef */
|
|
139
|
+
declare const GRAPH_DEF_BRAND: "__graphDef";
|
|
140
|
+
/**
|
|
141
|
+
* An edge entry in the graph definition.
|
|
142
|
+
* Can be:
|
|
143
|
+
* - EdgeType directly (if it has from/to defined)
|
|
144
|
+
* - EdgeRegistration object (always works, can override/narrow defaults)
|
|
145
|
+
*/
|
|
146
|
+
type EdgeEntry = EdgeRegistration | EdgeTypeWithEndpoints;
|
|
147
|
+
/**
|
|
148
|
+
* Normalized edge map type - all entries become EdgeRegistration.
|
|
149
|
+
*/
|
|
150
|
+
type NormalizedEdges<TEdges extends Record<string, EdgeEntry>> = {
|
|
151
|
+
[K in keyof TEdges]: TEdges[K] extends EdgeRegistration ? TEdges[K] : TEdges[K] extends EdgeTypeWithEndpoints ? EdgeRegistration<TEdges[K], TEdges[K]["from"][number], TEdges[K]["to"][number]> : never;
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Configuration for defineGraph.
|
|
155
|
+
*/
|
|
156
|
+
type GraphDefConfig<TNodes extends Record<string, NodeRegistration>, TEdges extends Record<string, EdgeEntry>, TOntology extends readonly OntologyRelation[]> = Readonly<{
|
|
157
|
+
/** Unique identifier for this graph */
|
|
158
|
+
id: string;
|
|
159
|
+
/** Node registrations */
|
|
160
|
+
nodes: TNodes;
|
|
161
|
+
/** Edge registrations or EdgeTypes with built-in domain/range */
|
|
162
|
+
edges: TEdges;
|
|
163
|
+
/** Ontology relations */
|
|
164
|
+
ontology?: TOntology;
|
|
165
|
+
/** Graph-wide defaults */
|
|
166
|
+
defaults?: GraphDefaults;
|
|
167
|
+
}>;
|
|
168
|
+
/**
|
|
169
|
+
* A graph definition.
|
|
170
|
+
*
|
|
171
|
+
* This is a compile-time artifact that describes the structure of a graph.
|
|
172
|
+
* Use `createStore()` to create a runtime store from this definition.
|
|
173
|
+
*/
|
|
174
|
+
type GraphDef<TNodes extends Record<string, NodeRegistration> = Record<string, NodeRegistration>, TEdges extends Record<string, EdgeRegistration> = Record<string, EdgeRegistration>, TOntology extends readonly OntologyRelation[] = readonly OntologyRelation[]> = Readonly<{
|
|
175
|
+
[GRAPH_DEF_BRAND]: true;
|
|
176
|
+
id: string;
|
|
177
|
+
nodes: TNodes;
|
|
178
|
+
edges: TEdges;
|
|
179
|
+
ontology: TOntology;
|
|
180
|
+
defaults: Readonly<{
|
|
181
|
+
onNodeDelete: DeleteBehavior;
|
|
182
|
+
temporalMode: TemporalMode;
|
|
183
|
+
}>;
|
|
184
|
+
}>;
|
|
185
|
+
/**
|
|
186
|
+
* Extract node type names from a GraphDef.
|
|
187
|
+
*/
|
|
188
|
+
type NodeTypeNames<G extends GraphDef> = keyof G["nodes"] & string;
|
|
189
|
+
/**
|
|
190
|
+
* Extract edge type names from a GraphDef.
|
|
191
|
+
*/
|
|
192
|
+
type EdgeTypeNames<G extends GraphDef> = keyof G["edges"] & string;
|
|
193
|
+
/**
|
|
194
|
+
* Get a NodeType from a GraphDef by name.
|
|
195
|
+
*/
|
|
196
|
+
type GetNodeType<G extends GraphDef, K extends NodeTypeNames<G>> = G["nodes"][K]["type"];
|
|
197
|
+
/**
|
|
198
|
+
* Get an EdgeType from a GraphDef by name.
|
|
199
|
+
*/
|
|
200
|
+
type GetEdgeType<G extends GraphDef, K extends EdgeTypeNames<G>> = G["edges"][K]["type"];
|
|
201
|
+
/**
|
|
202
|
+
* Get all NodeTypes from a GraphDef.
|
|
203
|
+
*/
|
|
204
|
+
type AllNodeTypes<G extends GraphDef> = {
|
|
205
|
+
[K in NodeTypeNames<G>]: G["nodes"][K]["type"];
|
|
206
|
+
}[NodeTypeNames<G>];
|
|
207
|
+
/**
|
|
208
|
+
* Get all EdgeTypes from a GraphDef.
|
|
209
|
+
*/
|
|
210
|
+
type AllEdgeTypes<G extends GraphDef> = {
|
|
211
|
+
[K in EdgeTypeNames<G>]: G["edges"][K]["type"];
|
|
212
|
+
}[EdgeTypeNames<G>];
|
|
213
|
+
/**
|
|
214
|
+
* Creates a graph definition.
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```typescript
|
|
218
|
+
* const graph = defineGraph({
|
|
219
|
+
* id: "my_graph",
|
|
220
|
+
* nodes: {
|
|
221
|
+
* Person: { type: Person },
|
|
222
|
+
* Company: { type: Company },
|
|
223
|
+
* },
|
|
224
|
+
* edges: {
|
|
225
|
+
* // Traditional EdgeRegistration syntax
|
|
226
|
+
* worksAt: {
|
|
227
|
+
* type: worksAt,
|
|
228
|
+
* from: [Person],
|
|
229
|
+
* to: [Company],
|
|
230
|
+
* cardinality: "many",
|
|
231
|
+
* },
|
|
232
|
+
* // Or use EdgeType directly if it has from/to defined
|
|
233
|
+
* knows, // EdgeType with built-in domain/range
|
|
234
|
+
* },
|
|
235
|
+
* ontology: [
|
|
236
|
+
* subClassOf(Company, Organization),
|
|
237
|
+
* disjointWith(Person, Organization),
|
|
238
|
+
* ],
|
|
239
|
+
* defaults: {
|
|
240
|
+
* onNodeDelete: "restrict",
|
|
241
|
+
* temporalMode: "current",
|
|
242
|
+
* },
|
|
243
|
+
* });
|
|
244
|
+
* ```
|
|
245
|
+
*/
|
|
246
|
+
declare function defineGraph<TNodes extends Record<string, NodeRegistration<NodeType>>, TEdges extends Record<string, EdgeEntry>, TOntology extends readonly OntologyRelation[]>(config: GraphDefConfig<TNodes, TEdges, TOntology>): GraphDef<TNodes, NormalizedEdges<TEdges>, TOntology>;
|
|
247
|
+
/**
|
|
248
|
+
* Checks if a value is a GraphDef.
|
|
249
|
+
*/
|
|
250
|
+
declare function isGraphDef(value: unknown): value is GraphDef;
|
|
251
|
+
/**
|
|
252
|
+
* Gets all node type names from a GraphDef.
|
|
253
|
+
*/
|
|
254
|
+
declare function getNodeTypeNames<G extends GraphDef>(graph: G): readonly string[];
|
|
255
|
+
/**
|
|
256
|
+
* Gets all edge type names from a GraphDef.
|
|
257
|
+
*/
|
|
258
|
+
declare function getEdgeTypeNames<G extends GraphDef>(graph: G): readonly string[];
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* KindRegistry holds precomputed closures for ontological reasoning.
|
|
262
|
+
*
|
|
263
|
+
* Computed at store initialization and cached for fast query-time lookups.
|
|
264
|
+
*/
|
|
265
|
+
declare class KindRegistry {
|
|
266
|
+
readonly nodeKinds: ReadonlyMap<string, NodeType>;
|
|
267
|
+
readonly edgeKinds: ReadonlyMap<string, AnyEdgeType>;
|
|
268
|
+
readonly subClassAncestors: ReadonlyMap<string, ReadonlySet<string>>;
|
|
269
|
+
readonly subClassDescendants: ReadonlyMap<string, ReadonlySet<string>>;
|
|
270
|
+
readonly broaderClosure: ReadonlyMap<string, ReadonlySet<string>>;
|
|
271
|
+
readonly narrowerClosure: ReadonlyMap<string, ReadonlySet<string>>;
|
|
272
|
+
readonly equivalenceSets: ReadonlyMap<string, ReadonlySet<string>>;
|
|
273
|
+
readonly iriToKind: ReadonlyMap<string, string>;
|
|
274
|
+
readonly disjointPairs: ReadonlySet<string>;
|
|
275
|
+
readonly partOfClosure: ReadonlyMap<string, ReadonlySet<string>>;
|
|
276
|
+
readonly hasPartClosure: ReadonlyMap<string, ReadonlySet<string>>;
|
|
277
|
+
readonly edgeInverses: ReadonlyMap<string, string>;
|
|
278
|
+
readonly edgeImplicationsClosure: ReadonlyMap<string, ReadonlySet<string>>;
|
|
279
|
+
readonly edgeImplyingClosure: ReadonlyMap<string, ReadonlySet<string>>;
|
|
280
|
+
constructor(nodeKinds: ReadonlyMap<string, NodeType>, edgeKinds: ReadonlyMap<string, AnyEdgeType>, closures: {
|
|
281
|
+
subClassAncestors: ReadonlyMap<string, ReadonlySet<string>>;
|
|
282
|
+
subClassDescendants: ReadonlyMap<string, ReadonlySet<string>>;
|
|
283
|
+
broaderClosure: ReadonlyMap<string, ReadonlySet<string>>;
|
|
284
|
+
narrowerClosure: ReadonlyMap<string, ReadonlySet<string>>;
|
|
285
|
+
equivalenceSets: ReadonlyMap<string, ReadonlySet<string>>;
|
|
286
|
+
iriToKind: ReadonlyMap<string, string>;
|
|
287
|
+
disjointPairs: ReadonlySet<string>;
|
|
288
|
+
partOfClosure: ReadonlyMap<string, ReadonlySet<string>>;
|
|
289
|
+
hasPartClosure: ReadonlyMap<string, ReadonlySet<string>>;
|
|
290
|
+
edgeInverses: ReadonlyMap<string, string>;
|
|
291
|
+
edgeImplicationsClosure: ReadonlyMap<string, ReadonlySet<string>>;
|
|
292
|
+
edgeImplyingClosure: ReadonlyMap<string, ReadonlySet<string>>;
|
|
293
|
+
});
|
|
294
|
+
/**
|
|
295
|
+
* Checks if child is a subclass of parent (directly or transitively).
|
|
296
|
+
*/
|
|
297
|
+
isSubClassOf(child: string, parent: string): boolean;
|
|
298
|
+
/**
|
|
299
|
+
* Expands a kind to include all its subclasses.
|
|
300
|
+
* Returns [kind, ...subclasses].
|
|
301
|
+
*/
|
|
302
|
+
expandSubClasses(kind: string): readonly string[];
|
|
303
|
+
/**
|
|
304
|
+
* Gets all ancestors of a kind (via subClassOf).
|
|
305
|
+
*/
|
|
306
|
+
getAncestors(kind: string): ReadonlySet<string>;
|
|
307
|
+
/**
|
|
308
|
+
* Gets all descendants of a kind (via subClassOf).
|
|
309
|
+
*/
|
|
310
|
+
getDescendants(kind: string): ReadonlySet<string>;
|
|
311
|
+
/**
|
|
312
|
+
* Checks if narrowerConcept is narrower than broaderConcept.
|
|
313
|
+
*/
|
|
314
|
+
isNarrowerThan(narrowerConcept: string, broaderConcept: string): boolean;
|
|
315
|
+
/**
|
|
316
|
+
* Checks if broaderConcept is broader than narrowerConcept.
|
|
317
|
+
*/
|
|
318
|
+
isBroaderThan(broaderConcept: string, narrowerConcept: string): boolean;
|
|
319
|
+
/**
|
|
320
|
+
* Expands to include all narrower concepts.
|
|
321
|
+
*/
|
|
322
|
+
expandNarrower(kind: string): readonly string[];
|
|
323
|
+
/**
|
|
324
|
+
* Expands to include all broader concepts.
|
|
325
|
+
*/
|
|
326
|
+
expandBroader(kind: string): readonly string[];
|
|
327
|
+
/**
|
|
328
|
+
* Checks if two kinds are equivalent.
|
|
329
|
+
*/
|
|
330
|
+
areEquivalent(a: string, b: string): boolean;
|
|
331
|
+
/**
|
|
332
|
+
* Gets all equivalents of a kind (including external IRIs).
|
|
333
|
+
*/
|
|
334
|
+
getEquivalents(kind: string): readonly string[];
|
|
335
|
+
/**
|
|
336
|
+
* Resolves an external IRI to an internal kind name.
|
|
337
|
+
*/
|
|
338
|
+
resolveIri(iri: string): string | undefined;
|
|
339
|
+
/**
|
|
340
|
+
* Checks if two kinds are disjoint.
|
|
341
|
+
*/
|
|
342
|
+
areDisjoint(a: string, b: string): boolean;
|
|
343
|
+
/**
|
|
344
|
+
* Gets all kinds that are disjoint with the given kind.
|
|
345
|
+
*/
|
|
346
|
+
getDisjointKinds(kind: string): readonly string[];
|
|
347
|
+
/**
|
|
348
|
+
* Checks if part is part of whole (directly or transitively).
|
|
349
|
+
*/
|
|
350
|
+
isPartOf(part: string, whole: string): boolean;
|
|
351
|
+
/**
|
|
352
|
+
* Gets all wholes that contain this part.
|
|
353
|
+
*/
|
|
354
|
+
getWholes(part: string): readonly string[];
|
|
355
|
+
/**
|
|
356
|
+
* Gets all parts of this whole.
|
|
357
|
+
*/
|
|
358
|
+
getParts(whole: string): readonly string[];
|
|
359
|
+
/**
|
|
360
|
+
* Gets the inverse edge kind for a given edge kind.
|
|
361
|
+
* If edgeA inverseOf edgeB, then getInverseEdge("edgeA") returns "edgeB".
|
|
362
|
+
*/
|
|
363
|
+
getInverseEdge(edgeKind: string): string | undefined;
|
|
364
|
+
/**
|
|
365
|
+
* Gets all edges implied by a given edge (transitively).
|
|
366
|
+
* If A implies B and B implies C, then getImpliedEdges("A") returns ["B", "C"].
|
|
367
|
+
*/
|
|
368
|
+
getImpliedEdges(edgeKind: string): readonly string[];
|
|
369
|
+
/**
|
|
370
|
+
* Gets all edges that imply a given edge (transitively).
|
|
371
|
+
* If A implies B and B implies C, then getImplyingEdges("C") returns ["A", "B"].
|
|
372
|
+
* Used for query-time expansion: when querying for C, also include A and B edges.
|
|
373
|
+
*/
|
|
374
|
+
getImplyingEdges(edgeKind: string): readonly string[];
|
|
375
|
+
/**
|
|
376
|
+
* Expands an edge kind to include all edges that imply it.
|
|
377
|
+
* Returns [edgeKind, ...implyingEdges].
|
|
378
|
+
*/
|
|
379
|
+
expandImplyingEdges(edgeKind: string): readonly string[];
|
|
380
|
+
/**
|
|
381
|
+
* Checks if a concrete kind is assignable to a target kind.
|
|
382
|
+
* Uses subsumption: Company is assignable to Organization if Company subClassOf Organization.
|
|
383
|
+
*/
|
|
384
|
+
isAssignableTo(concreteKind: string, targetKind: string): boolean;
|
|
385
|
+
/**
|
|
386
|
+
* Validates that a kind exists in the registry.
|
|
387
|
+
*/
|
|
388
|
+
hasNodeType(name: string): boolean;
|
|
389
|
+
/**
|
|
390
|
+
* Validates that an edge kind exists in the registry.
|
|
391
|
+
*/
|
|
392
|
+
hasEdgeType(name: string): boolean;
|
|
393
|
+
/**
|
|
394
|
+
* Gets a node kind by name.
|
|
395
|
+
*/
|
|
396
|
+
getNodeType(name: string): NodeType | undefined;
|
|
397
|
+
/**
|
|
398
|
+
* Gets an edge kind by name.
|
|
399
|
+
*/
|
|
400
|
+
getEdgeType(name: string): AnyEdgeType | undefined;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* SQL Schema Configuration for Query Compilation
|
|
405
|
+
*
|
|
406
|
+
* Provides table and column identifiers that the query compiler uses.
|
|
407
|
+
* This allows the compiler to work with custom table names instead of
|
|
408
|
+
* hard-coded defaults.
|
|
409
|
+
*/
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Table names for TypeGraph SQL schema.
|
|
413
|
+
*/
|
|
414
|
+
type SqlTableNames = Readonly<{
|
|
415
|
+
/** Nodes table name (default: "typegraph_nodes") */
|
|
416
|
+
nodes: string;
|
|
417
|
+
/** Edges table name (default: "typegraph_edges") */
|
|
418
|
+
edges: string;
|
|
419
|
+
/** Node embeddings table name (default: "typegraph_node_embeddings") */
|
|
420
|
+
embeddings: string;
|
|
421
|
+
}>;
|
|
422
|
+
/**
|
|
423
|
+
* SQL schema configuration for query compilation.
|
|
424
|
+
* Contains table identifiers and utility methods for generating SQL references.
|
|
425
|
+
*/
|
|
426
|
+
type SqlSchema = Readonly<{
|
|
427
|
+
/** Table names */
|
|
428
|
+
tables: SqlTableNames;
|
|
429
|
+
/** Get a SQL reference to the nodes table */
|
|
430
|
+
nodesTable: SQL;
|
|
431
|
+
/** Get a SQL reference to the edges table */
|
|
432
|
+
edgesTable: SQL;
|
|
433
|
+
/** Get a SQL reference to the embeddings table */
|
|
434
|
+
embeddingsTable: SQL;
|
|
435
|
+
}>;
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Store types for TypeGraph operations.
|
|
439
|
+
*/
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Metadata for a node instance.
|
|
443
|
+
*/
|
|
444
|
+
type NodeMeta = Readonly<{
|
|
445
|
+
version: number;
|
|
446
|
+
validFrom: string | undefined;
|
|
447
|
+
validTo: string | undefined;
|
|
448
|
+
createdAt: string;
|
|
449
|
+
updatedAt: string;
|
|
450
|
+
deletedAt: string | undefined;
|
|
451
|
+
}>;
|
|
452
|
+
/**
|
|
453
|
+
* A node instance in the graph.
|
|
454
|
+
*
|
|
455
|
+
* Properties from the schema are spread at the top level for ergonomic access:
|
|
456
|
+
* - `node.name` instead of `node.props.name`
|
|
457
|
+
* - System metadata is under `node.meta.*`
|
|
458
|
+
*/
|
|
459
|
+
type Node<N extends NodeType = NodeType> = Readonly<{
|
|
460
|
+
kind: N["name"];
|
|
461
|
+
id: NodeId<N>;
|
|
462
|
+
meta: NodeMeta;
|
|
463
|
+
}> & Readonly<z.infer<N["schema"]>>;
|
|
464
|
+
/**
|
|
465
|
+
* Input for creating a node.
|
|
466
|
+
*/
|
|
467
|
+
type CreateNodeInput<N extends NodeType = NodeType> = Readonly<{
|
|
468
|
+
kind: N["name"];
|
|
469
|
+
id?: string;
|
|
470
|
+
props: z.infer<N["schema"]>;
|
|
471
|
+
validFrom?: string;
|
|
472
|
+
validTo?: string;
|
|
473
|
+
}>;
|
|
474
|
+
/**
|
|
475
|
+
* Input for updating a node.
|
|
476
|
+
*/
|
|
477
|
+
type UpdateNodeInput<N extends NodeType = NodeType> = Readonly<{
|
|
478
|
+
kind: N["name"];
|
|
479
|
+
id: NodeId<N>;
|
|
480
|
+
props: Partial<z.infer<N["schema"]>>;
|
|
481
|
+
validTo?: string;
|
|
482
|
+
}>;
|
|
483
|
+
/**
|
|
484
|
+
* Metadata for an edge instance.
|
|
485
|
+
*/
|
|
486
|
+
type EdgeMeta = Readonly<{
|
|
487
|
+
validFrom: string | undefined;
|
|
488
|
+
validTo: string | undefined;
|
|
489
|
+
createdAt: string;
|
|
490
|
+
updatedAt: string;
|
|
491
|
+
deletedAt: string | undefined;
|
|
492
|
+
}>;
|
|
493
|
+
/**
|
|
494
|
+
* An edge instance in the graph.
|
|
495
|
+
*
|
|
496
|
+
* Properties from the schema are spread at the top level for ergonomic access:
|
|
497
|
+
* - `edge.role` instead of `edge.props.role`
|
|
498
|
+
* - System metadata is under `edge.meta.*`
|
|
499
|
+
*/
|
|
500
|
+
type Edge<E extends AnyEdgeType = EdgeType> = Readonly<{
|
|
501
|
+
id: string;
|
|
502
|
+
kind: E["name"];
|
|
503
|
+
fromKind: string;
|
|
504
|
+
fromId: string;
|
|
505
|
+
toKind: string;
|
|
506
|
+
toId: string;
|
|
507
|
+
meta: EdgeMeta;
|
|
508
|
+
}> & Readonly<z.infer<E["schema"]>>;
|
|
509
|
+
/**
|
|
510
|
+
* Input for creating an edge.
|
|
511
|
+
*/
|
|
512
|
+
type CreateEdgeInput<E extends AnyEdgeType = EdgeType> = Readonly<{
|
|
513
|
+
kind: E["name"];
|
|
514
|
+
id?: string;
|
|
515
|
+
fromKind: string;
|
|
516
|
+
fromId: string;
|
|
517
|
+
toKind: string;
|
|
518
|
+
toId: string;
|
|
519
|
+
props: z.infer<E["schema"]>;
|
|
520
|
+
validFrom?: string;
|
|
521
|
+
validTo?: string;
|
|
522
|
+
}>;
|
|
523
|
+
/**
|
|
524
|
+
* Input for updating an edge.
|
|
525
|
+
*/
|
|
526
|
+
type UpdateEdgeInput<E extends AnyEdgeType = EdgeType> = Readonly<{
|
|
527
|
+
id: string;
|
|
528
|
+
props: Partial<z.infer<E["schema"]>>;
|
|
529
|
+
validTo?: string;
|
|
530
|
+
}>;
|
|
531
|
+
/**
|
|
532
|
+
* Options for node and edge queries.
|
|
533
|
+
*/
|
|
534
|
+
type QueryOptions = Readonly<{
|
|
535
|
+
/** Temporal mode for the query */
|
|
536
|
+
temporalMode?: TemporalMode;
|
|
537
|
+
/** Specific timestamp for asOf queries */
|
|
538
|
+
asOf?: string;
|
|
539
|
+
}>;
|
|
540
|
+
/**
|
|
541
|
+
* Context passed to observability hooks.
|
|
542
|
+
*/
|
|
543
|
+
type HookContext = Readonly<{
|
|
544
|
+
/** Unique ID for this operation */
|
|
545
|
+
operationId: string;
|
|
546
|
+
/** Graph ID */
|
|
547
|
+
graphId: string;
|
|
548
|
+
/** Timestamp when operation started */
|
|
549
|
+
startedAt: Date;
|
|
550
|
+
}>;
|
|
551
|
+
/**
|
|
552
|
+
* Query hook context with SQL information.
|
|
553
|
+
*/
|
|
554
|
+
type QueryHookContext = HookContext & Readonly<{
|
|
555
|
+
/** The SQL query being executed */
|
|
556
|
+
sql: string;
|
|
557
|
+
/** Query parameters */
|
|
558
|
+
params: readonly unknown[];
|
|
559
|
+
}>;
|
|
560
|
+
/**
|
|
561
|
+
* Operation hook context for CRUD operations.
|
|
562
|
+
*/
|
|
563
|
+
type OperationHookContext = HookContext & Readonly<{
|
|
564
|
+
/** Operation type */
|
|
565
|
+
operation: "create" | "update" | "delete";
|
|
566
|
+
/** Entity type */
|
|
567
|
+
entity: "node" | "edge";
|
|
568
|
+
/** Kind of node or edge */
|
|
569
|
+
kind: string;
|
|
570
|
+
/** Entity ID */
|
|
571
|
+
id: string;
|
|
572
|
+
}>;
|
|
573
|
+
/**
|
|
574
|
+
* Observability hooks for monitoring store operations.
|
|
575
|
+
*
|
|
576
|
+
* @example
|
|
577
|
+
* ```typescript
|
|
578
|
+
* const hooks: StoreHooks = {
|
|
579
|
+
* onQueryStart: (ctx) => {
|
|
580
|
+
* console.log(`[${ctx.operationId}] Query: ${ctx.sql}`);
|
|
581
|
+
* },
|
|
582
|
+
* onQueryEnd: (ctx, result) => {
|
|
583
|
+
* const duration = Date.now() - ctx.startedAt.getTime();
|
|
584
|
+
* console.log(`[${ctx.operationId}] Completed in ${duration}ms`);
|
|
585
|
+
* },
|
|
586
|
+
* onError: (ctx, error) => {
|
|
587
|
+
* console.error(`[${ctx.operationId}] Error:`, error);
|
|
588
|
+
* },
|
|
589
|
+
* };
|
|
590
|
+
*
|
|
591
|
+
* const store = createStore(graph, backend, { hooks });
|
|
592
|
+
* ```
|
|
593
|
+
*/
|
|
594
|
+
type StoreHooks = Readonly<{
|
|
595
|
+
/** Called before a query is executed */
|
|
596
|
+
onQueryStart?: (ctx: QueryHookContext) => void;
|
|
597
|
+
/** Called after a query completes successfully */
|
|
598
|
+
onQueryEnd?: (ctx: QueryHookContext, result: Readonly<{
|
|
599
|
+
rowCount: number;
|
|
600
|
+
durationMs: number;
|
|
601
|
+
}>) => void;
|
|
602
|
+
/** Called before a CRUD operation starts */
|
|
603
|
+
onOperationStart?: (ctx: OperationHookContext) => void;
|
|
604
|
+
/** Called after a CRUD operation completes */
|
|
605
|
+
onOperationEnd?: (ctx: OperationHookContext, result: Readonly<{
|
|
606
|
+
durationMs: number;
|
|
607
|
+
}>) => void;
|
|
608
|
+
/** Called when an error occurs */
|
|
609
|
+
onError?: (ctx: HookContext, error: Error) => void;
|
|
610
|
+
}>;
|
|
611
|
+
/**
|
|
612
|
+
* Options for creating a store.
|
|
613
|
+
*/
|
|
614
|
+
type StoreOptions = Readonly<{
|
|
615
|
+
/** Observability hooks for monitoring */
|
|
616
|
+
hooks?: StoreHooks;
|
|
617
|
+
/** SQL schema configuration for custom table names */
|
|
618
|
+
schema?: SqlSchema;
|
|
619
|
+
}>;
|
|
620
|
+
/**
|
|
621
|
+
* Configuration for creating a store.
|
|
622
|
+
*/
|
|
623
|
+
type StoreConfig<G extends GraphDef> = Readonly<{
|
|
624
|
+
/** The graph definition */
|
|
625
|
+
graph: G;
|
|
626
|
+
/** Database connection string or path */
|
|
627
|
+
connection?: string;
|
|
628
|
+
/** Auto-run migrations */
|
|
629
|
+
autoMigrate?: boolean;
|
|
630
|
+
}>;
|
|
631
|
+
/**
|
|
632
|
+
* A collection of nodes of a specific type.
|
|
633
|
+
*
|
|
634
|
+
* Provides ergonomic CRUD operations for a single node type.
|
|
635
|
+
*/
|
|
636
|
+
type NodeCollection<N extends NodeType> = Readonly<{
|
|
637
|
+
/** Create a new node */
|
|
638
|
+
create: (props: z.input<N["schema"]>, options?: Readonly<{
|
|
639
|
+
id?: string;
|
|
640
|
+
validFrom?: string;
|
|
641
|
+
validTo?: string;
|
|
642
|
+
}>) => Promise<Node<N>>;
|
|
643
|
+
/** Get a node by ID */
|
|
644
|
+
getById: (id: NodeId<N>, options?: QueryOptions) => Promise<Node<N> | undefined>;
|
|
645
|
+
/** Update a node */
|
|
646
|
+
update: (id: NodeId<N>, props: Partial<z.input<N["schema"]>>, options?: Readonly<{
|
|
647
|
+
validTo?: string;
|
|
648
|
+
}>) => Promise<Node<N>>;
|
|
649
|
+
/** Delete a node (soft delete - sets deletedAt timestamp) */
|
|
650
|
+
delete: (id: NodeId<N>) => Promise<void>;
|
|
651
|
+
/**
|
|
652
|
+
* Permanently delete a node from the database.
|
|
653
|
+
*
|
|
654
|
+
* Unlike `delete()` which performs a soft delete, this permanently
|
|
655
|
+
* removes the node and its associated data (uniqueness entries, embeddings).
|
|
656
|
+
*
|
|
657
|
+
* **Warning:** This operation is irreversible and should be used carefully.
|
|
658
|
+
* Consider using soft delete (`delete()`) for most use cases.
|
|
659
|
+
*
|
|
660
|
+
* @throws Error if edges are still connected to this node (delete edges first)
|
|
661
|
+
*/
|
|
662
|
+
hardDelete: (id: NodeId<N>) => Promise<void>;
|
|
663
|
+
/**
|
|
664
|
+
* Find nodes matching criteria.
|
|
665
|
+
*
|
|
666
|
+
* For simple queries. Use store.query() for complex traversals.
|
|
667
|
+
*/
|
|
668
|
+
find: (options?: Readonly<{
|
|
669
|
+
limit?: number;
|
|
670
|
+
offset?: number;
|
|
671
|
+
}>) => Promise<Node<N>[]>;
|
|
672
|
+
/** Count nodes matching criteria */
|
|
673
|
+
count: () => Promise<number>;
|
|
674
|
+
/**
|
|
675
|
+
* Create or update a node.
|
|
676
|
+
*
|
|
677
|
+
* If a node with the given ID exists, updates it with the provided props.
|
|
678
|
+
* Otherwise, creates a new node with that ID.
|
|
679
|
+
*/
|
|
680
|
+
upsert: (id: string, props: z.input<N["schema"]>, options?: Readonly<{
|
|
681
|
+
validFrom?: string;
|
|
682
|
+
validTo?: string;
|
|
683
|
+
}>) => Promise<Node<N>>;
|
|
684
|
+
/**
|
|
685
|
+
* Create multiple nodes in a batch.
|
|
686
|
+
*
|
|
687
|
+
* More efficient than calling create() multiple times.
|
|
688
|
+
*/
|
|
689
|
+
bulkCreate: (items: readonly Readonly<{
|
|
690
|
+
props: z.input<N["schema"]>;
|
|
691
|
+
id?: string;
|
|
692
|
+
validFrom?: string;
|
|
693
|
+
validTo?: string;
|
|
694
|
+
}>[]) => Promise<Node<N>[]>;
|
|
695
|
+
/**
|
|
696
|
+
* Create or update multiple nodes in a batch.
|
|
697
|
+
*
|
|
698
|
+
* For each item, if a node with the given ID exists, updates it.
|
|
699
|
+
* Otherwise, creates a new node with that ID.
|
|
700
|
+
*/
|
|
701
|
+
bulkUpsert: (items: readonly Readonly<{
|
|
702
|
+
id: string;
|
|
703
|
+
props: z.input<N["schema"]>;
|
|
704
|
+
validFrom?: string;
|
|
705
|
+
validTo?: string;
|
|
706
|
+
}>[]) => Promise<Node<N>[]>;
|
|
707
|
+
/**
|
|
708
|
+
* Delete multiple nodes by ID.
|
|
709
|
+
*
|
|
710
|
+
* Silently ignores IDs that don't exist.
|
|
711
|
+
*/
|
|
712
|
+
bulkDelete: (ids: readonly NodeId<N>[]) => Promise<void>;
|
|
713
|
+
}>;
|
|
714
|
+
/**
|
|
715
|
+
* Reference to a node endpoint (kind and id).
|
|
716
|
+
*
|
|
717
|
+
* Can be either an explicit `{ kind, id }` object or a Node instance.
|
|
718
|
+
*/
|
|
719
|
+
type NodeRef = Readonly<{
|
|
720
|
+
kind: string;
|
|
721
|
+
id: string;
|
|
722
|
+
}>;
|
|
723
|
+
/**
|
|
724
|
+
* Type-safe reference to a node of a specific kind.
|
|
725
|
+
*
|
|
726
|
+
* Accepts either:
|
|
727
|
+
* - A Node instance of the correct kind
|
|
728
|
+
* - An explicit { kind, id } object with the correct kind name
|
|
729
|
+
*
|
|
730
|
+
* This provides compile-time checking that edge endpoints match the
|
|
731
|
+
* allowed node kinds defined in the edge registration.
|
|
732
|
+
*/
|
|
733
|
+
type TypedNodeRef<N extends NodeType> = Node<N> | Readonly<{
|
|
734
|
+
kind: N["name"];
|
|
735
|
+
id: string;
|
|
736
|
+
}>;
|
|
737
|
+
/**
|
|
738
|
+
* Options for creating an edge.
|
|
739
|
+
*/
|
|
740
|
+
type EdgeCreateOptions = Readonly<{
|
|
741
|
+
id?: string;
|
|
742
|
+
validFrom?: string;
|
|
743
|
+
validTo?: string;
|
|
744
|
+
}>;
|
|
745
|
+
/**
|
|
746
|
+
* Arguments for edge creation, with props optional when schema allows empty object.
|
|
747
|
+
*
|
|
748
|
+
* Uses `{}` to check if an empty object literal satisfies the schema input type.
|
|
749
|
+
*/
|
|
750
|
+
type EdgeCreateArguments<E extends AnyEdgeType> = {} extends z.input<E["schema"]> ? [
|
|
751
|
+
props?: z.input<E["schema"]>,
|
|
752
|
+
options?: EdgeCreateOptions
|
|
753
|
+
] : [props: z.input<E["schema"]>, options?: EdgeCreateOptions];
|
|
754
|
+
/**
|
|
755
|
+
* A collection of edges of a specific type.
|
|
756
|
+
*
|
|
757
|
+
* Provides ergonomic CRUD operations for a single edge type.
|
|
758
|
+
* The From and To type parameters enforce that edge endpoints
|
|
759
|
+
* match the allowed node types at compile time.
|
|
760
|
+
*
|
|
761
|
+
* @example
|
|
762
|
+
* ```typescript
|
|
763
|
+
* // Create an edge - pass Node objects directly
|
|
764
|
+
* const edge = await store.edges.worksAt.create(alice, acme, { role: "Engineer" });
|
|
765
|
+
*
|
|
766
|
+
* // TypeScript error: Company is not a valid 'from' type for worksAt
|
|
767
|
+
* // store.edges.worksAt.create(acme, alice, { role: "Engineer" });
|
|
768
|
+
*
|
|
769
|
+
* // For edges with empty schemas, props is optional
|
|
770
|
+
* await store.edges.wrote.create(author, book);
|
|
771
|
+
*
|
|
772
|
+
* // Find edges from a node
|
|
773
|
+
* const edges = await store.edges.worksAt.findFrom(alice);
|
|
774
|
+
* ```
|
|
775
|
+
*/
|
|
776
|
+
type EdgeCollection<E extends AnyEdgeType, From extends NodeType = NodeType, To extends NodeType = NodeType> = Readonly<{
|
|
777
|
+
/**
|
|
778
|
+
* Create a new edge.
|
|
779
|
+
*
|
|
780
|
+
* @param from - Source node (must be one of the allowed 'from' types)
|
|
781
|
+
* @param to - Target node (must be one of the allowed 'to' types)
|
|
782
|
+
* @param args - Edge properties (optional if schema is empty) and creation options
|
|
783
|
+
*/
|
|
784
|
+
create: (from: TypedNodeRef<From>, to: TypedNodeRef<To>, ...args: EdgeCreateArguments<E>) => Promise<Edge<E>>;
|
|
785
|
+
/** Get an edge by ID */
|
|
786
|
+
getById: (id: string, options?: QueryOptions) => Promise<Edge<E> | undefined>;
|
|
787
|
+
/** Update an edge's properties */
|
|
788
|
+
update: (id: string, props: Partial<z.input<E["schema"]>>, options?: Readonly<{
|
|
789
|
+
validTo?: string;
|
|
790
|
+
}>) => Promise<Edge<E>>;
|
|
791
|
+
/** Find edges from a specific node */
|
|
792
|
+
findFrom: (from: TypedNodeRef<From>) => Promise<Edge<E>[]>;
|
|
793
|
+
/** Find edges to a specific node */
|
|
794
|
+
findTo: (to: TypedNodeRef<To>) => Promise<Edge<E>[]>;
|
|
795
|
+
/** Delete an edge (soft delete - sets deletedAt timestamp) */
|
|
796
|
+
delete: (id: string) => Promise<void>;
|
|
797
|
+
/**
|
|
798
|
+
* Permanently delete an edge from the database.
|
|
799
|
+
*
|
|
800
|
+
* Unlike `delete()` which performs a soft delete, this permanently
|
|
801
|
+
* removes the edge record.
|
|
802
|
+
*
|
|
803
|
+
* **Warning:** This operation is irreversible and should be used carefully.
|
|
804
|
+
* Consider using soft delete (`delete()`) for most use cases.
|
|
805
|
+
*/
|
|
806
|
+
hardDelete: (id: string) => Promise<void>;
|
|
807
|
+
/** Find edges matching criteria */
|
|
808
|
+
find: (options?: Readonly<{
|
|
809
|
+
from?: TypedNodeRef<From>;
|
|
810
|
+
to?: TypedNodeRef<To>;
|
|
811
|
+
limit?: number;
|
|
812
|
+
offset?: number;
|
|
813
|
+
}>) => Promise<Edge<E>[]>;
|
|
814
|
+
/** Count edges matching criteria */
|
|
815
|
+
count: (options?: Readonly<{
|
|
816
|
+
from?: TypedNodeRef<From>;
|
|
817
|
+
to?: TypedNodeRef<To>;
|
|
818
|
+
}>) => Promise<number>;
|
|
819
|
+
/**
|
|
820
|
+
* Create multiple edges in a batch.
|
|
821
|
+
*
|
|
822
|
+
* More efficient than calling create() multiple times.
|
|
823
|
+
*/
|
|
824
|
+
bulkCreate: (items: readonly Readonly<{
|
|
825
|
+
from: TypedNodeRef<From>;
|
|
826
|
+
to: TypedNodeRef<To>;
|
|
827
|
+
props?: z.input<E["schema"]>;
|
|
828
|
+
id?: string;
|
|
829
|
+
validFrom?: string;
|
|
830
|
+
validTo?: string;
|
|
831
|
+
}>[]) => Promise<Edge<E>[]>;
|
|
832
|
+
/**
|
|
833
|
+
* Delete multiple edges by ID.
|
|
834
|
+
*
|
|
835
|
+
* Silently ignores IDs that don't exist.
|
|
836
|
+
*/
|
|
837
|
+
bulkDelete: (ids: readonly string[]) => Promise<void>;
|
|
838
|
+
}>;
|
|
839
|
+
/**
|
|
840
|
+
* Extract the union of 'from' node types from an EdgeRegistration.
|
|
841
|
+
*/
|
|
842
|
+
type EdgeFromTypes<R extends EdgeRegistration> = R["from"] extends readonly (infer N)[] ? N : never;
|
|
843
|
+
/**
|
|
844
|
+
* Extract the union of 'to' node types from an EdgeRegistration.
|
|
845
|
+
*/
|
|
846
|
+
type EdgeToTypes<R extends EdgeRegistration> = R["to"] extends readonly (infer N)[] ? N : never;
|
|
847
|
+
/**
|
|
848
|
+
* Create a type-safe EdgeCollection from an EdgeRegistration.
|
|
849
|
+
* Extracts the edge type and from/to node types automatically.
|
|
850
|
+
*/
|
|
851
|
+
type TypedEdgeCollection<R extends EdgeRegistration> = EdgeCollection<R["type"], EdgeFromTypes<R> extends NodeType ? EdgeFromTypes<R> : NodeType, EdgeToTypes<R> extends NodeType ? EdgeToTypes<R> : NodeType>;
|
|
852
|
+
/**
|
|
853
|
+
* A typed transaction context with collection API.
|
|
854
|
+
*
|
|
855
|
+
* Provides the same `tx.nodes.*` and `tx.edges.*` API as the Store,
|
|
856
|
+
* but operations are executed within the transaction scope.
|
|
857
|
+
*
|
|
858
|
+
* @example
|
|
859
|
+
* ```typescript
|
|
860
|
+
* await store.transaction(async (tx) => {
|
|
861
|
+
* const person = await tx.nodes.Person.create({ name: "Alice" });
|
|
862
|
+
* const company = await tx.nodes.Company.create({ name: "Acme" });
|
|
863
|
+
* // Pass nodes directly - their kind and id properties are used
|
|
864
|
+
* await tx.edges.worksAt.create(person, company, { role: "Engineer" });
|
|
865
|
+
* });
|
|
866
|
+
* ```
|
|
867
|
+
*/
|
|
868
|
+
type TransactionContext<G extends GraphDef> = Readonly<{
|
|
869
|
+
/** Node collections for the transaction */
|
|
870
|
+
nodes: {
|
|
871
|
+
[K in keyof G["nodes"] & string]-?: NodeCollection<G["nodes"][K]["type"]>;
|
|
872
|
+
};
|
|
873
|
+
/** Edge collections for the transaction */
|
|
874
|
+
edges: {
|
|
875
|
+
[K in keyof G["edges"] & string]-?: TypedEdgeCollection<G["edges"][K]>;
|
|
876
|
+
};
|
|
877
|
+
}>;
|
|
878
|
+
|
|
879
|
+
type FieldTypeInfo = Readonly<{
|
|
880
|
+
valueType: ValueType;
|
|
881
|
+
elementType?: ValueType | undefined;
|
|
882
|
+
elementTypeInfo?: FieldTypeInfo | undefined;
|
|
883
|
+
shape?: Readonly<Record<string, FieldTypeInfo>> | undefined;
|
|
884
|
+
recordValueType?: FieldTypeInfo | undefined;
|
|
885
|
+
/** For embedding types: the number of dimensions */
|
|
886
|
+
dimensions?: number | undefined;
|
|
887
|
+
}>;
|
|
888
|
+
type SchemaIntrospector = Readonly<{
|
|
889
|
+
getFieldTypeInfo: (kindName: string, fieldName: string) => FieldTypeInfo | undefined;
|
|
890
|
+
getSharedFieldTypeInfo: (kindNames: readonly string[], fieldName: string) => FieldTypeInfo | undefined;
|
|
891
|
+
getEdgeFieldTypeInfo: (edgeKindName: string, fieldName: string) => FieldTypeInfo | undefined;
|
|
892
|
+
getSharedEdgeFieldTypeInfo: (edgeKindNames: readonly string[], fieldName: string) => FieldTypeInfo | undefined;
|
|
893
|
+
}>;
|
|
894
|
+
|
|
895
|
+
/**
|
|
896
|
+
* Predicate builders for TypeGraph queries.
|
|
897
|
+
*
|
|
898
|
+
* Provides a fluent API for building type-safe predicates.
|
|
899
|
+
*/
|
|
900
|
+
|
|
901
|
+
/**
|
|
902
|
+
* A chainable predicate that can be combined with AND/OR.
|
|
903
|
+
*/
|
|
904
|
+
type Predicate = Readonly<{
|
|
905
|
+
__expr: PredicateExpression;
|
|
906
|
+
and: (other: Predicate) => Predicate;
|
|
907
|
+
or: (other: Predicate) => Predicate;
|
|
908
|
+
not: () => Predicate;
|
|
909
|
+
}>;
|
|
910
|
+
/**
|
|
911
|
+
* Options for the similarTo method.
|
|
912
|
+
*/
|
|
913
|
+
type SimilarToOptions = Readonly<{
|
|
914
|
+
/** Similarity metric to use. Default: "cosine" */
|
|
915
|
+
metric?: VectorMetricType;
|
|
916
|
+
/**
|
|
917
|
+
* Minimum similarity score to include results.
|
|
918
|
+
* For cosine: 0-1 where 1 is identical.
|
|
919
|
+
* For L2: maximum distance to include.
|
|
920
|
+
* For inner_product: minimum inner product value.
|
|
921
|
+
*/
|
|
922
|
+
minScore?: number;
|
|
923
|
+
}>;
|
|
924
|
+
/**
|
|
925
|
+
* Creates a field reference.
|
|
926
|
+
*/
|
|
927
|
+
type FieldRefOptions = Readonly<{
|
|
928
|
+
jsonPointer?: JsonPointer | undefined;
|
|
929
|
+
valueType?: ValueType | undefined;
|
|
930
|
+
elementType?: ValueType | undefined;
|
|
931
|
+
}>;
|
|
932
|
+
declare function fieldRef(alias: string, path: readonly string[], options?: FieldRefOptions): FieldRef;
|
|
933
|
+
/**
|
|
934
|
+
* Creates an EXISTS subquery predicate.
|
|
935
|
+
* Returns true if the subquery returns at least one row.
|
|
936
|
+
*
|
|
937
|
+
* @param subquery - The subquery AST to check for existence
|
|
938
|
+
*
|
|
939
|
+
* @example
|
|
940
|
+
* ```typescript
|
|
941
|
+
* // Find persons who have at least one order
|
|
942
|
+
* query
|
|
943
|
+
* .from("Person", "p")
|
|
944
|
+
* .whereNode("p", () =>
|
|
945
|
+
* exists(
|
|
946
|
+
* query.from("Order", "o")
|
|
947
|
+
* .whereNode("o", (o) => o.customerId.eq(field("p.id")))
|
|
948
|
+
* .select((ctx) => ({ id: ctx.o.id }))
|
|
949
|
+
* .toAst()
|
|
950
|
+
* )
|
|
951
|
+
* )
|
|
952
|
+
* ```
|
|
953
|
+
*/
|
|
954
|
+
declare function exists(subquery: QueryAst): Predicate;
|
|
955
|
+
/**
|
|
956
|
+
* Creates a NOT EXISTS subquery predicate.
|
|
957
|
+
* Returns true if the subquery returns no rows.
|
|
958
|
+
*
|
|
959
|
+
* @param subquery - The subquery AST to check for non-existence
|
|
960
|
+
*/
|
|
961
|
+
declare function notExists(subquery: QueryAst): Predicate;
|
|
962
|
+
/**
|
|
963
|
+
* Creates an IN subquery predicate.
|
|
964
|
+
* Returns true if the field value is in the subquery results.
|
|
965
|
+
*
|
|
966
|
+
* @param field - The field to check
|
|
967
|
+
* @param subquery - The subquery AST that returns a single column
|
|
968
|
+
*
|
|
969
|
+
* @example
|
|
970
|
+
* ```typescript
|
|
971
|
+
* // Find persons whose ID is in the VIP list
|
|
972
|
+
* query
|
|
973
|
+
* .from("Person", "p")
|
|
974
|
+
* .where(() =>
|
|
975
|
+
* inSubquery(
|
|
976
|
+
* fieldRef("p", ["id"]),
|
|
977
|
+
* query.from("VIPMember", "v")
|
|
978
|
+
* .select({ id: field("v.personId") })
|
|
979
|
+
* .toAst()
|
|
980
|
+
* )
|
|
981
|
+
* )
|
|
982
|
+
* ```
|
|
983
|
+
*/
|
|
984
|
+
declare function inSubquery(field: FieldRef, subquery: QueryAst): Predicate;
|
|
985
|
+
/**
|
|
986
|
+
* Creates a NOT IN subquery predicate.
|
|
987
|
+
* Returns true if the field value is not in the subquery results.
|
|
988
|
+
*
|
|
989
|
+
* @param field - The field to check
|
|
990
|
+
* @param subquery - The subquery AST that returns a single column
|
|
991
|
+
*/
|
|
992
|
+
declare function notInSubquery(field: FieldRef, subquery: QueryAst): Predicate;
|
|
993
|
+
|
|
994
|
+
/**
|
|
995
|
+
* Shared type definitions for the query builder.
|
|
996
|
+
*
|
|
997
|
+
* Contains type definitions used across QueryBuilder, TraversalBuilder,
|
|
998
|
+
* and ExecutableQuery classes.
|
|
999
|
+
*/
|
|
1000
|
+
|
|
1001
|
+
/**
|
|
1002
|
+
* Extracts the names of valid target node kinds for an edge traversal.
|
|
1003
|
+
*
|
|
1004
|
+
* For "out" direction: returns the names of node kinds in the edge's "to" array.
|
|
1005
|
+
* For "in" direction: returns the names of node kinds in the edge's "from" array.
|
|
1006
|
+
*
|
|
1007
|
+
* @example
|
|
1008
|
+
* // Given: worksAt: { from: [Person], to: [Company, Organization] }
|
|
1009
|
+
* // ValidEdgeTargets<G, "worksAt", "out"> = "Company" | "Organization"
|
|
1010
|
+
* // ValidEdgeTargets<G, "worksAt", "in"> = "Person"
|
|
1011
|
+
*/
|
|
1012
|
+
type ValidEdgeTargets<G extends GraphDef, EK extends keyof G["edges"] & string, Dir extends TraversalDirection> = G["edges"][EK] extends EdgeRegistration ? Dir extends "out" ? G["edges"][EK]["to"][number]["name"] : G["edges"][EK]["from"][number]["name"] : never;
|
|
1013
|
+
/**
|
|
1014
|
+
* A node alias with its associated kind.
|
|
1015
|
+
*/
|
|
1016
|
+
type NodeAlias<K extends NodeType = NodeType, Optional extends boolean = false> = Readonly<{
|
|
1017
|
+
kind: K;
|
|
1018
|
+
alias: string;
|
|
1019
|
+
optional: Optional;
|
|
1020
|
+
}>;
|
|
1021
|
+
/**
|
|
1022
|
+
* A map of alias names to their node aliases.
|
|
1023
|
+
*/
|
|
1024
|
+
type AliasMap = Readonly<Record<string, NodeAlias<NodeType, boolean>>>;
|
|
1025
|
+
/**
|
|
1026
|
+
* An edge alias with its associated kind and optional flag.
|
|
1027
|
+
*/
|
|
1028
|
+
type EdgeAlias<E extends AnyEdgeType = EdgeType, Optional extends boolean = false> = Readonly<{
|
|
1029
|
+
kind: E;
|
|
1030
|
+
alias: string;
|
|
1031
|
+
optional: Optional;
|
|
1032
|
+
}>;
|
|
1033
|
+
/**
|
|
1034
|
+
* A map of alias names to their edge aliases.
|
|
1035
|
+
*/
|
|
1036
|
+
type EdgeAliasMap = Readonly<Record<string, EdgeAlias<EdgeType, boolean>>>;
|
|
1037
|
+
/**
|
|
1038
|
+
* Type utility for compile-time alias collision detection.
|
|
1039
|
+
*
|
|
1040
|
+
* When A already exists in Aliases, this resolves to an error message type
|
|
1041
|
+
* that will cause a type error with a descriptive message.
|
|
1042
|
+
*/
|
|
1043
|
+
type UniqueAlias<A extends string, Aliases extends AliasMap> = A extends keyof Aliases ? `Error: Alias '${A}' is already in use` : A;
|
|
1044
|
+
/**
|
|
1045
|
+
* Creates typed field accessors for a node kind's properties.
|
|
1046
|
+
*/
|
|
1047
|
+
type PropsAccessor<N extends NodeType> = Readonly<{
|
|
1048
|
+
[K in keyof z.infer<N["schema"]>]-?: FieldAccessor<z.infer<N["schema"]>[K]>;
|
|
1049
|
+
}>;
|
|
1050
|
+
/**
|
|
1051
|
+
* A field accessor with type-appropriate predicate methods.
|
|
1052
|
+
* Uses NonNullable to handle optional fields correctly.
|
|
1053
|
+
*/
|
|
1054
|
+
type FieldAccessor<T> = FieldAccessorForType<NonNullable<T>>;
|
|
1055
|
+
type FieldAccessorForType<T> = [
|
|
1056
|
+
T
|
|
1057
|
+
] extends [EmbeddingValue] ? EmbeddingFieldAccessor : [T] extends [string] ? StringFieldAccessor : [T] extends [number] ? NumberFieldAccessor : [T] extends [boolean] ? BooleanFieldAccessor : [T] extends [Date] ? DateFieldAccessor : [T] extends [readonly (infer U)[]] ? ArrayFieldAccessor<U> : [T] extends [Record<string, unknown>] ? ObjectFieldAccessor<T> : BaseFieldAccessor;
|
|
1058
|
+
type BaseFieldAccessor = Readonly<{
|
|
1059
|
+
eq: (value: unknown) => Predicate;
|
|
1060
|
+
neq: (value: unknown) => Predicate;
|
|
1061
|
+
isNull: () => Predicate;
|
|
1062
|
+
isNotNull: () => Predicate;
|
|
1063
|
+
in: (values: readonly unknown[]) => Predicate;
|
|
1064
|
+
notIn: (values: readonly unknown[]) => Predicate;
|
|
1065
|
+
}>;
|
|
1066
|
+
type StringFieldAccessor = BaseFieldAccessor & Readonly<{
|
|
1067
|
+
contains: (pattern: string) => Predicate;
|
|
1068
|
+
startsWith: (pattern: string) => Predicate;
|
|
1069
|
+
endsWith: (pattern: string) => Predicate;
|
|
1070
|
+
like: (pattern: string) => Predicate;
|
|
1071
|
+
ilike: (pattern: string) => Predicate;
|
|
1072
|
+
}>;
|
|
1073
|
+
type NumberFieldAccessor = BaseFieldAccessor & Readonly<{
|
|
1074
|
+
gt: (value: number) => Predicate;
|
|
1075
|
+
gte: (value: number) => Predicate;
|
|
1076
|
+
lt: (value: number) => Predicate;
|
|
1077
|
+
lte: (value: number) => Predicate;
|
|
1078
|
+
between: (lower: number, upper: number) => Predicate;
|
|
1079
|
+
}>;
|
|
1080
|
+
type BooleanFieldAccessor = BaseFieldAccessor;
|
|
1081
|
+
type DateFieldAccessor = BaseFieldAccessor & Readonly<{
|
|
1082
|
+
gt: (value: Date | string) => Predicate;
|
|
1083
|
+
gte: (value: Date | string) => Predicate;
|
|
1084
|
+
lt: (value: Date | string) => Predicate;
|
|
1085
|
+
lte: (value: Date | string) => Predicate;
|
|
1086
|
+
between: (lower: Date | string, upper: Date | string) => Predicate;
|
|
1087
|
+
}>;
|
|
1088
|
+
type ArrayFieldAccessor<U> = BaseFieldAccessor & Readonly<{
|
|
1089
|
+
contains: (value: U) => Predicate;
|
|
1090
|
+
containsAny: (values: readonly U[]) => Predicate;
|
|
1091
|
+
containsAll: (values: readonly U[]) => Predicate;
|
|
1092
|
+
length: NumberFieldAccessor;
|
|
1093
|
+
isEmpty: () => Predicate;
|
|
1094
|
+
isNotEmpty: () => Predicate;
|
|
1095
|
+
lengthEq: (length: number) => Predicate;
|
|
1096
|
+
lengthGt: (length: number) => Predicate;
|
|
1097
|
+
lengthGte: (length: number) => Predicate;
|
|
1098
|
+
lengthLt: (length: number) => Predicate;
|
|
1099
|
+
lengthLte: (length: number) => Predicate;
|
|
1100
|
+
}>;
|
|
1101
|
+
type EmbeddingFieldAccessor = BaseFieldAccessor & Readonly<{
|
|
1102
|
+
/**
|
|
1103
|
+
* Finds the k most similar items using vector similarity.
|
|
1104
|
+
*
|
|
1105
|
+
* @param queryEmbedding - The query vector to compare against
|
|
1106
|
+
* @param k - Maximum number of results to return
|
|
1107
|
+
* @param options - Optional metric and minimum score filter
|
|
1108
|
+
*/
|
|
1109
|
+
similarTo: (queryEmbedding: readonly number[], k: number, options?: SimilarToOptions) => Predicate;
|
|
1110
|
+
}>;
|
|
1111
|
+
type ObjectFieldAccessor<T> = BaseFieldAccessor & Readonly<{
|
|
1112
|
+
get: <K extends keyof T & string>(key: K) => T[K] extends Record<string, unknown> ? ObjectFieldAccessor<T[K]> : FieldAccessor<T[K]>;
|
|
1113
|
+
hasKey: (key: string) => Predicate;
|
|
1114
|
+
hasPath: <P extends JsonPointerInput<T>>(pointer: P) => Predicate;
|
|
1115
|
+
pathEquals: <P extends JsonPointerInput<T>>(pointer: P, value: string | number | boolean | Date) => Predicate;
|
|
1116
|
+
pathContains: <P extends JsonPointerInput<T>>(pointer: P, value: string | number | boolean | Date) => Predicate;
|
|
1117
|
+
pathIsNull: <P extends JsonPointerInput<T>>(pointer: P) => Predicate;
|
|
1118
|
+
pathIsNotNull: <P extends JsonPointerInput<T>>(pointer: P) => Predicate;
|
|
1119
|
+
}>;
|
|
1120
|
+
/**
|
|
1121
|
+
* Node accessor for predicate building.
|
|
1122
|
+
*
|
|
1123
|
+
* Properties are available at the top level for ergonomic access:
|
|
1124
|
+
* - `n.name` instead of `n.props.name`
|
|
1125
|
+
* - System fields: `n.id`, `n.kind`
|
|
1126
|
+
*/
|
|
1127
|
+
type NodeAccessor<N extends NodeType> = Readonly<{
|
|
1128
|
+
id: StringFieldAccessor;
|
|
1129
|
+
kind: StringFieldAccessor;
|
|
1130
|
+
}> & PropsAccessor<N>;
|
|
1131
|
+
/**
|
|
1132
|
+
* Creates typed field accessors for an edge kind's properties.
|
|
1133
|
+
*/
|
|
1134
|
+
type EdgePropsAccessor<E extends AnyEdgeType> = Readonly<{
|
|
1135
|
+
[K in keyof z.infer<E["schema"]>]-?: FieldAccessor<z.infer<E["schema"]>[K]>;
|
|
1136
|
+
}>;
|
|
1137
|
+
/**
|
|
1138
|
+
* Edge accessor for predicate building.
|
|
1139
|
+
*
|
|
1140
|
+
* Properties are available at the top level for ergonomic access:
|
|
1141
|
+
* - `e.role` instead of `e.props.role`
|
|
1142
|
+
* - System fields: `e.id`, `e.kind`, `e.fromId`, `e.toId`
|
|
1143
|
+
*/
|
|
1144
|
+
type EdgeAccessor<E extends AnyEdgeType> = Readonly<{
|
|
1145
|
+
id: StringFieldAccessor;
|
|
1146
|
+
kind: StringFieldAccessor;
|
|
1147
|
+
fromId: StringFieldAccessor;
|
|
1148
|
+
toId: StringFieldAccessor;
|
|
1149
|
+
}> & EdgePropsAccessor<E>;
|
|
1150
|
+
/**
|
|
1151
|
+
* Metadata for a selectable node result.
|
|
1152
|
+
*/
|
|
1153
|
+
type SelectableNodeMeta = Readonly<{
|
|
1154
|
+
version: number;
|
|
1155
|
+
validFrom: string | undefined;
|
|
1156
|
+
validTo: string | undefined;
|
|
1157
|
+
createdAt: string;
|
|
1158
|
+
updatedAt: string;
|
|
1159
|
+
deletedAt: string | undefined;
|
|
1160
|
+
}>;
|
|
1161
|
+
/**
|
|
1162
|
+
* A selectable node result.
|
|
1163
|
+
*
|
|
1164
|
+
* Properties from the schema are spread at the top level for ergonomic access:
|
|
1165
|
+
* - `node.name` instead of `node.props.name`
|
|
1166
|
+
* - System metadata is under `node.meta.*`
|
|
1167
|
+
*/
|
|
1168
|
+
type SelectableNode<N extends NodeType> = Readonly<{
|
|
1169
|
+
id: string;
|
|
1170
|
+
kind: N["name"];
|
|
1171
|
+
meta: SelectableNodeMeta;
|
|
1172
|
+
}> & Readonly<z.infer<N["schema"]>>;
|
|
1173
|
+
/**
|
|
1174
|
+
* Metadata for a selectable edge result.
|
|
1175
|
+
*/
|
|
1176
|
+
type SelectableEdgeMeta = Readonly<{
|
|
1177
|
+
validFrom: string | undefined;
|
|
1178
|
+
validTo: string | undefined;
|
|
1179
|
+
createdAt: string;
|
|
1180
|
+
updatedAt: string;
|
|
1181
|
+
deletedAt: string | undefined;
|
|
1182
|
+
}>;
|
|
1183
|
+
/**
|
|
1184
|
+
* A selectable edge result.
|
|
1185
|
+
*
|
|
1186
|
+
* Properties from the schema are spread at the top level for ergonomic access:
|
|
1187
|
+
* - `edge.role` instead of `edge.props.role`
|
|
1188
|
+
* - System metadata is under `edge.meta.*`
|
|
1189
|
+
*/
|
|
1190
|
+
type SelectableEdge<E extends AnyEdgeType = EdgeType> = Readonly<{
|
|
1191
|
+
id: string;
|
|
1192
|
+
kind: E["name"];
|
|
1193
|
+
fromId: string;
|
|
1194
|
+
toId: string;
|
|
1195
|
+
meta: SelectableEdgeMeta;
|
|
1196
|
+
}> & Readonly<z.infer<E["schema"]>>;
|
|
1197
|
+
/**
|
|
1198
|
+
* Selection context passed to select callback.
|
|
1199
|
+
*
|
|
1200
|
+
* Includes both node aliases and edge aliases. Edge aliases from optional
|
|
1201
|
+
* traversals are nullable.
|
|
1202
|
+
*/
|
|
1203
|
+
type SelectContext<Aliases extends AliasMap, EdgeAliases extends EdgeAliasMap = Record<string, never>> = Readonly<{
|
|
1204
|
+
[A in keyof Aliases]: Aliases[A]["optional"] extends true ? SelectableNode<Aliases[A]["kind"]> | undefined : SelectableNode<Aliases[A]["kind"]>;
|
|
1205
|
+
}> & Readonly<{
|
|
1206
|
+
[EA in keyof EdgeAliases]: EdgeAliases[EA]["optional"] extends true ? SelectableEdge<EdgeAliases[EA]["kind"]> | undefined : SelectableEdge<EdgeAliases[EA]["kind"]>;
|
|
1207
|
+
}>;
|
|
1208
|
+
/**
|
|
1209
|
+
* Result of a paginated query.
|
|
1210
|
+
*/
|
|
1211
|
+
type PaginatedResult<R> = Readonly<{
|
|
1212
|
+
/** The data items for this page */
|
|
1213
|
+
data: readonly R[];
|
|
1214
|
+
/** Cursor to fetch the next page (undefined if no more pages) */
|
|
1215
|
+
nextCursor: string | undefined;
|
|
1216
|
+
/** Cursor to fetch the previous page (undefined if on first page) */
|
|
1217
|
+
prevCursor: string | undefined;
|
|
1218
|
+
/** Whether there are more items after this page */
|
|
1219
|
+
hasNextPage: boolean;
|
|
1220
|
+
/** Whether there are items before this page */
|
|
1221
|
+
hasPrevPage: boolean;
|
|
1222
|
+
}>;
|
|
1223
|
+
/**
|
|
1224
|
+
* Options for cursor-based pagination.
|
|
1225
|
+
*
|
|
1226
|
+
* Use `first`/`after` for forward pagination, `last`/`before` for backward.
|
|
1227
|
+
*/
|
|
1228
|
+
type PaginateOptions = Readonly<{
|
|
1229
|
+
/** Number of items to fetch (forward pagination) */
|
|
1230
|
+
first?: number;
|
|
1231
|
+
/** Cursor to start after (forward pagination) */
|
|
1232
|
+
after?: string;
|
|
1233
|
+
/** Number of items to fetch (backward pagination) */
|
|
1234
|
+
last?: number;
|
|
1235
|
+
/** Cursor to start before (backward pagination) */
|
|
1236
|
+
before?: string;
|
|
1237
|
+
}>;
|
|
1238
|
+
/**
|
|
1239
|
+
* Options for streaming results.
|
|
1240
|
+
*/
|
|
1241
|
+
type StreamOptions = Readonly<{
|
|
1242
|
+
/** Number of items to fetch per batch (default: 1000) */
|
|
1243
|
+
batchSize?: number;
|
|
1244
|
+
}>;
|
|
1245
|
+
/**
|
|
1246
|
+
* Configuration for the query builder.
|
|
1247
|
+
*/
|
|
1248
|
+
type QueryBuilderConfig = Readonly<{
|
|
1249
|
+
graphId: string;
|
|
1250
|
+
registry: KindRegistry;
|
|
1251
|
+
schemaIntrospector: SchemaIntrospector;
|
|
1252
|
+
backend?: GraphBackend;
|
|
1253
|
+
dialect?: SqlDialect;
|
|
1254
|
+
/** SQL schema configuration for custom table names. */
|
|
1255
|
+
schema?: SqlSchema;
|
|
1256
|
+
}>;
|
|
1257
|
+
/**
|
|
1258
|
+
* Internal state of the query builder.
|
|
1259
|
+
*/
|
|
1260
|
+
type QueryBuilderState = Readonly<{
|
|
1261
|
+
startAlias: string;
|
|
1262
|
+
startKinds: readonly string[];
|
|
1263
|
+
/** The current alias (last traversal target, or startAlias if no traversals) */
|
|
1264
|
+
currentAlias: string;
|
|
1265
|
+
includeSubClasses: boolean;
|
|
1266
|
+
traversals: readonly Traversal[];
|
|
1267
|
+
predicates: readonly NodePredicate[];
|
|
1268
|
+
projection: readonly ProjectedField[];
|
|
1269
|
+
orderBy: readonly OrderSpec[];
|
|
1270
|
+
limit: number | undefined;
|
|
1271
|
+
offset: number | undefined;
|
|
1272
|
+
temporalMode: TemporalMode;
|
|
1273
|
+
asOf: string | undefined;
|
|
1274
|
+
groupBy: GroupBySpec | undefined;
|
|
1275
|
+
having: PredicateExpression | undefined;
|
|
1276
|
+
}>;
|
|
1277
|
+
/**
|
|
1278
|
+
* Options for creating a query builder.
|
|
1279
|
+
*/
|
|
1280
|
+
type CreateQueryBuilderOptions = Readonly<{
|
|
1281
|
+
/** Backend for query execution */
|
|
1282
|
+
backend?: GraphBackend;
|
|
1283
|
+
/** SQL dialect for compilation */
|
|
1284
|
+
dialect?: SqlDialect;
|
|
1285
|
+
/** SQL schema configuration for custom table names */
|
|
1286
|
+
schema?: SqlSchema;
|
|
1287
|
+
}>;
|
|
1288
|
+
|
|
1289
|
+
/**
|
|
1290
|
+
* ExecutableAggregateQuery - A query with aggregate functions that can be executed.
|
|
1291
|
+
*/
|
|
1292
|
+
|
|
1293
|
+
/**
|
|
1294
|
+
* Result type for aggregate queries.
|
|
1295
|
+
* Maps field refs to their value types and aggregates to numbers.
|
|
1296
|
+
*/
|
|
1297
|
+
type AggregateResult<R extends Record<string, FieldRef | AggregateExpr>> = {
|
|
1298
|
+
[K in keyof R]: R[K] extends AggregateExpr ? number : R[K] extends FieldRef ? unknown : never;
|
|
1299
|
+
};
|
|
1300
|
+
/**
|
|
1301
|
+
* An aggregate query that can be executed.
|
|
1302
|
+
*/
|
|
1303
|
+
declare class ExecutableAggregateQuery<G extends GraphDef, Aliases extends AliasMap, R extends Record<string, FieldRef | AggregateExpr>> {
|
|
1304
|
+
#private;
|
|
1305
|
+
constructor(config: QueryBuilderConfig, state: QueryBuilderState, fields: R);
|
|
1306
|
+
/**
|
|
1307
|
+
* Builds the query AST.
|
|
1308
|
+
*/
|
|
1309
|
+
toAst(): QueryAst;
|
|
1310
|
+
/**
|
|
1311
|
+
* Limits the number of results.
|
|
1312
|
+
*/
|
|
1313
|
+
limit(n: number): ExecutableAggregateQuery<G, Aliases, R>;
|
|
1314
|
+
/**
|
|
1315
|
+
* Offsets the results.
|
|
1316
|
+
*/
|
|
1317
|
+
offset(n: number): ExecutableAggregateQuery<G, Aliases, R>;
|
|
1318
|
+
/**
|
|
1319
|
+
* Compiles the query to a Drizzle SQL object.
|
|
1320
|
+
*/
|
|
1321
|
+
compile(): SQL;
|
|
1322
|
+
/**
|
|
1323
|
+
* Executes the query and returns typed results.
|
|
1324
|
+
*
|
|
1325
|
+
* @throws Error if no backend is configured
|
|
1326
|
+
*/
|
|
1327
|
+
execute(): Promise<readonly AggregateResult<R>[]>;
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
/**
|
|
1331
|
+
* UnionableQuery - A query formed by combining multiple queries with set operations.
|
|
1332
|
+
*/
|
|
1333
|
+
|
|
1334
|
+
interface ExecutableQueryLike<G extends GraphDef, R> {
|
|
1335
|
+
toAst(): QueryAst;
|
|
1336
|
+
}
|
|
1337
|
+
/**
|
|
1338
|
+
* Internal state for unionable query.
|
|
1339
|
+
*/
|
|
1340
|
+
type UnionableQueryState = Readonly<{
|
|
1341
|
+
left: ComposableQuery;
|
|
1342
|
+
operator: SetOperationType;
|
|
1343
|
+
right: ComposableQuery;
|
|
1344
|
+
limit?: number;
|
|
1345
|
+
offset?: number;
|
|
1346
|
+
startAlias?: string;
|
|
1347
|
+
traversals?: readonly Traversal[];
|
|
1348
|
+
selectFn?: (context: SelectContext<AliasMap, EdgeAliasMap>) => unknown;
|
|
1349
|
+
}>;
|
|
1350
|
+
/**
|
|
1351
|
+
* A query formed by combining multiple queries with set operations.
|
|
1352
|
+
* Supports chaining: q1.union(q2).intersect(q3)
|
|
1353
|
+
*/
|
|
1354
|
+
declare class UnionableQuery<G extends GraphDef, R> {
|
|
1355
|
+
#private;
|
|
1356
|
+
constructor(config: QueryBuilderConfig, state: UnionableQueryState);
|
|
1357
|
+
/**
|
|
1358
|
+
* Combines with another query using UNION.
|
|
1359
|
+
*/
|
|
1360
|
+
union(other: ExecutableQueryLike<G, R>): UnionableQuery<G, R>;
|
|
1361
|
+
/**
|
|
1362
|
+
* Combines with another query using UNION ALL.
|
|
1363
|
+
*/
|
|
1364
|
+
unionAll(other: ExecutableQueryLike<G, R>): UnionableQuery<G, R>;
|
|
1365
|
+
/**
|
|
1366
|
+
* Combines with another query using INTERSECT.
|
|
1367
|
+
*/
|
|
1368
|
+
intersect(other: ExecutableQueryLike<G, R>): UnionableQuery<G, R>;
|
|
1369
|
+
/**
|
|
1370
|
+
* Combines with another query using EXCEPT.
|
|
1371
|
+
*/
|
|
1372
|
+
except(other: ExecutableQueryLike<G, R>): UnionableQuery<G, R>;
|
|
1373
|
+
/**
|
|
1374
|
+
* Limits the number of results from the combined query.
|
|
1375
|
+
*/
|
|
1376
|
+
limit(n: number): UnionableQuery<G, R>;
|
|
1377
|
+
/**
|
|
1378
|
+
* Offsets the results from the combined query.
|
|
1379
|
+
*/
|
|
1380
|
+
offset(n: number): UnionableQuery<G, R>;
|
|
1381
|
+
/**
|
|
1382
|
+
* Builds the set operation AST.
|
|
1383
|
+
*/
|
|
1384
|
+
toAst(): SetOperation;
|
|
1385
|
+
/**
|
|
1386
|
+
* Compiles the set operation to SQL.
|
|
1387
|
+
*/
|
|
1388
|
+
compile(): SQL;
|
|
1389
|
+
/**
|
|
1390
|
+
* Executes the combined query.
|
|
1391
|
+
*/
|
|
1392
|
+
execute(): Promise<readonly R[]>;
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1395
|
+
/**
|
|
1396
|
+
* ExecutableQuery - A query that can be executed, paginated, or streamed.
|
|
1397
|
+
*/
|
|
1398
|
+
|
|
1399
|
+
/**
|
|
1400
|
+
* A query that can be executed.
|
|
1401
|
+
*/
|
|
1402
|
+
declare class ExecutableQuery<G extends GraphDef, Aliases extends AliasMap, EdgeAliases extends EdgeAliasMap = {}, R = unknown> {
|
|
1403
|
+
#private;
|
|
1404
|
+
constructor(config: QueryBuilderConfig, state: QueryBuilderState, selectFunction: (context: SelectContext<Aliases, EdgeAliases>) => R);
|
|
1405
|
+
/**
|
|
1406
|
+
* Builds the query AST.
|
|
1407
|
+
*/
|
|
1408
|
+
toAst(): QueryAst;
|
|
1409
|
+
/**
|
|
1410
|
+
* Orders results.
|
|
1411
|
+
*/
|
|
1412
|
+
orderBy<A extends keyof Aliases & string>(alias: A, field: string, direction?: SortDirection): ExecutableQuery<G, Aliases, EdgeAliases, R>;
|
|
1413
|
+
/**
|
|
1414
|
+
* Limits the number of results.
|
|
1415
|
+
*/
|
|
1416
|
+
limit(n: number): ExecutableQuery<G, Aliases, EdgeAliases, R>;
|
|
1417
|
+
/**
|
|
1418
|
+
* Offsets the results.
|
|
1419
|
+
*/
|
|
1420
|
+
offset(n: number): ExecutableQuery<G, Aliases, EdgeAliases, R>;
|
|
1421
|
+
/**
|
|
1422
|
+
* Applies a query fragment to transform this executable query.
|
|
1423
|
+
*
|
|
1424
|
+
* Useful for applying post-select transformations like ordering,
|
|
1425
|
+
* limits, and offsets from reusable fragments.
|
|
1426
|
+
*
|
|
1427
|
+
* @example
|
|
1428
|
+
* ```typescript
|
|
1429
|
+
* const paginated = (q) => q.orderBy("u", "createdAt", "desc").limit(10);
|
|
1430
|
+
*
|
|
1431
|
+
* const results = await query()
|
|
1432
|
+
* .from("User", "u")
|
|
1433
|
+
* .select((ctx) => ctx.u)
|
|
1434
|
+
* .pipe(paginated)
|
|
1435
|
+
* .execute();
|
|
1436
|
+
* ```
|
|
1437
|
+
*
|
|
1438
|
+
* @param fragment - A function that transforms the executable query
|
|
1439
|
+
* @returns The transformed executable query
|
|
1440
|
+
*/
|
|
1441
|
+
pipe<NewR = R>(fragment: (query: ExecutableQuery<G, Aliases, EdgeAliases, R>) => ExecutableQuery<G, Aliases, EdgeAliases, NewR>): ExecutableQuery<G, Aliases, EdgeAliases, NewR>;
|
|
1442
|
+
/**
|
|
1443
|
+
* Combines this query with another using UNION (removes duplicates).
|
|
1444
|
+
*/
|
|
1445
|
+
union(other: ExecutableQuery<G, any, any, R>): UnionableQuery<G, R>;
|
|
1446
|
+
/**
|
|
1447
|
+
* Combines this query with another using UNION ALL (keeps duplicates).
|
|
1448
|
+
*/
|
|
1449
|
+
unionAll(other: ExecutableQuery<G, any, any, R>): UnionableQuery<G, R>;
|
|
1450
|
+
/**
|
|
1451
|
+
* Combines this query with another using INTERSECT.
|
|
1452
|
+
*/
|
|
1453
|
+
intersect(other: ExecutableQuery<G, any, any, R>): UnionableQuery<G, R>;
|
|
1454
|
+
/**
|
|
1455
|
+
* Combines this query with another using EXCEPT.
|
|
1456
|
+
*/
|
|
1457
|
+
except(other: ExecutableQuery<G, any, any, R>): UnionableQuery<G, R>;
|
|
1458
|
+
/**
|
|
1459
|
+
* Compiles the query to a Drizzle SQL object.
|
|
1460
|
+
*
|
|
1461
|
+
* Returns a Drizzle SQL object that can be executed directly
|
|
1462
|
+
* with db.all(), db.get(), etc.
|
|
1463
|
+
*/
|
|
1464
|
+
compile(): SQL;
|
|
1465
|
+
/**
|
|
1466
|
+
* Executes the query and returns typed results.
|
|
1467
|
+
*
|
|
1468
|
+
* Uses smart optimization to detect when only specific fields are accessed
|
|
1469
|
+
* in the select callback. If the callback only accesses simple field
|
|
1470
|
+
* references (no method calls or computations), generates optimized SQL
|
|
1471
|
+
* that only extracts those fields instead of the full props blob.
|
|
1472
|
+
*
|
|
1473
|
+
* @throws Error if no backend is configured
|
|
1474
|
+
*/
|
|
1475
|
+
execute(): Promise<readonly R[]>;
|
|
1476
|
+
/**
|
|
1477
|
+
* Executes a paginated query using cursor-based keyset pagination.
|
|
1478
|
+
*
|
|
1479
|
+
* Cursor pagination is efficient for large datasets as it avoids OFFSET.
|
|
1480
|
+
* Requires ORDER BY to be specified for deterministic results.
|
|
1481
|
+
*
|
|
1482
|
+
* @param options - Pagination options (first/after for forward, last/before for backward)
|
|
1483
|
+
* @throws ValidationError if ORDER BY is not specified
|
|
1484
|
+
* @throws ValidationError if cursor columns don't match query ORDER BY columns
|
|
1485
|
+
*/
|
|
1486
|
+
paginate(options: PaginateOptions): Promise<PaginatedResult<R>>;
|
|
1487
|
+
/**
|
|
1488
|
+
* Returns an async iterator that streams results in batches.
|
|
1489
|
+
*
|
|
1490
|
+
* Uses cursor pagination internally for efficient memory usage.
|
|
1491
|
+
* Requires ORDER BY to be specified for deterministic results.
|
|
1492
|
+
*
|
|
1493
|
+
* @param options - Stream options (batchSize defaults to 1000)
|
|
1494
|
+
* @throws ValidationError if ORDER BY is not specified
|
|
1495
|
+
*/
|
|
1496
|
+
stream(options?: StreamOptions): AsyncIterable<R>;
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
/**
|
|
1500
|
+
* TraversalBuilder - Intermediate builder for edge traversals.
|
|
1501
|
+
*/
|
|
1502
|
+
|
|
1503
|
+
/**
|
|
1504
|
+
* State for variable-length traversal configuration.
|
|
1505
|
+
*/
|
|
1506
|
+
interface VariableLengthState {
|
|
1507
|
+
enabled: boolean;
|
|
1508
|
+
minDepth: number;
|
|
1509
|
+
maxDepth: number;
|
|
1510
|
+
collectPath: boolean;
|
|
1511
|
+
pathAlias?: string;
|
|
1512
|
+
depthAlias?: string;
|
|
1513
|
+
}
|
|
1514
|
+
/**
|
|
1515
|
+
* Intermediate builder for traversal operations.
|
|
1516
|
+
*
|
|
1517
|
+
* Type parameters track the edge kind and direction to constrain
|
|
1518
|
+
* which node kinds are valid targets in the `to()` method.
|
|
1519
|
+
*/
|
|
1520
|
+
declare class TraversalBuilder<G extends GraphDef, Aliases extends AliasMap, EdgeAliases extends EdgeAliasMap = {}, EK extends keyof G["edges"] & string = keyof G["edges"] & string, EA extends string = string, Dir extends TraversalDirection = "out", Optional extends boolean = false> {
|
|
1521
|
+
#private;
|
|
1522
|
+
constructor(config: QueryBuilderConfig, state: QueryBuilderState, edgeKinds: readonly string[], edgeAlias: EA, direction: Dir, fromAlias: string, optional?: Optional, variableLength?: VariableLengthState, pendingEdgePredicates?: readonly NodePredicate[]);
|
|
1523
|
+
/**
|
|
1524
|
+
* Enables variable-length (recursive) traversal.
|
|
1525
|
+
* By default, traverses unlimited depth with cycle detection.
|
|
1526
|
+
*/
|
|
1527
|
+
recursive(): TraversalBuilder<G, Aliases, EdgeAliases, EK, EA, Dir, Optional>;
|
|
1528
|
+
/**
|
|
1529
|
+
* Sets the maximum traversal depth.
|
|
1530
|
+
* @param max Maximum number of hops (must be >= 1)
|
|
1531
|
+
*/
|
|
1532
|
+
maxHops(max: number): TraversalBuilder<G, Aliases, EdgeAliases, EK, EA, Dir, Optional>;
|
|
1533
|
+
/**
|
|
1534
|
+
* Sets the minimum traversal depth (skip nodes closer than this).
|
|
1535
|
+
* @param min Minimum hops before including results (default: 1)
|
|
1536
|
+
*/
|
|
1537
|
+
minHops(min: number): TraversalBuilder<G, Aliases, EdgeAliases, EK, EA, Dir, Optional>;
|
|
1538
|
+
/**
|
|
1539
|
+
* Includes the traversal path as an array in results.
|
|
1540
|
+
* @param alias Column alias for the path array (default: "{nodeAlias}_path")
|
|
1541
|
+
*/
|
|
1542
|
+
collectPath(alias?: string): TraversalBuilder<G, Aliases, EdgeAliases, EK, EA, Dir, Optional>;
|
|
1543
|
+
/**
|
|
1544
|
+
* Includes the traversal depth in results.
|
|
1545
|
+
* @param alias Column alias for the depth (default: "{nodeAlias}_depth")
|
|
1546
|
+
*/
|
|
1547
|
+
withDepth(alias?: string): TraversalBuilder<G, Aliases, EdgeAliases, EK, EA, Dir, Optional>;
|
|
1548
|
+
/**
|
|
1549
|
+
* Adds a WHERE clause for the edge being traversed.
|
|
1550
|
+
*
|
|
1551
|
+
* @param alias - The edge alias to filter on (must be the current edge alias)
|
|
1552
|
+
* @param predicateFunction - A function that builds predicates using the edge accessor
|
|
1553
|
+
*/
|
|
1554
|
+
whereEdge(alias: EA, predicateFunction: (edge: EdgeAccessor<G["edges"][EK]["type"]>) => Predicate): TraversalBuilder<G, Aliases, EdgeAliases, EK, EA, Dir, Optional>;
|
|
1555
|
+
/**
|
|
1556
|
+
* Specifies the target node kind.
|
|
1557
|
+
*
|
|
1558
|
+
* The kind must be a valid target for this edge based on the traversal direction:
|
|
1559
|
+
* - "out" direction: kind must be in the edge's "to" array
|
|
1560
|
+
* - "in" direction: kind must be in the edge's "from" array
|
|
1561
|
+
*
|
|
1562
|
+
* @param kind - The target node kind
|
|
1563
|
+
* @param alias - A unique alias for this node (compile-time error if duplicate)
|
|
1564
|
+
*/
|
|
1565
|
+
to<K extends ValidEdgeTargets<G, EK, Dir>, A extends string>(kind: K, alias: UniqueAlias<A, Aliases>, options?: {
|
|
1566
|
+
includeSubClasses?: false;
|
|
1567
|
+
}): QueryBuilder<G, Aliases & Record<A, NodeAlias<G["nodes"][K]["type"], Optional>>, EdgeAliases & Record<EA, EdgeAlias<G["edges"][EK]["type"], Optional>>>;
|
|
1568
|
+
to<K extends ValidEdgeTargets<G, EK, Dir>, A extends string>(kind: K, alias: UniqueAlias<A, Aliases>, options: {
|
|
1569
|
+
includeSubClasses: true;
|
|
1570
|
+
}): QueryBuilder<G, Aliases & Record<A, NodeAlias<NodeType, Optional>>, EdgeAliases & Record<EA, EdgeAlias<G["edges"][EK]["type"], Optional>>>;
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
/**
|
|
1574
|
+
* QueryBuilder - The fluent query builder.
|
|
1575
|
+
*/
|
|
1576
|
+
|
|
1577
|
+
/**
|
|
1578
|
+
* The fluent query builder.
|
|
1579
|
+
*
|
|
1580
|
+
* Type parameters accumulate as methods are chained:
|
|
1581
|
+
* - G: The graph definition
|
|
1582
|
+
* - Aliases: Map of alias names to their node kinds
|
|
1583
|
+
* - EdgeAliases: Map of alias names to their edge kinds (accumulated during traversals)
|
|
1584
|
+
*/
|
|
1585
|
+
declare class QueryBuilder<G extends GraphDef, Aliases extends AliasMap = {}, EdgeAliases extends EdgeAliasMap = {}> {
|
|
1586
|
+
#private;
|
|
1587
|
+
constructor(config: QueryBuilderConfig, state: QueryBuilderState);
|
|
1588
|
+
/**
|
|
1589
|
+
* Starts a query from a node kind.
|
|
1590
|
+
*
|
|
1591
|
+
* @param kind - The node kind to start from
|
|
1592
|
+
* @param alias - A unique alias for this node (compile-time error if duplicate)
|
|
1593
|
+
*/
|
|
1594
|
+
from<K extends keyof G["nodes"] & string, A extends string>(kind: K, alias: UniqueAlias<A, Aliases>, options?: {
|
|
1595
|
+
includeSubClasses?: false;
|
|
1596
|
+
}): QueryBuilder<G, Aliases & Record<A, NodeAlias<G["nodes"][K]["type"]>>, EdgeAliases>;
|
|
1597
|
+
from<K extends keyof G["nodes"] & string, A extends string>(kind: K, alias: UniqueAlias<A, Aliases>, options: {
|
|
1598
|
+
includeSubClasses: true;
|
|
1599
|
+
}): QueryBuilder<G, Aliases & Record<A, NodeAlias>, EdgeAliases>;
|
|
1600
|
+
/**
|
|
1601
|
+
* Adds a WHERE clause for a node.
|
|
1602
|
+
*/
|
|
1603
|
+
whereNode<A extends keyof Aliases & string>(alias: A, predicateFunction: (n: NodeAccessor<Aliases[A]["kind"]>) => Predicate): QueryBuilder<G, Aliases, EdgeAliases>;
|
|
1604
|
+
/**
|
|
1605
|
+
* Adds a WHERE clause for an edge.
|
|
1606
|
+
*
|
|
1607
|
+
* @param alias - The edge alias to filter on
|
|
1608
|
+
* @param predicateFunction - A function that builds predicates using the edge accessor
|
|
1609
|
+
*/
|
|
1610
|
+
whereEdge<EA extends keyof EdgeAliases & string>(alias: EA, predicateFunction: (edge: EdgeAccessor<EdgeAliases[EA]["kind"]>) => Predicate): QueryBuilder<G, Aliases, EdgeAliases>;
|
|
1611
|
+
/**
|
|
1612
|
+
* Traverses an edge to another node (outgoing direction).
|
|
1613
|
+
*
|
|
1614
|
+
* By default, traverses from the current node (last traversal target, or start node).
|
|
1615
|
+
* Use the `from` option to traverse from a different alias (fan-out pattern).
|
|
1616
|
+
*
|
|
1617
|
+
* @param options.includeImplyingEdges - If true, also match edges that imply this edge kind
|
|
1618
|
+
* @param options.from - Alias to traverse from (defaults to current/last traversal target)
|
|
1619
|
+
*/
|
|
1620
|
+
traverse<EK extends keyof G["edges"] & string, EA extends string>(edgeKind: EK, edgeAlias: EA, options?: {
|
|
1621
|
+
direction?: "out";
|
|
1622
|
+
includeImplyingEdges?: boolean;
|
|
1623
|
+
from?: keyof Aliases & string;
|
|
1624
|
+
}): TraversalBuilder<G, Aliases, EdgeAliases, EK, EA>;
|
|
1625
|
+
/**
|
|
1626
|
+
* Traverses an edge to another node (incoming direction).
|
|
1627
|
+
*
|
|
1628
|
+
* By default, traverses from the current node (last traversal target, or start node).
|
|
1629
|
+
* Use the `from` option to traverse from a different alias (fan-out pattern).
|
|
1630
|
+
*
|
|
1631
|
+
* @param options.direction - Set to "in" for incoming edge traversal
|
|
1632
|
+
* @param options.includeImplyingEdges - If true, also match edges that imply this edge kind
|
|
1633
|
+
* @param options.from - Alias to traverse from (defaults to current/last traversal target)
|
|
1634
|
+
*/
|
|
1635
|
+
traverse<EK extends keyof G["edges"] & string, EA extends string>(edgeKind: EK, edgeAlias: EA, options: {
|
|
1636
|
+
direction: "in";
|
|
1637
|
+
includeImplyingEdges?: boolean;
|
|
1638
|
+
from?: keyof Aliases & string;
|
|
1639
|
+
}): TraversalBuilder<G, Aliases, EdgeAliases, EK, EA, "in">;
|
|
1640
|
+
/**
|
|
1641
|
+
* Optionally traverses an edge to another node (LEFT JOIN semantics).
|
|
1642
|
+
* If no matching edge/node exists, the result will include null values.
|
|
1643
|
+
*
|
|
1644
|
+
* By default, traverses from the current node (last traversal target, or start node).
|
|
1645
|
+
* Use the `from` option to traverse from a different alias (fan-out pattern).
|
|
1646
|
+
*
|
|
1647
|
+
* @param options.direction - Direction of traversal: "out" (default) or "in"
|
|
1648
|
+
* @param options.includeImplyingEdges - If true, also match edges that imply this edge kind
|
|
1649
|
+
* @param options.from - Alias to traverse from (defaults to current/last traversal target)
|
|
1650
|
+
*/
|
|
1651
|
+
optionalTraverse<EK extends keyof G["edges"] & string, EA extends string>(edgeKind: EK, edgeAlias: EA, options?: {
|
|
1652
|
+
direction?: "out";
|
|
1653
|
+
includeImplyingEdges?: boolean;
|
|
1654
|
+
from?: keyof Aliases & string;
|
|
1655
|
+
}): TraversalBuilder<G, Aliases, EdgeAliases, EK, EA, "out", true>;
|
|
1656
|
+
optionalTraverse<EK extends keyof G["edges"] & string, EA extends string>(edgeKind: EK, edgeAlias: EA, options: {
|
|
1657
|
+
direction: "in";
|
|
1658
|
+
includeImplyingEdges?: boolean;
|
|
1659
|
+
from?: keyof Aliases & string;
|
|
1660
|
+
}): TraversalBuilder<G, Aliases, EdgeAliases, EK, EA, "in", true>;
|
|
1661
|
+
/**
|
|
1662
|
+
* Selects fields to return.
|
|
1663
|
+
*/
|
|
1664
|
+
select<R>(selectFunction: (context: SelectContext<Aliases, EdgeAliases>) => R): ExecutableQuery<G, Aliases, EdgeAliases, R>;
|
|
1665
|
+
/**
|
|
1666
|
+
* Selects fields including aggregates.
|
|
1667
|
+
* Use with groupBy() for aggregate queries.
|
|
1668
|
+
*
|
|
1669
|
+
* @param fields - Object mapping output names to field refs or aggregate expressions
|
|
1670
|
+
*/
|
|
1671
|
+
selectAggregate<R extends Record<string, FieldRef | AggregateExpr>>(fields: R): ExecutableAggregateQuery<G, Aliases, R>;
|
|
1672
|
+
/**
|
|
1673
|
+
* Orders results.
|
|
1674
|
+
*/
|
|
1675
|
+
orderBy<A extends keyof Aliases & string>(alias: A, field: string, direction?: SortDirection): QueryBuilder<G, Aliases, EdgeAliases>;
|
|
1676
|
+
/**
|
|
1677
|
+
* Limits the number of results.
|
|
1678
|
+
*/
|
|
1679
|
+
limit(n: number): QueryBuilder<G, Aliases, EdgeAliases>;
|
|
1680
|
+
/**
|
|
1681
|
+
* Offsets the results.
|
|
1682
|
+
*/
|
|
1683
|
+
offset(n: number): QueryBuilder<G, Aliases, EdgeAliases>;
|
|
1684
|
+
/**
|
|
1685
|
+
* Sets temporal mode.
|
|
1686
|
+
*
|
|
1687
|
+
* @param mode - The temporal mode to use
|
|
1688
|
+
* @param asOf - Required timestamp for "asOf" mode (ISO 8601 string)
|
|
1689
|
+
* @throws ValidationError if mode is "asOf" but no timestamp is provided
|
|
1690
|
+
*/
|
|
1691
|
+
temporal(mode: TemporalMode, asOf?: string): QueryBuilder<G, Aliases, EdgeAliases>;
|
|
1692
|
+
/**
|
|
1693
|
+
* Groups results by the specified field.
|
|
1694
|
+
* Use with aggregate functions like COUNT, SUM, AVG in select().
|
|
1695
|
+
*
|
|
1696
|
+
* @param alias - The node alias to group by
|
|
1697
|
+
* @param field - The field name to group by
|
|
1698
|
+
*/
|
|
1699
|
+
groupBy<A extends keyof Aliases & string>(alias: A, field: string): QueryBuilder<G, Aliases, EdgeAliases>;
|
|
1700
|
+
/**
|
|
1701
|
+
* Groups results by the node ID.
|
|
1702
|
+
* Use when you want to group by a complete node rather than a specific field.
|
|
1703
|
+
*
|
|
1704
|
+
* @param alias - The node alias to group by (uses the node's ID)
|
|
1705
|
+
*/
|
|
1706
|
+
groupByNode<A extends keyof Aliases & string>(alias: A): QueryBuilder<G, Aliases, EdgeAliases>;
|
|
1707
|
+
/**
|
|
1708
|
+
* Filters grouped results using aggregate conditions (HAVING clause).
|
|
1709
|
+
* Use after groupBy() to filter based on aggregate values.
|
|
1710
|
+
*
|
|
1711
|
+
* @param predicate - A predicate expression to filter groups
|
|
1712
|
+
*/
|
|
1713
|
+
having(predicate: PredicateExpression): QueryBuilder<G, Aliases, EdgeAliases>;
|
|
1714
|
+
/**
|
|
1715
|
+
* Applies a query fragment to transform this builder.
|
|
1716
|
+
*
|
|
1717
|
+
* Fragments are reusable query transformations that can add predicates,
|
|
1718
|
+
* traversals, ordering, and other query operations. Use this for
|
|
1719
|
+
* composing complex queries from simpler, reusable parts.
|
|
1720
|
+
*
|
|
1721
|
+
* @example
|
|
1722
|
+
* ```typescript
|
|
1723
|
+
* // Define a reusable fragment
|
|
1724
|
+
* const activeUsers = createFragment<MyGraph>()((q) =>
|
|
1725
|
+
* q.whereNode("u", ({ status }) => status.eq("active"))
|
|
1726
|
+
* );
|
|
1727
|
+
*
|
|
1728
|
+
* // Apply the fragment
|
|
1729
|
+
* const results = await query()
|
|
1730
|
+
* .from("User", "u")
|
|
1731
|
+
* .pipe(activeUsers)
|
|
1732
|
+
* .select((ctx) => ctx.u)
|
|
1733
|
+
* .execute();
|
|
1734
|
+
* ```
|
|
1735
|
+
*
|
|
1736
|
+
* @param fragment - A function that transforms the builder
|
|
1737
|
+
* @returns The transformed builder
|
|
1738
|
+
*/
|
|
1739
|
+
pipe<OutAliases extends AliasMap, OutEdgeAliases extends EdgeAliasMap = EdgeAliases>(fragment: (builder: QueryBuilder<G, Aliases, EdgeAliases>) => QueryBuilder<G, OutAliases, OutEdgeAliases>): QueryBuilder<G, OutAliases, OutEdgeAliases>;
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
/**
|
|
1743
|
+
* Types for serialized schema storage.
|
|
1744
|
+
*
|
|
1745
|
+
* These types represent the JSON-serializable format used for
|
|
1746
|
+
* homoiconic schema storage in the database.
|
|
1747
|
+
*/
|
|
1748
|
+
|
|
1749
|
+
/**
|
|
1750
|
+
* JSON Schema type (subset used by Zod toJSONSchema).
|
|
1751
|
+
*
|
|
1752
|
+
* This is a simplified version - the actual JSON Schema has many more properties.
|
|
1753
|
+
*/
|
|
1754
|
+
type JsonSchema = Readonly<{
|
|
1755
|
+
$schema?: string;
|
|
1756
|
+
type?: string | readonly string[];
|
|
1757
|
+
properties?: Record<string, JsonSchema>;
|
|
1758
|
+
required?: readonly string[];
|
|
1759
|
+
items?: JsonSchema;
|
|
1760
|
+
additionalProperties?: boolean | JsonSchema;
|
|
1761
|
+
enum?: readonly unknown[];
|
|
1762
|
+
const?: unknown;
|
|
1763
|
+
anyOf?: readonly JsonSchema[];
|
|
1764
|
+
oneOf?: readonly JsonSchema[];
|
|
1765
|
+
allOf?: readonly JsonSchema[];
|
|
1766
|
+
not?: JsonSchema;
|
|
1767
|
+
description?: string;
|
|
1768
|
+
default?: unknown;
|
|
1769
|
+
minimum?: number;
|
|
1770
|
+
maximum?: number;
|
|
1771
|
+
minLength?: number;
|
|
1772
|
+
maxLength?: number;
|
|
1773
|
+
pattern?: string;
|
|
1774
|
+
format?: string;
|
|
1775
|
+
[key: string]: unknown;
|
|
1776
|
+
}>;
|
|
1777
|
+
/**
|
|
1778
|
+
* Serialized representation of a meta-edge.
|
|
1779
|
+
*/
|
|
1780
|
+
type SerializedMetaEdge = Readonly<{
|
|
1781
|
+
name: string;
|
|
1782
|
+
transitive: boolean;
|
|
1783
|
+
symmetric: boolean;
|
|
1784
|
+
reflexive: boolean;
|
|
1785
|
+
inverse: string | undefined;
|
|
1786
|
+
inference: InferenceType;
|
|
1787
|
+
description: string | undefined;
|
|
1788
|
+
}>;
|
|
1789
|
+
/**
|
|
1790
|
+
* Serialized representation of an ontology relation.
|
|
1791
|
+
*/
|
|
1792
|
+
type SerializedOntologyRelation = Readonly<{
|
|
1793
|
+
metaEdge: string;
|
|
1794
|
+
from: string;
|
|
1795
|
+
to: string;
|
|
1796
|
+
}>;
|
|
1797
|
+
/**
|
|
1798
|
+
* Precomputed closures stored in the schema for fast runtime lookup.
|
|
1799
|
+
*/
|
|
1800
|
+
type SerializedClosures = Readonly<{
|
|
1801
|
+
subClassAncestors: Record<string, readonly string[]>;
|
|
1802
|
+
subClassDescendants: Record<string, readonly string[]>;
|
|
1803
|
+
broaderClosure: Record<string, readonly string[]>;
|
|
1804
|
+
narrowerClosure: Record<string, readonly string[]>;
|
|
1805
|
+
equivalenceSets: Record<string, readonly string[]>;
|
|
1806
|
+
disjointPairs: readonly string[];
|
|
1807
|
+
partOfClosure: Record<string, readonly string[]>;
|
|
1808
|
+
hasPartClosure: Record<string, readonly string[]>;
|
|
1809
|
+
iriToKind: Record<string, string>;
|
|
1810
|
+
edgeInverses: Record<string, string>;
|
|
1811
|
+
edgeImplicationsClosure: Record<string, readonly string[]>;
|
|
1812
|
+
edgeImplyingClosure: Record<string, readonly string[]>;
|
|
1813
|
+
}>;
|
|
1814
|
+
/**
|
|
1815
|
+
* Complete serialized ontology section.
|
|
1816
|
+
*/
|
|
1817
|
+
type SerializedOntology = Readonly<{
|
|
1818
|
+
metaEdges: Record<string, SerializedMetaEdge>;
|
|
1819
|
+
relations: readonly SerializedOntologyRelation[];
|
|
1820
|
+
closures: SerializedClosures;
|
|
1821
|
+
}>;
|
|
1822
|
+
/**
|
|
1823
|
+
* Serialized representation of a uniqueness constraint.
|
|
1824
|
+
*/
|
|
1825
|
+
type SerializedUniqueConstraint = Readonly<{
|
|
1826
|
+
name: string;
|
|
1827
|
+
fields: readonly string[];
|
|
1828
|
+
where: string | undefined;
|
|
1829
|
+
scope: UniquenessScope;
|
|
1830
|
+
collation: Collation;
|
|
1831
|
+
}>;
|
|
1832
|
+
/**
|
|
1833
|
+
* Serialized representation of a node kind.
|
|
1834
|
+
*/
|
|
1835
|
+
type SerializedNodeDef = Readonly<{
|
|
1836
|
+
name: string;
|
|
1837
|
+
properties: JsonSchema;
|
|
1838
|
+
uniqueConstraints: readonly SerializedUniqueConstraint[];
|
|
1839
|
+
onDelete: DeleteBehavior;
|
|
1840
|
+
description: string | undefined;
|
|
1841
|
+
}>;
|
|
1842
|
+
/**
|
|
1843
|
+
* Serialized representation of an edge kind.
|
|
1844
|
+
*/
|
|
1845
|
+
type SerializedEdgeDef = Readonly<{
|
|
1846
|
+
name: string;
|
|
1847
|
+
fromKinds: readonly string[];
|
|
1848
|
+
toKinds: readonly string[];
|
|
1849
|
+
properties: JsonSchema;
|
|
1850
|
+
cardinality: Cardinality;
|
|
1851
|
+
endpointExistence: EndpointExistence;
|
|
1852
|
+
description: string | undefined;
|
|
1853
|
+
}>;
|
|
1854
|
+
/**
|
|
1855
|
+
* Complete serialized schema document.
|
|
1856
|
+
*
|
|
1857
|
+
* This is the format stored in the schema_doc column of
|
|
1858
|
+
* typegraph_schema_versions.
|
|
1859
|
+
*/
|
|
1860
|
+
type SerializedSchema = Readonly<{
|
|
1861
|
+
graphId: string;
|
|
1862
|
+
version: number;
|
|
1863
|
+
generatedAt: string;
|
|
1864
|
+
nodes: Record<string, SerializedNodeDef>;
|
|
1865
|
+
edges: Record<string, SerializedEdgeDef>;
|
|
1866
|
+
ontology: SerializedOntology;
|
|
1867
|
+
defaults: Readonly<{
|
|
1868
|
+
onNodeDelete: DeleteBehavior;
|
|
1869
|
+
temporalMode: TemporalMode;
|
|
1870
|
+
}>;
|
|
1871
|
+
}>;
|
|
1872
|
+
/**
|
|
1873
|
+
* A schema hash for detecting changes.
|
|
1874
|
+
*
|
|
1875
|
+
* We hash the schema content (excluding version and generatedAt)
|
|
1876
|
+
* to detect if the schema has actually changed.
|
|
1877
|
+
*/
|
|
1878
|
+
type SchemaHash = string;
|
|
1879
|
+
|
|
1880
|
+
/**
|
|
1881
|
+
* Schema migration utilities.
|
|
1882
|
+
*
|
|
1883
|
+
* Provides diff detection between schema versions to identify
|
|
1884
|
+
* what has changed and what migrations might be needed.
|
|
1885
|
+
*/
|
|
1886
|
+
|
|
1887
|
+
/**
|
|
1888
|
+
* Types of changes that can occur in a schema.
|
|
1889
|
+
*/
|
|
1890
|
+
type ChangeType = "added" | "removed" | "modified" | "renamed";
|
|
1891
|
+
/**
|
|
1892
|
+
* Severity of a change for migration purposes.
|
|
1893
|
+
*/
|
|
1894
|
+
type ChangeSeverity = "safe" | "warning" | "breaking";
|
|
1895
|
+
/**
|
|
1896
|
+
* A change to a node definition.
|
|
1897
|
+
*/
|
|
1898
|
+
type NodeChange = Readonly<{
|
|
1899
|
+
type: ChangeType;
|
|
1900
|
+
name: string;
|
|
1901
|
+
severity: ChangeSeverity;
|
|
1902
|
+
details: string;
|
|
1903
|
+
before?: SerializedNodeDef | undefined;
|
|
1904
|
+
after?: SerializedNodeDef | undefined;
|
|
1905
|
+
}>;
|
|
1906
|
+
/**
|
|
1907
|
+
* A change to an edge definition.
|
|
1908
|
+
*/
|
|
1909
|
+
type EdgeChange = Readonly<{
|
|
1910
|
+
type: ChangeType;
|
|
1911
|
+
name: string;
|
|
1912
|
+
severity: ChangeSeverity;
|
|
1913
|
+
details: string;
|
|
1914
|
+
before?: SerializedEdgeDef | undefined;
|
|
1915
|
+
after?: SerializedEdgeDef | undefined;
|
|
1916
|
+
}>;
|
|
1917
|
+
/**
|
|
1918
|
+
* A change to the ontology.
|
|
1919
|
+
*/
|
|
1920
|
+
type OntologyChange = Readonly<{
|
|
1921
|
+
type: ChangeType;
|
|
1922
|
+
entity: "metaEdge" | "relation";
|
|
1923
|
+
name: string;
|
|
1924
|
+
severity: ChangeSeverity;
|
|
1925
|
+
details: string;
|
|
1926
|
+
}>;
|
|
1927
|
+
/**
|
|
1928
|
+
* A complete diff between two schema versions.
|
|
1929
|
+
*/
|
|
1930
|
+
type SchemaDiff = Readonly<{
|
|
1931
|
+
fromVersion: number;
|
|
1932
|
+
toVersion: number;
|
|
1933
|
+
/** Changes to node definitions */
|
|
1934
|
+
nodes: readonly NodeChange[];
|
|
1935
|
+
/** Changes to edge definitions */
|
|
1936
|
+
edges: readonly EdgeChange[];
|
|
1937
|
+
/** Changes to ontology */
|
|
1938
|
+
ontology: readonly OntologyChange[];
|
|
1939
|
+
/** Whether any breaking changes exist */
|
|
1940
|
+
hasBreakingChanges: boolean;
|
|
1941
|
+
/** Whether any changes exist at all */
|
|
1942
|
+
hasChanges: boolean;
|
|
1943
|
+
/** Summary of changes */
|
|
1944
|
+
summary: string;
|
|
1945
|
+
}>;
|
|
1946
|
+
/**
|
|
1947
|
+
* Computes the diff between two schema versions.
|
|
1948
|
+
*
|
|
1949
|
+
* @param before - The previous schema version
|
|
1950
|
+
* @param after - The new schema version
|
|
1951
|
+
* @returns A diff describing all changes
|
|
1952
|
+
*/
|
|
1953
|
+
declare function computeSchemaDiff(before: SerializedSchema, after: SerializedSchema): SchemaDiff;
|
|
1954
|
+
/**
|
|
1955
|
+
* Checks if a schema change is backwards compatible.
|
|
1956
|
+
*
|
|
1957
|
+
* A change is backwards compatible if:
|
|
1958
|
+
* - No nodes or edges were removed
|
|
1959
|
+
* - No required properties were added
|
|
1960
|
+
* - No existing properties were removed
|
|
1961
|
+
*/
|
|
1962
|
+
declare function isBackwardsCompatible(diff: SchemaDiff): boolean;
|
|
1963
|
+
/**
|
|
1964
|
+
* Gets a list of actions needed for migration.
|
|
1965
|
+
*/
|
|
1966
|
+
declare function getMigrationActions(diff: SchemaDiff): readonly string[];
|
|
1967
|
+
|
|
1968
|
+
/**
|
|
1969
|
+
* Schema manager for TypeGraph.
|
|
1970
|
+
*
|
|
1971
|
+
* Provides schema lifecycle management:
|
|
1972
|
+
* - Initialization on first store creation
|
|
1973
|
+
* - Validation on store open
|
|
1974
|
+
* - Auto-migration for safe changes
|
|
1975
|
+
* - Error reporting for breaking changes
|
|
1976
|
+
*/
|
|
1977
|
+
|
|
1978
|
+
/**
|
|
1979
|
+
* Result of schema validation.
|
|
1980
|
+
*/
|
|
1981
|
+
type SchemaValidationResult = {
|
|
1982
|
+
status: "initialized";
|
|
1983
|
+
version: number;
|
|
1984
|
+
} | {
|
|
1985
|
+
status: "unchanged";
|
|
1986
|
+
version: number;
|
|
1987
|
+
} | {
|
|
1988
|
+
status: "migrated";
|
|
1989
|
+
fromVersion: number;
|
|
1990
|
+
toVersion: number;
|
|
1991
|
+
diff: SchemaDiff;
|
|
1992
|
+
} | {
|
|
1993
|
+
status: "breaking";
|
|
1994
|
+
diff: SchemaDiff;
|
|
1995
|
+
actions: readonly string[];
|
|
1996
|
+
};
|
|
1997
|
+
/**
|
|
1998
|
+
* Options for schema management.
|
|
1999
|
+
*/
|
|
2000
|
+
type SchemaManagerOptions = Readonly<{
|
|
2001
|
+
/** If true, auto-migrate safe changes. Default: true */
|
|
2002
|
+
autoMigrate?: boolean;
|
|
2003
|
+
/** If true, throw on breaking changes. Default: true */
|
|
2004
|
+
throwOnBreaking?: boolean;
|
|
2005
|
+
}>;
|
|
2006
|
+
/**
|
|
2007
|
+
* Ensures the schema is initialized and up-to-date.
|
|
2008
|
+
*
|
|
2009
|
+
* This is the main entry point for schema management. It:
|
|
2010
|
+
* 1. Initializes the schema if this is the first run (version 1)
|
|
2011
|
+
* 2. Returns "unchanged" if the schema matches the current graph
|
|
2012
|
+
* 3. Auto-migrates safe changes if autoMigrate is true
|
|
2013
|
+
* 4. Throws MigrationError for breaking changes if throwOnBreaking is true
|
|
2014
|
+
*
|
|
2015
|
+
* @param backend - The database backend
|
|
2016
|
+
* @param graph - The current graph definition
|
|
2017
|
+
* @param options - Schema management options
|
|
2018
|
+
* @returns The result of schema validation
|
|
2019
|
+
* @throws MigrationError if breaking changes detected and throwOnBreaking is true
|
|
2020
|
+
*/
|
|
2021
|
+
declare function ensureSchema<G extends GraphDef>(backend: GraphBackend, graph: G, options?: SchemaManagerOptions): Promise<SchemaValidationResult>;
|
|
2022
|
+
/**
|
|
2023
|
+
* Initializes the schema for a new graph.
|
|
2024
|
+
*
|
|
2025
|
+
* Creates version 1 of the schema and marks it as active.
|
|
2026
|
+
*
|
|
2027
|
+
* @param backend - The database backend
|
|
2028
|
+
* @param graph - The graph definition
|
|
2029
|
+
* @returns The created schema version row
|
|
2030
|
+
*/
|
|
2031
|
+
declare function initializeSchema<G extends GraphDef>(backend: GraphBackend, graph: G): Promise<SchemaVersionRow>;
|
|
2032
|
+
/**
|
|
2033
|
+
* Migrates the schema to match the current graph definition.
|
|
2034
|
+
*
|
|
2035
|
+
* This creates a new schema version and marks it as active.
|
|
2036
|
+
* The old version is preserved for history/rollback.
|
|
2037
|
+
*
|
|
2038
|
+
* @param backend - The database backend
|
|
2039
|
+
* @param graph - The current graph definition
|
|
2040
|
+
* @param currentVersion - The current active schema version
|
|
2041
|
+
* @returns The new version number
|
|
2042
|
+
*/
|
|
2043
|
+
declare function migrateSchema<G extends GraphDef>(backend: GraphBackend, graph: G, currentVersion: number): Promise<number>;
|
|
2044
|
+
/**
|
|
2045
|
+
* Gets the current active schema for a graph.
|
|
2046
|
+
*
|
|
2047
|
+
* @param backend - The database backend
|
|
2048
|
+
* @param graphId - The graph ID
|
|
2049
|
+
* @returns The active schema or undefined if not initialized
|
|
2050
|
+
*/
|
|
2051
|
+
declare function getActiveSchema(backend: GraphBackend, graphId: string): Promise<SerializedSchema | undefined>;
|
|
2052
|
+
/**
|
|
2053
|
+
* Checks if a graph's schema has been initialized.
|
|
2054
|
+
*
|
|
2055
|
+
* @param backend - The database backend
|
|
2056
|
+
* @param graphId - The graph ID
|
|
2057
|
+
* @returns True if the schema has been initialized
|
|
2058
|
+
*/
|
|
2059
|
+
declare function isSchemaInitialized(backend: GraphBackend, graphId: string): Promise<boolean>;
|
|
2060
|
+
/**
|
|
2061
|
+
* Gets the schema diff between the stored schema and current graph.
|
|
2062
|
+
*
|
|
2063
|
+
* @param backend - The database backend
|
|
2064
|
+
* @param graph - The current graph definition
|
|
2065
|
+
* @returns The diff, or undefined if schema not initialized
|
|
2066
|
+
*/
|
|
2067
|
+
declare function getSchemaChanges<G extends GraphDef>(backend: GraphBackend, graph: G): Promise<SchemaDiff | undefined>;
|
|
2068
|
+
|
|
2069
|
+
/**
|
|
2070
|
+
* Main Store implementation for TypeGraph.
|
|
2071
|
+
*
|
|
2072
|
+
* The Store is the primary interface for interacting with a TypeGraph.
|
|
2073
|
+
* It coordinates:
|
|
2074
|
+
* - Node and edge CRUD operations
|
|
2075
|
+
* - Constraint validation
|
|
2076
|
+
* - Schema management
|
|
2077
|
+
* - Transaction handling
|
|
2078
|
+
*/
|
|
2079
|
+
|
|
2080
|
+
/**
|
|
2081
|
+
* The Store provides typed access to a TypeGraph database.
|
|
2082
|
+
*
|
|
2083
|
+
* @example
|
|
2084
|
+
* ```typescript
|
|
2085
|
+
* const store = createStore(myGraph, backend);
|
|
2086
|
+
*
|
|
2087
|
+
* // Create nodes using collection API
|
|
2088
|
+
* const person = await store.nodes.Person.create({
|
|
2089
|
+
* name: "Alice",
|
|
2090
|
+
* email: "alice@example.com",
|
|
2091
|
+
* });
|
|
2092
|
+
*
|
|
2093
|
+
* const company = await store.nodes.Company.create({
|
|
2094
|
+
* name: "Acme",
|
|
2095
|
+
* industry: "Technology",
|
|
2096
|
+
* });
|
|
2097
|
+
*
|
|
2098
|
+
* // Create edges
|
|
2099
|
+
* await store.edges.worksAt.create(
|
|
2100
|
+
* { kind: "Person", id: person.id },
|
|
2101
|
+
* { kind: "Company", id: company.id },
|
|
2102
|
+
* { role: "Engineer" }
|
|
2103
|
+
* );
|
|
2104
|
+
*
|
|
2105
|
+
* // Query with the fluent API
|
|
2106
|
+
* const results = await store.query()
|
|
2107
|
+
* .from("Person", "p")
|
|
2108
|
+
* .whereNode("p", (p) => p.name.eq("Alice"))
|
|
2109
|
+
* .select((ctx) => ctx.p)
|
|
2110
|
+
* .execute();
|
|
2111
|
+
* ```
|
|
2112
|
+
*/
|
|
2113
|
+
declare class Store<G extends GraphDef> {
|
|
2114
|
+
#private;
|
|
2115
|
+
constructor(graph: G, backend: GraphBackend, options?: StoreOptions);
|
|
2116
|
+
/** The graph definition */
|
|
2117
|
+
get graph(): G;
|
|
2118
|
+
/** The graph ID */
|
|
2119
|
+
get graphId(): string;
|
|
2120
|
+
/** The kind registry for ontology lookups */
|
|
2121
|
+
get registry(): KindRegistry;
|
|
2122
|
+
/** The database backend */
|
|
2123
|
+
get backend(): GraphBackend;
|
|
2124
|
+
/**
|
|
2125
|
+
* Node collections for ergonomic CRUD operations.
|
|
2126
|
+
*
|
|
2127
|
+
* @example
|
|
2128
|
+
* ```typescript
|
|
2129
|
+
* // Create a node
|
|
2130
|
+
* const person = await store.nodes.Person.create({ name: "Alice" });
|
|
2131
|
+
*
|
|
2132
|
+
* // Get by ID
|
|
2133
|
+
* const fetched = await store.nodes.Person.getById(person.id);
|
|
2134
|
+
*
|
|
2135
|
+
* // Find all
|
|
2136
|
+
* const people = await store.nodes.Person.find({ limit: 10 });
|
|
2137
|
+
* ```
|
|
2138
|
+
*/
|
|
2139
|
+
get nodes(): {
|
|
2140
|
+
[K in keyof G["nodes"] & string]-?: NodeCollection<G["nodes"][K]["type"]>;
|
|
2141
|
+
};
|
|
2142
|
+
/**
|
|
2143
|
+
* Edge collections for ergonomic CRUD operations.
|
|
2144
|
+
*
|
|
2145
|
+
* @example
|
|
2146
|
+
* ```typescript
|
|
2147
|
+
* // Create an edge
|
|
2148
|
+
* const edge = await store.edges.worksAt.create(
|
|
2149
|
+
* { kind: "Person", id: person.id },
|
|
2150
|
+
* { kind: "Company", id: company.id },
|
|
2151
|
+
* { role: "Engineer" }
|
|
2152
|
+
* );
|
|
2153
|
+
*
|
|
2154
|
+
* // Find edges from a node
|
|
2155
|
+
* const edges = await store.edges.worksAt.findFrom({ kind: "Person", id: person.id });
|
|
2156
|
+
* ```
|
|
2157
|
+
*/
|
|
2158
|
+
get edges(): {
|
|
2159
|
+
[K in keyof G["edges"] & string]-?: TypedEdgeCollection<G["edges"][K]>;
|
|
2160
|
+
};
|
|
2161
|
+
/**
|
|
2162
|
+
* Creates a query builder for this store.
|
|
2163
|
+
*
|
|
2164
|
+
* @example
|
|
2165
|
+
* ```typescript
|
|
2166
|
+
* const results = await store.query()
|
|
2167
|
+
* .from("Person", "p")
|
|
2168
|
+
* .whereNode("p", (p) => p.name.eq("Alice"))
|
|
2169
|
+
* .select((ctx) => ctx.p)
|
|
2170
|
+
* .execute();
|
|
2171
|
+
* ```
|
|
2172
|
+
*/
|
|
2173
|
+
query(): QueryBuilder<G>;
|
|
2174
|
+
/**
|
|
2175
|
+
* Executes a function within a transaction.
|
|
2176
|
+
*
|
|
2177
|
+
* The transaction context provides the same collection API as the Store:
|
|
2178
|
+
* - `tx.nodes.Person.create(...)` - Create a node
|
|
2179
|
+
* - `tx.edges.worksAt.create(...)` - Create an edge
|
|
2180
|
+
*
|
|
2181
|
+
* @example
|
|
2182
|
+
* ```typescript
|
|
2183
|
+
* await store.transaction(async (tx) => {
|
|
2184
|
+
* const person = await tx.nodes.Person.create({ name: "Alice" });
|
|
2185
|
+
* const company = await tx.nodes.Company.create({ name: "Acme" });
|
|
2186
|
+
* await tx.edges.worksAt.create(
|
|
2187
|
+
* { kind: "Person", id: person.id },
|
|
2188
|
+
* { kind: "Company", id: company.id },
|
|
2189
|
+
* { role: "Engineer" }
|
|
2190
|
+
* );
|
|
2191
|
+
* });
|
|
2192
|
+
* ```
|
|
2193
|
+
*/
|
|
2194
|
+
transaction<T>(fn: (tx: TransactionContext<G>) => Promise<T>): Promise<T>;
|
|
2195
|
+
/**
|
|
2196
|
+
* Closes the store and releases underlying resources.
|
|
2197
|
+
*
|
|
2198
|
+
* Note: When using the Drizzle adapter, this method does not close the database
|
|
2199
|
+
* connection itself, as Drizzle delegates connection management to the user.
|
|
2200
|
+
* You should close the underlying database connection (e.g., better-sqlite3 or pg pool)
|
|
2201
|
+
* using their respective APIs.
|
|
2202
|
+
*/
|
|
2203
|
+
close(): Promise<void>;
|
|
2204
|
+
}
|
|
2205
|
+
/**
|
|
2206
|
+
* Creates a new Store instance.
|
|
2207
|
+
*
|
|
2208
|
+
* @param graph - The graph definition
|
|
2209
|
+
* @param backend - The database backend
|
|
2210
|
+
* @param options - Optional store configuration including observability hooks
|
|
2211
|
+
* @returns A new Store instance
|
|
2212
|
+
*
|
|
2213
|
+
* @example
|
|
2214
|
+
* ```typescript
|
|
2215
|
+
* // Basic usage
|
|
2216
|
+
* const store = createStore(graph, backend);
|
|
2217
|
+
*
|
|
2218
|
+
* // With observability hooks
|
|
2219
|
+
* const store = createStore(graph, backend, {
|
|
2220
|
+
* hooks: {
|
|
2221
|
+
* onOperationStart: (ctx) => {
|
|
2222
|
+
* console.log(`Starting ${ctx.operation} on ${ctx.entity}:${ctx.kind}`);
|
|
2223
|
+
* },
|
|
2224
|
+
* onOperationEnd: (ctx, result) => {
|
|
2225
|
+
* console.log(`Completed in ${result.durationMs}ms`);
|
|
2226
|
+
* },
|
|
2227
|
+
* onError: (ctx, error) => {
|
|
2228
|
+
* console.error(`Operation ${ctx.operationId} failed:`, error);
|
|
2229
|
+
* },
|
|
2230
|
+
* },
|
|
2231
|
+
* });
|
|
2232
|
+
* ```
|
|
2233
|
+
*/
|
|
2234
|
+
declare function createStore<G extends GraphDef>(graph: G, backend: GraphBackend, options?: StoreOptions): Store<G>;
|
|
2235
|
+
|
|
2236
|
+
/**
|
|
2237
|
+
* Creates a store and ensures the schema is initialized/migrated.
|
|
2238
|
+
*
|
|
2239
|
+
* This is the recommended way to create a store in production.
|
|
2240
|
+
* It automatically:
|
|
2241
|
+
* - Initializes the schema on first run (version 1)
|
|
2242
|
+
* - Auto-migrates safe changes (additive changes)
|
|
2243
|
+
* - Throws MigrationError for breaking changes
|
|
2244
|
+
*
|
|
2245
|
+
* @param graph - The graph definition
|
|
2246
|
+
* @param backend - The database backend
|
|
2247
|
+
* @param options - Store and schema options
|
|
2248
|
+
* @returns A tuple of [store, validationResult]
|
|
2249
|
+
*
|
|
2250
|
+
* @example
|
|
2251
|
+
* ```typescript
|
|
2252
|
+
* const [store, result] = await createStoreWithSchema(graph, backend);
|
|
2253
|
+
*
|
|
2254
|
+
* if (result.status === "initialized") {
|
|
2255
|
+
* console.log("Schema initialized at version", result.version);
|
|
2256
|
+
* } else if (result.status === "migrated") {
|
|
2257
|
+
* console.log(`Migrated from v${result.fromVersion} to v${result.toVersion}`);
|
|
2258
|
+
* }
|
|
2259
|
+
* ```
|
|
2260
|
+
*/
|
|
2261
|
+
declare function createStoreWithSchema<G extends GraphDef>(graph: G, backend: GraphBackend, options?: StoreOptions & SchemaManagerOptions): Promise<[Store<G>, SchemaValidationResult]>;
|
|
2262
|
+
|
|
2263
|
+
export { type QueryOptions as $, type AliasMap as A, type NodeAlias as B, type CreateQueryBuilderOptions as C, type NodeChange as D, type EdgeAliasMap as E, type FieldAccessor as F, type GraphDef as G, type HookContext as H, type InferenceType as I, type JsonSchema as J, KindRegistry as K, type NodeCollection as L, type MetaEdge as M, type Node as N, type OntologyRelation as O, type NodeRef as P, QueryBuilder as Q, type NodeTypeNames as R, Store as S, TraversalBuilder as T, type OntologyChange as U, type OperationHookContext as V, type PaginateOptions as W, type PaginatedResult as X, type Predicate as Y, type PropsAccessor as Z, type QueryHookContext as _, type SerializedNodeDef as a, type SchemaDiff as a0, type SchemaManagerOptions as a1, type SchemaValidationResult as a2, type SelectContext as a3, type SelectableEdge as a4, type SelectableNode as a5, type SerializedOntology as a6, type SerializedUniqueConstraint as a7, type StoreConfig as a8, type StoreHooks as a9, isMetaEdge as aA, isSchemaInitialized as aB, migrateSchema as aC, notExists as aD, notInSubquery as aE, type StoreOptions as aa, type StreamOptions as ab, type TransactionContext as ac, type TypedEdgeCollection as ad, type TypedNodeRef as ae, type UpdateEdgeInput as af, type UpdateNodeInput as ag, computeSchemaDiff as ah, createStore as ai, createStoreWithSchema as aj, defineGraph as ak, embedding as al, ensureSchema as am, exists as an, fieldRef as ao, getActiveSchema as ap, getEdgeTypeNames as aq, getEmbeddingDimensions as ar, getMigrationActions as as, getNodeTypeNames as at, getSchemaChanges as au, inSubquery as av, initializeSchema as aw, isBackwardsCompatible as ax, isEmbeddingSchema as ay, isGraphDef as az, type SerializedEdgeDef as b, type SerializedMetaEdge as c, type SerializedOntologyRelation as d, type SerializedClosures as e, type SerializedSchema as f, type SchemaHash as g, type AllEdgeTypes as h, type AllNodeTypes as i, type ChangeSeverity as j, type ChangeType as k, type CreateEdgeInput as l, type CreateNodeInput as m, type Edge as n, type EdgeAccessor as o, type EdgeChange as p, type EdgeCollection as q, type EdgeTypeNames as r, type EmbeddingSchema as s, type EmbeddingValue as t, ExecutableAggregateQuery as u, ExecutableQuery as v, type GetEdgeType as w, type GetNodeType as x, type MetaEdgeProperties as y, type NodeAccessor as z };
|