@nicia-ai/typegraph 0.49.0 → 0.51.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 (370) hide show
  1. package/README.md +12 -0
  2. package/dist/backend/drizzle/indexes.cjs +11 -9
  3. package/dist/backend/drizzle/indexes.d.cts +1 -1
  4. package/dist/backend/drizzle/indexes.d.ts +1 -1
  5. package/dist/backend/drizzle/indexes.js +7 -5
  6. package/dist/backend/index.cjs +190 -53
  7. package/dist/backend/index.d.cts +90 -4
  8. package/dist/backend/index.d.ts +90 -4
  9. package/dist/backend/index.js +9 -12
  10. package/dist/backend/postgres/index.cjs +36 -28
  11. package/dist/backend/postgres/index.d.cts +7 -7
  12. package/dist/backend/postgres/index.d.ts +7 -7
  13. package/dist/backend/postgres/index.js +19 -15
  14. package/dist/backend/postgres/pglite-store.cjs +7 -62
  15. package/dist/backend/postgres/pglite-store.cjs.map +1 -1
  16. package/dist/backend/postgres/pglite-store.d.cts +8 -8
  17. package/dist/backend/postgres/pglite-store.d.ts +8 -8
  18. package/dist/backend/postgres/pglite-store.js +7 -62
  19. package/dist/backend/postgres/pglite-store.js.map +1 -1
  20. package/dist/backend/postgres/pglite.cjs +21 -17
  21. package/dist/backend/postgres/pglite.d.cts +3 -3
  22. package/dist/backend/postgres/pglite.d.ts +3 -3
  23. package/dist/backend/postgres/pglite.js +20 -16
  24. package/dist/backend/sqlite/index.cjs +33 -25
  25. package/dist/backend/sqlite/index.d.cts +7 -7
  26. package/dist/backend/sqlite/index.d.ts +7 -7
  27. package/dist/backend/sqlite/index.js +17 -13
  28. package/dist/backend/sqlite/libsql.cjs +24 -20
  29. package/dist/backend/sqlite/libsql.cjs.map +1 -1
  30. package/dist/backend/sqlite/libsql.d.cts +3 -3
  31. package/dist/backend/sqlite/libsql.d.ts +3 -3
  32. package/dist/backend/sqlite/libsql.js +19 -15
  33. package/dist/backend/sqlite/libsql.js.map +1 -1
  34. package/dist/backend/sqlite/local-store.cjs +9 -64
  35. package/dist/backend/sqlite/local-store.cjs.map +1 -1
  36. package/dist/backend/sqlite/local-store.d.cts +8 -8
  37. package/dist/backend/sqlite/local-store.d.ts +8 -8
  38. package/dist/backend/sqlite/local-store.js +8 -64
  39. package/dist/backend/sqlite/local-store.js.map +1 -1
  40. package/dist/backend/sqlite/local.cjs +25 -20
  41. package/dist/backend/sqlite/local.d.cts +3 -3
  42. package/dist/backend/sqlite/local.d.ts +3 -3
  43. package/dist/backend/sqlite/local.js +21 -16
  44. package/dist/chunk-2CVDZCXH.cjs +1278 -0
  45. package/dist/chunk-2CVDZCXH.cjs.map +1 -0
  46. package/dist/{chunk-MYKHJI2J.js → chunk-2DWTBNSH.js} +3 -3
  47. package/dist/{chunk-MYKHJI2J.js.map → chunk-2DWTBNSH.js.map} +1 -1
  48. package/dist/{chunk-JB6T4GLL.cjs → chunk-2KCTP3U2.cjs} +870 -528
  49. package/dist/chunk-2KCTP3U2.cjs.map +1 -0
  50. package/dist/{chunk-OORXGFL5.cjs → chunk-322TBTOQ.cjs} +48 -48
  51. package/dist/{chunk-OORXGFL5.cjs.map → chunk-322TBTOQ.cjs.map} +1 -1
  52. package/dist/{chunk-FA2AFWLP.cjs → chunk-36SX6QXP.cjs} +31 -12
  53. package/dist/chunk-36SX6QXP.cjs.map +1 -0
  54. package/dist/{chunk-SDBBMD4N.js → chunk-36VYWVQU.js} +3 -3
  55. package/dist/{chunk-SDBBMD4N.js.map → chunk-36VYWVQU.js.map} +1 -1
  56. package/dist/chunk-4DKY6RIU.js +1253 -0
  57. package/dist/chunk-4DKY6RIU.js.map +1 -0
  58. package/dist/chunk-4QKOZYMV.js +9 -0
  59. package/dist/chunk-4QKOZYMV.js.map +1 -0
  60. package/dist/{chunk-WIC7DRXW.js → chunk-57JM6NW3.js} +9 -19
  61. package/dist/chunk-57JM6NW3.js.map +1 -0
  62. package/dist/chunk-5WWEYV4H.cjs +5113 -0
  63. package/dist/chunk-5WWEYV4H.cjs.map +1 -0
  64. package/dist/chunk-6KQEICJ6.cjs +12 -0
  65. package/dist/{chunk-MKJ4KXL5.cjs.map → chunk-6KQEICJ6.cjs.map} +1 -1
  66. package/dist/{chunk-DZAICA5J.js → chunk-6NKSE5AU.js} +4 -4
  67. package/dist/{chunk-DZAICA5J.js.map → chunk-6NKSE5AU.js.map} +1 -1
  68. package/dist/{chunk-KKBDXCLQ.js → chunk-6NLYIMJO.js} +4 -4
  69. package/dist/{chunk-KKBDXCLQ.js.map → chunk-6NLYIMJO.js.map} +1 -1
  70. package/dist/{chunk-BFUOME67.cjs → chunk-7B7I7YAW.cjs} +20 -11
  71. package/dist/chunk-7B7I7YAW.cjs.map +1 -0
  72. package/dist/{chunk-ZDKTPBGV.js → chunk-7G5IYROL.js} +6 -548
  73. package/dist/chunk-7G5IYROL.js.map +1 -0
  74. package/dist/{chunk-3DMMGT6S.js → chunk-7QFRK6PU.js} +4 -8
  75. package/dist/chunk-7QFRK6PU.js.map +1 -0
  76. package/dist/chunk-A4C4NJ5U.cjs +12 -0
  77. package/dist/chunk-A4C4NJ5U.cjs.map +1 -0
  78. package/dist/{chunk-CHAOFCHV.js → chunk-AH2A74OZ.js} +3 -3
  79. package/dist/{chunk-CHAOFCHV.js.map → chunk-AH2A74OZ.js.map} +1 -1
  80. package/dist/{chunk-UGHQV7MP.cjs → chunk-B3MN7EJR.cjs} +228 -162
  81. package/dist/chunk-B3MN7EJR.cjs.map +1 -0
  82. package/dist/{chunk-TZEGUG6D.cjs → chunk-BZ5MVITP.cjs} +4 -4
  83. package/dist/{chunk-TZEGUG6D.cjs.map → chunk-BZ5MVITP.cjs.map} +1 -1
  84. package/dist/{chunk-YVF2EM7B.js → chunk-CAI6SMP6.js} +3 -3
  85. package/dist/{chunk-YVF2EM7B.js.map → chunk-CAI6SMP6.js.map} +1 -1
  86. package/dist/{chunk-JONXFAPO.js → chunk-CBOD7TXH.js} +5 -5
  87. package/dist/{chunk-JONXFAPO.js.map → chunk-CBOD7TXH.js.map} +1 -1
  88. package/dist/{chunk-FQPEMEWX.cjs → chunk-CRZ56SZU.cjs} +81 -32
  89. package/dist/chunk-CRZ56SZU.cjs.map +1 -0
  90. package/dist/{chunk-DO7SAMEK.cjs → chunk-D3GWARN7.cjs} +47 -47
  91. package/dist/{chunk-DO7SAMEK.cjs.map → chunk-D3GWARN7.cjs.map} +1 -1
  92. package/dist/{chunk-QTD6HX4O.js → chunk-D3OUDFU7.js} +5 -5
  93. package/dist/{chunk-QTD6HX4O.js.map → chunk-D3OUDFU7.js.map} +1 -1
  94. package/dist/{chunk-2QGYQBS2.cjs → chunk-DWUDZ66O.cjs} +10 -10
  95. package/dist/{chunk-2QGYQBS2.cjs.map → chunk-DWUDZ66O.cjs.map} +1 -1
  96. package/dist/chunk-EKG2UXNX.cjs +23 -0
  97. package/dist/chunk-EKG2UXNX.cjs.map +1 -0
  98. package/dist/chunk-FMMW3KX7.cjs +148 -0
  99. package/dist/chunk-FMMW3KX7.cjs.map +1 -0
  100. package/dist/{chunk-XVWOYKIK.js → chunk-FZHF5UWR.js} +3 -3
  101. package/dist/{chunk-XVWOYKIK.js.map → chunk-FZHF5UWR.js.map} +1 -1
  102. package/dist/chunk-H2VWDQWC.cjs +571 -0
  103. package/dist/chunk-H2VWDQWC.cjs.map +1 -0
  104. package/dist/chunk-H4FY6OZK.js +13 -0
  105. package/dist/chunk-H4FY6OZK.js.map +1 -0
  106. package/dist/{chunk-EDN4Y4ZG.cjs → chunk-H5IJSROF.cjs} +9 -15
  107. package/dist/chunk-H5IJSROF.cjs.map +1 -0
  108. package/dist/chunk-HZUB5CON.js +27 -0
  109. package/dist/chunk-HZUB5CON.js.map +1 -0
  110. package/dist/{chunk-NACVVDWB.js → chunk-I5IOSA27.js} +103 -105
  111. package/dist/chunk-I5IOSA27.js.map +1 -0
  112. package/dist/{chunk-OI2GQ25X.cjs → chunk-I7YAY2VQ.cjs} +7 -7
  113. package/dist/{chunk-OI2GQ25X.cjs.map → chunk-I7YAY2VQ.cjs.map} +1 -1
  114. package/dist/chunk-IRCWIA3R.js +20 -0
  115. package/dist/chunk-IRCWIA3R.js.map +1 -0
  116. package/dist/chunk-IVQBLXBK.cjs +55 -0
  117. package/dist/chunk-IVQBLXBK.cjs.map +1 -0
  118. package/dist/{chunk-7SQSZN2J.js → chunk-IZD4HTCP.js} +5 -5
  119. package/dist/{chunk-7SQSZN2J.js.map → chunk-IZD4HTCP.js.map} +1 -1
  120. package/dist/{chunk-3FPR224C.cjs → chunk-JHRUZ73O.cjs} +116 -107
  121. package/dist/chunk-JHRUZ73O.cjs.map +1 -0
  122. package/dist/{chunk-EZEEWCFJ.cjs → chunk-JQKMEKKW.cjs} +525 -298
  123. package/dist/chunk-JQKMEKKW.cjs.map +1 -0
  124. package/dist/chunk-JVA3KDEA.cjs +691 -0
  125. package/dist/chunk-JVA3KDEA.cjs.map +1 -0
  126. package/dist/{chunk-5K2BKEBD.js → chunk-K46SDNQD.js} +10 -4
  127. package/dist/chunk-K46SDNQD.js.map +1 -0
  128. package/dist/{chunk-7LZJNLA5.js → chunk-K67P5DLL.js} +108 -42
  129. package/dist/chunk-K67P5DLL.js.map +1 -0
  130. package/dist/{chunk-3G5W2U2L.cjs → chunk-KACEYDYV.cjs} +335 -258
  131. package/dist/chunk-KACEYDYV.cjs.map +1 -0
  132. package/dist/{chunk-JFRT7S3B.cjs → chunk-L6EVYIID.cjs} +318 -478
  133. package/dist/chunk-L6EVYIID.cjs.map +1 -0
  134. package/dist/{chunk-SHFBB23Q.js → chunk-LI4K2KEJ.js} +6 -4
  135. package/dist/chunk-LI4K2KEJ.js.map +1 -0
  136. package/dist/chunk-LKZDQ2B4.js +1581 -0
  137. package/dist/chunk-LKZDQ2B4.js.map +1 -0
  138. package/dist/{chunk-WODMN3Q2.cjs → chunk-LLFPQOBA.cjs} +27 -27
  139. package/dist/{chunk-WODMN3Q2.cjs.map → chunk-LLFPQOBA.cjs.map} +1 -1
  140. package/dist/{chunk-P6YLZTRE.js → chunk-LZMQ3SFK.js} +3 -3
  141. package/dist/{chunk-P6YLZTRE.js.map → chunk-LZMQ3SFK.js.map} +1 -1
  142. package/dist/{chunk-HEV35TGT.js → chunk-M3VTS3F6.js} +13 -4
  143. package/dist/chunk-M3VTS3F6.js.map +1 -0
  144. package/dist/{chunk-TQHGE7UC.cjs → chunk-M5MSP3BI.cjs} +18 -10
  145. package/dist/chunk-M5MSP3BI.cjs.map +1 -0
  146. package/dist/{chunk-D4QLTJSM.js → chunk-NBOS7BY3.js} +63 -23
  147. package/dist/chunk-NBOS7BY3.js.map +1 -0
  148. package/dist/chunk-NGQDGL5X.js +140 -0
  149. package/dist/chunk-NGQDGL5X.js.map +1 -0
  150. package/dist/{chunk-SIT26LAZ.cjs → chunk-NLX5OWK7.cjs} +33 -5
  151. package/dist/chunk-NLX5OWK7.cjs.map +1 -0
  152. package/dist/chunk-NUQ2YFFH.cjs +1637 -0
  153. package/dist/chunk-NUQ2YFFH.cjs.map +1 -0
  154. package/dist/{chunk-UMGZDVOA.cjs → chunk-OGL4X4PH.cjs} +206 -208
  155. package/dist/chunk-OGL4X4PH.cjs.map +1 -0
  156. package/dist/{chunk-LRQKXRXO.cjs → chunk-OTNTGEXR.cjs} +4 -4
  157. package/dist/{chunk-LRQKXRXO.cjs.map → chunk-OTNTGEXR.cjs.map} +1 -1
  158. package/dist/chunk-OTWE63BW.js +53 -0
  159. package/dist/chunk-OTWE63BW.js.map +1 -0
  160. package/dist/chunk-PC5NGH5A.js +549 -0
  161. package/dist/chunk-PC5NGH5A.js.map +1 -0
  162. package/dist/{chunk-26YKDNUD.cjs → chunk-PS3TUWJM.cjs} +12 -10
  163. package/dist/chunk-PS3TUWJM.cjs.map +1 -0
  164. package/dist/{chunk-OMZ37BM2.js → chunk-PVFFH7TL.js} +5 -5
  165. package/dist/{chunk-OMZ37BM2.js.map → chunk-PVFFH7TL.js.map} +1 -1
  166. package/dist/chunk-QCD5JKU4.cjs +15 -0
  167. package/dist/chunk-QCD5JKU4.cjs.map +1 -0
  168. package/dist/{chunk-UGHG7PGX.js → chunk-QG5VEOKX.js} +30 -4
  169. package/dist/chunk-QG5VEOKX.js.map +1 -0
  170. package/dist/{chunk-TUNPBZY3.cjs → chunk-QLLZM5I3.cjs} +4 -4
  171. package/dist/{chunk-TUNPBZY3.cjs.map → chunk-QLLZM5I3.cjs.map} +1 -1
  172. package/dist/{chunk-BRRP76WO.js → chunk-RCBG6YMT.js} +781 -375
  173. package/dist/chunk-RCBG6YMT.js.map +1 -0
  174. package/dist/{chunk-LTXQOEIC.js → chunk-RI7RJH4G.js} +281 -204
  175. package/dist/chunk-RI7RJH4G.js.map +1 -0
  176. package/dist/{chunk-GYEG3ZLZ.cjs → chunk-RJMHU2MG.cjs} +121 -18
  177. package/dist/chunk-RJMHU2MG.cjs.map +1 -0
  178. package/dist/{chunk-GLHXM7C4.js → chunk-RVUL2HXY.js} +61 -23
  179. package/dist/chunk-RVUL2HXY.js.map +1 -0
  180. package/dist/chunk-RWUWTJQY.cjs +30 -0
  181. package/dist/chunk-RWUWTJQY.cjs.map +1 -0
  182. package/dist/{chunk-2O4PCIZ6.cjs → chunk-S5GU4LUN.cjs} +13 -13
  183. package/dist/{chunk-2O4PCIZ6.cjs.map → chunk-S5GU4LUN.cjs.map} +1 -1
  184. package/dist/{chunk-JPD2CTC3.js → chunk-SDPWO2Z5.js} +7 -7
  185. package/dist/{chunk-JPD2CTC3.js.map → chunk-SDPWO2Z5.js.map} +1 -1
  186. package/dist/{chunk-OVI7IXYX.js → chunk-SLGGT2XD.js} +3 -3
  187. package/dist/{chunk-OVI7IXYX.js.map → chunk-SLGGT2XD.js.map} +1 -1
  188. package/dist/{chunk-ROR5ZR6A.cjs → chunk-TIJUA4I6.cjs} +45 -45
  189. package/dist/{chunk-ROR5ZR6A.cjs.map → chunk-TIJUA4I6.cjs.map} +1 -1
  190. package/dist/{chunk-AOSSQDVO.cjs → chunk-TM54OBHX.cjs} +13 -13
  191. package/dist/{chunk-AOSSQDVO.cjs.map → chunk-TM54OBHX.cjs.map} +1 -1
  192. package/dist/{chunk-KF6K7TGH.js → chunk-TYEYRCXL.js} +766 -433
  193. package/dist/chunk-TYEYRCXL.js.map +1 -0
  194. package/dist/{chunk-Z2JCLZFJ.js → chunk-UKOVGCRN.js} +2151 -570
  195. package/dist/chunk-UKOVGCRN.js.map +1 -0
  196. package/dist/chunk-UYKDYE5D.cjs +12 -0
  197. package/dist/{chunk-CICO5GXD.cjs.map → chunk-UYKDYE5D.cjs.map} +1 -1
  198. package/dist/{chunk-S5TERQVW.js → chunk-VAAC7L57.js} +284 -66
  199. package/dist/chunk-VAAC7L57.js.map +1 -0
  200. package/dist/{chunk-7UOLHNWC.cjs → chunk-VKHXYVN7.cjs} +22 -33
  201. package/dist/chunk-VKHXYVN7.cjs.map +1 -0
  202. package/dist/{chunk-6NGW27EO.cjs → chunk-VLBTRXA2.cjs} +10 -10
  203. package/dist/{chunk-6NGW27EO.cjs.map → chunk-VLBTRXA2.cjs.map} +1 -1
  204. package/dist/{chunk-YIURNGXI.js → chunk-VUQZNUHU.js} +22 -6
  205. package/dist/chunk-VUQZNUHU.js.map +1 -0
  206. package/dist/{chunk-YYUHLYM2.cjs → chunk-WDM5WQK4.cjs} +183 -143
  207. package/dist/chunk-WDM5WQK4.cjs.map +1 -0
  208. package/dist/{chunk-ZFMCDJGB.js → chunk-WFSYYU4W.js} +70 -220
  209. package/dist/chunk-WFSYYU4W.js.map +1 -0
  210. package/dist/{chunk-SR725PWF.cjs → chunk-WRBV2FNH.cjs} +2065 -1659
  211. package/dist/chunk-WRBV2FNH.cjs.map +1 -0
  212. package/dist/{chunk-MRDBBHIZ.cjs → chunk-X4GDXBOP.cjs} +2 -2
  213. package/dist/chunk-X4GDXBOP.cjs.map +1 -0
  214. package/dist/chunk-XORONCV3.js +202 -0
  215. package/dist/chunk-XORONCV3.js.map +1 -0
  216. package/dist/{chunk-D5R42W5D.js → chunk-XZW2CTNO.js} +115 -12
  217. package/dist/chunk-XZW2CTNO.js.map +1 -0
  218. package/dist/{chunk-ZLONH2UD.js → chunk-YDEJQWOL.js} +2 -2
  219. package/dist/chunk-YDEJQWOL.js.map +1 -0
  220. package/dist/{chunk-2TYSSBU5.js → chunk-YT2IVFAI.js} +30 -21
  221. package/dist/chunk-YT2IVFAI.js.map +1 -0
  222. package/dist/chunk-ZGVTNKTX.cjs +217 -0
  223. package/dist/chunk-ZGVTNKTX.cjs.map +1 -0
  224. package/dist/core/index.cjs +29 -28
  225. package/dist/core/index.d.cts +4 -4
  226. package/dist/core/index.d.ts +4 -4
  227. package/dist/core/index.js +9 -8
  228. package/dist/{ddl-D_oW-EVO.d.ts → ddl-BvcbgzHo.d.ts} +3 -3
  229. package/dist/{ddl-BL1NZLMY.d.cts → ddl-Ufebz5q5.d.cts} +3 -3
  230. package/dist/graph-extension/index.cjs +21 -20
  231. package/dist/graph-extension/index.d.cts +2 -4
  232. package/dist/graph-extension/index.d.ts +2 -4
  233. package/dist/graph-extension/index.js +5 -4
  234. package/dist/graph-merge/index.cjs +324 -307
  235. package/dist/graph-merge/index.cjs.map +1 -1
  236. package/dist/graph-merge/index.d.cts +8 -9
  237. package/dist/graph-merge/index.d.ts +8 -9
  238. package/dist/graph-merge/index.js +51 -34
  239. package/dist/graph-merge/index.js.map +1 -1
  240. package/dist/index.cjs +224 -222
  241. package/dist/index.cjs.map +1 -1
  242. package/dist/index.d.cts +11 -12
  243. package/dist/index.d.ts +11 -12
  244. package/dist/index.js +38 -36
  245. package/dist/index.js.map +1 -1
  246. package/dist/indexes/index.cjs +15 -13
  247. package/dist/indexes/index.d.cts +4 -4
  248. package/dist/indexes/index.d.ts +4 -4
  249. package/dist/indexes/index.js +8 -6
  250. package/dist/{ingestion-import-target-dNeL7iAv.d.ts → ingestion-import-target-CAs1OX-l.d.cts} +1 -1
  251. package/dist/{ingestion-import-target-XPxZYw89.d.cts → ingestion-import-target-DCQSPfNx.d.ts} +1 -1
  252. package/dist/interchange/index.cjs +57 -54
  253. package/dist/interchange/index.cjs.map +1 -1
  254. package/dist/interchange/index.d.cts +19 -8
  255. package/dist/interchange/index.d.ts +19 -8
  256. package/dist/interchange/index.js +21 -18
  257. package/dist/interchange/index.js.map +1 -1
  258. package/dist/local-store-impl-6DDTFM32.cjs +77 -0
  259. package/dist/local-store-impl-6DDTFM32.cjs.map +1 -0
  260. package/dist/local-store-impl-OXTOVU2J.js +75 -0
  261. package/dist/local-store-impl-OXTOVU2J.js.map +1 -0
  262. package/dist/{manager-CYaff3n3.d.cts → manager-B68OrPR2.d.ts} +29 -2
  263. package/dist/{manager-D9eRT_ns.d.ts → manager-D_t7oK69.d.cts} +29 -2
  264. package/dist/pglite-store-impl-6EMZGL7K.js +73 -0
  265. package/dist/pglite-store-impl-6EMZGL7K.js.map +1 -0
  266. package/dist/pglite-store-impl-GJG3Y7RP.cjs +75 -0
  267. package/dist/pglite-store-impl-GJG3Y7RP.cjs.map +1 -0
  268. package/dist/{postgres-CcL4bAHS.d.ts → postgres-BPLSVyHM.d.ts} +279 -2
  269. package/dist/{postgres-DMj39MEu.d.cts → postgres-CqvtFC2y.d.cts} +279 -2
  270. package/dist/profiler/index.d.cts +9 -9
  271. package/dist/profiler/index.d.ts +9 -9
  272. package/dist/provenance/index.cjs +59 -44
  273. package/dist/provenance/index.cjs.map +1 -1
  274. package/dist/provenance/index.d.cts +7 -7
  275. package/dist/provenance/index.d.ts +7 -7
  276. package/dist/provenance/index.js +28 -13
  277. package/dist/provenance/index.js.map +1 -1
  278. package/dist/{repair-validity-windows-BFNZvd_H.d.cts → repair-validity-windows-DEzCKAdy.d.cts} +7 -3
  279. package/dist/{repair-validity-windows-DlUSqwCg.d.ts → repair-validity-windows-GMdaS2AH.d.ts} +7 -3
  280. package/dist/resolve-D_H8MHtq.d.ts +1805 -0
  281. package/dist/resolve-WEW8gWws.d.cts +1805 -0
  282. package/dist/schema/index.cjs +48 -46
  283. package/dist/schema/index.d.cts +4 -6
  284. package/dist/schema/index.d.ts +4 -6
  285. package/dist/schema/index.js +21 -19
  286. package/dist/{searchable-bpE1bBfc.d.ts → searchable-C_UREI9K.d.ts} +1 -1
  287. package/dist/{searchable-DHJMh_nj.d.cts → searchable-ClgET_i7.d.cts} +1 -1
  288. package/dist/{sqlite-YppHrNFb.d.cts → sqlite-D1mXO9Kp.d.cts} +310 -2
  289. package/dist/{sqlite-D7Oz0SQh.d.ts → sqlite-MZA3oZNB.d.ts} +310 -2
  290. package/dist/{store-bphCSo7z.d.cts → store-CuFX7fCx.d.cts} +117 -31
  291. package/dist/{store-DRrFCx5x.d.ts → store-D-ZjXQpW.d.ts} +117 -31
  292. package/dist/{temporal-CbnLzTmM.d.ts → temporal-CpyEiRY8.d.cts} +1 -1
  293. package/dist/{temporal-5GqpYCk2.d.cts → temporal-y0Aep9Su.d.ts} +1 -1
  294. package/dist/{types-BqFZTQmV.d.cts → types-6yf0Vv-_.d.cts} +2016 -94
  295. package/dist/{types-BqFZTQmV.d.ts → types-6yf0Vv-_.d.ts} +2016 -94
  296. package/dist/{types-Bx74kaTt.d.ts → types-DzJ4dlzk.d.cts} +1 -1
  297. package/dist/{types-CXAhpW-c.d.cts → types-_vVSB9k-.d.ts} +1 -1
  298. package/dist/{where-O-k2wgYm.d.ts → where-DuG2LCLe.d.ts} +1 -1
  299. package/dist/{where-DI_Fqz-X.d.cts → where-Mhf_yyKX.d.cts} +1 -1
  300. package/package.json +7 -2
  301. package/dist/chunk-26YKDNUD.cjs.map +0 -1
  302. package/dist/chunk-2TYSSBU5.js.map +0 -1
  303. package/dist/chunk-3DMMGT6S.js.map +0 -1
  304. package/dist/chunk-3FPR224C.cjs.map +0 -1
  305. package/dist/chunk-3G5W2U2L.cjs.map +0 -1
  306. package/dist/chunk-3KOY4FH3.cjs +0 -934
  307. package/dist/chunk-3KOY4FH3.cjs.map +0 -1
  308. package/dist/chunk-3QNZ5SAJ.cjs +0 -3502
  309. package/dist/chunk-3QNZ5SAJ.cjs.map +0 -1
  310. package/dist/chunk-3U5ABFDW.cjs +0 -259
  311. package/dist/chunk-3U5ABFDW.cjs.map +0 -1
  312. package/dist/chunk-5K2BKEBD.js.map +0 -1
  313. package/dist/chunk-5PRKMB24.cjs +0 -124
  314. package/dist/chunk-5PRKMB24.cjs.map +0 -1
  315. package/dist/chunk-6LN7FIVU.js +0 -107
  316. package/dist/chunk-6LN7FIVU.js.map +0 -1
  317. package/dist/chunk-6SWPJEYN.js +0 -1126
  318. package/dist/chunk-6SWPJEYN.js.map +0 -1
  319. package/dist/chunk-7LZJNLA5.js.map +0 -1
  320. package/dist/chunk-7UOLHNWC.cjs.map +0 -1
  321. package/dist/chunk-BFUOME67.cjs.map +0 -1
  322. package/dist/chunk-BRRP76WO.js.map +0 -1
  323. package/dist/chunk-CICO5GXD.cjs +0 -12
  324. package/dist/chunk-D4QLTJSM.js.map +0 -1
  325. package/dist/chunk-D5R42W5D.js.map +0 -1
  326. package/dist/chunk-EDN4Y4ZG.cjs.map +0 -1
  327. package/dist/chunk-EZEEWCFJ.cjs.map +0 -1
  328. package/dist/chunk-FA2AFWLP.cjs.map +0 -1
  329. package/dist/chunk-FQPEMEWX.cjs.map +0 -1
  330. package/dist/chunk-GLHXM7C4.js.map +0 -1
  331. package/dist/chunk-GYEG3ZLZ.cjs.map +0 -1
  332. package/dist/chunk-HDL2ARHX.cjs +0 -1156
  333. package/dist/chunk-HDL2ARHX.cjs.map +0 -1
  334. package/dist/chunk-HEV35TGT.js.map +0 -1
  335. package/dist/chunk-I4GAZH5Z.js +0 -913
  336. package/dist/chunk-I4GAZH5Z.js.map +0 -1
  337. package/dist/chunk-JB6T4GLL.cjs.map +0 -1
  338. package/dist/chunk-JBQQ7THH.js +0 -20
  339. package/dist/chunk-JBQQ7THH.js.map +0 -1
  340. package/dist/chunk-JFRT7S3B.cjs.map +0 -1
  341. package/dist/chunk-KF6K7TGH.js.map +0 -1
  342. package/dist/chunk-L3LQNR34.cjs +0 -1254
  343. package/dist/chunk-L3LQNR34.cjs.map +0 -1
  344. package/dist/chunk-LTXQOEIC.js.map +0 -1
  345. package/dist/chunk-MKJ4KXL5.cjs +0 -12
  346. package/dist/chunk-MRDBBHIZ.cjs.map +0 -1
  347. package/dist/chunk-NACVVDWB.js.map +0 -1
  348. package/dist/chunk-NVY5CJFP.js +0 -244
  349. package/dist/chunk-NVY5CJFP.js.map +0 -1
  350. package/dist/chunk-PWLJ77UV.cjs +0 -23
  351. package/dist/chunk-PWLJ77UV.cjs.map +0 -1
  352. package/dist/chunk-S5TERQVW.js.map +0 -1
  353. package/dist/chunk-SHFBB23Q.js.map +0 -1
  354. package/dist/chunk-SIT26LAZ.cjs.map +0 -1
  355. package/dist/chunk-SR725PWF.cjs.map +0 -1
  356. package/dist/chunk-TQHGE7UC.cjs.map +0 -1
  357. package/dist/chunk-UGHG7PGX.js.map +0 -1
  358. package/dist/chunk-UGHQV7MP.cjs.map +0 -1
  359. package/dist/chunk-UMGZDVOA.cjs.map +0 -1
  360. package/dist/chunk-WIC7DRXW.js.map +0 -1
  361. package/dist/chunk-YIURNGXI.js.map +0 -1
  362. package/dist/chunk-YYUHLYM2.cjs.map +0 -1
  363. package/dist/chunk-Z2JCLZFJ.js.map +0 -1
  364. package/dist/chunk-ZDKTPBGV.js.map +0 -1
  365. package/dist/chunk-ZFMCDJGB.js.map +0 -1
  366. package/dist/chunk-ZLONH2UD.js.map +0 -1
  367. package/dist/index-COs_z6nV.d.cts +0 -1132
  368. package/dist/index-D7d1u2gr.d.ts +0 -1132
  369. package/dist/materialize-indexes-DJ3ykH59.d.ts +0 -266
  370. package/dist/materialize-indexes-DTtAnvfY.d.cts +0 -266
