@nicia-ai/typegraph 0.20.0 → 0.21.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.
Files changed (99) hide show
  1. package/dist/{ast-Bh2NDeaK.d.cts → ast-CSLbPIOC.d.ts} +56 -3
  2. package/dist/{ast-COMyNeMn.d.ts → ast-DogwbBqA.d.cts} +56 -3
  3. package/dist/backend/postgres/index.cjs +123 -45
  4. package/dist/backend/postgres/index.cjs.map +1 -1
  5. package/dist/backend/postgres/index.d.cts +15 -7
  6. package/dist/backend/postgres/index.d.ts +15 -7
  7. package/dist/backend/postgres/index.js +101 -23
  8. package/dist/backend/postgres/index.js.map +1 -1
  9. package/dist/backend/sqlite/index.cjs +15 -15
  10. package/dist/backend/sqlite/index.d.cts +11 -7
  11. package/dist/backend/sqlite/index.d.ts +11 -7
  12. package/dist/backend/sqlite/index.js +5 -5
  13. package/dist/backend/sqlite/libsql.cjs +8 -8
  14. package/dist/backend/sqlite/libsql.d.cts +4 -5
  15. package/dist/backend/sqlite/libsql.d.ts +4 -5
  16. package/dist/backend/sqlite/libsql.js +5 -5
  17. package/dist/backend/sqlite/local.cjs +9 -9
  18. package/dist/backend/sqlite/local.d.cts +4 -5
  19. package/dist/backend/sqlite/local.d.ts +4 -5
  20. package/dist/backend/sqlite/local.js +5 -5
  21. package/dist/{chunk-LELLOHJK.cjs → chunk-2X7P7AD5.cjs} +35 -35
  22. package/dist/{chunk-LELLOHJK.cjs.map → chunk-2X7P7AD5.cjs.map} +1 -1
  23. package/dist/{chunk-GNIYZKBI.js → chunk-4XNE2JG3.js} +376 -8
  24. package/dist/chunk-4XNE2JG3.js.map +1 -0
  25. package/dist/{chunk-HXJXTOXR.cjs → chunk-CQL6FOTT.cjs} +82 -21
  26. package/dist/chunk-CQL6FOTT.cjs.map +1 -0
  27. package/dist/{chunk-K7SQ3SWP.js → chunk-EYELZHKY.js} +120 -12
  28. package/dist/chunk-EYELZHKY.js.map +1 -0
  29. package/dist/{chunk-MME3H4ZF.cjs → chunk-FQCQM3KG.cjs} +385 -9
  30. package/dist/chunk-FQCQM3KG.cjs.map +1 -0
  31. package/dist/{chunk-X33WV2UF.cjs → chunk-HRNQ3DVJ.cjs} +24 -21
  32. package/dist/chunk-HRNQ3DVJ.cjs.map +1 -0
  33. package/dist/{chunk-W6M7XWKX.js → chunk-JYUQA77I.js} +21 -18
  34. package/dist/chunk-JYUQA77I.js.map +1 -0
  35. package/dist/{chunk-LLHFS53Q.js → chunk-NRNJ52AA.js} +72 -11
  36. package/dist/chunk-NRNJ52AA.js.map +1 -0
  37. package/dist/{chunk-IYWWXOVK.cjs → chunk-Q73OWTJY.cjs} +204 -89
  38. package/dist/chunk-Q73OWTJY.cjs.map +1 -0
  39. package/dist/{chunk-G5CYWKRF.js → chunk-RS5OLGEW.js} +2 -2
  40. package/dist/{chunk-G5CYWKRF.js.map → chunk-RS5OLGEW.js.map} +1 -1
  41. package/dist/{chunk-6GWJH6AR.js → chunk-SMMOAVJ5.js} +4 -4
  42. package/dist/{chunk-6GWJH6AR.js.map → chunk-SMMOAVJ5.js.map} +1 -1
  43. package/dist/{chunk-QFZQGEQ3.js → chunk-UQVBVBVG.js} +151 -36
  44. package/dist/chunk-UQVBVBVG.js.map +1 -0
  45. package/dist/{chunk-P5CNM325.cjs → chunk-UVZHTBZ5.cjs} +123 -11
  46. package/dist/chunk-UVZHTBZ5.cjs.map +1 -0
  47. package/dist/{chunk-5GZMPJOP.cjs → chunk-WRWVWKQL.cjs} +2 -2
  48. package/dist/{chunk-5GZMPJOP.cjs.map → chunk-WRWVWKQL.cjs.map} +1 -1
  49. package/dist/{ddl-BBo2EcFc.d.cts → ddl-BqkTShcR.d.ts} +28 -6
  50. package/dist/{ddl-D4jlcOH_.d.ts → ddl-Dk1NDN3M.d.cts} +28 -6
  51. package/dist/index.cjs +1705 -490
  52. package/dist/index.cjs.map +1 -1
  53. package/dist/index.d.cts +8 -10
  54. package/dist/index.d.ts +8 -10
  55. package/dist/index.js +1552 -361
  56. package/dist/index.js.map +1 -1
  57. package/dist/indexes/index.cjs +17 -17
  58. package/dist/indexes/index.d.cts +5 -5
  59. package/dist/indexes/index.d.ts +5 -5
  60. package/dist/indexes/index.js +3 -3
  61. package/dist/interchange/index.cjs +6 -6
  62. package/dist/interchange/index.d.cts +4 -5
  63. package/dist/interchange/index.d.ts +4 -5
  64. package/dist/interchange/index.js +1 -1
  65. package/dist/{manager-Chhrq1vl.d.ts → manager-0jVZtiE8.d.ts} +1 -2
  66. package/dist/{manager-Bj1UEnhE.d.cts → manager-BPK-2PUI.d.cts} +1 -2
  67. package/dist/profiler/index.cjs +15 -8
  68. package/dist/profiler/index.cjs.map +1 -1
  69. package/dist/profiler/index.d.cts +7 -8
  70. package/dist/profiler/index.d.ts +7 -8
  71. package/dist/profiler/index.js +8 -1
  72. package/dist/profiler/index.js.map +1 -1
  73. package/dist/schema/index.cjs +21 -21
  74. package/dist/schema/index.d.cts +4 -5
  75. package/dist/schema/index.d.ts +4 -5
  76. package/dist/schema/index.js +3 -3
  77. package/dist/{sqlite-DE-6NWtC.d.cts → sqlite-D1rrwcir.d.cts} +14 -1
  78. package/dist/{sqlite-Blq-AhmK.d.ts → sqlite-W3rmJMlc.d.ts} +14 -1
  79. package/dist/{store-BMrRi_mY.d.ts → store-2QW2SIRk.d.cts} +404 -5
  80. package/dist/{store-DRRvALu8.d.cts → store-C0q13mtJ.d.ts} +404 -5
  81. package/dist/{types-B3mmOMJV.d.cts → types-CQF88McG.d.cts} +475 -2
  82. package/dist/{types-ThB4cFLp.d.ts → types-CQF88McG.d.ts} +475 -2
  83. package/dist/{types-COPePE8_.d.ts → types-CglvhPKz.d.ts} +1 -1
  84. package/dist/{types-CVtGFpB9.d.cts → types-D23slCOA.d.cts} +1 -1
  85. package/dist/{types-Ceb01czq.d.ts → types-IMQCuser.d.ts} +2 -2
  86. package/dist/{types-CZd2PEOc.d.cts → types-vgjar7Ch.d.cts} +2 -2
  87. package/package.json +9 -9
  88. package/dist/chunk-GNIYZKBI.js.map +0 -1
  89. package/dist/chunk-HXJXTOXR.cjs.map +0 -1
  90. package/dist/chunk-IYWWXOVK.cjs.map +0 -1
  91. package/dist/chunk-K7SQ3SWP.js.map +0 -1
  92. package/dist/chunk-LLHFS53Q.js.map +0 -1
  93. package/dist/chunk-MME3H4ZF.cjs.map +0 -1
  94. package/dist/chunk-P5CNM325.cjs.map +0 -1
  95. package/dist/chunk-QFZQGEQ3.js.map +0 -1
  96. package/dist/chunk-W6M7XWKX.js.map +0 -1
  97. package/dist/chunk-X33WV2UF.cjs.map +0 -1
  98. package/dist/types-DMzKq0d5.d.cts +0 -181
  99. package/dist/types-DMzKq0d5.d.ts +0 -181
