@nicia-ai/typegraph 0.40.0 → 0.41.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 (85) hide show
  1. package/dist/backend/drizzle/indexes.d.cts +1 -1
  2. package/dist/backend/drizzle/indexes.d.ts +1 -1
  3. package/dist/backend/index.d.cts +2 -2
  4. package/dist/backend/index.d.ts +2 -2
  5. package/dist/backend/postgres/index.d.cts +5 -5
  6. package/dist/backend/postgres/index.d.ts +5 -5
  7. package/dist/backend/postgres/pglite-store.cjs +3 -3
  8. package/dist/backend/postgres/pglite-store.d.cts +5 -5
  9. package/dist/backend/postgres/pglite-store.d.ts +5 -5
  10. package/dist/backend/postgres/pglite-store.js +2 -2
  11. package/dist/backend/postgres/pglite.d.cts +2 -2
  12. package/dist/backend/postgres/pglite.d.ts +2 -2
  13. package/dist/backend/sqlite/index.d.cts +5 -5
  14. package/dist/backend/sqlite/index.d.ts +5 -5
  15. package/dist/backend/sqlite/libsql.d.cts +2 -2
  16. package/dist/backend/sqlite/libsql.d.ts +2 -2
  17. package/dist/backend/sqlite/local-store.cjs +3 -3
  18. package/dist/backend/sqlite/local-store.d.cts +5 -5
  19. package/dist/backend/sqlite/local-store.d.ts +5 -5
  20. package/dist/backend/sqlite/local-store.js +2 -2
  21. package/dist/backend/sqlite/local.d.cts +2 -2
  22. package/dist/backend/sqlite/local.d.ts +2 -2
  23. package/dist/{chunk-K4FB2RMO.cjs → chunk-JP5EICR6.cjs} +7 -2
  24. package/dist/chunk-JP5EICR6.cjs.map +1 -0
  25. package/dist/chunk-KOI7UEI5.js +81 -0
  26. package/dist/chunk-KOI7UEI5.js.map +1 -0
  27. package/dist/{chunk-H6I36MGT.cjs → chunk-LOKG3KQV.cjs} +114 -37
  28. package/dist/chunk-LOKG3KQV.cjs.map +1 -0
  29. package/dist/{chunk-3BL3JFHL.js → chunk-MQBF3XGY.js} +82 -5
  30. package/dist/chunk-MQBF3XGY.js.map +1 -0
  31. package/dist/chunk-QCKD3RCI.cjs +83 -0
  32. package/dist/chunk-QCKD3RCI.cjs.map +1 -0
  33. package/dist/{chunk-CU3LPYNB.js → chunk-V3S74J44.js} +7 -3
  34. package/dist/chunk-V3S74J44.js.map +1 -0
  35. package/dist/core/index.d.cts +3 -3
  36. package/dist/core/index.d.ts +3 -3
  37. package/dist/{ddl-KnCdF_le.d.cts → ddl-BCXFRLWg.d.cts} +3 -3
  38. package/dist/{ddl-BLEzHw6j.d.ts → ddl-ByLmGgn9.d.ts} +3 -3
  39. package/dist/{define-graph-DQnj3fNH.d.ts → define-graph-BSviZubs.d.ts} +1 -1
  40. package/dist/{define-graph-Cv3CFwKm.d.cts → define-graph-XyJheaFm.d.cts} +1 -1
  41. package/dist/graph-merge/index.cjs +5 -5
  42. package/dist/graph-merge/index.d.cts +5 -5
  43. package/dist/graph-merge/index.d.ts +5 -5
  44. package/dist/graph-merge/index.js +2 -2
  45. package/dist/index.cjs +58 -53
  46. package/dist/index.cjs.map +1 -1
  47. package/dist/index.d.cts +10 -10
  48. package/dist/index.d.ts +10 -10
  49. package/dist/index.js +3 -2
  50. package/dist/index.js.map +1 -1
  51. package/dist/indexes/index.d.cts +4 -4
  52. package/dist/indexes/index.d.ts +4 -4
  53. package/dist/interchange/index.d.cts +5 -5
  54. package/dist/interchange/index.d.ts +5 -5
  55. package/dist/{manager-DjE6Mhag.d.ts → manager-C7iC5bk_.d.ts} +27 -3
  56. package/dist/{manager-mqee5MVB.d.cts → manager-Dm6MCYO7.d.cts} +27 -3
  57. package/dist/{postgres-Bm4DyFQU.d.cts → postgres-Cb6ceh4-.d.ts} +1 -1
  58. package/dist/{postgres-DtaVALOZ.d.ts → postgres-DZxwzCQ8.d.cts} +1 -1
  59. package/dist/profiler/index.d.cts +7 -7
  60. package/dist/profiler/index.d.ts +7 -7
  61. package/dist/provenance/index.d.cts +5 -5
  62. package/dist/provenance/index.d.ts +5 -5
  63. package/dist/schema/index.cjs +29 -95
  64. package/dist/schema/index.cjs.map +1 -1
  65. package/dist/schema/index.d.cts +55 -55
  66. package/dist/schema/index.d.ts +55 -55
  67. package/dist/schema/index.js +2 -80
  68. package/dist/schema/index.js.map +1 -1
  69. package/dist/{searchable-ChJ29MCd.d.ts → searchable-Cet4Oztt.d.ts} +2 -2
  70. package/dist/{searchable-BxlJQVFw.d.cts → searchable-aUaKh3_r.d.cts} +2 -2
  71. package/dist/{sqlite-m9Izphk_.d.ts → sqlite-Cb3Ilj9_.d.ts} +1 -1
  72. package/dist/{sqlite-DT6tTHOG.d.cts → sqlite-Dxklpizv.d.cts} +1 -1
  73. package/dist/{store-view-CagdeyNn.d.ts → store-view-BDjGFjpN.d.ts} +64 -13
  74. package/dist/{store-view-C-buB8Q8.d.cts → store-view-PCT7vTKH.d.cts} +64 -13
  75. package/dist/{types-CYdXzZef.d.ts → types-CFZiEEPh.d.ts} +1 -1
  76. package/dist/{types-CqSfMRW3.d.cts → types-CsaG00wS.d.cts} +1 -1
  77. package/dist/{types-D8szWDUo.d.ts → types-D-vOo_pM.d.ts} +1 -1
  78. package/dist/{types-C5pZeKTl.d.cts → types-ho4DJJb_.d.cts} +1 -1
  79. package/dist/{where-sQL4u5h-.d.ts → where-DLYaXa4L.d.ts} +1 -1
  80. package/dist/{where-C3-HRgUq.d.cts → where-udes1WRA.d.cts} +1 -1
  81. package/package.json +1 -1
  82. package/dist/chunk-3BL3JFHL.js.map +0 -1
  83. package/dist/chunk-CU3LPYNB.js.map +0 -1
  84. package/dist/chunk-H6I36MGT.cjs.map +0 -1
  85. package/dist/chunk-K4FB2RMO.cjs.map +0 -1
@@ -1,10 +1,10 @@
1
1
  import { z } from 'zod';
2
2
  import { l as KindAnnotations, a as NodeType, d as EdgeType } from '../extension-types-BLEVH4SG.cjs';
3
3
  export { A as AnyEdgeType, e as Cardinality, f as Collation, D as DeleteBehavior, g as EdgeId, h as EdgeProps, E as EdgeRegistration, i as EdgeTypeWithEndpoints, j as EndpointExistence, b as GraphDefaults, I as IndexEntity, J as JsonValue, K as KindEntity, m as NodeId, n as NodeProps, N as NodeRegistration, c as NullCheckOp, T as TemporalMode, U as UniqueConstraint, o as UniquenessScope, p as asEdgeId, q as asNodeId, r as isEdgeType, s as isEdgeTypeWithEndpoints, t as isNodeType } from '../extension-types-BLEVH4SG.cjs';
4
- import { D as InferenceType, at as MetaEdge } from '../types-C5pZeKTl.cjs';
5
- export { D as DEFAULT_SEARCHABLE_LANGUAGE, b as EmbeddingSchema, c as EmbeddingValue, S as SearchableMetadata, d as SearchableOptions, e as SearchableSchema, f as embedding, g as getEmbeddingDimensions, h as getSearchableMetadata, i as isEmbeddingSchema, j as isSearchableSchema, r as resolveGraphVectorSlots, s as searchable } from '../searchable-BxlJQVFw.cjs';
4
+ import { D as InferenceType, at as MetaEdge } from '../types-ho4DJJb_.cjs';
5
+ export { D as DEFAULT_SEARCHABLE_LANGUAGE, b as EmbeddingSchema, c as EmbeddingValue, S as SearchableMetadata, d as SearchableOptions, e as SearchableSchema, f as embedding, g as getEmbeddingDimensions, h as getSearchableMetadata, i as isEmbeddingSchema, j as isSearchableSchema, r as resolveGraphVectorSlots, s as searchable } from '../searchable-aUaKh3_r.cjs';
6
6
  export { R as RecordedInstant, a as asRecordedInstant, c as compareRecordedInstants, r as recordedInstantRevision, b as recordedInstantWallTime } from '../temporal-Dn_JADWY.cjs';
7
- export { A as AllEdgeTypes, a as AllNodeTypes, E as EdgeKinds, b as GetEdgeType, c as GetNodeType, G as GraphDef, N as NodeKinds, d as defineGraph, g as getEdgeKinds, e as getNodeKinds, i as isGraphDef } from '../define-graph-Cv3CFwKm.cjs';
7
+ export { A as AllEdgeTypes, a as AllNodeTypes, E as EdgeKinds, b as GetEdgeType, c as GetNodeType, G as GraphDef, N as NodeKinds, d as defineGraph, g as getEdgeKinds, e as getNodeKinds, i as isGraphDef } from '../define-graph-XyJheaFm.cjs';
8
8
 