@@ -1,25 +1,11 @@
1
- import { createSqliteTables, sqliteContributions, createPostgresTables, postgresContributions } from './chunk-6SWPJEYN.js';
2
- import { createSqlSchema } from './chunk-NVY5CJFP.js';
3
- import { runOptionallyInTransaction } from './chunk-6LN7FIVU.js';
4
- import { asRecordedInstant, createRecordedInstant, RECORDED_MAX_REVISION } from './chunk-DZAICA5J.js';
5
- import { canonicalizeDatabaseTimestamp } from './chunk-5K2BKEBD.js';
6
- import { shortHash } from './chunk-ZDKTPBGV.js';
7
- import { asCompiledRowsSql, sql, asCompiledStatementSql } from './chunk-3DMMGT6S.js';
8
- import { ConfigurationError, ValidationError } from './chunk-ZLONH2UD.js';
9
-
10
- // src/backend/table-names.ts
11
- function definedTableNameOverrides(override) {
12
- if (override === void 0) return {};
13
- return Object.fromEntries(
14
- Object.entries(override).filter(([, tableName]) => tableName !== void 0)
15
- );
16
- }
17
- function resolvedTableNames(backend, override) {
18
- return createSqlSchema({
19
- ...backend.tableNames,
20
- ...definedTableNameOverrides(override)
21
- }).tables;
22
- }
1
+ import { resolvedTableNames } from './chunk-IRCWIA3R.js';
2
+ import { statementExecutionVerdict } from './chunk-XORONCV3.js';
3
+ import { runOptionallyInTransaction, createSqlSchema, statementExecutionMembers } from './chunk-LKZDQ2B4.js';
4
+ import { asRecordedInstant, createRecordedInstant, RECORDED_MAX_REVISION } from './chunk-6NKSE5AU.js';
5
+ import { canonicalizeDatabaseTimestamp } from './chunk-K46SDNQD.js';
6
+ import { shortHash } from './chunk-PC5NGH5A.js';
7
+ import { asCompiledRowsSql, sql, asCompiledStatementSql } from './chunk-7QFRK6PU.js';
8
+ import { ConfigurationError, UnsupportedBackendCapabilityError, ValidationError } from './chunk-YDEJQWOL.js';
23
9
 
