@nicia-ai/typegraph 0.24.1 → 0.25.1

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 (159) hide show
  1. package/dist/backend/postgres/index.cjs +226 -55
  2. package/dist/backend/postgres/index.cjs.map +1 -1
  3. package/dist/backend/postgres/index.d.cts +6 -7
  4. package/dist/backend/postgres/index.d.ts +6 -7
  5. package/dist/backend/postgres/index.js +195 -28
  6. package/dist/backend/postgres/index.js.map +1 -1
  7. package/dist/backend/sqlite/index.cjs +19 -17
  8. package/dist/backend/sqlite/index.d.cts +6 -7
  9. package/dist/backend/sqlite/index.d.ts +6 -7
  10. package/dist/backend/sqlite/index.js +9 -7
  11. package/dist/backend/sqlite/libsql.cjs +12 -10
  12. package/dist/backend/sqlite/libsql.cjs.map +1 -1
  13. package/dist/backend/sqlite/libsql.d.cts +4 -5
  14. package/dist/backend/sqlite/libsql.d.ts +4 -5
  15. package/dist/backend/sqlite/libsql.js +9 -7
  16. package/dist/backend/sqlite/libsql.js.map +1 -1
  17. package/dist/backend/sqlite/local.cjs +14 -12
  18. package/dist/backend/sqlite/local.cjs.map +1 -1
  19. package/dist/backend/sqlite/local.d.cts +4 -5
  20. package/dist/backend/sqlite/local.d.ts +4 -5
  21. package/dist/backend/sqlite/local.js +9 -7
  22. package/dist/backend/sqlite/local.js.map +1 -1
  23. package/dist/chunk-4BOWVUGQ.js +2029 -0
  24. package/dist/chunk-4BOWVUGQ.js.map +1 -0
  25. package/dist/chunk-7V335GHG.cjs +112 -0
  26. package/dist/chunk-7V335GHG.cjs.map +1 -0
  27. package/dist/chunk-AAA2CR3P.js +2628 -0
  28. package/dist/chunk-AAA2CR3P.js.map +1 -0
  29. package/dist/{chunk-QOLTW7OZ.js → chunk-CLEUFN2K.js} +195 -13
  30. package/dist/chunk-CLEUFN2K.js.map +1 -0
  31. package/dist/{chunk-OVJ2BE5Q.cjs → chunk-CLGC7AQ2.cjs} +215 -33
  32. package/dist/chunk-CLGC7AQ2.cjs.map +1 -0
  33. package/dist/{chunk-GUTQTMOV.js → chunk-CPFR3O7L.js} +2 -2
  34. package/dist/chunk-CPFR3O7L.js.map +1 -0
  35. package/dist/{chunk-5HVDOPZU.cjs → chunk-CQVNGKU7.cjs} +452 -104
  36. package/dist/chunk-CQVNGKU7.cjs.map +1 -0
  37. package/dist/chunk-CTHNVU6K.cjs +551 -0
  38. package/dist/chunk-CTHNVU6K.cjs.map +1 -0
  39. package/dist/chunk-D2GO3RBL.cjs +12 -0
  40. package/dist/chunk-D2GO3RBL.cjs.map +1 -0
  41. package/dist/{chunk-WFMTAEEN.js → chunk-DOTEN2FG.js} +81 -7
  42. package/dist/chunk-DOTEN2FG.js.map +1 -0
  43. package/dist/chunk-E5JZSEGJ.cjs +301 -0
  44. package/dist/chunk-E5JZSEGJ.cjs.map +1 -0
  45. package/dist/chunk-EG6TJ3I5.js +286 -0
  46. package/dist/chunk-EG6TJ3I5.js.map +1 -0
  47. package/dist/chunk-EJCDOA37.js +537 -0
  48. package/dist/chunk-EJCDOA37.js.map +1 -0
  49. package/dist/{chunk-UVZHTBZ5.cjs → chunk-EK6RJ373.cjs} +7 -150
  50. package/dist/chunk-EK6RJ373.cjs.map +1 -0
  51. package/dist/{chunk-3JK66E3I.cjs → chunk-JTI5WT4P.cjs} +630 -59
  52. package/dist/chunk-JTI5WT4P.cjs.map +1 -0
  53. package/dist/chunk-NHQWXSTS.js +10 -0
  54. package/dist/chunk-NHQWXSTS.js.map +1 -0
  55. package/dist/chunk-NZ5PMBTG.js +105 -0
  56. package/dist/chunk-NZ5PMBTG.js.map +1 -0
  57. package/dist/{chunk-SUHW2UYL.cjs → chunk-OECDVACY.cjs} +2 -2
  58. package/dist/chunk-OECDVACY.cjs.map +1 -0
  59. package/dist/{chunk-EYELZHKY.js → chunk-OOS2RKRH.js} +5 -140
  60. package/dist/chunk-OOS2RKRH.js.map +1 -0
  61. package/dist/{chunk-EY4LBX3F.js → chunk-PSKUWVCB.js} +373 -38
  62. package/dist/chunk-PSKUWVCB.js.map +1 -0
  63. package/dist/chunk-QMQYK3IF.cjs +2680 -0
  64. package/dist/chunk-QMQYK3IF.cjs.map +1 -0
  65. package/dist/chunk-RCAJZG67.cjs +2069 -0
  66. package/dist/chunk-RCAJZG67.cjs.map +1 -0
  67. package/dist/{chunk-O5PST6TB.cjs → chunk-W5MTHMTE.cjs} +83 -6
  68. package/dist/chunk-W5MTHMTE.cjs.map +1 -0
  69. package/dist/chunk-WVQXAFP3.js +79 -0
  70. package/dist/chunk-WVQXAFP3.js.map +1 -0
  71. package/dist/chunk-X3244EKP.cjs +84 -0
  72. package/dist/chunk-X3244EKP.cjs.map +1 -0
  73. package/dist/{chunk-753F33CV.js → chunk-YZZBDCLV.js} +617 -44
  74. package/dist/chunk-YZZBDCLV.js.map +1 -0
  75. package/dist/{ddl-B_H8JM-E.d.cts → ddl-BqMmpNor.d.ts} +1328 -283
  76. package/dist/{ddl-1tFIvt9V.d.ts → ddl-Bwjh8Hff.d.cts} +1328 -283
  77. package/dist/extension-types-D07e_NTw.d.cts +543 -0
  78. package/dist/extension-types-D07e_NTw.d.ts +543 -0
  79. package/dist/graph-extension/index.cjs +71 -0
  80. package/dist/graph-extension/index.cjs.map +1 -0
  81. package/dist/graph-extension/index.d.cts +278 -0
  82. package/dist/graph-extension/index.d.ts +278 -0
  83. package/dist/graph-extension/index.js +6 -0
  84. package/dist/graph-extension/index.js.map +1 -0
  85. package/dist/{index-DXkEXpNz.d.ts → index-CT6nvtxL.d.cts} +114 -5
  86. package/dist/{index-DXkEXpNz.d.cts → index-DQheiVQV.d.ts} +114 -5
  87. package/dist/index.cjs +2672 -901
  88. package/dist/index.cjs.map +1 -1
  89. package/dist/index.d.cts +29 -10
  90. package/dist/index.d.ts +29 -10
  91. package/dist/index.js +2248 -598
  92. package/dist/index.js.map +1 -1
  93. package/dist/indexes/index.cjs +25 -23
  94. package/dist/indexes/index.d.cts +40 -22
  95. package/dist/indexes/index.d.ts +40 -22
  96. package/dist/indexes/index.js +5 -3
  97. package/dist/interchange/index.cjs +8 -7
  98. package/dist/interchange/index.cjs.map +1 -1
  99. package/dist/interchange/index.d.cts +5 -4
  100. package/dist/interchange/index.d.ts +5 -4
  101. package/dist/interchange/index.js +3 -2
  102. package/dist/interchange/index.js.map +1 -1
  103. package/dist/{manager-Vkz28eAC.d.cts → manager-Cy3dhwYO.d.cts} +194 -6
  104. package/dist/{manager-nIhmttD-.d.ts → manager-sZkU2VPC.d.ts} +194 -6
  105. package/dist/materialize-indexes-BB9N5uQl.d.cts +68 -0
  106. package/dist/materialize-indexes-BYpU2RKh.d.ts +68 -0
  107. package/dist/profiler/index.cjs +10 -8
  108. package/dist/profiler/index.cjs.map +1 -1
  109. package/dist/profiler/index.d.cts +8 -7
  110. package/dist/profiler/index.d.ts +8 -7
  111. package/dist/profiler/index.js +3 -1
  112. package/dist/profiler/index.js.map +1 -1
  113. package/dist/schema/index.cjs +43 -22
  114. package/dist/schema/index.cjs.map +1 -1
  115. package/dist/schema/index.d.cts +17 -8
  116. package/dist/schema/index.d.ts +17 -8
  117. package/dist/schema/index.js +9 -4
  118. package/dist/schema/index.js.map +1 -1
  119. package/dist/{sqlite-D0aceIe0.d.cts → sqlite-BhFswiAR.d.cts} +837 -120
  120. package/dist/{sqlite-SUxbZqfy.d.ts → sqlite-h6dta1IJ.d.ts} +837 -120
  121. package/dist/{store-CpvwTMxV.d.cts → store-BS_hehiz.d.ts} +659 -23
  122. package/dist/{store-U3i2tUch.d.ts → store-CkCvqRUf.d.cts} +659 -23
  123. package/dist/{types-yH4_p0XB.d.cts → types-BpgACExN.d.cts} +3 -2
  124. package/dist/{types-qYFZ9SqD.d.ts → types-Bz-Pi681.d.ts} +3 -2
  125. package/dist/types-DptZHe-l.d.ts +2132 -0
  126. package/dist/types-WF5ItKQu.d.cts +2132 -0
  127. package/dist/where-C40InMIp.d.ts +11 -0
  128. package/dist/where-DZYMiXVq.d.cts +11 -0
  129. package/package.json +33 -73
  130. package/dist/ast-C8S37w1A.d.ts +0 -497
  131. package/dist/ast-dgLhLOg0.d.cts +0 -497
  132. package/dist/chunk-3JK66E3I.cjs.map +0 -1
  133. package/dist/chunk-3PPEHLGK.js +0 -1116
  134. package/dist/chunk-3PPEHLGK.js.map +0 -1
  135. package/dist/chunk-5HVDOPZU.cjs.map +0 -1
  136. package/dist/chunk-753F33CV.js.map +0 -1
  137. package/dist/chunk-EY4LBX3F.js.map +0 -1
  138. package/dist/chunk-EYELZHKY.js.map +0 -1
  139. package/dist/chunk-GFGVREHH.js +0 -1381
  140. package/dist/chunk-GFGVREHH.js.map +0 -1
  141. package/dist/chunk-GUTQTMOV.js.map +0 -1
  142. package/dist/chunk-LBORRUNJ.js +0 -135
  143. package/dist/chunk-LBORRUNJ.js.map +0 -1
  144. package/dist/chunk-O5PST6TB.cjs.map +0 -1
  145. package/dist/chunk-OLROXS2S.cjs +0 -147
  146. package/dist/chunk-OLROXS2S.cjs.map +0 -1
  147. package/dist/chunk-OVJ2BE5Q.cjs.map +0 -1
  148. package/dist/chunk-PAUN562Y.cjs +0 -1417
  149. package/dist/chunk-PAUN562Y.cjs.map +0 -1
  150. package/dist/chunk-PEE4EWXZ.cjs +0 -1131
  151. package/dist/chunk-PEE4EWXZ.cjs.map +0 -1
  152. package/dist/chunk-QOLTW7OZ.js.map +0 -1
  153. package/dist/chunk-SUHW2UYL.cjs.map +0 -1
  154. package/dist/chunk-UVZHTBZ5.cjs.map +0 -1
  155. package/dist/chunk-WFMTAEEN.js.map +0 -1
  156. package/dist/types-C-zfYDJB.d.ts +0 -159
  157. package/dist/types-CQx4iW5Y.d.cts +0 -159
  158. package/dist/types-Qk2l3IkQ.d.cts +0 -1254
  159. package/dist/types-Qk2l3IkQ.d.ts +0 -1254