9
9
  /**
10
10
  * Options for defining a node type.
@@ -1,10 +1,10 @@
1
1
  import { z } from 'zod';
2
2
  import { l as KindAnnotations, a as NodeType, d as EdgeType } from '../extension-types-BLEVH4SG.js';
3
3
  export { A as AnyEdgeType, e as Cardinality, f as Collation, D as DeleteBehavior, g as EdgeId, h as EdgeProps, E as EdgeRegistration, i as EdgeTypeWithEndpoints, j as EndpointExistence, b as GraphDefaults, I as IndexEntity, J as JsonValue, K as KindEntity, m as NodeId, n as NodeProps, N as NodeRegistration, c as NullCheckOp, T as TemporalMode, U as UniqueConstraint, o as UniquenessScope, p as asEdgeId, q as asNodeId, r as isEdgeType, s as isEdgeTypeWithEndpoints, t as isNodeType } from '../extension-types-BLEVH4SG.js';
4
- import { D as InferenceType, at as MetaEdge } from '../types-D8szWDUo.js';
5
- export { D as DEFAULT_SEARCHABLE_LANGUAGE, b as EmbeddingSchema, c as EmbeddingValue, S as SearchableMetadata, d as SearchableOptions, e as SearchableSchema, f as embedding, g as getEmbeddingDimensions, h as getSearchableMetadata, i as isEmbeddingSchema, j as isSearchableSchema, r as resolveGraphVectorSlots, s as searchable } from '../searchable-ChJ29MCd.js';
4
+ import { D as InferenceType, at as MetaEdge } from '../types-D-vOo_pM.js';
5
+ export { D as DEFAULT_SEARCHABLE_LANGUAGE, b as EmbeddingSchema, c as EmbeddingValue, S as SearchableMetadata, d as SearchableOptions, e as SearchableSchema, f as embedding, g as getEmbeddingDimensions, h as getSearchableMetadata, i as isEmbeddingSchema, j as isSearchableSchema, r as resolveGraphVectorSlots, s as searchable } from '../searchable-Cet4Oztt.js';
6
6
  export { R as RecordedInstant, a as asRecordedInstant, c as compareRecordedInstants, r as recordedInstantRevision, b as recordedInstantWallTime } from '../temporal-CyFsSPe8.js';
7
- export { A as AllEdgeTypes, a as AllNodeTypes, E as EdgeKinds, b as GetEdgeType, c as GetNodeType, G as GraphDef, N as NodeKinds, d as defineGraph, g as getEdgeKinds, e as getNodeKinds, i as isGraphDef } from '../define-graph-DQnj3fNH.js';
7
+ export { A as AllEdgeTypes, a as AllNodeTypes, E as EdgeKinds, b as GetEdgeType, c as GetNodeType, G as GraphDef, N as NodeKinds, d as defineGraph, g as getEdgeKinds, e as getNodeKinds, i as isGraphDef } from '../define-graph-BSviZubs.js';
8
8
 
9
9
  /**
10
10
  * Options for defining a node type.
@@ -1,6 +1,6 @@
1
- import { F as FulltextStrategy } from './types-C5pZeKTl.cjs';
2
- import { P as PostgresTables } from './postgres-Bm4DyFQU.cjs';
3
- import { S as SqliteTables } from './sqlite-DT6tTHOG.cjs';
1
+ import { F as FulltextStrategy } from './types-ho4DJJb_.cjs';
2
+ import { P as PostgresTables } from './postgres-DZxwzCQ8.cjs';
3
+ import { S as SqliteTables } from './sqlite-Dxklpizv.cjs';
4
4
 
5
5
  /**
6
6
  * Generates all DDL statements for the given SQLite tables.
@@ -1,6 +1,6 @@
1
- import { F as FulltextStrategy } from './types-D8szWDUo.js';
2
- import { P as PostgresTables } from './postgres-DtaVALOZ.js';
3
- import { S as SqliteTables } from './sqlite-m9Izphk_.js';
1
+ import { F as FulltextStrategy } from './types-D-vOo_pM.js';
2
+ import { P as PostgresTables } from './postgres-Cb6ceh4-.js';
3
+ import { S as SqliteTables } from './sqlite-Cb3Ilj9_.js';
4
4
 
5
5
  /**
6
6
  * Generates all DDL statements for the given SQLite tables.
@@ -1,5 +1,5 @@
1
1
  import { N as NodeRegistration, E as EdgeRegistration, D as DeleteBehavior, T as TemporalMode, G as GraphExtension, a as NodeType, A as AnyEdgeType, b as GraphDefaults } from './extension-types-BLEVH4SG.js';
2
- import { O as OntologyRelation, I as IndexDeclaration } from './types-D8szWDUo.js';
2
+ import { O as OntologyRelation, I as IndexDeclaration } from './types-D-vOo_pM.js';
3
3
 
4
4
  /** Brand key for GraphDef */
5
5
  declare const GRAPH_DEF_BRAND: "__graphDef";
@@ -1,5 +1,5 @@
1
1
  import { N as NodeRegistration, E as EdgeRegistration, D as DeleteBehavior, T as TemporalMode, G as GraphExtension, a as NodeType, A as AnyEdgeType, b as GraphDefaults } from './extension-types-BLEVH4SG.cjs';
2
- import { O as OntologyRelation, I as IndexDeclaration } from './types-C5pZeKTl.cjs';
2
+ import { O as OntologyRelation, I as IndexDeclaration } from './types-ho4DJJb_.cjs';
3
3
 
4
4
  /** Brand key for GraphDef */
5
5
  declare const GRAPH_DEF_BRAND: "__graphDef";
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkH6I36MGT_cjs = require('../chunk-H6I36MGT.cjs');
3
+ var chunkLOKG3KQV_cjs = require('../chunk-LOKG3KQV.cjs');
4
4
  var chunkTRF4EBJT_cjs = require('../chunk-TRF4EBJT.cjs');
5
5
  require('../chunk-7UTUKH4E.cjs');
6
6
  var chunkKHNKYSGP_cjs = require('../chunk-KHNKYSGP.cjs');
@@ -10,7 +10,7 @@ require('../chunk-ZDH3DX3C.cjs');
10
10
  require('../chunk-JZYMOHHM.cjs');
11
11
  require('../chunk-QYDUCWD2.cjs');
12
12
  require('../chunk-LL5D5T5W.cjs');
13
- var chunkK4FB2RMO_cjs = require('../chunk-K4FB2RMO.cjs');
13
+ var chunkJP5EICR6_cjs = require('../chunk-JP5EICR6.cjs');
14
14
  var chunkRW24SAHI_cjs = require('../chunk-RW24SAHI.cjs');
15
15
  require('../chunk-X4PVHAZ6.cjs');
16
16
  var chunkACSVZPK7_cjs = require('../chunk-ACSVZPK7.cjs');
@@ -371,7 +371,7 @@ async function computeSchemaComponent(store) {
371
371
  chunkUCHW2MGP_cjs.storeBackend(store),
372
372
  store.graphId
373
373
  );
374
- return chunkK4FB2RMO_cjs.computeSchemaHash(chunkK4FB2RMO_cjs.serializeSchema(store.graph, version));
374
+ return chunkJP5EICR6_cjs.computeSchemaHash(chunkJP5EICR6_cjs.serializeSchema(store.graph, version));
375
375
  }