24
10
  // src/backend/migrate-recorded-time.ts
25
11
  var LEGACY_RECORDED_MAX = "9999-12-31T23:59:59.999Z";
@@ -222,46 +208,48 @@ async function writeMappingRows(target, tableName, rows) {
222
208
  );
223
209
  }
224
210
  }
225
- function tableDdl(dialect, tables, temporary) {
226
- if (dialect === "sqlite") {
227
- const temporaryTables2 = createSqliteTables(temporary);
228
- const finalTables2 = createSqliteTables(tables);
229
- const temporaryContributions = sqliteContributions(temporaryTables2);
230
- const finalContributions = sqliteContributions(finalTables2);
231
- return ddlForRecordedTables(temporaryContributions, finalContributions);
211
+ function recordedMigrationDdl(recordedTableDdl, finalNames, temporaryNames) {
212
+ const temporaryDdl = recordedTableDdl(temporaryNames);
213
+ const finalDdl = recordedTableDdl(finalNames);
214
+ function composed(key) {
215
+ return {
216
+ createTable: temporaryDdl[key].createTable,
217
+ indexes: finalDdl[key].indexes
218
+ };
232
219
  }
233
- const temporaryTables = createPostgresTables(temporary);
234
- const finalTables = createPostgresTables(tables);
235
- return ddlForRecordedTables(
236
- postgresContributions(temporaryTables),
237
- postgresContributions(finalTables)
238
- );
239
- }
240
- function ddlForRecordedTables(temporary, final) {
241
- function statements(logicalName) {
242
- const temporaryDdl = temporary.find(
243
- (entry) => entry.logicalName === logicalName
244
- )?.createDdl;
245
- const finalDdl = final.find(
246
- (entry) => entry.logicalName === logicalName
247
- )?.createDdl;
248
- if (temporaryDdl === void 0 || finalDdl === void 0) {
249
- throw new ConfigurationError(
250
- `Could not generate migration DDL for ${logicalName}.`
251
- );
252
- }
253
- const createTable = temporaryDdl[0];
254
- if (createTable === void 0) {
220
+ function primaryKeyConstraintRename(key) {
221
+ const temporaryConstraintName = temporaryDdl[key].primaryKeyConstraintName;
222
+ const finalConstraintName = finalDdl[key].primaryKeyConstraintName;
223
+ if (temporaryConstraintName === void 0 && finalConstraintName === void 0)
224
+ return { status: "none" };
225
+ if (temporaryConstraintName === void 0 || finalConstraintName === void 0)
255
226
  throw new ConfigurationError(
256
- `Could not generate migration table DDL for ${logicalName}.`
227
+ "Recorded relation DDL must name both primary-key constraints or neither.",
228
+ {
229
+ code: "RECORDED_DDL_CONSTRAINT_NAME_MISMATCH",
230
+ relation: key,
231
+ finalTable: finalNames[key],
232
+ temporaryConstraintName,
233
+ finalConstraintName
234
+ }
257
235
  );
258
- }
259
- return [createTable, ...finalDdl.slice(1)];
236
+ return {
237
+ status: "rename",
238
+ from: temporaryConstraintName,
239
+ to: finalConstraintName
240
+ };
260
241
  }
261
242
  return {
262
- clock: statements("recordedClock"),
263
- edges: statements("recordedEdges"),
264
- nodes: statements("recordedNodes")
243
+ ddl: {
244
+ recordedClock: composed("recordedClock"),
245
+ recordedEdges: composed("recordedEdges"),
246
+ recordedNodes: composed("recordedNodes")
247
+ },
248
+ primaryKeyConstraintRenames: {
249
+ recordedClock: primaryKeyConstraintRename("recordedClock"),
250
+ recordedEdges: primaryKeyConstraintRename("recordedEdges"),
251
+ recordedNodes: primaryKeyConstraintRename("recordedNodes")
252
+ }
265
253
  };
266
254
  }
267
255
  function migratedColumn(column, legacyAlias) {
@@ -381,22 +369,31 @@ async function copyRecordedClock(target, options) {
381
369
  `
382
370
  );
383
371
  }
384
- async function replaceLegacyTables(target, tables, mappingTable) {
372
+ async function replaceLegacyTables(target, tables, mappingTable, recordedTableDdl) {
385
373
  const temporary = {
386
374
  recordedNodes: temporaryTableName(tables.recordedNodes, "rn"),
387
375
  recordedEdges: temporaryTableName(tables.recordedEdges, "re"),
388
376
  recordedClock: temporaryTableName(tables.recordedClock, "rc")
389
377
  };
390
- const ddl = tableDdl(target.dialect, tables, temporary);
378
+ const finalNames = {
379
+ recordedNodes: tables.recordedNodes,
380
+ recordedEdges: tables.recordedEdges,
381
+ recordedClock: tables.recordedClock
382
+ };
383
+ const { ddl, primaryKeyConstraintRenames } = recordedMigrationDdl(
384
+ recordedTableDdl,
385
+ finalNames,
386
+ temporary
387
+ );
391
388
  for (const table of Object.values(temporary)) {
392
389
  await executeStatement(
393
390
  target,
394
391
  sql`DROP TABLE IF EXISTS ${sql.identifier(table)}`
395
392
  );
396
393
  }
397
- await executeDdl(target, requireCreateTable(ddl.nodes));
398
- await executeDdl(target, requireCreateTable(ddl.edges));
399
- await executeDdl(target, requireCreateTable(ddl.clock));
394
+ await executeDdl(target, ddl.recordedNodes.createTable);
395
+ await executeDdl(target, ddl.recordedEdges.createTable);
396
+ await executeDdl(target, ddl.recordedClock.createTable);
400
397
  await copyRecordedRelation(target, {
401
398
  columns: RECORDED_NODE_COLUMNS,
402
399
  legacyTable: tables.recordedNodes,
@@ -431,45 +428,38 @@ async function replaceLegacyTables(target, tables, mappingTable) {
431
428
  await renameTable(target, temporary.recordedClock, tables.recordedClock);
432
429
  await renamePrimaryKeyConstraint(
433
430
  target,
434
- temporary.recordedNodes,
435
- tables.recordedNodes
431
+ tables.recordedNodes,
432
+ primaryKeyConstraintRenames.recordedNodes
436
433
  );
437
434
  await renamePrimaryKeyConstraint(
438
435
  target,
439
- temporary.recordedEdges,
440
- tables.recordedEdges
436
+ tables.recordedEdges,
437
+ primaryKeyConstraintRenames.recordedEdges
441
438
  );
442
439
  await renamePrimaryKeyConstraint(
443
440
  target,
444
- temporary.recordedClock,
445
- tables.recordedClock
441
+ tables.recordedClock,
442
+ primaryKeyConstraintRenames.recordedClock
446
443
  );
447
444
  for (const statement of [
448
- ...ddl.nodes.slice(1),
449
- ...ddl.edges.slice(1),
450
- ...ddl.clock.slice(1)
445
+ ...ddl.recordedNodes.indexes,
446
+ ...ddl.recordedEdges.indexes,
447
+ ...ddl.recordedClock.indexes
451
448
  ]) {
452
449
  await executeDdl(target, statement);
453
450
  }
454
451
  }
455
- async function renamePrimaryKeyConstraint(target, temporaryTable, finalTable) {
456
- if (target.dialect !== "postgres") return;
452
+ async function renamePrimaryKeyConstraint(target, finalTable, rename) {
453
+ if (rename.status === "none") return;
457
454
  await executeStatement(
458
455
  target,
459
456
  sql`
460
457
  ALTER TABLE ${sql.identifier(finalTable)}
461
- RENAME CONSTRAINT ${sql.identifier(`${temporaryTable}_pkey`)}
462
- TO ${sql.identifier(shortenedIdentifier(`${finalTable}_pkey`))}
458
+ RENAME CONSTRAINT ${sql.identifier(rename.from)}
459
+ TO ${sql.identifier(shortenedIdentifier(rename.to))}
463
460
  `
464
461
  );
465
462
  }
466
- function requireCreateTable(statements) {
467
- const statement = statements[0];
468
- if (statement === void 0) {
469
- throw new ConfigurationError("Recorded migration table DDL was empty.");
470
- }
471
- return statement;
472
- }
473
463
  async function renameTable(target, from, to) {
474
464
  try {
475
465
  await executeStatement(
@@ -487,6 +477,7 @@ async function renameTable(target, from, to) {
487
477
  async function migrateLegacyRecordedTime(options) {
488
478
  const tables = resolvedTableNames(options.backend, options.tableNames);
489
479
  const mapTable = mappingTableName(tables, options.mappingTableName);
480
+ const recordedTableDdl = options.backend.recordedTableDdl;
490
481
  return options.backend.transaction(async (target) => {
491
482
  const clockColumns = await columnNames(target, tables.recordedClock);
492
483
  if (clockColumns.size === 0) {
@@ -530,10 +521,18 @@ async function migrateLegacyRecordedTime(options) {
530
521
  { tables }
531
522
  );
532
523
  }
524
+ if (recordedTableDdl === void 0) {
525
+ throw new UnsupportedBackendCapabilityError(
526
+ "migrateLegacyRecordedTime",
527
+ "recordedTableDdl",
528
+ { dialect: target.dialect, tables },
529
+ "Migrating the timestamp-only preview recorded schema needs the backend to author its own recorded-relation DDL. Only the bundled SQLite and PostgreSQL backends created that schema."
530
+ );
531
+ }
533
532
  await executeDdl(target, migrationMapDdl(target.dialect, mapTable));
534
533
  const mapping = await readLegacyInstants(target, tables);
535
534
  await writeMappingRows(target, mapTable, mapping);
536
- await replaceLegacyTables(target, tables, mapTable);
535
+ await replaceLegacyTables(target, tables, mapTable, recordedTableDdl);
537
536
  return {
538
537
  migrated: true,
539
538
  graphs: new Set(mapping.map((row) => row.graphId)).size,
@@ -575,12 +574,7 @@ async function migrateRecordedAnchor(options) {
575
574
  );
576
575
  }
577
576
  async function deleteLegacyRecordedAnchorMap(options) {
578
- if (options.backend.executeStatement === void 0) {
579
- throw new ConfigurationError(
580
- "Deleting a recorded anchor migration map requires executeStatement support.",
581
- { dialect: options.backend.dialect }
582
- );
583
- }
577
+ requireStatements(options.backend);
584
578
  const tables = resolvedTableNames(options.backend, options.tableNames);
585
579
  const mapTable = mappingTableName(tables, options.mappingTableName);
586
580
  await options.backend.transaction(async (target) => {
@@ -690,17 +684,14 @@ async function countMatching(target, table, predicate) {
690
684
  );
691
685
  return safeCount(rows[0]?.matches, table);
692
686
  }
693
- function requireStatements2(target) {
694
- if (target.executeStatement === void 0) {
695
- throw new ConfigurationError(
696
- "Repairing inverted validity windows requires executeStatement support.",
697
- { dialect: target.dialect, mode: "apply" },
698
- {
699
- suggestion: 'Use a built-in SQLite or PostgreSQL backend to apply the repair. Detection needs no such support: call this with mode: "report" to count the affected rows on any backend.'
700
- }
701
- );
702
- }
703
- return target.executeStatement;
687
+ function statementExecutionRequiredError(dialect) {
688
+ return new ConfigurationError(
689
+ "Repairing inverted validity windows requires executeStatement support.",
690
+ { dialect, mode: "apply" },
691
+ {
692
+ suggestion: 'Use a built-in SQLite or PostgreSQL backend to apply the repair. Detection needs no such support: call this with mode: "report" to count the affected rows on any backend.'
693
+ }
694
+ );
704
695
  }
705
696
  function translatedCaptureRefusal(error) {
706
697
  if (!(error instanceof ConfigurationError) || error.details["code"] !== "RECORDED_CAPTURE_RAW_SQL_DISABLED") {
@@ -715,9 +706,12 @@ function translatedCaptureRefusal(error) {
715
706
  }
716
707
  );
717
708
  }
718
- async function repairRelation(target, table, predicate) {
709
+ async function repairRelation(target, verdict, table, predicate) {
710
+ if (!verdict.supported) {
711
+ throw statementExecutionRequiredError(target.dialect);
712
+ }
719
713
  try {
720
- await requireStatements2(target)(
714
+ await statementExecutionMembers(target, verdict).executeStatement(
721
715
  asCompiledStatementSql(sql`
722
716
  UPDATE ${sql.identifier(table)}
723
717
  SET valid_from = NULL
@@ -753,7 +747,10 @@ function relationRecord(counts) {
753
747
  async function repairInvertedValidityWindows(options) {
754
748
  const tables = resolvedTableNames(options.backend, options.tableNames);
755
749
  const relations = scopedRelations(options.relations);
756
- if (options.mode === "apply") requireStatements2(options.backend);
750
+ const verdict = statementExecutionVerdict(options.backend);
751
+ if (options.mode === "apply" && !verdict.supported) {
752
+ throw statementExecutionRequiredError(options.backend.dialect);
753
+ }
757
754
  return runOptionallyInTransaction(
758
755
  options.backend,
759
756
  async (target, execution) => {
@@ -780,6 +777,7 @@ async function repairInvertedValidityWindows(options) {
780
777
  for (const relation of relations) {
781
778
  await repairRelation(
782
779
  target,
780
+ verdict,
783
781
  relationTable(tables, relation),
784
782
  predicate
785
783
  );
@@ -797,5 +795,5 @@ async function repairInvertedValidityWindows(options) {
797
795
  }
798
796
 
799
797
  export { deleteLegacyRecordedAnchorMap, migrateLegacyRecordedTime, migrateRecordedAnchor, repairInvertedValidityWindows };
800
- //# sourceMappingURL=chunk-NACVVDWB.js.map
801
- //# sourceMappingURL=chunk-NACVVDWB.js.map
798
+ //# sourceMappingURL=chunk-I5IOSA27.js.map
799
+ //# sourceMappingURL=chunk-I5IOSA27.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/backend/migrate-recorded-time.ts","../src/backend/repair-validity-windows.ts"],"names":[],"mappings":"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","file":"chunk-I5IOSA27.js","sourcesContent":["/**\n * One-time offline migration from timestamp-only recorded relations to numeric\n * revisions. The durable remap table lets applications translate checkpoints\n * stored outside TypeGraph before deleting the migration metadata.\n */\nimport {\n asRecordedInstant,\n createRecordedInstant,\n RECORDED_MAX_REVISION,\n type RecordedInstant,\n} from \"../core/temporal\";\nimport {\n ConfigurationError,\n UnsupportedBackendCapabilityError,\n ValidationError,\n} from \"../errors\";\nimport {\n createSqlSchema,\n type ResolvedSqlTableNames,\n type SqlTableNames,\n} from \"../query/compiler/schema\";\nimport { shortHash } from \"../query/dialect/vector-strategy\";\nimport { sql, type SqlFragment } from \"../query/sql-fragment\";\nimport { asCompiledRowsSql, asCompiledStatementSql } from \"../query/sql-intent\";\nimport { canonicalizeDatabaseTimestamp } from \"../utils/date\";\nimport { resolvedTableNames } from \"./table-names\";\nimport {\n type GraphBackend,\n type RecordedRelationDdl,\n type RecordedTableNames,\n type TransactionBackend,\n} from \"./types\";\n\nconst LEGACY_RECORDED_MAX = \"9999-12-31T23:59:59.999Z\";\nconst MIGRATION_SUFFIX = \"legacy_recorded_anchors\";\n\nconst RECORDED_NODE_COLUMNS = [\n \"history_id\",\n \"graph_id\",\n \"kind\",\n \"id\",\n \"props\",\n \"version\",\n \"valid_from\",\n \"valid_to\",\n \"created_at\",\n \"updated_at\",\n \"deleted_at\",\n \"recorded_from\",\n \"recorded_to\",\n \"op\",\n \"schema_version\",\n \"tx_id\",\n \"meta\",\n] as const;\n\nconst RECORDED_EDGE_COLUMNS = [\n \"history_id\",\n \"graph_id\",\n \"id\",\n \"kind\",\n \"from_kind\",\n \"from_id\",\n \"to_kind\",\n \"to_id\",\n \"props\",\n \"valid_from\",\n \"valid_to\",\n \"created_at\",\n \"updated_at\",\n \"deleted_at\",\n \"recorded_from\",\n \"recorded_to\",\n \"op\",\n \"schema_version\",\n \"tx_id\",\n \"meta\",\n] as const;\n\ntype LegacyInstantRow = Readonly<{\n graph_id: unknown;\n recorded_at: unknown;\n}>;\n\ntype MappingRow = Readonly<{\n graphId: string;\n legacyRecordedAt: string;\n recordedAt: string;\n revision: number;\n}>;\n\ntype RemapRow = Readonly<{ recorded_at: unknown; revision: unknown }>;\ntype MappingCountRow = Readonly<{ anchors: unknown; graphs: unknown }>;\ntype MissingMappingRow = Readonly<{ missing: unknown }>;\ntype ColumnRow = Readonly<{ name: unknown }>;\n\nexport type MigrateLegacyRecordedTimeOptions = Readonly<{\n backend: GraphBackend;\n /** Patch selected backend table names; unstated names remain configured. */\n tableNames?: Partial<SqlTableNames> | undefined;\n /** Override the durable legacy-anchor mapping table name. */\n mappingTableName?: string | undefined;\n}>;\n\nexport type MigrateLegacyRecordedTimeResult = Readonly<{\n /** `true` when timestamp columns were rewritten during this call. */\n migrated: boolean;\n /** Number of graphs represented in the legacy commit order. */\n graphs: number;\n /** Number of distinct legacy anchors available for remapping. */\n anchors: number;\n /** Physical table retaining the old-anchor → revision mapping. */\n mappingTableName: string;\n}>;\n\nexport type MigrateRecordedAnchorOptions = Readonly<{\n backend: Pick<GraphBackend, \"dialect\" | \"execute\" | \"tableNames\">;\n graphId: string;\n anchor: string;\n /** Patch selected backend table names; unstated names remain configured. */\n tableNames?: Partial<SqlTableNames> | undefined;\n mappingTableName?: string | undefined;\n}>;\n\nexport type DeleteLegacyRecordedAnchorMapOptions = Readonly<{\n backend: Pick<\n GraphBackend,\n \"dialect\" | \"execute\" | \"executeStatement\" | \"tableNames\" | \"transaction\"\n >;\n graphId: string;\n /** Patch selected backend table names; unstated names remain configured. */\n tableNames?: Partial<SqlTableNames> | undefined;\n mappingTableName?: string | undefined;\n /** Drop the mapping table when this deletion leaves it empty. */\n dropWhenEmpty?: boolean | undefined;\n}>;\n\nfunction shortenedIdentifier(value: string): string {\n if (value.length <= 63) return value;\n return `${value.slice(0, 50)}_${shortHash(value)}`;\n}\n\nfunction mappingTableName(\n tables: ResolvedSqlTableNames,\n override: string | undefined,\n): string {\n const candidate = override ?? `${tables.recordedClock}_${MIGRATION_SUFFIX}`;\n return createSqlSchema({\n recordedClock: shortenedIdentifier(candidate),\n }).tables.recordedClock;\n}\n\nfunction temporaryTableName(tableName: string, role: string): string {\n return shortenedIdentifier(`__tg_${role}_${shortHash(tableName)}`);\n}\n\nfunction requireStatements(\n target: Pick<TransactionBackend, \"dialect\" | \"executeStatement\">,\n): NonNullable<TransactionBackend[\"executeStatement\"]> {\n if (target.executeStatement === undefined) {\n throw new ConfigurationError(\n \"Recorded-time migration requires executeStatement support.\",\n { dialect: target.dialect },\n { suggestion: \"Use a built-in SQLite or PostgreSQL backend.\" },\n );\n }\n return target.executeStatement;\n}\n\nasync function executeStatement(\n target: Pick<TransactionBackend, \"dialect\" | \"executeStatement\">,\n statement: SqlFragment,\n): Promise<void> {\n await requireStatements(target)(asCompiledStatementSql(statement));\n}\n\nasync function executeDdl(\n target: Pick<TransactionBackend, \"dialect\" | \"executeStatement\">,\n ddl: string,\n): Promise<void> {\n await executeStatement(target, sql.raw(ddl));\n}\n\nfunction canonicalLegacyInstant(value: unknown): string {\n const canonical = canonicalizeDatabaseTimestamp(value);\n if (canonical === undefined) {\n throw new ConfigurationError(\n \"Legacy recorded-time relation contained an invalid timestamp.\",\n { value },\n );\n }\n return canonical;\n}\n\nfunction safeRevision(value: unknown): number {\n const revision =\n typeof value === \"bigint\" ? Number(value)\n : typeof value === \"string\" && /^\\d+$/.test(value) ? Number(value)\n : value;\n if (\n typeof revision !== \"number\" ||\n !Number.isSafeInteger(revision) ||\n revision < 1 ||\n revision >= RECORDED_MAX_REVISION\n ) {\n throw new ConfigurationError(\n \"Recorded anchor mapping contained an invalid revision.\",\n { value },\n );\n }\n return revision;\n}\n\nasync function columnNames(\n target: TransactionBackend,\n tableName: string,\n): Promise<ReadonlySet<string>> {\n const rows =\n target.dialect === \"sqlite\" ?\n await target.execute<ColumnRow>(\n asCompiledRowsSql(sql`PRAGMA table_info(${sql.identifier(tableName)})`),\n )\n : await target.execute<ColumnRow>(\n asCompiledRowsSql(sql`\n SELECT column_name AS name\n FROM information_schema.columns\n WHERE table_schema = current_schema()\n AND table_name = ${tableName}\n `),\n );\n return new Set(\n rows.flatMap((row) => (typeof row.name === \"string\" ? [row.name] : [])),\n );\n}\n\nasync function readLegacyInstants(\n target: TransactionBackend,\n tables: ResolvedSqlTableNames,\n): Promise<readonly MappingRow[]> {\n const rows = await target.execute<LegacyInstantRow>(\n asCompiledRowsSql(sql`\n SELECT graph_id, recorded_from AS recorded_at\n FROM ${sql.identifier(tables.recordedNodes)}\n UNION\n SELECT graph_id, recorded_to AS recorded_at\n FROM ${sql.identifier(tables.recordedNodes)}\n WHERE recorded_to <> ${LEGACY_RECORDED_MAX}\n UNION\n SELECT graph_id, recorded_from AS recorded_at\n FROM ${sql.identifier(tables.recordedEdges)}\n UNION\n SELECT graph_id, recorded_to AS recorded_at\n FROM ${sql.identifier(tables.recordedEdges)}\n WHERE recorded_to <> ${LEGACY_RECORDED_MAX}\n UNION\n SELECT graph_id, recorded_at\n FROM ${sql.identifier(tables.recordedClock)}\n `),\n );\n const instants = rows.map((row) => {\n if (typeof row.graph_id !== \"string\") {\n throw new ConfigurationError(\n \"Legacy recorded-time relation contained an invalid graph id.\",\n { graphId: row.graph_id },\n );\n }\n return {\n graphId: row.graph_id,\n recordedAt: canonicalLegacyInstant(row.recorded_at),\n };\n });\n instants.sort((left, right) => {\n if (left.graphId < right.graphId) return -1;\n if (left.graphId > right.graphId) return 1;\n if (left.recordedAt < right.recordedAt) return -1;\n if (left.recordedAt > right.recordedAt) return 1;\n return 0;\n });\n\n const mapping: MappingRow[] = [];\n let graphId: string | undefined;\n let revision = 0;\n let previousInstant: string | undefined;\n for (const instant of instants) {\n if (instant.graphId !== graphId) {\n graphId = instant.graphId;\n revision = 0;\n previousInstant = undefined;\n }\n if (instant.recordedAt === previousInstant) continue;\n revision += 1;\n mapping.push({\n graphId: instant.graphId,\n legacyRecordedAt: instant.recordedAt,\n recordedAt: instant.recordedAt,\n revision,\n });\n previousInstant = instant.recordedAt;\n }\n return mapping;\n}\n\nfunction migrationMapDdl(\n dialect: GraphBackend[\"dialect\"],\n table: string,\n): string {\n const revisionType = dialect === \"postgres\" ? \"BIGINT\" : \"INTEGER\";\n const recordedAtType = dialect === \"postgres\" ? \"TIMESTAMPTZ\" : \"TEXT\";\n return `CREATE TABLE IF NOT EXISTS \"${table}\" (\n graph_id TEXT NOT NULL,\n legacy_recorded_at TEXT NOT NULL,\n revision ${revisionType} NOT NULL,\n recorded_at ${recordedAtType} NOT NULL,\n PRIMARY KEY (graph_id, legacy_recorded_at)\n);`;\n}\n\nasync function writeMappingRows(\n target: TransactionBackend,\n tableName: string,\n rows: readonly MappingRow[],\n): Promise<void> {\n await executeStatement(target, sql`DELETE FROM ${sql.identifier(tableName)}`);\n const rowsPerStatement = Math.max(\n 1,\n Math.floor((target.capabilities.maxBindParameters ?? 900) / 4),\n );\n for (let start = 0; start < rows.length; start += rowsPerStatement) {\n const values = rows\n .slice(start, start + rowsPerStatement)\n .map(\n (row) =>\n sql`(${row.graphId}, ${row.legacyRecordedAt}, ${row.revision}, ${row.recordedAt})`,\n );\n await executeStatement(\n target,\n sql`\n INSERT INTO ${sql.identifier(tableName)}\n (graph_id, legacy_recorded_at, revision, recorded_at)\n VALUES ${sql.join(values, sql`, `)}\n `,\n );\n }\n}\n\ntype RecordedDdlSet = Readonly<\n Record<keyof RecordedTableNames, RecordedRelationDdl>\n>;\n\ntype PrimaryKeyConstraintRename =\n | Readonly<{ status: \"none\" }>\n | Readonly<{ status: \"rename\"; from: string; to: string }>;\n\n/**\n * The two calls the offline migration makes to the port, plus their\n * composition. `primaryKeyConstraintRenames` carries the backend-authored\n * decision itself, so the swap cannot re-derive it or silently ignore one\n * supplied name.\n */\ntype RecordedMigrationDdl = Readonly<{\n /**\n * The temp-named `CREATE TABLE` (so the swap-in relation is empty and safe\n * to populate) paired with the final-named `indexes` (so the swapped-in\n * relation ends up carrying the SAME index/constraint statements the final\n * table would get if provisioned fresh).\n */\n ddl: RecordedDdlSet;\n primaryKeyConstraintRenames: Readonly<\n Record<keyof RecordedTableNames, PrimaryKeyConstraintRename>\n >;\n}>;\n\n/**\n * The offline migration's own composition of the port's per-name-set DDL.\n * `recordedTableDdl` is called exactly once per name set — mirroring the\n * two-Drizzle-table-build shape this replaces — and the backend-authored\n * constraint-name pair is resolved here before any migration SQL executes.\n */\nfunction recordedMigrationDdl(\n recordedTableDdl: NonNullable<GraphBackend[\"recordedTableDdl\"]>,\n finalNames: RecordedTableNames,\n temporaryNames: RecordedTableNames,\n): RecordedMigrationDdl {\n const temporaryDdl = recordedTableDdl(temporaryNames);\n const finalDdl = recordedTableDdl(finalNames);\n function composed(key: keyof RecordedTableNames): RecordedRelationDdl {\n return {\n createTable: temporaryDdl[key].createTable,\n indexes: finalDdl[key].indexes,\n };\n }\n function primaryKeyConstraintRename(\n key: keyof RecordedTableNames,\n ): PrimaryKeyConstraintRename {\n const temporaryConstraintName = temporaryDdl[key].primaryKeyConstraintName;\n const finalConstraintName = finalDdl[key].primaryKeyConstraintName;\n if (\n temporaryConstraintName === undefined &&\n finalConstraintName === undefined\n )\n return { status: \"none\" };\n if (\n temporaryConstraintName === undefined ||\n finalConstraintName === undefined\n )\n throw new ConfigurationError(\n \"Recorded relation DDL must name both primary-key constraints or neither.\",\n {\n code: \"RECORDED_DDL_CONSTRAINT_NAME_MISMATCH\",\n relation: key,\n finalTable: finalNames[key],\n temporaryConstraintName,\n finalConstraintName,\n },\n );\n return {\n status: \"rename\",\n from: temporaryConstraintName,\n to: finalConstraintName,\n };\n }\n return {\n ddl: {\n recordedClock: composed(\"recordedClock\"),\n recordedEdges: composed(\"recordedEdges\"),\n recordedNodes: composed(\"recordedNodes\"),\n },\n primaryKeyConstraintRenames: {\n recordedClock: primaryKeyConstraintRename(\"recordedClock\"),\n recordedEdges: primaryKeyConstraintRename(\"recordedEdges\"),\n recordedNodes: primaryKeyConstraintRename(\"recordedNodes\"),\n },\n };\n}\n\nfunction migratedColumn(column: string, legacyAlias: string): SqlFragment {\n if (column === \"recorded_from\") return sql`from_map.revision`;\n if (column === \"recorded_to\") {\n return sql`\n CASE\n WHEN ${sql.raw(legacyAlias)}.recorded_to = ${LEGACY_RECORDED_MAX}\n THEN ${RECORDED_MAX_REVISION}\n ELSE to_map.revision\n END\n `;\n }\n return sql`${sql.raw(legacyAlias)}.${sql.identifier(column)}`;\n}\n\nfunction mappingMatch(\n dialect: GraphBackend[\"dialect\"],\n mappingAlias: \"anchor_map\" | \"from_map\" | \"to_map\",\n legacyColumn: \"recorded_at\" | \"recorded_from\" | \"recorded_to\",\n): SqlFragment {\n const mapping = sql.raw(mappingAlias);\n const legacy = sql.raw(`legacy.${legacyColumn}`);\n return dialect === \"postgres\" ?\n sql`${mapping}.recorded_at = ${legacy}`\n : sql`${mapping}.legacy_recorded_at = ${legacy}`;\n}\n\nfunction missingMappingCount(value: unknown, legacyTable: string): number {\n const count = Number(value);\n if (!Number.isSafeInteger(count) || count < 0) {\n throw new ConfigurationError(\n \"Recorded-time migration returned an invalid integrity-check count.\",\n { legacyTable, value },\n );\n }\n return count;\n}\n\nasync function assertRecordedRelationMappings(\n target: TransactionBackend,\n options: Readonly<{ legacyTable: string; mappingTable: string }>,\n): Promise<void> {\n const fromMatch = mappingMatch(target.dialect, \"from_map\", \"recorded_from\");\n const toMatch = mappingMatch(target.dialect, \"to_map\", \"recorded_to\");\n const rows = await target.execute<MissingMappingRow>(\n asCompiledRowsSql(sql`\n SELECT COUNT(*) AS missing\n FROM ${sql.identifier(options.legacyTable)} AS legacy\n LEFT JOIN ${sql.identifier(options.mappingTable)} AS from_map\n ON from_map.graph_id = legacy.graph_id AND ${fromMatch}\n LEFT JOIN ${sql.identifier(options.mappingTable)} AS to_map\n ON to_map.graph_id = legacy.graph_id AND ${toMatch}\n WHERE from_map.revision IS NULL\n OR (\n legacy.recorded_to <> ${LEGACY_RECORDED_MAX}\n AND to_map.revision IS NULL\n )\n `),\n );\n const missing = missingMappingCount(rows[0]?.missing, options.legacyTable);\n if (missing === 0) return;\n throw new ConfigurationError(\n \"Legacy recorded-time boundaries could not be mapped exactly.\",\n { legacyTable: options.legacyTable, missingRows: missing },\n {\n suggestion:\n \"Ensure every legacy boundary is a valid millisecond-precision timestamp produced by the preview recorded clock before retrying the offline migration.\",\n },\n );\n}\n\nasync function assertRecordedClockMappings(\n target: TransactionBackend,\n options: Readonly<{ legacyTable: string; mappingTable: string }>,\n): Promise<void> {\n const match = mappingMatch(target.dialect, \"anchor_map\", \"recorded_at\");\n const rows = await target.execute<MissingMappingRow>(\n asCompiledRowsSql(sql`\n SELECT COUNT(*) AS missing\n FROM ${sql.identifier(options.legacyTable)} AS legacy\n LEFT JOIN ${sql.identifier(options.mappingTable)} AS anchor_map\n ON anchor_map.graph_id = legacy.graph_id AND ${match}\n WHERE anchor_map.revision IS NULL\n `),\n );\n const missing = missingMappingCount(rows[0]?.missing, options.legacyTable);\n if (missing === 0) return;\n throw new ConfigurationError(\n \"Legacy recorded clock values could not be mapped exactly.\",\n { legacyTable: options.legacyTable, missingRows: missing },\n {\n suggestion:\n \"Ensure every legacy clock value is a valid millisecond-precision timestamp produced by the preview recorded clock before retrying the offline migration.\",\n },\n );\n}\n\nasync function copyRecordedRelation(\n target: TransactionBackend,\n options: Readonly<{\n columns: readonly string[];\n legacyTable: string;\n mappingTable: string;\n temporaryTable: string;\n }>,\n): Promise<void> {\n const columnList = options.columns.map((column) => sql.identifier(column));\n const values = options.columns.map((column) =>\n migratedColumn(column, \"legacy\"),\n );\n await assertRecordedRelationMappings(target, options);\n const fromMatch = mappingMatch(target.dialect, \"from_map\", \"recorded_from\");\n const toMatch = mappingMatch(target.dialect, \"to_map\", \"recorded_to\");\n await executeStatement(\n target,\n sql`\n INSERT INTO ${sql.identifier(options.temporaryTable)}\n (${sql.join(columnList, sql`, `)})\n SELECT ${sql.join(values, sql`, `)}\n FROM ${sql.identifier(options.legacyTable)} AS legacy\n -- LEFT JOIN is deliberate: a missing mapping reaches the NOT NULL\n -- revision columns and fails loud instead of silently dropping history.\n LEFT JOIN ${sql.identifier(options.mappingTable)} AS from_map\n ON from_map.graph_id = legacy.graph_id AND ${fromMatch}\n LEFT JOIN ${sql.identifier(options.mappingTable)} AS to_map\n ON to_map.graph_id = legacy.graph_id AND ${toMatch}\n `,\n );\n}\n\nasync function copyRecordedClock(\n target: TransactionBackend,\n options: Readonly<{\n legacyTable: string;\n mappingTable: string;\n temporaryTable: string;\n }>,\n): Promise<void> {\n await assertRecordedClockMappings(target, options);\n const match = mappingMatch(target.dialect, \"anchor_map\", \"recorded_at\");\n await executeStatement(\n target,\n sql`\n INSERT INTO ${sql.identifier(options.temporaryTable)}\n (graph_id, revision, recorded_at)\n SELECT legacy.graph_id, anchor_map.revision, legacy.recorded_at\n FROM ${sql.identifier(options.legacyTable)} AS legacy\n -- Preserve fail-loud behavior if the preflight invariant changes later.\n LEFT JOIN ${sql.identifier(options.mappingTable)} AS anchor_map\n ON anchor_map.graph_id = legacy.graph_id AND ${match}\n `,\n );\n}\n\nasync function replaceLegacyTables(\n target: TransactionBackend,\n tables: ResolvedSqlTableNames,\n mappingTable: string,\n recordedTableDdl: NonNullable<GraphBackend[\"recordedTableDdl\"]>,\n): Promise<void> {\n const temporary: RecordedTableNames = {\n recordedNodes: temporaryTableName(tables.recordedNodes, \"rn\"),\n recordedEdges: temporaryTableName(tables.recordedEdges, \"re\"),\n recordedClock: temporaryTableName(tables.recordedClock, \"rc\"),\n };\n const finalNames: RecordedTableNames = {\n recordedNodes: tables.recordedNodes,\n recordedEdges: tables.recordedEdges,\n recordedClock: tables.recordedClock,\n };\n const { ddl, primaryKeyConstraintRenames } = recordedMigrationDdl(\n recordedTableDdl,\n finalNames,\n temporary,\n );\n for (const table of Object.values(temporary)) {\n await executeStatement(\n target,\n sql`DROP TABLE IF EXISTS ${sql.identifier(table)}`,\n );\n }\n await executeDdl(target, ddl.recordedNodes.createTable);\n await executeDdl(target, ddl.recordedEdges.createTable);\n await executeDdl(target, ddl.recordedClock.createTable);\n await copyRecordedRelation(target, {\n columns: RECORDED_NODE_COLUMNS,\n legacyTable: tables.recordedNodes,\n mappingTable,\n temporaryTable: temporary.recordedNodes,\n });\n await copyRecordedRelation(target, {\n columns: RECORDED_EDGE_COLUMNS,\n legacyTable: tables.recordedEdges,\n mappingTable,\n temporaryTable: temporary.recordedEdges,\n });\n await copyRecordedClock(target, {\n legacyTable: tables.recordedClock,\n mappingTable,\n temporaryTable: temporary.recordedClock,\n });\n\n await executeStatement(\n target,\n sql`DROP TABLE ${sql.identifier(tables.recordedNodes)}`,\n );\n await executeStatement(\n target,\n sql`DROP TABLE ${sql.identifier(tables.recordedEdges)}`,\n );\n await executeStatement(\n target,\n sql`DROP TABLE ${sql.identifier(tables.recordedClock)}`,\n );\n await renameTable(target, temporary.recordedNodes, tables.recordedNodes);\n await renameTable(target, temporary.recordedEdges, tables.recordedEdges);\n await renameTable(target, temporary.recordedClock, tables.recordedClock);\n await renamePrimaryKeyConstraint(\n target,\n tables.recordedNodes,\n primaryKeyConstraintRenames.recordedNodes,\n );\n await renamePrimaryKeyConstraint(\n target,\n tables.recordedEdges,\n primaryKeyConstraintRenames.recordedEdges,\n );\n await renamePrimaryKeyConstraint(\n target,\n tables.recordedClock,\n primaryKeyConstraintRenames.recordedClock,\n );\n for (const statement of [\n ...ddl.recordedNodes.indexes,\n ...ddl.recordedEdges.indexes,\n ...ddl.recordedClock.indexes,\n ]) {\n await executeDdl(target, statement);\n }\n}\n\n/**\n * Renames the temporary table's PRIMARY KEY constraint to the final table's\n * name, once the swap has renamed the table itself. Both names come from the\n * authoring backend's `recordedTableDdl` (an ENGINE convention it alone\n * knows — engines that do not name PK constraints separately, e.g. SQLite,\n * return `undefined` for both, and this is a no-op). Identifier reduction on\n * an over-long target stays this migration's own decision — `shortenedIdentifier`\n * is applied to the target only, never the source (see {@link RecordedRelationDdl}).\n */\nasync function renamePrimaryKeyConstraint(\n target: TransactionBackend,\n finalTable: string,\n rename: PrimaryKeyConstraintRename,\n): Promise<void> {\n if (rename.status === \"none\") return;\n await executeStatement(\n target,\n sql`\n ALTER TABLE ${sql.identifier(finalTable)}\n RENAME CONSTRAINT ${sql.identifier(rename.from)}\n TO ${sql.identifier(shortenedIdentifier(rename.to))}\n `,\n );\n}\n\nasync function renameTable(\n target: TransactionBackend,\n from: string,\n to: string,\n): Promise<void> {\n try {\n await executeStatement(\n target,\n sql`ALTER TABLE ${sql.identifier(from)} RENAME TO ${sql.identifier(to)}`,\n );\n } catch (error) {\n throw new ConfigurationError(\n \"Could not rename a migrated recorded-time table.\",\n { from, to },\n { cause: error },\n );\n }\n}\n\n/**\n * Rewrites timestamp-only recorded relations to numeric revisions.\n *\n * Run offline before opening a Store with the new schema. The durable mapping\n * table is retained so external checkpoint stores can call\n * {@link migrateRecordedAnchor}; delete each graph's rows after its downstream\n * checkpoints have been rewritten.\n */\nexport async function migrateLegacyRecordedTime(\n options: MigrateLegacyRecordedTimeOptions,\n): Promise<MigrateLegacyRecordedTimeResult> {\n const tables = resolvedTableNames(options.backend, options.tableNames);\n const mapTable = mappingTableName(tables, options.mappingTableName);\n const recordedTableDdl = options.backend.recordedTableDdl;\n return options.backend.transaction(async (target) => {\n const clockColumns = await columnNames(target, tables.recordedClock);\n if (clockColumns.size === 0) {\n return {\n migrated: false,\n graphs: 0,\n anchors: 0,\n mappingTableName: mapTable,\n };\n }\n if (clockColumns.has(\"revision\")) {\n const mapColumns = await columnNames(target, mapTable);\n if (mapColumns.size === 0) {\n return {\n migrated: false,\n graphs: 0,\n anchors: 0,\n mappingTableName: mapTable,\n };\n }\n const rows = await target.execute<MappingCountRow>(\n asCompiledRowsSql(sql`\n SELECT COUNT(*) AS anchors, COUNT(DISTINCT graph_id) AS graphs\n FROM ${sql.identifier(mapTable)}\n `),\n );\n const anchors = Number(rows[0]?.anchors ?? 0);\n const graphs = Number(rows[0]?.graphs ?? 0);\n return {\n migrated: false,\n graphs: Number.isSafeInteger(graphs) ? graphs : 0,\n anchors: Number.isSafeInteger(anchors) ? anchors : 0,\n mappingTableName: mapTable,\n };\n }\n const nodeColumns = await columnNames(target, tables.recordedNodes);\n const edgeColumns = await columnNames(target, tables.recordedEdges);\n if (\n !nodeColumns.has(\"recorded_from\") ||\n !edgeColumns.has(\"recorded_from\")\n ) {\n throw new ConfigurationError(\n \"Legacy recorded-time schema is incomplete.\",\n { tables },\n );\n }\n\n if (recordedTableDdl === undefined) {\n throw new UnsupportedBackendCapabilityError(\n \"migrateLegacyRecordedTime\",\n \"recordedTableDdl\",\n { dialect: target.dialect, tables },\n \"Migrating the timestamp-only preview recorded schema needs the backend to author its own recorded-relation DDL. Only the bundled SQLite and PostgreSQL backends created that schema.\",\n );\n }\n\n await executeDdl(target, migrationMapDdl(target.dialect, mapTable));\n const mapping = await readLegacyInstants(target, tables);\n await writeMappingRows(target, mapTable, mapping);\n await replaceLegacyTables(target, tables, mapTable, recordedTableDdl);\n return {\n migrated: true,\n graphs: new Set(mapping.map((row) => row.graphId)).size,\n anchors: mapping.length,\n mappingTableName: mapTable,\n };\n });\n}\n\n/** Remaps one timestamp-only checkpoint after {@link migrateLegacyRecordedTime}. */\nexport async function migrateRecordedAnchor(\n options: MigrateRecordedAnchorOptions,\n): Promise<RecordedInstant> {\n try {\n return asRecordedInstant(options.anchor);\n } catch (error) {\n if (!(error instanceof ValidationError)) throw error;\n }\n const legacyRecordedAt = canonicalLegacyInstant(options.anchor);\n const tables = resolvedTableNames(options.backend, options.tableNames);\n const mapTable = mappingTableName(tables, options.mappingTableName);\n const rows = await options.backend.execute<RemapRow>(\n asCompiledRowsSql(sql`\n SELECT revision, recorded_at\n FROM ${sql.identifier(mapTable)}\n WHERE graph_id = ${options.graphId}\n AND legacy_recorded_at = ${legacyRecordedAt}\n `),\n );\n const row = rows[0];\n if (row === undefined) {\n throw new ConfigurationError(\n \"No migrated recorded anchor matches this graph and legacy timestamp.\",\n { anchor: options.anchor, graphId: options.graphId },\n {\n suggestion:\n \"Run migrateLegacyRecordedTime() before deleting its mapping rows, and pass the graph that produced the checkpoint.\",\n },\n );\n }\n return createRecordedInstant(\n safeRevision(row.revision),\n canonicalLegacyInstant(row.recorded_at),\n );\n}\n\n/**\n * Deletes one graph's legacy remap rows after downstream checkpoints migrate.\n * Set `dropWhenEmpty` to remove the migration table after the final graph.\n */\nexport async function deleteLegacyRecordedAnchorMap(\n options: DeleteLegacyRecordedAnchorMapOptions,\n): Promise<void> {\n requireStatements(options.backend);\n const tables = resolvedTableNames(options.backend, options.tableNames);\n const mapTable = mappingTableName(tables, options.mappingTableName);\n await options.backend.transaction(async (target) => {\n await executeStatement(\n target,\n sql`\n DELETE FROM ${sql.identifier(mapTable)}\n WHERE graph_id = ${options.graphId}\n `,\n );\n if (options.dropWhenEmpty !== true) return;\n const rows = await target.execute<MappingCountRow>(\n asCompiledRowsSql(sql`\n SELECT COUNT(*) AS anchors, COUNT(DISTINCT graph_id) AS graphs\n FROM ${sql.identifier(mapTable)}\n `),\n );\n const remaining = missingMappingCount(rows[0]?.anchors, mapTable);\n if (remaining === 0) {\n await executeStatement(\n target,\n sql`DROP TABLE ${sql.identifier(mapTable)}`,\n );\n }\n });\n}\n","/**\n * Offline repair for validity windows that older library versions stored\n * inverted (`valid_from > valid_to`).\n *\n * Such a row is readable at no coordinate at all: `asOf(t)` needs\n * `valid_from <= t < valid_to`, and no `t` satisfies both when the bounds are\n * backwards. The library no longer mints them — a write that stamps a lower\n * bound the caller did not state stores no bound rather than an inverting one —\n * but deploying that fix rewrites nothing, so rows written by an older version\n * (or by direct SQL) stay invisible until an operator repairs them.\n *\n * The repair normalizes those rows to \"ended at T, start unknown\"\n * (`valid_from = NULL`), which is the shape the current write paths store. It\n * deliberately does **not** bump `version`, touch `updated_at`, or mint a\n * recorded revision: it normalizes a storage convention for rows that were\n * never observable at any coordinate, so it is not a logical write — and\n * minting a revision would make the pre-repair recorded state re-materialize\n * the inverted shape at `asOfRecorded` coordinates.\n *\n * Operator consequences, all of them stated in the docs as well:\n *\n * 1. **Run `\"apply\"` with writers stopped.** A concurrent window-bearing update\n * may fence its write on the validity lower bound it read, so a repair that\n * lands in between can make the peer's first `UPDATE` match no row. Store\n * node/edge updates re-read and re-judge against the repaired bound; an\n * interchange update records a per-row target-changed error instead of\n * claiming the row was written. `\"report\"` needs no quiescing — it scans in\n * a read-only transaction, so it cannot write.\n * 2. **Repaired rows become visible** at `asOf` coordinates before their end.\n * That is the point, and it is a read-visibility change to historical\n * queries.\n * 3. **Outstanding `base@V` merge tokens are invalidated** for repaired rows —\n * `valid_from` is part of the base content fingerprint. Quiesce merges,\n * repair, then re-baseline branches.\n * 4. **Prefer `relations: \"live-and-recorded\"`.** Repairing only the live axis\n * leaves the recorded twin carrying the inverted window, which\n * re-materializes the invisible row at any `asOfRecorded` coordinate.\n */\nimport { ConfigurationError } from \"../errors\";\nimport type {\n ResolvedSqlTableNames,\n SqlTableNames,\n} from \"../query/compiler/schema\";\nimport { sql, type SqlFragment } from \"../query/sql-fragment\";\nimport { asCompiledRowsSql, asCompiledStatementSql } from \"../query/sql-intent\";\nimport { statementExecutionMembers } from \"./capabilities/bind\";\nimport type { STATEMENT_EXECUTION } from \"./capabilities/bundle-registry\";\nimport {\n type BundleVerdictOf,\n statementExecutionVerdict,\n} from \"./capabilities/resolve\";\nimport { resolvedTableNames } from \"./table-names\";\nimport {\n type GraphBackend,\n runOptionallyInTransaction,\n type RunOptionallyInTransactionOptions,\n type TransactionBackend,\n} from \"./types\";\n\n/** A relation whose rows carry a validity window this repair can normalize. */\nexport type RepairRelation =\n \"nodes\" | \"edges\" | \"recordedNodes\" | \"recordedEdges\";\n\n/**\n * Which relations one call scans.\n *\n * `\"live-and-recorded\"` is the recommended scope. `\"live\"` is correct in\n * exactly two cases: the store captures no history and the `recorded_*` tables\n * do not exist, or the operator is deliberately preserving the recorded axis as\n * an audit record of what was stored before the repair — and accepts that\n * historical `asOfRecorded` reads keep returning the invisible shape.\n */\nexport type RepairRelationScope = \"live\" | \"live-and-recorded\";\n\n/** Inputs for detecting or repairing legacy inverted validity windows. */\nexport type RepairInvertedWindowsOptions = Readonly<{\n backend: GraphBackend;\n /** Omit to sweep every graph in the database. */\n graphId?: string | undefined;\n /** Required: the scope is a decision, not a default. */\n relations: RepairRelationScope;\n /**\n * `\"report\"` counts and writes nothing; `\"apply\"` counts and then normalizes\n * the rows it counted.\n */\n mode: \"report\" | \"apply\";\n /**\n * Patch selected backend table names, exactly as migrate-recorded-time does.\n * Unstated names continue to come from `backend.tableNames`; see\n * {@link resolvedTableNames}.\n */\n tableNames?: Partial<SqlTableNames> | undefined;\n}>;\n\n/** Counts and execution guarantees observed by one repair/report call. */\nexport type RepairInvertedWindowsReport = Readonly<{\n /** Echoes the scope actually scanned — a count of 0 and \"not scanned\" are different facts. */\n relations: RepairRelationScope;\n /**\n * Rows whose stored window is inverted: found in `\"report\"` mode, repaired in\n * `\"apply\"` mode. `undefined` means NOT SCANNED, never \"clean\".\n */\n counts: Readonly<Record<RepairRelation, number | undefined>>;\n /**\n * Rows whose stored bounds are not canonical ISO and were therefore not\n * classified. SQLite only in substance: on PostgreSQL the columns are\n * `timestamptz`, so a scanned relation always reports `0` (never `undefined`\n * — that value is reserved for \"not scanned\", on both dialects).\n *\n * `\"apply\"` refuses while any scanned relation reports a non-zero count:\n * classifying those rows needs a timestamp semantics this repair does not\n * own, and skipping them silently would be an accepted option ignored.\n */\n nonCanonical: Readonly<Record<RepairRelation, number | undefined>>;\n /**\n * Whether every statement of this call ran in ONE transaction. `false` on a\n * backend that reports `capabilities.transactions === false`, where the call\n * degrades to per-relation statements.\n *\n * Reported by the seam, not inferred from backend object identity:\n * {@link runOptionallyInTransaction} explicitly tells its callback whether it\n * opened a transaction. \"One snapshot\" and \"four snapshots\" are different\n * facts about a report, and the report must state which occurred even when a\n * custom backend passes the same object into its transaction callback.\n *\n * When `false`, a `\"report\"`'s counts may come from different snapshots and a\n * crash mid-`\"apply\"` can leave the live axis repaired and the recorded axis\n * not. Both are survivable the same way: each relation's statement is\n * idempotent and convergent, so a re-run finishes the job and a later\n * `\"report\"` proves it.\n */\n atomic: boolean;\n}>;\n\nconst LIVE_RELATIONS = [\n \"nodes\",\n \"edges\",\n] as const satisfies readonly RepairRelation[];\n\nconst RECORDED_RELATIONS = [\n \"recordedNodes\",\n \"recordedEdges\",\n] as const satisfies readonly RepairRelation[];\n\n/**\n * Canonical fixed-width UTC ISO 8601, as a SQLite `GLOB` pattern.\n *\n * SQLite stores the bounds as `TEXT` and compares them lexicographically, which\n * equals chronological order only for canonical values. This repair exists to\n * clean up rows written by older paths and by direct SQL, so it cannot assume\n * canonicality — it establishes it per row instead.\n */\nconst CANONICAL_INSTANT_GLOB =\n \"[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]Z\";\n\ntype RepairTarget = GraphBackend | TransactionBackend;\n\ntype CountRow = Readonly<{ matches: unknown }>;\n\nfunction scopedRelations(\n scope: RepairRelationScope,\n): readonly RepairRelation[] {\n return scope === \"live\" ? LIVE_RELATIONS : (\n [...LIVE_RELATIONS, ...RECORDED_RELATIONS]\n );\n}\n\nfunction relationTable(\n tables: ResolvedSqlTableNames,\n relation: RepairRelation,\n): string {\n switch (relation) {\n case \"nodes\": {\n return tables.nodes;\n }\n case \"edges\": {\n return tables.edges;\n }\n case \"recordedNodes\": {\n return tables.recordedNodes;\n }\n case \"recordedEdges\": {\n return tables.recordedEdges;\n }\n }\n}\n\nfunction graphScopeClauses(\n graphId: string | undefined,\n): readonly SqlFragment[] {\n return graphId === undefined ? [] : [sql`graph_id = ${graphId}`];\n}\n\nfunction canonicalBoundsClauses(\n dialect: GraphBackend[\"dialect\"],\n): readonly SqlFragment[] {\n if (dialect !== \"sqlite\") return [];\n return [\n sql`valid_from GLOB ${CANONICAL_INSTANT_GLOB}`,\n sql`valid_to GLOB ${CANONICAL_INSTANT_GLOB}`,\n ];\n}\n\n/**\n * The one spelling of \"this stored window is inverted\".\n *\n * Both modes compile it: `\"report\"` into `SELECT COUNT(*) … WHERE <this>` and\n * `\"apply\"` into `UPDATE … SET valid_from = NULL WHERE <this>`, so the count\n * and the repair cannot disagree about which rows are in scope.\n *\n * The comparison is strict (`>`). A stored zero-width window is a legal shape a\n * caller may have stated in full, and this repair does not second-guess it.\n */\nexport function invertedValidityWindowPredicate(\n options: Readonly<{\n dialect: GraphBackend[\"dialect\"];\n graphId?: string | undefined;\n }>,\n): SqlFragment {\n return sql.join(\n [\n sql`valid_from IS NOT NULL`,\n sql`valid_to IS NOT NULL`,\n ...canonicalBoundsClauses(options.dialect),\n sql`valid_from > valid_to`,\n ...graphScopeClauses(options.graphId),\n ],\n sql` AND `,\n );\n}\n\n/**\n * Rows carrying both bounds where either one is not canonical, and which the\n * inverted predicate therefore refuses to classify. SQLite only: PostgreSQL\n * stores `timestamptz`, where every stored value compares chronologically.\n */\nfunction nonCanonicalWindowPredicate(graphId: string | undefined): SqlFragment {\n return sql.join(\n [\n sql`valid_from IS NOT NULL`,\n sql`valid_to IS NOT NULL`,\n sql`(valid_from NOT GLOB ${CANONICAL_INSTANT_GLOB} OR valid_to NOT GLOB ${CANONICAL_INSTANT_GLOB})`,\n ...graphScopeClauses(graphId),\n ],\n sql` AND `,\n );\n}\n\nfunction safeCount(value: unknown, table: string): number {\n const count = Number(value);\n if (!Number.isSafeInteger(count) || count < 0) {\n throw new ConfigurationError(\n \"Validity-window repair returned an invalid row count.\",\n { table, value },\n );\n }\n return count;\n}\n\nasync function countMatching(\n target: RepairTarget,\n table: string,\n predicate: SqlFragment,\n): Promise<number> {\n const rows = await target.execute<CountRow>(\n asCompiledRowsSql(sql`\n SELECT COUNT(*) AS matches\n FROM ${sql.identifier(table)}\n WHERE ${predicate}\n `),\n );\n return safeCount(rows[0]?.matches, table);\n}\n\n/**\n * `\"apply\"` writes, so it needs the optional non-row-returning statement path.\n * `\"report\"` deliberately does not: `execute` is a required member, so\n * detection stays available on every backend even where repair is not.\n *\n * Shared by both throw sites below: the public entry refuses BEFORE opening a\n * transaction (so an unsupported backend never pays for one), and\n * {@link repairRelation}'s own guard exists ONLY because a nested closure\n * cannot inherit the entry's narrowing of `verdict` to `{ supported: true }` —\n * it can never fire at runtime, since the entry already refused. One message,\n * two structurally-required call sites.\n */\nfunction statementExecutionRequiredError(\n dialect: GraphBackend[\"dialect\"],\n): ConfigurationError {\n return new ConfigurationError(\n \"Repairing inverted validity windows requires executeStatement support.\",\n { dialect, mode: \"apply\" },\n {\n suggestion:\n 'Use a built-in SQLite or PostgreSQL backend to apply the repair. Detection needs no such support: call this with mode: \"report\" to count the affected rows on any backend.',\n },\n );\n}\n\n/**\n * Translates the recorded-capture wrapper's refusal instead of swallowing it.\n *\n * A history-enabled store replaces `executeStatement` with a rejecting stub, so\n * `\"apply\"` against that backend fails with a message about raw SQL rather than\n * about this repair. The remedy is specific enough to be worth naming: hand the\n * repair the raw backend the history store was constructed from. Bypassing\n * capture is the intended behavior here, not a workaround — the repair mints no\n * revision by design.\n */\nfunction translatedCaptureRefusal(error: unknown): unknown {\n if (\n !(error instanceof ConfigurationError) ||\n error.details[\"code\"] !== \"RECORDED_CAPTURE_RAW_SQL_DISABLED\"\n ) {\n return error;\n }\n return new ConfigurationError(\n \"Repairing inverted validity windows cannot run against a history-capturing backend.\",\n { code: \"RECORDED_CAPTURE_RAW_SQL_DISABLED\", mode: \"apply\" },\n {\n cause: error,\n suggestion:\n 'Pass the raw backend you constructed the history store from. The repair deliberately mints no revision — it normalizes storage for rows that were never visible at any coordinate — so bypassing recorded-time capture is the intended behavior, not a workaround. mode: \"report\" needs no such care: it runs against the capture-wrapped backend.',\n },\n );\n}\n\nasync function repairRelation(\n target: RepairTarget,\n verdict: BundleVerdictOf<typeof STATEMENT_EXECUTION>,\n table: string,\n predicate: SqlFragment,\n): Promise<void> {\n // Unreachable at runtime: `repairInvertedValidityWindows` already refused an\n // unsupported backend before opening the transaction this runs inside. The\n // check exists only so `verdict` narrows for `statementExecutionMembers` —\n // TypeScript does not carry the entry's narrowing into this closure.\n if (!verdict.supported) {\n throw statementExecutionRequiredError(target.dialect);\n }\n try {\n await statementExecutionMembers(target, verdict).executeStatement(\n asCompiledStatementSql(sql`\n UPDATE ${sql.identifier(table)}\n SET valid_from = NULL\n WHERE ${predicate}\n `),\n );\n } catch (error) {\n throw translatedCaptureRefusal(error);\n }\n}\n\nfunction assertClassifiableBounds(\n nonCanonical: ReadonlyMap<RepairRelation, number>,\n): void {\n const unclassified = [...nonCanonical].filter(([, count]) => count > 0);\n if (unclassified.length === 0) return;\n throw new ConfigurationError(\n \"Refusing to repair validity windows: some scanned rows store non-canonical bounds.\",\n { nonCanonical: Object.fromEntries(unclassified) },\n {\n suggestion:\n 'Normalize those bounds to canonical UTC ISO 8601 (YYYY-MM-DDTHH:MM:SS.mmmZ) and re-run, or narrow the call with graphId. Classifying them here would need a timestamp semantics this repair does not own, and skipping them silently would report a repair it did not make. mode: \"report\" still counts them.',\n },\n );\n}\n\n/**\n * Declares `\"report\"`'s read-only-ness to the ENGINE rather than only to the\n * reader of this file.\n *\n * The docs send an operator to diagnose against the live store's backend and\n * require quiescing only for `\"apply\"`, so the scan must not behave like a\n * writer: on SQLite a default transaction is `BEGIN IMMEDIATE`, which reserves\n * the single writer slot for the duration of up to four full-table `COUNT(*)`\n * scans and can fail `SQLITE_BUSY` against an active writer; `read_only` issues\n * a plain `BEGIN` instead. On PostgreSQL it issues `BEGIN … READ ONLY`, which\n * makes \"report writes nothing\" enforced by the engine and not merely asserted\n * by a test.\n *\n * `\"apply\"` writes, so it takes the default read-write transaction.\n */\nfunction transactionOptionsFor(\n mode: RepairInvertedWindowsOptions[\"mode\"],\n): RunOptionallyInTransactionOptions | undefined {\n return mode === \"report\" ?\n { transaction: { accessMode: \"read_only\" } }\n : undefined;\n}\n\nfunction relationRecord(\n counts: ReadonlyMap<RepairRelation, number>,\n): Readonly<Record<RepairRelation, number | undefined>> {\n return {\n nodes: counts.get(\"nodes\"),\n edges: counts.get(\"edges\"),\n recordedNodes: counts.get(\"recordedNodes\"),\n recordedEdges: counts.get(\"recordedEdges\"),\n };\n}\n\n/**\n * Counts — and, in `\"apply\"` mode, normalizes — rows whose stored validity\n * window is inverted.\n *\n * ```typescript\n * // Diagnose with the store's backend: `report` reads only, so it runs\n * // anywhere, including a capture-wrapped or statement-less backend.\n * const report = await repairInvertedValidityWindows({\n * backend: anyBackend,\n * relations: \"live-and-recorded\",\n * mode: \"report\",\n * });\n *\n * // Repair with the raw one, while writers are stopped.\n * await repairInvertedValidityWindows({\n * backend: rawBackend,\n * relations: \"live-and-recorded\",\n * mode: \"apply\",\n * });\n * ```\n *\n * Idempotent and convergent: a second `\"apply\"` reports zero, because the rows\n * the first one repaired no longer match the predicate.\n *\n * No batching, deliberately. Unlike the recorded-time migration, which rewrites\n * every row, this statement touches only rows the library mis-stored — an empty\n * set on a healthy graph. A deployment that reports a count large enough to\n * worry about should run it per `graphId`.\n *\n * @throws ConfigurationError in `\"apply\"` mode when the backend cannot execute\n * statements, when the backend is a recorded-capture wrapper, or when any\n * scanned relation stores non-canonical bounds. A transaction TARGET that\n * disagrees with the top-level verdict (missing `executeStatement` the\n * top-level backend has) refuses separately, with I20's\n * `BUNDLE_PORT_SURFACE_MISMATCH` — the per-bundle port check\n * `statementExecutionMembers` performs, not a second spelling of this one.\n */\nexport async function repairInvertedValidityWindows(\n options: RepairInvertedWindowsOptions,\n): Promise<RepairInvertedWindowsReport> {\n const tables = resolvedTableNames(options.backend, options.tableNames);\n const relations = scopedRelations(options.relations);\n const verdict = statementExecutionVerdict(options.backend);\n // Refuse before opening a transaction: a backend with no statement path can\n // never apply, whatever the scan finds.\n if (options.mode === \"apply\" && !verdict.supported) {\n throw statementExecutionRequiredError(options.backend.dialect);\n }\n\n return runOptionallyInTransaction(\n options.backend,\n async (target, execution) => {\n const predicate = invertedValidityWindowPredicate({\n dialect: target.dialect,\n graphId: options.graphId,\n });\n const inverted = new Map<RepairRelation, number>();\n const nonCanonical = new Map<RepairRelation, number>();\n for (const relation of relations) {\n const table = relationTable(tables, relation);\n nonCanonical.set(\n relation,\n target.dialect === \"sqlite\" ?\n await countMatching(\n target,\n table,\n nonCanonicalWindowPredicate(options.graphId),\n )\n : 0,\n );\n inverted.set(relation, await countMatching(target, table, predicate));\n }\n\n if (options.mode === \"apply\") {\n assertClassifiableBounds(nonCanonical);\n for (const relation of relations) {\n await repairRelation(\n target,\n verdict,\n relationTable(tables, relation),\n predicate,\n );\n }\n }\n\n return {\n relations: options.relations,\n counts: relationRecord(inverted),\n nonCanonical: relationRecord(nonCanonical),\n atomic: execution.atomic,\n };\n },\n transactionOptionsFor(options.mode),\n );\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkL3LQNR34_cjs = require('./chunk-L3LQNR34.cjs');
3
+ var chunkH2VWDQWC_cjs = require('./chunk-H2VWDQWC.cjs');
4
4
 
5
5
  // src/indexes/system.ts
6
6
  var SYSTEM_INDEX_DECLARATIONS = [
@@ -175,7 +175,7 @@ var MAX_SQL_IDENTIFIER_LENGTH = 63;
175
175
  function systemIndexName(physicalTableName, suffix) {
176
176
  const full = `${physicalTableName}_${suffix}`;
177
177
  if (full.length <= MAX_SQL_IDENTIFIER_LENGTH) return full;
178
- const hash = chunkL3LQNR34_cjs.shortHash(JSON.stringify([physicalTableName, suffix]));
178
+ const hash = chunkH2VWDQWC_cjs.shortHash(JSON.stringify([physicalTableName, suffix]));
179
179
  return `${full.slice(0, MAX_SQL_IDENTIFIER_LENGTH - 1 - hash.length)}_${hash}`;
180
180
  }
181
181
  function resolveSystemIndexNames(overrides) {
@@ -200,11 +200,11 @@ function assertNoSystemIndexNameCollision(indexes, overrides) {
200
200
  }
201
201
  }
202
202
  function generateSystemIndexDDL(declaration, physicalTableName, options) {
203
- const name = chunkL3LQNR34_cjs.quoteIdentifier(
203
+ const name = chunkH2VWDQWC_cjs.quoteIdentifier(
204
204
  systemIndexName(physicalTableName, declaration.suffix)
205
205
  );
206
- const table = chunkL3LQNR34_cjs.quoteIdentifier(physicalTableName);
207
- const columns = declaration.columns.map((column) => chunkL3LQNR34_cjs.quoteIdentifier(column)).join(", ");
206
+ const table = chunkH2VWDQWC_cjs.quoteIdentifier(physicalTableName);
207
+ const columns = declaration.columns.map((column) => chunkH2VWDQWC_cjs.quoteIdentifier(column)).join(", ");
208
208
  const concurrently = options.concurrent ? "CONCURRENTLY " : "";
209
209
  return `CREATE INDEX ${concurrently}IF NOT EXISTS ${name} ON ${table} (${columns});`;
210
210
  }
@@ -215,5 +215,5 @@ exports.generateSystemIndexDDL = generateSystemIndexDDL;
215
215
  exports.resolveSystemIndexNames = resolveSystemIndexNames;
216
216
  exports.resolveSystemIndexTableName = resolveSystemIndexTableName;
217
217
  exports.systemIndexName = systemIndexName;
218
- //# sourceMappingURL=chunk-OI2GQ25X.cjs.map
219
- //# sourceMappingURL=chunk-OI2GQ25X.cjs.map
218
+ //# sourceMappingURL=chunk-I7YAY2VQ.cjs.map
219
+ //# sourceMappingURL=chunk-I7YAY2VQ.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/indexes/system.ts"],"names":["shortHash","quoteIdentifier"],"mappings":"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","file":"chunk-OI2GQ25X.cjs","sourcesContent":["/**\n * System-index declarations — the single source of truth for the plain\n * btree indexes TypeGraph ships on its own relations.\n *\n * Both dialect schema factories (`createSqliteTables` /\n * `createPostgresTables`) derive their Drizzle index builders from this\n * list, so the two dialects cannot drift, and\n * `materializeSystemIndexes()` derives the same indexes as runtime DDL so\n * an index added in a new library version reaches already-initialized\n * databases (bootstrap DDL only runs on first boot — see\n * `loadActiveSchemaWithBootstrap`).\n *\n * Scope: non-unique btree column indexes on the four graph relations,\n * where performance iteration actually happens. Primary keys, unique /\n * partial-unique constraints, and status-table indexes are structural —\n * they are created with their table and never retrofitted — and stay in\n * the schema files.\n *\n * Changing a declaration's shape under the same suffix is a signature\n * drift: `materializeSystemIndexes` reports `failed` for it until the\n * operator drops the old physical index. Rename (new suffix) instead,\n * exactly like graph-declared indexes. Two acknowledged limits of that\n * contract: on databases whose indexes were bootstrap-created (no status\n * rows) an in-place reshape is undetectable at runtime — the rename rule\n * is enforced by review and the parity tests; and a renamed suffix\n * strands the old physical index (the runner only adds). When the first\n * rename actually happens, add a retired-suffixes list + drop path here.\n */\nimport { quoteIdentifier, shortHash } from \"../query/dialect/vector-strategy\";\n\n/** The TypeGraph relations that carry system indexes. */\nexport type SystemIndexTable =\n \"nodes\" | \"edges\" | \"recordedNodes\" | \"recordedEdges\";\n\ntype LiveColumn =\n | \"graph_id\"\n | \"kind\"\n | \"id\"\n | \"deleted_at\"\n | \"valid_from\"\n | \"valid_to\"\n | \"created_at\";\n\ntype LiveEdgeColumn =\n LiveColumn | \"from_kind\" | \"from_id\" | \"to_kind\" | \"to_id\";\n\ntype RecordedColumn =\n | \"graph_id\"\n | \"kind\"\n | \"id\"\n | \"valid_from\"\n | \"valid_to\"\n | \"recorded_from\"\n | \"recorded_to\";\n\ntype RecordedEdgeColumn =\n RecordedColumn | \"from_kind\" | \"from_id\" | \"to_kind\" | \"to_id\";\n\ntype SystemIndexColumnsFor<T extends SystemIndexTable> =\n T extends \"nodes\" ? LiveColumn\n : T extends \"edges\" ? LiveEdgeColumn\n : T extends \"recordedNodes\" ? RecordedColumn\n : RecordedEdgeColumn;\n\ntype SystemIndexDeclarationFor<T extends SystemIndexTable> = Readonly<{\n table: T;\n /** Physical index name is `${physicalTableName}_${suffix}`. */\n suffix: string;\n columns: readonly [SystemIndexColumnsFor<T>, ...SystemIndexColumnsFor<T>[]];\n}>;\n\nexport type SystemIndexDeclaration =\n | SystemIndexDeclarationFor<\"nodes\">\n | SystemIndexDeclarationFor<\"edges\">\n | SystemIndexDeclarationFor<\"recordedNodes\">\n | SystemIndexDeclarationFor<\"recordedEdges\">;\n\nexport const SYSTEM_INDEX_DECLARATIONS: readonly SystemIndexDeclaration[] = [\n // ---------------------------------------------------------- nodes\n { table: \"nodes\", suffix: \"kind_idx\", columns: [\"graph_id\", \"kind\"] },\n // Listing shape: kind partition ordered by creation with the\n // soft-delete column ahead of it so `deleted_at IS NULL` list queries\n // stay index-served.\n {\n table: \"nodes\",\n suffix: \"kind_created_idx\",\n columns: [\"graph_id\", \"kind\", \"deleted_at\", \"created_at\"],\n },\n {\n table: \"nodes\",\n suffix: \"deleted_idx\",\n columns: [\"graph_id\", \"deleted_at\"],\n },\n {\n table: \"nodes\",\n suffix: \"valid_idx\",\n columns: [\"graph_id\", \"valid_from\", \"valid_to\"],\n },\n // Bare-id lookup: the primary key leads with `kind` (graph_id, kind,\n // id), so a `WHERE graph_id = ? AND id = ?` probe that doesn't know the\n // kind can't seek it — SQLite falls back to a graph_id-only scan of\n // every node in the graph (~3M at LDBC SF1).\n // `store.algorithms.degree`'s node-kind subquery does exactly that\n // lookup (it resolves the seed's kind by id), so without this index\n // degree is a full nodes scan (~95ms at SF1). See typegraph#280.\n { table: \"nodes\", suffix: \"id_idx\", columns: [\"graph_id\", \"id\"] },\n\n // ---------------------------------------------------------- edges\n { table: \"edges\", suffix: \"kind_idx\", columns: [\"graph_id\", \"kind\"] },\n // Directional traversal index (outgoing): supports endpoint lookups\n // and extra filtering by edge kind / target kind. Includes every\n // system column the compiled query's soft-delete/temporal-validity\n // predicate touches (deleted_at, valid_from, valid_to), trailed by\n // to_id — the compiled traversal join reads `n.id = e.to_id` for an\n // outgoing traversal (standard-builders.ts), so without to_id here\n // the join still fetches the edge's heap row for that one column\n // even with the seek/predicate columns covered.\n {\n table: \"edges\",\n suffix: \"from_idx\",\n columns: [\n \"graph_id\",\n \"from_kind\",\n \"from_id\",\n \"kind\",\n \"to_kind\",\n \"deleted_at\",\n \"valid_from\",\n \"valid_to\",\n \"to_id\",\n ],\n },\n // Directional traversal index (incoming): mirrors from_idx for\n // reverse traversals, trailed by from_id for the same reason\n // (`n.id = e.from_id` for an incoming traversal).\n {\n table: \"edges\",\n suffix: \"to_idx\",\n columns: [\n \"graph_id\",\n \"to_kind\",\n \"to_id\",\n \"kind\",\n \"from_kind\",\n \"deleted_at\",\n \"valid_from\",\n \"valid_to\",\n \"from_id\",\n ],\n },\n {\n table: \"edges\",\n suffix: \"kind_created_idx\",\n columns: [\"graph_id\", \"kind\", \"deleted_at\", \"created_at\"],\n },\n {\n table: \"edges\",\n suffix: \"deleted_idx\",\n columns: [\"graph_id\", \"deleted_at\"],\n },\n {\n table: \"edges\",\n suffix: \"valid_idx\",\n columns: [\"graph_id\", \"valid_from\", \"valid_to\"],\n },\n // Cardinality enforcement: the one-per-endpoint check probes for a\n // currently-valid edge of a kind from a specific endpoint.\n {\n table: \"edges\",\n suffix: \"cardinality_idx\",\n columns: [\"graph_id\", \"kind\", \"from_kind\", \"from_id\", \"valid_to\"],\n },\n\n // ---------------------------------------------------------- recordedNodes\n {\n table: \"recordedNodes\",\n suffix: \"entity_idx\",\n columns: [\"graph_id\", \"kind\", \"id\", \"recorded_from\", \"recorded_to\"],\n },\n {\n table: \"recordedNodes\",\n suffix: \"open_idx\",\n columns: [\"graph_id\", \"recorded_to\"],\n },\n {\n table: \"recordedNodes\",\n suffix: \"valid_idx\",\n columns: [\"graph_id\", \"valid_from\", \"valid_to\"],\n },\n // Bare-id lookup parity with the live nodes table: recorded-pinned\n // reads swap this relation in as the node source, and `entity_idx`\n // leads with `kind`, so the same kind-by-bare-id probe (e.g.\n // `degree()` at a recorded coordinate) would otherwise scan every\n // historical version in the graph. See typegraph#280.\n { table: \"recordedNodes\", suffix: \"id_idx\", columns: [\"graph_id\", \"id\"] },\n\n // ---------------------------------------------------------- recordedEdges\n {\n table: \"recordedEdges\",\n suffix: \"entity_idx\",\n columns: [\"graph_id\", \"kind\", \"id\", \"recorded_from\", \"recorded_to\"],\n },\n {\n table: \"recordedEdges\",\n suffix: \"open_idx\",\n columns: [\"graph_id\", \"recorded_to\"],\n },\n {\n table: \"recordedEdges\",\n suffix: \"from_idx\",\n columns: [\n \"graph_id\",\n \"from_kind\",\n \"from_id\",\n \"kind\",\n \"to_kind\",\n \"recorded_from\",\n \"recorded_to\",\n ],\n },\n {\n table: \"recordedEdges\",\n suffix: \"to_idx\",\n columns: [\n \"graph_id\",\n \"to_kind\",\n \"to_id\",\n \"kind\",\n \"from_kind\",\n \"recorded_from\",\n \"recorded_to\",\n ],\n },\n {\n table: \"recordedEdges\",\n suffix: \"valid_idx\",\n columns: [\"graph_id\", \"valid_from\", \"valid_to\"],\n },\n];\n\n/** Default physical table names for the system-index relations. */\nconst DEFAULT_SYSTEM_INDEX_TABLE_NAMES: Readonly<\n Record<SystemIndexTable, string>\n> = {\n nodes: \"typegraph_nodes\",\n edges: \"typegraph_edges\",\n recordedNodes: \"typegraph_recorded_nodes\",\n recordedEdges: \"typegraph_recorded_edges\",\n};\n\n/**\n * Resolves the physical table name for a system-index relation, honoring\n * a backend's table-name overrides.\n */\nexport function resolveSystemIndexTableName(\n table: SystemIndexTable,\n overrides:\n Readonly<Partial<Record<SystemIndexTable, string | undefined>>> | undefined,\n): string {\n return overrides?.[table] ?? DEFAULT_SYSTEM_INDEX_TABLE_NAMES[table];\n}\n\n/**\n * PostgreSQL truncates identifiers to NAMEDATALEN-1 = 63 bytes SILENTLY —\n * two suffixes of one long custom table name would collide after\n * truncation, and the catalog probes (which compare by exact name) would\n * never match the stored name, re-attempting the build on every boot.\n * SQLite has no such limit but uses the same bound so the two dialects'\n * index sets stay in byte-for-byte parity. (Char-based like the vector\n * identifier bound — multibyte table names are out of scope.)\n */\nconst MAX_SQL_IDENTIFIER_LENGTH = 63;\n\n/**\n * Physical index name: `${physicalTableName}_${suffix}`, deterministically\n * truncated + hash-suffixed past the 63-char identifier bound so distinct\n * indexes stay distinct. Single choke point — the Drizzle builders, the\n * runtime DDL, the catalog probes, and the status keys all derive the\n * name here, so they can never disagree.\n */\nexport function systemIndexName(\n physicalTableName: string,\n suffix: string,\n): string {\n const full = `${physicalTableName}_${suffix}`;\n if (full.length <= MAX_SQL_IDENTIFIER_LENGTH) return full;\n const hash = shortHash(JSON.stringify([physicalTableName, suffix]));\n return `${full.slice(0, MAX_SQL_IDENTIFIER_LENGTH - 1 - hash.length)}_${hash}`;\n}\n\n/**\n * Every system index name for a deployment's (possibly overridden) table\n * names. Graph-declared index names must not collide with these: a\n * colliding `CREATE INDEX IF NOT EXISTS` would silently no-op against the\n * system index (wrong shape) while recording a false success — see the\n * guards in the schema factories and `materializeIndexes`.\n */\nexport function resolveSystemIndexNames(\n overrides:\n Readonly<Partial<Record<SystemIndexTable, string | undefined>>> | undefined,\n): ReadonlySet<string> {\n return new Set(\n SYSTEM_INDEX_DECLARATIONS.map((declaration) =>\n systemIndexName(\n resolveSystemIndexTableName(declaration.table, overrides),\n declaration.suffix,\n ),\n ),\n );\n}\n\n/**\n * Rejects graph-declared indexes whose names collide with this\n * deployment's system index names. Called by both dialect schema\n * factories so a colliding declaration fails at table-definition time\n * instead of silently no-opping against the (differently shaped) system\n * index at CREATE INDEX IF NOT EXISTS time. `materializeIndexes` applies\n * the same check per-declaration on its runtime path.\n */\nexport function assertNoSystemIndexNameCollision(\n indexes: readonly Readonly<{ name: string }>[],\n overrides:\n Readonly<Partial<Record<SystemIndexTable, string | undefined>>> | undefined,\n): void {\n if (indexes.length === 0) return;\n const reserved = resolveSystemIndexNames(overrides);\n for (const index of indexes) {\n if (reserved.has(index.name)) {\n throw new Error(\n `Index name \"${index.name}\" collides with a TypeGraph system ` +\n `index. Choose a different name — system index names are ` +\n `reserved, and a same-named CREATE INDEX IF NOT EXISTS would ` +\n `silently no-op against the system index instead of creating ` +\n `the declared one.`,\n );\n }\n }\n}\n\n/**\n * Runtime DDL for one system index — byte-compatible with the index the\n * bootstrap path creates from the Drizzle schema (same name, same\n * columns), plus `CONCURRENTLY` where the dialect supports building\n * without blocking writes.\n */\nexport function generateSystemIndexDDL(\n declaration: SystemIndexDeclaration,\n physicalTableName: string,\n options: Readonly<{ concurrent: boolean }>,\n): string {\n const name = quoteIdentifier(\n systemIndexName(physicalTableName, declaration.suffix),\n );\n const table = quoteIdentifier(physicalTableName);\n const columns = declaration.columns\n .map((column) => quoteIdentifier(column))\n .join(\", \");\n const concurrently = options.concurrent ? \"CONCURRENTLY \" : \"\";\n return `CREATE INDEX ${concurrently}IF NOT EXISTS ${name} ON ${table} (${columns});`;\n}\n"]}
1
+ {"version":3,"sources":["../src/indexes/system.ts"],"names":["shortHash","quoteIdentifier"],"mappings":"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","file":"chunk-I7YAY2VQ.cjs","sourcesContent":["/**\n * System-index declarations — the single source of truth for the plain\n * btree indexes TypeGraph ships on its own relations.\n *\n * Both dialect schema factories (`createSqliteTables` /\n * `createPostgresTables`) derive their Drizzle index builders from this\n * list, so the two dialects cannot drift, and\n * `materializeSystemIndexes()` derives the same indexes as runtime DDL so\n * an index added in a new library version reaches already-initialized\n * databases (bootstrap DDL only runs on first boot — see\n * `loadActiveSchemaWithBootstrap`).\n *\n * Scope: non-unique btree column indexes on the four graph relations,\n * where performance iteration actually happens. Primary keys, unique /\n * partial-unique constraints, and status-table indexes are structural —\n * they are created with their table and never retrofitted — and stay in\n * the schema files.\n *\n * Changing a declaration's shape under the same suffix is a signature\n * drift: `materializeSystemIndexes` reports `failed` for it until the\n * operator drops the old physical index. Rename (new suffix) instead,\n * exactly like graph-declared indexes. Two acknowledged limits of that\n * contract: on databases whose indexes were bootstrap-created (no status\n * rows) an in-place reshape is undetectable at runtime — the rename rule\n * is enforced by review and the parity tests; and a renamed suffix\n * strands the old physical index (the runner only adds). When the first\n * rename actually happens, add a retired-suffixes list + drop path here.\n */\nimport { quoteIdentifier, shortHash } from \"../query/dialect/vector-strategy\";\n\n/** The TypeGraph relations that carry system indexes. */\nexport type SystemIndexTable =\n \"nodes\" | \"edges\" | \"recordedNodes\" | \"recordedEdges\";\n\ntype LiveColumn =\n | \"graph_id\"\n | \"kind\"\n | \"id\"\n | \"deleted_at\"\n | \"valid_from\"\n | \"valid_to\"\n | \"created_at\";\n\ntype LiveEdgeColumn =\n LiveColumn | \"from_kind\" | \"from_id\" | \"to_kind\" | \"to_id\";\n\ntype RecordedColumn =\n | \"graph_id\"\n | \"kind\"\n | \"id\"\n | \"valid_from\"\n | \"valid_to\"\n | \"recorded_from\"\n | \"recorded_to\";\n\ntype RecordedEdgeColumn =\n RecordedColumn | \"from_kind\" | \"from_id\" | \"to_kind\" | \"to_id\";\n\ntype SystemIndexColumnsFor<T extends SystemIndexTable> =\n T extends \"nodes\" ? LiveColumn\n : T extends \"edges\" ? LiveEdgeColumn\n : T extends \"recordedNodes\" ? RecordedColumn\n : RecordedEdgeColumn;\n\ntype SystemIndexDeclarationFor<T extends SystemIndexTable> = Readonly<{\n table: T;\n /** Physical index name is `${physicalTableName}_${suffix}`. */\n suffix: string;\n columns: readonly [SystemIndexColumnsFor<T>, ...SystemIndexColumnsFor<T>[]];\n}>;\n\nexport type SystemIndexDeclaration =\n | SystemIndexDeclarationFor<\"nodes\">\n | SystemIndexDeclarationFor<\"edges\">\n | SystemIndexDeclarationFor<\"recordedNodes\">\n | SystemIndexDeclarationFor<\"recordedEdges\">;\n\nexport const SYSTEM_INDEX_DECLARATIONS: readonly SystemIndexDeclaration[] = [\n // ---------------------------------------------------------- nodes\n { table: \"nodes\", suffix: \"kind_idx\", columns: [\"graph_id\", \"kind\"] },\n // Listing shape: kind partition ordered by creation with the\n // soft-delete column ahead of it so `deleted_at IS NULL` list queries\n // stay index-served.\n {\n table: \"nodes\",\n suffix: \"kind_created_idx\",\n columns: [\"graph_id\", \"kind\", \"deleted_at\", \"created_at\"],\n },\n {\n table: \"nodes\",\n suffix: \"deleted_idx\",\n columns: [\"graph_id\", \"deleted_at\"],\n },\n {\n table: \"nodes\",\n suffix: \"valid_idx\",\n columns: [\"graph_id\", \"valid_from\", \"valid_to\"],\n },\n // Bare-id lookup: the primary key leads with `kind` (graph_id, kind,\n // id), so a `WHERE graph_id = ? AND id = ?` probe that doesn't know the\n // kind can't seek it — SQLite falls back to a graph_id-only scan of\n // every node in the graph (~3M at LDBC SF1).\n // `store.algorithms.degree`'s node-kind subquery does exactly that\n // lookup (it resolves the seed's kind by id), so without this index\n // degree is a full nodes scan (~95ms at SF1). See typegraph#280.\n { table: \"nodes\", suffix: \"id_idx\", columns: [\"graph_id\", \"id\"] },\n\n // ---------------------------------------------------------- edges\n { table: \"edges\", suffix: \"kind_idx\", columns: [\"graph_id\", \"kind\"] },\n // Directional traversal index (outgoing): supports endpoint lookups\n // and extra filtering by edge kind / target kind. Includes every\n // system column the compiled query's soft-delete/temporal-validity\n // predicate touches (deleted_at, valid_from, valid_to), trailed by\n // to_id — the compiled traversal join reads `n.id = e.to_id` for an\n // outgoing traversal (standard-builders.ts), so without to_id here\n // the join still fetches the edge's heap row for that one column\n // even with the seek/predicate columns covered.\n {\n table: \"edges\",\n suffix: \"from_idx\",\n columns: [\n \"graph_id\",\n \"from_kind\",\n \"from_id\",\n \"kind\",\n \"to_kind\",\n \"deleted_at\",\n \"valid_from\",\n \"valid_to\",\n \"to_id\",\n ],\n },\n // Directional traversal index (incoming): mirrors from_idx for\n // reverse traversals, trailed by from_id for the same reason\n // (`n.id = e.from_id` for an incoming traversal).\n {\n table: \"edges\",\n suffix: \"to_idx\",\n columns: [\n \"graph_id\",\n \"to_kind\",\n \"to_id\",\n \"kind\",\n \"from_kind\",\n \"deleted_at\",\n \"valid_from\",\n \"valid_to\",\n \"from_id\",\n ],\n },\n {\n table: \"edges\",\n suffix: \"kind_created_idx\",\n columns: [\"graph_id\", \"kind\", \"deleted_at\", \"created_at\"],\n },\n {\n table: \"edges\",\n suffix: \"deleted_idx\",\n columns: [\"graph_id\", \"deleted_at\"],\n },\n {\n table: \"edges\",\n suffix: \"valid_idx\",\n columns: [\"graph_id\", \"valid_from\", \"valid_to\"],\n },\n // Cardinality enforcement: the one-per-endpoint check probes for a\n // currently-valid edge of a kind from a specific endpoint.\n {\n table: \"edges\",\n suffix: \"cardinality_idx\",\n columns: [\"graph_id\", \"kind\", \"from_kind\", \"from_id\", \"valid_to\"],\n },\n\n // ---------------------------------------------------------- recordedNodes\n {\n table: \"recordedNodes\",\n suffix: \"entity_idx\",\n columns: [\"graph_id\", \"kind\", \"id\", \"recorded_from\", \"recorded_to\"],\n },\n {\n table: \"recordedNodes\",\n suffix: \"open_idx\",\n columns: [\"graph_id\", \"recorded_to\"],\n },\n {\n table: \"recordedNodes\",\n suffix: \"valid_idx\",\n columns: [\"graph_id\", \"valid_from\", \"valid_to\"],\n },\n // Bare-id lookup parity with the live nodes table: recorded-pinned\n // reads swap this relation in as the node source, and `entity_idx`\n // leads with `kind`, so the same kind-by-bare-id probe (e.g.\n // `degree()` at a recorded coordinate) would otherwise scan every\n // historical version in the graph. See typegraph#280.\n { table: \"recordedNodes\", suffix: \"id_idx\", columns: [\"graph_id\", \"id\"] },\n\n // ---------------------------------------------------------- recordedEdges\n {\n table: \"recordedEdges\",\n suffix: \"entity_idx\",\n columns: [\"graph_id\", \"kind\", \"id\", \"recorded_from\", \"recorded_to\"],\n },\n {\n table: \"recordedEdges\",\n suffix: \"open_idx\",\n columns: [\"graph_id\", \"recorded_to\"],\n },\n {\n table: \"recordedEdges\",\n suffix: \"from_idx\",\n columns: [\n \"graph_id\",\n \"from_kind\",\n \"from_id\",\n \"kind\",\n \"to_kind\",\n \"recorded_from\",\n \"recorded_to\",\n ],\n },\n {\n table: \"recordedEdges\",\n suffix: \"to_idx\",\n columns: [\n \"graph_id\",\n \"to_kind\",\n \"to_id\",\n \"kind\",\n \"from_kind\",\n \"recorded_from\",\n \"recorded_to\",\n ],\n },\n {\n table: \"recordedEdges\",\n suffix: \"valid_idx\",\n columns: [\"graph_id\", \"valid_from\", \"valid_to\"],\n },\n];\n\n/** Default physical table names for the system-index relations. */\nconst DEFAULT_SYSTEM_INDEX_TABLE_NAMES: Readonly<\n Record<SystemIndexTable, string>\n> = {\n nodes: \"typegraph_nodes\",\n edges: \"typegraph_edges\",\n recordedNodes: \"typegraph_recorded_nodes\",\n recordedEdges: \"typegraph_recorded_edges\",\n};\n\n/**\n * Resolves the physical table name for a system-index relation, honoring\n * a backend's table-name overrides.\n */\nexport function resolveSystemIndexTableName(\n table: SystemIndexTable,\n overrides:\n Readonly<Partial<Record<SystemIndexTable, string | undefined>>> | undefined,\n): string {\n return overrides?.[table] ?? DEFAULT_SYSTEM_INDEX_TABLE_NAMES[table];\n}\n\n/**\n * PostgreSQL truncates identifiers to NAMEDATALEN-1 = 63 bytes SILENTLY —\n * two suffixes of one long custom table name would collide after\n * truncation, and the catalog probes (which compare by exact name) would\n * never match the stored name, re-attempting the build on every boot.\n * SQLite has no such limit but uses the same bound so the two dialects'\n * index sets stay in byte-for-byte parity. (Char-based like the vector\n * identifier bound — multibyte table names are out of scope.)\n */\nconst MAX_SQL_IDENTIFIER_LENGTH = 63;\n\n/**\n * Physical index name: `${physicalTableName}_${suffix}`, deterministically\n * truncated + hash-suffixed past the 63-char identifier bound so distinct\n * indexes stay distinct. Single choke point — the Drizzle builders, the\n * runtime DDL, the catalog probes, and the status keys all derive the\n * name here, so they can never disagree.\n */\nexport function systemIndexName(\n physicalTableName: string,\n suffix: string,\n): string {\n const full = `${physicalTableName}_${suffix}`;\n if (full.length <= MAX_SQL_IDENTIFIER_LENGTH) return full;\n const hash = shortHash(JSON.stringify([physicalTableName, suffix]));\n return `${full.slice(0, MAX_SQL_IDENTIFIER_LENGTH - 1 - hash.length)}_${hash}`;\n}\n\n/**\n * Every system index name for a deployment's (possibly overridden) table\n * names. Graph-declared index names must not collide with these: a\n * colliding `CREATE INDEX IF NOT EXISTS` would silently no-op against the\n * system index (wrong shape) while recording a false success — see the\n * guards in the schema factories and `materializeIndexes`.\n */\nexport function resolveSystemIndexNames(\n overrides:\n Readonly<Partial<Record<SystemIndexTable, string | undefined>>> | undefined,\n): ReadonlySet<string> {\n return new Set(\n SYSTEM_INDEX_DECLARATIONS.map((declaration) =>\n systemIndexName(\n resolveSystemIndexTableName(declaration.table, overrides),\n declaration.suffix,\n ),\n ),\n );\n}\n\n/**\n * Rejects graph-declared indexes whose names collide with this\n * deployment's system index names. Called by both dialect schema\n * factories so a colliding declaration fails at table-definition time\n * instead of silently no-opping against the (differently shaped) system\n * index at CREATE INDEX IF NOT EXISTS time. `materializeIndexes` applies\n * the same check per-declaration on its runtime path.\n */\nexport function assertNoSystemIndexNameCollision(\n indexes: readonly Readonly<{ name: string }>[],\n overrides:\n Readonly<Partial<Record<SystemIndexTable, string | undefined>>> | undefined,\n): void {\n if (indexes.length === 0) return;\n const reserved = resolveSystemIndexNames(overrides);\n for (const index of indexes) {\n if (reserved.has(index.name)) {\n throw new Error(\n `Index name \"${index.name}\" collides with a TypeGraph system ` +\n `index. Choose a different name — system index names are ` +\n `reserved, and a same-named CREATE INDEX IF NOT EXISTS would ` +\n `silently no-op against the system index instead of creating ` +\n `the declared one.`,\n );\n }\n }\n}\n\n/**\n * Runtime DDL for one system index — byte-compatible with the index the\n * bootstrap path creates from the Drizzle schema (same name, same\n * columns), plus `CONCURRENTLY` where the dialect supports building\n * without blocking writes.\n */\nexport function generateSystemIndexDDL(\n declaration: SystemIndexDeclaration,\n physicalTableName: string,\n options: Readonly<{ concurrent: boolean }>,\n): string {\n const name = quoteIdentifier(\n systemIndexName(physicalTableName, declaration.suffix),\n );\n const table = quoteIdentifier(physicalTableName);\n const columns = declaration.columns\n .map((column) => quoteIdentifier(column))\n .join(\", \");\n const concurrently = options.concurrent ? \"CONCURRENTLY \" : \"\";\n return `CREATE INDEX ${concurrently}IF NOT EXISTS ${name} ON ${table} (${columns});`;\n}\n"]}