@@ -1,5 +1,170 @@
1
1
  import { SQL } from 'drizzle-orm';
2
- import { N as NodeType, E as EdgeType, j as UniquenessScope, a as Collation, D as DeleteBehavior, C as Cardinality, f as EndpointExistence, T as TemporalMode, S as SqlDialect } from './types-DMzKq0d5.cjs';
2
+ import { z } from 'zod';
3
+
4
+ /** Brand key for NodeType */
5
+ declare const NODE_TYPE_BRAND: "__nodeType";
6
+ /** Brand key for EdgeType */
7
+ declare const EDGE_TYPE_BRAND: "__edgeType";
8
+ /** Brand symbol for NodeId */
9
+ declare const __nodeId: unique symbol;
10
+ /** Brand symbol for EdgeId */
11
+ declare const __edgeId: unique symbol;
12
+ /**
13
+ * A node type definition.
14
+ *
15
+ * Created via `defineNode()`. Represents a type of node in the graph
16
+ * with an associated Zod schema for properties.
17
+ */
18
+ type NodeType<K extends string = string, S extends z.ZodObject<z.ZodRawShape> = z.ZodObject<z.ZodRawShape>> = Readonly<{
19
+ [NODE_TYPE_BRAND]: true;
20
+ kind: K;
21
+ schema: S;
22
+ description: string | undefined;
23
+ }>;
24
+ /**
25
+ * Branded node ID type.
26
+ *
27
+ * Prevents mixing IDs from different node types at compile time.
28
+ */
29
+ type NodeId<N extends NodeType> = string & Readonly<{
30
+ [__nodeId]: N;
31
+ }>;
32
+ /**
33
+ * Infer the props type from a NodeType.
34
+ */
35
+ type NodeProps<N extends NodeType> = z.infer<N["schema"]>;
36
+ /**
37
+ * An edge type definition.
38
+ *
39
+ * Created via `defineEdge()`. Represents a type of edge in the graph
40
+ * with an optional Zod schema for properties.
41
+ *
42
+ * Optionally includes `from` and `to` arrays that define the allowed
43
+ * source and target node types (domain and range constraints).
44
+ */
45
+ type EdgeType<K extends string = string, S extends z.ZodObject<z.ZodRawShape> = z.ZodObject<z.ZodRawShape>, From extends readonly NodeType[] | undefined = undefined, To extends readonly NodeType[] | undefined = undefined> = Readonly<{
46
+ [EDGE_TYPE_BRAND]: true;
47
+ kind: K;
48
+ schema: S;
49
+ description: string | undefined;
50
+ from: From;
51
+ to: To;
52
+ }>;
53
+ /**
54
+ * Base edge type for use in constraints - accepts any from/to configuration.
55
+ */
56
+ type AnyEdgeType = EdgeType<string, z.ZodObject<z.ZodRawShape>, readonly NodeType[] | undefined, readonly NodeType[] | undefined>;
57
+ /**
58
+ * An edge type that has both from and to constraints defined.
59
+ * Can be used directly in defineGraph without an EdgeRegistration wrapper.
60
+ */
61
+ type EdgeTypeWithEndpoints = EdgeType<string, z.ZodObject<z.ZodRawShape>, readonly NodeType[], readonly NodeType[]>;
62
+ /**
63
+ * Branded edge ID type.
64
+ *
65
+ * Prevents mixing IDs from different edge types at compile time.
66
+ */
67
+ type EdgeId<E extends AnyEdgeType = AnyEdgeType> = string & Readonly<{
68
+ [__edgeId]: E;
69
+ }>;
70
+ /**
71
+ * Infer the props type from an EdgeType.
72
+ */
73
+ type EdgeProps<E extends AnyEdgeType> = z.infer<E["schema"]>;
74
+ /**
75
+ * Delete behaviors for nodes.
76
+ */
77
+ type DeleteBehavior = "restrict" | "cascade" | "disconnect";
78
+ /**
79
+ * Edge cardinality constraints.
80
+ */
81
+ type Cardinality = "many" | "one" | "unique" | "oneActive";
82
+ /**
83
+ * Endpoint existence modes for edge validation.
84
+ */
85
+ type EndpointExistence = "notDeleted" | "currentlyValid" | "ever";
86
+ /**
87
+ * Temporal query modes.
88
+ */
89
+ type TemporalMode = "current" | "asOf" | "includeEnded" | "includeTombstones";
90
+ /**
91
+ * Uniqueness constraint scope.
92
+ */
93
+ type UniquenessScope = "kind" | "kindWithSubClasses";
94
+ /**
95
+ * Collation for uniqueness constraints.
96
+ */
97
+ type Collation = "binary" | "caseInsensitive";
98
+ /**
99
+ * Uniqueness constraint definition.
100
+ */
101
+ type UniqueConstraint<S extends z.ZodObject<z.ZodRawShape> = z.ZodObject<z.ZodRawShape>> = Readonly<{
102
+ name: string;
103
+ fields: readonly (keyof z.infer<S> & string)[];
104
+ where?: (props: UniqueConstraintPredicateBuilder<S>) => UniqueConstraintPredicate;
105
+ scope: UniquenessScope;
106
+ collation: Collation;
107
+ }>;
108
+ /**
109
+ * Predicate builder for uniqueness constraint where clause.
110
+ * Uses -? to make all fields required in the builder, even if optional in the schema.
111
+ */
112
+ type UniqueConstraintPredicateBuilder<S extends z.ZodObject<z.ZodRawShape>> = Readonly<{
113
+ [K in keyof z.infer<S>]-?: UniqueConstraintField;
114
+ }>;
115
+ /**
116
+ * Field operations for uniqueness constraint predicates.
117
+ */
118
+ type UniqueConstraintField = Readonly<{
119
+ isNull: () => UniqueConstraintPredicate;
120
+ isNotNull: () => UniqueConstraintPredicate;
121
+ }>;
122
+ /**
123
+ * A uniqueness constraint predicate (internal representation).
124
+ */
125
+ type UniqueConstraintPredicate = Readonly<{
126
+ __type: "unique_predicate";
127
+ field: string;
128
+ op: "isNull" | "isNotNull";
129
+ }>;
130
+ /**
131
+ * Node registration in a graph definition.
132
+ */
133
+ type NodeRegistration<N extends NodeType = NodeType> = Readonly<{
134
+ type: N;
135
+ unique?: readonly UniqueConstraint<N["schema"]>[];
136
+ onDelete?: DeleteBehavior;
137
+ }>;
138
+ /**
139
+ * Edge registration in a graph definition.
140
+ */
141
+ type EdgeRegistration<E extends AnyEdgeType = AnyEdgeType, FromTypes extends NodeType = NodeType, ToTypes extends NodeType = NodeType> = Readonly<{
142
+ type: E;
143
+ from: readonly FromTypes[];
144
+ to: readonly ToTypes[];
145
+ cardinality?: Cardinality;
146
+ endpointExistence?: EndpointExistence;
147
+ }>;
148
+ /**
149
+ * Default settings for a graph.
150
+ */
151
+ type GraphDefaults = Readonly<{
152
+ onNodeDelete?: DeleteBehavior;
153
+ temporalMode?: TemporalMode;
154
+ }>;
155
+ /**
156
+ * Checks if a value is a NodeType.
157
+ */
158
+ declare function isNodeType(value: unknown): value is NodeType;
159
+ /**
160
+ * Checks if a value is an EdgeType.
161
+ */
162
+ declare function isEdgeType(value: unknown): value is AnyEdgeType;
163
+ /**
164
+ * Checks if a value is an EdgeType with both from and to constraints defined.
165
+ * Such edges can be used directly in defineGraph without an EdgeRegistration wrapper.
166
+ */
167
+ declare function isEdgeTypeWithEndpoints(value: unknown): value is EdgeTypeWithEndpoints;
3
168
 