@@ -1,8 +1,9 @@
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-Qk2l3IkQ.js';
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-nIhmttD-.js';
3
1
  import { z } from 'zod';
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-C8S37w1A.js';
2
+ import { m as SqlDialect, ac as SqlSchema, F as FulltextStrategy, aq as ValueType, ar as PredicateExpression, as as VectorMetricType, X as FulltextQueryMode, Q as QueryAst, J as JsonPointer, C as FieldRef, a7 as ParameterRef, G as GraphBackend, ae as TransactionBackend, a0 as JsonPointerInput, af as TraversalExpansion, at as Traversal, au as NodePredicate, av as ProjectedField, a6 as OrderSpec, aw as GroupBySpec, _ as HybridFusionOptions, ax as RecursiveCyclePolicy, ay as TraversalDirection$1, az as EdgeRow, aA as NodeRow, A as AggregateExpr, aB as SelectiveField, aC as ComposableQuery, aD as SetOperationType, aE as SetOperation, ab as SortDirection, j as JsonSchema, aF as VectorMetric } from './types-WF5ItKQu.cjs';
3
+ import { K as KindRegistry, G as GraphDef, t as EdgeKinds, w as NodeKinds, s as AllNodeTypes, c as SchemaManagerOptions, d as SchemaValidationResult } from './manager-Cy3dhwYO.cjs';
4
+ import { A as AnyEdgeType, N as NodeType, T as TemporalMode, d as EdgeType, E as EdgeRegistration, i as EdgeId, m as NodeId, b as NodeRegistration, K as KindEntity, f as Cardinality, g as EndpointExistence, e as KindAnnotations, U as UniquenessScope, C as Collation, G as GraphExtension } from './extension-types-D07e_NTw.cjs';
5
5
  import { SQL } from 'drizzle-orm';
6
+ import { b as MaterializeIndexesOptions, M as MaterializeIndexesResult } from './materialize-indexes-BB9N5uQl.cjs';
6
7
 
7
8
  /**
8
9
  * Embedding type for vector search.
@@ -31,12 +32,73 @@ type EmbeddingValue = readonly number[] & {
31
32
  * and extract dimension information.
32
33
  */
33
34
  declare const EMBEDDING_DIMENSIONS_KEY: "_embeddingDimensions";
35
+ /**
36
+ * Symbol key for storing the embedding's preferred index configuration
37
+ * on the schema. The schema introspector reads this when auto-deriving
38
+ * `VectorIndexDeclaration` entries at `defineGraph()` time.
39
+ */
40
+ declare const EMBEDDING_INDEX_KEY: "_embeddingIndex";
41
+ /**
42
+ * Distance metric used for vector similarity. Pinned at the embedding
43
+ * brand because changing the metric usually means generating different
44
+ * model output (e.g. cosine-normalized vs. raw inner-product), and the
45
+ * stored index needs the same metric to score correctly.
46
+ *
47
+ * - `cosine`: cosine similarity. The default — works for most
48
+ * sentence-transformer / OpenAI-style embeddings that are already
49
+ * length-normalized.
50
+ * - `l2`: Euclidean distance. Use when your model outputs vectors
51
+ * trained for L2 (e.g. some image embedding models).
52
+ * - `inner_product`: dot-product distance. Use when your model outputs
53
+ * pre-normalized vectors AND you want to skip the cosine
54
+ * normalization step at query time.
55
+ */
56
+ type EmbeddingMetric = "cosine" | "l2" | "inner_product";
57
+ /**
58
+ * Vector index implementation. `hnsw` is the default and what pgvector
59
+ * recommends for most workloads. `ivfflat` is the alternative for
60
+ * larger datasets where memory is the bottleneck. `none` disables
61
+ * automatic index creation for this embedding (the operator can still
62
+ * call `backend.createVectorIndex` manually).
63
+ */
64
+ type EmbeddingIndexType = "hnsw" | "ivfflat" | "none";
65
+ /**
66
+ * Per-embedding configuration for the auto-derived
67
+ * `VectorIndexDeclaration`. All fields are optional with sensible
68
+ * defaults (`cosine` / `hnsw` / pgvector defaults: `m=16`,
69
+ * `ef_construction=64`). Override only when your model or dataset has
70
+ * a known reason to.
71
+ */
72
+ type EmbeddingIndexOptions = Readonly<{
73
+ /** Distance metric. Default `"cosine"`. */
74
+ metric?: EmbeddingMetric;
75
+ /** Vector index implementation. Default `"hnsw"`. */
76
+ indexType?: EmbeddingIndexType;
77
+ /** HNSW `m` parameter — max connections per layer. Default `16`. */
78
+ m?: number;
79
+ /** HNSW `ef_construction` parameter — build-time search depth. Default `64`. */
80
+ efConstruction?: number;
81
+ /** IVFFlat `lists` parameter — number of inverted-list partitions. */
82
+ lists?: number;
83
+ }>;
84
+ /**
85
+ * Resolved embedding index configuration with all defaults applied.
86
+ * What gets attached to the brand and read by the auto-derivation pass.
87
+ */
88
+ type ResolvedEmbeddingIndex = Readonly<{
89
+ metric: EmbeddingMetric;
90
+ indexType: EmbeddingIndexType;
91
+ m: number;
92
+ efConstruction: number;
93
+ lists: number | undefined;
94
+ }>;
34
95
  /**
35
96
  * A Zod schema for vector embeddings with attached dimension metadata.
36
97
  * Uses the branded EmbeddingValue type for type-level distinction.
37
98
  */