376
376
  function byDigestEntry(left, right) {
377
377
  const byKind = chunkTRF4EBJT_cjs.compareStrings(left.kind, right.kind);
@@ -542,7 +542,7 @@ function cloneWorkingCopyStrategy(makeBackend) {
542
542
  create: async (baseStore) => {
543
543
  const backend = await makeBackend();
544
544
  try {
545
- const [freshStore] = await chunkH6I36MGT_cjs.createStoreWithSchema(
545
+ const [freshStore] = await chunkLOKG3KQV_cjs.createStoreWithSchema(
546
546
  baseStore.graph,
547
547
  backend,
548
548
  {
@@ -2192,7 +2192,7 @@ function buildProvenanceGraph(targetGraphId) {
2192
2192
  }
2193
2193
  async function openProvenanceStore(...args) {
2194
2194
  const [backend, targetGraphId] = args.length === 1 ? [chunkUCHW2MGP_cjs.storeBackend(args[0]), args[0].graphId] : args;
2195
- const [store] = await chunkH6I36MGT_cjs.createStoreWithSchema(
2195
+ const [store] = await chunkLOKG3KQV_cjs.createStoreWithSchema(
2196
2196
  buildProvenanceGraph(targetGraphId),
2197
2197
  backend
2198
2198
  );
@@ -1,14 +1,14 @@
1
- import { G as GraphDef, N as NodeKinds, c as GetNodeType } from '../define-graph-Cv3CFwKm.cjs';
2
- import { a as Store, ar as Node, bQ as UniqueIntrospection } from '../store-view-C-buB8Q8.cjs';
1
+ import { G as GraphDef, N as NodeKinds, c as GetNodeType } from '../define-graph-XyJheaFm.cjs';
2
+ import { a as Store, ar as Node, bR as UniqueIntrospection } from '../store-view-PCT7vTKH.cjs';
3
3
  import { m as NodeId, a as NodeType, g as EdgeId, J as JsonValue, l as KindAnnotations, d as EdgeType, D as DeleteBehavior, T as TemporalMode, k as GraphExtensionVersion, u as ExtensionNodeDef, v as ExtensionEdgeDef, w as ExtensionOntologyRelation, x as ExtensionIndex } from '../extension-types-BLEVH4SG.cjs';
4
4
  import { $ as TypeGraphError } from '../index-BihFPsPu.cjs';
5
5
  import { R as Result } from '../result-DWo6mUVz.cjs';
6
6
  export { i as isErr, a as isOk, u as unwrap } from '../result-DWo6mUVz.cjs';
7
- import { G as GraphBackend, at as MetaEdge, I as IndexDeclaration } from '../types-C5pZeKTl.cjs';
7
+ import { G as GraphBackend, at as MetaEdge, I as IndexDeclaration } from '../types-ho4DJJb_.cjs';
8
8
  import { z } from 'zod';
9
9
  import '../temporal-Dn_JADWY.cjs';
10
- import '../manager-mqee5MVB.cjs';
11
- import '../searchable-BxlJQVFw.cjs';
10
+ import '../manager-Dm6MCYO7.cjs';
11
+ import '../searchable-aUaKh3_r.cjs';
12
12
  import '../materialize-indexes-ExQ6OrAh.cjs';
13
13
 
14
14
  /**
@@ -1,14 +1,14 @@
1
- import { G as GraphDef, N as NodeKinds, c as GetNodeType } from '../define-graph-DQnj3fNH.js';
2
- import { a as Store, ar as Node, bQ as UniqueIntrospection } from '../store-view-CagdeyNn.js';
1
+ import { G as GraphDef, N as NodeKinds, c as GetNodeType } from '../define-graph-BSviZubs.js';
2
+ import { a as Store, ar as Node, bR as UniqueIntrospection } from '../store-view-BDjGFjpN.js';
3
3
  import { m as NodeId, a as NodeType, g as EdgeId, J as JsonValue, l as KindAnnotations, d as EdgeType, D as DeleteBehavior, T as TemporalMode, k as GraphExtensionVersion, u as ExtensionNodeDef, v as ExtensionEdgeDef, w as ExtensionOntologyRelation, x as ExtensionIndex } from '../extension-types-BLEVH4SG.js';
4
4
  import { $ as TypeGraphError } from '../index-BD_3TCgh.js';
5
5
  import { R as Result } from '../result-DWo6mUVz.js';
6
6
  export { i as isErr, a as isOk, u as unwrap } from '../result-DWo6mUVz.js';
7
- import { G as GraphBackend, at as MetaEdge, I as IndexDeclaration } from '../types-D8szWDUo.js';
7
+ import { G as GraphBackend, at as MetaEdge, I as IndexDeclaration } from '../types-D-vOo_pM.js';
8
8
  import { z } from 'zod';
9
9
  import '../temporal-CyFsSPe8.js';
10
- import '../manager-DjE6Mhag.js';
11
- import '../searchable-ChJ29MCd.js';
10
+ import '../manager-C7iC5bk_.js';
11
+ import '../searchable-Cet4Oztt.js';
12
12
  import '../materialize-indexes-D4iei4Kp.js';
13
13
 
14
14
  /**
@@ -1,4 +1,4 @@
1
- import { createStoreWithSchema } from '../chunk-3BL3JFHL.js';
1
+ import { createStoreWithSchema } from '../chunk-MQBF3XGY.js';
2
2
  import { compareStrings } from '../chunk-DRACN6XG.js';
3
3
  import '../chunk-L3DDZUZP.js';
4
4
  import { importGraphStream, exportGraphStream } from '../chunk-XMEYZYGE.js';
@@ -8,7 +8,7 @@ import '../chunk-35S6P5ZU.js';
8
8
  import '../chunk-YYLMXERH.js';
9
9
  import '../chunk-L5ET7FYQ.js';
10
10
  import '../chunk-QOHTVDHU.js';
11
- import { computeSchemaHash, serializeSchema } from '../chunk-CU3LPYNB.js';
11
+ import { computeSchemaHash, serializeSchema } from '../chunk-V3S74J44.js';
12
12
  import { defineNode } from '../chunk-76HE7DJP.js';
13
13
  import '../chunk-ZE6NVENI.js';
14
14
  import { sortedReplacer } from '../chunk-UR7W5YQK.js';
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkH6I36MGT_cjs = require('./chunk-H6I36MGT.cjs');
3
+ var chunkLOKG3KQV_cjs = require('./chunk-LOKG3KQV.cjs');
4
4
  require('./chunk-TRF4EBJT.cjs');
5
5
  var chunkHQRZEYYB_cjs = require('./chunk-HQRZEYYB.cjs');
6
6
  var chunk2J5NMMVR_cjs = require('./chunk-2J5NMMVR.cjs');
@@ -17,7 +17,8 @@ require('./chunk-ZDH3DX3C.cjs');
17
17
  var chunkJZYMOHHM_cjs = require('./chunk-JZYMOHHM.cjs');
18
18
  var chunkQYDUCWD2_cjs = require('./chunk-QYDUCWD2.cjs');
19
19
  var chunkLL5D5T5W_cjs = require('./chunk-LL5D5T5W.cjs');
20
- var chunkK4FB2RMO_cjs = require('./chunk-K4FB2RMO.cjs');
20
+ require('./chunk-QCKD3RCI.cjs');
21
+ var chunkJP5EICR6_cjs = require('./chunk-JP5EICR6.cjs');
21
22
  var chunkRW24SAHI_cjs = require('./chunk-RW24SAHI.cjs');
22
23
  require('./chunk-X4PVHAZ6.cjs');
23
24
  require('./chunk-ACSVZPK7.cjs');
@@ -240,155 +241,155 @@ function decodeEmbeddingJson(row) {
240
241
 
241
242
  Object.defineProperty(exports, "ExecutableAggregateQuery", {
242
243
  enumerable: true,
243
- get: function () { return chunkH6I36MGT_cjs.ExecutableAggregateQuery; }
244
+ get: function () { return chunkLOKG3KQV_cjs.ExecutableAggregateQuery; }
244
245
  });
245
246
  Object.defineProperty(exports, "ExecutableQuery", {
246
247
  enumerable: true,
247
- get: function () { return chunkH6I36MGT_cjs.ExecutableQuery; }
248
+ get: function () { return chunkLOKG3KQV_cjs.ExecutableQuery; }
248
249
  });
249
250
  Object.defineProperty(exports, "MAX_EXPLICIT_RECURSIVE_DEPTH", {
250
251
  enumerable: true,
251
- get: function () { return chunkH6I36MGT_cjs.MAX_EXPLICIT_RECURSIVE_DEPTH; }
252
+ get: function () { return chunkLOKG3KQV_cjs.MAX_EXPLICIT_RECURSIVE_DEPTH; }
252
253
  });
253
254
  Object.defineProperty(exports, "MAX_RECURSIVE_DEPTH", {
254
255
  enumerable: true,
255
- get: function () { return chunkH6I36MGT_cjs.MAX_RECURSIVE_DEPTH; }
256
+ get: function () { return chunkLOKG3KQV_cjs.MAX_RECURSIVE_DEPTH; }
256
257
  });
257
258
  Object.defineProperty(exports, "PreparedQuery", {
258
259
  enumerable: true,
259
- get: function () { return chunkH6I36MGT_cjs.PreparedQuery; }
260
+ get: function () { return chunkLOKG3KQV_cjs.PreparedQuery; }
260
261
  });
261
262
  Object.defineProperty(exports, "QueryBuilder", {
262
263
  enumerable: true,
263
- get: function () { return chunkH6I36MGT_cjs.QueryBuilder; }
264
+ get: function () { return chunkLOKG3KQV_cjs.QueryBuilder; }
264
265
  });
265
266
  Object.defineProperty(exports, "RecordedStoreView", {
266
267
  enumerable: true,
267
- get: function () { return chunkH6I36MGT_cjs.RecordedStoreView; }
268
+ get: function () { return chunkLOKG3KQV_cjs.RecordedStoreView; }
268
269
  });
269
270
  Object.defineProperty(exports, "StoreSearch", {
270
271
  enumerable: true,
271
- get: function () { return chunkH6I36MGT_cjs.StoreSearch; }
272
+ get: function () { return chunkLOKG3KQV_cjs.StoreSearch; }
272
273
  });
273
274
  Object.defineProperty(exports, "StoreView", {
274
275
  enumerable: true,
275
- get: function () { return chunkH6I36MGT_cjs.StoreView; }
276
+ get: function () { return chunkLOKG3KQV_cjs.StoreView; }
276
277
  });
277
278
  Object.defineProperty(exports, "UnionableQuery", {
278
279
  enumerable: true,
279
- get: function () { return chunkH6I36MGT_cjs.UnionableQuery; }
280
+ get: function () { return chunkLOKG3KQV_cjs.UnionableQuery; }
280
281
  });
281
282
  Object.defineProperty(exports, "avg", {
282
283
  enumerable: true,
283
- get: function () { return chunkH6I36MGT_cjs.avg; }
284
+ get: function () { return chunkLOKG3KQV_cjs.avg; }
284
285
  });
285
286
  Object.defineProperty(exports, "composeFragments", {
286
287
  enumerable: true,
287
- get: function () { return chunkH6I36MGT_cjs.composeFragments; }
288
+ get: function () { return chunkLOKG3KQV_cjs.composeFragments; }
288
289
  });
289
290
  Object.defineProperty(exports, "count", {
290
291
  enumerable: true,
291
- get: function () { return chunkH6I36MGT_cjs.count; }
292
+ get: function () { return chunkLOKG3KQV_cjs.count; }
292
293
  });
293
294
  Object.defineProperty(exports, "countDistinct", {
294
295
  enumerable: true,
295
- get: function () { return chunkH6I36MGT_cjs.countDistinct; }
296
+ get: function () { return chunkLOKG3KQV_cjs.countDistinct; }
296
297
  });
297
298
  Object.defineProperty(exports, "countDistinctEdges", {
298
299
  enumerable: true,
299
- get: function () { return chunkH6I36MGT_cjs.countDistinctEdges; }
300
+ get: function () { return chunkLOKG3KQV_cjs.countDistinctEdges; }
300
301
  });
301
302
  Object.defineProperty(exports, "countEdges", {
302
303
  enumerable: true,
303
- get: function () { return chunkH6I36MGT_cjs.countEdges; }
304
+ get: function () { return chunkLOKG3KQV_cjs.countEdges; }
304
305
  });
305
306
  Object.defineProperty(exports, "createAdapterStore", {
306
307
  enumerable: true,
307
- get: function () { return chunkH6I36MGT_cjs.createAdapterStore; }
308
+ get: function () { return chunkLOKG3KQV_cjs.createAdapterStore; }
308
309
  });
309
310
  Object.defineProperty(exports, "createAdapterStoreWithSchema", {
310
311
  enumerable: true,
311
- get: function () { return chunkH6I36MGT_cjs.createAdapterStoreWithSchema; }
312
+ get: function () { return chunkLOKG3KQV_cjs.createAdapterStoreWithSchema; }
312
313
  });
313
314
  Object.defineProperty(exports, "createFragment", {
314
315
  enumerable: true,
315
- get: function () { return chunkH6I36MGT_cjs.createFragment; }
316
+ get: function () { return chunkLOKG3KQV_cjs.createFragment; }
316
317
  });
317
318
  Object.defineProperty(exports, "createQueryBuilder", {
318
319
  enumerable: true,
319
- get: function () { return chunkH6I36MGT_cjs.createQueryBuilder; }
320
+ get: function () { return chunkLOKG3KQV_cjs.createQueryBuilder; }
320
321
  });
321
322
  Object.defineProperty(exports, "createStore", {
322
323
  enumerable: true,
323
- get: function () { return chunkH6I36MGT_cjs.createStore; }
324
+ get: function () { return chunkLOKG3KQV_cjs.createStore; }
324
325
  });
325
326
  Object.defineProperty(exports, "createStoreWithSchema", {
326
327
  enumerable: true,
327
- get: function () { return chunkH6I36MGT_cjs.createStoreWithSchema; }
328
+ get: function () { return chunkLOKG3KQV_cjs.createStoreWithSchema; }
328
329
  });
329
330
  Object.defineProperty(exports, "createVerifiedAdapterStore", {
330
331
  enumerable: true,
331
- get: function () { return chunkH6I36MGT_cjs.createVerifiedAdapterStore; }
332
+ get: function () { return chunkLOKG3KQV_cjs.createVerifiedAdapterStore; }
332
333
  });
333
334
  Object.defineProperty(exports, "createVerifiedStore", {
334
335
  enumerable: true,
335
- get: function () { return chunkH6I36MGT_cjs.createVerifiedStore; }
336
+ get: function () { return chunkLOKG3KQV_cjs.createVerifiedStore; }
336
337
  });
337
338
  Object.defineProperty(exports, "defineSubgraphProject", {
338
339
  enumerable: true,
339
- get: function () { return chunkH6I36MGT_cjs.defineSubgraphProject; }
340
+ get: function () { return chunkLOKG3KQV_cjs.defineSubgraphProject; }
340
341
  });
341
342
  Object.defineProperty(exports, "field", {
342
343
  enumerable: true,
343
- get: function () { return chunkH6I36MGT_cjs.field; }
344
+ get: function () { return chunkLOKG3KQV_cjs.field; }
344
345
  });
345
346
  Object.defineProperty(exports, "having", {
346
347
  enumerable: true,
347
- get: function () { return chunkH6I36MGT_cjs.having; }
348
+ get: function () { return chunkLOKG3KQV_cjs.having; }
348
349
  });
349
350
  Object.defineProperty(exports, "havingEq", {
350
351
  enumerable: true,
351
- get: function () { return chunkH6I36MGT_cjs.havingEq; }
352
+ get: function () { return chunkLOKG3KQV_cjs.havingEq; }
352
353
  });
353
354
  Object.defineProperty(exports, "havingGt", {
354
355
  enumerable: true,
355
- get: function () { return chunkH6I36MGT_cjs.havingGt; }
356
+ get: function () { return chunkLOKG3KQV_cjs.havingGt; }
356
357
  });
357
358
  Object.defineProperty(exports, "havingGte", {
358
359
  enumerable: true,
359
- get: function () { return chunkH6I36MGT_cjs.havingGte; }
360
+ get: function () { return chunkLOKG3KQV_cjs.havingGte; }
360
361
  });
361
362
  Object.defineProperty(exports, "havingLt", {
362
363
  enumerable: true,
363
- get: function () { return chunkH6I36MGT_cjs.havingLt; }
364
+ get: function () { return chunkLOKG3KQV_cjs.havingLt; }
364
365
  });
365
366
  Object.defineProperty(exports, "havingLte", {
366
367
  enumerable: true,
367
- get: function () { return chunkH6I36MGT_cjs.havingLte; }
368
+ get: function () { return chunkLOKG3KQV_cjs.havingLte; }
368
369
  });
369
370
  Object.defineProperty(exports, "limitFragment", {
370
371
  enumerable: true,
371
- get: function () { return chunkH6I36MGT_cjs.limitFragment; }
372
+ get: function () { return chunkLOKG3KQV_cjs.limitFragment; }
372
373
  });
373
374
  Object.defineProperty(exports, "max", {
374
375
  enumerable: true,
375
- get: function () { return chunkH6I36MGT_cjs.max; }
376
+ get: function () { return chunkLOKG3KQV_cjs.max; }
376
377
  });
377
378
  Object.defineProperty(exports, "min", {
378
379
  enumerable: true,
379
- get: function () { return chunkH6I36MGT_cjs.min; }
380
+ get: function () { return chunkLOKG3KQV_cjs.min; }
380
381
  });
381
382
  Object.defineProperty(exports, "offsetFragment", {
382
383
  enumerable: true,
383
- get: function () { return chunkH6I36MGT_cjs.offsetFragment; }
384
+ get: function () { return chunkLOKG3KQV_cjs.offsetFragment; }
384
385
  });
385
386
  Object.defineProperty(exports, "orderByFragment", {
386
387
  enumerable: true,
387
- get: function () { return chunkH6I36MGT_cjs.orderByFragment; }
388
+ get: function () { return chunkLOKG3KQV_cjs.orderByFragment; }
388
389
  });
389
390
  Object.defineProperty(exports, "sum", {
390
391
  enumerable: true,
391
- get: function () { return chunkH6I36MGT_cjs.sum; }
392
+ get: function () { return chunkLOKG3KQV_cjs.sum; }
392
393
  });
393
394
  Object.defineProperty(exports, "sqliteVecStrategy", {
394
395
  enumerable: true,
@@ -504,55 +505,59 @@ Object.defineProperty(exports, "recordedInstantWallTime", {
504
505
  });
505
506
  Object.defineProperty(exports, "broader", {
506
507
  enumerable: true,
507
- get: function () { return chunkK4FB2RMO_cjs.broader; }
508
+ get: function () { return chunkJP5EICR6_cjs.broader; }
508
509
  });
509
510
  Object.defineProperty(exports, "core", {
510
511
  enumerable: true,
511
- get: function () { return chunkK4FB2RMO_cjs.core; }
512
+ get: function () { return chunkJP5EICR6_cjs.core; }
512
513
  });
513
514
  Object.defineProperty(exports, "differentFrom", {
514
515
  enumerable: true,
515
- get: function () { return chunkK4FB2RMO_cjs.differentFrom; }
516
+ get: function () { return chunkJP5EICR6_cjs.differentFrom; }
516
517
  });
517
518
  Object.defineProperty(exports, "disjointWith", {
518
519
  enumerable: true,
519
- get: function () { return chunkK4FB2RMO_cjs.disjointWith; }
520
+ get: function () { return chunkJP5EICR6_cjs.disjointWith; }
520
521
  });
521
522
  Object.defineProperty(exports, "equivalentTo", {
522
523
  enumerable: true,
523
- get: function () { return chunkK4FB2RMO_cjs.equivalentTo; }
524
+ get: function () { return chunkJP5EICR6_cjs.equivalentTo; }
525
+ });
526
+ Object.defineProperty(exports, "getCommittedSchemaVersion", {
527
+ enumerable: true,
528
+ get: function () { return chunkJP5EICR6_cjs.getCommittedSchemaVersion; }
524
529
  });
525
530
  Object.defineProperty(exports, "hasPart", {
526
531
  enumerable: true,
527
- get: function () { return chunkK4FB2RMO_cjs.hasPart; }
532
+ get: function () { return chunkJP5EICR6_cjs.hasPart; }
528
533
  });
529
534
  Object.defineProperty(exports, "implies", {
530
535
  enumerable: true,
531
- get: function () { return chunkK4FB2RMO_cjs.implies; }
536
+ get: function () { return chunkJP5EICR6_cjs.implies; }
532
537
  });
533
538
  Object.defineProperty(exports, "inverseOf", {
534
539
  enumerable: true,
535
- get: function () { return chunkK4FB2RMO_cjs.inverseOf; }
540
+ get: function () { return chunkJP5EICR6_cjs.inverseOf; }
536
541
  });
537
542
  Object.defineProperty(exports, "narrower", {
538
543
  enumerable: true,
539
- get: function () { return chunkK4FB2RMO_cjs.narrower; }
544
+ get: function () { return chunkJP5EICR6_cjs.narrower; }
540
545
  });
541
546
  Object.defineProperty(exports, "partOf", {
542
547
  enumerable: true,
543
- get: function () { return chunkK4FB2RMO_cjs.partOf; }
548
+ get: function () { return chunkJP5EICR6_cjs.partOf; }
544
549
  });
545
550
  Object.defineProperty(exports, "relatedTo", {
546
551
  enumerable: true,
547
- get: function () { return chunkK4FB2RMO_cjs.relatedTo; }
552
+ get: function () { return chunkJP5EICR6_cjs.relatedTo; }
548
553
  });
549
554
  Object.defineProperty(exports, "sameAs", {
550
555
  enumerable: true,
551
- get: function () { return chunkK4FB2RMO_cjs.sameAs; }
556
+ get: function () { return chunkJP5EICR6_cjs.sameAs; }
552
557
  });
553
558
  Object.defineProperty(exports, "subClassOf", {
554
559
  enumerable: true,
555
- get: function () { return chunkK4FB2RMO_cjs.subClassOf; }
560
+ get: function () { return chunkJP5EICR6_cjs.subClassOf; }
556
561
  });
557
562
  Object.defineProperty(exports, "defineEdge", {
558
563
  enumerable: true,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/backend/migrate-vectors.ts"],"names":["DEFAULT_EMBEDDING_METRIC","DEFAULT_EMBEDDING_INDEX_TYPE","LEGACY_EMBEDDINGS_TABLE_NAME","isMissingTableError","embedding","EmbeddingDimensionChangedError","requireDefined","sql","asCompiledRowsSql"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * One-time offline migration: legacy shared embeddings table → per-field\n * strategy storage.\n *\n * ## What this is for\n *\n * The cross-backend vector cutover (#157) dropped the single shared\n * `typegraph_node_embeddings` table. Each\n * `VectorStrategy` now OWNS one typed, fixed-dimension structure per\n * `(nodeKind, fieldPath)` — the only layout that can be ANN-indexed on\n * libSQL and sqlite-vec, not just pgvector.\n *\n * Deployments that wrote embeddings under the old shared table before\n * upgrading still hold those rows. This utility drains them into the new\n * per-field storage **once**, during the upgrade, so existing embedded\n * data survives the cutover without re-embedding from source.\n *\n * It is an explicitly-run, offline step — not wired into `materializeIndexes`\n * or any boot path. Run it once after deploying the new version and before\n * (or alongside) the first `materializeIndexes()`, then drop the legacy\n * table at your leisure.\n *\n * ## How it works\n *\n * - Skips cleanly (returns a zero summary) when the legacy table is absent —\n * a fresh install, or a re-run after the table was dropped.\n * - Reads rows in keyset-paginated batches (never the whole table at once),\n * decoding the engine-native embedding column to a numeric array at the SQL\n * level: sqlite-vec stored a `vec_f32` blob (`vec_to_json` decodes it);\n * pgvector stored a native `vector` (`::text` yields a `[…]` literal).\n * - Re-inserts each row through `backend.upsertEmbedding`, which routes the\n * active strategy's `buildUpsert` and idempotently provisions the per-field\n * storage (the same `(nodeKind, fieldPath)` slot a fresh store write uses).\n * The migration stays graph-agnostic and execution-correct on both the\n * sync (better-sqlite3) and async (libsql / Postgres) backends — it does\n * not re-implement the backend's statement-execution glue.\n *\n * Idempotent and resumable: a partial run followed by a full run converges\n * to the same per-field tables, because every write is an upsert keyed by\n * `(graph_id, node_id)` in the strategy's owned storage.\n */\nimport {\n DEFAULT_EMBEDDING_INDEX_TYPE,\n DEFAULT_EMBEDDING_METRIC,\n type EmbeddingIndexType,\n type EmbeddingMetric,\n} from \"../core/embedding\";\nimport { EmbeddingDimensionChangedError } from \"../errors\";\nimport { sql, type SqlFragment } from \"../query/sql-fragment\";\nimport { asCompiledRowsSql } from \"../query/sql-intent\";\nimport { requireDefined } from \"../utils/presence\";\nimport { isMissingTableError } from \"../utils/sql-errors\";\nimport { LEGACY_EMBEDDINGS_TABLE_NAME } from \"./drizzle/schema/sqlite\";\nimport { type GraphBackend } from \"./types\";\n\n/**\n * Default rows read per round-trip. Large enough to amortize round-trip\n * latency, small enough to bound peak memory regardless of table size.\n */\nconst DEFAULT_BATCH_SIZE = 500;\n\n/**\n * Metric / index type applied to a migrated field when no\n * {@link MigrateLegacyEmbeddingsOptions.resolveSlotConfig} is supplied (or\n * it returns `undefined`). Matches the defaults `embedding()` and\n * `resolveEmbeddingFields` apply, so a migrated field lands in storage shaped\n * identically to one written fresh through the store. Migrated data is only\n * ever brute-forceable until `materializeIndexes()` builds the ANN index, so\n * the index-type default governs only which ANN structure the per-field\n * storage DDL provisions, not the migration's correctness.\n */\nconst DEFAULT_SLOT_METRIC: EmbeddingMetric = DEFAULT_EMBEDDING_METRIC;\nconst DEFAULT_SLOT_INDEX_TYPE: EmbeddingIndexType =\n DEFAULT_EMBEDDING_INDEX_TYPE;\n\n/**\n * The resolved storage config for one `(nodeKind, fieldPath)` slot that the\n * legacy table did not record. The legacy shared table stored only the\n * vector and its dimension count — not the metric or index type — so a\n * caller that wants migrated fields to match a specific graph's `embedding()`\n * declarations supplies this resolver.\n */\nexport type LegacyEmbeddingSlotConfig = Readonly<{\n metric: EmbeddingMetric;\n indexType: EmbeddingIndexType;\n}>;\n\n/**\n * Options for {@link migrateLegacyEmbeddings}.\n */\nexport type MigrateLegacyEmbeddingsOptions = Readonly<{\n /**\n * The backend to migrate, wired with the destination `VectorStrategy`\n * (i.e. the post-cutover backend). Its `vectorStrategy` owns the per-field\n * storage rows are written into and its `upsertEmbedding` performs the\n * writes.\n */\n backend: GraphBackend;\n\n /**\n * Restrict the migration to a single graph. When omitted, every graph's\n * rows in the legacy table are migrated (the table is graph-scoped by its\n * `graph_id` column).\n */\n graphId?: string;\n\n /**\n * Resolves the metric / index type for a `(nodeKind, fieldPath)` slot the\n * legacy table didn't persist. Return `undefined` to fall back to the\n * cosine / hnsw defaults. Supply this (typically reading the graph's\n * `embedding()` declarations) when migrated fields must match a specific\n * metric — e.g. an `l2` field, which scores incorrectly under the cosine\n * default.\n */\n resolveSlotConfig?: (\n nodeKind: string,\n fieldPath: string,\n ) => LegacyEmbeddingSlotConfig | undefined;\n\n /** Rows read per round-trip. Defaults to {@link DEFAULT_BATCH_SIZE}. */\n batchSize?: number;\n\n /**\n * Physical name of the legacy table to drain. Defaults to\n * {@link LEGACY_EMBEDDINGS_TABLE_NAME}. Override only for a non-default\n * deployment that renamed the embeddings table.\n */\n legacyTableName?: string;\n}>;\n\n/**\n * Summary of a {@link migrateLegacyEmbeddings} run.\n */\nexport type MigrateLegacyEmbeddingsResult = Readonly<{\n /** Total embedding rows re-inserted into per-field storage. */\n migrated: number;\n /**\n * Per-`(nodeKind, fieldPath)` counts, keyed `\"<nodeKind>.<fieldPath>\"`\n * (the strategy's logical-slot key form). Empty when the legacy table was\n * absent or held no rows for the requested scope.\n */\n perField: Readonly<Record<string, number>>;\n /**\n * Rows skipped because their vector length didn't match the per-field\n * table's fixed dimension. The legacy shared column allowed mixed\n * dimensions for one `(nodeKind, fieldPath)` (e.g. an unmigrated model\n * change); the first migrated row fixes the typed table's dimension and\n * any differently-sized rows for that slot are skipped rather than aborting\n * the whole migration. Keyed `\"<nodeKind>.<fieldPath>\"`. Non-empty here\n * means those fields need a deliberate re-embed at a single dimension.\n */\n skippedDimensionMismatch: Readonly<Record<string, number>>;\n /**\n * Rows skipped because their legacy embedding could not be decoded into a\n * finite-number array — a corrupt value (e.g. a pgvector `vector` column\n * permits `NaN`/`Infinity`, which is not valid JSON). Keyed\n * `\"<nodeKind>.<fieldPath>\"`. Skipping + reporting keeps one bad row from\n * aborting the whole migration; non-empty here means those rows need manual\n * repair.\n */\n skippedDecodeError: Readonly<Record<string, number>>;\n /**\n * Whether the legacy table existed. `false` means the run was a clean\n * no-op (fresh install, or already-dropped table on a re-run).\n */\n legacyTablePresent: boolean;\n}>;\n\n/**\n * A single legacy embedding row, with the engine-native vector already\n * decoded to a JSON array string by the dialect-specific SELECT. The\n * legacy `dimensions` column is intentionally not read: the decoded array's\n * length is the authoritative fixed dimension for the destination slot, and\n * relying on it sidesteps the per-driver string/number coercion the legacy\n * integer column would otherwise need.\n */\ntype LegacyEmbeddingRow = Readonly<{\n graph_id: string;\n node_kind: string;\n node_id: string;\n field_path: string;\n /** JSON array text, e.g. `\"[0.1,0.2,0.3]\"` — decoded per dialect. */\n embedding_json: string;\n}>;\n\n/**\n * Re-inserts every embedding from the legacy shared\n * `typegraph_node_embeddings` table into the active\n * `backend.vectorStrategy`'s per-`(nodeKind, fieldPath)` storage.\n *\n * One-time, explicitly-run upgrade step for the shared-table → per-field\n * cutover (#157). Idempotent, batched, and a clean no-op when the legacy\n * table is absent. See the module doc comment for the full contract.\n *\n * @throws Error when the backend exposes no `vectorStrategy` /\n * `upsertEmbedding` (nothing to migrate *into*) — a configuration\n * error the caller must fix by wiring the destination strategy\n * before migrating.\n */\nexport async function migrateLegacyEmbeddings(\n options: MigrateLegacyEmbeddingsOptions,\n): Promise<MigrateLegacyEmbeddingsResult> {\n const {\n backend,\n graphId,\n resolveSlotConfig,\n batchSize = DEFAULT_BATCH_SIZE,\n legacyTableName = LEGACY_EMBEDDINGS_TABLE_NAME,\n } = options;\n\n if (\n backend.vectorStrategy === undefined ||\n backend.upsertEmbedding === undefined\n ) {\n throw new Error(\n \"migrateLegacyEmbeddings requires a backend wired with a vectorStrategy \" +\n \"(the destination per-field storage). Pass the post-cutover backend.\",\n );\n }\n if (!Number.isInteger(batchSize) || batchSize <= 0) {\n throw new RangeError(\n `batchSize must be a positive integer, got: ${batchSize}`,\n );\n }\n const upsertEmbedding = backend.upsertEmbedding;\n const ensureVectorSlotContribution = backend.ensureVectorSlotContribution;\n\n const perField: Record<string, number> = {};\n const skippedDimensionMismatch: Record<string, number> = {};\n const skippedDecodeError: Record<string, number> = {};\n // (kind, field) slots whose per-field table + durable marker this run has\n // already provisioned, mapped to the dimension the table was fixed at.\n // `upsertEmbedding` asserts the marker (#135) and no longer self-creates\n // the table, so this offline migration (privileged) provisions each slot\n // once — at the first row's dimension, which fixes the typed table just as\n // the original lazy write did. Differently-sized later rows for the same\n // slot are detected against this map and skipped BEFORE the upsert: the\n // marker assert would otherwise read the differently-dimensioned slot as\n // stale and abort the whole migration, and the ensure is deliberately not\n // re-run per row (that would trip the marker drift-guard).\n const ensuredSlots = new Map<string, number>();\n let migrated = 0;\n\n let cursor: LegacyRowCursor | undefined;\n for (;;) {\n let batch: readonly LegacyEmbeddingRow[];\n try {\n batch = await readLegacyBatch(backend, {\n legacyTableName,\n graphId,\n batchSize,\n after: cursor,\n });\n } catch (error) {\n // A missing legacy table is the expected \"nothing to migrate\" path on\n // the first read — surface it as a clean no-op, not a failure.\n if (cursor === undefined && isMissingTableError(error)) {\n return {\n migrated: 0,\n perField: {},\n skippedDimensionMismatch: {},\n skippedDecodeError: {},\n legacyTablePresent: false,\n };\n }\n throw error;\n }\n\n if (batch.length === 0) break;\n\n for (const row of batch) {\n const slotKey = `${row.node_kind}.${row.field_path}`;\n\n let embedding: readonly number[];\n try {\n embedding = decodeEmbeddingJson(row);\n } catch {\n // A corrupt legacy value (e.g. a pgvector `vector` column permits\n // NaN/Infinity, which is not valid JSON) is skipped + reported rather\n // than aborting the whole migration on one bad row.\n skippedDecodeError[slotKey] = (skippedDecodeError[slotKey] ?? 0) + 1;\n continue;\n }\n const config = resolveSlotConfig?.(row.node_kind, row.field_path);\n // The decoded length is the authoritative fixed dimension — the\n // strategy provisions its column type (e.g. `F32_BLOB(N)`) from it.\n const slot = {\n graphId: row.graph_id,\n nodeKind: row.node_kind,\n fieldPath: row.field_path,\n dimensions: embedding.length,\n metric: config?.metric ?? DEFAULT_SLOT_METRIC,\n indexType: config?.indexType ?? DEFAULT_SLOT_INDEX_TYPE,\n };\n\n // Provision the per-field table + durable marker before the first\n // write into this slot. Once per (graph, kind, field): the first row's\n // dimension fixes the table. Keyed by graph id too — the legacy table\n // is graph-scoped, so the same `kind.field` can recur across graphs.\n const ensuredKey = JSON.stringify([\n row.graph_id,\n row.node_kind,\n row.field_path,\n ]);\n if (\n ensureVectorSlotContribution !== undefined &&\n !ensuredSlots.has(ensuredKey)\n ) {\n await ensureVectorSlotContribution(slot);\n ensuredSlots.set(ensuredKey, slot.dimensions);\n }\n\n // The legacy shared column allowed mixed dimensions for one\n // (nodeKind, fieldPath); the per-field table is fixed at the first\n // migrated row's dimension. Skip a differently-sized row up front —\n // its slot would fail the marker assert as stale (different\n // signature), aborting the migration instead of skipping the row.\n const provisionedDimensions = ensuredSlots.get(ensuredKey);\n if (\n provisionedDimensions !== undefined &&\n provisionedDimensions !== embedding.length\n ) {\n skippedDimensionMismatch[slotKey] =\n (skippedDimensionMismatch[slotKey] ?? 0) + 1;\n continue;\n }\n\n try {\n await upsertEmbedding({ ...slot, nodeId: row.node_id, embedding });\n } catch (error) {\n // The legacy shared column allowed mixed dimensions for one\n // (nodeKind, fieldPath); the per-field table is fixed at the first\n // migrated row's dimension, so a differently-sized row is skipped and\n // reported rather than aborting the whole migration.\n if (error instanceof EmbeddingDimensionChangedError) {\n skippedDimensionMismatch[slotKey] =\n (skippedDimensionMismatch[slotKey] ?? 0) + 1;\n continue;\n }\n throw error;\n }\n\n migrated += 1;\n perField[slotKey] = (perField[slotKey] ?? 0) + 1;\n }\n\n if (batch.length < batchSize) break;\n const last = requireDefined(batch.at(-1));\n cursor = {\n graphId: last.graph_id,\n nodeKind: last.node_kind,\n nodeId: last.node_id,\n fieldPath: last.field_path,\n };\n }\n\n return {\n migrated,\n perField,\n skippedDimensionMismatch,\n skippedDecodeError,\n legacyTablePresent: true,\n };\n}\n\n/**\n * Composite keyset cursor over the legacy table's primary key\n * `(graph_id, node_kind, node_id, field_path)`. Stable under concurrent\n * writes and immune to OFFSET drift, so a batched walk reads every row once.\n */\ntype LegacyRowCursor = Readonly<{\n graphId: string;\n nodeKind: string;\n nodeId: string;\n fieldPath: string;\n}>;\n\ntype ReadLegacyBatchParams = Readonly<{\n legacyTableName: string;\n graphId: string | undefined;\n batchSize: number;\n after: LegacyRowCursor | undefined;\n}>;\n\n/**\n * Reads one keyset-paginated batch of legacy rows, ordered by the primary\n * key, with the engine-native embedding column decoded to a JSON array\n * string by the dialect.\n */\nasync function readLegacyBatch(\n backend: GraphBackend,\n params: ReadLegacyBatchParams,\n): Promise<readonly LegacyEmbeddingRow[]> {\n const table = sql.identifier(params.legacyTableName);\n const embeddingJson = legacyEmbeddingDecodeExpression(backend);\n\n const conditions: SqlFragment[] = [];\n if (params.graphId !== undefined) {\n conditions.push(sql`\"graph_id\" = ${params.graphId}`);\n }\n if (params.after !== undefined) {\n conditions.push(keysetAfterCondition(params.after));\n }\n\n const whereClause =\n conditions.length === 0 ?\n sql``\n : sql` WHERE ${sql.join(conditions, sql` AND `)}`;\n\n const query = sql`\n SELECT\n \"graph_id\" AS graph_id,\n \"node_kind\" AS node_kind,\n \"node_id\" AS node_id,\n \"field_path\" AS field_path,\n ${embeddingJson} AS embedding_json\n FROM ${table}${whereClause}\n ORDER BY \"graph_id\" ASC, \"node_kind\" ASC, \"node_id\" ASC, \"field_path\" ASC\n LIMIT ${params.batchSize}\n `;\n\n return backend.execute<LegacyEmbeddingRow>(asCompiledRowsSql(query));\n}\n\n/**\n * The strict `>` comparison over the composite primary key, expressed as\n * the standard lexicographic OR-chain so it works on every dialect (SQLite\n * supports row-value comparison, but Postgres + SQLite both accept this\n * portable form).\n */\nfunction keysetAfterCondition(after: LegacyRowCursor): SqlFragment {\n return sql`\n (\n \"graph_id\" > ${after.graphId}\n OR (\"graph_id\" = ${after.graphId} AND \"node_kind\" > ${after.nodeKind})\n OR (\"graph_id\" = ${after.graphId} AND \"node_kind\" = ${after.nodeKind} AND \"node_id\" > ${after.nodeId})\n OR (\n \"graph_id\" = ${after.graphId}\n AND \"node_kind\" = ${after.nodeKind}\n AND \"node_id\" = ${after.nodeId}\n AND \"field_path\" > ${after.fieldPath}\n )\n )\n `;\n}\n\n/**\n * The SQL expression that decodes the legacy engine-native embedding column\n * into a JSON array string `embedding_json`. The single dialect branch in\n * this whole module: the legacy storage formats are genuinely engine-\n * specific, and there is no longer a strategy abstraction over the *legacy*\n * table to delegate to.\n */\nfunction legacyEmbeddingDecodeExpression(backend: GraphBackend): SqlFragment {\n switch (backend.dialect) {\n case \"sqlite\": {\n // Legacy SQLite embeddings were written via `vec_f32('[…]')`\n // (sqlite-vec binary). `vec_to_json` is its inverse, yielding the\n // JSON array text. Requires sqlite-vec on the connection — which the\n // legacy write path also required, so any deployment with legacy rows\n // has it loaded.\n return sql`vec_to_json(\"embedding\")`;\n }\n case \"postgres\": {\n // pgvector's native `vector` casts to its `[…]` text literal, which is\n // valid JSON for `JSON.parse`.\n return sql`\"embedding\"::text`;\n }\n default: {\n const _exhaustive: never = backend.dialect;\n throw new Error(\n `migrateLegacyEmbeddings does not support dialect: ${String(_exhaustive)}`,\n );\n }\n }\n}\n\n/**\n * Parses a decoded `embedding_json` array, asserting it is a non-empty array\n * of finite numbers. A bad decode (wrong type, NaN) names the offending row\n * loudly instead of writing a corrupt vector into per-field storage.\n */\nfunction decodeEmbeddingJson(row: LegacyEmbeddingRow): readonly number[] {\n let parsed: unknown;\n try {\n parsed = JSON.parse(row.embedding_json) as unknown;\n } catch (error) {\n throw new Error(\n `Failed to decode legacy embedding for ${row.node_kind}.${row.field_path} ` +\n `(graph ${row.graph_id}, node ${row.node_id}): not valid JSON.`,\n { cause: error },\n );\n }\n if (!Array.isArray(parsed) || parsed.length === 0) {\n throw new Error(\n `Legacy embedding for ${row.node_kind}.${row.field_path} ` +\n `(graph ${row.graph_id}, node ${row.node_id}) decoded to a non-array ` +\n `or empty value.`,\n );\n }\n for (const [index, value] of parsed.entries()) {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new TypeError(\n `Legacy embedding for ${row.node_kind}.${row.field_path} ` +\n `(graph ${row.graph_id}, node ${row.node_id}) has a non-finite ` +\n `value at index ${index}: ${String(value)}.`,\n );\n }\n }\n return parsed as readonly number[];\n}\n"]}
1
+ {"version":3,"sources":["../src/backend/migrate-vectors.ts"],"names":["DEFAULT_EMBEDDING_METRIC","DEFAULT_EMBEDDING_INDEX_TYPE","LEGACY_EMBEDDINGS_TABLE_NAME","isMissingTableError","embedding","EmbeddingDimensionChangedError","requireDefined","sql","asCompiledRowsSql"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * One-time offline migration: legacy shared embeddings table → per-field\n * strategy storage.\n *\n * ## What this is for\n *\n * The cross-backend vector cutover (#157) dropped the single shared\n * `typegraph_node_embeddings` table. Each\n * `VectorStrategy` now OWNS one typed, fixed-dimension structure per\n * `(nodeKind, fieldPath)` — the only layout that can be ANN-indexed on\n * libSQL and sqlite-vec, not just pgvector.\n *\n * Deployments that wrote embeddings under the old shared table before\n * upgrading still hold those rows. This utility drains them into the new\n * per-field storage **once**, during the upgrade, so existing embedded\n * data survives the cutover without re-embedding from source.\n *\n * It is an explicitly-run, offline step — not wired into `materializeIndexes`\n * or any boot path. Run it once after deploying the new version and before\n * (or alongside) the first `materializeIndexes()`, then drop the legacy\n * table at your leisure.\n *\n * ## How it works\n *\n * - Skips cleanly (returns a zero summary) when the legacy table is absent —\n * a fresh install, or a re-run after the table was dropped.\n * - Reads rows in keyset-paginated batches (never the whole table at once),\n * decoding the engine-native embedding column to a numeric array at the SQL\n * level: sqlite-vec stored a `vec_f32` blob (`vec_to_json` decodes it);\n * pgvector stored a native `vector` (`::text` yields a `[…]` literal).\n * - Re-inserts each row through `backend.upsertEmbedding`, which routes the\n * active strategy's `buildUpsert` and idempotently provisions the per-field\n * storage (the same `(nodeKind, fieldPath)` slot a fresh store write uses).\n * The migration stays graph-agnostic and execution-correct on both the\n * sync (better-sqlite3) and async (libsql / Postgres) backends — it does\n * not re-implement the backend's statement-execution glue.\n *\n * Idempotent and resumable: a partial run followed by a full run converges\n * to the same per-field tables, because every write is an upsert keyed by\n * `(graph_id, node_id)` in the strategy's owned storage.\n */\nimport {\n DEFAULT_EMBEDDING_INDEX_TYPE,\n DEFAULT_EMBEDDING_METRIC,\n type EmbeddingIndexType,\n type EmbeddingMetric,\n} from \"../core/embedding\";\nimport { EmbeddingDimensionChangedError } from \"../errors\";\nimport { sql, type SqlFragment } from \"../query/sql-fragment\";\nimport { asCompiledRowsSql } from \"../query/sql-intent\";\nimport { requireDefined } from \"../utils/presence\";\nimport { isMissingTableError } from \"../utils/sql-errors\";\nimport { LEGACY_EMBEDDINGS_TABLE_NAME } from \"./drizzle/schema/sqlite\";\nimport { type GraphBackend } from \"./types\";\n\n/**\n * Default rows read per round-trip. Large enough to amortize round-trip\n * latency, small enough to bound peak memory regardless of table size.\n */\nconst DEFAULT_BATCH_SIZE = 500;\n\n/**\n * Metric / index type applied to a migrated field when no\n * {@link MigrateLegacyEmbeddingsOptions.resolveSlotConfig} is supplied (or\n * it returns `undefined`). Matches the defaults `embedding()` and\n * `resolveEmbeddingFields` apply, so a migrated field lands in storage shaped\n * identically to one written fresh through the store. Migrated data is only\n * ever brute-forceable until `materializeIndexes()` builds the ANN index, so\n * the index-type default governs only which ANN structure the per-field\n * storage DDL provisions, not the migration's correctness.\n */\nconst DEFAULT_SLOT_METRIC: EmbeddingMetric = DEFAULT_EMBEDDING_METRIC;\nconst DEFAULT_SLOT_INDEX_TYPE: EmbeddingIndexType =\n DEFAULT_EMBEDDING_INDEX_TYPE;\n\n/**\n * The resolved storage config for one `(nodeKind, fieldPath)` slot that the\n * legacy table did not record. The legacy shared table stored only the\n * vector and its dimension count — not the metric or index type — so a\n * caller that wants migrated fields to match a specific graph's `embedding()`\n * declarations supplies this resolver.\n */\nexport type LegacyEmbeddingSlotConfig = Readonly<{\n metric: EmbeddingMetric;\n indexType: EmbeddingIndexType;\n}>;\n\n/**\n * Options for {@link migrateLegacyEmbeddings}.\n */\nexport type MigrateLegacyEmbeddingsOptions = Readonly<{\n /**\n * The backend to migrate, wired with the destination `VectorStrategy`\n * (i.e. the post-cutover backend). Its `vectorStrategy` owns the per-field\n * storage rows are written into and its `upsertEmbedding` performs the\n * writes.\n */\n backend: GraphBackend;\n\n /**\n * Restrict the migration to a single graph. When omitted, every graph's\n * rows in the legacy table are migrated (the table is graph-scoped by its\n * `graph_id` column).\n */\n graphId?: string;\n\n /**\n * Resolves the metric / index type for a `(nodeKind, fieldPath)` slot the\n * legacy table didn't persist. Return `undefined` to fall back to the\n * cosine / hnsw defaults. Supply this (typically reading the graph's\n * `embedding()` declarations) when migrated fields must match a specific\n * metric — e.g. an `l2` field, which scores incorrectly under the cosine\n * default.\n */\n resolveSlotConfig?: (\n nodeKind: string,\n fieldPath: string,\n ) => LegacyEmbeddingSlotConfig | undefined;\n\n /** Rows read per round-trip. Defaults to {@link DEFAULT_BATCH_SIZE}. */\n batchSize?: number;\n\n /**\n * Physical name of the legacy table to drain. Defaults to\n * {@link LEGACY_EMBEDDINGS_TABLE_NAME}. Override only for a non-default\n * deployment that renamed the embeddings table.\n */\n legacyTableName?: string;\n}>;\n\n/**\n * Summary of a {@link migrateLegacyEmbeddings} run.\n */\nexport type MigrateLegacyEmbeddingsResult = Readonly<{\n /** Total embedding rows re-inserted into per-field storage. */\n migrated: number;\n /**\n * Per-`(nodeKind, fieldPath)` counts, keyed `\"<nodeKind>.<fieldPath>\"`\n * (the strategy's logical-slot key form). Empty when the legacy table was\n * absent or held no rows for the requested scope.\n */\n perField: Readonly<Record<string, number>>;\n /**\n * Rows skipped because their vector length didn't match the per-field\n * table's fixed dimension. The legacy shared column allowed mixed\n * dimensions for one `(nodeKind, fieldPath)` (e.g. an unmigrated model\n * change); the first migrated row fixes the typed table's dimension and\n * any differently-sized rows for that slot are skipped rather than aborting\n * the whole migration. Keyed `\"<nodeKind>.<fieldPath>\"`. Non-empty here\n * means those fields need a deliberate re-embed at a single dimension.\n */\n skippedDimensionMismatch: Readonly<Record<string, number>>;\n /**\n * Rows skipped because their legacy embedding could not be decoded into a\n * finite-number array — a corrupt value (e.g. a pgvector `vector` column\n * permits `NaN`/`Infinity`, which is not valid JSON). Keyed\n * `\"<nodeKind>.<fieldPath>\"`. Skipping + reporting keeps one bad row from\n * aborting the whole migration; non-empty here means those rows need manual\n * repair.\n */\n skippedDecodeError: Readonly<Record<string, number>>;\n /**\n * Whether the legacy table existed. `false` means the run was a clean\n * no-op (fresh install, or already-dropped table on a re-run).\n */\n legacyTablePresent: boolean;\n}>;\n\n/**\n * A single legacy embedding row, with the engine-native vector already\n * decoded to a JSON array string by the dialect-specific SELECT. The\n * legacy `dimensions` column is intentionally not read: the decoded array's\n * length is the authoritative fixed dimension for the destination slot, and\n * relying on it sidesteps the per-driver string/number coercion the legacy\n * integer column would otherwise need.\n */\ntype LegacyEmbeddingRow = Readonly<{\n graph_id: string;\n node_kind: string;\n node_id: string;\n field_path: string;\n /** JSON array text, e.g. `\"[0.1,0.2,0.3]\"` — decoded per dialect. */\n embedding_json: string;\n}>;\n\n/**\n * Re-inserts every embedding from the legacy shared\n * `typegraph_node_embeddings` table into the active\n * `backend.vectorStrategy`'s per-`(nodeKind, fieldPath)` storage.\n *\n * One-time, explicitly-run upgrade step for the shared-table → per-field\n * cutover (#157). Idempotent, batched, and a clean no-op when the legacy\n * table is absent. See the module doc comment for the full contract.\n *\n * @throws Error when the backend exposes no `vectorStrategy` /\n * `upsertEmbedding` (nothing to migrate *into*) — a configuration\n * error the caller must fix by wiring the destination strategy\n * before migrating.\n */\nexport async function migrateLegacyEmbeddings(\n options: MigrateLegacyEmbeddingsOptions,\n): Promise<MigrateLegacyEmbeddingsResult> {\n const {\n backend,\n graphId,\n resolveSlotConfig,\n batchSize = DEFAULT_BATCH_SIZE,\n legacyTableName = LEGACY_EMBEDDINGS_TABLE_NAME,\n } = options;\n\n if (\n backend.vectorStrategy === undefined ||\n backend.upsertEmbedding === undefined\n ) {\n throw new Error(\n \"migrateLegacyEmbeddings requires a backend wired with a vectorStrategy \" +\n \"(the destination per-field storage). Pass the post-cutover backend.\",\n );\n }\n if (!Number.isInteger(batchSize) || batchSize <= 0) {\n throw new RangeError(\n `batchSize must be a positive integer, got: ${batchSize}`,\n );\n }\n const upsertEmbedding = backend.upsertEmbedding;\n const ensureVectorSlotContribution = backend.ensureVectorSlotContribution;\n\n const perField: Record<string, number> = {};\n const skippedDimensionMismatch: Record<string, number> = {};\n const skippedDecodeError: Record<string, number> = {};\n // (kind, field) slots whose per-field table + durable marker this run has\n // already provisioned, mapped to the dimension the table was fixed at.\n // `upsertEmbedding` asserts the marker (#135) and no longer self-creates\n // the table, so this offline migration (privileged) provisions each slot\n // once — at the first row's dimension, which fixes the typed table just as\n // the original lazy write did. Differently-sized later rows for the same\n // slot are detected against this map and skipped BEFORE the upsert: the\n // marker assert would otherwise read the differently-dimensioned slot as\n // stale and abort the whole migration, and the ensure is deliberately not\n // re-run per row (that would trip the marker drift-guard).\n const ensuredSlots = new Map<string, number>();\n let migrated = 0;\n\n let cursor: LegacyRowCursor | undefined;\n for (;;) {\n let batch: readonly LegacyEmbeddingRow[];\n try {\n batch = await readLegacyBatch(backend, {\n legacyTableName,\n graphId,\n batchSize,\n after: cursor,\n });\n } catch (error) {\n // A missing legacy table is the expected \"nothing to migrate\" path on\n // the first read — surface it as a clean no-op, not a failure.\n if (cursor === undefined && isMissingTableError(error)) {\n return {\n migrated: 0,\n perField: {},\n skippedDimensionMismatch: {},\n skippedDecodeError: {},\n legacyTablePresent: false,\n };\n }\n throw error;\n }\n\n if (batch.length === 0) break;\n\n for (const row of batch) {\n const slotKey = `${row.node_kind}.${row.field_path}`;\n\n let embedding: readonly number[];\n try {\n embedding = decodeEmbeddingJson(row);\n } catch {\n // A corrupt legacy value (e.g. a pgvector `vector` column permits\n // NaN/Infinity, which is not valid JSON) is skipped + reported rather\n // than aborting the whole migration on one bad row.\n skippedDecodeError[slotKey] = (skippedDecodeError[slotKey] ?? 0) + 1;\n continue;\n }\n const config = resolveSlotConfig?.(row.node_kind, row.field_path);\n // The decoded length is the authoritative fixed dimension — the\n // strategy provisions its column type (e.g. `F32_BLOB(N)`) from it.\n const slot = {\n graphId: row.graph_id,\n nodeKind: row.node_kind,\n fieldPath: row.field_path,\n dimensions: embedding.length,\n metric: config?.metric ?? DEFAULT_SLOT_METRIC,\n indexType: config?.indexType ?? DEFAULT_SLOT_INDEX_TYPE,\n };\n\n // Provision the per-field table + durable marker before the first\n // write into this slot. Once per (graph, kind, field): the first row's\n // dimension fixes the table. Keyed by graph id too — the legacy table\n // is graph-scoped, so the same `kind.field` can recur across graphs.\n const ensuredKey = JSON.stringify([\n row.graph_id,\n row.node_kind,\n row.field_path,\n ]);\n if (\n ensureVectorSlotContribution !== undefined &&\n !ensuredSlots.has(ensuredKey)\n ) {\n await ensureVectorSlotContribution(slot);\n ensuredSlots.set(ensuredKey, slot.dimensions);\n }\n\n // The legacy shared column allowed mixed dimensions for one\n // (nodeKind, fieldPath); the per-field table is fixed at the first\n // migrated row's dimension. Skip a differently-sized row up front —\n // its slot would fail the marker assert as stale (different\n // signature), aborting the migration instead of skipping the row.\n const provisionedDimensions = ensuredSlots.get(ensuredKey);\n if (\n provisionedDimensions !== undefined &&\n provisionedDimensions !== embedding.length\n ) {\n skippedDimensionMismatch[slotKey] =\n (skippedDimensionMismatch[slotKey] ?? 0) + 1;\n continue;\n }\n\n try {\n await upsertEmbedding({ ...slot, nodeId: row.node_id, embedding });\n } catch (error) {\n // The legacy shared column allowed mixed dimensions for one\n // (nodeKind, fieldPath); the per-field table is fixed at the first\n // migrated row's dimension, so a differently-sized row is skipped and\n // reported rather than aborting the whole migration.\n if (error instanceof EmbeddingDimensionChangedError) {\n skippedDimensionMismatch[slotKey] =\n (skippedDimensionMismatch[slotKey] ?? 0) + 1;\n continue;\n }\n throw error;\n }\n\n migrated += 1;\n perField[slotKey] = (perField[slotKey] ?? 0) + 1;\n }\n\n if (batch.length < batchSize) break;\n const last = requireDefined(batch.at(-1));\n cursor = {\n graphId: last.graph_id,\n nodeKind: last.node_kind,\n nodeId: last.node_id,\n fieldPath: last.field_path,\n };\n }\n\n return {\n migrated,\n perField,\n skippedDimensionMismatch,\n skippedDecodeError,\n legacyTablePresent: true,\n };\n}\n\n/**\n * Composite keyset cursor over the legacy table's primary key\n * `(graph_id, node_kind, node_id, field_path)`. Stable under concurrent\n * writes and immune to OFFSET drift, so a batched walk reads every row once.\n */\ntype LegacyRowCursor = Readonly<{\n graphId: string;\n nodeKind: string;\n nodeId: string;\n fieldPath: string;\n}>;\n\ntype ReadLegacyBatchParams = Readonly<{\n legacyTableName: string;\n graphId: string | undefined;\n batchSize: number;\n after: LegacyRowCursor | undefined;\n}>;\n\n/**\n * Reads one keyset-paginated batch of legacy rows, ordered by the primary\n * key, with the engine-native embedding column decoded to a JSON array\n * string by the dialect.\n */\nasync function readLegacyBatch(\n backend: GraphBackend,\n params: ReadLegacyBatchParams,\n): Promise<readonly LegacyEmbeddingRow[]> {\n const table = sql.identifier(params.legacyTableName);\n const embeddingJson = legacyEmbeddingDecodeExpression(backend);\n\n const conditions: SqlFragment[] = [];\n if (params.graphId !== undefined) {\n conditions.push(sql`\"graph_id\" = ${params.graphId}`);\n }\n if (params.after !== undefined) {\n conditions.push(keysetAfterCondition(params.after));\n }\n\n const whereClause =\n conditions.length === 0 ?\n sql``\n : sql` WHERE ${sql.join(conditions, sql` AND `)}`;\n\n const query = sql`\n SELECT\n \"graph_id\" AS graph_id,\n \"node_kind\" AS node_kind,\n \"node_id\" AS node_id,\n \"field_path\" AS field_path,\n ${embeddingJson} AS embedding_json\n FROM ${table}${whereClause}\n ORDER BY \"graph_id\" ASC, \"node_kind\" ASC, \"node_id\" ASC, \"field_path\" ASC\n LIMIT ${params.batchSize}\n `;\n\n return backend.execute<LegacyEmbeddingRow>(asCompiledRowsSql(query));\n}\n\n/**\n * The strict `>` comparison over the composite primary key, expressed as\n * the standard lexicographic OR-chain so it works on every dialect (SQLite\n * supports row-value comparison, but Postgres + SQLite both accept this\n * portable form).\n */\nfunction keysetAfterCondition(after: LegacyRowCursor): SqlFragment {\n return sql`\n (\n \"graph_id\" > ${after.graphId}\n OR (\"graph_id\" = ${after.graphId} AND \"node_kind\" > ${after.nodeKind})\n OR (\"graph_id\" = ${after.graphId} AND \"node_kind\" = ${after.nodeKind} AND \"node_id\" > ${after.nodeId})\n OR (\n \"graph_id\" = ${after.graphId}\n AND \"node_kind\" = ${after.nodeKind}\n AND \"node_id\" = ${after.nodeId}\n AND \"field_path\" > ${after.fieldPath}\n )\n )\n `;\n}\n\n/**\n * The SQL expression that decodes the legacy engine-native embedding column\n * into a JSON array string `embedding_json`. The single dialect branch in\n * this whole module: the legacy storage formats are genuinely engine-\n * specific, and there is no longer a strategy abstraction over the *legacy*\n * table to delegate to.\n */\nfunction legacyEmbeddingDecodeExpression(backend: GraphBackend): SqlFragment {\n switch (backend.dialect) {\n case \"sqlite\": {\n // Legacy SQLite embeddings were written via `vec_f32('[…]')`\n // (sqlite-vec binary). `vec_to_json` is its inverse, yielding the\n // JSON array text. Requires sqlite-vec on the connection — which the\n // legacy write path also required, so any deployment with legacy rows\n // has it loaded.\n return sql`vec_to_json(\"embedding\")`;\n }\n case \"postgres\": {\n // pgvector's native `vector` casts to its `[…]` text literal, which is\n // valid JSON for `JSON.parse`.\n return sql`\"embedding\"::text`;\n }\n default: {\n const _exhaustive: never = backend.dialect;\n throw new Error(\n `migrateLegacyEmbeddings does not support dialect: ${String(_exhaustive)}`,\n );\n }\n }\n}\n\n/**\n * Parses a decoded `embedding_json` array, asserting it is a non-empty array\n * of finite numbers. A bad decode (wrong type, NaN) names the offending row\n * loudly instead of writing a corrupt vector into per-field storage.\n */\nfunction decodeEmbeddingJson(row: LegacyEmbeddingRow): readonly number[] {\n let parsed: unknown;\n try {\n parsed = JSON.parse(row.embedding_json) as unknown;\n } catch (error) {\n throw new Error(\n `Failed to decode legacy embedding for ${row.node_kind}.${row.field_path} ` +\n `(graph ${row.graph_id}, node ${row.node_id}): not valid JSON.`,\n { cause: error },\n );\n }\n if (!Array.isArray(parsed) || parsed.length === 0) {\n throw new Error(\n `Legacy embedding for ${row.node_kind}.${row.field_path} ` +\n `(graph ${row.graph_id}, node ${row.node_id}) decoded to a non-array ` +\n `or empty value.`,\n );\n }\n for (const [index, value] of parsed.entries()) {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new TypeError(\n `Legacy embedding for ${row.node_kind}.${row.field_path} ` +\n `(graph ${row.graph_id}, node ${row.node_id}) has a non-finite ` +\n `value at index ${index}: ${String(value)}.`,\n );\n }\n }\n return parsed as readonly number[];\n}\n"]}