@nicia-ai/typegraph 0.20.0 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ast-Bh2NDeaK.d.cts → ast-CSLbPIOC.d.ts} +56 -3
- package/dist/{ast-COMyNeMn.d.ts → ast-DogwbBqA.d.cts} +56 -3
- package/dist/backend/postgres/index.cjs +123 -45
- package/dist/backend/postgres/index.cjs.map +1 -1
- package/dist/backend/postgres/index.d.cts +15 -7
- package/dist/backend/postgres/index.d.ts +15 -7
- package/dist/backend/postgres/index.js +101 -23
- package/dist/backend/postgres/index.js.map +1 -1
- package/dist/backend/sqlite/index.cjs +15 -15
- package/dist/backend/sqlite/index.d.cts +22 -7
- package/dist/backend/sqlite/index.d.ts +22 -7
- package/dist/backend/sqlite/index.js +5 -5
- package/dist/backend/sqlite/libsql.cjs +8 -8
- package/dist/backend/sqlite/libsql.d.cts +4 -5
- package/dist/backend/sqlite/libsql.d.ts +4 -5
- package/dist/backend/sqlite/libsql.js +5 -5
- package/dist/backend/sqlite/local.cjs +27 -10
- package/dist/backend/sqlite/local.cjs.map +1 -1
- package/dist/backend/sqlite/local.d.cts +4 -5
- package/dist/backend/sqlite/local.d.ts +4 -5
- package/dist/backend/sqlite/local.js +22 -6
- package/dist/backend/sqlite/local.js.map +1 -1
- package/dist/{chunk-MME3H4ZF.cjs → chunk-3JK66E3I.cjs} +387 -9
- package/dist/chunk-3JK66E3I.cjs.map +1 -0
- package/dist/{chunk-6GWJH6AR.js → chunk-3PPEHLGK.js} +4 -4
- package/dist/{chunk-6GWJH6AR.js.map → chunk-3PPEHLGK.js.map} +1 -1
- package/dist/{chunk-QFZQGEQ3.js → chunk-5ZMMHUWR.js} +199 -38
- package/dist/chunk-5ZMMHUWR.js.map +1 -0
- package/dist/{chunk-GNIYZKBI.js → chunk-753F33CV.js} +378 -8
- package/dist/chunk-753F33CV.js.map +1 -0
- package/dist/{chunk-K7SQ3SWP.js → chunk-EYELZHKY.js} +120 -12
- package/dist/chunk-EYELZHKY.js.map +1 -0
- package/dist/{chunk-HXJXTOXR.cjs → chunk-GUYI6VAS.cjs} +101 -21
- package/dist/chunk-GUYI6VAS.cjs.map +1 -0
- package/dist/{chunk-X33WV2UF.cjs → chunk-HRNQ3DVJ.cjs} +24 -21
- package/dist/chunk-HRNQ3DVJ.cjs.map +1 -0
- package/dist/{chunk-W6M7XWKX.js → chunk-JYUQA77I.js} +21 -18
- package/dist/chunk-JYUQA77I.js.map +1 -0
- package/dist/{chunk-LLHFS53Q.js → chunk-NSLTDXVH.js} +91 -11
- package/dist/chunk-NSLTDXVH.js.map +1 -0
- package/dist/{chunk-LELLOHJK.cjs → chunk-PEE4EWXZ.cjs} +35 -35
- package/dist/{chunk-LELLOHJK.cjs.map → chunk-PEE4EWXZ.cjs.map} +1 -1
- package/dist/{chunk-G5CYWKRF.js → chunk-RS5OLGEW.js} +2 -2
- package/dist/{chunk-G5CYWKRF.js.map → chunk-RS5OLGEW.js.map} +1 -1
- package/dist/{chunk-IYWWXOVK.cjs → chunk-SCXOGKLD.cjs} +252 -91
- package/dist/chunk-SCXOGKLD.cjs.map +1 -0
- package/dist/{chunk-P5CNM325.cjs → chunk-UVZHTBZ5.cjs} +123 -11
- package/dist/chunk-UVZHTBZ5.cjs.map +1 -0
- package/dist/{chunk-5GZMPJOP.cjs → chunk-WRWVWKQL.cjs} +2 -2
- package/dist/{chunk-5GZMPJOP.cjs.map → chunk-WRWVWKQL.cjs.map} +1 -1
- package/dist/{ddl-BBo2EcFc.d.cts → ddl-BqkTShcR.d.ts} +28 -6
- package/dist/{ddl-D4jlcOH_.d.ts → ddl-Dk1NDN3M.d.cts} +28 -6
- package/dist/index.cjs +1809 -513
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +53 -11
- package/dist/index.d.ts +53 -11
- package/dist/index.js +1668 -398
- package/dist/index.js.map +1 -1
- package/dist/indexes/index.cjs +17 -17
- package/dist/indexes/index.d.cts +5 -5
- package/dist/indexes/index.d.ts +5 -5
- package/dist/indexes/index.js +3 -3
- package/dist/interchange/index.cjs +6 -6
- package/dist/interchange/index.d.cts +4 -5
- package/dist/interchange/index.d.ts +4 -5
- package/dist/interchange/index.js +1 -1
- package/dist/{manager-Chhrq1vl.d.ts → manager-0jVZtiE8.d.ts} +1 -2
- package/dist/{manager-Bj1UEnhE.d.cts → manager-BPK-2PUI.d.cts} +1 -2
- package/dist/profiler/index.cjs +15 -8
- package/dist/profiler/index.cjs.map +1 -1
- package/dist/profiler/index.d.cts +7 -8
- package/dist/profiler/index.d.ts +7 -8
- package/dist/profiler/index.js +8 -1
- package/dist/profiler/index.js.map +1 -1
- package/dist/schema/index.cjs +21 -21
- package/dist/schema/index.d.cts +4 -5
- package/dist/schema/index.d.ts +4 -5
- package/dist/schema/index.js +3 -3
- package/dist/{sqlite-DE-6NWtC.d.cts → sqlite-D1rrwcir.d.cts} +14 -1
- package/dist/{sqlite-Blq-AhmK.d.ts → sqlite-W3rmJMlc.d.ts} +14 -1
- package/dist/{store-BMrRi_mY.d.ts → store-2QW2SIRk.d.cts} +404 -5
- package/dist/{store-DRRvALu8.d.cts → store-C0q13mtJ.d.ts} +404 -5
- package/dist/{types-B3mmOMJV.d.cts → types-CQF88McG.d.cts} +475 -2
- package/dist/{types-ThB4cFLp.d.ts → types-CQF88McG.d.ts} +475 -2
- package/dist/{types-COPePE8_.d.ts → types-CglvhPKz.d.ts} +1 -1
- package/dist/{types-CVtGFpB9.d.cts → types-D23slCOA.d.cts} +1 -1
- package/dist/{types-Ceb01czq.d.ts → types-IMQCuser.d.ts} +2 -2
- package/dist/{types-CZd2PEOc.d.cts → types-vgjar7Ch.d.cts} +2 -2
- package/package.json +9 -9
- package/dist/chunk-GNIYZKBI.js.map +0 -1
- package/dist/chunk-HXJXTOXR.cjs.map +0 -1
- package/dist/chunk-IYWWXOVK.cjs.map +0 -1
- package/dist/chunk-K7SQ3SWP.js.map +0 -1
- package/dist/chunk-LLHFS53Q.js.map +0 -1
- package/dist/chunk-MME3H4ZF.cjs.map +0 -1
- package/dist/chunk-P5CNM325.cjs.map +0 -1
- package/dist/chunk-QFZQGEQ3.js.map +0 -1
- package/dist/chunk-W6M7XWKX.js.map +0 -1
- package/dist/chunk-X33WV2UF.cjs.map +0 -1
- package/dist/types-DMzKq0d5.d.cts +0 -181
- package/dist/types-DMzKq0d5.d.ts +0 -181
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { S as SqlSchema, G as GraphBackend,
|
|
2
|
-
import { K as KindRegistry, G as GraphDef, E as EdgeKinds, N as NodeKinds, a as AllNodeTypes, S as SchemaManagerOptions, d as SchemaValidationResult } from './manager-
|
|
3
|
-
import { S as SqlDialect, N as NodeType, A as AnyEdgeType, T as TemporalMode, E as EdgeType, d as EdgeRegistration, b as EdgeId, g as NodeId, i as NodeRegistration } from './types-DMzKq0d5.js';
|
|
1
|
+
import { S as SqlDialect, s as SqlSchema, m as FulltextStrategy, j as FulltextQueryMode, N as NodeType, G as GraphBackend, u as TransactionBackend, A as AnyEdgeType, T as TemporalMode, E as EdgeType, f as EdgeRegistration, d as EdgeId, p as NodeId, P as EdgeRow, Q as NodeRow, r as NodeRegistration, R as VectorMetric } from './types-CQF88McG.cjs';
|
|
2
|
+
import { K as KindRegistry, G as GraphDef, E as EdgeKinds, N as NodeKinds, a as AllNodeTypes, S as SchemaManagerOptions, d as SchemaValidationResult } from './manager-BPK-2PUI.cjs';
|
|
4
3
|
import { z } from 'zod';
|
|
5
|
-
import { V as ValueType, i as PredicateExpression, k as VectorMetricType, Q as QueryAst, J as JsonPointer, F as FieldRef, P as ParameterRef, c as JsonPointerInput, T as TraversalExpansion, l as Traversal, N as NodePredicate, m as ProjectedField, O as OrderSpec, G as GroupBySpec, o as RecursiveCyclePolicy, q as TraversalDirection$1, A as AggregateExpr, r as SelectiveField, s as ComposableQuery, t as SetOperationType, u as SetOperation, S as SortDirection } from './ast-
|
|
4
|
+
import { V as ValueType, i as PredicateExpression, k as VectorMetricType, Q as QueryAst, J as JsonPointer, F as FieldRef, P as ParameterRef, c as JsonPointerInput, T as TraversalExpansion, l as Traversal, N as NodePredicate, m as ProjectedField, O as OrderSpec, G as GroupBySpec, H as HybridFusionOptions, o as RecursiveCyclePolicy, q as TraversalDirection$1, A as AggregateExpr, r as SelectiveField, s as ComposableQuery, t as SetOperationType, u as SetOperation, S as SortDirection } from './ast-DogwbBqA.cjs';
|
|
6
5
|
import { SQL } from 'drizzle-orm';
|
|
7
6
|
|
|
8
7
|
/**
|
|
@@ -86,6 +85,75 @@ declare function isEmbeddingSchema(value: unknown): value is EmbeddingSchema;
|
|
|
86
85
|
*/
|
|
87
86
|
declare function getEmbeddingDimensions(schema: z.ZodType): number | undefined;
|
|
88
87
|
|
|
88
|
+
/**
|
|
89
|
+
* Searchable string type for fulltext search.
|
|
90
|
+
*
|
|
91
|
+
* `searchable()` attaches `SearchableMetadata` to a plain Zod string so
|
|
92
|
+
* the schema introspector and fulltext-sync layer can keep the fulltext
|
|
93
|
+
* index in sync with node data.
|
|
94
|
+
*
|
|
95
|
+
* The metadata is preserved by Zod's `.meta()` across refinements
|
|
96
|
+
* (`.min(1)`, `.trim()`, `.regex(...)`) and wrapper types (`.optional()`,
|
|
97
|
+
* `.nullable()`, `.default(...)`, pipes) — `getSearchableMetadata()` walks
|
|
98
|
+
* these variants so runtime indexing works whether or not a user chains
|
|
99
|
+
* additional modifiers.
|
|
100
|
+
*
|
|
101
|
+
* `$fulltext` is exposed on every `NodeAccessor` at the type level; a
|
|
102
|
+
* runtime guard throws a clear error if you call `.matches()` on an
|
|
103
|
+
* alias whose node kind has no `searchable()` fields. This is simpler
|
|
104
|
+
* and more predictable than a type-level brand that silently disappears
|
|
105
|
+
* behind `.min(1)`.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```typescript
|
|
109
|
+
* const Document = defineNode("Document", {
|
|
110
|
+
* schema: z.object({
|
|
111
|
+
* title: searchable({ language: "english" }),
|
|
112
|
+
* body: searchable().min(1),
|
|
113
|
+
* authorId: z.string(),
|
|
114
|
+
* }),
|
|
115
|
+
* });
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
|
|
119
|
+
declare const SEARCHABLE_FIELD_KEY: "_searchableField";
|
|
120
|
+
declare const DEFAULT_SEARCHABLE_LANGUAGE: "english";
|
|
121
|
+
/**
|
|
122
|
+
* Searchable field metadata attached to a Zod schema.
|
|
123
|
+
*/
|
|
124
|
+
type SearchableMetadata = Readonly<{
|
|
125
|
+
/**
|
|
126
|
+
* Language for stemming / tokenization.
|
|
127
|
+
* Postgres: passed to `to_tsvector(regconfig, ...)`.
|
|
128
|
+
* SQLite FTS5: tokenizer is fixed at table-create time, so the
|
|
129
|
+
* language is recorded but not applied per-row.
|
|
130
|
+
*/
|
|
131
|
+
language: string;
|
|
132
|
+
}>;
|
|
133
|
+
/**
|
|
134
|
+
* Branded Zod string schema. The `SEARCHABLE_FIELD_KEY` marker is
|
|
135
|
+
* attached both as a direct property (fast runtime check) and via Zod's
|
|
136
|
+
* `.meta()` (so it survives `.min()`, `.trim()`, etc.).
|
|
137
|
+
*/
|
|
138
|
+
type SearchableSchema = z.ZodString & Readonly<{
|
|
139
|
+
[SEARCHABLE_FIELD_KEY]: SearchableMetadata;
|
|
140
|
+
}>;
|
|
141
|
+
type SearchableOptions = Readonly<{
|
|
142
|
+
language?: string;
|
|
143
|
+
}>;
|
|
144
|
+
/**
|
|
145
|
+
* Creates a Zod string schema tagged as fulltext-searchable.
|
|
146
|
+
*
|
|
147
|
+
* The returned schema passes runtime validation unchanged — the tag only
|
|
148
|
+
* affects how TypeGraph treats the field for indexing and search. Pair
|
|
149
|
+
* with `.optional()` / `.nullable()` / `.min()` / `.trim()` exactly like
|
|
150
|
+
* any other Zod string; `getSearchableMetadata()` finds the metadata
|
|
151
|
+
* through all of them.
|
|
152
|
+
*/
|
|
153
|
+
declare function searchable(options?: SearchableOptions): SearchableSchema;
|
|
154
|
+
declare function isSearchableSchema(value: unknown): value is SearchableSchema;
|
|
155
|
+
declare function getSearchableMetadata(schema: z.ZodType): SearchableMetadata | undefined;
|
|
156
|
+
|
|
89
157
|
/**
|
|
90
158
|
* Query Compiler Module
|
|
91
159
|
*
|
|
@@ -101,6 +169,14 @@ type CompileQueryOptions = Readonly<{
|
|
|
101
169
|
dialect?: SqlDialect | undefined;
|
|
102
170
|
/** SQL schema configuration for table names. Defaults to standard names. */
|
|
103
171
|
schema?: SqlSchema | undefined;
|
|
172
|
+
/**
|
|
173
|
+
* Fulltext strategy override. When set, overrides the dialect's
|
|
174
|
+
* default fulltext strategy for `$fulltext.matches()` compilation.
|
|
175
|
+
* Callers typically read this from `backend.fulltextStrategy` so a
|
|
176
|
+
* backend-declared strategy (e.g. ParadeDB) wins over the dialect
|
|
177
|
+
* default (tsvector).
|
|
178
|
+
*/
|
|
179
|
+
fulltextStrategy?: FulltextStrategy | undefined;
|
|
104
180
|
}>;
|
|
105
181
|
|
|
106
182
|
type FieldTypeInfo = Readonly<{
|
|
@@ -111,14 +187,29 @@ type FieldTypeInfo = Readonly<{
|
|
|
111
187
|
recordValueType?: FieldTypeInfo | undefined;
|
|
112
188
|
/** For embedding types: the number of dimensions */
|
|
113
189
|
dimensions?: number | undefined;
|
|
190
|
+
/** For fulltext-searchable string types: field-level metadata */
|
|
191
|
+
searchable?: SearchableMetadata | undefined;
|
|
114
192
|
}>;
|
|
115
193
|
type SchemaIntrospector = Readonly<{
|
|
116
194
|
getFieldTypeInfo: (kindName: string, fieldName: string) => FieldTypeInfo | undefined;
|
|
117
195
|
getSharedFieldTypeInfo: (kindNames: readonly string[], fieldName: string) => FieldTypeInfo | undefined;
|
|
118
196
|
getEdgeFieldTypeInfo: (edgeKindName: string, fieldName: string) => FieldTypeInfo | undefined;
|
|
119
197
|
getSharedEdgeFieldTypeInfo: (edgeKindNames: readonly string[], fieldName: string) => FieldTypeInfo | undefined;
|
|
198
|
+
/**
|
|
199
|
+
* True iff every kind in `kindNames` has at least one `searchable()`
|
|
200
|
+
* field. For polymorphic aliases, `$fulltext` is available only when
|
|
201
|
+
* every resolved kind has searchable content — otherwise `.matches()`
|
|
202
|
+
* would silently miss some kinds.
|
|
203
|
+
*/
|
|
204
|
+
hasSearchableField: (kindNames: readonly string[]) => boolean;
|
|
120
205
|
}>;
|
|
121
206
|
|
|
207
|
+
/**
|
|
208
|
+
* Predicate builders for TypeGraph queries.
|
|
209
|
+
*
|
|
210
|
+
* Provides a fluent API for building type-safe predicates.
|
|
211
|
+
*/
|
|
212
|
+
|
|
122
213
|
/**
|
|
123
214
|
* A chainable predicate that can be combined with AND/OR.
|
|
124
215
|
*/
|
|
@@ -151,6 +242,34 @@ declare function param(name: string): ParameterRef;
|
|
|
151
242
|
* Type guard for ParameterRef values.
|
|
152
243
|
*/
|
|
153
244
|
declare function isParameterRef(value: unknown): value is ParameterRef;
|
|
245
|
+
/**
|
|
246
|
+
* Options for the `$fulltext.matches()` predicate.
|
|
247
|
+
*
|
|
248
|
+
* Note the term glossary used throughout TypeGraph search:
|
|
249
|
+
* - **`k`** (the positional argument on `.matches(query, k)`) is the
|
|
250
|
+
* per-predicate top-k cap applied inside the fulltext CTE.
|
|
251
|
+
* - **`limit`** (on store-level `search.fulltext` / `search.hybrid` and
|
|
252
|
+
* on the query builder) is the final result count returned to the
|
|
253
|
+
* caller after any fusion.
|
|
254
|
+
*/
|
|
255
|
+
type MatchesOptions = Readonly<{
|
|
256
|
+
/**
|
|
257
|
+
* Parse mode for the query string. Default: "websearch".
|
|
258
|
+
*
|
|
259
|
+
* - "websearch": Google-style syntax (quoted phrases, `-excluded`, `OR`).
|
|
260
|
+
* Postgres: `websearch_to_tsquery`. SQLite: translated to FTS5 MATCH.
|
|
261
|
+
* - "phrase": treats the whole query as a phrase.
|
|
262
|
+
* - "plain": splits on whitespace and ANDs terms.
|
|
263
|
+
* - "raw": dialect-native syntax passed through unchanged.
|
|
264
|
+
*/
|
|
265
|
+
mode?: FulltextQueryMode;
|
|
266
|
+
/**
|
|
267
|
+
* Language override. Default: per-row language as stored at insert time.
|
|
268
|
+
*/
|
|
269
|
+
language?: string;
|
|
270
|
+
/** Minimum relevance score to include. */
|
|
271
|
+
minScore?: number;
|
|
272
|
+
}>;
|
|
154
273
|
/**
|
|
155
274
|
* Options for the similarTo method.
|
|
156
275
|
*/
|
|
@@ -174,6 +293,17 @@ type FieldRefOptions = Readonly<{
|
|
|
174
293
|
elementType?: ValueType | undefined;
|
|
175
294
|
}>;
|
|
176
295
|
declare function fieldRef(alias: string, path: readonly string[], options?: FieldRefOptions): FieldRef;
|
|
296
|
+
/**
|
|
297
|
+
* Node-level fulltext accessor. Always present on the `NodeAccessor`
|
|
298
|
+
* type — a runtime check throws a clear error if the node kind has no
|
|
299
|
+
* `searchable()` fields. `k` is the top-k cap applied inside the
|
|
300
|
+
* fulltext CTE; defaults to `DEFAULT_FULLTEXT_MATCH_K`. Use a larger
|
|
301
|
+
* value when feeding the result into RRF (`.fuseWith()` /
|
|
302
|
+
* `store.search.hybrid()`).
|
|
303
|
+
*/
|
|
304
|
+
type FulltextAccessor = Readonly<{
|
|
305
|
+
matches: (query: string, k?: number, options?: MatchesOptions) => Predicate;
|
|
306
|
+
}>;
|
|
177
307
|
/**
|
|
178
308
|
* Creates an EXISTS subquery predicate.
|
|
179
309
|
* Returns true if the subquery returns at least one row.
|
|
@@ -421,10 +551,15 @@ type ObjectFieldAccessor<T> = BaseFieldAccessor & Readonly<{
|
|
|
421
551
|
* Properties are available at the top level for ergonomic access:
|
|
422
552
|
* - `n.name` instead of `n.props.name`
|
|
423
553
|
* - System fields: `n.id`, `n.kind`
|
|
554
|
+
* - Fulltext: `n.$fulltext.matches(...)` — throws at query build time if
|
|
555
|
+
* the node kind has no `searchable()` fields. Exposed at the type
|
|
556
|
+
* level on every accessor so refinements like
|
|
557
|
+
* `searchable().min(1)` do not make it disappear.
|
|
424
558
|
*/
|
|
425
559
|
type NodeAccessor<N extends NodeType> = Readonly<{
|
|
426
560
|
id: StringFieldAccessor;
|
|
427
561
|
kind: StringFieldAccessor;
|
|
562
|
+
$fulltext: FulltextAccessor;
|
|
428
563
|
}> & PropsAccessor<N>;
|
|
429
564
|
/**
|
|
430
565
|
* Creates typed field accessors for an edge kind's properties.
|
|
@@ -591,6 +726,7 @@ type QueryBuilderState = Readonly<{
|
|
|
591
726
|
asOf: string | undefined;
|
|
592
727
|
groupBy: GroupBySpec | undefined;
|
|
593
728
|
having: PredicateExpression | undefined;
|
|
729
|
+
fusion: HybridFusionOptions | undefined;
|
|
594
730
|
}>;
|
|
595
731
|
/**
|
|
596
732
|
* Options for creating a query builder.
|
|
@@ -2052,6 +2188,30 @@ declare class QueryBuilder<G extends GraphDef, Aliases extends AliasMap = {}, Ed
|
|
|
2052
2188
|
* @param predicate - A predicate expression to filter groups
|
|
2053
2189
|
*/
|
|
2054
2190
|
having(predicate: PredicateExpression): QueryBuilder<G, Aliases, EdgeAliases, RecursiveAliases>;
|
|
2191
|
+
/**
|
|
2192
|
+
* Sets fusion parameters for hybrid (vector + fulltext) queries.
|
|
2193
|
+
*
|
|
2194
|
+
* Applies only when the query contains both a `.similarTo()` and a
|
|
2195
|
+
* `.$fulltext.matches()` predicate. Without this call, the default is
|
|
2196
|
+
* RRF with k=60 and equal weights. A mismatch between `.fuseWith()`
|
|
2197
|
+
* configuration and the predicates on the query is caught during
|
|
2198
|
+
* compilation, not here.
|
|
2199
|
+
*
|
|
2200
|
+
* @example
|
|
2201
|
+
* ```typescript
|
|
2202
|
+
* store.query()
|
|
2203
|
+
* .from("Document", "d")
|
|
2204
|
+
* .whereNode("d", d =>
|
|
2205
|
+
* d.$fulltext.matches("renewable energy", 50)
|
|
2206
|
+
* .and(d.embedding.similarTo(vec, 50))
|
|
2207
|
+
* .and(d.tenantId.eq(tenant))
|
|
2208
|
+
* )
|
|
2209
|
+
* .fuseWith({ k: 60, weights: { fulltext: 1.5 } })
|
|
2210
|
+
* .limit(10)
|
|
2211
|
+
* .execute();
|
|
2212
|
+
* ```
|
|
2213
|
+
*/
|
|
2214
|
+
fuseWith(options: HybridFusionOptions): QueryBuilder<G, Aliases, EdgeAliases, RecursiveAliases>;
|
|
2055
2215
|
/**
|
|
2056
2216
|
* Applies a query fragment to transform this builder.
|
|
2057
2217
|
*
|
|
@@ -2272,6 +2432,217 @@ type GraphAlgorithms<G extends GraphDef> = Readonly<{
|
|
|
2272
2432
|
degree: (node: NodeIdentifier, options?: DegreeOptions<G>) => Promise<number>;
|
|
2273
2433
|
}>;
|
|
2274
2434
|
|
|
2435
|
+
type RebuildFulltextOptions = Readonly<{
|
|
2436
|
+
/** Page size. Must be a positive integer. Default: 500. */
|
|
2437
|
+
pageSize?: number;
|
|
2438
|
+
/**
|
|
2439
|
+
* Maximum number of skipped node IDs to include in the `skippedIds`
|
|
2440
|
+
* array. Default: 10,000. Set higher to collect the full list when
|
|
2441
|
+
* investigating systemic corruption; set lower when `processed` is
|
|
2442
|
+
* all you care about. The `skipped` total is always accurate.
|
|
2443
|
+
*/
|
|
2444
|
+
maxSkippedIds?: number;
|
|
2445
|
+
}>;
|
|
2446
|
+
type RebuildFulltextResult = Readonly<{
|
|
2447
|
+
/** Node kinds that were rebuilt (those with at least one searchable field). */
|
|
2448
|
+
kinds: readonly string[];
|
|
2449
|
+
/** Total nodes scanned. */
|
|
2450
|
+
processed: number;
|
|
2451
|
+
/** Fulltext upsert operations executed. */
|
|
2452
|
+
upserted: number;
|
|
2453
|
+
/** Fulltext delete operations executed (soft-deleted or all-empty nodes). */
|
|
2454
|
+
cleared: number;
|
|
2455
|
+
/**
|
|
2456
|
+
* Nodes skipped due to corrupt or non-object `props` (not counted in
|
|
2457
|
+
* upserted/cleared).
|
|
2458
|
+
*/
|
|
2459
|
+
skipped: number;
|
|
2460
|
+
/**
|
|
2461
|
+
* IDs of skipped nodes, capped at 10,000 entries so pathological
|
|
2462
|
+
* corruption doesn't turn rebuild into an OOM. See `skippedTruncated`
|
|
2463
|
+
* to tell whether the cap was hit. Empty when `skipped === 0`.
|
|
2464
|
+
*/
|
|
2465
|
+
skippedIds: readonly string[];
|
|
2466
|
+
/** True when `skipped > skippedIds.length` (the cap was reached). */
|
|
2467
|
+
skippedTruncated: boolean;
|
|
2468
|
+
}>;
|
|
2469
|
+
|
|
2470
|
+
/**
|
|
2471
|
+
* Store-level search helpers.
|
|
2472
|
+
*
|
|
2473
|
+
* `fulltextSearch` is a thin typed wrapper over `backend.fulltextSearch`.
|
|
2474
|
+
* `hybridSearch` runs a vector and a fulltext query in parallel and
|
|
2475
|
+
* fuses the two ranked lists with Reciprocal Rank Fusion. RRF is
|
|
2476
|
+
* rank-based, so it papers over score-scale differences between
|
|
2477
|
+
* pgvector/sqlite-vec (distance-derived) and tsvector/FTS5 (BM25-style).
|
|
2478
|
+
*/
|
|
2479
|
+
|
|
2480
|
+
/**
|
|
2481
|
+
* A fulltext search hit. `N` defaults to the generic `Node`; the
|
|
2482
|
+
* `store.search.fulltext<K>(kind)` facade narrows it to the concrete
|
|
2483
|
+
* typed node for that kind so callers get `hit.node.title` without a cast.
|
|
2484
|
+
*/
|
|
2485
|
+
type FulltextSearchHit<N = Node> = Readonly<{
|
|
2486
|
+
node: N;
|
|
2487
|
+
/** Backend-native relevance score; higher is better. */
|
|
2488
|
+
score: number;
|
|
2489
|
+
/** 1-based rank within the result set. */
|
|
2490
|
+
rank: number;
|
|
2491
|
+
/** Highlighted snippet (only present when `includeSnippets: true`). */
|
|
2492
|
+
snippet?: string;
|
|
2493
|
+
}>;
|
|
2494
|
+
type VectorSearchHit<N = Node> = Readonly<{
|
|
2495
|
+
node: N;
|
|
2496
|
+
score: number;
|
|
2497
|
+
rank: number;
|
|
2498
|
+
}>;
|
|
2499
|
+
/**
|
|
2500
|
+
* A hybrid search hit. Both sub-results (`vector`, `fulltext`) carry the
|
|
2501
|
+
* same narrowed node type as the top-level `node` for ergonomic access.
|
|
2502
|
+
*/
|
|
2503
|
+
type HybridSearchHit<N = Node> = Readonly<{
|
|
2504
|
+
node: N;
|
|
2505
|
+
/** Fused RRF score (higher is better). */
|
|
2506
|
+
score: number;
|
|
2507
|
+
/** 1-based rank in the fused list. */
|
|
2508
|
+
rank: number;
|
|
2509
|
+
/** Sub-result from the vector half, if it ranked this node. */
|
|
2510
|
+
vector?: VectorSearchHit<N>;
|
|
2511
|
+
/** Sub-result from the fulltext half, if it ranked this node. */
|
|
2512
|
+
fulltext?: FulltextSearchHit<N>;
|
|
2513
|
+
}>;
|
|
2514
|
+
type FulltextSearchOptions = Readonly<{
|
|
2515
|
+
/** The user-supplied query string. */
|
|
2516
|
+
query: string;
|
|
2517
|
+
/** Max results. Required. */
|
|
2518
|
+
limit: number;
|
|
2519
|
+
/** Query parser mode. Default: "websearch". */
|
|
2520
|
+
mode?: FulltextQueryMode;
|
|
2521
|
+
/**
|
|
2522
|
+
* Language override for query parsing. Default: per-row language as
|
|
2523
|
+
* stored at insert time.
|
|
2524
|
+
*/
|
|
2525
|
+
language?: string;
|
|
2526
|
+
/** Minimum relevance score to include in results. */
|
|
2527
|
+
minScore?: number;
|
|
2528
|
+
/** Return a highlighted snippet alongside each hit. */
|
|
2529
|
+
includeSnippets?: boolean;
|
|
2530
|
+
}>;
|
|
2531
|
+
type HybridVectorOptions = Readonly<{
|
|
2532
|
+
/** Field path of the embedding column on the node kind. */
|
|
2533
|
+
fieldPath: string;
|
|
2534
|
+
/** Query embedding to compare against. */
|
|
2535
|
+
queryEmbedding: readonly number[];
|
|
2536
|
+
/** Distance metric. Default: "cosine". */
|
|
2537
|
+
metric?: VectorMetric;
|
|
2538
|
+
/** How many candidates to retrieve from the vector side. Default: 4 * limit. */
|
|
2539
|
+
k?: number;
|
|
2540
|
+
/** Minimum similarity to include (units depend on metric). */
|
|
2541
|
+
minScore?: number;
|
|
2542
|
+
}>;
|
|
2543
|
+
type HybridFulltextOptions = Readonly<{
|
|
2544
|
+
query: string;
|
|
2545
|
+
/** How many candidates to retrieve from the fulltext side. Default: 4 * limit. */
|
|
2546
|
+
k?: number;
|
|
2547
|
+
mode?: FulltextQueryMode;
|
|
2548
|
+
language?: string;
|
|
2549
|
+
minScore?: number;
|
|
2550
|
+
includeSnippets?: boolean;
|
|
2551
|
+
}>;
|
|
2552
|
+
type HybridSearchOptions = Readonly<{
|
|
2553
|
+
vector: HybridVectorOptions;
|
|
2554
|
+
fulltext: HybridFulltextOptions;
|
|
2555
|
+
fusion?: HybridFusionOptions;
|
|
2556
|
+
/** Final number of fused results to return. Required. */
|
|
2557
|
+
limit: number;
|
|
2558
|
+
}>;
|
|
2559
|
+
|
|
2560
|
+
/**
|
|
2561
|
+
* StoreSearch — store.search facade.
|
|
2562
|
+
*
|
|
2563
|
+
* Groups fulltext, hybrid, and maintenance operations under one
|
|
2564
|
+
* namespace so the top-level Store API stays focused on CRUD + graph
|
|
2565
|
+
* traversal. The three methods delegate to their respective execution
|
|
2566
|
+
* modules; this class exists purely to shape the surface, not to add
|
|
2567
|
+
* behavior.
|
|
2568
|
+
*/
|
|
2569
|
+
|
|
2570
|
+
/**
|
|
2571
|
+
* Narrows `Node` to the concrete typed node for a given kind in the graph.
|
|
2572
|
+
*/
|
|
2573
|
+
type NodeOfKind<G extends GraphDef, K extends NodeKinds<G>> = G["nodes"][K] extends NodeRegistration<infer N extends NodeType> ? Node<N> : Node;
|
|
2574
|
+
type StoreSearchContext = Readonly<{
|
|
2575
|
+
graphId: string;
|
|
2576
|
+
backend: GraphBackend;
|
|
2577
|
+
registry: KindRegistry;
|
|
2578
|
+
}>;
|
|
2579
|
+
/**
|
|
2580
|
+
* Search-related operations exposed via `store.search`.
|
|
2581
|
+
*
|
|
2582
|
+
* @example
|
|
2583
|
+
* ```typescript
|
|
2584
|
+
* // Fulltext only
|
|
2585
|
+
* const hits = await store.search.fulltext("Document", {
|
|
2586
|
+
* query: "climate change",
|
|
2587
|
+
* limit: 10,
|
|
2588
|
+
* includeSnippets: true,
|
|
2589
|
+
* });
|
|
2590
|
+
*
|
|
2591
|
+
* // Hybrid: vector + fulltext, fused with RRF
|
|
2592
|
+
* const ranked = await store.search.hybrid("Document", {
|
|
2593
|
+
* limit: 10,
|
|
2594
|
+
* vector: { fieldPath: "embedding", queryEmbedding: vec },
|
|
2595
|
+
* fulltext: { query: "climate change" },
|
|
2596
|
+
* });
|
|
2597
|
+
*
|
|
2598
|
+
* // Rebuild after backfill / schema change
|
|
2599
|
+
* const stats = await store.search.rebuildFulltext();
|
|
2600
|
+
* ```
|
|
2601
|
+
*/
|
|
2602
|
+
declare class StoreSearch<G extends GraphDef> {
|
|
2603
|
+
#private;
|
|
2604
|
+
constructor(context: StoreSearchContext);
|
|
2605
|
+
/**
|
|
2606
|
+
* Runs a fulltext search against nodes of the given kind.
|
|
2607
|
+
*
|
|
2608
|
+
* Requires fields on the node schema declared with `searchable()`.
|
|
2609
|
+
* The search hits the backend's fulltext index (tsvector + GIN on
|
|
2610
|
+
* Postgres, FTS5 on SQLite — or whatever strategy the backend is
|
|
2611
|
+
* configured with) and resolves the matching node IDs back to typed
|
|
2612
|
+
* `Node` objects.
|
|
2613
|
+
*/
|
|
2614
|
+
fulltext<K extends NodeKinds<G>>(nodeKind: K, options: FulltextSearchOptions): Promise<readonly FulltextSearchHit<NodeOfKind<G, K>>[]>;
|
|
2615
|
+
/**
|
|
2616
|
+
* Runs a vector + fulltext hybrid search and fuses the results with
|
|
2617
|
+
* Reciprocal Rank Fusion.
|
|
2618
|
+
*
|
|
2619
|
+
* RRF is rank-based, so it composes well across heterogeneous score
|
|
2620
|
+
* scales (cosine similarity vs ts_rank_cd vs FTS5 BM25). Default
|
|
2621
|
+
* over-fetch is 4× `limit` from each source — tune via `vector.k` /
|
|
2622
|
+
* `fulltext.k` for higher-recall corpora.
|
|
2623
|
+
*/
|
|
2624
|
+
hybrid<K extends NodeKinds<G>>(nodeKind: K, options: HybridSearchOptions): Promise<readonly HybridSearchHit<NodeOfKind<G, K>>[]>;
|
|
2625
|
+
/**
|
|
2626
|
+
* Rebuilds the fulltext index from existing node data.
|
|
2627
|
+
*
|
|
2628
|
+
* Use when:
|
|
2629
|
+
* - A node kind gained a `searchable()` field after data was already
|
|
2630
|
+
* written and existing rows were never indexed.
|
|
2631
|
+
* - The fulltext table was dropped / truncated.
|
|
2632
|
+
* - `language` was changed on a `searchable()` field.
|
|
2633
|
+
*
|
|
2634
|
+
* Iterates nodes with keyset pagination (stable under shared
|
|
2635
|
+
* timestamps and light concurrent writes), transacts per page, skips
|
|
2636
|
+
* kinds with no searchable fields, and cleans up stale rows for
|
|
2637
|
+
* soft-deleted nodes. Corrupt or non-object `props` are counted in
|
|
2638
|
+
* `skipped` with their node IDs surfaced via `skippedIds` so operators
|
|
2639
|
+
* can investigate. Concurrent hard-deletes between page fetches can
|
|
2640
|
+
* be missed by a single pass — run during a maintenance window for
|
|
2641
|
+
* full consistency.
|
|
2642
|
+
*/
|
|
2643
|
+
rebuildFulltext<K extends NodeKinds<G>>(nodeKind?: K, options?: RebuildFulltextOptions): Promise<RebuildFulltextResult>;
|
|
2644
|
+
}
|
|
2645
|
+
|
|
2275
2646
|
/**
|
|
2276
2647
|
* Main Store implementation for TypeGraph.
|
|
2277
2648
|
*
|
|
@@ -2411,6 +2782,34 @@ declare class Store<G extends GraphDef> {
|
|
|
2411
2782
|
* ```
|
|
2412
2783
|
*/
|
|
2413
2784
|
query(): QueryBuilder<G>;
|
|
2785
|
+
/**
|
|
2786
|
+
* Search-related operations (fulltext, hybrid, and rebuild).
|
|
2787
|
+
*
|
|
2788
|
+
* All search methods live under this facade to keep the top-level
|
|
2789
|
+
* Store API focused on CRUD + graph traversal. The facade is
|
|
2790
|
+
* lazy-initialized and cached for the lifetime of the store.
|
|
2791
|
+
*
|
|
2792
|
+
* @example
|
|
2793
|
+
* ```typescript
|
|
2794
|
+
* // Fulltext
|
|
2795
|
+
* const hits = await store.search.fulltext("Document", {
|
|
2796
|
+
* query: "climate warming",
|
|
2797
|
+
* limit: 10,
|
|
2798
|
+
* includeSnippets: true,
|
|
2799
|
+
* });
|
|
2800
|
+
*
|
|
2801
|
+
* // Hybrid (vector + fulltext fused with RRF)
|
|
2802
|
+
* const ranked = await store.search.hybrid("Document", {
|
|
2803
|
+
* limit: 10,
|
|
2804
|
+
* vector: { fieldPath: "embedding", queryEmbedding: vec },
|
|
2805
|
+
* fulltext: { query: "climate warming" },
|
|
2806
|
+
* });
|
|
2807
|
+
*
|
|
2808
|
+
* // Rebuild index after schema change
|
|
2809
|
+
* const stats = await store.search.rebuildFulltext();
|
|
2810
|
+
* ```
|
|
2811
|
+
*/
|
|
2812
|
+
get search(): StoreSearch<G>;
|
|
2414
2813
|
/**
|
|
2415
2814
|
* Executes multiple queries over a single connection with snapshot consistency.
|
|
2416
2815
|
*
|
|
@@ -2574,4 +2973,4 @@ declare function createStore<G extends GraphDef>(graph: G, backend: GraphBackend
|
|
|
2574
2973
|
*/
|
|
2575
2974
|
declare function createStoreWithSchema<G extends GraphDef>(graph: G, backend: GraphBackend, options?: StoreOptions & SchemaManagerOptions): Promise<[Store<G>, SchemaValidationResult]>;
|
|
2576
2975
|
|
|
2577
|
-
export { type
|
|
2976
|
+
export { type PaginatedResult as $, type AliasMap as A, type BaseTraversalOptions as B, type CreateQueryBuilderOptions as C, DEFAULT_SEARCHABLE_LANGUAGE as D, type EdgeAliasMap as E, type FieldAccessor as F, type GetOrCreateAction as G, type GraphNodeCollections as H, type HookContext as I, type HybridFulltextOptions as J, type HybridSearchHit as K, type HybridSearchOptions as L, type HybridVectorOptions as M, type IfExistsMode as N, type NeighborsOptions as O, type Node as P, QueryBuilder as Q, type NodeAccessor as R, type NodeAlias as S, TraversalBuilder as T, type NodeCollection as U, type NodeGetOrCreateByConstraintOptions as V, type NodeGetOrCreateByConstraintResult as W, type NodeIdentifier as X, type NodeRef as Y, type OperationHookContext as Z, type PaginateOptions as _, type AggregateResult as a, type PathNode as a0, type Predicate as a1, PreparedQuery as a2, type PropsAccessor as a3, type QueryHookContext as a4, type QueryOptions as a5, type ReachableNode as a6, type ReachableOptions as a7, type RebuildFulltextOptions as a8, type RebuildFulltextResult as a9, type UpdateEdgeInput as aA, type UpdateNodeInput as aB, type VectorSearchHit as aC, createStore as aD, createStoreWithSchema as aE, defineSubgraphProject as aF, embedding as aG, exists as aH, fieldRef as aI, getEmbeddingDimensions as aJ, getSearchableMetadata as aK, inSubquery as aL, isEmbeddingSchema as aM, isParameterRef as aN, isSearchableSchema as aO, notExists as aP, notInSubquery as aQ, param as aR, searchable as aS, type RecursiveTraversalOptions as aa, type SearchableMetadata as ab, type SearchableOptions as ac, type SearchableSchema as ad, type SelectContext as ae, type SelectableEdge as af, type SelectableNode as ag, type ShortestPathOptions as ah, type ShortestPathResult as ai, Store as aj, type StoreHooks as ak, type StoreOptions as al, type StoreProjection as am, StoreSearch as an, type StreamOptions as ao, type SubgraphEdgeResult as ap, type SubgraphNodeResult as aq, type SubgraphOptions as ar, type SubgraphResult as as, type SubsetEdge as at, type SubsetNode as au, type TemporalAlgorithmOptions as av, type TransactionContext as aw, type TraversalDirection as ax, type TypedEdgeCollection as ay, UnionableQuery as az, type AlgorithmCyclePolicy as b, type AnyEdge as c, type AnyNode as d, type BatchResults as e, type BatchableQuery as f, type ConstraintNames as g, type CreateEdgeInput as h, type CreateNodeInput as i, type DegreeOptions as j, type DynamicEdgeCollection as k, type DynamicNodeCollection as l, type Edge as m, type EdgeAccessor as n, type EdgeCollection as o, type EdgeFindByEndpointsOptions as p, type EdgeGetOrCreateByEndpointsOptions as q, type EdgeGetOrCreateByEndpointsResult as r, type EmbeddingSchema as s, type EmbeddingValue as t, ExecutableAggregateQuery as u, ExecutableQuery as v, type FulltextSearchHit as w, type FulltextSearchOptions as x, type GraphAlgorithms as y, type GraphEdgeCollections as z };
|