4
169
  /** Brand key for MetaEdge */
5
170
  declare const META_EDGE_BRAND: "__metaEdge";
@@ -69,6 +234,8 @@ type SqlTableNames = Readonly<{
69
234
  edges: string;
70
235
  /** Node embeddings table name (default: "typegraph_node_embeddings") */
71
236
  embeddings: string;
237
+ /** Node fulltext table name (default: "typegraph_node_fulltext") */
238
+ fulltext: string;
72
239
  }>;
73
240
  /**
74
241
  * SQL schema configuration for query compilation.
@@ -83,6 +250,8 @@ type SqlSchema = Readonly<{
83
250
  edgesTable: SQL;
84
251
  /** Get a SQL reference to the embeddings table */
85
252
  embeddingsTable: SQL;
253
+ /** Get a SQL reference to the fulltext table */
254
+ fulltextTable: SQL;
86
255
  }>;
87
256
  /**
88
257
  * Creates a SqlSchema configuration from table names.
@@ -113,6 +282,115 @@ declare function createSqlSchema(names?: Partial<SqlTableNames>): SqlSchema;
113
282
  */
114
283
  declare const DEFAULT_SQL_SCHEMA: SqlSchema;
115
284
 
285
+ /**
286
+ * Fulltext Strategy — pluggable DDL + SQL generation for a dialect's
287
+ * fulltext stack. A strategy owns every SQL statement that touches its
288
+ * backing table: DDL, upsert (single + batch), delete (single + batch),
289
+ * MATCH condition, rank expression, and snippet expression.
290
+ *
291
+ * A dialect picks one as its default; `createPostgresBackend` /
292
+ * `createSqliteBackend` accept an override for alternate Postgres stacks
293
+ * (pg_trgm, ParadeDB/pg_search, pgroonga) to swap the entire fulltext
294
+ * pipeline without forking TypeGraph.
295
+ */
296
+
297
+ /**
298
+ * A pluggable fulltext implementation. Each strategy is expected to be
299
+ * self-contained: given a table name, a query string, and a parse mode,
300
+ * it emits every SQL statement the compiler and backend need — DDL,
301
+ * reads, and writes. No out-of-band conventions across layers.
302
+ */
303
+ interface FulltextStrategy {
304
+ /** Human-readable identifier used in error messages and telemetry. */
305
+ readonly name: string;
306
+ /**
307
+ * Parse modes this strategy can translate. Callers validate against
308
+ * this list before emitting SQL; a mode outside the set means the
309
+ * strategy rejects the query at compile time.
310
+ */
311
+ readonly supportedModes: readonly FulltextQueryMode[];
312
+ /**
313
+ * Whether the strategy can emit a per-row highlighted snippet. When
314
+ * false, `snippetExpression` returns a literal `NULL` so callers can
315
+ * leave the `snippet` column in place without a branch.
316
+ */
317
+ readonly supportsSnippets: boolean;
318
+ /**
319
+ * Whether the strategy supports prefix queries (`foo*`). Used to
320
+ * populate `BackendCapabilities.fulltext.prefixQueries`. A strategy
321
+ * may support prefix queries via dedicated syntax without advertising
322
+ * "raw" mode (and vice-versa).
323
+ */
324
+ readonly supportsPrefix: boolean;
325
+ /**
326
+ * Whether a per-query `language` override is honored. Postgres' tsvector
327
+ * accepts any installed regconfig at query time; SQLite FTS5's tokenizer
328
+ * is fixed at table-create time, so the override is silently ignored.
329
+ * Callers may surface a warning when the user passes `language` to a
330
+ * strategy that doesn't honor it.
331
+ */
332
+ readonly supportsLanguageOverride: boolean;
333
+ /**
334
+ * Languages / tokenizer names understood by the strategy. Advisory — a
335
+ * runtime backend like Postgres may accept other installed regconfigs.
336
+ * Used to populate `BackendCapabilities.fulltext.languages`.
337
+ */
338
+ readonly languages: readonly string[];
339
+ /**
340
+ * Emits the WHERE-side MATCH expression.
341
+ *
342
+ * @example
343
+ * tsvector: `"typegraph_node_fulltext"."tsv" @@ websearch_to_tsquery('english', 'cats')`
344
+ * fts5: `"typegraph_node_fulltext" MATCH '"cats"'`
345
+ */
346
+ matchCondition(tableName: string, query: string, mode: FulltextQueryMode, language?: string): SQL;
347
+ /**
348
+ * Emits the relevance expression. Higher values = more relevant. The
349
+ * compiler orders by this expression DESC, and both builder and
350
+ * backend-direct paths use the same form so their top-k results agree.
351
+ */
352
+ rankExpression(tableName: string, query: string, mode: FulltextQueryMode, language?: string): SQL;
353
+ /**
354
+ * Emits a per-row highlighted snippet expression, or `NULL` when
355
+ * `supportsSnippets` is false. Snippet markup is `<mark>…</mark>` in
356
+ * both shipped strategies so consumers can apply one stylesheet.
357
+ */
358
+ snippetExpression(tableName: string, query: string, mode: FulltextQueryMode, language?: string): SQL;
359
+ /**
360
+ * DDL statements to create the backing table and any supporting
361
+ * indexes. Idempotent (`CREATE ... IF NOT EXISTS`). Called once from
362
+ * `bootstrapTables()` on a fresh database.
363
+ */
364
+ generateDdl(tableName: string): readonly string[];
365
+ /**
366
+ * Emits the statements that upsert a single fulltext row. Returns one
367
+ * or more statements — some backends (SQLite FTS5) cannot emulate
368
+ * upsert in a single statement and need DELETE + INSERT.
369
+ */
370
+ buildUpsert(tableName: string, params: UpsertFulltextParams, timestamp: string): readonly SQL[];
371
+ /**
372
+ * Emits the statements that upsert many fulltext rows at once. Input
373
+ * rows are expected to be de-duplicated last-write-wins by the
374
+ * strategy if the underlying SQL statement cannot tolerate duplicate
375
+ * conflict keys. Returns `[]` when `params.rows` is empty.
376
+ */
377
+ buildBatchUpsert(tableName: string, params: UpsertFulltextBatchParams, timestamp: string): readonly SQL[];
378
+ /**
379
+ * Emits the statements that delete a single fulltext row. Normally a
380
+ * single PK-scoped DELETE, but strategies that maintain auxiliary
381
+ * indexes (delete-triggered external stores, ParadeDB-style secondary
382
+ * structures) may need more.
383
+ */
384
+ buildDelete(tableName: string, params: DeleteFulltextParams): readonly SQL[];
385
+ /**
386
+ * Emits the statements that delete many fulltext rows at once. Returns
387
+ * `[]` when `params.nodeIds` is empty.
388
+ */
389
+ buildBatchDelete(tableName: string, params: DeleteFulltextBatchParams): readonly SQL[];
390
+ }
391
+ declare const tsvectorStrategy: FulltextStrategy;
392
+ declare const fts5Strategy: FulltextStrategy;
393
+
116
394
  /**
117
395
  * Types for serialized schema storage.
118
396
  *
@@ -257,6 +535,19 @@ type SerializedSchema = Readonly<{
257
535
  */
