@nicia-ai/typegraph 0.34.0 → 0.35.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 (287) hide show
  1. package/dist/backend/postgres/index.cjs +29 -29
  2. package/dist/backend/postgres/index.d.cts +39 -7
  3. package/dist/backend/postgres/index.d.ts +39 -7
  4. package/dist/backend/postgres/index.js +16 -16
  5. package/dist/backend/postgres/pglite.cjs +21 -21
  6. package/dist/backend/postgres/pglite.d.cts +4 -4
  7. package/dist/backend/postgres/pglite.d.ts +4 -4
  8. package/dist/backend/postgres/pglite.js +16 -16
  9. package/dist/backend/sqlite/index.cjs +25 -26
  10. package/dist/backend/sqlite/index.d.cts +8 -8
  11. package/dist/backend/sqlite/index.d.ts +8 -8
  12. package/dist/backend/sqlite/index.js +13 -14
  13. package/dist/backend/sqlite/libsql.cjs +19 -19
  14. package/dist/backend/sqlite/libsql.d.cts +4 -4
  15. package/dist/backend/sqlite/libsql.d.ts +4 -4
  16. package/dist/backend/sqlite/libsql.js +15 -15
  17. package/dist/backend/sqlite/local.cjs +101 -21
  18. package/dist/backend/sqlite/local.cjs.map +1 -1
  19. package/dist/backend/sqlite/local.d.cts +95 -5
  20. package/dist/backend/sqlite/local.d.ts +95 -5
  21. package/dist/backend/sqlite/local.js +95 -16
  22. package/dist/backend/sqlite/local.js.map +1 -1
  23. package/dist/{chunk-ZV5N4DBG.js → chunk-3TWF3SH4.js} +300 -58
  24. package/dist/chunk-3TWF3SH4.js.map +1 -0
  25. package/dist/chunk-4JEZZJ6S.cjs +1271 -0
  26. package/dist/chunk-4JEZZJ6S.cjs.map +1 -0
  27. package/dist/{chunk-UNNPKQUG.cjs → chunk-4TOD4LBZ.cjs} +246 -155
  28. package/dist/chunk-4TOD4LBZ.cjs.map +1 -0
  29. package/dist/{chunk-QV245VMN.js → chunk-55MZDDZV.js} +100 -6
  30. package/dist/chunk-55MZDDZV.js.map +1 -0
  31. package/dist/{chunk-GQANNXXT.cjs → chunk-5A6FNS6N.cjs} +75 -20
  32. package/dist/chunk-5A6FNS6N.cjs.map +1 -0
  33. package/dist/{chunk-3Z6TW3CT.cjs → chunk-5AQIKK56.cjs} +65 -25
  34. package/dist/chunk-5AQIKK56.cjs.map +1 -0
  35. package/dist/{chunk-BVTWD66D.js → chunk-5SEGFTZX.js} +3 -3
  36. package/dist/{chunk-BVTWD66D.js.map → chunk-5SEGFTZX.js.map} +1 -1
  37. package/dist/{chunk-6GNSY7AV.js → chunk-6FR2MMS6.js} +7 -7
  38. package/dist/chunk-6FR2MMS6.js.map +1 -0
  39. package/dist/chunk-7YSP4V4R.cjs +69 -0
  40. package/dist/chunk-7YSP4V4R.cjs.map +1 -0
  41. package/dist/chunk-A42GCBGX.cjs +28 -0
  42. package/dist/chunk-A42GCBGX.cjs.map +1 -0
  43. package/dist/{chunk-RHZWOJVA.cjs → chunk-BLZDPRXT.cjs} +52 -4
  44. package/dist/chunk-BLZDPRXT.cjs.map +1 -0
  45. package/dist/chunk-BYPOGQWK.js +25 -0
  46. package/dist/chunk-BYPOGQWK.js.map +1 -0
  47. package/dist/{chunk-6HVOHZHS.cjs → chunk-CK5BVQOW.cjs} +213 -168
  48. package/dist/chunk-CK5BVQOW.cjs.map +1 -0
  49. package/dist/{chunk-JJRCLAUN.cjs → chunk-CTTSDJLY.cjs} +116 -10
  50. package/dist/chunk-CTTSDJLY.cjs.map +1 -0
  51. package/dist/chunk-CUHM5CWJ.cjs +12 -0
  52. package/dist/chunk-CUHM5CWJ.cjs.map +1 -0
  53. package/dist/{chunk-A7SZZFAG.js → chunk-CZQ3FO2Q.js} +409 -99
  54. package/dist/chunk-CZQ3FO2Q.js.map +1 -0
  55. package/dist/{chunk-2JXB3NYJ.cjs → chunk-D7ZEOS56.cjs} +25 -32
  56. package/dist/chunk-D7ZEOS56.cjs.map +1 -0
  57. package/dist/chunk-DFVLCOP6.js +10 -0
  58. package/dist/chunk-DFVLCOP6.js.map +1 -0
  59. package/dist/{chunk-UJLOZYKT.cjs → chunk-EM3CWPND.cjs} +441 -115
  60. package/dist/chunk-EM3CWPND.cjs.map +1 -0
  61. package/dist/chunk-EMF62TZG.cjs +1176 -0
  62. package/dist/chunk-EMF62TZG.cjs.map +1 -0
  63. package/dist/chunk-EOLERH7Y.cjs +40 -0
  64. package/dist/chunk-EOLERH7Y.cjs.map +1 -0
  65. package/dist/{chunk-TGJE22RM.cjs → chunk-FACJJWGF.cjs} +24 -6
  66. package/dist/chunk-FACJJWGF.cjs.map +1 -0
  67. package/dist/{chunk-HK5SATYM.cjs → chunk-FL472AMI.cjs} +16 -109
  68. package/dist/chunk-FL472AMI.cjs.map +1 -0
  69. package/dist/{chunk-WVC2Q2FD.cjs → chunk-FN35DLCN.cjs} +31 -9
  70. package/dist/chunk-FN35DLCN.cjs.map +1 -0
  71. package/dist/{chunk-KUTNI6SI.js → chunk-FPIZFYHE.js} +10 -18
  72. package/dist/chunk-FPIZFYHE.js.map +1 -0
  73. package/dist/{chunk-VCGO4V26.js → chunk-FRV5Q5IO.js} +64 -9
  74. package/dist/chunk-FRV5Q5IO.js.map +1 -0
  75. package/dist/{chunk-K5P5OZXS.js → chunk-G6Q5UM7U.js} +2 -2
  76. package/dist/{chunk-K5P5OZXS.js.map → chunk-G6Q5UM7U.js.map} +1 -1
  77. package/dist/chunk-GSQ6NPH6.cjs +100 -0
  78. package/dist/chunk-GSQ6NPH6.cjs.map +1 -0
  79. package/dist/chunk-GUR2FNB5.cjs +12 -0
  80. package/dist/{chunk-HMFK4BXR.cjs.map → chunk-GUR2FNB5.cjs.map} +1 -1
  81. package/dist/{chunk-JQGIPGVL.cjs → chunk-H7YNSMA7.cjs} +43 -2
  82. package/dist/chunk-H7YNSMA7.cjs.map +1 -0
  83. package/dist/{chunk-2MRAX3UE.js → chunk-I7ZUZKFD.js} +47 -4
  84. package/dist/chunk-I7ZUZKFD.js.map +1 -0
  85. package/dist/{chunk-3BRVBQQD.cjs → chunk-J7WFGBJR.cjs} +2445 -2367
  86. package/dist/chunk-J7WFGBJR.cjs.map +1 -0
  87. package/dist/{chunk-V3QNTB7Z.js → chunk-JBTOYDMN.js} +194 -114
  88. package/dist/chunk-JBTOYDMN.js.map +1 -0
  89. package/dist/{chunk-K2TGS3EN.js → chunk-K3PPLHY7.js} +138 -89
  90. package/dist/chunk-K3PPLHY7.js.map +1 -0
  91. package/dist/{chunk-Z5XBMDXU.js → chunk-KBGQIPRQ.js} +42 -3
  92. package/dist/chunk-KBGQIPRQ.js.map +1 -0
  93. package/dist/chunk-KMI7LYAF.js +1252 -0
  94. package/dist/chunk-KMI7LYAF.js.map +1 -0
  95. package/dist/{chunk-JIEJCTDS.cjs → chunk-LGEALRC6.cjs} +21 -4
  96. package/dist/chunk-LGEALRC6.cjs.map +1 -0
  97. package/dist/{chunk-TQOYM4LN.js → chunk-MP2JQKSG.js} +21 -5
  98. package/dist/chunk-MP2JQKSG.js.map +1 -0
  99. package/dist/{chunk-ZP5WHI4C.cjs → chunk-O7UN7OXA.cjs} +358 -116
  100. package/dist/chunk-O7UN7OXA.cjs.map +1 -0
  101. package/dist/chunk-OHMP6N2J.js +47 -0
  102. package/dist/chunk-OHMP6N2J.js.map +1 -0
  103. package/dist/{chunk-4DIBPQNJ.js → chunk-OR5ZA5WP.js} +135 -25
  104. package/dist/chunk-OR5ZA5WP.js.map +1 -0
  105. package/dist/{chunk-DEQFL35G.js → chunk-Q5TEXCTB.js} +61 -7
  106. package/dist/chunk-Q5TEXCTB.js.map +1 -0
  107. package/dist/chunk-QNKSQTKQ.js +1312 -0
  108. package/dist/chunk-QNKSQTKQ.js.map +1 -0
  109. package/dist/{chunk-ZURTTSCM.js → chunk-QOTI55H7.js} +6 -94
  110. package/dist/chunk-QOTI55H7.js.map +1 -0
  111. package/dist/{chunk-CHXTTSC6.js → chunk-QWEUYILR.js} +104 -5
  112. package/dist/chunk-QWEUYILR.js.map +1 -0
  113. package/dist/{chunk-LANHCOXB.js → chunk-RGP33ZJ5.js} +485 -83
  114. package/dist/chunk-RGP33ZJ5.js.map +1 -0
  115. package/dist/chunk-RGPG7EOJ.js +94 -0
  116. package/dist/chunk-RGPG7EOJ.js.map +1 -0
  117. package/dist/{chunk-G6SOJEDI.cjs → chunk-S55OV6PW.cjs} +15 -15
  118. package/dist/chunk-S55OV6PW.cjs.map +1 -0
  119. package/dist/{chunk-3E7SNSIA.cjs → chunk-SJDMVITW.cjs} +4 -4
  120. package/dist/{chunk-3E7SNSIA.cjs.map → chunk-SJDMVITW.cjs.map} +1 -1
  121. package/dist/{chunk-XLUNB2TZ.js → chunk-SNXVDZAJ.js} +3 -3
  122. package/dist/{chunk-XLUNB2TZ.js.map → chunk-SNXVDZAJ.js.map} +1 -1
  123. package/dist/{chunk-RBV7YCQD.js → chunk-T2WUSPDA.js} +49 -9
  124. package/dist/chunk-T2WUSPDA.js.map +1 -0
  125. package/dist/{chunk-KGC4LY5T.cjs → chunk-TCOCYN2P.cjs} +75 -21
  126. package/dist/chunk-TCOCYN2P.cjs.map +1 -0
  127. package/dist/{chunk-FLRCVI2G.cjs → chunk-TDXIBCGY.cjs} +2 -2
  128. package/dist/{chunk-FLRCVI2G.cjs.map → chunk-TDXIBCGY.cjs.map} +1 -1
  129. package/dist/{chunk-ZY4GXIVN.cjs → chunk-TEDRJXOG.cjs} +5 -5
  130. package/dist/{chunk-ZY4GXIVN.cjs.map → chunk-TEDRJXOG.cjs.map} +1 -1
  131. package/dist/{chunk-WLRIWYHQ.js → chunk-UES55P7G.js} +1863 -1785
  132. package/dist/chunk-UES55P7G.js.map +1 -0
  133. package/dist/{chunk-WL2SG7ZV.cjs → chunk-UMDVATGY.cjs} +6 -6
  134. package/dist/{chunk-WL2SG7ZV.cjs.map → chunk-UMDVATGY.cjs.map} +1 -1
  135. package/dist/chunk-UT3S4SEN.js +31 -0
  136. package/dist/chunk-UT3S4SEN.js.map +1 -0
  137. package/dist/{chunk-RRKQAKD6.cjs → chunk-UUT7UN2N.cjs} +149 -39
  138. package/dist/chunk-UUT7UN2N.cjs.map +1 -0
  139. package/dist/{chunk-SHLY4MCM.js → chunk-UZV3AZKF.js} +21 -3
  140. package/dist/chunk-UZV3AZKF.js.map +1 -0
  141. package/dist/{chunk-CYX2JTDG.js → chunk-VHMPG6UL.js} +29 -7
  142. package/dist/chunk-VHMPG6UL.js.map +1 -0
  143. package/dist/{chunk-T6SPUYLX.cjs → chunk-VPYHY3LJ.cjs} +116 -10
  144. package/dist/chunk-VPYHY3LJ.cjs.map +1 -0
  145. package/dist/{chunk-T46GR2VY.js → chunk-VSPCZAXF.js} +3 -3
  146. package/dist/{chunk-T46GR2VY.js.map → chunk-VSPCZAXF.js.map} +1 -1
  147. package/dist/{chunk-K34OPSJK.js → chunk-W63OVYY4.js} +3 -3
  148. package/dist/{chunk-K34OPSJK.js.map → chunk-W63OVYY4.js.map} +1 -1
  149. package/dist/{chunk-RY2VIWAM.js → chunk-WDBCBWC4.js} +355 -32
  150. package/dist/chunk-WDBCBWC4.js.map +1 -0
  151. package/dist/chunk-WJT7OU7E.cjs +1334 -0
  152. package/dist/chunk-WJT7OU7E.cjs.map +1 -0
  153. package/dist/{chunk-5IQIX7LU.cjs → chunk-XOX22WHL.cjs} +476 -163
  154. package/dist/chunk-XOX22WHL.cjs.map +1 -0
  155. package/dist/{ddl-BrmPg61z.d.ts → ddl-C2rZ-Aen.d.ts} +4 -4
  156. package/dist/{ddl-j1-sH6lE.d.cts → ddl-CZz7a0E8.d.cts} +4 -4
  157. package/dist/{extension-types-YGFJPrzK.d.cts → extension-types-ixRpJVUp.d.cts} +24 -1
  158. package/dist/{extension-types-YGFJPrzK.d.ts → extension-types-ixRpJVUp.d.ts} +24 -1
  159. package/dist/{types-DkNnF-7K.d.cts → fulltext-strategy-B57yvC5Q.d.ts} +2562 -2133
  160. package/dist/{types-D1Sqeyxy.d.ts → fulltext-strategy-CDkSSYhq.d.cts} +2562 -2133
  161. package/dist/graph-extension/index.cjs +20 -19
  162. package/dist/graph-extension/index.d.cts +4 -4
  163. package/dist/graph-extension/index.d.ts +4 -4
  164. package/dist/graph-extension/index.js +5 -4
  165. package/dist/graph-merge/index.cjs +255 -164
  166. package/dist/graph-merge/index.cjs.map +1 -1
  167. package/dist/graph-merge/index.d.cts +63 -33
  168. package/dist/graph-merge/index.d.ts +63 -33
  169. package/dist/graph-merge/index.js +135 -44
  170. package/dist/graph-merge/index.js.map +1 -1
  171. package/dist/{index-DGX6D9j1.d.ts → index-6CSUAq-x.d.ts} +234 -93
  172. package/dist/{index-SEvUHDA6.d.cts → index-Bks_3HHK.d.cts} +234 -93
  173. package/dist/index.cjs +208 -188
  174. package/dist/index.d.cts +11 -11
  175. package/dist/index.d.ts +11 -11
  176. package/dist/index.js +33 -33
  177. package/dist/indexes/index.cjs +19 -20
  178. package/dist/indexes/index.d.cts +5 -5
  179. package/dist/indexes/index.d.ts +5 -5
  180. package/dist/indexes/index.js +10 -11
  181. package/dist/interchange/index.cjs +47 -26
  182. package/dist/interchange/index.d.cts +126 -12
  183. package/dist/interchange/index.d.ts +126 -12
  184. package/dist/interchange/index.js +14 -13
  185. package/dist/{manager-ms9cKdc6.d.cts → manager-DwQi8eV0.d.cts} +9 -2
  186. package/dist/{manager-BZUeN_BU.d.ts → manager-ejUCB52T.d.ts} +9 -2
  187. package/dist/{materialize-indexes-D20xNluI.d.cts → materialize-indexes-B4e9360H.d.cts} +20 -4
  188. package/dist/{materialize-indexes-CAkIYFV-.d.ts → materialize-indexes-te9TPMMJ.d.ts} +20 -4
  189. package/dist/{postgres-BhpxGMC5.d.cts → postgres-CfEqsRMp.d.cts} +152 -1
  190. package/dist/{postgres-CWHLwNl1.d.ts → postgres-DQ5R6rzV.d.ts} +152 -1
  191. package/dist/profiler/index.cjs +11 -11
  192. package/dist/profiler/index.d.cts +7 -7
  193. package/dist/profiler/index.d.ts +7 -7
  194. package/dist/profiler/index.js +4 -4
  195. package/dist/provenance/index.cjs +40 -41
  196. package/dist/provenance/index.cjs.map +1 -1
  197. package/dist/provenance/index.d.cts +5 -5
  198. package/dist/provenance/index.d.ts +5 -5
  199. package/dist/provenance/index.js +11 -12
  200. package/dist/provenance/index.js.map +1 -1
  201. package/dist/schema/index.cjs +53 -40
  202. package/dist/schema/index.cjs.map +1 -1
  203. package/dist/schema/index.d.cts +57 -57
  204. package/dist/schema/index.d.ts +57 -57
  205. package/dist/schema/index.js +28 -15
  206. package/dist/schema/index.js.map +1 -1
  207. package/dist/{sqlite-XrDxNaa7.d.cts → sqlite-D7zBinNR.d.cts} +92 -1
  208. package/dist/{sqlite-CGu5SLsw.d.ts → sqlite-DvQndLky.d.ts} +92 -1
  209. package/dist/{store-view-D09po4H6.d.cts → store-view-BSpqvAxK.d.cts} +415 -44
  210. package/dist/{store-view-BlgnhEYf.d.ts → store-view-CKbHFRnn.d.ts} +415 -44
  211. package/dist/{types-DiE1AO7p.d.cts → types-Bv9DcS_E.d.cts} +2 -2
  212. package/dist/{types-B1TbZJYS.d.ts → types-CoxuV7EJ.d.ts} +2 -2
  213. package/dist/{where-DKjuofPr.d.cts → where-7RKFOsXt.d.ts} +2 -2
  214. package/dist/{where-DrUIIWHb.d.ts → where-DdMIXOtH.d.cts} +2 -2
  215. package/package.json +14 -13
  216. package/dist/chunk-2EBMPJBO.js +0 -16
  217. package/dist/chunk-2EBMPJBO.js.map +0 -1
  218. package/dist/chunk-2JXB3NYJ.cjs.map +0 -1
  219. package/dist/chunk-2MRAX3UE.js.map +0 -1
  220. package/dist/chunk-3BRVBQQD.cjs.map +0 -1
  221. package/dist/chunk-3EUKJEQ3.js +0 -77
  222. package/dist/chunk-3EUKJEQ3.js.map +0 -1
  223. package/dist/chunk-3Z6TW3CT.cjs.map +0 -1
  224. package/dist/chunk-4DIBPQNJ.js.map +0 -1
  225. package/dist/chunk-4S2FXGBJ.js +0 -9
  226. package/dist/chunk-4S2FXGBJ.js.map +0 -1
  227. package/dist/chunk-5IQIX7LU.cjs.map +0 -1
  228. package/dist/chunk-6GNSY7AV.js.map +0 -1
  229. package/dist/chunk-6HVOHZHS.cjs.map +0 -1
  230. package/dist/chunk-6SCVW4AS.js +0 -20
  231. package/dist/chunk-6SCVW4AS.js.map +0 -1
  232. package/dist/chunk-A7SZZFAG.js.map +0 -1
  233. package/dist/chunk-CHXTTSC6.js.map +0 -1
  234. package/dist/chunk-CYX2JTDG.js.map +0 -1
  235. package/dist/chunk-DEQFL35G.js.map +0 -1
  236. package/dist/chunk-G6SOJEDI.cjs.map +0 -1
  237. package/dist/chunk-GQANNXXT.cjs.map +0 -1
  238. package/dist/chunk-GZCNZ7QW.js +0 -24
  239. package/dist/chunk-GZCNZ7QW.js.map +0 -1
  240. package/dist/chunk-HK5SATYM.cjs.map +0 -1
  241. package/dist/chunk-HMFK4BXR.cjs +0 -12
  242. package/dist/chunk-HTGDWIDE.cjs +0 -89
  243. package/dist/chunk-HTGDWIDE.cjs.map +0 -1
  244. package/dist/chunk-JIEJCTDS.cjs.map +0 -1
  245. package/dist/chunk-JJRCLAUN.cjs.map +0 -1
  246. package/dist/chunk-JQGIPGVL.cjs.map +0 -1
  247. package/dist/chunk-K2TGS3EN.js.map +0 -1
  248. package/dist/chunk-KGC4LY5T.cjs.map +0 -1
  249. package/dist/chunk-KNHYNQQ3.cjs +0 -663
  250. package/dist/chunk-KNHYNQQ3.cjs.map +0 -1
  251. package/dist/chunk-KUTNI6SI.js.map +0 -1
  252. package/dist/chunk-LANHCOXB.js.map +0 -1
  253. package/dist/chunk-N6WTUSBV.cjs +0 -23
  254. package/dist/chunk-N6WTUSBV.cjs.map +0 -1
  255. package/dist/chunk-NAUA4PW5.cjs +0 -28
  256. package/dist/chunk-NAUA4PW5.cjs.map +0 -1
  257. package/dist/chunk-QV245VMN.js.map +0 -1
  258. package/dist/chunk-RBV7YCQD.js.map +0 -1
  259. package/dist/chunk-RHZWOJVA.cjs.map +0 -1
  260. package/dist/chunk-RRKQAKD6.cjs.map +0 -1
  261. package/dist/chunk-RY2VIWAM.js.map +0 -1
  262. package/dist/chunk-SHLY4MCM.js.map +0 -1
  263. package/dist/chunk-T2DWPQNE.js +0 -649
  264. package/dist/chunk-T2DWPQNE.js.map +0 -1
  265. package/dist/chunk-T6SPUYLX.cjs.map +0 -1
  266. package/dist/chunk-TGJE22RM.cjs.map +0 -1
  267. package/dist/chunk-TOTPVGOG.cjs +0 -774
  268. package/dist/chunk-TOTPVGOG.cjs.map +0 -1
  269. package/dist/chunk-TQOYM4LN.js.map +0 -1
  270. package/dist/chunk-UJLOZYKT.cjs.map +0 -1
  271. package/dist/chunk-UNNPKQUG.cjs.map +0 -1
  272. package/dist/chunk-V3QNTB7Z.js.map +0 -1
  273. package/dist/chunk-VCGO4V26.js.map +0 -1
  274. package/dist/chunk-WLRIWYHQ.js.map +0 -1
  275. package/dist/chunk-WVC2Q2FD.cjs.map +0 -1
  276. package/dist/chunk-XXVEULWX.js +0 -39
  277. package/dist/chunk-XXVEULWX.js.map +0 -1
  278. package/dist/chunk-YAZE7QZR.cjs +0 -32
  279. package/dist/chunk-YAZE7QZR.cjs.map +0 -1
  280. package/dist/chunk-YC6PWTHY.cjs +0 -44
  281. package/dist/chunk-YC6PWTHY.cjs.map +0 -1
  282. package/dist/chunk-Z5HBYM7U.cjs +0 -11
  283. package/dist/chunk-Z5HBYM7U.cjs.map +0 -1
  284. package/dist/chunk-Z5XBMDXU.js.map +0 -1
  285. package/dist/chunk-ZP5WHI4C.cjs.map +0 -1
  286. package/dist/chunk-ZURTTSCM.js.map +0 -1
  287. package/dist/chunk-ZV5N4DBG.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/interchange/types.ts","../src/interchange/export.ts","../src/interchange/import.ts"],"names":["z","isCanonicalIsoDate","getNodeKinds","getEdgeKinds","nowIso","runInWriteTransaction","UniquenessError","validateOptionalCanonicalIsoDate","isLiveNodeRow","applyNodeUpdate","checkUniquenessConstraints","applyNodeInsertSideEffects","validateEdgeEndpoints","result"],"mappings":"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","file":"chunk-KNHYNQQ3.cjs","sourcesContent":["/**\n * Graph interchange format types.\n *\n * Defines Zod schemas for importing and exporting graph data.\n * The format is designed to be:\n * - JSON-serializable for API transport\n * - Validated via Zod at runtime\n * - Exportable as JSON Schema for LLM/API documentation\n */\nimport { z } from \"zod\";\n\nimport { isCanonicalIsoDate } from \"../utils/date\";\n\n// ============================================================\n// Format Version\n// ============================================================\n\n/**\n * Current interchange format version.\n * Increment for breaking changes to the format.\n */\nexport const FORMAT_VERSION = \"1.0\" as const;\n\n/**\n * A stored validity-window timestamp (`validFrom` / `validTo`). Must be a\n * canonical fixed-width UTC ISO-8601 string (`YYYY-MM-DDTHH:mm:ss.sssZ`) — the\n * same contract `create` / `update` enforce — because temporal filters compare\n * it as text against the `asOf` read coordinate, and a variable-width value\n * (date-only, offset, missing/variable milliseconds) would mis-sort and\n * silently include or exclude the wrong rows. Convert non-canonical inputs with\n * `new Date(value).toISOString()`.\n */\nconst ValidityTimestampSchema = z.iso\n .datetime()\n .refine((value) => isCanonicalIsoDate(value), {\n message:\n \"Expected canonical UTC ISO 8601 (YYYY-MM-DDTHH:mm:ss.sssZ); convert with new Date(value).toISOString().\",\n });\n\n// ============================================================\n// Node Interchange\n// ============================================================\n\n/**\n * Interchange format for a node.\n *\n * Properties are stored as a record to allow schema-agnostic transport.\n * Validation against the actual schema happens during import.\n */\nexport const InterchangeNodeSchema = z.object({\n kind: z.string().min(1),\n id: z.string().min(1),\n properties: z.record(z.string(), z.unknown()),\n validFrom: ValidityTimestampSchema.optional(),\n validTo: ValidityTimestampSchema.optional(),\n meta: z\n .object({\n version: z.number().int().positive().optional(),\n createdAt: z.iso.datetime().optional(),\n updatedAt: z.iso.datetime().optional(),\n })\n .optional(),\n});\n\nexport type InterchangeNode = z.infer<typeof InterchangeNodeSchema>;\n\n// ============================================================\n// Edge Interchange\n// ============================================================\n\n/**\n * Interchange format for an edge.\n *\n * Endpoint references are objects with kind and id, rather than\n * composite strings, for clarity and type safety.\n */\nexport const InterchangeEdgeSchema = z.object({\n kind: z.string().min(1),\n id: z.string().min(1),\n from: z.object({\n kind: z.string().min(1),\n id: z.string().min(1),\n }),\n to: z.object({\n kind: z.string().min(1),\n id: z.string().min(1),\n }),\n properties: z.record(z.string(), z.unknown()).default({}),\n validFrom: ValidityTimestampSchema.optional(),\n validTo: ValidityTimestampSchema.optional(),\n meta: z\n .object({\n createdAt: z.iso.datetime().optional(),\n updatedAt: z.iso.datetime().optional(),\n })\n .optional(),\n});\n\nexport type InterchangeEdge = z.infer<typeof InterchangeEdgeSchema>;\n\n// ============================================================\n// Import Configuration\n// ============================================================\n\n/**\n * Strategy for handling conflicts when a node/edge ID already exists.\n *\n * - `skip`: Keep existing, ignore incoming\n * - `update`: Merge incoming properties into existing\n * - `error`: Throw an error on conflict\n */\nexport const ConflictStrategySchema = z.enum([\"skip\", \"update\", \"error\"]);\nexport type ConflictStrategy = z.infer<typeof ConflictStrategySchema>;\n\n/**\n * Strategy for handling properties not defined in the schema.\n *\n * - `error`: Throw a validation error\n * - `strip`: Remove unknown properties silently\n * - `allow`: Pass through to storage (relies on backend behavior)\n */\nexport const UnknownPropertyStrategySchema = z.enum([\n \"error\",\n \"strip\",\n \"allow\",\n]);\nexport type UnknownPropertyStrategy = z.infer<\n typeof UnknownPropertyStrategySchema\n>;\n\n/**\n * Options for importing graph data.\n */\nexport const ImportOptionsSchema = z.object({\n /** How to handle existing nodes/edges with the same ID */\n onConflict: ConflictStrategySchema,\n /** How to handle properties not in the schema */\n onUnknownProperty: UnknownPropertyStrategySchema.default(\"error\"),\n /** Whether to validate that edge endpoints exist */\n validateReferences: z.boolean().default(true),\n /** Number of items to process in each batch */\n batchSize: z.number().int().positive().default(100),\n});\n\nexport type ImportOptions = z.infer<typeof ImportOptionsSchema>;\n\n// ============================================================\n// Graph Data Source\n// ============================================================\n\n/**\n * Source metadata for graph data.\n *\n * Uses discriminated union to capture different origin types:\n * - `typegraph-export`: Exported from a TypeGraph store\n * - `external`: From a third-party system\n */\nexport const GraphDataSourceSchema = z.discriminatedUnion(\"type\", [\n z.object({\n type: z.literal(\"typegraph-export\"),\n graphId: z.string(),\n schemaVersion: z.number().int().positive(),\n }),\n z.object({\n type: z.literal(\"external\"),\n description: z.string().optional(),\n }),\n]);\n\nexport type GraphDataSource = z.infer<typeof GraphDataSourceSchema>;\n\n// ============================================================\n// Graph Data Envelope\n// ============================================================\n\n/**\n * Complete graph data interchange format.\n *\n * The envelope contains metadata about the data source and format version,\n * plus arrays of nodes and edges to import.\n */\nexport const GraphDataSchema = z.object({\n formatVersion: z.literal(FORMAT_VERSION),\n exportedAt: z.iso.datetime(),\n source: GraphDataSourceSchema,\n nodes: z.array(InterchangeNodeSchema),\n edges: z.array(InterchangeEdgeSchema),\n});\n\nexport type GraphData = z.infer<typeof GraphDataSchema>;\n\n// ============================================================\n// Import Result\n// ============================================================\n\n/**\n * An error that occurred during import.\n */\nexport const ImportErrorSchema = z.object({\n entityType: z.enum([\"node\", \"edge\"]),\n kind: z.string(),\n id: z.string(),\n error: z.string(),\n});\n\nexport type ImportError = z.infer<typeof ImportErrorSchema>;\n\n/**\n * Result of an import operation.\n *\n * Contains counts of created/updated/skipped entities and any errors.\n */\nexport const ImportResultSchema = z.object({\n success: z.boolean(),\n nodes: z.object({\n created: z.number().int().nonnegative(),\n updated: z.number().int().nonnegative(),\n skipped: z.number().int().nonnegative(),\n }),\n edges: z.object({\n created: z.number().int().nonnegative(),\n updated: z.number().int().nonnegative(),\n skipped: z.number().int().nonnegative(),\n }),\n errors: z.array(ImportErrorSchema),\n});\n\nexport type ImportResult = z.infer<typeof ImportResultSchema>;\n\n// ============================================================\n// Export Options\n// ============================================================\n\n/**\n * Options for exporting graph data.\n */\nexport const ExportOptionsSchema = z.object({\n /** Filter to specific node kinds (undefined = all) */\n nodeKinds: z.array(z.string()).optional(),\n /** Filter to specific edge kinds (undefined = all) */\n edgeKinds: z.array(z.string()).optional(),\n /** Include temporal fields (validFrom, validTo) */\n includeTemporal: z.boolean().default(false),\n /** Include metadata (version, timestamps) */\n includeMeta: z.boolean().default(false),\n /** Include soft-deleted records */\n includeDeleted: z.boolean().default(false),\n});\n\n/** Export options with defaults applied (output type) */\nexport type ExportOptions = z.infer<typeof ExportOptionsSchema>;\n\n/** Export options as accepted by exportGraph (input type with optional defaults) */\nexport type ExportOptionsInput = z.input<typeof ExportOptionsSchema>;\n","/**\n * Graph data export functionality.\n *\n * Exports nodes and edges from a store to the interchange format.\n */\nimport { type GraphBackend } from \"../backend/types\";\nimport {\n getEdgeKinds,\n getNodeKinds,\n type GraphDef,\n} from \"../core/define-graph\";\nimport { type Store } from \"../store/store\";\nimport { nowIso } from \"../utils/date\";\nimport {\n type ExportOptionsInput,\n FORMAT_VERSION,\n type GraphData,\n type InterchangeEdge,\n type InterchangeNode,\n} from \"./types\";\n\n// ============================================================\n// Export Function\n// ============================================================\n\n/**\n * Export graph data from a store.\n *\n * @param store - The graph store to export from\n * @param options - Export configuration\n * @returns Graph data in interchange format\n *\n * @example\n * ```typescript\n * const data = await exportGraph(store, {\n * nodeKinds: [\"Person\", \"Organization\"],\n * includeMeta: true,\n * });\n *\n * // Write to file\n * await fs.writeFile(\"backup.json\", JSON.stringify(data, null, 2));\n * ```\n */\nexport async function exportGraph<G extends GraphDef>(\n store: Store<G>,\n options?: ExportOptionsInput,\n): Promise<GraphData> {\n const options_ = {\n nodeKinds: options?.nodeKinds,\n edgeKinds: options?.edgeKinds,\n includeTemporal: options?.includeTemporal ?? false,\n includeMeta: options?.includeMeta ?? false,\n includeDeleted: options?.includeDeleted ?? false,\n };\n\n const graph = store.graph;\n const graphId = store.graphId;\n const backend = store.backend;\n\n // Determine which kinds to export\n const nodeKindsToExport = options_.nodeKinds ?? getNodeKinds(graph);\n const edgeKindsToExport = options_.edgeKinds ?? getEdgeKinds(graph);\n\n // Export nodes\n const nodes: InterchangeNode[] = [];\n for (const kind of nodeKindsToExport) {\n const kindNodes = await exportNodesOfKind(backend, graphId, kind, options_);\n nodes.push(...kindNodes);\n }\n\n // Export edges\n const edges: InterchangeEdge[] = [];\n for (const kind of edgeKindsToExport) {\n const kindEdges = await exportEdgesOfKind(backend, graphId, kind, options_);\n edges.push(...kindEdges);\n }\n\n // Get current schema version\n const schemaVersion = await backend.getActiveSchema(graphId);\n\n return {\n formatVersion: FORMAT_VERSION,\n exportedAt: nowIso(),\n source: {\n type: \"typegraph-export\",\n graphId,\n schemaVersion: schemaVersion?.version ?? 1,\n },\n nodes,\n edges,\n };\n}\n\n// ============================================================\n// Node Export\n// ============================================================\n\ntype ExportOptions_ = Readonly<{\n includeTemporal: boolean;\n includeMeta: boolean;\n includeDeleted: boolean;\n}>;\n\nasync function exportNodesOfKind(\n backend: GraphBackend,\n graphId: string,\n kind: string,\n options: ExportOptions_,\n): Promise<InterchangeNode[]> {\n const rows = await backend.findNodesByKind({\n graphId,\n kind,\n excludeDeleted: !options.includeDeleted,\n });\n\n return rows.map((row) => {\n const node: InterchangeNode = {\n kind: row.kind,\n id: row.id,\n properties: JSON.parse(row.props) as Record<string, unknown>,\n };\n\n if (options.includeTemporal) {\n if (row.valid_from) {\n (node as { validFrom?: string }).validFrom = row.valid_from;\n }\n if (row.valid_to) {\n (node as { validTo?: string }).validTo = row.valid_to;\n }\n }\n\n if (options.includeMeta) {\n (node as { meta?: InterchangeNode[\"meta\"] }).meta = {\n version: row.version,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n return node;\n });\n}\n\n// ============================================================\n// Edge Export\n// ============================================================\n\nasync function exportEdgesOfKind(\n backend: GraphBackend,\n graphId: string,\n kind: string,\n options: ExportOptions_,\n): Promise<InterchangeEdge[]> {\n const rows = await backend.findEdgesByKind({\n graphId,\n kind,\n excludeDeleted: !options.includeDeleted,\n });\n\n return rows.map((row) => {\n const edge: InterchangeEdge = {\n kind: row.kind,\n id: row.id,\n from: {\n kind: row.from_kind,\n id: row.from_id,\n },\n to: {\n kind: row.to_kind,\n id: row.to_id,\n },\n properties: JSON.parse(row.props) as Record<string, unknown>,\n };\n\n if (options.includeTemporal) {\n if (row.valid_from) {\n (edge as { validFrom?: string }).validFrom = row.valid_from;\n }\n if (row.valid_to) {\n (edge as { validTo?: string }).validTo = row.valid_to;\n }\n }\n\n if (options.includeMeta) {\n (edge as { meta?: InterchangeEdge[\"meta\"] }).meta = {\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n return edge;\n });\n}\n","/**\n * Graph data import functionality.\n *\n * Imports nodes and edges from the interchange format into a store,\n * with configurable conflict resolution and validation.\n */\nimport type { z } from \"zod\";\n\nimport {\n type GraphBackend,\n isLiveNodeRow,\n type TransactionBackend,\n} from \"../backend/types\";\nimport { validateEdgeEndpoints } from \"../constraints\";\nimport {\n getEdgeKinds,\n getNodeKinds,\n type GraphDef,\n} from \"../core/define-graph\";\nimport { type EdgeRegistration, type NodeRegistration } from \"../core/types\";\nimport { UniquenessError } from \"../errors\";\nimport { type KindRegistry } from \"../registry/kind-registry\";\nimport {\n applyNodeInsertSideEffects,\n applyNodeUpdate,\n} from \"../store/operations/node-write-pipeline\";\nimport { runInWriteTransaction } from \"../store/operations/write-transaction\";\nimport { type GraphWriteLock } from \"../store/recorded-capture/clock\";\nimport { type Store } from \"../store/store\";\nimport { checkUniquenessConstraints } from \"../store/uniqueness\";\nimport { validateOptionalCanonicalIsoDate } from \"../utils/date\";\nimport {\n type GraphData,\n type ImportError,\n type ImportOptions,\n type ImportResult,\n type InterchangeEdge,\n type InterchangeNode,\n type UnknownPropertyStrategy,\n} from \"./types\";\n\n// ============================================================\n// Import Function\n// ============================================================\n\n/**\n * Import graph data into a store.\n *\n * Nodes are imported first to satisfy edge reference validation.\n * The import runs within a transaction for atomicity when supported.\n *\n * @param store - The graph store to import into\n * @param data - Graph data in interchange format\n * @param options - Import configuration\n * @returns Import statistics and any errors\n *\n * @example\n * ```typescript\n * const result = await importGraph(store, data, {\n * onConflict: \"update\",\n * onUnknownProperty: \"strip\",\n * });\n *\n * console.log(`Created ${result.nodes.created} nodes`);\n * ```\n */\nexport async function importGraph<G extends GraphDef>(\n store: Store<G>,\n data: GraphData,\n options: ImportOptions,\n): Promise<ImportResult> {\n const result: ImportResult = {\n success: true,\n nodes: { created: 0, updated: 0, skipped: 0 },\n edges: { created: 0, updated: 0, skipped: 0 },\n errors: [],\n };\n\n const errors: ImportError[] = [];\n const graph = store.graph;\n const graphId = store.graphId;\n const backend = store.backend;\n const registry = store.registry;\n\n // Build lookup maps for schema validation\n const nodeSchemas = buildNodeSchemaMap(graph);\n const edgeSchemas = buildEdgeSchemaMap(graph);\n\n // Track imported node IDs for reference validation\n const importedNodeIds = new Set<string>();\n\n // One transaction on a transactional backend; runs directly otherwise, with\n // the per-graph write lock taken before any row work — see\n // runInWriteTransaction for the shared lock-before-rows contract every\n // writer follows.\n await runInWriteTransaction(store, backend, async (target, lock) => {\n await processNodes(\n target,\n graphId,\n registry,\n data.nodes,\n nodeSchemas,\n options,\n result,\n errors,\n importedNodeIds,\n lock,\n );\n await processEdges(\n target,\n graphId,\n registry,\n data.edges,\n edgeSchemas,\n nodeSchemas,\n options,\n result,\n errors,\n importedNodeIds,\n );\n });\n\n return {\n ...result,\n success: errors.length === 0,\n errors,\n };\n}\n\n// ============================================================\n// Schema Maps\n// ============================================================\n\ntype NodeSchemaEntry = Readonly<{\n registration: NodeRegistration;\n schema: z.ZodObject<z.ZodRawShape>;\n}>;\n\ntype EdgeSchemaEntry = Readonly<{\n registration: EdgeRegistration;\n schema: z.ZodObject<z.ZodRawShape>;\n}>;\n\nfunction buildNodeSchemaMap(\n graph: GraphDef,\n): ReadonlyMap<string, NodeSchemaEntry> {\n const map = new Map<string, NodeSchemaEntry>();\n\n for (const kindName of getNodeKinds(graph)) {\n const registration = graph.nodes[kindName] as NodeRegistration;\n map.set(kindName, {\n registration,\n schema: registration.type.schema,\n });\n }\n\n return map;\n}\n\nfunction buildEdgeSchemaMap(\n graph: GraphDef,\n): ReadonlyMap<string, EdgeSchemaEntry> {\n const map = new Map<string, EdgeSchemaEntry>();\n\n for (const kindName of getEdgeKinds(graph)) {\n const registration = graph.edges[kindName] as EdgeRegistration;\n map.set(kindName, {\n registration,\n schema: registration.type.schema,\n });\n }\n\n return map;\n}\n\n// ============================================================\n// Node Processing\n// ============================================================\n\nasync function processNodes(\n backend: GraphBackend | TransactionBackend,\n graphId: string,\n registry: KindRegistry,\n nodes: readonly InterchangeNode[],\n schemas: ReadonlyMap<string, NodeSchemaEntry>,\n options: ImportOptions,\n result: ImportResult,\n errors: ImportError[],\n importedNodeIds: Set<string>,\n lock: GraphWriteLock,\n): Promise<void> {\n const batchSize = options.batchSize;\n\n for (let index = 0; index < nodes.length; index += batchSize) {\n const batch = nodes.slice(index, index + batchSize);\n\n for (const node of batch) {\n const importResult = await processNode(\n backend,\n graphId,\n registry,\n node,\n schemas,\n options,\n lock,\n );\n\n switch (importResult.status) {\n case \"created\": {\n result.nodes.created++;\n importedNodeIds.add(makeNodeKey(node.kind, node.id));\n break;\n }\n case \"updated\": {\n result.nodes.updated++;\n importedNodeIds.add(makeNodeKey(node.kind, node.id));\n break;\n }\n case \"skipped\": {\n result.nodes.skipped++;\n // A live skipped row is still a valid edge endpoint; a tombstone\n // is not.\n if (importResult.liveTarget) {\n importedNodeIds.add(makeNodeKey(node.kind, node.id));\n }\n break;\n }\n case \"error\": {\n errors.push({\n entityType: \"node\",\n kind: node.kind,\n id: node.id,\n error: importResult.error,\n });\n break;\n }\n }\n }\n }\n}\n\ntype ProcessResult =\n | { status: \"created\" }\n | { status: \"updated\" }\n /**\n * `liveTarget` distinguishes \"skipped because a LIVE row already exists\"\n * (a valid edge endpoint) from \"skipped because the row is a tombstone\"\n * (which must NOT be recorded as available — a live edge pointing at a\n * soft-deleted node violates the endpoint-liveness invariant the\n * collection API enforces).\n */\n | { status: \"skipped\"; liveTarget: boolean }\n | { status: \"error\"; error: string };\n\ntype UniquenessGuardResult<T> =\n | Readonly<{ ok: true; value: T }>\n | Readonly<{ ok: false; error: string }>;\n\n/**\n * Runs `fn` and reports a `UniquenessError` as a per-row result instead of\n * letting it abort the whole import — the same recovery both the node\n * uniqueness pre-check and the update path need. Any other error still\n * propagates.\n */\nasync function catchUniquenessError<T>(\n fn: () => Promise<T>,\n): Promise<UniquenessGuardResult<T>> {\n try {\n return { ok: true, value: await fn() };\n } catch (error) {\n if (error instanceof UniquenessError) {\n return { ok: false, error: error.message };\n }\n throw error;\n }\n}\n\n/**\n * Validates an entity's validity-window timestamps against the canonical\n * fixed-width UTC ISO-8601 contract that `create` / `update` enforce, so no\n * import write path can persist a non-canonical `valid_from` / `valid_to` that\n * later mis-sorts as text against an `asOf` read coordinate. The interchange\n * schema enforces the same contract at the parse boundary, but `importGraph`\n * accepts a pre-typed `GraphData` and does not re-parse it, so this is the\n * guarantee for callers that bypass the schema. Returns a per-row error message\n * (recorded in the import result) instead of throwing, so one malformed row\n * does not abort the whole import.\n */\nfunction validateValidityWindow(\n entity: Readonly<{\n validFrom?: string | undefined;\n validTo?: string | undefined;\n }>,\n): string | undefined {\n try {\n validateOptionalCanonicalIsoDate(entity.validFrom, \"validFrom\");\n validateOptionalCanonicalIsoDate(entity.validTo, \"validTo\");\n return undefined;\n } catch (error) {\n return error instanceof Error ? error.message : String(error);\n }\n}\n\nasync function processNode(\n backend: GraphBackend | TransactionBackend,\n graphId: string,\n registry: KindRegistry,\n node: InterchangeNode,\n schemas: ReadonlyMap<string, NodeSchemaEntry>,\n options: ImportOptions,\n lock: GraphWriteLock,\n): Promise<ProcessResult> {\n // Validate kind exists\n const schemaEntry = schemas.get(node.kind);\n if (!schemaEntry) {\n return { status: \"error\", error: `Unknown node kind: ${node.kind}` };\n }\n\n // Validate and transform properties\n const propsResult = validateProperties(\n node.properties,\n schemaEntry.schema,\n options.onUnknownProperty,\n );\n\n if (!propsResult.success) {\n return { status: \"error\", error: propsResult.error };\n }\n\n const validityError = validateValidityWindow(node);\n if (validityError !== undefined) {\n return { status: \"error\", error: validityError };\n }\n\n const { registration } = schemaEntry;\n const uniqueConstraints = registration.unique ?? [];\n const writeContext = { graphId, registry, lock };\n\n // Check if node already exists\n const existing = await backend.getNode(graphId, node.kind, node.id);\n\n if (existing) {\n switch (options.onConflict) {\n case \"skip\": {\n return { status: \"skipped\", liveTarget: isLiveNodeRow(existing) };\n }\n case \"error\": {\n return {\n status: \"error\",\n error: `Node already exists: ${node.kind}:${node.id}`,\n };\n }\n case \"update\": {\n if (!isLiveNodeRow(existing)) {\n // A soft-deleted node is not updatable: import never resurrects a\n // tombstone, and running the live-row update pipeline here would\n // recreate uniqueness/embedding/fulltext rows for a node that\n // stays invisible — a uniqueness reservation held by a tombstoned\n // node would block live creates of the same value.\n return { status: \"skipped\", liveTarget: false };\n }\n // Route through the shared write step so the update maintains\n // uniqueness entries, embeddings, and fulltext — the collection API's\n // integrity, which a raw backend.updateNode would skip. A uniqueness\n // conflict is reported per-row (updateUniquenessEntries throws before\n // the row is written, so no partial write escapes).\n const updateResult = await catchUniquenessError(() =>\n applyNodeUpdate(\n writeContext,\n {\n existing,\n schema: registration.type.schema,\n validatedProps: propsResult.data,\n uniqueConstraints,\n ...(node.validTo !== undefined && { validTo: node.validTo }),\n },\n backend,\n ),\n );\n if (!updateResult.ok) {\n return { status: \"error\", error: updateResult.error };\n }\n return { status: \"updated\" };\n }\n }\n }\n\n // Create new node. Pre-check uniqueness (as the collection create does) so a\n // conflict is a per-row error rather than an orphaned node row, then apply the\n // integrity side effects the raw backend.insertNode would otherwise bypass.\n const uniquenessResult = await catchUniquenessError(() =>\n checkUniquenessConstraints(\n { graphId, registry, backend },\n node.kind,\n node.id,\n propsResult.data,\n uniqueConstraints,\n ),\n );\n if (!uniquenessResult.ok) {\n return { status: \"error\", error: uniquenessResult.error };\n }\n\n await backend.insertNode({\n graphId,\n kind: node.kind,\n id: node.id,\n props: propsResult.data,\n ...(node.validFrom !== undefined && { validFrom: node.validFrom }),\n ...(node.validTo !== undefined && { validTo: node.validTo }),\n });\n await applyNodeInsertSideEffects(\n writeContext,\n {\n kind: node.kind,\n id: node.id,\n schema: registration.type.schema,\n props: propsResult.data,\n uniqueConstraints,\n },\n backend,\n );\n\n return { status: \"created\" };\n}\n\n// ============================================================\n// Edge Processing\n// ============================================================\n\nasync function processEdges(\n backend: GraphBackend | TransactionBackend,\n graphId: string,\n registry: KindRegistry,\n edges: readonly InterchangeEdge[],\n edgeSchemas: ReadonlyMap<string, EdgeSchemaEntry>,\n nodeSchemas: ReadonlyMap<string, NodeSchemaEntry>,\n options: ImportOptions,\n result: ImportResult,\n errors: ImportError[],\n importedNodeIds: Set<string>,\n): Promise<void> {\n const batchSize = options.batchSize;\n\n for (let index = 0; index < edges.length; index += batchSize) {\n const batch = edges.slice(index, index + batchSize);\n\n for (const edge of batch) {\n const importResult = await processEdge(\n backend,\n graphId,\n registry,\n edge,\n edgeSchemas,\n nodeSchemas,\n options,\n importedNodeIds,\n );\n\n switch (importResult.status) {\n case \"created\": {\n result.edges.created++;\n break;\n }\n case \"updated\": {\n result.edges.updated++;\n break;\n }\n case \"skipped\": {\n result.edges.skipped++;\n break;\n }\n case \"error\": {\n errors.push({\n entityType: \"edge\",\n kind: edge.kind,\n id: edge.id,\n error: importResult.error,\n });\n break;\n }\n }\n }\n }\n}\n\nasync function processEdge(\n backend: GraphBackend | TransactionBackend,\n graphId: string,\n registry: KindRegistry,\n edge: InterchangeEdge,\n edgeSchemas: ReadonlyMap<string, EdgeSchemaEntry>,\n nodeSchemas: ReadonlyMap<string, NodeSchemaEntry>,\n options: ImportOptions,\n importedNodeIds: Set<string>,\n): Promise<ProcessResult> {\n // Validate edge kind exists\n const schemaEntry = edgeSchemas.get(edge.kind);\n if (!schemaEntry) {\n return { status: \"error\", error: `Unknown edge kind: ${edge.kind}` };\n }\n\n // Validate endpoint kinds exist\n if (!nodeSchemas.has(edge.from.kind)) {\n return {\n status: \"error\",\n error: `Unknown from node kind: ${edge.from.kind}`,\n };\n }\n if (!nodeSchemas.has(edge.to.kind)) {\n return { status: \"error\", error: `Unknown to node kind: ${edge.to.kind}` };\n }\n\n // Validate endpoint kinds are allowed for this edge type. Uses the shared,\n // subclass-aware check (registry.isAssignableTo) that the collection API uses,\n // so an edge whose endpoint is a subclass of a declared kind — legal in the\n // store and emitted verbatim by export — imports cleanly instead of being\n // rejected by an exact-kind comparison.\n const endpointError = validateEdgeEndpoints(\n edge.kind,\n edge.from.kind,\n edge.to.kind,\n schemaEntry.registration,\n registry,\n );\n if (endpointError !== undefined) {\n return { status: \"error\", error: endpointError.message };\n }\n\n // Validate references exist (in DB or in import batch)\n if (options.validateReferences) {\n const fromKey = makeNodeKey(edge.from.kind, edge.from.id);\n const toKey = makeNodeKey(edge.to.kind, edge.to.id);\n\n // Check import batch first, then DB. The DB row must be LIVE: getNode\n // returns tombstones, and inserting an edge whose endpoint is\n // soft-deleted would bypass the endpoint-liveness invariant the\n // collection API enforces.\n if (!importedNodeIds.has(fromKey)) {\n const fromExists = await backend.getNode(\n graphId,\n edge.from.kind,\n edge.from.id,\n );\n if (fromExists === undefined || !isLiveNodeRow(fromExists)) {\n return {\n status: \"error\",\n error: `From node not found: ${edge.from.kind}:${edge.from.id}`,\n };\n }\n }\n\n if (!importedNodeIds.has(toKey)) {\n const toExists = await backend.getNode(graphId, edge.to.kind, edge.to.id);\n if (toExists === undefined || !isLiveNodeRow(toExists)) {\n return {\n status: \"error\",\n error: `To node not found: ${edge.to.kind}:${edge.to.id}`,\n };\n }\n }\n }\n\n // Validate and transform properties\n const propsResult = validateProperties(\n edge.properties,\n schemaEntry.schema,\n options.onUnknownProperty,\n );\n\n if (!propsResult.success) {\n return { status: \"error\", error: propsResult.error };\n }\n\n const validityError = validateValidityWindow(edge);\n if (validityError !== undefined) {\n return { status: \"error\", error: validityError };\n }\n\n // Check if edge already exists\n const existing = await backend.getEdge(graphId, edge.id);\n\n if (existing) {\n switch (options.onConflict) {\n case \"skip\": {\n return {\n status: \"skipped\",\n liveTarget: existing.deleted_at === undefined,\n };\n }\n case \"error\": {\n return { status: \"error\", error: `Edge already exists: ${edge.id}` };\n }\n case \"update\": {\n // Same contract as nodes: import never resurrects a tombstone, and\n // the backend's update targets live rows only.\n if (existing.deleted_at !== undefined) {\n return { status: \"skipped\", liveTarget: false };\n }\n await backend.updateEdge({\n graphId,\n id: edge.id,\n props: propsResult.data,\n ...(edge.validTo !== undefined && { validTo: edge.validTo }),\n });\n return { status: \"updated\" };\n }\n }\n }\n\n // Create new edge\n await backend.insertEdge({\n graphId,\n id: edge.id,\n kind: edge.kind,\n fromKind: edge.from.kind,\n fromId: edge.from.id,\n toKind: edge.to.kind,\n toId: edge.to.id,\n props: propsResult.data,\n ...(edge.validFrom !== undefined && { validFrom: edge.validFrom }),\n ...(edge.validTo !== undefined && { validTo: edge.validTo }),\n });\n\n return { status: \"created\" };\n}\n\n// ============================================================\n// Property Validation\n// ============================================================\n\ntype ValidationResult =\n | { success: true; data: Record<string, unknown> }\n | { success: false; error: string };\n\nfunction validateProperties(\n properties: Record<string, unknown>,\n schema: z.ZodObject<z.ZodRawShape>,\n unknownStrategy: UnknownPropertyStrategy,\n): ValidationResult {\n try {\n // Get the schema's known keys\n const knownKeys = new Set(Object.keys(schema.shape));\n\n // Check for unknown properties\n const unknownKeys = Object.keys(properties).filter(\n (key) => !knownKeys.has(key),\n );\n\n if (unknownKeys.length > 0) {\n switch (unknownStrategy) {\n case \"error\": {\n return {\n success: false,\n error: `Unknown properties: ${unknownKeys.join(\", \")}`,\n };\n }\n case \"strip\": {\n // Remove unknown properties\n const stripped: Record<string, unknown> = {};\n for (const key of knownKeys) {\n if (key in properties) {\n stripped[key] = properties[key];\n }\n }\n // Validate stripped properties\n const result = schema.safeParse(stripped);\n if (!result.success) {\n return {\n success: false,\n error: formatZodError(result.error),\n };\n }\n return {\n success: true,\n data: result.data,\n };\n }\n case \"allow\": {\n // Validate the known fields, then return the ORIGINAL properties\n // verbatim — unknown keys preserved, known values byte-for-byte.\n // Exported data already carries post-transform values, so\n // re-applying schema transforms here would corrupt every\n // export→import round trip whose transforms are not idempotent.\n // \"allow\" is the fidelity-preserving strategy; \"strip\" (and the\n // create path) remain the normalizing ones.\n const result = schema.safeParse(properties);\n if (!result.success) {\n return {\n success: false,\n error: formatZodError(result.error),\n };\n }\n return { success: true, data: properties };\n }\n }\n }\n\n // No unknown properties - standard validation\n const result = schema.safeParse(properties);\n if (!result.success) {\n return { success: false, error: formatZodError(result.error) };\n }\n\n return { success: true, data: result.data };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return { success: false, error: `Validation error: ${message}` };\n }\n}\n\nfunction formatZodError(error: z.ZodError): string {\n return error.issues\n .map((issue) => {\n const path = issue.path.join(\".\");\n return path ? `${path}: ${issue.message}` : issue.message;\n })\n .join(\"; \");\n}\n\n// ============================================================\n// Helpers\n// ============================================================\n\nfunction makeNodeKey(kind: string, id: string): string {\n return `${kind}:${id}`;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/backend/table-contribution.ts","../src/query/dialect/fulltext-strategy.ts","../src/query/dialect/vector-strategy.ts","../src/query/dialect/postgres.ts","../src/query/dialect/sqlite.ts","../src/query/dialect/index.ts","../src/indexes/compiler.ts"],"names":["sql","quoteIdentifier"],"mappings":"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","file":"chunk-KUTNI6SI.js","sourcesContent":["/**\n * Unified table-contribution contract (#129).\n *\n * Every table TypeGraph owns — whether modeled as a Drizzle table or\n * emitted as strategy-owned raw DDL — is described by a single\n * {@link TableContribution} shape. This is the one place that answers\n * \"what tables does this backend/strategy own?\", replacing the\n * previously split surfaces (Drizzle named exports, tables-factory\n * recursion, strategy raw DDL, per-table `ensureXTable` methods).\n *\n * Lives in the neutral `backend/` layer (sibling of `backend/types.ts`,\n * which `query/dialect` already depends on) and is deliberately\n * Drizzle-free, so declaring contributions does not pull the concrete\n * Drizzle backend runtime into the query/dialect layer.\n *\n * ## Identity vs. signature (prerequisite for #135)\n *\n * #135 (durable fulltext/contribution materialization) needs to make\n * \"not materialized\" vs. \"materialized but stale\" a decidable, durable\n * fact instead of an in-memory per-backend latch. That requires two\n * conceptually separate things, and #129's job is only to make both\n * *derivable* from the contract:\n *\n * - **Materialization identity** — `owner` + `logicalName` +\n * resolved physical `tableName`. Keying on `logicalName` alone is\n * insufficient: custom per-deployment table names must be\n * distinguishable, otherwise two deployments with different physical\n * names would collide on one durable marker. (#135 additionally\n * scopes this by `graphId` at persistence time.)\n * - **Drift signature** — a hash of the strategy identity/version,\n * the resolved table name(s), and the normalized `createDdl`. #129\n * guarantees `createDdl` is deterministic for a given resolved\n * configuration so the hash #135 computes is meaningful.\n *\n * The signature is intentionally **not** eagerly carried on the\n * contribution: hashing is async (Web Crypto, see `utils/hash`) and\n * #135 already owns signature persistence the same way\n * `materializeIndexes` does for declared indexes.\n */\n\n/**\n * `logicalName` of the strategy-owned fulltext slot. Used as a logic\n * discriminant (latch routing, runtime-ensure) across the strategies\n * and both backends — a shared constant so a strategy declaring a\n * different name fails loudly at the call site instead of silently\n * skipping the latched fulltext path.\n */\nexport const FULLTEXT_CONTRIBUTION_NAME = \"fulltext\";\n\n/** `owner` of core/base schema tables (not strategy-owned). */\nexport const BASE_CONTRIBUTION_OWNER = \"base\";\n\n/**\n * A single table TypeGraph owns.\n */\nexport type TableContribution = Readonly<{\n /**\n * Stable, graph- and deployment-independent identity for the logical\n * slot this contribution fills (e.g. `\"fulltext\"`). NOT the physical\n * table name. Stable across table-name overrides and across strategy\n * swaps of the *same* logical slot, so #135's durable marker can\n * survive both.\n */\n logicalName: string;\n /**\n * Identifies the producer of this contribution (e.g. a strategy id\n * like `\"tsvector\"` / `\"fts5\"`, or `\"base\"` for core schema tables).\n * Part of the #135 materialization identity and an input to the\n * drift signature — a strategy swap on the same `logicalName` is a\n * legitimate, detectable drift, not a silent reuse.\n */\n owner: string;\n /**\n * Resolved physical table name after any per-deployment name\n * override. Part of the #135 materialization identity (custom names\n * must be distinguishable) and used by diagnostics / the focused\n * bootstrap ensure.\n */\n tableName: string;\n /**\n * Idempotent (`CREATE ... IF NOT EXISTS`) statements that\n * materialize this contribution's table **and its supporting\n * indexes**. Running the full list is how the runtime ensure\n * self-heals partial states (table present, index missing) — it is\n * not a probe-and-skip. Deterministic for a given resolved\n * configuration: the canonical normalized input to #135's drift\n * signature.\n */\n createDdl: readonly string[];\n /**\n * When `true`, the post-schema-load focused ensure\n * (`loadActiveSchemaWithBootstrap`) materializes this contribution\n * on every successful schema load.\n *\n * **Invariant: only strategy-declared contributions may set this.**\n * Core/base tables are always `false` — they are created by\n * drizzle-kit / `bootstrapTables`. This is what lets the boot path\n * derive runtime contributions straight from the strategy\n * (`fulltextStrategy.ownedTables`) without walking — and generating\n * DDL for — every base table.\n */\n runtimeEnsure: boolean;\n}>;\n\n/**\n * A table a {@link FulltextStrategy} declares it owns. An alias, not a\n * distinct shape: a strategy's declaration is already authoritative\n * (no resolution step). The name documents the producer role.\n */\nexport type StrategyTableContribution = TableContribution;\n","/**\n * Fulltext Strategy — pluggable DDL + SQL generation for a dialect's\n * fulltext stack. A strategy owns every SQL statement that touches its\n * backing table: DDL, upsert (single + batch), delete (single + batch),\n * MATCH condition, rank expression, and snippet expression.\n *\n * A dialect picks one as its default; `createPostgresBackend` /\n * `createSqliteBackend` accept an override for alternate Postgres stacks\n * (pg_trgm, ParadeDB/pg_search, pgroonga) to swap the entire fulltext\n * pipeline without forking TypeGraph.\n */\nimport { type SQL, sql } from \"drizzle-orm\";\n\nimport { quotedTableName } from \"../../backend/drizzle/operations/shared\";\nimport {\n FULLTEXT_CONTRIBUTION_NAME,\n type StrategyTableContribution,\n} from \"../../backend/table-contribution\";\nimport {\n type DeleteFulltextBatchParams,\n type DeleteFulltextParams,\n type FulltextBatchRow,\n type FulltextCapabilities,\n type FulltextQueryMode,\n type UpsertFulltextBatchParams,\n type UpsertFulltextParams,\n} from \"../../backend/types\";\n\n/**\n * Every `FulltextQueryMode` both shipped strategies accept.\n */\nexport const ALL_FULLTEXT_MODES: readonly FulltextQueryMode[] = [\n \"websearch\",\n \"phrase\",\n \"plain\",\n \"raw\",\n] as const;\n\n/**\n * Derives the `FulltextCapabilities` backends advertise from the active\n * strategy, so the two never drift.\n */\nexport function buildFulltextCapabilities(\n strategy: FulltextStrategy,\n): FulltextCapabilities {\n return {\n supported: true,\n languages: strategy.languages,\n phraseQueries: strategy.supportedModes.includes(\"phrase\"),\n prefixQueries: strategy.supportsPrefix,\n highlighting: strategy.supportsSnippets,\n };\n}\n\n/**\n * A pluggable fulltext implementation. Each strategy is expected to be\n * self-contained: given a table name, a query string, and a parse mode,\n * it emits every SQL statement the compiler and backend need — DDL,\n * reads, and writes. No out-of-band conventions across layers.\n */\nexport interface FulltextStrategy {\n /** Human-readable identifier used in error messages and telemetry. */\n readonly name: string;\n\n /**\n * Parse modes this strategy can translate. Callers validate against\n * this list before emitting SQL; a mode outside the set means the\n * strategy rejects the query at compile time.\n */\n readonly supportedModes: readonly FulltextQueryMode[];\n\n /**\n * Whether the strategy can emit a per-row highlighted snippet. When\n * false, `snippetExpression` returns a literal `NULL` so callers can\n * leave the `snippet` column in place without a branch.\n */\n readonly supportsSnippets: boolean;\n\n /**\n * Whether the strategy supports prefix queries (`foo*`). Used to\n * populate `BackendCapabilities.fulltext.prefixQueries`. A strategy\n * may support prefix queries via dedicated syntax without advertising\n * \"raw\" mode (and vice-versa).\n */\n readonly supportsPrefix: boolean;\n\n /**\n * Whether a per-query `language` override is honored. Postgres' tsvector\n * accepts any installed regconfig at query time; SQLite FTS5's tokenizer\n * is fixed at table-create time, so the override is silently ignored.\n * Callers may surface a warning when the user passes `language` to a\n * strategy that doesn't honor it.\n */\n readonly supportsLanguageOverride: boolean;\n\n /**\n * Languages / tokenizer names understood by the strategy. Advisory — a\n * runtime backend like Postgres may accept other installed regconfigs.\n * Used to populate `BackendCapabilities.fulltext.languages`.\n */\n readonly languages: readonly string[];\n\n /**\n * Emits the WHERE-side MATCH expression.\n *\n * @example\n * tsvector: `\"typegraph_node_fulltext\".\"tsv\" @@ websearch_to_tsquery('english', 'cats')`\n * fts5: `\"typegraph_node_fulltext\" MATCH '\"cats\"'`\n */\n matchCondition(\n tableName: string,\n query: string,\n mode: FulltextQueryMode,\n language?: string,\n ): SQL;\n\n /**\n * Emits the relevance expression. Higher values = more relevant. The\n * compiler orders by this expression DESC, and both builder and\n * backend-direct paths use the same form so their top-k results agree.\n */\n rankExpression(\n tableName: string,\n query: string,\n mode: FulltextQueryMode,\n language?: string,\n ): SQL;\n\n /**\n * Emits a per-row highlighted snippet expression, or `NULL` when\n * `supportsSnippets` is false. Snippet markup is `<mark>…</mark>` in\n * both shipped strategies so consumers can apply one stylesheet.\n */\n snippetExpression(\n tableName: string,\n query: string,\n mode: FulltextQueryMode,\n language?: string,\n ): SQL;\n\n /**\n * The tables this strategy owns, as Drizzle-free, already\n * authoritative `TableContribution`s (`logicalName`, `owner`,\n * resolved `tableName`, idempotent `createDdl` for the table **and\n * its supporting indexes**, `runtimeEnsure`). A strategy never\n * constructs a Drizzle table itself; drizzle-kit visibility, when\n * applicable, is the schema barrel's responsibility (the default\n * Postgres strategy's `schema/postgres.ts` exports a matching\n * `tables.fulltext` — a non-default strategy must export its own).\n *\n * Replaces the former `generateDdl(tableName)`: DDL is now one field\n * of a contribution rather than the strategy's whole storage\n * surface. (Public API change — see #129.)\n */\n ownedTables(primaryTableName: string): readonly StrategyTableContribution[];\n\n /**\n * Emits the statements that upsert a single fulltext row. Returns one\n * or more statements — some backends (SQLite FTS5) cannot emulate\n * upsert in a single statement and need DELETE + INSERT.\n */\n buildUpsert(\n tableName: string,\n params: UpsertFulltextParams,\n timestamp: string,\n ): readonly SQL[];\n\n /**\n * Emits the statements that upsert many fulltext rows at once. Input\n * rows are expected to be de-duplicated last-write-wins by the\n * strategy if the underlying SQL statement cannot tolerate duplicate\n * conflict keys. Returns `[]` when `params.rows` is empty.\n */\n buildBatchUpsert(\n tableName: string,\n params: UpsertFulltextBatchParams,\n timestamp: string,\n ): readonly SQL[];\n\n /**\n * Emits the statements that delete a single fulltext row. Normally a\n * single PK-scoped DELETE, but strategies that maintain auxiliary\n * indexes (delete-triggered external stores, ParadeDB-style secondary\n * structures) may need more.\n */\n buildDelete(tableName: string, params: DeleteFulltextParams): readonly SQL[];\n\n /**\n * Emits the statements that delete many fulltext rows at once. Returns\n * `[]` when `params.nodeIds` is empty.\n */\n buildBatchDelete(\n tableName: string,\n params: DeleteFulltextBatchParams,\n ): readonly SQL[];\n}\n\n// ============================================================\n// Internal helpers\n// ============================================================\n\nfunction quoteIdentifier(name: string): string {\n return `\"${name.replaceAll('\"', '\"\"')}\"`;\n}\n\nfunction tsvectorColumn(tableName: string): SQL {\n return sql`${quotedTableName(tableName)}.\"tsv\"`;\n}\n\n/**\n * Dedupes batch rows last-write-wins by nodeId. Returns a plain array\n * in insertion order of the last occurrence of each id. Shared by both\n * shipped strategies.\n */\nfunction dedupeFulltextBatchRows(\n rows: readonly FulltextBatchRow[],\n): FulltextBatchRow[] {\n const seen = new Map<string, FulltextBatchRow>();\n for (const row of rows) seen.set(row.nodeId, row);\n return [...seen.values()];\n}\n\nfunction buildPkScopedDelete(\n tableName: string,\n params: DeleteFulltextParams,\n): SQL {\n const table = quotedTableName(tableName);\n return sql`\n DELETE FROM ${table}\n WHERE \"graph_id\" = ${params.graphId}\n AND \"node_kind\" = ${params.nodeKind}\n AND \"node_id\" = ${params.nodeId}\n `;\n}\n\nfunction buildPkScopedBatchDelete(\n tableName: string,\n params: DeleteFulltextBatchParams,\n): SQL | undefined {\n if (params.nodeIds.length === 0) return undefined;\n const unique = [...new Set(params.nodeIds)];\n const table = quotedTableName(tableName);\n return sql`\n DELETE FROM ${table}\n WHERE \"graph_id\" = ${params.graphId}\n AND \"node_kind\" = ${params.nodeKind}\n AND \"node_id\" IN (${sql.join(\n unique.map((id) => sql`${id}`),\n sql`, `,\n )})\n `;\n}\n\n// ============================================================\n// tsvector strategy (PostgreSQL built-in)\n// ============================================================\n\nfunction postgresTsquery(\n mode: FulltextQueryMode,\n query: string,\n language: string | undefined,\n): SQL {\n // The `language` column is already `regconfig`, so the non-override\n // path references the column directly. The per-query override path\n // still arrives as a bound text parameter and needs the cast.\n const langExpr: SQL =\n language === undefined ? sql`\"language\"` : sql`${language}::regconfig`;\n switch (mode) {\n case \"websearch\": {\n return sql`websearch_to_tsquery(${langExpr}, ${query})`;\n }\n case \"phrase\": {\n return sql`phraseto_tsquery(${langExpr}, ${query})`;\n }\n case \"plain\": {\n return sql`plainto_tsquery(${langExpr}, ${query})`;\n }\n case \"raw\": {\n return sql`to_tsquery(${langExpr}, ${query})`;\n }\n default: {\n const _exhaustive: never = mode;\n throw new Error(`Unsupported fulltext mode: ${String(_exhaustive)}`);\n }\n }\n}\n\nexport const tsvectorStrategy: FulltextStrategy = {\n name: \"tsvector\",\n supportedModes: ALL_FULLTEXT_MODES,\n supportsSnippets: true,\n // `raw` mode exposes `foo:*` prefix-match syntax to callers.\n supportsPrefix: true,\n supportsLanguageOverride: true,\n // Canonical Postgres stemmers; every stock install ships these plus a\n // few others. Runtime `to_tsvector` accepts any installed regconfig\n // name — this list is advisory for capability discovery.\n languages: [\n \"simple\",\n \"english\",\n \"french\",\n \"german\",\n \"italian\",\n \"portuguese\",\n \"russian\",\n \"spanish\",\n \"swedish\",\n ] as const,\n\n matchCondition(tableName, query, mode, language) {\n const q = postgresTsquery(mode, query, language);\n return sql`${tsvectorColumn(tableName)} @@ ${q}`;\n },\n\n rankExpression(tableName, query, mode, language) {\n const q = postgresTsquery(mode, query, language);\n return sql`ts_rank_cd(${tsvectorColumn(tableName)}, ${q})`;\n },\n\n snippetExpression(_tableName, query, mode, language) {\n const langExpr: SQL =\n language === undefined ? sql`\"language\"` : sql`${language}::regconfig`;\n const q = postgresTsquery(mode, query, language);\n return sql`ts_headline(${langExpr}, \"content\", ${q}, 'StartSel=<mark>,StopSel=</mark>,MaxFragments=1,MinWords=5,MaxWords=30,ShortWord=3')`;\n },\n\n ownedTables(primaryTableName) {\n const name = quoteIdentifier(primaryTableName);\n const gin = quoteIdentifier(`${primaryTableName}_tsv_idx`);\n const kind = quoteIdentifier(`${primaryTableName}_kind_idx`);\n // `language` is `regconfig` so `to_tsvector(\"language\", \"content\")`\n // is an immutable expression — Postgres can then compute `tsv` as a\n // GENERATED STORED column and own the `content → tsv` invariant.\n // (The text→regconfig cast happens once at INSERT time against the\n // bound parameter, which is fine because it's not inside the\n // generated expression.)\n const createDdl = [\n `CREATE TABLE IF NOT EXISTS ${name} (\n \"graph_id\" TEXT NOT NULL,\n \"node_kind\" TEXT NOT NULL,\n \"node_id\" TEXT NOT NULL,\n \"content\" TEXT NOT NULL,\n \"language\" regconfig NOT NULL,\n \"tsv\" tsvector NOT NULL\n GENERATED ALWAYS AS (to_tsvector(\"language\", \"content\")) STORED,\n \"updated_at\" TIMESTAMPTZ NOT NULL,\n PRIMARY KEY (\"graph_id\", \"node_kind\", \"node_id\")\n);`,\n `CREATE INDEX IF NOT EXISTS ${gin} ON ${name} USING GIN (\"tsv\");`,\n `CREATE INDEX IF NOT EXISTS ${kind} ON ${name} (\"graph_id\", \"node_kind\");`,\n ];\n // drizzle-kit visibility for this default strategy comes from\n // `schema/postgres.ts` exporting the matching `tables.fulltext`\n // pgTable through the barrel — one object, not two. `runtimeEnsure`\n // because drizzle-kit-managed setups create every base table except\n // this strategy-owned one.\n return [\n {\n logicalName: FULLTEXT_CONTRIBUTION_NAME,\n owner: \"tsvector\",\n tableName: primaryTableName,\n createDdl,\n runtimeEnsure: true,\n },\n ];\n },\n\n buildUpsert(tableName, params, timestamp) {\n const table = quotedTableName(tableName);\n // `tsv` is a GENERATED STORED column — Postgres computes it from\n // `content` + `language`, so it must not appear in the column list\n // or the ON CONFLICT update set.\n return [\n sql`\n INSERT INTO ${table} (\"graph_id\", \"node_kind\", \"node_id\", \"content\", \"language\", \"updated_at\")\n VALUES (\n ${params.graphId}, ${params.nodeKind}, ${params.nodeId},\n ${params.content}, ${params.language}::regconfig,\n ${timestamp}\n )\n ON CONFLICT (\"graph_id\", \"node_kind\", \"node_id\")\n DO UPDATE SET\n \"content\" = EXCLUDED.\"content\",\n \"language\" = EXCLUDED.\"language\",\n \"updated_at\" = EXCLUDED.\"updated_at\"\n `,\n ];\n },\n\n buildBatchUpsert(tableName, params, timestamp) {\n const rows = dedupeFulltextBatchRows(params.rows);\n if (rows.length === 0) return [];\n\n const table = quotedTableName(tableName);\n const valueTuples = rows.map(\n (row) => sql`\n (\n ${params.graphId}, ${params.nodeKind}, ${row.nodeId},\n ${row.content}, ${row.language}::regconfig,\n ${timestamp}\n )\n `,\n );\n\n return [\n sql`\n INSERT INTO ${table} (\"graph_id\", \"node_kind\", \"node_id\", \"content\", \"language\", \"updated_at\")\n VALUES ${sql.join(valueTuples, sql`, `)}\n ON CONFLICT (\"graph_id\", \"node_kind\", \"node_id\")\n DO UPDATE SET\n \"content\" = EXCLUDED.\"content\",\n \"language\" = EXCLUDED.\"language\",\n \"updated_at\" = EXCLUDED.\"updated_at\"\n `,\n ];\n },\n\n buildDelete(tableName, params) {\n return [buildPkScopedDelete(tableName, params)];\n },\n\n buildBatchDelete(tableName, params) {\n const stmt = buildPkScopedBatchDelete(tableName, params);\n return stmt === undefined ? [] : [stmt];\n },\n};\n\n// ============================================================\n// FTS5 strategy (SQLite)\n// ============================================================\n\nfunction translateToFts5Query(query: string, mode: FulltextQueryMode): string {\n switch (mode) {\n case \"phrase\": {\n return `\"${query.replaceAll('\"', '\"\"')}\"`;\n }\n case \"plain\": {\n return query\n .trim()\n .split(/\\s+/u)\n .filter((token) => token.length > 0)\n .map((token) => `\"${token.replaceAll('\"', '\"\"')}\"`)\n .join(\" \");\n }\n case \"websearch\": {\n return translateWebsearchToFts5(query);\n }\n case \"raw\": {\n return query;\n }\n default: {\n const _exhaustive: never = mode;\n throw new Error(`Unsupported fulltext mode: ${String(_exhaustive)}`);\n }\n }\n}\n\nfunction translateWebsearchToFts5(query: string): string {\n const tokens: string[] = [];\n let index = 0;\n\n function skipWhitespace(): void {\n while (index < query.length && /\\s/u.test(query[index] ?? \"\")) {\n index += 1;\n }\n }\n\n function readPhrase(): string {\n index += 1;\n let content = \"\";\n while (index < query.length && query[index] !== '\"') {\n content += query[index] ?? \"\";\n index += 1;\n }\n if (query[index] === '\"') index += 1;\n return `\"${content.replaceAll('\"', '\"\"')}\"`;\n }\n\n function readBareTerm(): string {\n let term = \"\";\n while (index < query.length && !/\\s/u.test(query[index] ?? \"\")) {\n term += query[index] ?? \"\";\n index += 1;\n }\n return term;\n }\n\n while (index < query.length) {\n skipWhitespace();\n if (index >= query.length) break;\n const ch = query[index];\n if (ch === '\"') {\n tokens.push(readPhrase());\n continue;\n }\n if (ch === \"-\") {\n index += 1;\n const term =\n query[index] === '\"' ?\n readPhrase()\n : `\"${readBareTerm().replaceAll('\"', '\"\"')}\"`;\n tokens.push(`NOT ${term}`);\n continue;\n }\n if (ch === \"+\") {\n index += 1;\n continue;\n }\n const bare = readBareTerm();\n if (bare.length === 0) continue;\n if (bare.toUpperCase() === \"OR\") {\n tokens.push(\"OR\");\n continue;\n }\n tokens.push(`\"${bare.replaceAll('\"', '\"\"')}\"`);\n }\n\n if (tokens.length > 0 && tokens[0]?.startsWith(\"NOT \")) {\n tokens.shift();\n }\n\n return tokens.join(\" \");\n}\n\nexport const fts5Strategy: FulltextStrategy = {\n name: \"fts5\",\n supportedModes: ALL_FULLTEXT_MODES,\n supportsSnippets: true,\n // FTS5 supports `foo*` prefix matching natively.\n supportsPrefix: true,\n // FTS5 tokenizer is fixed at table-create time; per-row / per-query\n // language metadata is stored but not consulted.\n supportsLanguageOverride: false,\n // The built-in tokenizer is `porter unicode61 remove_diacritics 2`; the\n // `language` field on searchable() is recorded for future use but not\n // applied at query time.\n languages: [\"porter\", \"unicode61\", \"trigram\"] as const,\n\n matchCondition(tableName, query, mode, _language) {\n const matchExpression = translateToFts5Query(query, mode);\n return sql`${quotedTableName(tableName)} MATCH ${matchExpression}`;\n },\n\n rankExpression(tableName, _query, _mode, _language) {\n // FTS5 bm25() returns a negative score where lower = more relevant.\n // Negate so callers see higher = better (uniform with tsvector).\n return sql`-bm25(${quotedTableName(tableName)})`;\n },\n\n snippetExpression(tableName, _query, _mode, _language) {\n return sql`snippet(${quotedTableName(tableName)}, -1, '<mark>', '</mark>', '…', 20)`;\n },\n\n ownedTables(primaryTableName) {\n const name = quoteIdentifier(primaryTableName);\n // FTS5 virtual tables cannot be modeled as a Drizzle table, so this\n // contribution is raw-ddl: emitted verbatim and invisible to\n // drizzle-kit. `runtimeEnsure` because no drizzle-kit-managed setup\n // can create it.\n return [\n {\n logicalName: FULLTEXT_CONTRIBUTION_NAME,\n owner: \"fts5\",\n tableName: primaryTableName,\n createDdl: [\n `CREATE VIRTUAL TABLE IF NOT EXISTS ${name} USING fts5(\n graph_id UNINDEXED,\n node_kind UNINDEXED,\n node_id UNINDEXED,\n language UNINDEXED,\n updated_at UNINDEXED,\n content,\n tokenize='porter unicode61 remove_diacritics 2'\n);`,\n ],\n runtimeEnsure: true,\n },\n ];\n },\n\n buildUpsert(tableName, params, timestamp) {\n const table = quotedTableName(tableName);\n // FTS5 virtual tables don't support ON CONFLICT — emulate with\n // DELETE + INSERT, atomic under the caller's outer transaction.\n return [\n sql`\n DELETE FROM ${table}\n WHERE \"graph_id\" = ${params.graphId}\n AND \"node_kind\" = ${params.nodeKind}\n AND \"node_id\" = ${params.nodeId}\n `,\n sql`\n INSERT INTO ${table} (graph_id, node_kind, node_id, content, language, updated_at)\n VALUES (${params.graphId}, ${params.nodeKind}, ${params.nodeId}, ${params.content}, ${params.language}, ${timestamp})\n `,\n ];\n },\n\n buildBatchUpsert(tableName, params, timestamp) {\n const rows = dedupeFulltextBatchRows(params.rows);\n if (rows.length === 0) return [];\n\n const table = quotedTableName(tableName);\n const nodeIds = rows.map((row) => row.nodeId);\n\n const deleteStmt = sql`\n DELETE FROM ${table}\n WHERE \"graph_id\" = ${params.graphId}\n AND \"node_kind\" = ${params.nodeKind}\n AND \"node_id\" IN (${sql.join(\n nodeIds.map((id) => sql`${id}`),\n sql`, `,\n )})\n `;\n\n const valueTuples = rows.map(\n (row) => sql`\n (\n ${params.graphId}, ${params.nodeKind}, ${row.nodeId},\n ${row.content}, ${row.language}, ${timestamp}\n )\n `,\n );\n\n const insertStmt = sql`\n INSERT INTO ${table} (graph_id, node_kind, node_id, content, language, updated_at)\n VALUES ${sql.join(valueTuples, sql`, `)}\n `;\n\n return [deleteStmt, insertStmt];\n },\n\n buildDelete(tableName, params) {\n return [buildPkScopedDelete(tableName, params)];\n },\n\n buildBatchDelete(tableName, params) {\n const stmt = buildPkScopedBatchDelete(tableName, params);\n return stmt === undefined ? [] : [stmt];\n },\n};\n","/**\n * Vector Strategy — pluggable storage + SQL generation for a backend's\n * vector stack. The sibling of {@link FulltextStrategy}: a strategy owns\n * every statement that touches its embedding storage — the per-field DDL,\n * upsert, delete, similarity search, and (optional) ANN index lifecycle —\n * plus the capability advertisement and the distance/score expressions the\n * query compiler splices into its relevance CTE.\n *\n * ## Why a strategy, and why per-(kind, field) storage\n *\n * The spike behind #157 established that \"real\" ANN on every engine we\n * support converges on a\n * **typed, fixed-dimension structure per `(nodeKind, fieldPath)`**:\n *\n * - pgvector: a `vector(N)` column + HNSW/IVFFlat;\n * - libSQL native: an `F32_BLOB(N)` column + `libsql_vector_idx` +\n * `vector_top_k` (a plain `BLOB` or dimensionless `F32_BLOB` is rejected\n * by the index — the dimension must live in the column type);\n * - sqlite-vec: a `vec0(embedding float[N])` virtual table.\n *\n * The legacy single shared `typegraph_node_embeddings` table (one generic\n * column holding mixed-dimension vectors) can only ever be brute-forced;\n * pgvector was the sole engine that hid this, because its index supplies the\n * dimension via a `::vector(N)` cast expression. So storage is the\n * strategy's to own, slot by slot, rather than a fixed global table.\n *\n * Brute force remains a legitimate, capability-advertised mode (libSQL's\n * `vector_distance_cos` over a column with no index, sqlite-vec's\n * `vec_distance_cosine`): a strategy whose `capabilities.indexTypes` is\n * `[\"none\"]` simply never emits an ANN index and `buildSearch` always scans.\n */\nimport { type SQL, sql } from \"drizzle-orm\";\n\nimport { type StrategyTableContribution } from \"../../backend/table-contribution\";\nimport {\n type DeleteEmbeddingParams,\n type UpsertEmbeddingParams,\n type VectorCapabilities,\n type VectorIndexType,\n type VectorMetric,\n type VectorSearchParams,\n} from \"../../backend/types\";\n\n/**\n * `logicalName` prefix of a strategy-owned vector slot. Each\n * `(nodeKind, fieldPath)` pair fills one logical vector slot; the full\n * logical name is `${VECTOR_CONTRIBUTION_PREFIX}:${nodeKind}.${fieldPath}`,\n * stable across table-name overrides and strategy swaps so #135's durable\n * materialization marker survives both.\n */\nexport const VECTOR_CONTRIBUTION_PREFIX = \"vector\";\n\n/**\n * The resolved identity of one embedding field's storage in a graph —\n * everything a strategy needs to DDL, address, and index it.\n *\n * Graph-scoped: each `(graphId, nodeKind, fieldPath)` gets its own physical\n * table. TypeGraph supports many graphs per physical database, and the same\n * `(kind, field)` can carry different embedding dimensions across graphs — a\n * shared per-`(kind, field)` table would collide on the fixed column type\n * (`vector(N)` / `F32_BLOB(N)`). Graph-scoping also makes libSQL's\n * table-global `vector_top_k` per-graph-exact (no cross-graph recall bleed).\n */\nexport type VectorSlot = Readonly<{\n /** Graph the embedding belongs to — scopes the physical table. */\n graphId: string;\n /** Node kind owning the embedding field (e.g. `\"Document\"`). */\n nodeKind: string;\n /** Dot-path of the embedding field within the node props (e.g. `\"embedding\"`). */\n fieldPath: string;\n /** Fixed vector dimension `N` for this field — carried into the column type. */\n dimensions: number;\n /** Distance metric the field's index is built for. */\n metric: VectorMetric;\n /**\n * Index type to materialize. `\"none\"` means brute-force only (no ANN\n * index emitted); the strategy still stores and searches the field.\n */\n indexType: VectorIndexType;\n /**\n * Optional ANN index tuning carried into the index DDL (pgvector\n * `m`/`ef_construction`/`lists`). Present on the create-index / re-embed\n * paths (resolved from the field's `embedding()` declaration); omitted on\n * the write/search ensure paths, where the strategy falls back to defaults.\n */\n indexParams?: Readonly<{\n m?: number;\n efConstruction?: number;\n lists?: number;\n }>;\n}>;\n\n/**\n * Derives the `VectorCapabilities` a backend advertises from its active\n * strategy, so the two never drift (mirrors `buildFulltextCapabilities`).\n * The strategy is the single source of truth; there are no per-call-site\n * `SQLITE_VECTOR_*` constants.\n */\nexport function buildVectorCapabilities(\n strategy: VectorStrategy,\n): VectorCapabilities {\n return strategy.capabilities;\n}\n\n/**\n * A pluggable vector implementation. Each strategy is self-contained:\n * given a {@link VectorSlot}, it emits every statement the backend and\n * compiler need — per-field storage DDL, writes, similarity search, ANN\n * index lifecycle — and advertises exactly the metrics and index types it\n * can honor. Adding the Nth backend is one of these objects; no core edits.\n */\nexport interface VectorStrategy {\n /** Human-readable identifier used in error messages and telemetry. */\n readonly name: string;\n\n /**\n * The metrics, index types, and dimension ceiling this strategy honors —\n * advertised verbatim as `backend.capabilities.vector`. Asymmetry across\n * engines is legitimate and explicit here (pgvector has `inner_product`;\n * libSQL/sqlite-vec do not), never a silent runtime failure.\n */\n readonly capabilities: VectorCapabilities;\n\n /**\n * Deterministic physical table (or virtual-table) name backing a field in\n * a graph. The compiler references this to scan the right per-field storage,\n * and the backend uses it to route upserts/deletes. Must be a stable,\n * collision-safe SQL identifier derived from `(graphId, nodeKind, fieldPath)`.\n */\n tableName(graphId: string, nodeKind: string, fieldPath: string): string;\n\n /**\n * The per-field storage this strategy owns for `slot`, as Drizzle-free\n * `StrategyTableContribution`s (resolved `tableName`, deterministic\n * idempotent `createDdl` for the table **and** its ANN index when the\n * slot's `indexType` warrants one, `runtimeEnsure`). Rides the #129/#135\n * table-contribution + durable-materialization machinery exactly as the\n * FTS5 / tsvector virtual tables do — these are materialized per graph by\n * `materializeIndexes()`, not by global `bootstrapTables`.\n */\n ownedTables(slot: VectorSlot): readonly StrategyTableContribution[];\n\n /**\n * Emits the statement(s) that upsert a single embedding into the slot's\n * storage. Multiple statements are allowed for engines that cannot upsert\n * a vector in one statement (e.g. a `vec0` virtual table → DELETE+INSERT).\n */\n buildUpsert(\n slot: VectorSlot,\n params: UpsertEmbeddingParams,\n timestamp: string,\n ): readonly SQL[];\n\n /** Emits the statement(s) that delete a single embedding from the slot. */\n buildDelete(slot: VectorSlot, params: DeleteEmbeddingParams): readonly SQL[];\n\n /**\n * Raw DDL statement(s) that drop the slot's entire physical storage\n * (table + ANN index, and any engine-managed shadow tables). Used by the\n * destructive `store.reembedVectorField()` path to recreate a field's\n * storage at a new dimension. Returned as raw strings (like\n * `ownedTables(...).createDdl`) for `backend.executeDdl`; must be idempotent\n * (`IF EXISTS`).\n */\n buildDropStorage(slot: VectorSlot): readonly string[];\n\n /**\n * Emits the similarity-search query for the `backend.vectorSearch` path,\n * returning rows shaped `{ node_id, score }` ordered best-first. The\n * strategy picks brute-force vs ANN based on whether `slot.indexType`\n * materialized an index — the caller never branches. `score` follows the\n * shared convention (cosine → similarity `1 - distance`; l2 /\n * inner_product → raw distance), so `coerceVectorScore` / fusion stay\n * dialect-neutral.\n */\n buildSearch(slot: VectorSlot, params: VectorSearchParams): SQL;\n\n /**\n * The distance expression over the slot's embedding column, used by the\n * **query compiler** to splice vector relevance into its CTE. This is the\n * one genuinely engine-specific fragment (`vec_distance_cosine` vs\n * `<=>` vs `vector_distance_cos`); the surrounding score / minScore /\n * ORDER BY math is shared (see {@link vectorScoreExpression} etc.).\n *\n * `embeddingColumn` is the already-qualified column SQL; `queryEmbedding`\n * is formatted by the strategy into its engine's literal form.\n */\n distanceExpression(\n embeddingColumn: SQL,\n queryEmbedding: readonly number[],\n metric: VectorMetric,\n ): SQL;\n\n /**\n * Emits the ANN index creation statement for a slot, or `undefined` when\n * indexing is inline (vec0) or unsupported (brute-force-only strategies).\n * Invoked through `backend.createVectorIndex` during `materializeIndexes`.\n */\n buildCreateIndex?(\n slot: VectorSlot,\n options?: Readonly<{ concurrent?: boolean }>,\n ): SQL | undefined;\n\n /** Emits the ANN index drop statement, or `undefined` when not applicable. */\n buildDropIndex?(slot: VectorSlot): SQL | undefined;\n}\n\n// ============================================================\n// Shared, dialect-neutral expression math\n// ============================================================\n//\n// These transforms are identical across pgvector / sqlite-vec / libSQL —\n// only `distanceExpression` differs — so they live once here and are reused\n// by both `buildSearch` implementations and the compiler CTE builder.\n\n/**\n * Converts a distance expression into a score expression (higher = better).\n * Cosine distance is mapped to similarity (`1 - d`); l2 and inner_product\n * are returned as-is (lower distance already ranks better, ordered ASC).\n */\nexport function vectorScoreExpression(\n distanceExpression: SQL,\n metric: VectorMetric,\n): SQL {\n switch (metric) {\n case \"cosine\": {\n return sql`(1 - (${distanceExpression}))`;\n }\n case \"l2\":\n case \"inner_product\": {\n return distanceExpression;\n }\n default: {\n const _exhaustive: never = metric;\n throw new Error(`Unsupported vector metric: ${String(_exhaustive)}`);\n }\n }\n}\n\n/**\n * Builds the `minScore` WHERE condition against a distance expression,\n * translating the score threshold back into the metric's distance space.\n */\nexport function vectorMinScoreCondition(\n distanceExpression: SQL,\n metric: VectorMetric,\n minScore: number,\n): SQL {\n // Validate against the RESOLVED metric — both the compiler's relevance CTE\n // and the backend search path funnel here, so an out-of-range floor (e.g. a\n // cosine minScore of 5 → `distance <= 1 - 5`, which matches nothing) is\n // rejected loudly instead of silently returning zero rows.\n assertVectorMinScore(minScore, metric);\n switch (metric) {\n case \"cosine\": {\n return sql`${distanceExpression} <= ${1 - minScore}`;\n }\n case \"l2\": {\n return sql`${distanceExpression} <= ${minScore}`;\n }\n case \"inner_product\": {\n return sql`${distanceExpression} <= ${-minScore}`;\n }\n default: {\n const _exhaustive: never = metric;\n throw new Error(`Unsupported vector metric: ${String(_exhaustive)}`);\n }\n }\n}\n\n/**\n * Validates that every value in an embedding is a finite number. Shared by\n * strategies so a NaN/Infinity is reported with the offending index before\n * it reaches engine-specific literal formatting (which would mask it).\n */\nexport function assertFiniteEmbedding(\n embedding: readonly number[],\n name: string,\n): void {\n for (const [index, value] of embedding.entries()) {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new TypeError(\n `${name}[${index}] must be a finite number, got: ${value}`,\n );\n }\n }\n}\n\n/**\n * Validates a vector-search `limit` is a positive integer. Enforced by the\n * backend's `vectorSearch` (defense in depth — the store boundary also\n * checks) so a direct backend call with `limit: 0` fails loudly instead of\n * silently scanning nothing.\n */\nexport function assertVectorSearchLimit(limit: number): void {\n if (!Number.isInteger(limit) || limit <= 0) {\n throw new RangeError(\n `vectorSearch limit must be a positive integer, got: ${limit}`,\n );\n }\n}\n\n/**\n * Validates a `minScore` floor against its (resolved) metric: it must be finite,\n * and for cosine it must lie in [-1, 1] (a cosine score is the `1 - distance`\n * similarity). Shared by the store facade, the compiler's relevance CTE\n * ({@link vectorMinScoreCondition}), and the backend search path so every entry\n * point rejects the same out-of-range floor instead of silently returning none.\n */\nexport function assertVectorMinScore(\n minScore: number,\n metric: VectorMetric,\n label = \"minScore\",\n): void {\n if (!Number.isFinite(minScore)) {\n throw new RangeError(`${label} must be a finite number, got: ${minScore}`);\n }\n if (metric === \"cosine\" && Math.abs(minScore) > 1) {\n throw new RangeError(\n `${label} for the cosine metric must be between -1 and 1, got: ${minScore}`,\n );\n }\n}\n\n// ============================================================\n// Shared physical naming\n// ============================================================\n\n/**\n * pgvector inherits Postgres' 63-byte identifier ceiling; SQLite/libSQL are\n * far more generous, so the smallest common cap keeps one naming scheme\n * across every strategy.\n */\nconst MAX_VECTOR_IDENTIFIER_LENGTH = 63;\n\nfunction sanitizeIdentifierPart(value: string): string {\n return value.toLowerCase().replaceAll(/[^a-z0-9_]/g, \"_\");\n}\n\n/**\n * Deterministic 8-char hash for collision-safe truncation of over-long\n * identifiers. Self-contained so the strategy layer has no backend-runtime\n * dependency.\n */\nfunction shortHash(input: string): string {\n let h1 = 0xde_ad_be_ef;\n let h2 = 0x41_c6_ce_57;\n for (let index = 0; index < input.length; index++) {\n const ch = input.codePointAt(index)!;\n h1 = Math.imul(h1 ^ ch, 0x9e_37_79_b1);\n h2 = Math.imul(h2 ^ ch, 0x5f_35_64_95);\n }\n h1 =\n Math.imul(h1 ^ (h1 >>> 16), 0x85_eb_ca_6b) ^\n Math.imul(h2 ^ (h2 >>> 13), 0xc2_b2_ae_35);\n h2 =\n Math.imul(h2 ^ (h2 >>> 16), 0x85_eb_ca_6b) ^\n Math.imul(h1 ^ (h1 >>> 13), 0xc2_b2_ae_35);\n const hi = (h2 >>> 0).toString(16).padStart(8, \"0\");\n const lo = (h1 >>> 0).toString(16).padStart(8, \"0\");\n return `${hi}${lo}`.slice(0, 8);\n}\n\n/**\n * Deterministic per-`(graphId, nodeKind, fieldPath)` physical name. Shared by\n * every strategy's `tableName`, by index naming, and by the compiler's\n * per-field table resolution so all three agree on which physical object backs\n * a field in a graph. Truncated with a hash suffix past the 63-char ceiling;\n * the hash covers all three parts, so truncation stays collision-safe even\n * when long graph ids dominate the prefix.\n *\n * @example `vectorPhysicalName(\"tg_vec\", \"g1\", \"Document\", \"embedding\")`\n * → `\"tg_vec_g1_document_embedding_<hash8>\"`\n */\nexport function vectorPhysicalName(\n prefix: string,\n graphId: string,\n nodeKind: string,\n fieldPath: string,\n): string {\n const readable = `${prefix}_${sanitizeIdentifierPart(graphId)}_${sanitizeIdentifierPart(nodeKind)}_${sanitizeIdentifierPart(fieldPath)}`;\n // Always suffix a hash of the EXACT (graphId, nodeKind, fieldPath) tuple.\n // Sanitization is lossy (case-folding, every non-`[a-z0-9_]` char → `_`) and\n // the `_` join is ambiguous, so distinct fields can share a readable part —\n // e.g. (\"a_b\",\"c\") vs (\"a\",\"b_c\"), or \"Doc-A\" vs \"Doc_A\" vs \"doc\". The hash\n // keeps their physical tables distinct so writes/searches never cross fields.\n const hash = shortHash(JSON.stringify([graphId, nodeKind, fieldPath]));\n const full = `${readable}_${hash}`;\n if (full.length <= MAX_VECTOR_IDENTIFIER_LENGTH) return full;\n // Over the ceiling: truncate the readable part, always keep the hash.\n return `${readable.slice(0, MAX_VECTOR_IDENTIFIER_LENGTH - 1 - hash.length)}_${hash}`;\n}\n\n/**\n * Double-quote a SQL identifier, escaping embedded quotes. Dialect-neutral\n * (both SQLite and Postgres use `\"...\"`), so the three vector strategies share\n * one implementation for quoting their per-field table / index names.\n */\nexport function quoteIdentifier(name: string): string {\n return `\"${name.replaceAll('\"', '\"\"')}\"`;\n}\n","/**\n * PostgreSQL Dialect Adapter\n *\n * Implements dialect-specific SQL generation for PostgreSQL databases.\n * Uses PostgreSQL's native JSONB operators for JSON operations.\n */\nimport { type SQL, sql } from \"drizzle-orm\";\n\nimport { type JsonPointer, parseJsonPointer } from \"../json-pointer\";\nimport { tsvectorStrategy } from \"./fulltext-strategy\";\nimport { likeEscapeClause } from \"./like-escape\";\nimport { type DialectAdapter } from \"./types\";\n\n/**\n * Escapes a string for use in a PostgreSQL string literal.\n * Uses single quotes and escapes embedded single quotes.\n */\nfunction escapePostgresLiteral(value: string): string {\n // PostgreSQL uses '' to escape single quotes inside string literals\n return `'${value.replaceAll(\"'\", \"''\")}'`;\n}\n\n/**\n * Converts a JSON pointer to PostgreSQL's text array path.\n *\n * Uses raw SQL (non-parameterized) to ensure the same expression text\n * is generated when the same field is used in multiple clauses (SELECT, GROUP BY).\n * This is safe because JSON pointers come from schema definitions, not user input.\n *\n * @example\n * \"/name\" → ARRAY['name']\n * \"/items/0\" → ARRAY['items', '0']\n * \"/a/b/c\" → ARRAY['a', 'b', 'c']\n */\nfunction toPostgresPath(pointer: JsonPointer): SQL {\n if (!pointer || pointer === \"\" || pointer === \"/\") {\n return sql.raw(\"ARRAY[]::text[]\");\n }\n\n const segments = parseJsonPointer(pointer);\n if (segments.length === 0) {\n return sql.raw(\"ARRAY[]::text[]\");\n }\n\n // Use raw SQL for path segments to ensure identical SQL text\n // when the same field is used in multiple clauses (e.g., SELECT and GROUP BY)\n const escapedSegments = segments\n .map((segment) => escapePostgresLiteral(segment))\n .join(\", \");\n return sql.raw(`ARRAY[${escapedSegments}]`);\n}\n\n/**\n * PostgreSQL dialect adapter implementation.\n */\nexport const postgresDialect: DialectAdapter = {\n name: \"postgres\",\n capabilities: {\n standardQueryStrategy: \"cte_project\",\n recursiveQueryStrategy: \"recursive_cte\",\n materializeIntermediateTraversalCtes: false,\n emitNotMaterializedHint: true,\n forceRecursiveWorktableOuterJoinOrder: false,\n vectorPredicateStrategy: \"native\",\n vectorMetrics: [\"cosine\", \"l2\", \"inner_product\"] as const,\n supportsFulltext: true,\n },\n\n // ============================================================\n // JSON Path Operations\n // ============================================================\n\n compilePath(pointer) {\n return toPostgresPath(pointer);\n },\n\n jsonExtract(column, pointer) {\n // #> returns JSONB value at path\n const path = toPostgresPath(pointer);\n return sql`${column} #> ${path}`;\n },\n\n jsonExtractText(column, pointer) {\n // #>> returns text value at path\n const path = toPostgresPath(pointer);\n return sql`${column} #>> ${path}`;\n },\n\n jsonExtractNumber(column, pointer) {\n // Extract as text then cast to numeric\n const path = toPostgresPath(pointer);\n return sql`(${column} #>> ${path})::numeric`;\n },\n\n jsonExtractBoolean(column, pointer) {\n // Extract as text then cast to boolean\n const path = toPostgresPath(pointer);\n return sql`(${column} #>> ${path})::boolean`;\n },\n\n jsonExtractDate(column, pointer) {\n // Extract as text then cast to timestamptz\n const path = toPostgresPath(pointer);\n return sql`(${column} #>> ${path})::timestamptz`;\n },\n\n // ============================================================\n // JSON Array Operations\n // ============================================================\n\n jsonArrayLength(column) {\n return sql`jsonb_array_length(${column})`;\n },\n\n jsonArrayContains(column, value) {\n // @> checks if left contains right\n const jsonValue = JSON.stringify([value]);\n return sql`${column} @> ${jsonValue}::jsonb`;\n },\n\n jsonArrayContainsAll(column, values) {\n if (values.length === 0) {\n return sql.raw(\"1=1\");\n }\n\n // @> with full array checks all values\n const jsonValue = JSON.stringify(values);\n return sql`${column} @> ${jsonValue}::jsonb`;\n },\n\n jsonArrayContainsAny(column, values) {\n if (values.length === 0) {\n return sql.raw(\"1=0\");\n }\n\n // Check each value with @> and OR them together\n // PostgreSQL doesn't have a native \"overlaps\" for jsonb arrays\n const conditions = values.map((value) => {\n const jsonValue = JSON.stringify([value]);\n return sql`${column} @> ${jsonValue}::jsonb`;\n });\n return sql`(${sql.join(conditions, sql` OR `)})`;\n },\n\n // ============================================================\n // JSON Object Operations\n // ============================================================\n\n jsonHasPath(column, pointer) {\n const path = toPostgresPath(pointer);\n return sql`${column} #> ${path} IS NOT NULL`;\n },\n\n jsonPathIsNull(column, pointer) {\n const path = toPostgresPath(pointer);\n // Check both SQL NULL and JSON null literal\n return sql`(${column} #> ${path} IS NULL OR ${column} #>> ${path} = 'null')`;\n },\n\n jsonPathIsNotNull(column, pointer) {\n const path = toPostgresPath(pointer);\n return sql`(${column} #> ${path} IS NOT NULL AND ${column} #>> ${path} != 'null')`;\n },\n\n // ============================================================\n // Comparison Operations\n // ============================================================\n\n nullSafeEquals(left, right) {\n return sql`${left} IS NOT DISTINCT FROM ${right}`;\n },\n\n // ============================================================\n // String Operations\n // ============================================================\n\n ilike(column, pattern) {\n // PostgreSQL has native ILIKE operator. Declaring backslash as the escape\n // character is a no-op (it is the LIKE default) but keeps the emitted SQL\n // identical in intent to SQLite, which has no default escape character.\n return sql`${column} ILIKE ${pattern} ${likeEscapeClause}`;\n },\n\n // ============================================================\n // Set Operations\n // ============================================================\n\n wrapSetOperationOperand(inner) {\n // PostgreSQL allows a complete SELECT (incl. its own WITH) as a\n // parenthesized compound operand.\n return sql`(${inner})`;\n },\n\n // ============================================================\n // Recursive CTE Path Operations\n // ============================================================\n\n initializePath(nodeId) {\n // PostgreSQL uses text arrays: ARRAY[id]\n return sql`ARRAY[${nodeId}]`;\n },\n\n extendPath(currentPath, nodeId) {\n // Array concatenation: path || id\n return sql`${currentPath} || ${nodeId}`;\n },\n\n cycleCheck(nodeId, path) {\n // Check that id is NOT in array path\n // Returns TRUE if no cycle (id not in array)\n return sql`${nodeId} != ALL(${path})`;\n },\n\n // ============================================================\n // Type Utilities\n // ============================================================\n\n currentTimestamp() {\n return sql`NOW()`;\n },\n\n // ============================================================\n // Value Binding & Literals\n // ============================================================\n\n bindValue(value) {\n // PostgreSQL supports native booleans, no conversion needed\n return value;\n },\n\n booleanLiteral(value) {\n return sql.raw(this.booleanLiteralString(value));\n },\n\n booleanLiteralString(value) {\n return value ? \"TRUE\" : \"FALSE\";\n },\n\n quoteIdentifier(name) {\n // PostgreSQL uses double quotes, escape embedded quotes by doubling\n return `\"${name.replaceAll('\"', '\"\"')}\"`;\n },\n\n // ============================================================\n // Vector Operations\n // ============================================================\n\n // Compile-time gate for `field.similarTo(...)`; the active\n // `VectorStrategy` (pgvector) owns the distance SQL.\n supportsVectors: true,\n\n // ============================================================\n // Fulltext Operations\n // ============================================================\n\n fulltext: tsvectorStrategy,\n};\n","/**\n * SQLite Dialect Adapter\n *\n * Implements dialect-specific SQL generation for SQLite databases.\n * Uses SQLite's JSON1 extension for JSON operations.\n */\nimport { sql } from \"drizzle-orm\";\n\nimport { type JsonPointer, parseJsonPointer } from \"../json-pointer\";\nimport { fts5Strategy } from \"./fulltext-strategy\";\nimport { likeEscapeClause } from \"./like-escape\";\nimport { type DialectAdapter } from \"./types\";\n\n/**\n * Escapes a string for use in a SQLite string literal.\n * SQLite uses single quotes and escapes embedded single quotes by doubling them.\n */\nfunction escapeSqliteLiteral(value: string): string {\n return `'${value.replaceAll(\"'\", \"''\")}'`;\n}\n\n/**\n * Converts a JSON pointer to SQLite's JSON path syntax.\n *\n * @example\n * \"/name\" → \"$.\\\"name\\\"\"\n * \"/items/0\" → \"$.\\\"items\\\"[0]\"\n * \"/a/b/c\" → \"$.\\\"a\\\".\\\"b\\\".\\\"c\\\"\"\n */\nfunction toSqlitePath(pointer: JsonPointer): string {\n if (!pointer || pointer === \"\" || pointer === \"/\") {\n return \"$\";\n }\n\n const segments = parseJsonPointer(pointer);\n const parts: string[] = [\"$\"];\n\n for (const segment of segments) {\n if (isArrayIndex(segment)) {\n parts.push(`[${segment}]`);\n } else {\n // Quote the key to handle special characters\n parts.push(`.${JSON.stringify(segment)}`);\n }\n }\n\n return parts.join(\"\");\n}\n\n/**\n * Checks if a JSON pointer segment is an array index.\n */\nfunction isArrayIndex(segment: string): boolean {\n return /^\\d+$/.test(segment);\n}\n\n/**\n * SQLite dialect adapter implementation.\n */\nexport const sqliteDialect: DialectAdapter = {\n name: \"sqlite\",\n capabilities: {\n standardQueryStrategy: \"cte_project\",\n recursiveQueryStrategy: \"recursive_cte\",\n materializeIntermediateTraversalCtes: true,\n emitNotMaterializedHint: false,\n forceRecursiveWorktableOuterJoinOrder: true,\n vectorPredicateStrategy: \"native\",\n vectorMetrics: [\"cosine\", \"l2\"] as const,\n supportsFulltext: true,\n },\n\n // ============================================================\n // JSON Path Operations\n // ============================================================\n\n compilePath(pointer) {\n // Use raw SQL to ensure the path is a literal, which allows expression\n // indexes on json_extract(...) to be used by the query planner.\n return sql.raw(escapeSqliteLiteral(toSqlitePath(pointer)));\n },\n\n jsonExtract(column, pointer) {\n const path = toSqlitePath(pointer);\n return sql`json_extract(${column}, ${sql.raw(escapeSqliteLiteral(path))})`;\n },\n\n jsonExtractText(column, pointer) {\n // SQLite's json_extract returns the native JSON type, which works\n // for text comparisons. For explicit text, we use the same function.\n const path = toSqlitePath(pointer);\n return sql`json_extract(${column}, ${sql.raw(escapeSqliteLiteral(path))})`;\n },\n\n jsonExtractNumber(column, pointer) {\n // SQLite json_extract returns numbers natively when the value is numeric\n const path = toSqlitePath(pointer);\n return sql`json_extract(${column}, ${sql.raw(escapeSqliteLiteral(path))})`;\n },\n\n jsonExtractBoolean(column, pointer) {\n // SQLite json_extract returns 0/1 for boolean values\n const path = toSqlitePath(pointer);\n return sql`json_extract(${column}, ${sql.raw(escapeSqliteLiteral(path))})`;\n },\n\n jsonExtractDate(column, pointer) {\n // SQLite stores dates as ISO strings, json_extract returns them as text\n const path = toSqlitePath(pointer);\n return sql`json_extract(${column}, ${sql.raw(escapeSqliteLiteral(path))})`;\n },\n\n // ============================================================\n // JSON Array Operations\n // ============================================================\n\n jsonArrayLength(column) {\n return sql`json_array_length(${column})`;\n },\n\n jsonArrayContains(column, value) {\n return sql`EXISTS (SELECT 1 FROM json_each(${column}) WHERE json_each.value = ${value})`;\n },\n\n jsonArrayContainsAll(column, values) {\n if (values.length === 0) {\n return sql.raw(\"1=1\");\n }\n\n const conditions = values.map(\n (value) =>\n sql`EXISTS (SELECT 1 FROM json_each(${column}) WHERE json_each.value = ${value})`,\n );\n return sql`(${sql.join(conditions, sql` AND `)})`;\n },\n\n jsonArrayContainsAny(column, values) {\n if (values.length === 0) {\n return sql.raw(\"1=0\");\n }\n\n const conditions = values.map(\n (value) =>\n sql`EXISTS (SELECT 1 FROM json_each(${column}) WHERE json_each.value = ${value})`,\n );\n return sql`(${sql.join(conditions, sql` OR `)})`;\n },\n\n // ============================================================\n // JSON Object Operations\n // ============================================================\n\n jsonHasPath(column, pointer) {\n const path = toSqlitePath(pointer);\n return sql`json_type(${column}, ${sql.raw(escapeSqliteLiteral(path))}) IS NOT NULL`;\n },\n\n jsonPathIsNull(column, pointer) {\n const path = toSqlitePath(pointer);\n const pathSql = sql.raw(escapeSqliteLiteral(path));\n return sql`(json_extract(${column}, ${pathSql}) IS NULL OR json_type(${column}, ${pathSql}) = 'null')`;\n },\n\n jsonPathIsNotNull(column, pointer) {\n const path = toSqlitePath(pointer);\n const pathSql = sql.raw(escapeSqliteLiteral(path));\n return sql`(json_extract(${column}, ${pathSql}) IS NOT NULL AND json_type(${column}, ${pathSql}) != 'null')`;\n },\n\n // ============================================================\n // Comparison Operations\n // ============================================================\n\n nullSafeEquals(left, right) {\n // SQLite's IS operator is null-safe equality (equivalent to = for\n // non-null operands, TRUE when both sides are NULL).\n return sql`${left} IS ${right}`;\n },\n\n // ============================================================\n // String Operations\n // ============================================================\n\n ilike(column, pattern) {\n // SQLite LIKE is case-insensitive for ASCII by default, but we use\n // LOWER() for consistency with non-ASCII characters. SQLite has no default\n // LIKE escape character, so declare backslash explicitly to honor the\n // escaping the compiler applies to the pattern (parity with Postgres).\n return sql`LOWER(${column}) LIKE LOWER(${pattern}) ${likeEscapeClause}`;\n },\n\n // ============================================================\n // Set Operations\n // ============================================================\n\n wrapSetOperationOperand(inner) {\n // SQLite forbids parenthesized compound operands, but a FROM-subquery may\n // carry its own WITH clause, so wrap each operand as a subquery.\n return sql`SELECT * FROM (${inner})`;\n },\n\n // ============================================================\n // Recursive CTE Path Operations\n // ============================================================\n\n initializePath(nodeId) {\n // SQLite uses string-based paths with delimiters: '|id|'\n return sql`'|' || ${nodeId} || '|'`;\n },\n\n extendPath(currentPath, nodeId) {\n // Append: path || id || '|'\n return sql`${currentPath} || ${nodeId} || '|'`;\n },\n\n cycleCheck(nodeId, path) {\n // Check that id is NOT in path using INSTR\n // Returns TRUE if no cycle (id not found in path)\n return sql`INSTR(${path}, '|' || ${nodeId} || '|') = 0`;\n },\n\n // ============================================================\n // Type Utilities\n // ============================================================\n\n currentTimestamp() {\n // Keep ISO-8601 format aligned with stored timestamps from Date.toISOString()\n // so string-based temporal comparisons remain correct in SQLite TEXT columns.\n return sql`strftime('%Y-%m-%dT%H:%M:%fZ', 'now')`;\n },\n\n // ============================================================\n // Value Binding & Literals\n // ============================================================\n\n bindValue(value) {\n // SQLite doesn't support native booleans, convert to 0/1\n if (typeof value === \"boolean\") {\n return value ? 1 : 0;\n }\n return value;\n },\n\n booleanLiteral(value) {\n return sql.raw(this.booleanLiteralString(value));\n },\n\n booleanLiteralString(value) {\n return value ? \"1\" : \"0\";\n },\n\n quoteIdentifier(name) {\n // SQLite uses double quotes (or backticks), escape embedded quotes by doubling\n return `\"${name.replaceAll('\"', '\"\"')}\"`;\n },\n\n // ============================================================\n // Vector Operations\n // ============================================================\n\n // Compile-time gate for `field.similarTo(...)`; the active\n // `VectorStrategy` (sqlite-vec / libSQL-native) owns the distance SQL.\n supportsVectors: true,\n\n // ============================================================\n // Fulltext Operations\n // ============================================================\n\n fulltext: fts5Strategy,\n};\n","/**\n * SQL Dialect Module\n *\n * Provides dialect adapters for different SQL databases.\n * Use `getDialect()` to get the appropriate adapter for a dialect name.\n */\n\nexport type { FulltextStrategy } from \"./fulltext-strategy\";\nexport {\n ALL_FULLTEXT_MODES,\n buildFulltextCapabilities,\n fts5Strategy,\n tsvectorStrategy,\n} from \"./fulltext-strategy\";\nexport { postgresDialect } from \"./postgres\";\nexport { sqliteDialect } from \"./sqlite\";\nexport type {\n DialectAdapter,\n DialectCapabilities,\n DialectRecursiveQueryStrategy,\n DialectStandardQueryStrategy,\n DialectVectorPredicateStrategy,\n SqlDialect,\n} from \"./types\";\nexport {\n buildVectorCapabilities,\n type VectorSlot,\n type VectorStrategy,\n} from \"./vector-strategy\";\n\nimport { postgresDialect } from \"./postgres\";\nimport { sqliteDialect } from \"./sqlite\";\nimport { type DialectAdapter, type SqlDialect } from \"./types\";\n\n/**\n * Map of dialect names to their adapters.\n */\nconst DIALECT_ADAPTERS: Record<SqlDialect, DialectAdapter> = {\n sqlite: sqliteDialect,\n postgres: postgresDialect,\n};\n\n/**\n * Gets the dialect adapter for a given dialect name.\n *\n * @param dialect - The dialect name (\"sqlite\" or \"postgres\")\n * @returns The dialect adapter\n *\n * @example\n * ```typescript\n * const adapter = getDialect(\"postgres\");\n * const sql = adapter.jsonExtract(column, \"/name\");\n * ```\n */\nexport function getDialect(dialect: SqlDialect): DialectAdapter {\n return DIALECT_ADAPTERS[dialect];\n}\n\n/**\n * Default dialect used when none is specified.\n */\nexport const DEFAULT_DIALECT: SqlDialect = \"sqlite\";\n","import { type SQL, sql } from \"drizzle-orm\";\n\nimport { type ValueType } from \"../query/ast\";\nimport { getDialect } from \"../query/dialect\";\nimport { type SqlDialect } from \"../query/dialect/types\";\nimport { type JsonPointer, jsonPointer } from \"../query/json-pointer\";\nimport {\n type EdgeIndexDeclaration,\n type IndexWhereExpression,\n type IndexWhereLiteral,\n type IndexWhereOp,\n type IndexWhereOperand,\n type NodeIndexDeclaration,\n type SystemColumnName,\n} from \"./types\";\n\n// ============================================================\n// Public Types\n// ============================================================\n\nexport type IndexCompilationContext = Readonly<{\n dialect: SqlDialect;\n propsColumn: SQL;\n systemColumn: (column: SystemColumnName) => SQL;\n}>;\n\ntype CompiledIndexKeys = Readonly<{\n /** SQL expressions in index key order */\n keys: readonly SQL[];\n}>;\n\n// ============================================================\n// Index Key Compilation\n// ============================================================\n\nexport function compileNodeIndexKeys(\n index: NodeIndexDeclaration,\n dialect: SqlDialect,\n propsColumn: SQL,\n systemColumn: (column: SystemColumnName) => SQL,\n): CompiledIndexKeys {\n const adapter = getDialect(dialect);\n const keys: SQL[] = [];\n\n for (const column of getNodeScopeColumns(index.scope)) {\n keys.push(systemColumn(column));\n }\n\n const allPointers = [...index.fields, ...index.coveringFields];\n const allValueTypes = [\n ...index.fieldValueTypes,\n ...index.coveringFieldValueTypes,\n ];\n\n for (const [pointerIndex, pointer] of allPointers.entries()) {\n const valueType = allValueTypes[pointerIndex];\n const extracted = compileIndexKeyValue(\n adapter,\n propsColumn,\n pointer,\n valueType,\n );\n keys.push(sql`(${extracted})`);\n }\n\n return { keys };\n}\n\nexport function compileEdgeIndexKeys(\n index: EdgeIndexDeclaration,\n dialect: SqlDialect,\n propsColumn: SQL,\n systemColumn: (column: SystemColumnName) => SQL,\n): CompiledIndexKeys {\n const adapter = getDialect(dialect);\n const keys: SQL[] = [];\n\n for (const column of getEdgeScopeColumns(index.scope, index.direction)) {\n keys.push(systemColumn(column));\n }\n\n const allPointers = [...index.fields, ...index.coveringFields];\n const allValueTypes = [\n ...index.fieldValueTypes,\n ...index.coveringFieldValueTypes,\n ];\n\n for (const [pointerIndex, pointer] of allPointers.entries()) {\n const valueType = allValueTypes[pointerIndex];\n const extracted = compileIndexKeyValue(\n adapter,\n propsColumn,\n pointer,\n valueType,\n );\n keys.push(sql`(${extracted})`);\n }\n\n return { keys };\n}\n\n/**\n * Compiles the per-field key-extraction expressions for a node index's\n * **lookup keys** — `index.fields` only, excluding scope columns and\n * `coveringFields` (which are index payload, not part of the lookup key).\n *\n * Each expression is the exact extraction the index DDL builds for that\n * field (via the shared {@link compileIndexKeyValue}), so a runtime lookup\n * predicate stays byte-identical to the materialized index expression —\n * the single source of truth that lets the planner use the physical index.\n */\nexport function compileNodeIndexFieldKeys(\n index: NodeIndexDeclaration,\n ctx: IndexCompilationContext,\n): readonly SQL[] {\n const adapter = getDialect(ctx.dialect);\n const keys: SQL[] = [];\n for (const [position, pointer] of index.fields.entries()) {\n const extracted = compileIndexKeyValue(\n adapter,\n ctx.propsColumn,\n pointer,\n index.fieldValueTypes[position],\n );\n keys.push(sql`(${extracted})`);\n }\n return keys;\n}\n\nfunction compileIndexKeyValue(\n dialect: ReturnType<typeof getDialect>,\n propsColumn: SQL,\n pointer: JsonPointer,\n valueType: ValueType | undefined,\n): SQL {\n switch (valueType) {\n case \"number\": {\n return dialect.jsonExtractNumber(propsColumn, pointer);\n }\n case \"boolean\": {\n return dialect.jsonExtractBoolean(propsColumn, pointer);\n }\n case \"date\": {\n return dialect.jsonExtractDate(propsColumn, pointer);\n }\n case \"string\":\n case \"unknown\":\n case undefined: {\n return dialect.jsonExtractText(propsColumn, pointer);\n }\n case \"array\":\n case \"object\":\n case \"embedding\": {\n // For advanced index types (GIN/json), callers should use dialect.jsonExtract\n // or index the props column directly. We keep this as a conservative fallback.\n return dialect.jsonExtract(propsColumn, pointer);\n }\n }\n}\n\nfunction getNodeScopeColumns(\n scope: NodeIndexDeclaration[\"scope\"],\n): readonly SystemColumnName[] {\n switch (scope) {\n case \"graphAndKind\": {\n return [\"graph_id\", \"kind\"];\n }\n case \"graph\": {\n return [\"graph_id\"];\n }\n case \"none\": {\n return [];\n }\n }\n}\n\nfunction getEdgeScopeColumns(\n scope: EdgeIndexDeclaration[\"scope\"],\n direction: EdgeIndexDeclaration[\"direction\"],\n): readonly SystemColumnName[] {\n const base =\n scope === \"graphAndKind\" ? ([\"graph_id\", \"kind\"] as const)\n : scope === \"graph\" ? ([\"graph_id\"] as const)\n : ([] as const);\n\n if (direction === \"out\") {\n return [...base, \"from_id\"];\n }\n if (direction === \"in\") {\n return [...base, \"to_id\"];\n }\n return [...base];\n}\n\n// ============================================================\n// WHERE Clause Compilation\n// ============================================================\n\nfunction isIndexWhereLiteralList(\n value: IndexWhereLiteral | readonly IndexWhereLiteral[],\n): value is readonly IndexWhereLiteral[] {\n return Array.isArray(value);\n}\n\nexport function compileIndexWhere(\n ctx: IndexCompilationContext,\n expression: IndexWhereExpression,\n): SQL {\n switch (expression.__type) {\n case \"index_where_and\": {\n return sql`(${sql.join(\n expression.predicates.map((p) => compileIndexWhere(ctx, p)),\n sql` AND `,\n )})`;\n }\n case \"index_where_or\": {\n return sql`(${sql.join(\n expression.predicates.map((p) => compileIndexWhere(ctx, p)),\n sql` OR `,\n )})`;\n }\n case \"index_where_not\": {\n return sql`(NOT ${compileIndexWhere(ctx, expression.predicate)})`;\n }\n case \"index_where_null_check\": {\n const operand = compileIndexWhereOperand(ctx, expression.operand);\n return expression.op === \"isNull\" ?\n sql`${operand} IS NULL`\n : sql`${operand} IS NOT NULL`;\n }\n case \"index_where_comparison\": {\n const left = compileIndexWhereOperand(ctx, expression.left);\n\n const right = expression.right;\n if (isIndexWhereLiteralList(right)) {\n if (expression.op !== \"in\" && expression.op !== \"notIn\") {\n throw new Error(\n `Operator \"${expression.op}\" does not support list comparison in index WHERE clause`,\n );\n }\n const values = right.map((literal) =>\n compileIndexWhereLiteral(ctx.dialect, literal),\n );\n const operator = expression.op === \"in\" ? sql`IN` : sql`NOT IN`;\n return sql`${left} ${operator} (${sql.join(values, sql`, `)})`;\n }\n\n if (expression.op === \"in\" || expression.op === \"notIn\") {\n throw new Error(\n `Operator \"${expression.op}\" requires a list of values in index WHERE clause`,\n );\n }\n\n const rightLiteral = compileIndexWhereLiteral(ctx.dialect, right);\n const opSql = compileComparisonOperator(expression.op);\n return sql`${left} ${opSql} ${rightLiteral}`;\n }\n }\n}\n\nfunction compileIndexWhereOperand(\n ctx: IndexCompilationContext,\n operand: IndexWhereOperand,\n): SQL {\n if (operand.__type === \"index_operand_system\") {\n return ctx.systemColumn(operand.column);\n }\n\n const adapter = getDialect(ctx.dialect);\n const pointer = jsonPointer([operand.field]);\n\n switch (operand.valueType) {\n case \"number\": {\n return adapter.jsonExtractNumber(ctx.propsColumn, pointer);\n }\n case \"boolean\": {\n return adapter.jsonExtractBoolean(ctx.propsColumn, pointer);\n }\n case \"date\": {\n return adapter.jsonExtractDate(ctx.propsColumn, pointer);\n }\n case \"array\":\n case \"object\":\n case \"embedding\": {\n return adapter.jsonExtract(ctx.propsColumn, pointer);\n }\n case \"string\":\n case \"unknown\":\n case undefined: {\n return adapter.jsonExtractText(ctx.propsColumn, pointer);\n }\n }\n}\n\nfunction compileIndexWhereLiteral(\n dialect: SqlDialect,\n literal: IndexWhereLiteral,\n): SQL {\n switch (literal.valueType) {\n case \"string\":\n case \"date\": {\n return sql.raw(escapeStringLiteral(literal.value.toString()));\n }\n case \"number\": {\n return sql.raw(literal.value.toString());\n }\n case \"boolean\": {\n return getDialect(dialect).booleanLiteral(literal.value as boolean);\n }\n case \"array\":\n case \"object\":\n case \"embedding\":\n case \"unknown\": {\n return sql.raw(escapeStringLiteral(literal.value.toString()));\n }\n }\n}\n\ntype ComparisonIndexWhereOp = Exclude<IndexWhereOp, \"in\" | \"notIn\">;\n\nfunction compileComparisonOperator(op: ComparisonIndexWhereOp): SQL {\n switch (op) {\n case \"eq\": {\n return sql`=`;\n }\n case \"neq\": {\n return sql`<>`;\n }\n case \"gt\": {\n return sql`>`;\n }\n case \"gte\": {\n return sql`>=`;\n }\n case \"lt\": {\n return sql`<`;\n }\n case \"lte\": {\n return sql`<=`;\n }\n }\n}\n\nfunction escapeStringLiteral(value: string): string {\n return `'${value.replaceAll(\"'\", \"''\")}'`;\n}\n"]}