38
99
  type EmbeddingSchema<D extends number = number> = z.ZodType<EmbeddingValue> & Readonly<{
39
100
  [EMBEDDING_DIMENSIONS_KEY]: D;
101
+ [EMBEDDING_INDEX_KEY]: ResolvedEmbeddingIndex;
40
102
  }>;
41
103
  /**
42
104
  * Creates a Zod schema for vector embeddings.
@@ -74,7 +136,7 @@ type EmbeddingSchema<D extends number = number> = z.ZodType<EmbeddingValue> & Re
74
136
  * });
75
137
  * ```
76
138
  */
77
- declare function embedding<D extends number>(dimensions: D): EmbeddingSchema<D>;
139
+ declare function embedding<D extends number>(dimensions: D, options?: EmbeddingIndexOptions): EmbeddingSchema<D>;
78
140
  /**
79
141
  * Checks if a value is an embedding schema.
80
142
  */
@@ -367,6 +429,93 @@ declare function inSubquery(field: FieldRef, subquery: QueryAst): Predicate;
367
429
  */
368
430
  declare function notInSubquery(field: FieldRef, subquery: QueryAst): Predicate;
369
431
 
432
+ /**
433
+ * Dynamic query builder types.
434
+ *
435
+ * Backs `fromDynamic` / `traverseDynamic` / `optionalTraverseDynamic`
436
+ * / `toDynamic` — the string-keyed sibling methods on `QueryBuilder`
437
+ * and `TraversalBuilder` that admit runtime-declared kinds. Same SQL
438
+ * compiler under the hood; only the alias-level surface types differ.
439
+ *
440
+ * Aliases declared via the dynamic methods carry `DynamicNodeType` /
441
+ * `DynamicEdgeType` brands. `NodeAccessor<N>` / `EdgeAccessor<E>` /
442
+ * `SelectableNode<N>` / `SelectableEdge<E>` branch on those brands so a
443
+ * single query can mix typed and dynamic aliases — a typed alias keeps
444
+ * `StringFieldAccessor`, etc., while a dynamic alias gets
445
+ * `DynamicNodeAccessor` with a `.field(name)` discriminator.
446
+ */
447
+
448
+ declare const DYNAMIC_NODE_BRAND: unique symbol;
449
+ declare const DYNAMIC_EDGE_BRAND: unique symbol;
450
+ type DynamicNodeType = NodeType & Readonly<{
451
+ [DYNAMIC_NODE_BRAND]: true;
452
+ }>;
453
+ type DynamicEdgeType = AnyEdgeType & Readonly<{
454
+ [DYNAMIC_EDGE_BRAND]: true;
455
+ }>;
456
+ type IsDynamicNodeType<N> = N extends Readonly<{
457
+ [DYNAMIC_NODE_BRAND]: true;
458
+ }> ? true : false;
459
+ type IsDynamicEdgeType<E> = E extends Readonly<{
460
+ [DYNAMIC_EDGE_BRAND]: true;
461
+ }> ? true : false;
462
+ /**
463
+ * Type-discriminated field builder for runtime-typed properties.
464
+ *
465
+ * `BaseFieldAccessor` methods (`eq`, `isNull`, etc.) are available
466
+ * directly. Type-specific methods (`gte`, `contains`, `similarTo`, …)
467
+ * sit behind a discriminator method that asserts the field's type:
468
+ *
469
+ * ```ts
470
+ * (n) => n.field("year").number().gte(2020)
471
+ * ```
472
+ *
473
+ * The discriminator validates against the registered Zod schema at
474
+ * query-build time and throws `TypeError` on mismatch — the user can't
475
+ * accidentally call `.between(...)` on a string field. The discriminator
476
+ * is a type assertion *and* a runtime check.
477
+ */
478
+ type DynamicFieldBuilder = BaseFieldAccessor & Readonly<{
479
+ string: () => StringFieldAccessor;
480
+ number: () => NumberFieldAccessor;
481
+ date: () => DateFieldAccessor;
482
+ array: () => ArrayFieldAccessor<unknown>;
483
+ object: () => ObjectFieldAccessor<Readonly<Record<string, unknown>>>;
484
+ embedding: () => EmbeddingFieldAccessor;
485
+ }>;
486
+ /**
487
+ * Predicate accessor for a runtime-kind alias.
488
+ *
489
+ * System fields keep their narrow types. Schema properties are reached
490
+ * through `.field(name)` — `.field()` validates the property exists on
491
+ * the registered Zod schema and throws if it doesn't.
492
+ */
493
+ type DynamicNodeAccessor = Readonly<{
494
+ id: StringFieldAccessor;
495
+ kind: StringFieldAccessor;
496
+ $fulltext: FulltextAccessor;
497
+ field: (name: string) => DynamicFieldBuilder;
498
+ }>;
499
+ type DynamicEdgeAccessor = Readonly<{
500
+ id: StringFieldAccessor;
501
+ kind: StringFieldAccessor;
502
+ fromId: StringFieldAccessor;
503
+ toId: StringFieldAccessor;
504
+ field: (name: string) => DynamicFieldBuilder;
505
+ }>;
506
+ type DynamicSelectableNode = Readonly<{
507
+ id: string;
508
+ kind: string;
509
+ meta: SelectableNodeMeta;
510
+ }> & Readonly<Record<string, unknown>>;
511
+ type DynamicSelectableEdge = Readonly<{
512
+ id: string;
513
+ kind: string;
514
+ fromId: string;
515
+ toId: string;
516
+ meta: SelectableEdgeMeta;
517
+ }> & Readonly<Record<string, unknown>>;
518
+
370
519
  /**
371
520
  * Shared type definitions for the query builder.
372
521
  *
@@ -555,8 +704,12 @@ type ObjectFieldAccessor<T> = BaseFieldAccessor & Readonly<{
555
704
  * the node kind has no `searchable()` fields. Exposed at the type
556
705
  * level on every accessor so refinements like
557
706
  * `searchable().min(1)` do not make it disappear.
707
+ *
708
+ * For aliases declared via `fromDynamic` / `toDynamic`, `N` carries the
709
+ * dynamic brand and this resolves to `DynamicNodeAccessor` — schema
710
+ * properties go through a `.field(name)` discriminator.
558
711
  */