258
536
  type SchemaHash = string;
259
537
 
538
+ /**
539
+ * SQL Dialect Abstraction Layer
540
+ *
541
+ * Provides a unified interface for dialect-specific SQL generation.
542
+ * Implementing a new dialect (MySQL, SQL Server, etc.) requires
543
+ * implementing this interface.
544
+ */
545
+
546
+ /**
547
+ * Supported SQL dialects.
548
+ */
549
+ type SqlDialect = "sqlite" | "postgres";
550
+
260
551
  /**
261
552
  * Backend interface types for TypeGraph storage.
262
553
  *
@@ -285,6 +576,37 @@ type VectorCapabilities = Readonly<{
285
576
  /** Maximum dimensions supported */
286
577
  maxDimensions: number;
287
578
  }>;
579
+ /**
580
+ * Query modes for fulltext search.
581
+ *
582
+ * - "websearch": Google-style syntax (quoted phrases, +required, -excluded).
583
+ * Postgres: `websearch_to_tsquery`. SQLite: translated to FTS5 MATCH.
584
+ * - "phrase": treats the whole query as a phrase.
585
+ * Postgres: `phraseto_tsquery`. SQLite: FTS5 `"..."` phrase.
586
+ * - "plain": splits on whitespace and ANDs terms.
587
+ * Postgres: `plainto_tsquery`. SQLite: default FTS5 AND.
588
+ * - "raw": dialect-native syntax passed through unchanged.
589
+ */
590
+ type FulltextQueryMode = "websearch" | "phrase" | "plain" | "raw";
591
+ /**
592
+ * Fulltext search capabilities declared by a backend.
593
+ */
594
+ type FulltextCapabilities = Readonly<{
595
+ /** Whether the backend supports fulltext operations */
596
+ supported: boolean;
597
+ /**
598
+ * Language / tokenizer names understood by this backend.
599
+ * Postgres: installed regconfigs (english, simple, ...).
600
+ * SQLite FTS5: tokenizer names (unicode61, porter, trigram).
601
+ */
602
+ languages: readonly string[];
603
+ /** Whether phrase queries are supported. */
604
+ phraseQueries: boolean;
605
+ /** Whether prefix (`foo*`) queries are supported. */
606
+ prefixQueries: boolean;
607
+ /** Whether highlighting / snippets are supported. */
608
+ highlighting: boolean;
609
+ }>;
288
610
 