559
- type NodeAccessor<N extends NodeType> = Readonly<{
712
+ type NodeAccessor<N extends NodeType> = IsDynamicNodeType<N> extends true ? DynamicNodeAccessor : Readonly<{
560
713
  id: StringFieldAccessor;
561
714
  kind: StringFieldAccessor;
562
715
  $fulltext: FulltextAccessor;
@@ -573,8 +726,11 @@ type EdgePropsAccessor<E extends AnyEdgeType> = Readonly<{
573
726
  * Properties are available at the top level for ergonomic access:
574
727
  * - `e.role` instead of `e.props.role`
575
728
  * - System fields: `e.id`, `e.kind`, `e.fromId`, `e.toId`
729
+ *
730
+ * Dynamic-mode counterpart: see `NodeAccessor` for the brand-detection
731
+ * pattern.
576
732
  */
577
- type EdgeAccessor<E extends AnyEdgeType> = Readonly<{
733
+ type EdgeAccessor<E extends AnyEdgeType> = IsDynamicEdgeType<E> extends true ? DynamicEdgeAccessor : Readonly<{
578
734
  id: StringFieldAccessor;
579
735
  kind: StringFieldAccessor;
580
736
  fromId: StringFieldAccessor;
@@ -597,8 +753,12 @@ type SelectableNodeMeta = Readonly<{
597
753
  * Properties from the schema are spread at the top level for ergonomic access:
598
754
  * - `node.name` instead of `node.props.name`
599
755
  * - System metadata is under `node.meta.*`
756
+ *
757
+ * For aliases declared via `fromDynamic` / `toDynamic` this resolves to
758
+ * `DynamicSelectableNode` — same wire shape, schema properties typed
759
+ * `unknown` for narrowing at the call site.
600
760
  */
601
- type SelectableNode<N extends NodeType> = Readonly<{
761
+ type SelectableNode<N extends NodeType> = IsDynamicNodeType<N> extends true ? DynamicSelectableNode : Readonly<{
602
762
  id: string;
603
763
  kind: N["kind"];
604
764
  meta: SelectableNodeMeta;
@@ -619,8 +779,10 @@ type SelectableEdgeMeta = Readonly<{
619
779
  * Properties from the schema are spread at the top level for ergonomic access:
620
780
  * - `edge.role` instead of `edge.props.role`
621
781
  * - System metadata is under `edge.meta.*`
782
+ *
783
+ * Dynamic-mode counterpart: see `SelectableNode`.
622
784
  */
623
- type SelectableEdge<E extends AnyEdgeType = EdgeType> = Readonly<{
785
+ type SelectableEdge<E extends AnyEdgeType = EdgeType> = IsDynamicEdgeType<E> extends true ? DynamicSelectableEdge : Readonly<{
624
786
  id: string;
625
787
  kind: E["kind"];
626
788
  fromId: string;
@@ -727,6 +889,14 @@ type QueryBuilderState = Readonly<{
727
889
  groupBy: GroupBySpec | undefined;
728
890
  having: PredicateExpression | undefined;
729
891
  fusion: HybridFusionOptions | undefined;
892
+ /**
893
+ * Aliases declared via `fromDynamic` / `toDynamic`. The accessor
894
+ * factories check membership to decide between typed and dynamic
895
+ * predicate surfaces.
896
+ */
897
+ dynamicNodeAliases: ReadonlySet<string>;
898
+ /** Edge aliases declared via `traverseDynamic` / `optionalTraverseDynamic`. */
899
+ dynamicEdgeAliases: ReadonlySet<string>;
730
900
  }>;
731
901
  /**
732
902
  * Options for creating a query builder.
@@ -891,7 +1061,7 @@ type OperationHookContext = HookContext & Readonly<{
891
1061
  /** Operation type */
892
1062
  operation: "create" | "update" | "delete";
893
1063
  /** Entity type */
894
- entity: "node" | "edge";
1064
+ entity: KindEntity;
895
1065
  /** Kind of node or edge */
896
1066
  kind: string;
897
1067
  /** Entity ID */
@@ -952,6 +1122,35 @@ type StoreOptions = Readonly<{
952
1122
  traversalExpansion?: TraversalExpansion;
953
1123
  }>;
954
1124
  }>;
1125
+ /**
1126
+ * A mutable handle to the current `Store`, used by `store.evolve(...)`
1127
+ * so long-lived consumers can dereference through the ref and pick up
1128
+ * the new store after each evolve call. `current` is overwritten by
1129
+ * `evolve()` atomically with the schema commit when the ref is passed
1130
+ * via `evolve(extension, { ref })`.
1131
+ *
1132
+ * **Mid-request semantics.** `ref.current` flips on the *next* call
1133
+ * after evolve, not mid-handler. Dereference once at request entry and
1134
+ * reuse the captured `Store` for the duration:
1135
+ *
1136
+ * ```ts
1137
+ * async function handleRequest(): Promise<void> {
1138
+ * const store = ref.current; // capture once
1139
+ * const tag = await store.nodes.Tag?.create({ label: "..." });
1140
+ * // ...further work on the same `store`...
1141
+ * }
1142
+ * ```
1143
+ *
1144
+ * Pure dereferenceable handle — no event/subscription machinery. If
1145
+ * consumers need eventing, they wrap the ref themselves.
1146
+ *
1147
+ * Generic over the held value (typically `Store<G>`) so the store
1148
+ * module can refer to it without importing the `Store` class into
1149
+ * `types.ts`.
1150
+ */
1151
+ interface StoreRef<T> {
1152
+ current: T;
1153
+ }
955
1154
  /**
956
1155
  * Behavior when a get-or-create operation matches an existing record.
957
1156
  */
@@ -1662,6 +1861,33 @@ type SubgraphResult<G extends GraphDef, NK extends NodeKinds<G> = NodeKinds<G>,
1662
1861
  reverseAdjacency: ReadonlyMap<string, ReadonlyMap<EK, readonly SubgraphEdgeResult<G, EK, P>[]>>;
1663
1862
  }>;
1664
1863
 
1864
+ /**
1865
+ * Data-cleanup phase for `store.removeKinds()`.
1866
+ *
1867
+ * The removeKinds verb commits the new schema atomically (millisecond
1868
+ * budget); the data deletion happens here, scoped per-deployment via
1869
+ * the `typegraph_kind_removals` status table. Splitting the verbs
1870
+ * mirrors how `materializeIndexes` complements `evolve`: schema
1871
+ * commits are atomic and fast, data work is bounded by row count and
1872
+ * deferrable / parallelizable.
1873
+ */
1874
+
1875
+ type MaterializeRemovalsOptions = Readonly<{
1876
+ /** Restrict to specific kind names. */
1877
+ kinds?: readonly string[];
1878
+ /** Halt on first failure. Default: false (best-effort). */
1879
+ stopOnError?: boolean;
1880
+ }>;
1881
+ type MaterializeRemovalsEntry = Readonly<{
1882
+ kind: string;
1883
+ entity: KindEntity;
1884
+ status: "removed" | "failed";
1885
+ error?: Error;
1886
+ }>;
1887
+ type MaterializeRemovalsResult = Readonly<{
1888
+ results: readonly MaterializeRemovalsEntry[];
1889
+ }>;
1890
+
1665
1891
  /**
1666
1892
  * ExecutableAggregateQuery - A query with aggregate functions that can be executed.
1667
1893
  */
@@ -1990,6 +2216,15 @@ declare class ExecutableQuery<G extends GraphDef, Aliases extends AliasMap, Edge
1990
2216
  * TraversalBuilder - Intermediate builder for edge traversals.
1991
2217
  */
1992
2218
 
2219
+ /**
2220
+ * Resolves the edge type for an edge alias based on its kind type parameter.
2221
+ *
2222
+ * For `traverse(...)`, `EK` is a literal like `"authoredBy"` and the
2223
+ * type comes from the typed graph. For `traverseDynamic(...)`, `EK` is
2224
+ * widened to `string` — `string extends EK` distinguishes that case and
2225
+ * resolves to `DynamicEdgeType`, so the conditional accessor types fire.
2226
+ */
2227
+ type EdgeTypeForKey<G extends GraphDef, EK> = string extends EK ? DynamicEdgeType : EK extends keyof G["edges"] & string ? G["edges"][EK]["type"] : DynamicEdgeType;
1993
2228
  /**
1994
2229
  * State for variable-length traversal configuration.
1995
2230
  */
@@ -2028,7 +2263,7 @@ declare class TraversalBuilder<G extends GraphDef, Aliases extends AliasMap, Edg
2028
2263
  * @param alias - The edge alias to filter on (must be the current edge alias)
2029
2264
  * @param predicateFunction - A function that builds predicates using the edge accessor
2030
2265
  */
2031
- whereEdge(alias: EA, predicateFunction: (edge: EdgeAccessor<G["edges"][EK]["type"]>) => Predicate): TraversalBuilder<G, Aliases, EdgeAliases, EK, EA, Dir, Optional, DC, PC, RecAliases>;
2266
+ whereEdge(alias: EA, predicateFunction: (edge: EdgeAccessor<EdgeTypeForKey<G, EK>>) => Predicate): TraversalBuilder<G, Aliases, EdgeAliases, EK, EA, Dir, Optional, DC, PC, RecAliases>;
2032
2267
  /**
2033
2268
  * Specifies the target node kind.
2034
2269
  *
@@ -2045,6 +2280,13 @@ declare class TraversalBuilder<G extends GraphDef, Aliases extends AliasMap, Edg
2045
2280
  to<K extends ValidEdgeTargets<G, EK, Dir>, A extends string>(kind: K, alias: UniqueAlias<A, Aliases>, options: {
2046
2281
  includeSubClasses: true;
2047
2282
  }): QueryBuilder<G, Aliases & Record<A, NodeAlias<NodeType, Optional>>, EdgeAliases & Record<EA, EdgeAlias<G["edges"][EK]["type"], Optional>>, RecAliases & BuildRecursiveAliases<DC, PC, A>>;
2283
+ /**
2284
+ * String-keyed sibling of `to` for runtime-declared target kinds.
2285
+ * Throws `KindNotFoundError` if the kind is not registered.
2286
+ */
2287
+ toDynamic<A extends string>(kind: string, alias: UniqueAlias<A, Aliases>, options?: {
2288
+ includeSubClasses?: boolean;
2289
+ }): QueryBuilder<G, Aliases & Record<A, NodeAlias<DynamicNodeType, Optional>>, EdgeAliases & Record<EA, EdgeAlias<EdgeTypeForKey<G, EK>, Optional>>, RecAliases & BuildRecursiveAliases<DC, PC, A>>;
2048
2290
  }
2049
2291
 
2050
2292
  /**
@@ -2074,6 +2316,14 @@ declare class QueryBuilder<G extends GraphDef, Aliases extends AliasMap = {}, Ed
2074
2316
  from<K extends keyof G["nodes"] & string, A extends string>(kind: K, alias: UniqueAlias<A, Aliases>, options: {
2075
2317
  includeSubClasses: true;
2076
2318
  }): QueryBuilder<G, Aliases & Record<A, NodeAlias>, EdgeAliases, RecursiveAliases>;
2319
+ /**
2320
+ * String-keyed sibling of `from` for runtime-declared kinds. Throws
2321
+ * `KindNotFoundError` if the kind is not registered. Predicates use
2322
+ * the `n.field("name").number().gte(...)` discriminator.
2323
+ */
2324
+ fromDynamic<A extends string>(kind: string, alias: UniqueAlias<A, Aliases>, options?: {
2325
+ includeSubClasses?: boolean;
2326
+ }): QueryBuilder<G, Aliases & Record<A, NodeAlias<DynamicNodeType>>, EdgeAliases, RecursiveAliases>;
2077
2327
  /**
2078
2328
  * Adds a WHERE clause for a node.
2079
2329
  */
@@ -2114,6 +2364,15 @@ declare class QueryBuilder<G extends GraphDef, Aliases extends AliasMap = {}, Ed
2114
2364
  expand?: TraversalExpansion;
2115
2365
  from?: keyof Aliases & string;
2116
2366
  }): TraversalBuilder<G, Aliases, EdgeAliases, EK, EA, "in", false, false, false, RecursiveAliases>;
2367
+ /**
2368
+ * String-keyed sibling of `traverse` for runtime-declared edge kinds.
2369
+ * Throws `KindNotFoundError` if the edge kind is not registered.
2370
+ */
2371
+ traverseDynamic<EA extends string>(edgeKind: string, edgeAlias: EA, options?: {
2372
+ direction?: TraversalDirection$1;
2373
+ expand?: TraversalExpansion;
2374
+ from?: keyof Aliases & string;
2375
+ }): TraversalBuilder<G, Aliases, EdgeAliases & Record<EA, EdgeAlias<DynamicEdgeType>>, string, EA, TraversalDirection$1, false, false, false, RecursiveAliases>;
2117
2376
  /**
2118
2377
  * Optionally traverses an edge to another node (LEFT JOIN semantics).
2119
2378
  * If no matching edge/node exists, the result will include null values.
@@ -2135,6 +2394,17 @@ declare class QueryBuilder<G extends GraphDef, Aliases extends AliasMap = {}, Ed
2135
2394
  expand?: TraversalExpansion;
2136
2395
  from?: keyof Aliases & string;
2137
2396
  }): TraversalBuilder<G, Aliases, EdgeAliases, EK, EA, "in", true, false, false, RecursiveAliases>;
2397
+ /**
2398
+ * String-keyed sibling of `optionalTraverse` for runtime-declared edge
2399
+ * kinds. LEFT JOIN semantics — non-matching rows produce a null edge
2400
+ * alias instead of dropping. Throws `KindNotFoundError` if the edge
2401
+ * kind is not registered.
2402
+ */
2403
+ optionalTraverseDynamic<EA extends string>(edgeKind: string, edgeAlias: EA, options?: {
2404
+ direction?: TraversalDirection$1;
2405
+ expand?: TraversalExpansion;
2406
+ from?: keyof Aliases & string;
2407
+ }): TraversalBuilder<G, Aliases, EdgeAliases & Record<EA, EdgeAlias<DynamicEdgeType, true>>, string, EA, TraversalDirection$1, true, false, false, RecursiveAliases>;
2138
2408
  /**
2139
2409
  * Selects fields to return.
2140
2410
  */
@@ -2432,6 +2702,81 @@ type GraphAlgorithms<G extends GraphDef> = Readonly<{
2432
2702
  degree: (node: NodeIdentifier, options?: DegreeOptions<G>) => Promise<number>;
2433
2703
  }>;
2434
2704
 
2705
+ /**
2706
+ * `store.introspect()` — unified read of the merged schema.
2707
+ *
2708
+ * Returns a coherent snapshot of "what does my schema look like right
2709
+ * now" suitable for schema-management UIs, codegen, and IDE plugins.
2710
+ * The previous surface was fragmented across `registry.hasNodeType`,
2711
+ * `store.deprecatedKinds`, and direct graph poking; `introspect()`
2712
+ * unifies them with explicit `origin` markers distinguishing
2713
+ * compile-time from runtime declarations.
2714
+ *
2715
+ * Pure read — no I/O. Built from the in-memory `GraphDef` and the
2716
+ * persisted-but-already-merged `extension`. `schemaVersion` /
2717
+ * `schemaHash` are populated when the loader cached them at
2718
+ * construction time and `undefined` otherwise; consumers needing a
2719
+ * fresh read should call `backend.getActiveSchema(graphId)` directly.
2720
+ */
2721
+
2722
+ type SchemaIntrospection = Readonly<{
2723
+ graphId: string;
2724
+ /** Active schema version on the backend, when known to the caller. */
2725
+ schemaVersion: number | undefined;
2726
+ /** Hash of the active schema document, when known to the caller. */
2727
+ schemaHash: string | undefined;
2728
+ kinds: readonly KindIntrospection[];
2729
+ edges: readonly EdgeIntrospection[];
2730
+ ontology: readonly OntologyIntrospection[];
2731
+ deprecatedKinds: ReadonlySet<string>;
2732
+ /**
2733
+ * The persisted graph extension, or `undefined` when the store has
2734
+ * no extensions. Round-trips: passing this value to
2735
+ * `defineGraphExtension` and `evolve` against an empty graph yields
2736
+ * a graph with the same extension kinds.
2737
+ */
2738
+ extension: GraphExtension | undefined;
2739
+ }>;
2740
+ type KindIntrospection = Readonly<{
2741
+ name: string;
2742
+ origin: "compile-time" | "runtime";
2743
+ description: string | undefined;
2744
+ annotations: KindAnnotations | undefined;
2745
+ deprecated: boolean;
2746
+ /**
2747
+ * JSON-Schema view of the kind's properties. For extension kinds the
2748
+ * lower-level `ExtensionPropertyType` shape (with first-class
2749
+ * `searchable` / `embedding` modifiers) is reachable via
2750
+ * `introspection.extension.nodes[name].properties`.
2751
+ */
2752
+ properties: JsonSchema;
2753
+ unique: readonly UniqueIntrospection[];
2754
+ }>;
2755
+ type EdgeIntrospection = Readonly<{
2756
+ name: string;
2757
+ origin: "compile-time" | "runtime";
2758
+ description: string | undefined;
2759
+ from: readonly string[];
2760
+ to: readonly string[];
2761
+ cardinality: Cardinality;
2762
+ endpointExistence: EndpointExistence;
2763
+ properties: JsonSchema;
2764
+ annotations: KindAnnotations | undefined;
2765
+ deprecated: boolean;
2766
+ }>;
2767
+ type OntologyIntrospection = Readonly<{
2768
+ metaEdge: string;
2769
+ from: string;
2770
+ to: string;
2771
+ origin: "compile-time" | "runtime";
2772
+ }>;
2773
+ type UniqueIntrospection = Readonly<{
2774
+ name: string;
2775
+ fields: readonly string[];
2776
+ scope: UniquenessScope;
2777
+ collation: Collation;
2778
+ }>;
2779
+
2435
2780
  type RebuildFulltextOptions = Readonly<{
2436
2781
  /** Page size. Must be a positive integer. Default: 500. */
2437
2782
  pageSize?: number;
@@ -2540,6 +2885,23 @@ type HybridVectorOptions = Readonly<{
2540
2885
  /** Minimum similarity to include (units depend on metric). */
2541
2886
  minScore?: number;
2542
2887
  }>;
2888
+ /**
2889
+ * Options for the standalone `store.search.vector` path. Mirrors the
2890
+ * vector half of `HybridSearchOptions` but flattens it because the
2891
+ * standalone path doesn't fuse against fulltext.
2892
+ */
2893
+ type VectorSearchOptions = Readonly<{
2894
+ /** Field path of the embedding column on the node kind. */
2895
+ fieldPath: string;
2896
+ /** Query embedding to compare against. */
2897
+ queryEmbedding: readonly number[];
2898
+ /** Max results. Required. */
2899
+ limit: number;
2900
+ /** Distance metric. Default: "cosine". */
2901
+ metric?: VectorMetric;
2902
+ /** Minimum similarity to include (units depend on metric). */
2903
+ minScore?: number;
2904
+ }>;
2543
2905
  type HybridFulltextOptions = Readonly<{
2544
2906
  query: string;
2545
2907
  /** How many candidates to retrieve from the fulltext side. Default: 4 * limit. */
@@ -2560,17 +2922,27 @@ type HybridSearchOptions = Readonly<{
2560
2922
  /**
2561
2923
  * StoreSearch — store.search facade.
2562
2924
  *
2563
- * Groups fulltext, hybrid, and maintenance operations under one
2925
+ * Groups fulltext, vector, hybrid, and maintenance operations under one
2564
2926
  * 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.
2927
+ * traversal. The methods delegate to their respective execution
2928
+ * modules; this class exists to shape the surface and to gate kind
2929
+ * names through the registry — the kind argument is `string` so
2930
+ * graph-extension kinds (added via `store.evolve()`) work without a
2931
+ * type cast, with a runtime guard rejecting misspellings at the call
2932
+ * site.
2568
2933
  */
2569
2934
 
2570
2935
  /**
2571
- * Narrows `Node` to the concrete typed node for a given kind in the graph.
2936
+ * Resolves the hit's `node` type. Compile-time kinds keep their
2937
+ * narrowed `Node<N>`; kinds outside `G` (added via graph extension through
2938
+ * `store.evolve()`, or string variables the type system can't see)
2939
+ * widen to the base `Node` so callers don't need a cast.
2940
+ *
2941
+ * This is the same shape as `getNodeCollection` — the dynamic form
2942
+ * works for any registered kind, and the type narrows when (and only
2943
+ * when) the literal is statically known.
2572
2944
  */
2573
- type NodeOfKind<G extends GraphDef, K extends NodeKinds<G>> = G["nodes"][K] extends NodeRegistration<infer N extends NodeType> ? Node<N> : Node;
2945
+ type ResolveNode<G extends GraphDef, K extends string> = K extends NodeKinds<G> ? G["nodes"][K] extends NodeRegistration<infer N extends NodeType> ? Node<N> : Node : Node;
2574
2946
  type StoreSearchContext = Readonly<{
2575
2947
  graphId: string;
2576
2948
  backend: GraphBackend;
@@ -2588,6 +2960,14 @@ type StoreSearchContext = Readonly<{
2588
2960
  * includeSnippets: true,
2589
2961
  * });
2590
2962
  *
2963
+ * // Vector only — for extension kinds with embedding() modifiers,
2964
+ * // the auto-derived index serves this query.
2965
+ * const nearest = await store.search.vector("Document", {
2966
+ * fieldPath: "embedding",
2967
+ * queryEmbedding: vec,
2968
+ * limit: 10,
2969
+ * });
2970
+ *
2591
2971
  * // Hybrid: vector + fulltext, fused with RRF
2592
2972
  * const ranked = await store.search.hybrid("Document", {
2593
2973
  * limit: 10,
@@ -2598,6 +2978,10 @@ type StoreSearchContext = Readonly<{
2598
2978
  * // Rebuild after backfill / schema change
2599
2979
  * const stats = await store.search.rebuildFulltext();
2600
2980
  * ```
2981
+ *
2982
+ * Extension kinds added via `store.evolve(...)` work with all four
2983
+ * methods without a type cast — the kind argument is `string` and a
2984
+ * registry check rejects misspellings at the call site.
2601
2985
  */
2602
2986
  declare class StoreSearch<G extends GraphDef> {
2603
2987
  #private;
@@ -2611,7 +2995,19 @@ declare class StoreSearch<G extends GraphDef> {
2611
2995
  * configured with) and resolves the matching node IDs back to typed
2612
2996
  * `Node` objects.
2613
2997
  */
2614
- fulltext<K extends NodeKinds<G>>(nodeKind: K, options: FulltextSearchOptions): Promise<readonly FulltextSearchHit<NodeOfKind<G, K>>[]>;
2998
+ fulltext<K extends string>(nodeKind: K, options: FulltextSearchOptions): Promise<readonly FulltextSearchHit<ResolveNode<G, K>>[]>;
2999
+ /**
3000
+ * Runs a vector similarity search against nodes of the given kind.
3001
+ *
3002
+ * Requires a field on the node schema declared with `embedding()`,
3003
+ * either at compile time or via a graph extension (the auto-derived
3004
+ * `VectorIndexDeclaration` flows through `materializeIndexes()` on
3005
+ * the same path either way).
3006
+ *
3007
+ * Pure vector — no fulltext leg, no fusion. For combined
3008
+ * vector+fulltext ranking, use `hybrid`.
3009
+ */
3010
+ vector<K extends string>(nodeKind: K, options: VectorSearchOptions): Promise<readonly VectorSearchHit<ResolveNode<G, K>>[]>;
2615
3011
  /**
2616
3012
  * Runs a vector + fulltext hybrid search and fuses the results with
2617
3013
  * Reciprocal Rank Fusion.
@@ -2621,7 +3017,7 @@ declare class StoreSearch<G extends GraphDef> {
2621
3017
  * over-fetch is 4× `limit` from each source — tune via `vector.k` /
2622
3018
  * `fulltext.k` for higher-recall corpora.
2623
3019
  */
2624
- hybrid<K extends NodeKinds<G>>(nodeKind: K, options: HybridSearchOptions): Promise<readonly HybridSearchHit<NodeOfKind<G, K>>[]>;
3020
+ hybrid<K extends string>(nodeKind: K, options: HybridSearchOptions): Promise<readonly HybridSearchHit<ResolveNode<G, K>>[]>;
2625
3021
  /**
2626
3022
  * Rebuilds the fulltext index from existing node data.
2627
3023
  *
@@ -2640,7 +3036,7 @@ declare class StoreSearch<G extends GraphDef> {
2640
3036
  * be missed by a single pass — run during a maintenance window for
2641
3037
  * full consistency.
2642
3038
  */
2643
- rebuildFulltext<K extends NodeKinds<G>>(nodeKind?: K, options?: RebuildFulltextOptions): Promise<RebuildFulltextResult>;
3039
+ rebuildFulltext<K extends string>(nodeKind?: K, options?: RebuildFulltextOptions): Promise<RebuildFulltextResult>;
2644
3040
  }
2645
3041
 
2646
3042
  /**
@@ -2654,6 +3050,10 @@ declare class StoreSearch<G extends GraphDef> {
2654
3050
  * - Transaction handling
2655
3051
  */
2656
3052
 
3053
+ type StoreSchemaMetadata = Readonly<{
3054
+ schemaVersion: number | undefined;
3055
+ schemaHash: string | undefined;
3056
+ }>;
2657
3057
  /**
2658
3058
  * The Store provides typed access to a TypeGraph database.
2659
3059
  *
@@ -2689,7 +3089,7 @@ declare class StoreSearch<G extends GraphDef> {
2689
3089
  */
2690
3090
  declare class Store<G extends GraphDef> {
2691
3091
  #private;
2692
- constructor(graph: G, backend: GraphBackend, options?: StoreOptions);
3092
+ constructor(graph: G, backend: GraphBackend, options?: StoreOptions, schemaMetadata?: StoreSchemaMetadata);
2693
3093
  /** The graph definition */
2694
3094
  get graph(): G;
2695
3095
  /** The graph ID */
@@ -2758,17 +3158,74 @@ declare class Store<G extends GraphDef> {
2758
3158
  *
2759
3159
  * Use this for runtime string-keyed access when the kind is not known at
2760
3160
  * compile time (e.g., iterating all kinds, resolving from edge metadata,
2761
- * dynamic admin UIs).
3161
+ * dynamic admin UIs). For the post-evolve "I just added this kind, give
3162
+ * me the collection" pattern, prefer `getNodeCollectionOrThrow` — it
3163
+ * throws `KindNotFoundError` instead of forcing a null-check.
2762
3164
  */
2763
3165
  getNodeCollection(kind: string): DynamicNodeCollection | undefined;
3166
+ /**
3167
+ * Returns the node collection for the given kind. Throws
3168
+ * `KindNotFoundError` when the kind is not registered.
3169
+ *
3170
+ * The dominant graph-extension-kind access pattern: `await store.evolve(...)`
3171
+ * returns a new store, the caller immediately operates on the new
3172
+ * kind, and the null-check the optional variant requires is busywork.
3173
+ */
3174
+ getNodeCollectionOrThrow(kind: string): DynamicNodeCollection;
2764
3175
  /**
2765
3176
  * Returns the edge collection for the given kind, or undefined if the kind
2766
3177
  * is not registered in this graph.
2767
3178
  *
2768
3179
  * Use this for runtime string-keyed access when the kind is not known at
2769
- * compile time.
3180
+ * compile time. For post-evolve access, prefer `getEdgeCollectionOrThrow`.
2770
3181
  */
2771
3182
  getEdgeCollection(kind: string): DynamicEdgeCollection | undefined;
3183
+ /**
3184
+ * Returns the edge collection for the given kind. Throws
3185
+ * `KindNotFoundError` when the kind is not registered.
3186
+ */
3187
+ getEdgeCollectionOrThrow(kind: string): DynamicEdgeCollection;
3188
+ /**
3189
+ * Returns the Zod props schema for the given node kind, or `undefined`
3190
+ * if the kind is not registered. Identity-preserving: returns the
3191
+ * exact instance used by `.create()` / `.update()`, so a `parse()`
3192
+ * surfaces the same underlying Zod issues that `ValidationError`
3193
+ * wraps (operation-level checks like uniqueness and endpoints stay
3194
+ * in `collection.create`).
3195
+ */
3196
+ getNodePropsSchema(kind: string): z.ZodObject<z.ZodRawShape> | undefined;
3197
+ /**
3198
+ * Returns the Zod props schema for the given node kind. Throws
3199
+ * `KindNotFoundError` when the kind is not registered.
3200
+ */
3201
+ getNodePropsSchemaOrThrow(kind: string): z.ZodObject<z.ZodRawShape>;
3202
+ /**
3203
+ * Returns the Zod props schema for the given edge kind, or `undefined`
3204
+ * if the kind is not registered. Symmetric with `getNodePropsSchema`.
3205
+ */
3206
+ getEdgePropsSchema(kind: string): z.ZodObject<z.ZodRawShape> | undefined;
3207
+ /**
3208
+ * Returns the Zod props schema for the given edge kind. Throws
3209
+ * `KindNotFoundError` when the kind is not registered.
3210
+ */
3211
+ getEdgePropsSchemaOrThrow(kind: string): z.ZodObject<z.ZodRawShape>;
3212
+ /**
3213
+ * Returns a unified read of the merged schema — every compile-time
3214
+ * and graph-extension kind, every edge, every ontology relation,
3215
+ * with explicit `origin: "compile-time" | "runtime"` markers — plus
3216
+ * the persisted `extension` for round-tripping.
3217
+ *
3218
+ * Pure synchronous read built from the in-memory graph and the
3219
+ * already-merged graph-extension document. `schemaVersion` and `schemaHash`
3220
+ * are populated when the loader cached them at construction or after
3221
+ * `evolve` returns; consumers needing a fresh read should call
3222
+ * `backend.getActiveSchema(graphId)`.
3223
+ *
3224
+ * The return shape is the canonical schema-introspection surface:
3225
+ * the prior standalone `store.deprecatedKinds` accessor is replaced
3226
+ * by `introspect().deprecatedKinds`.
3227
+ */
3228
+ introspect(): SchemaIntrospection;
2772
3229
  /**
2773
3230
  * Creates a query builder for this store.
2774
3231
  *
@@ -2952,6 +3409,185 @@ declare class Store<G extends GraphDef> {
2952
3409
  * ```
2953
3410
  */
2954
3411
  refreshStatistics(): Promise<void>;
3412
+ /**
3413
+ * Evolves the graph at runtime by merging a graph extension into the
3414
+ * current schema, atomically committing a new schema version, and
3415
+ * returning a fresh `Store` constructed against the merged graph.
3416
+ *
3417
+ * The `Store` is immutable — its registry, collections, and operation
3418
+ * contexts close over the graph at construction time — so callers
3419
+ * must use the returned store (or pass a `ref` to be re-pointed) for
3420
+ * any work involving the new kinds.
3421
+ *
3422
+ * **Cost for purely additive extensions is proportional to schema
3423
+ * document size, not row count.** The commit is a single CAS write.
3424
+ * Tightening changes against existing graph-extension-declared kinds run
3425
+ * row-count probes for those affected kinds so populated kinds can
3426
+ * be rejected without a backfill.
3427
+ *
3428
+ * **Concurrent evolve recovery.** On `StaleVersionError`, refetch the
3429
+ * current active schema (or dereference your `StoreRef`),
3430
+ * reconstruct your `Store`, and re-call `evolve(extension)` against
3431
+ * the new store. Re-validation may now surface deterministic errors
3432
+ * (e.g., another caller just added a kind that collides with yours,
3433
+ * or redeclared one of yours with a different shape). Don't loop
3434
+ * blindly — surface the error.
3435
+ *
3436
+ * @param extension - Graph extension produced by
3437
+ * `defineGraphExtension(...)`.
3438
+ * @param options.ref - Optional handle whose `current` is overwritten
3439
+ * atomically with the schema commit. Long-lived consumers
3440
+ * (request handlers, background workers) that dereference through
3441
+ * the ref see the new kinds on the *next* call.
3442
+ *
3443
+ * @throws {GraphExtensionValidationError} when the extension is
3444
+ * structurally invalid.
3445
+ * @throws {KindCollisionError} when an extension kind shadows a
3446
+ * compile-time kind (code `KIND_COLLISION`).
3447
+ * @throws {IncompatibleChangeError} when a redeclared kind narrows
3448
+ * in a way the existing rows can't satisfy
3449
+ * (code `INCOMPATIBLE_CHANGE`).
3450
+ * @throws {GraphExtensionUnresolvedEndpointError} when an edge
3451
+ * endpoint references a kind that exists in neither the extension
3452
+ * nor the host graph
3453
+ * (code `GRAPH_EXTENSION_UNRESOLVED_ENDPOINT`).
3454
+ * @throws {StaleVersionError} when another writer has advanced the
3455
+ * schema since this store was constructed; recovery as above.
3456
+ * @throws {SchemaContentConflictError} when a row already exists at
3457
+ * the target version with a different content hash.
3458
+ */
3459
+ evolve(extension: GraphExtension, options?: Readonly<{
3460
+ ref?: StoreRef<Store<G>>;
3461
+ /**
3462
+ * When set, automatically run `materializeIndexes()` on the new
3463
+ * Store after the schema commit succeeds. Pass `{}` for default
3464
+ * behavior (all declared indexes, best-effort) or a populated
3465
+ * options object for finer control. Omit to defer materialization
3466
+ * to a later `materializeIndexes()` call.
3467
+ *
3468
+ * The schema-version write is NOT rolled back if materialization
3469
+ * produces failed entries — failure surfaces as
3470
+ * `EagerMaterializationError` thrown AFTER the new Store is
3471
+ * constructed and `ref.current` is updated, so the caller can
3472
+ * recover via the ref handle.
3473
+ */
3474
+ eager?: MaterializeIndexesOptions;
3475
+ }>): Promise<Store<G>>;
3476
+ /**
3477
+ * Marks the named node and edge kinds as soft-deprecated. Surfaces in
3478
+ * `store.introspect().deprecatedKinds` for introspection (codegen,
3479
+ * UI tooling, lints) but does not gate reads, writes, or queries —
3480
+ * deprecation is a signal, not a removal.
3481
+ *
3482
+ * Atomically commits a new schema version through the same primitive
3483
+ * `evolve()` uses, so concurrent deprecate/evolve calls produce
3484
+ * `StaleVersionError | SchemaContentConflictError` race losers that
3485
+ * the caller refetches and retries. Idempotent: re-deprecating a
3486
+ * kind that's already marked is a no-op (no version bump).
3487
+ *
3488
+ * @param names - Node or edge kind names to mark as deprecated.
3489
+ * @param options.ref - Optional handle to be re-pointed atomically
3490
+ * with the schema commit, mirroring `evolve()`.
3491
+ *
3492
+ * @throws {ConfigurationError} on `DEPRECATE_BEFORE_INITIALIZE` (no
3493
+ * schema yet) or `DEPRECATE_UNKNOWN_KIND` (name not on the graph).
3494
+ * @throws {StaleVersionError} when another writer has advanced the
3495
+ * schema since this store was constructed; refetch and retry per
3496
+ * the same recipe `evolve()` documents.
3497
+ * @throws {SchemaContentConflictError} when a row already exists at
3498
+ * the target version with a different content hash.
3499
+ */
3500
+ deprecateKinds(names: readonly string[], options?: Readonly<{
3501
+ ref?: StoreRef<Store<G>>;
3502
+ }>): Promise<Store<G>>;
3503
+ /**
3504
+ * Reverses `deprecateKinds(...)` for the named kinds. Same race +
3505
+ * idempotency semantics: removing a name that isn't currently
3506
+ * deprecated is a no-op for that name (the call as a whole is a
3507
+ * no-op only if every name was already absent).
3508
+ *
3509
+ * @param names - Node or edge kind names to remove from the
3510
+ * deprecated set.
3511
+ * @param options.ref - Optional handle to be re-pointed atomically
3512
+ * with the schema commit.
3513
+ *
3514
+ * @throws {ConfigurationError} on `DEPRECATE_BEFORE_INITIALIZE`.
3515
+ * @throws {StaleVersionError} on a CAS race with another writer.
3516
+ * @throws {SchemaContentConflictError} on a same-version content
3517
+ * conflict.
3518
+ */
3519
+ undeprecateKinds(names: readonly string[], options?: Readonly<{
3520
+ ref?: StoreRef<Store<G>>;
3521
+ }>): Promise<Store<G>>;
3522
+ /**
3523
+ * Runs `CREATE INDEX` DDL for the indexes declared on this graph and
3524
+ * records per-deployment status in `typegraph_index_materializations`.
3525
+ * The status table is per-database (two replicas of the same
3526
+ * `schema_doc` are still two different databases for DDL purposes),
3527
+ * so the same call against two replicas materializes independently.
3528
+ *
3529
+ * Idempotent. Re-running the verb against an already-materialized
3530
+ * index is a no-op (`status: "alreadyMaterialized"`). Postgres uses
3531
+ * `CREATE INDEX CONCURRENTLY` so live tables never take an
3532
+ * `AccessExclusiveLock`. SQLite is single-writer regardless.
3533
+ *
3534
+ * Best-effort by default: a failed index records `status: "failed"`
3535
+ * with the error and the loop continues. Pass `{ stopOnError: true }`
3536
+ * to halt on the first failure.
3537
+ *
3538
+ * @param options.kinds - Restrict to indexes whose `kind` is in this
3539
+ * set. Throws `ConfigurationError` (`code:
3540
+ * "MATERIALIZE_UNKNOWN_KIND"`) if any name doesn't match a known
3541
+ * compile-time or extension kind.
3542
+ * @param options.stopOnError - Halt on first failure. Default false.
3543
+ *
3544
+ * @throws {ConfigurationError} `MATERIALIZE_BACKEND_UNSUPPORTED` if
3545
+ * the backend lacks `executeDdl`, `getIndexMaterialization`, or
3546
+ * `recordIndexMaterialization`; `MATERIALIZE_UNKNOWN_KIND` for an
3547
+ * unknown kind name; `MATERIALIZE_BEFORE_INITIALIZE` if the store
3548
+ * has no schema yet.
3549
+ */
3550
+ materializeIndexes(options?: MaterializeIndexesOptions): Promise<MaterializeIndexesResult>;
3551
+ /**
3552
+ * Removes extension kinds from the schema with cascading edge and
3553
+ * ontology cleanup. Two-phase by design:
3554
+ *
3555
+ * 1. **Schema commit (this method).** Validates the removal,
3556
+ * rebuilds the persisted extension without the named kinds
3557
+ * (and without extension edges that lose their last endpoint),
3558
+ * CAS-commits the new schema version, and queues
3559
+ * per-deployment data-cleanup status. Millisecond budget.
3560
+ * 2. **Data cleanup (`materializeRemovals`).** Deletes the orphan
3561
+ * rows from the nodes/edges tables. Bounded by row count.
3562
+ *
3563
+ * Pass `{ eager: {} }` to run the data-cleanup pass inline with
3564
+ * default options, or `{ eager: { ... } }` to scope it; otherwise
3565
+ * call `materializeRemovals()` later.
3566
+ *
3567
+ * Idempotent: removing a name that doesn't exist is a no-op (no
3568
+ * version bump). Removing an extension kind referenced by a compile-
3569
+ * time edge or ontology relation throws `KindHasReferentsError`.
3570
+ * Removing a compile-time kind throws `RemoveCompileTimeKindError` —
3571
+ * compile-time kinds are removed by recompiling and redeploying.
3572
+ *
3573
+ * @throws {RemoveCompileTimeKindError} when `names` includes a
3574
+ * compile-time kind.
3575
+ * @throws {KindHasReferentsError} when an extension kind being
3576
+ * removed is referenced by a compile-time declaration.
3577
+ * @throws {StaleVersionError} on a CAS race with another writer.
3578
+ * @throws {SchemaContentConflictError} on a same-version content
3579
+ * conflict.
3580
+ */
3581
+ removeKinds(names: readonly string[], options?: Readonly<{
3582
+ ref?: StoreRef<Store<G>>;
3583
+ eager?: MaterializeRemovalsOptions;
3584
+ }>): Promise<Store<G>>;
3585
+ /**
3586
+ * Runs the data-cleanup phase for any kinds removed via
3587
+ * `removeKinds()` whose data has not yet been deleted on this
3588
+ * deployment. Safe to call repeatedly; idempotent.
3589
+ */
3590
+ materializeRemovals(options?: MaterializeRemovalsOptions): Promise<MaterializeRemovalsResult>;
2955
3591
  /**
2956
3592
  * Closes the store and releases underlying resources.
2957
3593
  *
@@ -3023,4 +3659,4 @@ declare function createStore<G extends GraphDef>(graph: G, backend: GraphBackend
3023
3659
  */
3024
3660
  declare function createStoreWithSchema<G extends GraphDef>(graph: G, backend: GraphBackend, options?: StoreOptions & SchemaManagerOptions): Promise<[Store<G>, SchemaValidationResult]>;
3025
3661
 
3026
- 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 };
3662
+ export { type MaterializeRemovalsOptions as $, type AliasMap as A, type BaseTraversalOptions as B, type CreateQueryBuilderOptions as C, DEFAULT_SEARCHABLE_LANGUAGE as D, type EdgeAliasMap as E, type EmbeddingSchema as F, type EmbeddingValue as G, ExecutableAggregateQuery as H, ExecutableQuery as I, type FieldAccessor as J, type FulltextSearchHit as K, type FulltextSearchOptions as L, type GetOrCreateAction as M, type GraphAlgorithms as N, type GraphEdgeCollections as O, type GraphNodeCollections as P, QueryBuilder as Q, type HookContext as R, Store as S, TraversalBuilder as T, type HybridFulltextOptions as U, type HybridSearchHit as V, type HybridSearchOptions as W, type HybridVectorOptions as X, type IfExistsMode as Y, type KindIntrospection as Z, type MaterializeRemovalsEntry as _, type AggregateResult as a, getSearchableMetadata as a$, type MaterializeRemovalsResult as a0, type NeighborsOptions as a1, type Node as a2, type NodeAccessor as a3, type NodeAlias as a4, type NodeCollection as a5, type NodeGetOrCreateByConstraintOptions as a6, type NodeGetOrCreateByConstraintResult as a7, type NodeIdentifier as a8, type NodeRef as a9, type StoreProjection as aA, type StoreRef as aB, StoreSearch as aC, type StreamOptions as aD, type SubgraphEdgeResult as aE, type SubgraphNodeResult as aF, type SubgraphOptions as aG, type SubgraphResult as aH, type SubsetEdge as aI, type SubsetNode as aJ, type TemporalAlgorithmOptions as aK, type TransactionContext as aL, type TraversalDirection as aM, type TypedEdgeCollection as aN, UnionableQuery as aO, type UniqueIntrospection as aP, type UpdateEdgeInput as aQ, type UpdateNodeInput as aR, type VectorSearchHit as aS, type VectorSearchOptions as aT, createStore as aU, createStoreWithSchema as aV, defineSubgraphProject as aW, embedding as aX, exists as aY, fieldRef as aZ, getEmbeddingDimensions as a_, type OntologyIntrospection as aa, type OperationHookContext as ab, type PaginateOptions as ac, type PaginatedResult as ad, type PathNode as ae, type Predicate as af, PreparedQuery as ag, type PropsAccessor as ah, type QueryHookContext as ai, type QueryOptions as aj, type ReachableNode as ak, type ReachableOptions as al, type RebuildFulltextOptions as am, type RebuildFulltextResult as an, type RecursiveTraversalOptions as ao, type SchemaIntrospection as ap, type SearchableMetadata as aq, type SearchableOptions as ar, type SearchableSchema as as, type SelectContext as at, type SelectableEdge as au, type SelectableNode as av, type ShortestPathOptions as aw, type ShortestPathResult as ax, type StoreHooks as ay, type StoreOptions as az, type AlgorithmCyclePolicy as b, inSubquery as b0, isEmbeddingSchema as b1, isParameterRef as b2, isSearchableSchema as b3, notExists as b4, notInSubquery as b5, param as b6, searchable as b7, 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 DynamicEdgeAccessor as k, type DynamicEdgeCollection as l, type DynamicEdgeType as m, type DynamicFieldBuilder as n, type DynamicNodeAccessor as o, type DynamicNodeCollection as p, type DynamicNodeType as q, type DynamicSelectableEdge as r, type DynamicSelectableNode as s, type Edge as t, type EdgeAccessor as u, type EdgeCollection as v, type EdgeFindByEndpointsOptions as w, type EdgeGetOrCreateByEndpointsOptions as x, type EdgeGetOrCreateByEndpointsResult as y, type EdgeIntrospection as z };