289
611
  /**
290
612
  * Backend capabilities that vary by dialect.
@@ -304,6 +626,8 @@ type BackendCapabilities = Readonly<{
304
626
  transactions: boolean;
305
627
  /** Vector search capabilities (undefined if not configured) */
306
628
  vector?: VectorCapabilities | undefined;
629
+ /** Fulltext search capabilities (undefined if not configured) */
630
+ fulltext?: FulltextCapabilities | undefined;
307
631
  }>;
308
632
  /**
309
633
  * A row from the typegraph_nodes table.
@@ -524,6 +848,118 @@ type DropVectorIndexParams = Readonly<{
524
848
  nodeKind: string;
525
849
  fieldPath: string;
526
850
  }>;
851
+ /**
852
+ * Parameters for inserting or updating a fulltext entry.
853
+ *
854
+ * One row per node. Callers concatenate the searchable fields into
855
+ * `content` so a single MATCH query can find terms spread across fields.
856
+ */
857
+ type UpsertFulltextParams = Readonly<{
858
+ graphId: string;
859
+ nodeKind: string;
860
+ nodeId: string;
861
+ content: string;
862
+ language: string;
863
+ }>;
864
+ /**
865
+ * Parameters for deleting a single fulltext entry.
866
+ */
867
+ type DeleteFulltextParams = Readonly<{
868
+ graphId: string;
869
+ nodeKind: string;
870
+ nodeId: string;
871
+ }>;
872
+ /**
873
+ * A single row in a fulltext batch upsert.
874
+ */
875
+ type FulltextBatchRow = Readonly<{
876
+ nodeId: string;
877
+ content: string;
878
+ language: string;
879
+ }>;
880
+ /**
881
+ * Parameters for a batched fulltext upsert.
882
+ *
883
+ * Homogeneous: one graph, one node kind, many nodes. Duplicate `nodeId`
884
+ * values within a single batch are deduplicated last-write-wins by the
885
+ * builders before SQL generation — Postgres `ON CONFLICT` errors on
886
+ * repeated conflict keys in one statement, and SQLite `DELETE + INSERT`
887
+ * would create duplicate virtual-table rows otherwise.
888
+ */
889
+ type UpsertFulltextBatchParams = Readonly<{
890
+ graphId: string;
891
+ nodeKind: string;
892
+ rows: readonly FulltextBatchRow[];
893
+ }>;
894
+ /**
895
+ * Parameters for a batched fulltext delete.
896
+ */
897
+ type DeleteFulltextBatchParams = Readonly<{
898
+ graphId: string;
899
+ nodeKind: string;
900
+ nodeIds: readonly string[];
901
+ }>;
902
+ /**
903
+ * Parameters for fulltext search.
904
+ */
905
+ type FulltextSearchParams = Readonly<{
906
+ graphId: string;
907
+ nodeKind: string;
908
+ /** The user-supplied query string. */
909
+ query: string;
910
+ /** How to parse `query`. Default: "websearch". */
911
+ mode?: FulltextQueryMode;
912
+ /**
913
+ * Language override. Default: per-row language (as stored at insert time).
914
+ * Postgres: passed as the regconfig to `to_tsquery` / `websearch_to_tsquery`.
915
+ * SQLite: informational only (FTS5 tokenizer is fixed at table-create time).
916
+ */
917
+ language?: string;
918
+ /** Max rows to return. */
919
+ limit: number;
920
+ /** Minimum rank to include (backend-dependent units). */
921
+ minScore?: number;
922
+ /** Whether to return a highlighted snippet per match. */
923
+ includeSnippets?: boolean;
924
+ }>;
925
+ /**
926
+ * Result from a fulltext search.
927
+ *
928
+ * Score semantics differ by backend; prefer `rank` (1-based) when fusing
929
+ * with another source via RRF.
930
+ */
931
+ type FulltextSearchResult = Readonly<{
932
+ nodeId: string;
933
+ /**
934
+ * Backend-native relevance score.
935
+ * Postgres: `ts_rank_cd` (higher is better).
936
+ * SQLite FTS5: negated `bm25()` (higher is better; FTS5 returns lower-is-better).
937
+ */
938
+ score: number;
939
+ /** 1-based rank within the result set, suitable for RRF. */
940
+ rank: number;
941
+ /** Highlighted snippet of the content (if `includeSnippets` was set). */
942
+ snippet?: string;
943
+ }>;
944
+ /**
945
+ * Parameters for creating a fulltext index.
946
+ *
947
+ * The canonical index (Postgres GIN on `tsv`, SQLite FTS5 virtual table)
948
+ * is created when the fulltext table itself is created. This is reserved
949
+ * for advanced per-kind specializations.
950
+ */
951
+ type CreateFulltextIndexParams = Readonly<{
952
+ graphId: string;
953
+ nodeKind: string;
954
+ language: string;
955
+ }>;
956
+ /**
957
+ * Parameters for dropping a fulltext index created via createFulltextIndex.
958
+ */
959
+ type DropFulltextIndexParams = Readonly<{
960
+ graphId: string;
961
+ nodeKind: string;
962
+ }>;
527
963
  /**
528
964
  * Transaction options.
529
965
  */
@@ -549,6 +985,14 @@ type GraphBackend = Readonly<{
549
985
  capabilities: BackendCapabilities;
550
986
  /** Table names used by this backend (for query schema auto-derivation) */
551
987
  tableNames?: SqlTableNames | undefined;
988
+ /**
989
+ * Optional fulltext strategy override. When present, both the compiler
990
+ * (for `$fulltext.matches()` in query builder) and backend-direct
991
+ * search paths use this instead of the dialect's default strategy —
992
+ * allowing a Postgres backend to ship pg_trgm, ParadeDB, pgroonga etc.
993
+ * When absent, the dialect's default strategy is used.
994
+ */
995
+ fulltextStrategy?: FulltextStrategy | undefined;
552
996
  insertNode: (params: InsertNodeParams) => Promise<NodeRow>;
553
997
  insertNodeNoReturn?: (params: InsertNodeParams) => Promise<void>;
554
998
  insertNodesBatch?: (params: readonly InsertNodeParams[]) => Promise<void>;
@@ -588,6 +1032,21 @@ type GraphBackend = Readonly<{
588
1032
  vectorSearch?: (params: VectorSearchParams) => Promise<readonly VectorSearchResult[]>;
589
1033
  createVectorIndex?: (params: CreateVectorIndexParams) => Promise<void>;
590
1034
  dropVectorIndex?: (params: DropVectorIndexParams) => Promise<void>;
1035
+ upsertFulltext?: (params: UpsertFulltextParams) => Promise<void>;
1036
+ deleteFulltext?: (params: DeleteFulltextParams) => Promise<void>;
1037
+ /**
1038
+ * Batched variant of `upsertFulltext`. Optional — callers fall back to
1039
+ * per-row `upsertFulltext` when unset.
1040
+ */
1041
+ upsertFulltextBatch?: (params: UpsertFulltextBatchParams) => Promise<void>;
1042
+ /**
1043
+ * Batched variant of `deleteFulltext`. Optional — callers fall back to
1044
+ * per-row `deleteFulltext` when unset.
1045
+ */
1046
+ deleteFulltextBatch?: (params: DeleteFulltextBatchParams) => Promise<void>;
1047
+ fulltextSearch?: (params: FulltextSearchParams) => Promise<readonly FulltextSearchResult[]>;
1048
+ createFulltextIndex?: (params: CreateFulltextIndexParams) => Promise<void>;
1049
+ dropFulltextIndex?: (params: DropFulltextIndexParams) => Promise<void>;
591
1050
  /**
592
1051
  * Hard-deletes all data for a graph (nodes, edges, uniques, embeddings, schema versions).
593
1052
  * Intended for import-replacement workflows. No hooks, no per-row logic.
@@ -700,7 +1159,9 @@ type FindEdgesConnectedToParams = Readonly<{
700
1159
  type FindNodesByKindParams = Readonly<{
701
1160
  graphId: string;
702
1161
  kind: string;
1162
+ /** Max rows to return. */
703
1163
  limit?: number;
1164
+ /** Offset. Present for backward compat; rebuild uses `after` instead. */
704
1165
  offset?: number;
705
1166
  /** If true, exclude deleted nodes. Default true. */
706
1167
  excludeDeleted?: boolean;
@@ -708,6 +1169,18 @@ type FindNodesByKindParams = Readonly<{
708
1169
  temporalMode?: TemporalMode;
709
1170
  /** Timestamp for "current" and "asOf" temporal modes. */
710
1171
  asOf?: string;
1172
+ /**
1173
+ * Stable ordering for keyset pagination. Default: "created_at" (existing
1174
+ * behavior). Rebuild should use "id" for iteration that is stable under
1175
+ * concurrent writes and shared timestamps.
1176
+ */
1177
+ orderBy?: "id" | "created_at";
1178
+ /**
1179
+ * Keyset cursor. Returns rows strictly greater (by `orderBy`) than this
1180
+ * value. When `orderBy: "id"`, compared lexicographically. Mutually
1181
+ * exclusive with `offset` — callers pick one.
1182
+ */
1183
+ after?: string;
711
1184
  }>;
712
1185
  /**
713
1186
  * Parameters for counting nodes by kind.
@@ -759,4 +1232,4 @@ type CountEdgesByKindParams = Readonly<{
759
1232
  asOf?: string;
760
1233
  }>;
761
1234
 
762
- export { DEFAULT_SQL_SCHEMA as D, type EdgeRow as E, type GraphBackend as G, type InferenceType as I, type JsonSchema as J, type MetaEdge as M, type NodeRow as N, type OntologyRelation as O, type SqlSchema as S, type TransactionBackend as T, type MetaEdgeProperties as a, type SqlTableNames as b, createSqlSchema as c, type SerializedNodeDef as d, type SerializedEdgeDef as e, type SerializedMetaEdge as f, type SerializedOntologyRelation as g, type SerializedClosures as h, isMetaEdge as i, type SerializedSchema as j, type SchemaHash as k, type SerializedOntology as l, type SerializedUniqueConstraint as m, type SchemaVersionRow as n };
1235
+ export { type SerializedSchema as $, type AnyEdgeType as A, type BackendCapabilities as B, type Cardinality as C, DEFAULT_SQL_SCHEMA as D, type EdgeType as E, type FulltextBatchRow as F, type GraphBackend as G, isEdgeTypeWithEndpoints as H, type InferenceType as I, isMetaEdge as J, isNodeType as K, tsvectorStrategy as L, type MetaEdge as M, type NodeType as N, type OntologyRelation as O, type EdgeRow as P, type NodeRow as Q, type VectorMetric as R, type SqlDialect as S, type TemporalMode as T, type UniqueConstraint as U, type VectorCapabilities as V, type SerializedNodeDef as W, type SerializedEdgeDef as X, type SerializedMetaEdge as Y, type SerializedOntologyRelation as Z, type SerializedClosures as _, type Collation as a, type SchemaHash as a0, type JsonSchema as a1, type SerializedOntology as a2, type SerializedUniqueConstraint as a3, type SchemaVersionRow as a4, type DeleteBehavior as b, type DeleteFulltextBatchParams as c, type EdgeId as d, type EdgeProps as e, type EdgeRegistration as f, type EdgeTypeWithEndpoints as g, type EndpointExistence as h, type FulltextCapabilities as i, type FulltextQueryMode as j, type FulltextSearchParams as k, type FulltextSearchResult as l, type FulltextStrategy as m, type GraphDefaults as n, type MetaEdgeProperties as o, type NodeId as p, type NodeProps as q, type NodeRegistration as r, type SqlSchema as s, type SqlTableNames as t, type TransactionBackend as u, type UniquenessScope as v, type UpsertFulltextBatchParams as w, createSqlSchema as x, fts5Strategy as y, isEdgeType as z };